2 * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
11 * SHA256 low level APIs are deprecated for public use, but still ok for
12 * internal use. Note, that due to symbols not being exported, only the
13 * #defines can be accessed. In this case SHA256_CBLOCK.
15 #include "internal/deprecated.h"
18 #include <openssl/sha.h>
19 #include <openssl/evp.h>
20 #include <openssl/provider.h>
21 #include "internal/sizes.h"
24 static char *config_file = NULL;
25 static char *alg = "digest";
26 static int use_default_ctx = 0;
27 static char *fetch_property = NULL;
28 static int expected_fetch_result = 1;
30 typedef enum OPTION_choice {
41 const OPTIONS *test_get_options(void)
43 static const OPTIONS test_options[] = {
44 OPT_TEST_OPTIONS_WITH_EXTRA_USAGE("[provname...]\n"),
45 { "config", OPT_CONFIG_FILE, '<', "The configuration file to use for the libctx" },
46 { "type", OPT_ALG_FETCH_TYPE, 's', "The fetch type to test" },
47 { "property", OPT_FETCH_PROPERTY, 's', "The fetch property e.g. provider=fips" },
48 { "fetchfail", OPT_FETCH_FAILURE, '-', "fetch is expected to fail" },
49 { "defaultctx", OPT_USE_DEFAULTCTX, '-',
50 "Use the default context if this is set" },
51 { OPT_HELP_STR, 1, '-', "file\tProvider names to explicitly load\n" },
57 static int calculate_digest(const EVP_MD *md, const char *msg, size_t len,
58 const unsigned char *exptd)
60 unsigned char out[SHA256_DIGEST_LENGTH];
64 if (!TEST_ptr(ctx = EVP_MD_CTX_new())
65 || !TEST_true(EVP_DigestInit_ex(ctx, md, NULL))
66 || !TEST_true(EVP_DigestUpdate(ctx, msg, len))
67 || !TEST_true(EVP_DigestFinal_ex(ctx, out, NULL))
68 || !TEST_mem_eq(out, SHA256_DIGEST_LENGTH, exptd,
70 || !TEST_true(md == EVP_MD_CTX_get0_md(ctx)))
79 static int load_providers(OSSL_LIB_CTX **libctx, OSSL_PROVIDER *prov[])
81 OSSL_LIB_CTX *ctx = NULL;
85 ctx = OSSL_LIB_CTX_new();
89 if (!TEST_true(OSSL_LIB_CTX_load_config(ctx, config_file)))
91 if (test_get_argument_count() > 2)
94 for (i = 0; i < test_get_argument_count(); ++i) {
95 char *provname = test_get_argument(i);
96 prov[i] = OSSL_PROVIDER_load(ctx, provname);
97 if (!TEST_ptr(prov[i]))
105 OSSL_LIB_CTX_free(ctx);
109 static void unload_providers(OSSL_LIB_CTX **libctx, OSSL_PROVIDER *prov[])
112 OSSL_PROVIDER_unload(prov[0]);
114 OSSL_PROVIDER_unload(prov[1]);
115 /* Not normally needed, but we would like to test that
116 * OPENSSL_thread_stop_ex() behaves as expected.
118 if (libctx != NULL && *libctx != NULL) {
119 OPENSSL_thread_stop_ex(*libctx);
120 OSSL_LIB_CTX_free(*libctx);
124 static int test_legacy_provider_unloaded(void)
126 OSSL_LIB_CTX *ctx = NULL;
129 ctx = OSSL_LIB_CTX_new();
133 if (!TEST_true(OSSL_LIB_CTX_load_config(ctx, config_file)))
136 if (!TEST_int_eq(OSSL_PROVIDER_available(ctx, "legacy"), 0))
141 OSSL_LIB_CTX_free(ctx);
145 static X509_ALGOR *make_algor(int nid)
149 if (!TEST_ptr(algor = X509_ALGOR_new())
150 || !TEST_true(X509_ALGOR_set0(algor, OBJ_nid2obj(nid),
151 V_ASN1_UNDEF, NULL))) {
152 X509_ALGOR_free(algor);
159 * Test EVP_MD_fetch()
161 static int test_md(const EVP_MD *md)
163 const char testmsg[] = "Hello world";
164 const unsigned char exptd[] = {
165 0x27, 0x51, 0x8b, 0xa9, 0x68, 0x30, 0x11, 0xf6, 0xb3, 0x96, 0x07, 0x2c,
166 0x05, 0xf6, 0x65, 0x6d, 0x04, 0xf5, 0xfb, 0xc3, 0x78, 0x7c, 0xf9, 0x24,
167 0x90, 0xec, 0x60, 0x6e, 0x50, 0x92, 0xe3, 0x26
171 && TEST_true(EVP_MD_is_a(md, "SHA256"))
172 && TEST_true(calculate_digest(md, testmsg, sizeof(testmsg), exptd))
173 && TEST_int_eq(EVP_MD_get_size(md), SHA256_DIGEST_LENGTH)
174 && TEST_int_eq(EVP_MD_get_block_size(md), SHA256_CBLOCK);
177 static int test_implicit_EVP_MD_fetch(void)
179 OSSL_LIB_CTX *ctx = NULL;
180 OSSL_PROVIDER *prov[2] = {NULL, NULL};
183 ret = (use_default_ctx == 0 || load_providers(&ctx, prov))
184 && test_md(EVP_sha256());
186 unload_providers(&ctx, prov);
190 static int test_explicit_EVP_MD_fetch(const char *id)
192 OSSL_LIB_CTX *ctx = NULL;
194 OSSL_PROVIDER *prov[2] = {NULL, NULL};
197 if (use_default_ctx == 0 && !load_providers(&ctx, prov))
200 md = EVP_MD_fetch(ctx, id, fetch_property);
201 if (expected_fetch_result != 0) {
205 /* Also test EVP_MD_up_ref() while we're doing this */
206 if (!TEST_true(EVP_MD_up_ref(md)))
208 /* Ref count should now be 2. Release first one here */
211 if (!TEST_ptr_null(md))
218 unload_providers(&ctx, prov);
222 static int test_explicit_EVP_MD_fetch_by_name(void)
224 return test_explicit_EVP_MD_fetch("SHA256");
228 * idx 0: Allow names from OBJ_obj2txt()
229 * idx 1: Force an OID in text form from OBJ_obj2txt()
231 static int test_explicit_EVP_MD_fetch_by_X509_ALGOR(int idx)
234 X509_ALGOR *algor = make_algor(NID_sha256);
235 const ASN1_OBJECT *obj;
236 char id[OSSL_MAX_NAME_SIZE] = { 0 };
241 X509_ALGOR_get0(&obj, NULL, NULL, algor);
244 if (!TEST_int_gt(OBJ_obj2txt(id, sizeof(id), obj, 0), 0))
248 if (!TEST_int_gt(OBJ_obj2txt(id, sizeof(id), obj, 1), 0))
253 ret = test_explicit_EVP_MD_fetch(id);
255 X509_ALGOR_free(algor);
260 * Test EVP_CIPHER_fetch()
262 static int encrypt_decrypt(const EVP_CIPHER *cipher, const unsigned char *msg,
265 int ret = 0, ctlen, ptlen;
266 EVP_CIPHER_CTX *ctx = NULL;
267 unsigned char key[128 / 8];
268 unsigned char ct[64], pt[64];
270 memset(key, 0, sizeof(key));
271 if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new())
272 || !TEST_true(EVP_CipherInit_ex(ctx, cipher, NULL, key, NULL, 1))
273 || !TEST_true(EVP_CipherUpdate(ctx, ct, &ctlen, msg, len))
274 || !TEST_true(EVP_CipherFinal_ex(ctx, ct, &ctlen))
275 || !TEST_true(EVP_CipherInit_ex(ctx, cipher, NULL, key, NULL, 0))
276 || !TEST_true(EVP_CipherUpdate(ctx, pt, &ptlen, ct, ctlen))
277 || !TEST_true(EVP_CipherFinal_ex(ctx, pt, &ptlen))
278 || !TEST_mem_eq(pt, ptlen, msg, len))
283 EVP_CIPHER_CTX_free(ctx);
287 static int test_cipher(const EVP_CIPHER *cipher)
289 const unsigned char testmsg[] = "Hello world";
291 return TEST_ptr(cipher)
292 && TEST_true(encrypt_decrypt(cipher, testmsg, sizeof(testmsg)));
295 static int test_implicit_EVP_CIPHER_fetch(void)
297 OSSL_LIB_CTX *ctx = NULL;
298 OSSL_PROVIDER *prov[2] = {NULL, NULL};
301 ret = (use_default_ctx == 0 || load_providers(&ctx, prov))
302 && test_cipher(EVP_aes_128_cbc());
304 unload_providers(&ctx, prov);
308 static int test_explicit_EVP_CIPHER_fetch(const char *id)
310 OSSL_LIB_CTX *ctx = NULL;
311 EVP_CIPHER *cipher = NULL;
312 OSSL_PROVIDER *prov[2] = {NULL, NULL};
315 if (use_default_ctx == 0 && !load_providers(&ctx, prov))
318 cipher = EVP_CIPHER_fetch(ctx, id, fetch_property);
319 if (expected_fetch_result != 0) {
320 if (!test_cipher(cipher))
323 if (!TEST_true(EVP_CIPHER_up_ref(cipher)))
325 /* Ref count should now be 2. Release first one here */
326 EVP_CIPHER_free(cipher);
328 if (!TEST_ptr_null(cipher))
333 EVP_CIPHER_free(cipher);
334 unload_providers(&ctx, prov);
338 static int test_explicit_EVP_CIPHER_fetch_by_name(void)
340 return test_explicit_EVP_CIPHER_fetch("AES-128-CBC");
344 * idx 0: Allow names from OBJ_obj2txt()
345 * idx 1: Force an OID in text form from OBJ_obj2txt()
347 static int test_explicit_EVP_CIPHER_fetch_by_X509_ALGOR(int idx)
350 X509_ALGOR *algor = make_algor(NID_aes_128_cbc);
351 const ASN1_OBJECT *obj;
352 char id[OSSL_MAX_NAME_SIZE] = { 0 };
357 X509_ALGOR_get0(&obj, NULL, NULL, algor);
360 if (!TEST_int_gt(OBJ_obj2txt(id, sizeof(id), obj, 0), 0))
364 if (!TEST_int_gt(OBJ_obj2txt(id, sizeof(id), obj, 1), 0))
369 ret = test_explicit_EVP_CIPHER_fetch(id);
371 X509_ALGOR_free(algor);
375 int setup_tests(void)
379 while ((o = opt_next()) != OPT_EOF) {
381 case OPT_CONFIG_FILE:
382 config_file = opt_arg();
384 case OPT_ALG_FETCH_TYPE:
387 case OPT_FETCH_PROPERTY:
388 fetch_property = opt_arg();
390 case OPT_FETCH_FAILURE:
391 expected_fetch_result = 0;
393 case OPT_USE_DEFAULTCTX:
403 ADD_TEST(test_legacy_provider_unloaded);
404 if (strcmp(alg, "digest") == 0) {
405 ADD_TEST(test_implicit_EVP_MD_fetch);
406 ADD_TEST(test_explicit_EVP_MD_fetch_by_name);
407 ADD_ALL_TESTS_NOSUBTEST(test_explicit_EVP_MD_fetch_by_X509_ALGOR, 2);
409 ADD_TEST(test_implicit_EVP_CIPHER_fetch);
410 ADD_TEST(test_explicit_EVP_CIPHER_fetch_by_name);
411 ADD_ALL_TESTS_NOSUBTEST(test_explicit_EVP_CIPHER_fetch_by_X509_ALGOR, 2);