summaryrefslogtreecommitdiff
path: root/regress/lib/libcrypto/mlkem/mlkem1024_nist_decap_tests.c
diff options
context:
space:
mode:
Diffstat (limited to 'regress/lib/libcrypto/mlkem/mlkem1024_nist_decap_tests.c')
-rw-r--r--regress/lib/libcrypto/mlkem/mlkem1024_nist_decap_tests.c210
1 files changed, 146 insertions, 64 deletions
diff --git a/regress/lib/libcrypto/mlkem/mlkem1024_nist_decap_tests.c b/regress/lib/libcrypto/mlkem/mlkem1024_nist_decap_tests.c
index a59d062234c..ba05de9f051 100644
--- a/regress/lib/libcrypto/mlkem/mlkem1024_nist_decap_tests.c
+++ b/regress/lib/libcrypto/mlkem/mlkem1024_nist_decap_tests.c
@@ -1,7 +1,8 @@
-/* $OpenBSD: mlkem1024_nist_decap_tests.c,v 1.2 2024/12/14 19:16:24 tb Exp $ */
+/* $OpenBSD: mlkem1024_nist_decap_tests.c,v 1.3 2024/12/20 00:07:12 tb Exp $ */
/*
- * Copyright (c) 2024, Google Inc.
- * Copyright (c) 2024, Bob Beck <beck@obtuse.com>
+ * Copyright (c) 2024 Google Inc.
+ * Copyright (c) 2024 Bob Beck <beck@obtuse.com>
+ * Copyright (c) 2024 Theo Buehler <tb@openbsd.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -16,96 +17,177 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <assert.h>
+#include <err.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
-#include <openssl/bytestring.h>
-#include <openssl/mlkem.h>
+#include "bytestring.h"
+#include "mlkem.h"
#include "mlkem_internal.h"
#include "mlkem_tests_util.h"
-static void
-MlkemNistDecapFileTest(CBS *c, CBS *k, CBS *dk)
+static int
+MlkemNistDecapFileTest(CBB *c_cbb, CBB *k_cbb, CBS *dk, size_t line)
{
+ uint8_t *c = NULL, *k = NULL;
+ size_t c_len = 0, k_len = 0;
uint8_t shared_secret[MLKEM_SHARED_SECRET_BYTES];
struct MLKEM1024_private_key priv;
+ int failed = 1;
- TEST(CBS_len(dk) != MLKEM1024_PRIVATE_KEY_BYTES,
- "private key len bogus");
- TEST(CBS_len(k) != MLKEM_SHARED_SECRET_BYTES,
- "shared secret len bogus");
+ if (!CBB_finish(c_cbb, &c, &c_len))
+ goto err;
+ if (!CBB_finish(k_cbb, &k, &k_len))
+ goto err;
- TEST(!MLKEM1024_parse_private_key(&priv, dk), "parse_private_key");
- TEST(!MLKEM1024_decap(shared_secret, CBS_data(c), CBS_len(c), &priv),
- "decap");
- TEST_DATAEQ(shared_secret, CBS_data(k),
- MLKEM_SHARED_SECRET_BYTES, "shared_secret");
+ if (!compare_length(MLKEM1024_PRIVATE_KEY_BYTES, CBS_len(dk), line,
+ "private key len bogus"))
+ goto err;
+ if (!compare_length(MLKEM_SHARED_SECRET_BYTES, k_len, line,
+ "shared secret len bogus"))
+ goto err;
+
+ if (!MLKEM1024_parse_private_key(&priv, dk)) {
+ warnx("#%zu MLKEM1024_parse_private_key", line);
+ goto err;
+ }
+ if (!MLKEM1024_decap(shared_secret, c, c_len, &priv)) {
+ warnx("#%zu MLKEM1024_decap", line);
+ goto err;
+ }
+
+ failed = compare_data(shared_secret, k, k_len, line, "shared_secret");
+
+ err:
+ CBB_cleanup(c_cbb);
+ CBB_cleanup(k_cbb);
+ freezero(c, c_len);
+ freezero(k, k_len);
+
+ return failed;
}
-#define S_START 0
-#define S_CIPHERTEXT 1
-#define S_SHARED_SECRET 2
-#define S_PRIVATE_KEY 3
+#define S_START 0
+#define S_C 1
+#define S_K 2
+#define S_EMPTY 3
+
+#define S2S(x) case x: return #x
+
+static const char *
+state2str(int state)
+{
+ switch (state) {
+ S2S(S_START);
+ S2S(S_C);
+ S2S(S_K);
+ S2S(S_EMPTY);
+ default:
+ errx(1, "unknown state %d", state);
+ }
+}
int
main(int argc, char **argv)
{
- CBS ciphertext, shared_secret, private_key;
- const uint8_t *p;
- char *buf;
+ CBB dk_cbb = { 0 }, c = { 0 }, k = { 0 };
+ CBS instr;
+ uint8_t *dk = NULL;
+ size_t dk_len = 0;
+ uint8_t bracket, newline;
+ const char *test;
+ size_t line;
+ char *buf = NULL;
+ size_t buflen = 0;
+ ssize_t len;
FILE *fp;
int state;
+ int failed = 0;
+
+ if (argc < 2)
+ errx(1, "%s: missing test file", argv[0]);
+
+ test = argv[1];
+
+ if ((fp = fopen(test, "r")) == NULL)
+ err(1, "cant't open test file");
+
+ if ((len = getline(&buf, &buflen, fp)) == -1)
+ err(1, "failed to read instruction line");
+
+ /*
+ * The private key is enclosed in brackets in an "instruction line".
+ */
+ line = 1;
+ CBS_init(&instr, buf, len);
+ if (!CBS_get_u8(&instr, &bracket))
+ err(1, "failed to parse instruction line '['");
+ assert(bracket == '[');
+ if (!CBS_get_last_u8(&instr, &newline))
+ errx(1, "failed to parse instruction line '\\n'");
+ assert(newline == '\n');
+ if (!CBS_get_last_u8(&instr, &bracket))
+ errx(1, "failed to parse instruction line ']'");
+ assert(bracket == ']');
+ if (!get_string_cbs(&instr, "dk: ", line, "private key"))
+ errx(1, "failed to read instruction line 'dk: '");
+ hex_decode_cbs(&instr, &dk_cbb, line, "private key");
+ assert(CBS_len(&instr) == 0);
+
+ if (!CBB_finish(&dk_cbb, &dk, &dk_len))
+ errx(1, "CBB finish instruction line");
+
+ state = S_START;
+
+ while ((len = getline(&buf, &buflen, fp)) != -1) {
+ const char *msg = state2str(state);
+ CBS cbs, dk_cbs;
+ uint8_t u8;
+
+ line++;
+ CBS_init(&cbs, buf, len);
+
+ if (!CBS_get_last_u8(&cbs, &u8))
+ errx(1, "#%zu %s: CBB_get_last_u8", line, msg);
+ assert(u8 == '\n');
- fprintf(stderr, "Testing NIST decap test vectors in %s\n", argv[1]);
- TEST((fp = fopen(argv[1], "r")) == NULL, "can't open test file");
- MALLOC(buf, 16*1024);
- state = S_CIPHERTEXT;
- test_number = 1;
- while (fgets(buf, 16*1024, fp) != NULL) {
switch (state) {
case S_START:
- if (strcmp(buf, "\n") != 0)
- break;
- state = S_CIPHERTEXT;
+ state = S_C;
break;
- case S_CIPHERTEXT:
- if (strncmp(buf, "ciphertext: ",
- strlen("ciphertext: ")) != 0) {
- break;
- }
- grab_data(&ciphertext, buf, strlen("ciphertext: "));
- state = S_SHARED_SECRET;
+ case S_C:
+ if (!get_string_cbs(&cbs, "c: ", line, msg))
+ errx(1, "#%zu %s: get_string_cbs", line, msg);
+ hex_decode_cbs(&cbs, &c, line, msg);
+ state = S_K;
break;
- case S_SHARED_SECRET:
- if (strncmp(buf, "shared_secret: ",
- strlen("shared_secret: ")) != 0)
- break;
- grab_data(&shared_secret, buf,
- strlen("shared_secret: "));
- state = S_PRIVATE_KEY;
+ case S_K:
+ if (!get_string_cbs(&cbs, "k: ", line, msg))
+ errx(1, "#%zu %s: get_string_cbs", line, msg);
+ hex_decode_cbs(&cbs, &k, line, msg);
+ state = S_EMPTY;
break;
- case S_PRIVATE_KEY:
- if (strncmp(buf, "private_key: ",
- strlen("private_key: ")) != 0)
- break;
- grab_data(&private_key, buf, strlen("private_key: "));
- p = CBS_data(&private_key);
-
- MlkemNistDecapFileTest(&ciphertext, &shared_secret,
- &private_key);
- free((void *)CBS_data(&ciphertext));
- free((void *)CBS_data(&shared_secret));
- free((void *)p);
-
- state = S_START;
- test_number++;
+ case S_EMPTY:
+ CBS_init(&dk_cbs, dk, dk_len);
+
+ failed |= MlkemNistDecapFileTest(&c, &k, &dk_cbs, line);
+
+ state = S_C;
break;
}
+ if (CBS_len(&cbs) > 0)
+ errx(1, "#%zu %s: CBS_len", line, msg);
}
-
free(buf);
- exit(failure);
+
+ if (ferror(fp))
+ err(1, NULL);
+ fclose(fp);
+
+ freezero(dk, dk_len);
+
+ return failed;
}