2 * Copyright 2019-2020 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>
23 static char *config_file = NULL;
24 static char *alg = "digest";
25 static int use_default_ctx = 0;
26 static char *fetch_property = NULL;
27 static int expected_fetch_result = 1;
29 typedef enum OPTION_choice {
40 const OPTIONS *test_get_options(void)
42 static const OPTIONS test_options[] = {
43 OPT_TEST_OPTIONS_WITH_EXTRA_USAGE("[provname...]\n"),
44 { "config", OPT_CONFIG_FILE, '<', "The configuration file to use for the libctx" },
45 { "type", OPT_ALG_FETCH_TYPE, 's', "The fetch type to test" },
46 { "property", OPT_FETCH_PROPERTY, 's', "The fetch property e.g. provider=fips" },
47 { "fetchfail", OPT_FETCH_FAILURE, '-', "fetch is expected to fail" },
48 { "defaultctx", OPT_USE_DEFAULTCTX, '-',
49 "Use the default context if this is set" },
50 { OPT_HELP_STR, 1, '-',
51 "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_md(ctx)))
79 static int load_providers(OPENSSL_CTX **libctx, OSSL_PROVIDER *prov[])
81 OPENSSL_CTX *ctx = NULL;
85 ctx = OPENSSL_CTX_new();
89 if (!TEST_true(OPENSSL_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 OPENSSL_CTX_free(ctx);
110 * Test EVP_MD_fetch()
112 static int test_EVP_MD_fetch(void)
114 OPENSSL_CTX *ctx = NULL;
116 OSSL_PROVIDER *prov[2] = {NULL, NULL};
118 const char testmsg[] = "Hello world";
119 const unsigned char exptd[] = {
120 0x27, 0x51, 0x8b, 0xa9, 0x68, 0x30, 0x11, 0xf6, 0xb3, 0x96, 0x07, 0x2c,
121 0x05, 0xf6, 0x65, 0x6d, 0x04, 0xf5, 0xfb, 0xc3, 0x78, 0x7c, 0xf9, 0x24,
122 0x90, 0xec, 0x60, 0x6e, 0x50, 0x92, 0xe3, 0x26
125 if (use_default_ctx == 0 && !load_providers(&ctx, prov))
128 /* Implicit fetching of the MD should produce the expected result */
129 if (!TEST_true(calculate_digest(EVP_sha256(), testmsg, sizeof(testmsg),
131 || !TEST_int_eq(EVP_MD_size(EVP_sha256()), SHA256_DIGEST_LENGTH)
132 || !TEST_int_eq(EVP_MD_block_size(EVP_sha256()), SHA256_CBLOCK))
135 /* Fetch the digest from a provider using properties. */
136 md = EVP_MD_fetch(ctx, "SHA256", fetch_property);
137 if (expected_fetch_result != 0) {
139 || !TEST_int_eq(EVP_MD_nid(md), NID_sha256)
140 || !TEST_true(calculate_digest(md, testmsg, sizeof(testmsg), exptd))
141 || !TEST_int_eq(EVP_MD_size(md), SHA256_DIGEST_LENGTH)
142 || !TEST_int_eq(EVP_MD_block_size(md), SHA256_CBLOCK))
145 /* Also test EVP_MD_up_ref() while we're doing this */
146 if (!TEST_true(EVP_MD_up_ref(md)))
148 /* Ref count should now be 2. Release first one here */
149 EVP_MD_meth_free(md);
151 if (!TEST_ptr_null(md))
157 EVP_MD_meth_free(md);
158 OSSL_PROVIDER_unload(prov[0]);
159 OSSL_PROVIDER_unload(prov[1]);
160 /* Not normally needed, but we would like to test that
161 * OPENSSL_thread_stop_ex() behaves as expected.
164 OPENSSL_thread_stop_ex(ctx);
165 OPENSSL_CTX_free(ctx);
170 static int encrypt_decrypt(const EVP_CIPHER *cipher, const unsigned char *msg,
173 int ret = 0, ctlen, ptlen;
174 EVP_CIPHER_CTX *ctx = NULL;
175 unsigned char key[128 / 8];
176 unsigned char ct[64], pt[64];
178 memset(key, 0, sizeof(key));
179 if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new())
180 || !TEST_true(EVP_CipherInit_ex(ctx, cipher, NULL, key, NULL, 1))
181 || !TEST_true(EVP_CipherUpdate(ctx, ct, &ctlen, msg, len))
182 || !TEST_true(EVP_CipherFinal_ex(ctx, ct, &ctlen))
183 || !TEST_true(EVP_CipherInit_ex(ctx, cipher, NULL, key, NULL, 0))
184 || !TEST_true(EVP_CipherUpdate(ctx, pt, &ptlen, ct, ctlen))
185 || !TEST_true(EVP_CipherFinal_ex(ctx, pt, &ptlen))
186 || !TEST_mem_eq(pt, ptlen, msg, len))
191 EVP_CIPHER_CTX_free(ctx);
196 * Test EVP_CIPHER_fetch()
198 static int test_EVP_CIPHER_fetch(void)
200 OPENSSL_CTX *ctx = NULL;
201 EVP_CIPHER *cipher = NULL;
202 OSSL_PROVIDER *prov[2] = {NULL, NULL};
204 const unsigned char testmsg[] = "Hello world";
206 if (use_default_ctx == 0 && !load_providers(&ctx, prov))
209 /* Implicit fetching of the cipher should produce the expected result */
210 if (!TEST_true(encrypt_decrypt(EVP_aes_128_cbc(), testmsg, sizeof(testmsg))))
213 /* Fetch the cipher from a provider using properties. */
214 cipher = EVP_CIPHER_fetch(ctx, "AES-128-CBC", fetch_property);
215 if (expected_fetch_result != 0) {
216 if (!TEST_ptr(cipher)
217 || !TEST_true(encrypt_decrypt(cipher, testmsg, sizeof(testmsg)))) {
218 if (!TEST_true(EVP_CIPHER_up_ref(cipher)))
220 /* Ref count should now be 2. Release first one here */
221 EVP_CIPHER_meth_free(cipher);
224 if (!TEST_ptr_null(cipher))
229 EVP_CIPHER_meth_free(cipher);
230 OSSL_PROVIDER_unload(prov[0]);
231 OSSL_PROVIDER_unload(prov[1]);
232 OPENSSL_CTX_free(ctx);
236 int setup_tests(void)
240 while ((o = opt_next()) != OPT_EOF) {
242 case OPT_CONFIG_FILE:
243 config_file = opt_arg();
245 case OPT_ALG_FETCH_TYPE:
248 case OPT_FETCH_PROPERTY:
249 fetch_property = opt_arg();
251 case OPT_FETCH_FAILURE:
252 expected_fetch_result = 0;
254 case OPT_USE_DEFAULTCTX:
264 if (strcmp(alg, "digest") == 0)
265 ADD_TEST(test_EVP_MD_fetch);
267 ADD_TEST(test_EVP_CIPHER_fetch);