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 X509_ALGOR
*make_algor(int nid
)
128 if (!TEST_ptr(algor
= X509_ALGOR_new())
129 || !TEST_true(X509_ALGOR_set0(algor
, OBJ_nid2obj(nid
),
130 V_ASN1_UNDEF
, NULL
))) {
131 X509_ALGOR_free(algor
);
138 * Test EVP_MD_fetch()
140 static int test_md(const EVP_MD
*md
)
142 const char testmsg
[] = "Hello world";
143 const unsigned char exptd
[] = {
144 0x27, 0x51, 0x8b, 0xa9, 0x68, 0x30, 0x11, 0xf6, 0xb3, 0x96, 0x07, 0x2c,
145 0x05, 0xf6, 0x65, 0x6d, 0x04, 0xf5, 0xfb, 0xc3, 0x78, 0x7c, 0xf9, 0x24,
146 0x90, 0xec, 0x60, 0x6e, 0x50, 0x92, 0xe3, 0x26
150 && TEST_true(EVP_MD_is_a(md
, "SHA256"))
151 && TEST_true(calculate_digest(md
, testmsg
, sizeof(testmsg
), exptd
))
152 && TEST_int_eq(EVP_MD_get_size(md
), SHA256_DIGEST_LENGTH
)
153 && TEST_int_eq(EVP_MD_get_block_size(md
), SHA256_CBLOCK
);
156 static int test_implicit_EVP_MD_fetch(void)
158 OSSL_LIB_CTX
*ctx
= NULL
;
159 OSSL_PROVIDER
*prov
[2] = {NULL
, NULL
};
162 ret
= (use_default_ctx
== 0 || load_providers(&ctx
, prov
))
163 && test_md(EVP_sha256());
165 unload_providers(&ctx
, prov
);
169 static int test_explicit_EVP_MD_fetch(const char *id
)
171 OSSL_LIB_CTX
*ctx
= NULL
;
173 OSSL_PROVIDER
*prov
[2] = {NULL
, NULL
};
176 if (use_default_ctx
== 0 && !load_providers(&ctx
, prov
))
179 md
= EVP_MD_fetch(ctx
, id
, fetch_property
);
180 if (expected_fetch_result
!= 0) {
184 /* Also test EVP_MD_up_ref() while we're doing this */
185 if (!TEST_true(EVP_MD_up_ref(md
)))
187 /* Ref count should now be 2. Release first one here */
190 if (!TEST_ptr_null(md
))
197 unload_providers(&ctx
, prov
);
201 static int test_explicit_EVP_MD_fetch_by_name(void)
203 return test_explicit_EVP_MD_fetch("SHA256");
207 * idx 0: Allow names from OBJ_obj2txt()
208 * idx 1: Force an OID in text form from OBJ_obj2txt()
210 static int test_explicit_EVP_MD_fetch_by_X509_ALGOR(int idx
)
213 X509_ALGOR
*algor
= make_algor(NID_sha256
);
214 const ASN1_OBJECT
*obj
;
215 char id
[OSSL_MAX_NAME_SIZE
] = { 0 };
220 X509_ALGOR_get0(&obj
, NULL
, NULL
, algor
);
223 if (!TEST_int_gt(OBJ_obj2txt(id
, sizeof(id
), obj
, 0), 0))
227 if (!TEST_int_gt(OBJ_obj2txt(id
, sizeof(id
), obj
, 1), 0))
232 ret
= test_explicit_EVP_MD_fetch(id
);
234 X509_ALGOR_free(algor
);
239 * Test EVP_CIPHER_fetch()
241 static int encrypt_decrypt(const EVP_CIPHER
*cipher
, const unsigned char *msg
,
244 int ret
= 0, ctlen
, ptlen
;
245 EVP_CIPHER_CTX
*ctx
= NULL
;
246 unsigned char key
[128 / 8];
247 unsigned char ct
[64], pt
[64];
249 memset(key
, 0, sizeof(key
));
250 if (!TEST_ptr(ctx
= EVP_CIPHER_CTX_new())
251 || !TEST_true(EVP_CipherInit_ex(ctx
, cipher
, NULL
, key
, NULL
, 1))
252 || !TEST_true(EVP_CipherUpdate(ctx
, ct
, &ctlen
, msg
, len
))
253 || !TEST_true(EVP_CipherFinal_ex(ctx
, ct
, &ctlen
))
254 || !TEST_true(EVP_CipherInit_ex(ctx
, cipher
, NULL
, key
, NULL
, 0))
255 || !TEST_true(EVP_CipherUpdate(ctx
, pt
, &ptlen
, ct
, ctlen
))
256 || !TEST_true(EVP_CipherFinal_ex(ctx
, pt
, &ptlen
))
257 || !TEST_mem_eq(pt
, ptlen
, msg
, len
))
262 EVP_CIPHER_CTX_free(ctx
);
266 static int test_cipher(const EVP_CIPHER
*cipher
)
268 const unsigned char testmsg
[] = "Hello world";
270 return TEST_ptr(cipher
)
271 && TEST_true(encrypt_decrypt(cipher
, testmsg
, sizeof(testmsg
)));
274 static int test_implicit_EVP_CIPHER_fetch(void)
276 OSSL_LIB_CTX
*ctx
= NULL
;
277 OSSL_PROVIDER
*prov
[2] = {NULL
, NULL
};
280 ret
= (use_default_ctx
== 0 || load_providers(&ctx
, prov
))
281 && test_cipher(EVP_aes_128_cbc());
283 unload_providers(&ctx
, prov
);
287 static int test_explicit_EVP_CIPHER_fetch(const char *id
)
289 OSSL_LIB_CTX
*ctx
= NULL
;
290 EVP_CIPHER
*cipher
= NULL
;
291 OSSL_PROVIDER
*prov
[2] = {NULL
, NULL
};
294 if (use_default_ctx
== 0 && !load_providers(&ctx
, prov
))
297 cipher
= EVP_CIPHER_fetch(ctx
, id
, fetch_property
);
298 if (expected_fetch_result
!= 0) {
299 if (!test_cipher(cipher
))
302 if (!TEST_true(EVP_CIPHER_up_ref(cipher
)))
304 /* Ref count should now be 2. Release first one here */
305 EVP_CIPHER_free(cipher
);
307 if (!TEST_ptr_null(cipher
))
312 EVP_CIPHER_free(cipher
);
313 unload_providers(&ctx
, prov
);
317 static int test_explicit_EVP_CIPHER_fetch_by_name(void)
319 return test_explicit_EVP_CIPHER_fetch("AES-128-CBC");
323 * idx 0: Allow names from OBJ_obj2txt()
324 * idx 1: Force an OID in text form from OBJ_obj2txt()
326 static int test_explicit_EVP_CIPHER_fetch_by_X509_ALGOR(int idx
)
329 X509_ALGOR
*algor
= make_algor(NID_aes_128_cbc
);
330 const ASN1_OBJECT
*obj
;
331 char id
[OSSL_MAX_NAME_SIZE
] = { 0 };
336 X509_ALGOR_get0(&obj
, NULL
, NULL
, algor
);
339 if (!TEST_int_gt(OBJ_obj2txt(id
, sizeof(id
), obj
, 0), 0))
343 if (!TEST_int_gt(OBJ_obj2txt(id
, sizeof(id
), obj
, 1), 0))
348 ret
= test_explicit_EVP_CIPHER_fetch(id
);
350 X509_ALGOR_free(algor
);
354 int setup_tests(void)
358 while ((o
= opt_next()) != OPT_EOF
) {
360 case OPT_CONFIG_FILE
:
361 config_file
= opt_arg();
363 case OPT_ALG_FETCH_TYPE
:
366 case OPT_FETCH_PROPERTY
:
367 fetch_property
= opt_arg();
369 case OPT_FETCH_FAILURE
:
370 expected_fetch_result
= 0;
372 case OPT_USE_DEFAULTCTX
:
382 if (strcmp(alg
, "digest") == 0) {
383 ADD_TEST(test_implicit_EVP_MD_fetch
);
384 ADD_TEST(test_explicit_EVP_MD_fetch_by_name
);
385 ADD_ALL_TESTS_NOSUBTEST(test_explicit_EVP_MD_fetch_by_X509_ALGOR
, 2);
387 ADD_TEST(test_implicit_EVP_CIPHER_fetch
);
388 ADD_TEST(test_explicit_EVP_CIPHER_fetch_by_name
);
389 ADD_ALL_TESTS_NOSUBTEST(test_explicit_EVP_CIPHER_fetch_by_X509_ALGOR
, 2);