]>
Commit | Line | Data |
---|---|---|
36fc5fc6 | 1 | /* |
4333b89f | 2 | * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. |
36fc5fc6 | 3 | * |
a6ed19dc | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
36fc5fc6 SL |
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 | #include <string.h> | |
11 | #include <openssl/evp.h> | |
12 | #include <openssl/kdf.h> | |
ec4d1b8f SL |
13 | #include <openssl/core_names.h> |
14 | #include <openssl/param_build.h> | |
d5e66eab | 15 | #include "internal/cryptlib.h" |
36fc5fc6 SL |
16 | #include "internal/nelem.h" |
17 | #include "self_test.h" | |
18 | #include "self_test_data.inc" | |
19 | ||
47c239c6 | 20 | static int self_test_digest(const ST_KAT_DIGEST *t, OSSL_SELF_TEST *st, |
b4250010 | 21 | OSSL_LIB_CTX *libctx) |
36fc5fc6 SL |
22 | { |
23 | int ok = 0; | |
24 | unsigned char out[EVP_MAX_MD_SIZE]; | |
25 | unsigned int out_len = 0; | |
26 | EVP_MD_CTX *ctx = EVP_MD_CTX_new(); | |
27 | EVP_MD *md = EVP_MD_fetch(libctx, t->algorithm, NULL); | |
28 | ||
47c239c6 | 29 | OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_DIGEST, t->desc); |
36fc5fc6 SL |
30 | |
31 | if (ctx == NULL | |
32 | || md == NULL | |
33 | || !EVP_DigestInit_ex(ctx, md, NULL) | |
34 | || !EVP_DigestUpdate(ctx, t->pt, t->pt_len) | |
35 | || !EVP_DigestFinal(ctx, out, &out_len)) | |
36 | goto err; | |
37 | ||
38 | /* Optional corruption */ | |
47c239c6 | 39 | OSSL_SELF_TEST_oncorrupt_byte(st, out); |
36fc5fc6 SL |
40 | |
41 | if (out_len != t->expected_len | |
42 | || memcmp(out, t->expected, out_len) != 0) | |
43 | goto err; | |
44 | ok = 1; | |
45 | err: | |
36fc5fc6 SL |
46 | EVP_MD_free(md); |
47 | EVP_MD_CTX_free(ctx); | |
ec4d1b8f | 48 | OSSL_SELF_TEST_onend(st, ok); |
36fc5fc6 SL |
49 | return ok; |
50 | } | |
51 | ||
52 | /* | |
53 | * Helper function to setup a EVP_CipherInit | |
54 | * Used to hide the complexity of Authenticated ciphers. | |
55 | */ | |
56 | static int cipher_init(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, | |
57 | const ST_KAT_CIPHER *t, int enc) | |
58 | { | |
59 | unsigned char *in_tag = NULL; | |
60 | int pad = 0, tmp; | |
61 | ||
62 | /* Flag required for Key wrapping */ | |
63 | EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); | |
64 | if (t->tag == NULL) { | |
65 | /* Use a normal cipher init */ | |
66 | return EVP_CipherInit_ex(ctx, cipher, NULL, t->key, t->iv, enc) | |
67 | && EVP_CIPHER_CTX_set_padding(ctx, pad); | |
68 | } | |
69 | ||
70 | /* The authenticated cipher init */ | |
71 | if (!enc) | |
72 | in_tag = (unsigned char *)t->tag; | |
73 | ||
74 | return EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc) | |
75 | && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, t->iv_len, NULL) | |
76 | && (in_tag == NULL | |
77 | || EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, t->tag_len, | |
78 | in_tag)) | |
79 | && EVP_CipherInit_ex(ctx, NULL, NULL, t->key, t->iv, enc) | |
80 | && EVP_CIPHER_CTX_set_padding(ctx, pad) | |
81 | && EVP_CipherUpdate(ctx, NULL, &tmp, t->aad, t->aad_len); | |
82 | } | |
83 | ||
84 | /* Test a single KAT for encrypt/decrypt */ | |
47c239c6 | 85 | static int self_test_cipher(const ST_KAT_CIPHER *t, OSSL_SELF_TEST *st, |
b4250010 | 86 | OSSL_LIB_CTX *libctx) |
36fc5fc6 | 87 | { |
3fed2718 | 88 | int ret = 0, encrypt = 1, len = 0, ct_len = 0, pt_len = 0; |
36fc5fc6 SL |
89 | EVP_CIPHER_CTX *ctx = NULL; |
90 | EVP_CIPHER *cipher = NULL; | |
91 | unsigned char ct_buf[256] = { 0 }; | |
92 | unsigned char pt_buf[256] = { 0 }; | |
93 | ||
47c239c6 | 94 | OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_CIPHER, t->base.desc); |
36fc5fc6 SL |
95 | |
96 | ctx = EVP_CIPHER_CTX_new(); | |
97 | if (ctx == NULL) | |
980a880e | 98 | goto err; |
3fed2718 | 99 | cipher = EVP_CIPHER_fetch(libctx, t->base.algorithm, NULL); |
36fc5fc6 | 100 | if (cipher == NULL) |
980a880e | 101 | goto err; |
36fc5fc6 SL |
102 | |
103 | /* Encrypt plain text message */ | |
3fed2718 SL |
104 | if ((t->mode & CIPHER_MODE_ENCRYPT) != 0) { |
105 | if (!cipher_init(ctx, cipher, t, encrypt) | |
106 | || !EVP_CipherUpdate(ctx, ct_buf, &len, t->base.pt, | |
107 | t->base.pt_len) | |
108 | || !EVP_CipherFinal_ex(ctx, ct_buf + len, &ct_len)) | |
109 | goto err; | |
36fc5fc6 | 110 | |
3fed2718 SL |
111 | OSSL_SELF_TEST_oncorrupt_byte(st, ct_buf); |
112 | ct_len += len; | |
113 | if (ct_len != (int)t->base.expected_len | |
114 | || memcmp(t->base.expected, ct_buf, ct_len) != 0) | |
115 | goto err; | |
36fc5fc6 | 116 | |
3fed2718 SL |
117 | if (t->tag != NULL) { |
118 | unsigned char tag[16] = { 0 }; | |
36fc5fc6 | 119 | |
3fed2718 SL |
120 | if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, t->tag_len, |
121 | tag) | |
122 | || memcmp(tag, t->tag, t->tag_len) != 0) | |
123 | goto err; | |
124 | } | |
36fc5fc6 SL |
125 | } |
126 | ||
3fed2718 SL |
127 | /* Decrypt cipher text */ |
128 | if ((t->mode & CIPHER_MODE_DECRYPT) != 0) { | |
129 | if (!(cipher_init(ctx, cipher, t, !encrypt) | |
130 | && EVP_CipherUpdate(ctx, pt_buf, &len, | |
131 | t->base.expected, t->base.expected_len) | |
132 | && EVP_CipherFinal_ex(ctx, pt_buf + len, &pt_len))) | |
133 | goto err; | |
134 | OSSL_SELF_TEST_oncorrupt_byte(st, pt_buf); | |
135 | pt_len += len; | |
136 | if (pt_len != (int)t->base.pt_len | |
137 | || memcmp(pt_buf, t->base.pt, pt_len) != 0) | |
138 | goto err; | |
139 | } | |
36fc5fc6 SL |
140 | |
141 | ret = 1; | |
980a880e | 142 | err: |
36fc5fc6 SL |
143 | EVP_CIPHER_free(cipher); |
144 | EVP_CIPHER_CTX_free(ctx); | |
47c239c6 | 145 | OSSL_SELF_TEST_onend(st, ret); |
36fc5fc6 SL |
146 | return ret; |
147 | } | |
148 | ||
ec4d1b8f SL |
149 | static int add_params(OSSL_PARAM_BLD *bld, const ST_KAT_PARAM *params, |
150 | BN_CTX *ctx) | |
151 | { | |
152 | int ret = 0; | |
153 | const ST_KAT_PARAM *p; | |
154 | ||
155 | if (params == NULL) | |
156 | return 1; | |
157 | for (p = params; p->data != NULL; ++p) | |
158 | { | |
159 | switch (p->type) { | |
160 | case OSSL_PARAM_UNSIGNED_INTEGER: { | |
161 | BIGNUM *bn = BN_CTX_get(ctx); | |
162 | ||
163 | if (bn == NULL | |
164 | || (BN_bin2bn(p->data, p->data_len, bn) == NULL) | |
165 | || !OSSL_PARAM_BLD_push_BN(bld, p->name, bn)) | |
166 | goto err; | |
167 | break; | |
168 | } | |
169 | case OSSL_PARAM_UTF8_STRING: { | |
a8eb71ad RL |
170 | if (!OSSL_PARAM_BLD_push_utf8_string(bld, p->name, p->data, |
171 | p->data_len)) | |
ec4d1b8f SL |
172 | goto err; |
173 | break; | |
174 | } | |
175 | case OSSL_PARAM_OCTET_STRING: { | |
176 | if (!OSSL_PARAM_BLD_push_octet_string(bld, p->name, p->data, | |
177 | p->data_len)) | |
178 | goto err; | |
179 | break; | |
180 | } | |
acd3e548 SL |
181 | case OSSL_PARAM_INTEGER: { |
182 | if (!OSSL_PARAM_BLD_push_int(bld, p->name, *(int *)p->data)) | |
183 | goto err; | |
184 | break; | |
185 | } | |
ec4d1b8f SL |
186 | default: |
187 | break; | |
188 | } | |
189 | } | |
190 | ret = 1; | |
191 | err: | |
192 | return ret; | |
193 | } | |
194 | ||
47c239c6 | 195 | static int self_test_kdf(const ST_KAT_KDF *t, OSSL_SELF_TEST *st, |
b4250010 | 196 | OSSL_LIB_CTX *libctx) |
36fc5fc6 SL |
197 | { |
198 | int ret = 0; | |
acd3e548 | 199 | unsigned char out[128]; |
36fc5fc6 SL |
200 | EVP_KDF *kdf = NULL; |
201 | EVP_KDF_CTX *ctx = NULL; | |
ec4d1b8f SL |
202 | BN_CTX *bnctx = NULL; |
203 | OSSL_PARAM *params = NULL; | |
204 | OSSL_PARAM_BLD *bld = NULL; | |
36fc5fc6 | 205 | |
47c239c6 | 206 | OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_KDF, t->desc); |
36fc5fc6 | 207 | |
ec4d1b8f SL |
208 | bld = OSSL_PARAM_BLD_new(); |
209 | if (bld == NULL) | |
210 | goto err; | |
d5e66eab | 211 | |
36fc5fc6 | 212 | kdf = EVP_KDF_fetch(libctx, t->algorithm, ""); |
ec4d1b8f SL |
213 | if (kdf == NULL) |
214 | goto err; | |
215 | ||
660c5344 | 216 | ctx = EVP_KDF_CTX_new(kdf); |
36fc5fc6 | 217 | if (ctx == NULL) |
980a880e | 218 | goto err; |
36fc5fc6 | 219 | |
ec4d1b8f SL |
220 | bnctx = BN_CTX_new_ex(libctx); |
221 | if (bnctx == NULL) | |
222 | goto err; | |
223 | if (!add_params(bld, t->params, bnctx)) | |
224 | goto err; | |
225 | params = OSSL_PARAM_BLD_to_param(bld); | |
226 | if (params == NULL) | |
227 | goto err; | |
36fc5fc6 SL |
228 | |
229 | if (t->expected_len > sizeof(out)) | |
980a880e | 230 | goto err; |
6bcd32a4 | 231 | if (EVP_KDF_derive(ctx, out, t->expected_len, params) <= 0) |
980a880e | 232 | goto err; |
36fc5fc6 | 233 | |
47c239c6 | 234 | OSSL_SELF_TEST_oncorrupt_byte(st, out); |
36fc5fc6 SL |
235 | |
236 | if (memcmp(out, t->expected, t->expected_len) != 0) | |
980a880e | 237 | goto err; |
36fc5fc6 SL |
238 | |
239 | ret = 1; | |
980a880e | 240 | err: |
36fc5fc6 | 241 | EVP_KDF_free(kdf); |
660c5344 | 242 | EVP_KDF_CTX_free(ctx); |
ec4d1b8f | 243 | BN_CTX_free(bnctx); |
3f883c7c | 244 | OSSL_PARAM_free(params); |
ec4d1b8f | 245 | OSSL_PARAM_BLD_free(bld); |
47c239c6 | 246 | OSSL_SELF_TEST_onend(st, ret); |
36fc5fc6 SL |
247 | return ret; |
248 | } | |
249 | ||
47c239c6 | 250 | static int self_test_drbg(const ST_KAT_DRBG *t, OSSL_SELF_TEST *st, |
b4250010 | 251 | OSSL_LIB_CTX *libctx) |
980a880e SL |
252 | { |
253 | int ret = 0; | |
254 | unsigned char out[256]; | |
6154f9a7 P |
255 | EVP_RAND *rand; |
256 | EVP_RAND_CTX *test = NULL, *drbg = NULL; | |
257 | unsigned int strength = 256; | |
980a880e SL |
258 | int prediction_resistance = 1; /* Causes a reseed */ |
259 | OSSL_PARAM drbg_params[3] = { | |
260 | OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END | |
261 | }; | |
262 | ||
47c239c6 | 263 | OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_DRBG, t->desc); |
980a880e | 264 | |
6154f9a7 P |
265 | rand = EVP_RAND_fetch(libctx, "TEST-RAND", NULL); |
266 | if (rand == NULL) | |
267 | goto err; | |
980a880e | 268 | |
6154f9a7 P |
269 | test = EVP_RAND_CTX_new(rand, NULL); |
270 | EVP_RAND_free(rand); | |
271 | if (test == NULL) | |
980a880e SL |
272 | goto err; |
273 | ||
6154f9a7 P |
274 | drbg_params[0] = OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_STRENGTH, |
275 | &strength); | |
e494fac7 | 276 | if (!EVP_RAND_CTX_set_params(test, drbg_params)) |
980a880e SL |
277 | goto err; |
278 | ||
6154f9a7 P |
279 | rand = EVP_RAND_fetch(libctx, t->algorithm, NULL); |
280 | if (rand == NULL) | |
281 | goto err; | |
282 | ||
283 | drbg = EVP_RAND_CTX_new(rand, test); | |
284 | EVP_RAND_free(rand); | |
285 | if (drbg == NULL) | |
286 | goto err; | |
287 | ||
288 | strength = EVP_RAND_strength(drbg); | |
289 | ||
290 | drbg_params[0] = OSSL_PARAM_construct_utf8_string(t->param_name, | |
291 | t->param_value, 0); | |
292 | /* This is only used by HMAC-DRBG but it is ignored by the others */ | |
293 | drbg_params[1] = | |
294 | OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_MAC, "HMAC", 0); | |
e494fac7 | 295 | if (!EVP_RAND_CTX_set_params(drbg, drbg_params)) |
980a880e SL |
296 | goto err; |
297 | ||
298 | drbg_params[0] = | |
6154f9a7 P |
299 | OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_ENTROPY, |
300 | (void *)t->entropyin, | |
301 | t->entropyinlen); | |
980a880e | 302 | drbg_params[1] = |
6154f9a7 | 303 | OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_NONCE, |
980a880e | 304 | (void *)t->nonce, t->noncelen); |
8d5b197b | 305 | if (!EVP_RAND_instantiate(test, strength, 0, NULL, 0, drbg_params)) |
6154f9a7 | 306 | goto err; |
8d5b197b P |
307 | if (!EVP_RAND_instantiate(drbg, strength, 0, t->persstr, t->persstrlen, |
308 | NULL)) | |
980a880e SL |
309 | goto err; |
310 | ||
311 | drbg_params[0] = | |
6154f9a7 | 312 | OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_ENTROPY, |
980a880e SL |
313 | (void *)t->entropyinpr1, |
314 | t->entropyinpr1len); | |
e494fac7 | 315 | if (!EVP_RAND_CTX_set_params(test, drbg_params)) |
6154f9a7 | 316 | goto err; |
980a880e | 317 | |
6154f9a7 P |
318 | if (!EVP_RAND_generate(drbg, out, t->expectedlen, strength, |
319 | prediction_resistance, | |
320 | t->entropyaddin1, t->entropyaddin1len)) | |
980a880e SL |
321 | goto err; |
322 | ||
323 | drbg_params[0] = | |
6154f9a7 | 324 | OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_ENTROPY, |
980a880e SL |
325 | (void *)t->entropyinpr2, |
326 | t->entropyinpr2len); | |
e494fac7 | 327 | if (!EVP_RAND_CTX_set_params(test, drbg_params)) |
6154f9a7 P |
328 | goto err; |
329 | ||
7d6766cb P |
330 | /* |
331 | * This calls ossl_prov_drbg_reseed() internally when | |
332 | * prediction_resistance = 1 | |
333 | */ | |
6154f9a7 P |
334 | if (!EVP_RAND_generate(drbg, out, t->expectedlen, strength, |
335 | prediction_resistance, | |
336 | t->entropyaddin2, t->entropyaddin2len)) | |
980a880e SL |
337 | goto err; |
338 | ||
47c239c6 | 339 | OSSL_SELF_TEST_oncorrupt_byte(st, out); |
980a880e SL |
340 | |
341 | if (memcmp(out, t->expected, t->expectedlen) != 0) | |
342 | goto err; | |
343 | ||
6154f9a7 | 344 | if (!EVP_RAND_uninstantiate(drbg)) |
980a880e SL |
345 | goto err; |
346 | /* | |
7d6766cb P |
347 | * Check that the DRBG data has been zeroized after |
348 | * ossl_prov_drbg_uninstantiate. | |
980a880e | 349 | */ |
6154f9a7 | 350 | if (!EVP_RAND_verify_zeroization(drbg)) |
e7045215 DMSP |
351 | goto err; |
352 | ||
980a880e SL |
353 | ret = 1; |
354 | err: | |
6154f9a7 P |
355 | EVP_RAND_CTX_free(drbg); |
356 | EVP_RAND_CTX_free(test); | |
47c239c6 | 357 | OSSL_SELF_TEST_onend(st, ret); |
980a880e SL |
358 | return ret; |
359 | } | |
360 | ||
cbb85bda | 361 | #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC) |
ec4d1b8f | 362 | static int self_test_ka(const ST_KAT_KAS *t, |
b4250010 | 363 | OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) |
ec4d1b8f SL |
364 | { |
365 | int ret = 0; | |
366 | EVP_PKEY_CTX *kactx = NULL, *dctx = NULL; | |
367 | EVP_PKEY *pkey = NULL, *peerkey = NULL; | |
368 | OSSL_PARAM *params = NULL; | |
369 | OSSL_PARAM *params_peer = NULL; | |
370 | unsigned char secret[256]; | |
6d9a54c6 | 371 | size_t secret_len = sizeof(secret); |
ec4d1b8f SL |
372 | OSSL_PARAM_BLD *bld = NULL; |
373 | BN_CTX *bnctx = NULL; | |
374 | ||
375 | OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_KA, t->desc); | |
376 | ||
377 | bnctx = BN_CTX_new_ex(libctx); | |
378 | if (bnctx == NULL) | |
379 | goto err; | |
380 | ||
381 | bld = OSSL_PARAM_BLD_new(); | |
382 | if (bld == NULL) | |
383 | goto err; | |
384 | ||
385 | if (!add_params(bld, t->key_group, bnctx) | |
386 | || !add_params(bld, t->key_host_data, bnctx)) | |
387 | goto err; | |
388 | params = OSSL_PARAM_BLD_to_param(bld); | |
389 | ||
390 | if (!add_params(bld, t->key_group, bnctx) | |
391 | || !add_params(bld, t->key_peer_data, bnctx)) | |
392 | goto err; | |
393 | ||
394 | params_peer = OSSL_PARAM_BLD_to_param(bld); | |
395 | if (params == NULL || params_peer == NULL) | |
396 | goto err; | |
397 | ||
398 | /* Create a EVP_PKEY_CTX to load the DH keys into */ | |
399 | kactx = EVP_PKEY_CTX_new_from_name(libctx, t->algorithm, ""); | |
400 | if (kactx == NULL) | |
401 | goto err; | |
2db985b7 SL |
402 | if (EVP_PKEY_fromdata_init(kactx) <= 0 |
403 | || EVP_PKEY_fromdata(kactx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0) | |
ec4d1b8f | 404 | goto err; |
2db985b7 SL |
405 | if (EVP_PKEY_fromdata_init(kactx) <= 0 |
406 | || EVP_PKEY_fromdata(kactx, &peerkey, EVP_PKEY_KEYPAIR, params_peer) <= 0) | |
ec4d1b8f SL |
407 | goto err; |
408 | ||
409 | /* Create a EVP_PKEY_CTX to perform key derivation */ | |
410 | dctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, NULL); | |
411 | if (dctx == NULL) | |
412 | goto err; | |
413 | ||
414 | if (EVP_PKEY_derive_init(dctx) <= 0 | |
415 | || EVP_PKEY_derive_set_peer(dctx, peerkey) <= 0 | |
416 | || EVP_PKEY_derive(dctx, secret, &secret_len) <= 0) | |
417 | goto err; | |
418 | ||
419 | OSSL_SELF_TEST_oncorrupt_byte(st, secret); | |
420 | ||
421 | if (secret_len != t->expected_len | |
422 | || memcmp(secret, t->expected, t->expected_len) != 0) | |
423 | goto err; | |
424 | ret = 1; | |
425 | err: | |
426 | BN_CTX_free(bnctx); | |
427 | EVP_PKEY_free(pkey); | |
428 | EVP_PKEY_free(peerkey); | |
429 | EVP_PKEY_CTX_free(kactx); | |
430 | EVP_PKEY_CTX_free(dctx); | |
3f883c7c SL |
431 | OSSL_PARAM_free(params_peer); |
432 | OSSL_PARAM_free(params); | |
ec4d1b8f SL |
433 | OSSL_PARAM_BLD_free(bld); |
434 | OSSL_SELF_TEST_onend(st, ret); | |
435 | return ret; | |
436 | } | |
cbb85bda | 437 | #endif /* !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC) */ |
ec4d1b8f SL |
438 | |
439 | static int self_test_sign(const ST_KAT_SIGN *t, | |
b4250010 | 440 | OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) |
ec4d1b8f SL |
441 | { |
442 | int ret = 0; | |
443 | OSSL_PARAM *params = NULL, *params_sig = NULL; | |
444 | OSSL_PARAM_BLD *bld = NULL; | |
445 | EVP_PKEY_CTX *sctx = NULL, *kctx = NULL; | |
446 | EVP_PKEY *pkey = NULL; | |
447 | unsigned char sig[256]; | |
448 | BN_CTX *bnctx = NULL; | |
449 | size_t siglen = 0; | |
450 | static const unsigned char dgst[] = { | |
451 | 0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81, | |
452 | 0x48, 0xa1, 0xd6, 0x5d, 0xfc, 0x2d, 0x4b, 0x1f, 0xa3, 0xd6, 0x77, 0x28, | |
453 | 0x4a, 0xdd, 0xd2, 0x00, 0x12, 0x6d, 0x90, 0x69 | |
454 | }; | |
455 | ||
456 | OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_SIGNATURE, t->desc); | |
457 | ||
458 | bnctx = BN_CTX_new_ex(libctx); | |
459 | if (bnctx == NULL) | |
460 | goto err; | |
461 | ||
462 | bld = OSSL_PARAM_BLD_new(); | |
463 | if (bld == NULL) | |
464 | goto err; | |
465 | ||
466 | if (!add_params(bld, t->key, bnctx)) | |
467 | goto err; | |
468 | params = OSSL_PARAM_BLD_to_param(bld); | |
469 | ||
470 | /* Create a EVP_PKEY_CTX to load the DSA key into */ | |
471 | kctx = EVP_PKEY_CTX_new_from_name(libctx, t->algorithm, ""); | |
472 | if (kctx == NULL || params == NULL) | |
473 | goto err; | |
2db985b7 SL |
474 | if (EVP_PKEY_fromdata_init(kctx) <= 0 |
475 | || EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0) | |
ec4d1b8f SL |
476 | goto err; |
477 | ||
478 | /* Create a EVP_PKEY_CTX to use for the signing operation */ | |
479 | sctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, NULL); | |
480 | if (sctx == NULL | |
481 | || EVP_PKEY_sign_init(sctx) <= 0) | |
482 | goto err; | |
483 | ||
484 | /* set signature parameters */ | |
485 | if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_SIGNATURE_PARAM_DIGEST, | |
486 | t->mdalgorithm, | |
487 | strlen(t->mdalgorithm) + 1)) | |
488 | goto err; | |
489 | params_sig = OSSL_PARAM_BLD_to_param(bld); | |
490 | if (EVP_PKEY_CTX_set_params(sctx, params_sig) <= 0) | |
491 | goto err; | |
492 | ||
493 | if (EVP_PKEY_sign(sctx, sig, &siglen, dgst, sizeof(dgst)) <= 0 | |
494 | || EVP_PKEY_verify_init(sctx) <= 0 | |
495 | || EVP_PKEY_CTX_set_params(sctx, params_sig) <= 0) | |
496 | goto err; | |
497 | ||
498 | /* | |
499 | * Used by RSA, for other key types where the signature changes, we | |
500 | * can only use the verify. | |
501 | */ | |
502 | if (t->sig_expected != NULL | |
503 | && (siglen != t->sig_expected_len | |
504 | || memcmp(sig, t->sig_expected, t->sig_expected_len) != 0)) | |
505 | goto err; | |
506 | ||
507 | OSSL_SELF_TEST_oncorrupt_byte(st, sig); | |
508 | if (EVP_PKEY_verify(sctx, sig, siglen, dgst, sizeof(dgst)) <= 0) | |
509 | goto err; | |
510 | ret = 1; | |
511 | err: | |
512 | BN_CTX_free(bnctx); | |
513 | EVP_PKEY_free(pkey); | |
514 | EVP_PKEY_CTX_free(kctx); | |
515 | EVP_PKEY_CTX_free(sctx); | |
3f883c7c SL |
516 | OSSL_PARAM_free(params); |
517 | OSSL_PARAM_free(params_sig); | |
ec4d1b8f SL |
518 | OSSL_PARAM_BLD_free(bld); |
519 | OSSL_SELF_TEST_onend(st, ret); | |
520 | return ret; | |
521 | } | |
522 | ||
4343a418 SL |
523 | /* |
524 | * Test an encrypt or decrypt KAT.. | |
525 | * | |
526 | * FIPS 140-2 IG D.9 states that separate KAT tests are needed for encrypt | |
527 | * and decrypt.. | |
528 | */ | |
529 | static int self_test_asym_cipher(const ST_KAT_ASYM_CIPHER *t, OSSL_SELF_TEST *st, | |
b4250010 | 530 | OSSL_LIB_CTX *libctx) |
4343a418 SL |
531 | { |
532 | int ret = 0; | |
533 | OSSL_PARAM *keyparams = NULL, *initparams = NULL; | |
534 | OSSL_PARAM_BLD *keybld = NULL, *initbld = NULL; | |
535 | EVP_PKEY_CTX *encctx = NULL, *keyctx = NULL; | |
536 | EVP_PKEY *key = NULL; | |
537 | BN_CTX *bnctx = NULL; | |
538 | unsigned char out[256]; | |
539 | size_t outlen = sizeof(out); | |
540 | ||
541 | OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_ASYM_CIPHER, t->desc); | |
542 | ||
543 | bnctx = BN_CTX_new_ex(libctx); | |
544 | if (bnctx == NULL) | |
545 | goto err; | |
546 | ||
547 | /* Load a public or private key from data */ | |
548 | keybld = OSSL_PARAM_BLD_new(); | |
549 | if (keybld == NULL | |
550 | || !add_params(keybld, t->key, bnctx)) | |
551 | goto err; | |
552 | keyparams = OSSL_PARAM_BLD_to_param(keybld); | |
553 | keyctx = EVP_PKEY_CTX_new_from_name(libctx, t->algorithm, NULL); | |
554 | if (keyctx == NULL || keyparams == NULL) | |
555 | goto err; | |
2db985b7 SL |
556 | if (EVP_PKEY_fromdata_init(keyctx) <= 0 |
557 | || EVP_PKEY_fromdata(keyctx, &key, EVP_PKEY_KEYPAIR, keyparams) <= 0) | |
4343a418 SL |
558 | goto err; |
559 | ||
560 | /* Create a EVP_PKEY_CTX to use for the encrypt or decrypt operation */ | |
561 | encctx = EVP_PKEY_CTX_new_from_pkey(libctx, key, NULL); | |
562 | if (encctx == NULL | |
563 | || (t->encrypt && EVP_PKEY_encrypt_init(encctx) <= 0) | |
564 | || (!t->encrypt && EVP_PKEY_decrypt_init(encctx) <= 0)) | |
565 | goto err; | |
566 | ||
567 | /* Add any additional parameters such as padding */ | |
568 | if (t->postinit != NULL) { | |
569 | initbld = OSSL_PARAM_BLD_new(); | |
570 | if (initbld == NULL) | |
571 | goto err; | |
572 | if (!add_params(initbld, t->postinit, bnctx)) | |
573 | goto err; | |
574 | initparams = OSSL_PARAM_BLD_to_param(initbld); | |
575 | if (initparams == NULL) | |
576 | goto err; | |
577 | if (EVP_PKEY_CTX_set_params(encctx, initparams) <= 0) | |
578 | goto err; | |
579 | } | |
580 | ||
581 | if (t->encrypt) { | |
582 | if (EVP_PKEY_encrypt(encctx, out, &outlen, | |
583 | t->in, t->in_len) <= 0) | |
584 | goto err; | |
585 | } else { | |
586 | if (EVP_PKEY_decrypt(encctx, out, &outlen, | |
587 | t->in, t->in_len) <= 0) | |
588 | goto err; | |
589 | } | |
590 | /* Check the KAT */ | |
591 | OSSL_SELF_TEST_oncorrupt_byte(st, out); | |
592 | if (outlen != t->expected_len | |
593 | || memcmp(out, t->expected, t->expected_len) != 0) | |
594 | goto err; | |
595 | ||
596 | ret = 1; | |
597 | err: | |
598 | BN_CTX_free(bnctx); | |
599 | EVP_PKEY_free(key); | |
600 | EVP_PKEY_CTX_free(encctx); | |
601 | EVP_PKEY_CTX_free(keyctx); | |
3f883c7c | 602 | OSSL_PARAM_free(keyparams); |
4343a418 | 603 | OSSL_PARAM_BLD_free(keybld); |
3f883c7c | 604 | OSSL_PARAM_free(initparams); |
4343a418 SL |
605 | OSSL_PARAM_BLD_free(initbld); |
606 | OSSL_SELF_TEST_onend(st, ret); | |
607 | return ret; | |
608 | } | |
609 | ||
36fc5fc6 SL |
610 | /* |
611 | * Test a data driven list of KAT's for digest algorithms. | |
612 | * All tests are run regardless of if they fail or not. | |
613 | * Return 0 if any test fails. | |
614 | */ | |
b4250010 | 615 | static int self_test_digests(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) |
36fc5fc6 SL |
616 | { |
617 | int i, ret = 1; | |
618 | ||
619 | for (i = 0; i < (int)OSSL_NELEM(st_kat_digest_tests); ++i) { | |
47c239c6 | 620 | if (!self_test_digest(&st_kat_digest_tests[i], st, libctx)) |
36fc5fc6 SL |
621 | ret = 0; |
622 | } | |
623 | return ret; | |
624 | } | |
625 | ||
b4250010 | 626 | static int self_test_ciphers(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) |
36fc5fc6 SL |
627 | { |
628 | int i, ret = 1; | |
629 | ||
630 | for (i = 0; i < (int)OSSL_NELEM(st_kat_cipher_tests); ++i) { | |
47c239c6 | 631 | if (!self_test_cipher(&st_kat_cipher_tests[i], st, libctx)) |
36fc5fc6 SL |
632 | ret = 0; |
633 | } | |
634 | return ret; | |
635 | } | |
636 | ||
b4250010 | 637 | static int self_test_asym_ciphers(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) |
4343a418 SL |
638 | { |
639 | int i, ret = 1; | |
640 | ||
641 | for (i = 0; i < (int)OSSL_NELEM(st_kat_asym_cipher_tests); ++i) { | |
642 | if (!self_test_asym_cipher(&st_kat_asym_cipher_tests[i], st, libctx)) | |
643 | ret = 0; | |
644 | } | |
645 | return ret; | |
646 | } | |
647 | ||
b4250010 | 648 | static int self_test_kdfs(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) |
36fc5fc6 SL |
649 | { |
650 | int i, ret = 1; | |
651 | ||
652 | for (i = 0; i < (int)OSSL_NELEM(st_kat_kdf_tests); ++i) { | |
47c239c6 | 653 | if (!self_test_kdf(&st_kat_kdf_tests[i], st, libctx)) |
36fc5fc6 SL |
654 | ret = 0; |
655 | } | |
656 | return ret; | |
657 | } | |
658 | ||
b4250010 | 659 | static int self_test_drbgs(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) |
980a880e SL |
660 | { |
661 | int i, ret = 1; | |
662 | ||
663 | for (i = 0; i < (int)OSSL_NELEM(st_kat_drbg_tests); ++i) { | |
47c239c6 | 664 | if (!self_test_drbg(&st_kat_drbg_tests[i], st, libctx)) |
980a880e SL |
665 | ret = 0; |
666 | } | |
667 | return ret; | |
668 | } | |
669 | ||
b4250010 | 670 | static int self_test_kas(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) |
ec4d1b8f | 671 | { |
cbb85bda MC |
672 | int ret = 1; |
673 | #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC) | |
674 | int i; | |
ec4d1b8f SL |
675 | |
676 | for (i = 0; i < (int)OSSL_NELEM(st_kat_kas_tests); ++i) { | |
677 | if (!self_test_ka(&st_kat_kas_tests[i], st, libctx)) | |
678 | ret = 0; | |
679 | } | |
cbb85bda MC |
680 | #endif |
681 | ||
ec4d1b8f SL |
682 | return ret; |
683 | } | |
684 | ||
b4250010 | 685 | static int self_test_signatures(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) |
ec4d1b8f SL |
686 | { |
687 | int i, ret = 1; | |
688 | ||
689 | for (i = 0; i < (int)OSSL_NELEM(st_kat_sign_tests); ++i) { | |
690 | if (!self_test_sign(&st_kat_sign_tests[i], st, libctx)) | |
691 | ret = 0; | |
692 | } | |
693 | return ret; | |
694 | } | |
695 | ||
36fc5fc6 SL |
696 | /* |
697 | * Run the algorithm KAT's. | |
698 | * Return 1 is successful, otherwise return 0. | |
699 | * This runs all the tests regardless of if any fail. | |
36fc5fc6 | 700 | */ |
b4250010 | 701 | int SELF_TEST_kats(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) |
36fc5fc6 SL |
702 | { |
703 | int ret = 1; | |
704 | ||
47c239c6 | 705 | if (!self_test_digests(st, libctx)) |
36fc5fc6 | 706 | ret = 0; |
47c239c6 | 707 | if (!self_test_ciphers(st, libctx)) |
36fc5fc6 | 708 | ret = 0; |
ec4d1b8f SL |
709 | if (!self_test_signatures(st, libctx)) |
710 | ret = 0; | |
47c239c6 | 711 | if (!self_test_kdfs(st, libctx)) |
36fc5fc6 | 712 | ret = 0; |
47c239c6 | 713 | if (!self_test_drbgs(st, libctx)) |
980a880e | 714 | ret = 0; |
ec4d1b8f SL |
715 | if (!self_test_kas(st, libctx)) |
716 | ret = 0; | |
4343a418 SL |
717 | if (!self_test_asym_ciphers(st, libctx)) |
718 | ret = 0; | |
36fc5fc6 SL |
719 | |
720 | return ret; | |
721 | } |