xref: /openssl/providers/fips/self_test_kats.c (revision 7ed6de99)
1 /*
2  * Copyright 2019-2024 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 #include <string.h>
11 #include <openssl/evp.h>
12 #include <openssl/kdf.h>
13 #include <openssl/core_names.h>
14 #include <openssl/param_build.h>
15 #include <openssl/rand.h>
16 #include "crypto/rand.h"
17 #include "internal/cryptlib.h"
18 #include "internal/nelem.h"
19 #include "self_test.h"
20 #include "self_test_data.inc"
21 
22 static int set_kat_drbg(OSSL_LIB_CTX *ctx,
23                         const unsigned char *entropy, size_t entropy_len,
24                         const unsigned char *nonce, size_t nonce_len,
25                         const unsigned char *persstr, size_t persstr_len);
26 static int reset_main_drbg(OSSL_LIB_CTX *ctx);
27 
self_test_digest(const ST_KAT_DIGEST * t,OSSL_SELF_TEST * st,OSSL_LIB_CTX * libctx)28 static int self_test_digest(const ST_KAT_DIGEST *t, OSSL_SELF_TEST *st,
29                             OSSL_LIB_CTX *libctx)
30 {
31     int ok = 0;
32     unsigned char out[EVP_MAX_MD_SIZE];
33     unsigned int out_len = 0;
34     EVP_MD_CTX *ctx = EVP_MD_CTX_new();
35     EVP_MD *md = EVP_MD_fetch(libctx, t->algorithm, NULL);
36 
37     OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_DIGEST, t->desc);
38 
39     if (ctx == NULL
40             || md == NULL
41             || !EVP_DigestInit_ex(ctx, md, NULL)
42             || !EVP_DigestUpdate(ctx, t->pt, t->pt_len)
43             || !EVP_DigestFinal(ctx, out, &out_len))
44         goto err;
45 
46     /* Optional corruption */
47     OSSL_SELF_TEST_oncorrupt_byte(st, out);
48 
49     if (out_len != t->expected_len
50             || memcmp(out, t->expected, out_len) != 0)
51         goto err;
52     ok = 1;
53 err:
54     EVP_MD_free(md);
55     EVP_MD_CTX_free(ctx);
56     OSSL_SELF_TEST_onend(st, ok);
57     return ok;
58 }
59 
60 /*
61  * Helper function to setup a EVP_CipherInit
62  * Used to hide the complexity of Authenticated ciphers.
63  */
cipher_init(EVP_CIPHER_CTX * ctx,const EVP_CIPHER * cipher,const ST_KAT_CIPHER * t,int enc)64 static int cipher_init(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
65                        const ST_KAT_CIPHER *t, int enc)
66 {
67     unsigned char *in_tag = NULL;
68     int pad = 0, tmp;
69 
70     /* Flag required for Key wrapping */
71     EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
72     if (t->tag == NULL) {
73         /* Use a normal cipher init */
74         return EVP_CipherInit_ex(ctx, cipher, NULL, t->key, t->iv, enc)
75                && EVP_CIPHER_CTX_set_padding(ctx, pad);
76     }
77 
78     /* The authenticated cipher init */
79     if (!enc)
80         in_tag = (unsigned char *)t->tag;
81 
82     return EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc)
83            && (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, t->iv_len, NULL) > 0)
84            && (in_tag == NULL
85                || EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, t->tag_len,
86                                       in_tag) > 0)
87            && EVP_CipherInit_ex(ctx, NULL, NULL, t->key, t->iv, enc)
88            && EVP_CIPHER_CTX_set_padding(ctx, pad)
89            && EVP_CipherUpdate(ctx, NULL, &tmp, t->aad, t->aad_len);
90 }
91 
92 /* Test a single KAT for encrypt/decrypt */
self_test_cipher(const ST_KAT_CIPHER * t,OSSL_SELF_TEST * st,OSSL_LIB_CTX * libctx)93 static int self_test_cipher(const ST_KAT_CIPHER *t, OSSL_SELF_TEST *st,
94                             OSSL_LIB_CTX *libctx)
95 {
96     int ret = 0, encrypt = 1, len = 0, ct_len = 0, pt_len = 0;
97     EVP_CIPHER_CTX *ctx = NULL;
98     EVP_CIPHER *cipher = NULL;
99     unsigned char ct_buf[256] = { 0 };
100     unsigned char pt_buf[256] = { 0 };
101 
102     OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_CIPHER, t->base.desc);
103 
104     ctx = EVP_CIPHER_CTX_new();
105     if (ctx == NULL)
106         goto err;
107     cipher = EVP_CIPHER_fetch(libctx, t->base.algorithm, NULL);
108     if (cipher == NULL)
109         goto err;
110 
111     /* Encrypt plain text message */
112     if ((t->mode & CIPHER_MODE_ENCRYPT) != 0) {
113         if (!cipher_init(ctx, cipher, t, encrypt)
114                 || !EVP_CipherUpdate(ctx, ct_buf, &len, t->base.pt,
115                                      t->base.pt_len)
116                 || !EVP_CipherFinal_ex(ctx, ct_buf + len, &ct_len))
117             goto err;
118 
119         OSSL_SELF_TEST_oncorrupt_byte(st, ct_buf);
120         ct_len += len;
121         if (ct_len != (int)t->base.expected_len
122             || memcmp(t->base.expected, ct_buf, ct_len) != 0)
123             goto err;
124 
125         if (t->tag != NULL) {
126             unsigned char tag[16] = { 0 };
127 
128             if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, t->tag_len,
129                                      tag) <= 0
130                 || memcmp(tag, t->tag, t->tag_len) != 0)
131                 goto err;
132         }
133     }
134 
135     /* Decrypt cipher text */
136     if ((t->mode & CIPHER_MODE_DECRYPT) != 0) {
137         if (!(cipher_init(ctx, cipher, t, !encrypt)
138               && EVP_CipherUpdate(ctx, pt_buf, &len,
139                                   t->base.expected, t->base.expected_len)
140               && EVP_CipherFinal_ex(ctx, pt_buf + len, &pt_len)))
141             goto err;
142         OSSL_SELF_TEST_oncorrupt_byte(st, pt_buf);
143         pt_len += len;
144         if (pt_len != (int)t->base.pt_len
145                 || memcmp(pt_buf, t->base.pt, pt_len) != 0)
146             goto err;
147     }
148 
149     ret = 1;
150 err:
151     EVP_CIPHER_free(cipher);
152     EVP_CIPHER_CTX_free(ctx);
153     OSSL_SELF_TEST_onend(st, ret);
154     return ret;
155 }
156 
add_params(OSSL_PARAM_BLD * bld,const ST_KAT_PARAM * params,BN_CTX * ctx)157 static int add_params(OSSL_PARAM_BLD *bld, const ST_KAT_PARAM *params,
158                       BN_CTX *ctx)
159 {
160     int ret = 0;
161     const ST_KAT_PARAM *p;
162 
163     if (params == NULL)
164         return 1;
165     for (p = params; p->data != NULL; ++p) {
166         switch (p->type) {
167         case OSSL_PARAM_UNSIGNED_INTEGER: {
168             BIGNUM *bn = BN_CTX_get(ctx);
169 
170             if (bn == NULL
171                 || (BN_bin2bn(p->data, p->data_len, bn) == NULL)
172                 || !OSSL_PARAM_BLD_push_BN(bld, p->name, bn))
173                 goto err;
174             break;
175         }
176         case OSSL_PARAM_UTF8_STRING: {
177             if (!OSSL_PARAM_BLD_push_utf8_string(bld, p->name, p->data,
178                                                  p->data_len))
179                 goto err;
180             break;
181         }
182         case OSSL_PARAM_OCTET_STRING: {
183             if (!OSSL_PARAM_BLD_push_octet_string(bld, p->name, p->data,
184                                                   p->data_len))
185                 goto err;
186             break;
187         }
188         case OSSL_PARAM_INTEGER: {
189             if (!OSSL_PARAM_BLD_push_int(bld, p->name, *(int *)p->data))
190                 goto err;
191             break;
192         }
193         default:
194             break;
195         }
196     }
197     ret = 1;
198 err:
199     return ret;
200 }
201 
self_test_kdf(const ST_KAT_KDF * t,OSSL_SELF_TEST * st,OSSL_LIB_CTX * libctx)202 static int self_test_kdf(const ST_KAT_KDF *t, OSSL_SELF_TEST *st,
203                          OSSL_LIB_CTX *libctx)
204 {
205     int ret = 0;
206     unsigned char out[128];
207     EVP_KDF *kdf = NULL;
208     EVP_KDF_CTX *ctx = NULL;
209     BN_CTX *bnctx = NULL;
210     OSSL_PARAM *params  = NULL;
211     OSSL_PARAM_BLD *bld = NULL;
212 
213     OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_KDF, t->desc);
214 
215     bld = OSSL_PARAM_BLD_new();
216     if (bld == NULL)
217         goto err;
218 
219     kdf = EVP_KDF_fetch(libctx, t->algorithm, "");
220     if (kdf == NULL)
221         goto err;
222 
223     ctx = EVP_KDF_CTX_new(kdf);
224     if (ctx == NULL)
225         goto err;
226 
227     bnctx = BN_CTX_new_ex(libctx);
228     if (bnctx == NULL)
229         goto err;
230     if (!add_params(bld, t->params, bnctx))
231         goto err;
232     params = OSSL_PARAM_BLD_to_param(bld);
233     if (params == NULL)
234         goto err;
235 
236     if (t->expected_len > sizeof(out))
237         goto err;
238     if (EVP_KDF_derive(ctx, out, t->expected_len, params) <= 0)
239         goto err;
240 
241     OSSL_SELF_TEST_oncorrupt_byte(st, out);
242 
243     if (memcmp(out, t->expected,  t->expected_len) != 0)
244         goto err;
245 
246     ret = 1;
247 err:
248     EVP_KDF_free(kdf);
249     EVP_KDF_CTX_free(ctx);
250     BN_CTX_free(bnctx);
251     OSSL_PARAM_free(params);
252     OSSL_PARAM_BLD_free(bld);
253     OSSL_SELF_TEST_onend(st, ret);
254     return ret;
255 }
256 
self_test_drbg(const ST_KAT_DRBG * t,OSSL_SELF_TEST * st,OSSL_LIB_CTX * libctx)257 static int self_test_drbg(const ST_KAT_DRBG *t, OSSL_SELF_TEST *st,
258                           OSSL_LIB_CTX *libctx)
259 {
260     int ret = 0;
261     unsigned char out[256];
262     EVP_RAND *rand;
263     EVP_RAND_CTX *test = NULL, *drbg = NULL;
264     unsigned int strength = 256;
265     int prediction_resistance = 1; /* Causes a reseed */
266     OSSL_PARAM drbg_params[3] = {
267         OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END
268     };
269 
270     OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_DRBG, t->desc);
271 
272     rand = EVP_RAND_fetch(libctx, "TEST-RAND", NULL);
273     if (rand == NULL)
274         goto err;
275 
276     test = EVP_RAND_CTX_new(rand, NULL);
277     EVP_RAND_free(rand);
278     if (test == NULL)
279         goto err;
280 
281     drbg_params[0] = OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_STRENGTH,
282                                                &strength);
283     if (!EVP_RAND_CTX_set_params(test, drbg_params))
284         goto err;
285 
286     rand = EVP_RAND_fetch(libctx, t->algorithm, NULL);
287     if (rand == NULL)
288         goto err;
289 
290     drbg = EVP_RAND_CTX_new(rand, test);
291     EVP_RAND_free(rand);
292     if (drbg == NULL)
293         goto err;
294 
295     strength = EVP_RAND_get_strength(drbg);
296 
297     drbg_params[0] = OSSL_PARAM_construct_utf8_string(t->param_name,
298                                                       t->param_value, 0);
299     /* This is only used by HMAC-DRBG but it is ignored by the others */
300     drbg_params[1] =
301         OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_MAC, "HMAC", 0);
302     if (!EVP_RAND_CTX_set_params(drbg, drbg_params))
303         goto err;
304 
305     drbg_params[0] =
306         OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_ENTROPY,
307                                           (void *)t->entropyin,
308                                           t->entropyinlen);
309     drbg_params[1] =
310         OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_NONCE,
311                                           (void *)t->nonce, t->noncelen);
312     if (!EVP_RAND_instantiate(test, strength, 0, NULL, 0, drbg_params))
313         goto err;
314     if (!EVP_RAND_instantiate(drbg, strength, 0, t->persstr, t->persstrlen,
315                               NULL))
316         goto err;
317 
318     drbg_params[0] =
319         OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_ENTROPY,
320                                           (void *)t->entropyinpr1,
321                                           t->entropyinpr1len);
322     if (!EVP_RAND_CTX_set_params(test, drbg_params))
323         goto err;
324 
325     if (!EVP_RAND_generate(drbg, out, t->expectedlen, strength,
326                            prediction_resistance,
327                            t->entropyaddin1, t->entropyaddin1len))
328         goto err;
329 
330     drbg_params[0] =
331         OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_ENTROPY,
332                                          (void *)t->entropyinpr2,
333                                          t->entropyinpr2len);
334     if (!EVP_RAND_CTX_set_params(test, drbg_params))
335         goto err;
336 
337     /*
338      * This calls ossl_prov_drbg_reseed() internally when
339      * prediction_resistance = 1
340      */
341     if (!EVP_RAND_generate(drbg, out, t->expectedlen, strength,
342                            prediction_resistance,
343                            t->entropyaddin2, t->entropyaddin2len))
344         goto err;
345 
346     OSSL_SELF_TEST_oncorrupt_byte(st, out);
347 
348     if (memcmp(out, t->expected, t->expectedlen) != 0)
349         goto err;
350 
351     if (!EVP_RAND_uninstantiate(drbg))
352         goto err;
353     /*
354      * Check that the DRBG data has been zeroized after
355      * ossl_prov_drbg_uninstantiate.
356      */
357     if (!EVP_RAND_verify_zeroization(drbg))
358         goto err;
359 
360     ret = 1;
361 err:
362     EVP_RAND_CTX_free(drbg);
363     EVP_RAND_CTX_free(test);
364     OSSL_SELF_TEST_onend(st, ret);
365     return ret;
366 }
367 
368 #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC)
self_test_ka(const ST_KAT_KAS * t,OSSL_SELF_TEST * st,OSSL_LIB_CTX * libctx)369 static int self_test_ka(const ST_KAT_KAS *t,
370                         OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)
371 {
372     int ret = 0;
373     EVP_PKEY_CTX *kactx = NULL, *dctx = NULL;
374     EVP_PKEY *pkey = NULL, *peerkey = NULL;
375     OSSL_PARAM *params = NULL;
376     OSSL_PARAM *params_peer = NULL;
377     unsigned char secret[256];
378     size_t secret_len = t->expected_len;
379     OSSL_PARAM_BLD *bld = NULL;
380     BN_CTX *bnctx = NULL;
381 
382     OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_KA, t->desc);
383 
384     if (secret_len > sizeof(secret))
385         goto err;
386 
387     bnctx = BN_CTX_new_ex(libctx);
388     if (bnctx == NULL)
389         goto err;
390 
391     bld = OSSL_PARAM_BLD_new();
392     if (bld == NULL)
393         goto err;
394 
395     if (!add_params(bld, t->key_group, bnctx)
396         || !add_params(bld, t->key_host_data, bnctx))
397         goto err;
398     params = OSSL_PARAM_BLD_to_param(bld);
399 
400     if (!add_params(bld, t->key_group, bnctx)
401         || !add_params(bld, t->key_peer_data, bnctx))
402         goto err;
403 
404     params_peer = OSSL_PARAM_BLD_to_param(bld);
405     if (params == NULL || params_peer == NULL)
406         goto err;
407 
408     /* Create a EVP_PKEY_CTX to load the DH keys into */
409     kactx = EVP_PKEY_CTX_new_from_name(libctx, t->algorithm, "");
410     if (kactx == NULL)
411         goto err;
412     if (EVP_PKEY_fromdata_init(kactx) <= 0
413         || EVP_PKEY_fromdata(kactx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0)
414         goto err;
415     if (EVP_PKEY_fromdata_init(kactx) <= 0
416         || EVP_PKEY_fromdata(kactx, &peerkey, EVP_PKEY_KEYPAIR, params_peer) <= 0)
417         goto err;
418 
419     /* Create a EVP_PKEY_CTX to perform key derivation */
420     dctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, NULL);
421     if (dctx == NULL)
422         goto err;
423 
424     if (EVP_PKEY_derive_init(dctx) <= 0
425         || EVP_PKEY_derive_set_peer(dctx, peerkey) <= 0
426         || EVP_PKEY_derive(dctx, secret, &secret_len) <= 0)
427         goto err;
428 
429     OSSL_SELF_TEST_oncorrupt_byte(st, secret);
430 
431     if (secret_len != t->expected_len
432         || memcmp(secret, t->expected, t->expected_len) != 0)
433         goto err;
434     ret = 1;
435 err:
436     BN_CTX_free(bnctx);
437     EVP_PKEY_free(pkey);
438     EVP_PKEY_free(peerkey);
439     EVP_PKEY_CTX_free(kactx);
440     EVP_PKEY_CTX_free(dctx);
441     OSSL_PARAM_free(params_peer);
442     OSSL_PARAM_free(params);
443     OSSL_PARAM_BLD_free(bld);
444     OSSL_SELF_TEST_onend(st, ret);
445     return ret;
446 }
447 #endif /* !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC) */
448 
self_test_digest_sign(const ST_KAT_SIGN * t,OSSL_SELF_TEST * st,OSSL_LIB_CTX * libctx)449 static int self_test_digest_sign(const ST_KAT_SIGN *t,
450                                  OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)
451 {
452     int ret = 0;
453     OSSL_PARAM *paramskey = NULL, *paramsinit = NULL;
454     OSSL_PARAM_BLD *bldkey = NULL, *bldinit = NULL;
455     EVP_MD_CTX *mctx = NULL;
456     EVP_PKEY_CTX *fromctx = NULL;
457     EVP_PKEY *pkey = NULL;
458     unsigned char sig[256];
459     BN_CTX *bnctx = NULL;
460     size_t siglen = sizeof(sig);
461     int oneshot = 0;
462     const char *typ = OSSL_SELF_TEST_TYPE_KAT_SIGNATURE;
463 
464     if (t->sig_expected == NULL)
465         typ = OSSL_SELF_TEST_TYPE_PCT_SIGNATURE;
466 
467     OSSL_SELF_TEST_onbegin(st, typ, t->desc);
468 
469     if (t->entropy != NULL) {
470         if (!set_kat_drbg(libctx, t->entropy, t->entropy_len,
471                           t->nonce, t->nonce_len, t->persstr, t->persstr_len))
472             goto err;
473     }
474 
475     bnctx = BN_CTX_new_ex(libctx);
476     if (bnctx == NULL)
477         goto err;
478 
479     bldkey = OSSL_PARAM_BLD_new();
480     bldinit = OSSL_PARAM_BLD_new();
481     if (bldkey == NULL || bldinit == NULL)
482         goto err;
483 
484     if (!add_params(bldkey, t->key, bnctx))
485         goto err;
486     if (!add_params(bldinit, t->init, bnctx))
487         goto err;
488     paramskey = OSSL_PARAM_BLD_to_param(bldkey);
489     paramsinit = OSSL_PARAM_BLD_to_param(bldinit);
490 
491     fromctx = EVP_PKEY_CTX_new_from_name(libctx, t->algorithm, "");
492     if (fromctx == NULL
493         || paramskey == NULL
494         || paramsinit == NULL)
495         goto err;
496     if (EVP_PKEY_fromdata_init(fromctx) <= 0
497         || EVP_PKEY_fromdata(fromctx, &pkey, EVP_PKEY_KEYPAIR, paramskey) <= 0)
498         goto err;
499 
500     mctx = EVP_MD_CTX_new();
501     if (mctx == NULL)
502         goto err;
503 
504     oneshot = ((t->mode & SIGNATURE_MODE_ONESHOT) != 0);
505 
506     if ((t->mode & SIGNATURE_MODE_VERIFY_ONLY) != 0) {
507         memcpy(sig, t->sig_expected, t->sig_expected_len);
508         siglen = t->sig_expected_len;
509     } else {
510         if (EVP_DigestSignInit_ex(mctx, NULL, t->mdalgorithm, libctx, NULL,
511                                   pkey, paramsinit) <= 0)
512             goto err;
513 
514         if (oneshot) {
515             if (EVP_DigestSign(mctx, sig, &siglen, t->msg, t->msg_len) <= 0)
516                 goto err;
517         } else {
518             if (EVP_DigestSignUpdate(mctx, t->msg, t->msg_len) <= 0
519                     || EVP_DigestSignFinal(mctx, sig, &siglen) <= 0)
520                 goto err;
521         }
522 
523         if (t->sig_expected != NULL
524             && (siglen != t->sig_expected_len
525                 || memcmp(sig, t->sig_expected, t->sig_expected_len) != 0))
526             goto err;
527     }
528 
529     if ((t->mode & SIGNATURE_MODE_SIGN_ONLY) == 0) {
530         if (EVP_DigestVerifyInit_ex(mctx, NULL, t->mdalgorithm, libctx, NULL,
531                                     pkey, paramsinit) <= 0)
532             goto err;
533         OSSL_SELF_TEST_oncorrupt_byte(st, sig);
534         if (oneshot) {
535             if (EVP_DigestVerify(mctx, sig, siglen, t->msg, t->msg_len) <= 0)
536                 goto err;
537         } else {
538             if (EVP_DigestVerifyUpdate(mctx, t->msg, t->msg_len) <= 0
539                     || EVP_DigestVerifyFinal(mctx, sig, siglen) <= 0)
540                 goto err;
541         }
542     }
543     ret = 1;
544 err:
545     BN_CTX_free(bnctx);
546     EVP_PKEY_free(pkey);
547     EVP_PKEY_CTX_free(fromctx);
548     EVP_MD_CTX_free(mctx);
549     OSSL_PARAM_free(paramskey);
550     OSSL_PARAM_free(paramsinit);
551     OSSL_PARAM_BLD_free(bldkey);
552     OSSL_PARAM_BLD_free(bldinit);
553     if (t->entropy != NULL) {
554         if (!reset_main_drbg(libctx))
555             ret = 0;
556     }
557     OSSL_SELF_TEST_onend(st, ret);
558     return ret;
559 }
560 
561 /*
562  * Test an encrypt or decrypt KAT..
563  *
564  * FIPS 140-2 IG D.9 states that separate KAT tests are needed for encrypt
565  * and decrypt..
566  */
self_test_asym_cipher(const ST_KAT_ASYM_CIPHER * t,OSSL_SELF_TEST * st,OSSL_LIB_CTX * libctx)567 static int self_test_asym_cipher(const ST_KAT_ASYM_CIPHER *t, OSSL_SELF_TEST *st,
568                                  OSSL_LIB_CTX *libctx)
569 {
570     int ret = 0;
571     OSSL_PARAM *keyparams = NULL, *initparams = NULL;
572     OSSL_PARAM_BLD *keybld = NULL, *initbld = NULL;
573     EVP_PKEY_CTX *encctx = NULL, *keyctx = NULL;
574     EVP_PKEY *key = NULL;
575     BN_CTX *bnctx = NULL;
576     unsigned char out[256];
577     size_t outlen = sizeof(out);
578 
579     OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_ASYM_CIPHER, t->desc);
580 
581     bnctx = BN_CTX_new_ex(libctx);
582     if (bnctx == NULL)
583         goto err;
584 
585     /* Load a public or private key from data */
586     keybld = OSSL_PARAM_BLD_new();
587     if (keybld == NULL
588         || !add_params(keybld, t->key, bnctx))
589         goto err;
590     keyparams = OSSL_PARAM_BLD_to_param(keybld);
591     keyctx = EVP_PKEY_CTX_new_from_name(libctx, t->algorithm, NULL);
592     if (keyctx == NULL || keyparams == NULL)
593         goto err;
594     if (EVP_PKEY_fromdata_init(keyctx) <= 0
595         || EVP_PKEY_fromdata(keyctx, &key, EVP_PKEY_KEYPAIR, keyparams) <= 0)
596         goto err;
597 
598     /* Create a EVP_PKEY_CTX to use for the encrypt or decrypt operation */
599     encctx = EVP_PKEY_CTX_new_from_pkey(libctx, key, NULL);
600     if (encctx == NULL
601         || (t->encrypt && EVP_PKEY_encrypt_init(encctx) <= 0)
602         || (!t->encrypt && EVP_PKEY_decrypt_init(encctx) <= 0))
603         goto err;
604 
605     /* Add any additional parameters such as padding */
606     if (t->postinit != NULL) {
607         initbld = OSSL_PARAM_BLD_new();
608         if (initbld == NULL)
609             goto err;
610         if (!add_params(initbld, t->postinit, bnctx))
611             goto err;
612         initparams = OSSL_PARAM_BLD_to_param(initbld);
613         if (initparams == NULL)
614             goto err;
615         if (EVP_PKEY_CTX_set_params(encctx, initparams) <= 0)
616             goto err;
617     }
618 
619     if (t->encrypt) {
620         if (EVP_PKEY_encrypt(encctx, out, &outlen,
621                              t->in, t->in_len) <= 0)
622             goto err;
623     } else {
624         if (EVP_PKEY_decrypt(encctx, out, &outlen,
625                              t->in, t->in_len) <= 0)
626             goto err;
627     }
628     /* Check the KAT */
629     OSSL_SELF_TEST_oncorrupt_byte(st, out);
630     if (outlen != t->expected_len
631         || memcmp(out, t->expected, t->expected_len) != 0)
632         goto err;
633 
634     ret = 1;
635 err:
636     BN_CTX_free(bnctx);
637     EVP_PKEY_free(key);
638     EVP_PKEY_CTX_free(encctx);
639     EVP_PKEY_CTX_free(keyctx);
640     OSSL_PARAM_free(keyparams);
641     OSSL_PARAM_BLD_free(keybld);
642     OSSL_PARAM_free(initparams);
643     OSSL_PARAM_BLD_free(initbld);
644     OSSL_SELF_TEST_onend(st, ret);
645     return ret;
646 }
647 
648 /*
649  * Test a data driven list of KAT's for digest algorithms.
650  * All tests are run regardless of if they fail or not.
651  * Return 0 if any test fails.
652  */
self_test_digests(OSSL_SELF_TEST * st,OSSL_LIB_CTX * libctx)653 static int self_test_digests(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)
654 {
655     int i, ret = 1;
656 
657     for (i = 0; i < (int)OSSL_NELEM(st_kat_digest_tests); ++i) {
658         if (!self_test_digest(&st_kat_digest_tests[i], st, libctx))
659             ret = 0;
660     }
661     return ret;
662 }
663 
self_test_ciphers(OSSL_SELF_TEST * st,OSSL_LIB_CTX * libctx)664 static int self_test_ciphers(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)
665 {
666     int i, ret = 1;
667 
668     for (i = 0; i < (int)OSSL_NELEM(st_kat_cipher_tests); ++i) {
669         if (!self_test_cipher(&st_kat_cipher_tests[i], st, libctx))
670             ret = 0;
671     }
672     return ret;
673 }
674 
self_test_asym_ciphers(OSSL_SELF_TEST * st,OSSL_LIB_CTX * libctx)675 static int self_test_asym_ciphers(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)
676 {
677     int i, ret = 1;
678 
679     for (i = 0; i < (int)OSSL_NELEM(st_kat_asym_cipher_tests); ++i) {
680         if (!self_test_asym_cipher(&st_kat_asym_cipher_tests[i], st, libctx))
681             ret = 0;
682     }
683     return ret;
684 }
685 
self_test_kdfs(OSSL_SELF_TEST * st,OSSL_LIB_CTX * libctx)686 static int self_test_kdfs(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)
687 {
688     int i, ret = 1;
689 
690     for (i = 0; i < (int)OSSL_NELEM(st_kat_kdf_tests); ++i) {
691         if (!self_test_kdf(&st_kat_kdf_tests[i], st, libctx))
692             ret = 0;
693     }
694     return ret;
695 }
696 
self_test_drbgs(OSSL_SELF_TEST * st,OSSL_LIB_CTX * libctx)697 static int self_test_drbgs(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)
698 {
699     int i, ret = 1;
700 
701     for (i = 0; i < (int)OSSL_NELEM(st_kat_drbg_tests); ++i) {
702         if (!self_test_drbg(&st_kat_drbg_tests[i], st, libctx))
703             ret = 0;
704     }
705     return ret;
706 }
707 
self_test_kas(OSSL_SELF_TEST * st,OSSL_LIB_CTX * libctx)708 static int self_test_kas(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)
709 {
710     int ret = 1;
711 #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC)
712     int i;
713 
714     for (i = 0; i < (int)OSSL_NELEM(st_kat_kas_tests); ++i) {
715         if (!self_test_ka(&st_kat_kas_tests[i], st, libctx))
716             ret = 0;
717     }
718 #endif
719 
720     return ret;
721 }
722 
self_test_signatures(OSSL_SELF_TEST * st,OSSL_LIB_CTX * libctx)723 static int self_test_signatures(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)
724 {
725     int i, ret = 1;
726 
727     for (i = 0; i < (int)OSSL_NELEM(st_kat_sign_tests); ++i) {
728         if (!self_test_digest_sign(&st_kat_sign_tests[i], st, libctx))
729             ret = 0;
730     }
731     return ret;
732 }
733 
734 /*
735  * Swap the library context DRBG for KAT testing
736  *
737  * In FIPS 140-3, the asymmetric POST must be a KAT, not a PCT.  For DSA and ECDSA,
738  * the sign operation includes the random value 'k'.  For a KAT to work, we
739  * have to have control of the DRBG to make sure it is in a "test" state, where
740  * its output is truly deterministic.
741  *
742  */
743 
744 /*
745  * Replacement "random" sources
746  * main_rand is used for most tests and it's set to generate mode.
747  * kat_rand is used for KATs where specific input is mandated.
748  */
749 static EVP_RAND_CTX *kat_rand = NULL;
750 static EVP_RAND_CTX *main_rand = NULL;
751 
set_kat_drbg(OSSL_LIB_CTX * ctx,const unsigned char * entropy,size_t entropy_len,const unsigned char * nonce,size_t nonce_len,const unsigned char * persstr,size_t persstr_len)752 static int set_kat_drbg(OSSL_LIB_CTX *ctx,
753                         const unsigned char *entropy, size_t entropy_len,
754                         const unsigned char *nonce, size_t nonce_len,
755                         const unsigned char *persstr, size_t persstr_len) {
756     EVP_RAND *rand;
757     unsigned int strength = 256;
758     EVP_RAND_CTX *parent_rand = NULL;
759     OSSL_PARAM drbg_params[3] = {
760         OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END
761     };
762 
763     /* If not NULL, we didn't cleanup from last call: BAD */
764     if (kat_rand != NULL)
765         return 0;
766 
767     rand = EVP_RAND_fetch(ctx, "TEST-RAND", NULL);
768     if (rand == NULL)
769         return 0;
770 
771     parent_rand = EVP_RAND_CTX_new(rand, NULL);
772     EVP_RAND_free(rand);
773     if (parent_rand == NULL)
774         goto err;
775 
776     drbg_params[0] = OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_STRENGTH,
777                                                &strength);
778     if (!EVP_RAND_CTX_set_params(parent_rand, drbg_params))
779         goto err;
780 
781     rand = EVP_RAND_fetch(ctx, "HASH-DRBG", NULL);
782     if (rand == NULL)
783         goto err;
784 
785     kat_rand = EVP_RAND_CTX_new(rand, parent_rand);
786     EVP_RAND_free(rand);
787     if (kat_rand == NULL)
788         goto err;
789 
790     drbg_params[0] = OSSL_PARAM_construct_utf8_string("digest", "SHA256", 0);
791     if (!EVP_RAND_CTX_set_params(kat_rand, drbg_params))
792         goto err;
793 
794     /* Instantiate the RNGs */
795     drbg_params[0] =
796         OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_ENTROPY,
797                                           (void *)entropy, entropy_len);
798     drbg_params[1] =
799         OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_NONCE,
800                                           (void *)nonce, nonce_len);
801     if (!EVP_RAND_instantiate(parent_rand, strength, 0, NULL, 0, drbg_params))
802         goto err;
803 
804     EVP_RAND_CTX_free(parent_rand);
805     parent_rand = NULL;
806 
807     if (!EVP_RAND_instantiate(kat_rand, strength, 0, persstr, persstr_len, NULL))
808         goto err;
809 
810     /* When we set the new private generator this one is freed, so upref it */
811     if (!EVP_RAND_CTX_up_ref(main_rand))
812         goto err;
813 
814     /* Update the library context DRBG */
815     if (RAND_set0_private(ctx, kat_rand) > 0) {
816         /* Keeping a copy to verify zeroization */
817         if (EVP_RAND_CTX_up_ref(kat_rand))
818             return 1;
819         RAND_set0_private(ctx, main_rand);
820     }
821 
822  err:
823     EVP_RAND_CTX_free(parent_rand);
824     EVP_RAND_CTX_free(kat_rand);
825     kat_rand = NULL;
826     return 0;
827 }
828 
reset_main_drbg(OSSL_LIB_CTX * ctx)829 static int reset_main_drbg(OSSL_LIB_CTX *ctx) {
830     int ret = 1;
831 
832     if (!RAND_set0_private(ctx, main_rand))
833         ret = 0;
834     if (kat_rand != NULL) {
835         if (!EVP_RAND_uninstantiate(kat_rand)
836                 || !EVP_RAND_verify_zeroization(kat_rand))
837             ret = 0;
838         EVP_RAND_CTX_free(kat_rand);
839         kat_rand = NULL;
840     }
841     return ret;
842 }
843 
setup_main_random(OSSL_LIB_CTX * libctx)844 static int setup_main_random(OSSL_LIB_CTX *libctx)
845 {
846     OSSL_PARAM drbg_params[3] = {
847         OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END
848     };
849     unsigned int strength = 256, generate = 1;
850     EVP_RAND *rand;
851 
852     rand = EVP_RAND_fetch(libctx, "TEST-RAND", NULL);
853     if (rand == NULL)
854         return 0;
855 
856     main_rand = EVP_RAND_CTX_new(rand, NULL);
857     EVP_RAND_free(rand);
858     if (main_rand == NULL)
859         goto err;
860 
861     drbg_params[0] = OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_GENERATE,
862                                                &generate);
863     drbg_params[1] = OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_STRENGTH,
864                                                &strength);
865 
866     if (!EVP_RAND_instantiate(main_rand, strength, 0, NULL, 0, drbg_params))
867         goto err;
868     return 1;
869  err:
870     EVP_RAND_CTX_free(main_rand);
871     return 0;
872 }
873 
874 /*
875  * Run the algorithm KAT's.
876  * Return 1 is successful, otherwise return 0.
877  * This runs all the tests regardless of if any fail.
878  */
SELF_TEST_kats(OSSL_SELF_TEST * st,OSSL_LIB_CTX * libctx)879 int SELF_TEST_kats(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)
880 {
881     EVP_RAND_CTX *saved_rand = ossl_rand_get0_private_noncreating(libctx);
882     int ret = 1;
883 
884     if (saved_rand != NULL && !EVP_RAND_CTX_up_ref(saved_rand))
885         return 0;
886     if (!setup_main_random(libctx)
887             || !RAND_set0_private(libctx, main_rand)) {
888         /* Decrement saved_rand reference counter */
889         EVP_RAND_CTX_free(saved_rand);
890         EVP_RAND_CTX_free(main_rand);
891         return 0;
892     }
893 
894     if (!self_test_digests(st, libctx))
895         ret = 0;
896     if (!self_test_ciphers(st, libctx))
897         ret = 0;
898     if (!self_test_signatures(st, libctx))
899         ret = 0;
900     if (!self_test_kdfs(st, libctx))
901         ret = 0;
902     if (!self_test_drbgs(st, libctx))
903         ret = 0;
904     if (!self_test_kas(st, libctx))
905         ret = 0;
906     if (!self_test_asym_ciphers(st, libctx))
907         ret = 0;
908 
909     RAND_set0_private(libctx, saved_rand);
910     return ret;
911 }
912 
913