diff options
Diffstat (limited to 'regress/lib/libcrypto/mlkem/mlkem1024_nist_decap_tests.c')
-rw-r--r-- | regress/lib/libcrypto/mlkem/mlkem1024_nist_decap_tests.c | 210 |
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; } |