summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/regress/lib/libcrypto/mlkem/mlkem_tests.c174
1 files changed, 91 insertions, 83 deletions
diff --git a/src/regress/lib/libcrypto/mlkem/mlkem_tests.c b/src/regress/lib/libcrypto/mlkem/mlkem_tests.c
index 3269ba951f..32557ed8f5 100644
--- a/src/regress/lib/libcrypto/mlkem/mlkem_tests.c
+++ b/src/regress/lib/libcrypto/mlkem/mlkem_tests.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mlkem_tests.c,v 1.7 2025/08/14 15:48:48 beck Exp $ */ 1/* $OpenBSD: mlkem_tests.c,v 1.8 2025/08/15 07:49:12 tb Exp $ */
2/* 2/*
3 * Copyright (c) 2024 Google Inc. 3 * Copyright (c) 2024 Google Inc.
4 * Copyright (c) 2024 Theo Buehler <tb@openbsd.org> 4 * Copyright (c) 2024 Theo Buehler <tb@openbsd.org>
@@ -38,8 +38,8 @@ enum test_type {
38 38
39struct decap_ctx { 39struct decap_ctx {
40 struct parse *parse_ctx; 40 struct parse *parse_ctx;
41
41 int rank; 42 int rank;
42 MLKEM_private_key *private_key;
43}; 43};
44 44
45enum decap_states { 45enum decap_states {
@@ -85,26 +85,23 @@ decap_init(void *ctx, void *parse_ctx)
85 85
86 decap->parse_ctx = parse_ctx; 86 decap->parse_ctx = parse_ctx;
87 87
88 return (decap->private_key = MLKEM_private_key_new(decap->rank)) 88 return 1;
89 != NULL;
90} 89}
91 90
92static void 91static void
93decap_finish(void *ctx) 92decap_finish(void *ctx)
94{ 93{
95 struct decap_ctx *decap = ctx; 94 (void)ctx;
96
97 MLKEM_private_key_free(decap->private_key);
98 decap->private_key = NULL;
99} 95}
100 96
101static int 97static int
102MlkemDecapFileTest(struct decap_ctx *decap) 98MlkemDecapFileTest(struct decap_ctx *decap)
103{ 99{
104 struct parse *p = decap->parse_ctx; 100 struct parse *p = decap->parse_ctx;
105 uint8_t *shared_secret_buf = NULL; 101 MLKEM_private_key *priv_key = NULL;
106 CBS ciphertext, shared_secret, private_key; 102 CBS ciphertext, shared_secret, private_key;
107 size_t s_len = 0; 103 uint8_t *shared_secret_buf = NULL;
104 size_t shared_secret_buf_len = 0;
108 int should_fail; 105 int should_fail;
109 int failed = 1; 106 int failed = 1;
110 107
@@ -113,28 +110,31 @@ MlkemDecapFileTest(struct decap_ctx *decap)
113 parse_get_cbs(p, DECAP_PRIVATE_KEY, &private_key); 110 parse_get_cbs(p, DECAP_PRIVATE_KEY, &private_key);
114 parse_get_int(p, DECAP_RESULT, &should_fail); 111 parse_get_int(p, DECAP_RESULT, &should_fail);
115 112
116 if (!MLKEM_parse_private_key(decap->private_key, 113 if ((priv_key = MLKEM_private_key_new(decap->rank)) == NULL)
114 parse_errx(p, "MLKEM_private_key_new");
115
116 if (!MLKEM_parse_private_key(priv_key,
117 CBS_data(&private_key), CBS_len(&private_key))) { 117 CBS_data(&private_key), CBS_len(&private_key))) {
118 if ((failed = !should_fail)) 118 if ((failed = !should_fail))
119 parse_info(p, "parse private key"); 119 parse_info(p, "parse private key");
120 goto err; 120 goto err;
121 } 121 }
122 if (!MLKEM_decap(decap->private_key, CBS_data(&ciphertext), 122 if (!MLKEM_decap(priv_key, CBS_data(&ciphertext), CBS_len(&ciphertext),
123 CBS_len(&ciphertext), &shared_secret_buf, &s_len)) { 123 &shared_secret_buf, &shared_secret_buf_len)) {
124 if ((failed = !should_fail)) 124 if ((failed = !should_fail))
125 parse_info(p, "decap"); 125 parse_info(p, "decap");
126 goto err; 126 goto err;
127 } 127 }
128 128
129 if (s_len != MLKEM_SHARED_SECRET_LENGTH) { 129 if (shared_secret_buf_len != MLKEM_SHARED_SECRET_LENGTH) {
130 if ((failed = !should_fail)) 130 if ((failed = !should_fail))
131 parse_info(p, "shared secret length %zu != %d", s_len, 131 parse_info(p, "shared secret length %zu != %d",
132 MLKEM_SHARED_SECRET_LENGTH); 132 shared_secret_buf_len, MLKEM_SHARED_SECRET_LENGTH);
133 goto err; 133 goto err;
134 } 134 }
135 135
136 failed = !parse_data_equal(p, "shared_secret", &shared_secret, 136 failed = !parse_data_equal(p, "shared_secret", &shared_secret,
137 shared_secret_buf, s_len); 137 shared_secret_buf, shared_secret_buf_len);
138 138
139 if (should_fail != failed) { 139 if (should_fail != failed) {
140 parse_info(p, "FAIL: should_fail %d, failed %d", 140 parse_info(p, "FAIL: should_fail %d, failed %d",
@@ -143,7 +143,9 @@ MlkemDecapFileTest(struct decap_ctx *decap)
143 } 143 }
144 144
145 err: 145 err:
146 freezero(shared_secret_buf, s_len); 146 MLKEM_private_key_free(priv_key);
147 freezero(shared_secret_buf, shared_secret_buf_len);
148
147 return failed; 149 return failed;
148} 150}
149 151
@@ -202,44 +204,49 @@ static int
202MlkemNistDecapFileTest(struct decap_ctx *decap) 204MlkemNistDecapFileTest(struct decap_ctx *decap)
203{ 205{
204 struct parse *p = decap->parse_ctx; 206 struct parse *p = decap->parse_ctx;
205 uint8_t *shared_secret = NULL; 207 MLKEM_private_key *priv_key = NULL;
206 CBS dk, c, k; 208 CBS dk, c, k;
207 size_t s_len = 0; 209 uint8_t *shared_secret = NULL;
210 size_t shared_secret_len = 0;
208 int failed = 1; 211 int failed = 1;
209 212
210 parse_instruction_get_cbs(p, NIST_DECAP_DK, &dk); 213 parse_instruction_get_cbs(p, NIST_DECAP_DK, &dk);
211 parse_get_cbs(p, NIST_DECAP_C, &c); 214 parse_get_cbs(p, NIST_DECAP_C, &c);
212 parse_get_cbs(p, NIST_DECAP_K, &k); 215 parse_get_cbs(p, NIST_DECAP_K, &k);
213 216
217 if ((priv_key = MLKEM_private_key_new(decap->rank)) == NULL)
218 parse_errx(p, "MLKEM_private_key_new");
219
214 if (!parse_length_equal(p, "private key", 220 if (!parse_length_equal(p, "private key",
215 MLKEM_private_key_encoded_length(decap->private_key), CBS_len(&dk))) 221 MLKEM_private_key_encoded_length(priv_key), CBS_len(&dk)))
216 goto err; 222 goto err;
217 if (!parse_length_equal(p, "shared secret", 223 if (!parse_length_equal(p, "shared secret",
218 MLKEM_SHARED_SECRET_BYTES, CBS_len(&k))) 224 MLKEM_SHARED_SECRET_LENGTH, CBS_len(&k)))
219 goto err; 225 goto err;
220 226
221 if (!MLKEM_parse_private_key(decap->private_key, CBS_data(&dk), 227 if (!MLKEM_parse_private_key(priv_key, CBS_data(&dk), CBS_len(&dk))) {
222 CBS_len(&dk))) {
223 parse_info(p, "parse private key"); 228 parse_info(p, "parse private key");
224 goto err; 229 goto err;
225 } 230 }
226 if (!MLKEM_decap(decap->private_key, CBS_data(&c), CBS_len(&c), 231 if (!MLKEM_decap(priv_key, CBS_data(&c), CBS_len(&c),
227 &shared_secret, &s_len)) { 232 &shared_secret, &shared_secret_len)) {
228 parse_info(p, "decap"); 233 parse_info(p, "decap");
229 goto err; 234 goto err;
230 } 235 }
231 236
232 if (s_len != MLKEM_SHARED_SECRET_LENGTH) { 237 if (shared_secret_len != MLKEM_SHARED_SECRET_LENGTH) {
233 parse_info(p, "shared secret length %zu != %d", s_len, 238 parse_info(p, "shared secret length %zu != %d",
234 MLKEM_SHARED_SECRET_LENGTH); 239 shared_secret_len, MLKEM_SHARED_SECRET_LENGTH);
235 goto err; 240 goto err;
236 } 241 }
237 242
238 failed = !parse_data_equal(p, "shared secret", &k, 243 failed = !parse_data_equal(p, "shared secret", &k,
239 shared_secret, s_len); 244 shared_secret, shared_secret_len);
240 245
241 err: 246 err:
242 free(shared_secret); 247 MLKEM_private_key_free(priv_key);
248 freezero(shared_secret, shared_secret_len);
249
243 return failed; 250 return failed;
244} 251}
245 252
@@ -285,9 +292,6 @@ struct encap_ctx {
285 struct parse *parse_ctx; 292 struct parse *parse_ctx;
286 293
287 int rank; 294 int rank;
288 MLKEM_public_key *public_key;
289 uint8_t *ciphertext;
290 size_t ciphertext_len;
291}; 295};
292 296
293enum encap_states { 297enum encap_states {
@@ -340,30 +344,25 @@ encap_init(void *ctx, void *parse_ctx)
340 344
341 encap->parse_ctx = parse_ctx; 345 encap->parse_ctx = parse_ctx;
342 346
343 encap->ciphertext = NULL; 347 return 1;
344 return (encap->public_key = MLKEM_public_key_new(encap->rank))
345 != NULL;
346} 348}
347 349
348static void 350static void
349encap_finish(void *ctx) 351encap_finish(void *ctx)
350{ 352{
351 struct encap_ctx *encap = ctx; 353 (void)ctx;
352
353 freezero(encap->ciphertext, encap->ciphertext_len);
354 encap->ciphertext = NULL;
355 MLKEM_public_key_free(encap->public_key);
356 encap->public_key = NULL;
357} 354}
358 355
359static int 356static int
360MlkemEncapFileTest(struct encap_ctx *encap) 357MlkemEncapFileTest(struct encap_ctx *encap)
361{ 358{
362 CBS entropy, public_key, ciphertext, shared_secret;
363 struct parse *p = encap->parse_ctx; 359 struct parse *p = encap->parse_ctx;
360 MLKEM_public_key *pub_key = NULL;
361 CBS entropy, public_key, ciphertext, shared_secret;
362 uint8_t *ciphertext_buf = NULL;
363 size_t ciphertext_buf_len = 0;
364 uint8_t *shared_secret_buf = NULL; 364 uint8_t *shared_secret_buf = NULL;
365 size_t s_len = 0; 365 size_t shared_secret_buf_len = 0;
366
367 int should_fail; 366 int should_fail;
368 int failed = 1; 367 int failed = 1;
369 368
@@ -373,32 +372,34 @@ MlkemEncapFileTest(struct encap_ctx *encap)
373 parse_get_cbs(p, ENCAP_SHARED_SECRET, &shared_secret); 372 parse_get_cbs(p, ENCAP_SHARED_SECRET, &shared_secret);
374 parse_get_int(p, ENCAP_RESULT, &should_fail); 373 parse_get_int(p, ENCAP_RESULT, &should_fail);
375 374
376 if (!MLKEM_parse_public_key(encap->public_key, CBS_data(&public_key), 375 if ((pub_key = MLKEM_public_key_new(encap->rank)) == NULL)
377 CBS_len(&public_key))) { 376 parse_errx(p, "MLKEM_public_key_new");
377
378 if (!MLKEM_parse_public_key(pub_key,
379 CBS_data(&public_key), CBS_len(&public_key))) {
378 if ((failed = !should_fail)) 380 if ((failed = !should_fail))
379 parse_info(p, "parse public key"); 381 parse_info(p, "parse public key");
380 goto err; 382 goto err;
381 } 383 }
382 if (!MLKEM_encap_external_entropy(encap->public_key, CBS_data(&entropy), 384 if (!MLKEM_encap_external_entropy(pub_key, CBS_data(&entropy),
383 &encap->ciphertext, &encap->ciphertext_len, &shared_secret_buf, 385 &ciphertext_buf, &ciphertext_buf_len,
384 &s_len)) { 386 &shared_secret_buf, &shared_secret_buf_len)) {
385 if ((failed = !should_fail)) 387 if ((failed = !should_fail))
386 parse_info(p, "encap_external_entropy"); 388 parse_info(p, "encap_external_entropy");
387 goto err; 389 goto err;
388 } 390 }
389 391
390 if (s_len != MLKEM_SHARED_SECRET_LENGTH) { 392 if (shared_secret_buf_len != MLKEM_SHARED_SECRET_LENGTH) {
391 if ((failed = !should_fail)) 393 if ((failed = !should_fail))
392 parse_info(p, "shared secret length %zu != %d", s_len, 394 parse_info(p, "shared secret length %zu != %d",
393 MLKEM_SHARED_SECRET_LENGTH); 395 shared_secret_buf_len, MLKEM_SHARED_SECRET_LENGTH);
394 goto err; 396 goto err;
395 } 397 }
396 398
397 failed = !parse_data_equal(p, "shared_secret", &shared_secret, 399 failed = !parse_data_equal(p, "shared_secret", &shared_secret,
398 shared_secret_buf, s_len); 400 shared_secret_buf, shared_secret_buf_len);
399 failed |= !parse_data_equal(p, "ciphertext", &ciphertext, 401 failed |= !parse_data_equal(p, "ciphertext", &ciphertext,
400 encap->ciphertext, encap->ciphertext_len); 402 ciphertext_buf, ciphertext_buf_len);
401
402 403
403 if (should_fail != failed) { 404 if (should_fail != failed) {
404 parse_info(p, "FAIL: should_fail %d, failed %d", 405 parse_info(p, "FAIL: should_fail %d, failed %d",
@@ -407,7 +408,10 @@ MlkemEncapFileTest(struct encap_ctx *encap)
407 } 408 }
408 409
409 err: 410 err:
410 freezero(shared_secret_buf, s_len); 411 MLKEM_public_key_free(pub_key);
412 freezero(ciphertext_buf, ciphertext_buf_len);
413 freezero(shared_secret_buf, shared_secret_buf_len);
414
411 return failed; 415 return failed;
412} 416}
413 417
@@ -441,9 +445,6 @@ struct keygen_ctx {
441 struct parse *parse_ctx; 445 struct parse *parse_ctx;
442 446
443 int rank; 447 int rank;
444 MLKEM_private_key *private_key;
445 uint8_t *encoded_public_key;
446 size_t encoded_public_key_len;
447}; 448};
448 449
449enum keygen_states { 450enum keygen_states {
@@ -481,28 +482,25 @@ keygen_init(void *ctx, void *parse_ctx)
481 482
482 keygen->parse_ctx = parse_ctx; 483 keygen->parse_ctx = parse_ctx;
483 484
484 return (keygen->private_key = MLKEM_private_key_new(keygen->rank)) 485 return 1;
485 != NULL;
486} 486}
487 487
488static void 488static void
489keygen_finish(void *ctx) 489keygen_finish(void *ctx)
490{ 490{
491 struct keygen_ctx *keygen = ctx; 491 (void)ctx;
492
493 freezero(keygen->encoded_public_key, keygen->encoded_public_key_len);
494 keygen->encoded_public_key = NULL;
495 MLKEM_private_key_free(keygen->private_key);
496 keygen->private_key = NULL;
497} 492}
498 493
499static int 494static int
500MlkemKeygenFileTest(struct keygen_ctx *keygen) 495MlkemKeygenFileTest(struct keygen_ctx *keygen)
501{ 496{
502 struct parse *p = keygen->parse_ctx; 497 struct parse *p = keygen->parse_ctx;
498 MLKEM_private_key *priv_key = NULL;
503 CBS seed, public_key, private_key; 499 CBS seed, public_key, private_key;
504 uint8_t *encoded_private_key = NULL; 500 uint8_t *encoded_private_key = NULL;
505 size_t encoded_private_key_len = 0; 501 size_t encoded_private_key_len = 0;
502 uint8_t *encoded_public_key = NULL;
503 size_t encoded_public_key_len = 0;
506 int failed = 1; 504 int failed = 1;
507 505
508 parse_get_cbs(p, KEYGEN_SEED, &seed); 506 parse_get_cbs(p, KEYGEN_SEED, &seed);
@@ -512,22 +510,23 @@ MlkemKeygenFileTest(struct keygen_ctx *keygen)
512 if (!parse_length_equal(p, "seed", MLKEM_SEED_LENGTH, CBS_len(&seed))) 510 if (!parse_length_equal(p, "seed", MLKEM_SEED_LENGTH, CBS_len(&seed)))
513 goto err; 511 goto err;
514 512
515 if (!MLKEM_generate_key_external_entropy(keygen->private_key, 513 if ((priv_key = MLKEM_private_key_new(keygen->rank)) == NULL)
516 &keygen->encoded_public_key, &keygen->encoded_public_key_len, 514 parse_errx(p, "MLKEM_public_key_free");
517 CBS_data(&seed))) { 515
516 if (!MLKEM_generate_key_external_entropy(priv_key,
517 &encoded_public_key, &encoded_public_key_len, CBS_data(&seed))) {
518 parse_info(p, "generate_key_external_entropy"); 518 parse_info(p, "generate_key_external_entropy");
519 goto err; 519 goto err;
520 } 520 }
521 521
522 if (!parse_length_equal(p, "public key", 522 if (!parse_length_equal(p, "public key",
523 keygen->encoded_public_key_len, CBS_len(&public_key))) 523 encoded_public_key_len, CBS_len(&public_key)))
524 goto err; 524 goto err;
525 if (!parse_length_equal(p, "private key", 525 if (!parse_length_equal(p, "private key",
526 MLKEM_private_key_encoded_length(keygen->private_key), 526 MLKEM_private_key_encoded_length(priv_key), CBS_len(&private_key)))
527 CBS_len(&private_key)))
528 goto err; 527 goto err;
529 528
530 if (!MLKEM_marshal_private_key(keygen->private_key, 529 if (!MLKEM_marshal_private_key(priv_key,
531 &encoded_private_key, &encoded_private_key_len)) { 530 &encoded_private_key, &encoded_private_key_len)) {
532 parse_info(p, "encode private key"); 531 parse_info(p, "encode private key");
533 goto err; 532 goto err;
@@ -536,10 +535,12 @@ MlkemKeygenFileTest(struct keygen_ctx *keygen)
536 failed = !parse_data_equal(p, "private key", &private_key, 535 failed = !parse_data_equal(p, "private key", &private_key,
537 encoded_private_key, encoded_private_key_len); 536 encoded_private_key, encoded_private_key_len);
538 failed |= !parse_data_equal(p, "public key", &public_key, 537 failed |= !parse_data_equal(p, "public key", &public_key,
539 keygen->encoded_public_key, keygen->encoded_public_key_len); 538 encoded_public_key, encoded_public_key_len);
540 539
541 err: 540 err:
541 MLKEM_private_key_free(priv_key);
542 freezero(encoded_private_key, encoded_private_key_len); 542 freezero(encoded_private_key, encoded_private_key_len);
543 freezero(encoded_public_key, encoded_public_key_len);
543 544
544 return failed; 545 return failed;
545} 546}
@@ -599,12 +600,15 @@ static int
599MlkemNistKeygenFileTest(struct keygen_ctx *keygen) 600MlkemNistKeygenFileTest(struct keygen_ctx *keygen)
600{ 601{
601 struct parse *p = keygen->parse_ctx; 602 struct parse *p = keygen->parse_ctx;
603 MLKEM_private_key *priv_key = NULL;
602 CBB seed_cbb; 604 CBB seed_cbb;
603 CBS z, d, ek, dk; 605 CBS z, d, ek, dk;
604 uint8_t seed[MLKEM_SEED_LENGTH]; 606 uint8_t seed[MLKEM_SEED_LENGTH];
605 size_t seed_len; 607 size_t seed_len;
606 uint8_t *encoded_private_key = NULL; 608 uint8_t *encoded_private_key = NULL;
607 size_t encoded_private_key_len = 0; 609 size_t encoded_private_key_len = 0;
610 uint8_t *encoded_public_key = NULL;
611 size_t encoded_public_key_len = 0;
608 int failed = 1; 612 int failed = 1;
609 613
610 parse_get_cbs(p, NIST_KEYGEN_Z, &z); 614 parse_get_cbs(p, NIST_KEYGEN_Z, &z);
@@ -624,26 +628,30 @@ MlkemNistKeygenFileTest(struct keygen_ctx *keygen)
624 if (!parse_length_equal(p, "bogus z or d", MLKEM_SEED_LENGTH, seed_len)) 628 if (!parse_length_equal(p, "bogus z or d", MLKEM_SEED_LENGTH, seed_len))
625 goto err; 629 goto err;
626 630
627 if (!MLKEM_generate_key_external_entropy(keygen->private_key, 631 if ((priv_key = MLKEM_private_key_new(keygen->rank)) == NULL)
628 &keygen->encoded_public_key, &keygen->encoded_public_key_len, 632 parse_errx(p, "MLKEM_private_key_new");
629 seed)) { 633
630 parse_info(p, "generate_key_external_entropy"); 634 if (!MLKEM_generate_key_external_entropy(priv_key,
635 &encoded_public_key, &encoded_public_key_len, seed)) {
636 parse_info(p, "MLKEM_generate_key_external_entropy");
631 goto err; 637 goto err;
632 } 638 }
633 639
634 if (!MLKEM_marshal_private_key(keygen->private_key, 640 if (!MLKEM_marshal_private_key(priv_key,
635 &encoded_private_key, &encoded_private_key_len)) { 641 &encoded_private_key, &encoded_private_key_len)) {
636 parse_info(p, "encode private key"); 642 parse_info(p, "encode private key");
637 goto err; 643 goto err;
638 } 644 }
639 645
640 failed = !parse_data_equal(p, "public key", &ek, 646 failed = !parse_data_equal(p, "public key", &ek,
641 keygen->encoded_public_key, keygen->encoded_public_key_len); 647 encoded_public_key, encoded_public_key_len);
642 failed |= !parse_data_equal(p, "private key", &dk, 648 failed |= !parse_data_equal(p, "private key", &dk,
643 encoded_private_key, encoded_private_key_len); 649 encoded_private_key, encoded_private_key_len);
644 650
645 err: 651 err:
652 MLKEM_private_key_free(priv_key);
646 freezero(encoded_private_key, encoded_private_key_len); 653 freezero(encoded_private_key, encoded_private_key_len);
654 freezero(encoded_public_key, encoded_public_key_len);
647 655
648 return failed; 656 return failed;
649} 657}