diff options
Diffstat (limited to 'src/regress/lib/libcrypto/mlkem/mlkem1024_nist_keygen_tests.c')
-rw-r--r-- | src/regress/lib/libcrypto/mlkem/mlkem1024_nist_keygen_tests.c | 203 |
1 files changed, 131 insertions, 72 deletions
diff --git a/src/regress/lib/libcrypto/mlkem/mlkem1024_nist_keygen_tests.c b/src/regress/lib/libcrypto/mlkem/mlkem1024_nist_keygen_tests.c index d293d121d4..e84f7dafc6 100644 --- a/src/regress/lib/libcrypto/mlkem/mlkem1024_nist_keygen_tests.c +++ b/src/regress/lib/libcrypto/mlkem/mlkem1024_nist_keygen_tests.c | |||
@@ -1,7 +1,8 @@ | |||
1 | /* $OpenBSD: mlkem1024_nist_keygen_tests.c,v 1.3 2024/12/17 07:20:10 tb Exp $ */ | 1 | /* $OpenBSD: mlkem1024_nist_keygen_tests.c,v 1.4 2024/12/20 00:07:12 tb Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2024, Google Inc. | 3 | * Copyright (c) 2024 Google Inc. |
4 | * Copyright (c) 2024, Bob Beck <beck@obtuse.com> | 4 | * Copyright (c) 2024 Bob Beck <beck@obtuse.com> |
5 | * Copyright (c) 2024 Theo Buehler <tb@openbsd.org> | ||
5 | * | 6 | * |
6 | * Permission to use, copy, modify, and/or distribute this software for any | 7 | * Permission to use, copy, modify, and/or distribute this software for any |
7 | * purpose with or without fee is hereby granted, provided that the above | 8 | * purpose with or without fee is hereby granted, provided that the above |
@@ -16,123 +17,181 @@ | |||
16 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 17 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
17 | */ | 18 | */ |
18 | 19 | ||
20 | #include <assert.h> | ||
21 | #include <err.h> | ||
19 | #include <stdint.h> | 22 | #include <stdint.h> |
20 | #include <stdio.h> | 23 | #include <stdio.h> |
21 | #include <stdlib.h> | 24 | #include <stdlib.h> |
22 | #include <string.h> | ||
23 | 25 | ||
24 | #include <openssl/bytestring.h> | 26 | #include "bytestring.h" |
25 | #include <openssl/mlkem.h> | 27 | #include "mlkem.h" |
26 | 28 | ||
27 | #include "mlkem_internal.h" | 29 | #include "mlkem_internal.h" |
28 | #include "mlkem_tests_util.h" | 30 | #include "mlkem_tests_util.h" |
29 | 31 | ||
30 | static int | 32 | static int |
31 | encode_private_key(const struct MLKEM1024_private_key *priv, uint8_t **out_buf, | 33 | MlkemNistKeygenFileTest(CBB *z_cbb, CBB *d_cbb, CBB *ek_cbb, CBB *dk_cbb, |
32 | size_t *out_len) | 34 | size_t line) |
33 | { | ||
34 | CBB cbb; | ||
35 | if (!CBB_init(&cbb, MLKEM1024_PUBLIC_KEY_BYTES)) | ||
36 | return 0; | ||
37 | if (!MLKEM1024_marshal_private_key(&cbb, priv)) | ||
38 | return 0; | ||
39 | if (!CBB_finish(&cbb, out_buf, out_len)) | ||
40 | return 0; | ||
41 | CBB_cleanup(&cbb); | ||
42 | return 1; | ||
43 | } | ||
44 | |||
45 | static void | ||
46 | MlkemNistKeygenFileTest(CBS *z, CBS *d, CBS *ek, CBS *dk) | ||
47 | { | 35 | { |
36 | CBB seed_cbb; | ||
37 | uint8_t *z = NULL, *d = NULL, *ek = NULL, *dk = NULL; | ||
38 | size_t z_len = 0, d_len = 0, ek_len = 0, dk_len = 0; | ||
48 | uint8_t seed[MLKEM_SEED_BYTES]; | 39 | uint8_t seed[MLKEM_SEED_BYTES]; |
49 | struct MLKEM1024_private_key priv; | 40 | struct MLKEM1024_private_key priv; |
50 | uint8_t *encoded_private_key = NULL; | 41 | uint8_t *encoded_private_key = NULL; |
51 | uint8_t encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES]; | 42 | uint8_t encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES]; |
52 | size_t len; | 43 | size_t len; |
44 | int failed = 1; | ||
45 | |||
46 | if (!CBB_init_fixed(&seed_cbb, seed, sizeof(seed))) | ||
47 | goto err; | ||
48 | |||
49 | if (!CBB_finish(z_cbb, &z, &z_len)) | ||
50 | goto err; | ||
51 | if (!CBB_finish(d_cbb, &d, &d_len)) | ||
52 | goto err; | ||
53 | if (!CBB_finish(ek_cbb, &ek, &ek_len)) | ||
54 | goto err; | ||
55 | if (!CBB_finish(dk_cbb, &dk, &dk_len)) | ||
56 | goto err; | ||
57 | |||
58 | if (!CBB_add_bytes(&seed_cbb, d, d_len)) | ||
59 | goto err; | ||
60 | if (!CBB_add_bytes(&seed_cbb, z, z_len)) | ||
61 | goto err; | ||
62 | if (!CBB_finish(&seed_cbb, NULL, &len)) | ||
63 | goto err; | ||
64 | |||
65 | if (!compare_length(MLKEM_SEED_BYTES, len, line, "z or d length bogus")) | ||
66 | goto err; | ||
53 | 67 | ||
54 | TEST(CBS_len(d) != (MLKEM_SEED_BYTES / 2), "d len bogus"); | ||
55 | TEST(CBS_len(z) != (MLKEM_SEED_BYTES / 2), "z len bogus"); | ||
56 | TEST(CBS_len(dk) != MLKEM1024_PRIVATE_KEY_BYTES, | ||
57 | "expected private key len bogus"); | ||
58 | TEST(CBS_len(ek) != MLKEM1024_PUBLIC_KEY_BYTES, | ||
59 | "expected public key len bogus"); | ||
60 | memcpy(&seed[0], CBS_data(d), CBS_len(d)); | ||
61 | memcpy(&seed[MLKEM_SEED_BYTES / 2], CBS_data(z), CBS_len(z)); | ||
62 | MLKEM1024_generate_key_external_entropy(encoded_public_key, &priv, seed); | 68 | MLKEM1024_generate_key_external_entropy(encoded_public_key, &priv, seed); |
63 | TEST(!encode_private_key(&priv, &encoded_private_key, | 69 | |
64 | &len), "encode_private_key"); | 70 | if (!mlkem1024_encode_private_key(&priv, &encoded_private_key, &len)) { |
65 | TEST(len != MLKEM1024_PRIVATE_KEY_BYTES, "private key len bogus"); | 71 | warnx("#%zu mlkem1024_encode_private_key", line); |
66 | TEST_DATAEQ(encoded_public_key, CBS_data(ek), | 72 | goto err; |
67 | MLKEM1024_PUBLIC_KEY_BYTES, "public key"); | 73 | } |
68 | TEST_DATAEQ(encoded_private_key, CBS_data(dk), | 74 | |
69 | MLKEM1024_PRIVATE_KEY_BYTES, "private key"); | 75 | if (!compare_length(MLKEM1024_PRIVATE_KEY_BYTES, len, line, |
76 | "private key length")) | ||
77 | goto err; | ||
78 | |||
79 | failed = compare_data(ek, encoded_public_key, MLKEM1024_PUBLIC_KEY_BYTES, | ||
80 | line, "public key"); | ||
81 | failed |= compare_data(dk, encoded_private_key, MLKEM1024_PRIVATE_KEY_BYTES, | ||
82 | line, "private key"); | ||
83 | |||
84 | err: | ||
85 | CBB_cleanup(&seed_cbb); | ||
86 | CBB_cleanup(z_cbb); | ||
87 | CBB_cleanup(d_cbb); | ||
88 | CBB_cleanup(ek_cbb); | ||
89 | CBB_cleanup(dk_cbb); | ||
90 | freezero(z, z_len); | ||
91 | freezero(d, d_len); | ||
92 | freezero(ek, ek_len); | ||
93 | freezero(dk, dk_len); | ||
70 | free(encoded_private_key); | 94 | free(encoded_private_key); |
95 | |||
96 | return failed; | ||
71 | } | 97 | } |
72 | 98 | ||
73 | #define S_START 0 | 99 | #define S_START 0 |
74 | #define S_Z 1 | 100 | #define S_Z 1 |
75 | #define S_D 2 | 101 | #define S_D 2 |
76 | #define S_EK 3 | 102 | #define S_EK 3 |
77 | #define S_DK 4 | 103 | #define S_DK 4 |
104 | |||
105 | #define S2S(x) case x: return #x | ||
106 | |||
107 | static const char * | ||
108 | state2str(int state) | ||
109 | { | ||
110 | switch (state) { | ||
111 | S2S(S_START); | ||
112 | S2S(S_Z); | ||
113 | S2S(S_D); | ||
114 | S2S(S_EK); | ||
115 | S2S(S_DK); | ||
116 | default: | ||
117 | errx(1, "unknown state %d", state); | ||
118 | } | ||
119 | } | ||
78 | 120 | ||
79 | int | 121 | int |
80 | main(int argc, char **argv) | 122 | main(int argc, char **argv) |
81 | { | 123 | { |
82 | CBS z, d, ek, dk; | 124 | CBB z = { 0 }, d = { 0 }, ek = { 0 }, dk = { 0 }; |
83 | char *buf; | 125 | const char *test; |
126 | size_t line = 0; | ||
127 | char *buf = NULL; | ||
128 | size_t buflen = 0; | ||
129 | ssize_t len; | ||
84 | FILE *fp; | 130 | FILE *fp; |
85 | int state; | 131 | int state; |
132 | int failed = 0; | ||
133 | |||
134 | if (argc < 2) | ||
135 | errx(1, "%s: missing test file", argv[0]); | ||
136 | |||
137 | test = argv[1]; | ||
138 | |||
139 | if ((fp = fopen(test, "r")) == NULL) | ||
140 | err(1, "cant't open test file"); | ||
86 | 141 | ||
87 | fprintf(stderr, "Testing NIST keygen test vectors in %s\n", argv[1]); | ||
88 | TEST((fp = fopen(argv[1], "r")) == NULL, "can't open test file"); | ||
89 | MALLOC(buf, 16*1024); | ||
90 | state = S_Z; | 142 | state = S_Z; |
91 | test_number = 1; | 143 | line = 0; |
92 | while (fgets(buf, 16*1024, fp) != NULL) { | 144 | |
145 | while ((len = getline(&buf, &buflen, fp)) != -1) { | ||
146 | const char *msg = state2str(state); | ||
147 | CBS cbs; | ||
148 | uint8_t u8; | ||
149 | |||
150 | line++; | ||
151 | CBS_init(&cbs, buf, len); | ||
152 | |||
153 | if (!CBS_get_last_u8(&cbs, &u8)) | ||
154 | errx(1, "#%zu %s: CBB_get_last_u8", line, msg); | ||
155 | assert(u8 == '\n'); | ||
156 | |||
93 | switch (state) { | 157 | switch (state) { |
94 | case S_START: | 158 | case S_START: |
95 | if (strcmp(buf, "\n") != 0) | ||
96 | break; | ||
97 | state = S_Z; | 159 | state = S_Z; |
98 | break; | 160 | break; |
99 | case S_Z: | 161 | case S_Z: |
100 | if (strncmp(buf, "z: ", strlen("z: ")) != 0) { | 162 | if (!get_string_cbs(&cbs, "z: ", line, msg)) |
101 | break; | 163 | errx(1, "#%zu %s: get_string_cbs", line, msg); |
102 | } | 164 | hex_decode_cbs(&cbs, &z, line, msg); |
103 | grab_data(&z, buf, strlen("z: ")); | ||
104 | state = S_D; | 165 | state = S_D; |
105 | break; | 166 | break; |
106 | case S_D: | 167 | case S_D: |
107 | if (strncmp(buf, "d: ", strlen("d: ")) != 0) | 168 | if (!get_string_cbs(&cbs, "d: ", line, msg)) |
108 | break; | 169 | errx(1, "#%zu %s: get_string_cbs", line, msg); |
109 | grab_data(&d, buf, strlen("d: ")); | 170 | hex_decode_cbs(&cbs, &d, line, msg); |
110 | state = S_EK; | 171 | state = S_EK; |
111 | break; | 172 | break; |
112 | case S_EK: | 173 | case S_EK: |
113 | if (strncmp(buf, "ek: ", strlen("ek: ")) != 0) | 174 | if (!get_string_cbs(&cbs, "ek: ", line, msg)) |
114 | break; | 175 | errx(1, "#%zu %s: get_string_cbs", line, msg); |
115 | grab_data(&ek, buf, strlen("ek: ")); | 176 | hex_decode_cbs(&cbs, &ek, line, msg); |
116 | state = S_DK; | 177 | state = S_DK; |
117 | break; | 178 | break; |
118 | case S_DK: | 179 | case S_DK: |
119 | if (strncmp(buf, "dk: ", strlen("dk: ")) != 0) | 180 | if (!get_string_cbs(&cbs, "dk: ", line, msg)) |
120 | break; | 181 | errx(1, "#%zu %s: get_string_cbs", line, msg); |
121 | grab_data(&dk, buf, strlen("dk: ")); | 182 | hex_decode_cbs(&cbs, &dk, line, msg); |
122 | 183 | ||
123 | MlkemNistKeygenFileTest(&z, &d, &ek, &dk); | 184 | failed |= MlkemNistKeygenFileTest(&z, &d, &ek, &dk, line); |
124 | free((void *)CBS_data(&z)); | ||
125 | free((void *)CBS_data(&d)); | ||
126 | free((void *)CBS_data(&ek)); | ||
127 | free((void *)CBS_data(&dk)); | ||
128 | 185 | ||
129 | test_number++; | ||
130 | state = S_START; | 186 | state = S_START; |
131 | break; | 187 | break; |
132 | } | 188 | } |
133 | } | 189 | } |
134 | |||
135 | free(buf); | 190 | free(buf); |
191 | |||
192 | if (ferror(fp)) | ||
193 | err(1, NULL); | ||
136 | fclose(fp); | 194 | fclose(fp); |
137 | exit(failure); | 195 | |
196 | return failed; | ||
138 | } | 197 | } |