]> git.ipfire.org Git - thirdparty/openssl.git/blob - test/evp_fetch_prov_test.c
Add "origin" field to EVP_CIPHER, EVP_MD
[thirdparty/openssl.git] / test / evp_fetch_prov_test.c
1 /*
2 * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
3 *
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
8 */
9
10 /*
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.
14 */
15 #include "internal/deprecated.h"
16
17 #include <string.h>
18 #include <openssl/sha.h>
19 #include <openssl/evp.h>
20 #include <openssl/provider.h>
21 #include "testutil.h"
22
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;
28
29 typedef enum OPTION_choice {
30 OPT_ERR = -1,
31 OPT_EOF = 0,
32 OPT_ALG_FETCH_TYPE,
33 OPT_FETCH_PROPERTY,
34 OPT_FETCH_FAILURE,
35 OPT_USE_DEFAULTCTX,
36 OPT_CONFIG_FILE,
37 OPT_TEST_ENUM
38 } OPTION_CHOICE;
39
40 const OPTIONS *test_get_options(void)
41 {
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, '-', "file\tProvider names to explicitly load\n" },
51 { NULL }
52 };
53 return test_options;
54 }
55
56 static int calculate_digest(const EVP_MD *md, const char *msg, size_t len,
57 const unsigned char *exptd)
58 {
59 unsigned char out[SHA256_DIGEST_LENGTH];
60 EVP_MD_CTX *ctx;
61 int ret = 0;
62
63 if (!TEST_ptr(ctx = EVP_MD_CTX_new())
64 || !TEST_true(EVP_DigestInit_ex(ctx, md, NULL))
65 || !TEST_true(EVP_DigestUpdate(ctx, msg, len))
66 || !TEST_true(EVP_DigestFinal_ex(ctx, out, NULL))
67 || !TEST_mem_eq(out, SHA256_DIGEST_LENGTH, exptd,
68 SHA256_DIGEST_LENGTH)
69 || !TEST_true(md == EVP_MD_CTX_get0_md(ctx)))
70 goto err;
71
72 ret = 1;
73 err:
74 EVP_MD_CTX_free(ctx);
75 return ret;
76 }
77
78 static int load_providers(OSSL_LIB_CTX **libctx, OSSL_PROVIDER *prov[])
79 {
80 OSSL_LIB_CTX *ctx = NULL;
81 int ret = 0;
82 size_t i;
83
84 ctx = OSSL_LIB_CTX_new();
85 if (!TEST_ptr(ctx))
86 goto err;
87
88 if (!TEST_true(OSSL_LIB_CTX_load_config(ctx, config_file)))
89 goto err;
90 if (test_get_argument_count() > 2)
91 goto err;
92
93 for (i = 0; i < test_get_argument_count(); ++i) {
94 char *provname = test_get_argument(i);
95 prov[i] = OSSL_PROVIDER_load(ctx, provname);
96 if (!TEST_ptr(prov[i]))
97 goto err;
98 }
99
100 ret = 1;
101 *libctx = ctx;
102 err:
103 if (ret == 0)
104 OSSL_LIB_CTX_free(ctx);
105 return ret;
106 }
107
108 /*
109 * Test EVP_MD_fetch()
110 */
111 static int test_EVP_MD_fetch(void)
112 {
113 OSSL_LIB_CTX *ctx = NULL;
114 EVP_MD *md = NULL;
115 OSSL_PROVIDER *prov[2] = {NULL, NULL};
116 int ret = 0;
117 const char testmsg[] = "Hello world";
118 const unsigned char exptd[] = {
119 0x27, 0x51, 0x8b, 0xa9, 0x68, 0x30, 0x11, 0xf6, 0xb3, 0x96, 0x07, 0x2c,
120 0x05, 0xf6, 0x65, 0x6d, 0x04, 0xf5, 0xfb, 0xc3, 0x78, 0x7c, 0xf9, 0x24,
121 0x90, 0xec, 0x60, 0x6e, 0x50, 0x92, 0xe3, 0x26
122 };
123
124 if (use_default_ctx == 0 && !load_providers(&ctx, prov))
125 goto err;
126
127 /* Implicit fetching of the MD should produce the expected result */
128 if (!TEST_true(calculate_digest(EVP_sha256(), testmsg, sizeof(testmsg),
129 exptd))
130 || !TEST_int_eq(EVP_MD_size(EVP_sha256()), SHA256_DIGEST_LENGTH)
131 || !TEST_int_eq(EVP_MD_block_size(EVP_sha256()), SHA256_CBLOCK))
132 goto err;
133
134 /* Fetch the digest from a provider using properties. */
135 md = EVP_MD_fetch(ctx, "SHA256", fetch_property);
136 if (expected_fetch_result != 0) {
137 if (!TEST_ptr(md)
138 || !TEST_int_eq(EVP_MD_nid(md), NID_sha256)
139 || !TEST_true(calculate_digest(md, testmsg, sizeof(testmsg), exptd))
140 || !TEST_int_eq(EVP_MD_size(md), SHA256_DIGEST_LENGTH)
141 || !TEST_int_eq(EVP_MD_block_size(md), SHA256_CBLOCK))
142 goto err;
143
144 /* Also test EVP_MD_up_ref() while we're doing this */
145 if (!TEST_true(EVP_MD_up_ref(md)))
146 goto err;
147 /* Ref count should now be 2. Release first one here */
148 EVP_MD_free(md);
149 } else {
150 if (!TEST_ptr_null(md))
151 goto err;
152 }
153 ret = 1;
154
155 err:
156 EVP_MD_free(md);
157 OSSL_PROVIDER_unload(prov[0]);
158 OSSL_PROVIDER_unload(prov[1]);
159 /* Not normally needed, but we would like to test that
160 * OPENSSL_thread_stop_ex() behaves as expected.
161 */
162 if (ctx != NULL) {
163 OPENSSL_thread_stop_ex(ctx);
164 OSSL_LIB_CTX_free(ctx);
165 }
166 return ret;
167 }
168
169 static int encrypt_decrypt(const EVP_CIPHER *cipher, const unsigned char *msg,
170 size_t len)
171 {
172 int ret = 0, ctlen, ptlen;
173 EVP_CIPHER_CTX *ctx = NULL;
174 unsigned char key[128 / 8];
175 unsigned char ct[64], pt[64];
176
177 memset(key, 0, sizeof(key));
178 if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new())
179 || !TEST_true(EVP_CipherInit_ex(ctx, cipher, NULL, key, NULL, 1))
180 || !TEST_true(EVP_CipherUpdate(ctx, ct, &ctlen, msg, len))
181 || !TEST_true(EVP_CipherFinal_ex(ctx, ct, &ctlen))
182 || !TEST_true(EVP_CipherInit_ex(ctx, cipher, NULL, key, NULL, 0))
183 || !TEST_true(EVP_CipherUpdate(ctx, pt, &ptlen, ct, ctlen))
184 || !TEST_true(EVP_CipherFinal_ex(ctx, pt, &ptlen))
185 || !TEST_mem_eq(pt, ptlen, msg, len))
186 goto err;
187
188 ret = 1;
189 err:
190 EVP_CIPHER_CTX_free(ctx);
191 return ret;
192 }
193
194 /*
195 * Test EVP_CIPHER_fetch()
196 */
197 static int test_EVP_CIPHER_fetch(void)
198 {
199 OSSL_LIB_CTX *ctx = NULL;
200 EVP_CIPHER *cipher = NULL;
201 OSSL_PROVIDER *prov[2] = {NULL, NULL};
202 int ret = 0;
203 const unsigned char testmsg[] = "Hello world";
204
205 if (use_default_ctx == 0 && !load_providers(&ctx, prov))
206 goto err;
207
208 /* Implicit fetching of the cipher should produce the expected result */
209 if (!TEST_true(encrypt_decrypt(EVP_aes_128_cbc(), testmsg, sizeof(testmsg))))
210 goto err;
211
212 /* Fetch the cipher from a provider using properties. */
213 cipher = EVP_CIPHER_fetch(ctx, "AES-128-CBC", fetch_property);
214 if (expected_fetch_result != 0) {
215 if (!TEST_ptr(cipher)
216 || !TEST_true(encrypt_decrypt(cipher, testmsg, sizeof(testmsg)))) {
217 if (!TEST_true(EVP_CIPHER_up_ref(cipher)))
218 goto err;
219 /* Ref count should now be 2. Release first one here */
220 EVP_CIPHER_free(cipher);
221 }
222 } else {
223 if (!TEST_ptr_null(cipher))
224 goto err;
225 }
226 ret = 1;
227 err:
228 EVP_CIPHER_free(cipher);
229 OSSL_PROVIDER_unload(prov[0]);
230 OSSL_PROVIDER_unload(prov[1]);
231 OSSL_LIB_CTX_free(ctx);
232 return ret;
233 }
234
235 int setup_tests(void)
236 {
237 OPTION_CHOICE o;
238
239 while ((o = opt_next()) != OPT_EOF) {
240 switch (o) {
241 case OPT_CONFIG_FILE:
242 config_file = opt_arg();
243 break;
244 case OPT_ALG_FETCH_TYPE:
245 alg = opt_arg();
246 break;
247 case OPT_FETCH_PROPERTY:
248 fetch_property = opt_arg();
249 break;
250 case OPT_FETCH_FAILURE:
251 expected_fetch_result = 0;
252 break;
253 case OPT_USE_DEFAULTCTX:
254 use_default_ctx = 1;
255 break;
256 case OPT_TEST_CASES:
257 break;
258 default:
259 case OPT_ERR:
260 return 0;
261 }
262 }
263 if (strcmp(alg, "digest") == 0)
264 ADD_TEST(test_EVP_MD_fetch);
265 else
266 ADD_TEST(test_EVP_CIPHER_fetch);
267 return 1;
268 }