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