diff options
Diffstat (limited to 'src/regress/lib/libcrypto/mlkem/mlkem1024_decap_tests.c')
-rw-r--r-- | src/regress/lib/libcrypto/mlkem/mlkem1024_decap_tests.c | 201 |
1 files changed, 134 insertions, 67 deletions
diff --git a/src/regress/lib/libcrypto/mlkem/mlkem1024_decap_tests.c b/src/regress/lib/libcrypto/mlkem/mlkem1024_decap_tests.c index b38cd52d28..c75b2c7ca8 100644 --- a/src/regress/lib/libcrypto/mlkem/mlkem1024_decap_tests.c +++ b/src/regress/lib/libcrypto/mlkem/mlkem1024_decap_tests.c | |||
@@ -1,7 +1,8 @@ | |||
1 | /* $OpenBSD: mlkem1024_decap_tests.c,v 1.2 2024/12/14 19:16:24 tb Exp $ */ | 1 | /* $OpenBSD: mlkem1024_decap_tests.c,v 1.3 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,113 +17,179 @@ | |||
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_tests_util.h" | 29 | #include "mlkem_tests_util.h" |
28 | 30 | ||
29 | static void | 31 | static int |
30 | MlkemDecapFileTest(CBS *c, CBS *k, CBS *dk, int should_fail) | 32 | MlkemDecapFileTest(CBB *ciphertext_cbb, CBB *shared_secret_cbb, |
33 | CBB *private_key_cbb, int should_fail, size_t line) | ||
31 | { | 34 | { |
32 | uint8_t shared_secret[MLKEM_SHARED_SECRET_BYTES]; | ||
33 | struct MLKEM1024_private_key priv; | 35 | struct MLKEM1024_private_key priv; |
34 | int parse_ok, decap_ok; | 36 | uint8_t *ciphertext = NULL, *shared_secret = NULL, *private_key = NULL; |
37 | size_t ciphertext_len = 0, shared_secret_len = 0, private_key_len = 0; | ||
38 | uint8_t shared_secret_buf[MLKEM_SHARED_SECRET_BYTES]; | ||
39 | CBS private_key_cbs; | ||
40 | int failed = 1; | ||
35 | 41 | ||
36 | parse_ok = MLKEM1024_parse_private_key(&priv, dk); | 42 | if (!CBB_finish(ciphertext_cbb, &ciphertext, &ciphertext_len)) |
37 | if (!parse_ok) { | 43 | goto err; |
38 | TEST(!should_fail, "parse_private_key"); | 44 | if (!CBB_finish(shared_secret_cbb, &shared_secret, &shared_secret_len)) |
39 | return; | 45 | goto err; |
46 | if (!CBB_finish(private_key_cbb, &private_key, &private_key_len)) | ||
47 | goto err; | ||
48 | |||
49 | CBS_init(&private_key_cbs, private_key, private_key_len); | ||
50 | |||
51 | if (!MLKEM1024_parse_private_key(&priv, &private_key_cbs)) { | ||
52 | if ((failed = !should_fail)) | ||
53 | warnx("#%zu: parse_private_key", line); | ||
54 | goto err; | ||
55 | } | ||
56 | if (!MLKEM1024_decap(shared_secret_buf, ciphertext, ciphertext_len, | ||
57 | &priv)) { | ||
58 | if ((failed = !should_fail)) | ||
59 | warnx("#%zu: decap", line); | ||
60 | goto err; | ||
40 | } | 61 | } |
41 | decap_ok = MLKEM1024_decap(shared_secret, CBS_data(c), CBS_len(c), | 62 | |
42 | &priv); | 63 | failed = compare_data(shared_secret, shared_secret_buf, |
43 | if (!decap_ok) { | 64 | MLKEM_SHARED_SECRET_BYTES, line, "shared_secret"); |
44 | TEST(!should_fail, "decap"); | 65 | |
45 | return; | 66 | if (should_fail != failed) { |
67 | warnx("FAIL: #%zu: should_fail %d, failed %d", | ||
68 | line, should_fail, failed); | ||
69 | failed = 1; | ||
46 | } | 70 | } |
47 | TEST_DATAEQ(shared_secret, CBS_data(k), | 71 | |
48 | MLKEM_SHARED_SECRET_BYTES, "shared_secret"); | 72 | err: |
73 | CBB_cleanup(ciphertext_cbb); | ||
74 | CBB_cleanup(shared_secret_cbb); | ||
75 | CBB_cleanup(private_key_cbb); | ||
76 | freezero(ciphertext, ciphertext_len); | ||
77 | freezero(shared_secret, shared_secret_len); | ||
78 | freezero(private_key, private_key_len); | ||
79 | |||
80 | return failed; | ||
49 | } | 81 | } |
50 | 82 | ||
51 | #define S_START 0 | 83 | #define S_START 0 |
52 | #define S_COMMENT 1 | 84 | #define S_COMMENT 1 |
53 | #define S_PRIVATE_KEY 2 | 85 | #define S_PRIVATE_KEY 2 |
54 | #define S_CIPHERTEXT 3 | 86 | #define S_CIPHERTEXT 3 |
55 | #define S_RESULT 4 | 87 | #define S_RESULT 4 |
56 | #define S_SHARED_SECRET 5 | 88 | #define S_SHARED_SECRET 5 |
89 | |||
90 | #define S2S(x) case x: return #x | ||
91 | |||
92 | static const char * | ||
93 | state2str(int state) | ||
94 | { | ||
95 | switch (state) { | ||
96 | S2S(S_START); | ||
97 | S2S(S_COMMENT); | ||
98 | S2S(S_PRIVATE_KEY); | ||
99 | S2S(S_CIPHERTEXT); | ||
100 | S2S(S_RESULT); | ||
101 | S2S(S_SHARED_SECRET); | ||
102 | default: | ||
103 | errx(1, "unknown state %d", state); | ||
104 | } | ||
105 | } | ||
57 | 106 | ||
58 | int | 107 | int |
59 | main(int argc, char **argv) | 108 | main(int argc, char **argv) |
60 | { | 109 | { |
61 | CBS ciphertext, shared_secret, private_key; | 110 | CBB ciphertext = { 0 }, shared_secret = { 0 }, private_key = { 0 }; |
62 | const uint8_t *p = NULL; | ||
63 | int should_fail = 0; | 111 | int should_fail = 0; |
64 | char *buf; | 112 | const char *test; |
113 | size_t line = 0; | ||
114 | char *buf = NULL; | ||
115 | size_t buflen = 0; | ||
116 | ssize_t len; | ||
65 | FILE *fp; | 117 | FILE *fp; |
66 | int state; | 118 | int state; |
119 | int failed = 0; | ||
120 | |||
121 | if (argc < 2) | ||
122 | errx(1, "%s: missing test file", argv[0]); | ||
123 | |||
124 | test = argv[1]; | ||
125 | |||
126 | if ((fp = fopen(test, "r")) == NULL) | ||
127 | err(1, "cant't open test file"); | ||
67 | 128 | ||
68 | fprintf(stderr, "Testing decap test vectors in %s\n", argv[1]); | ||
69 | TEST((fp = fopen(argv[1], "r")) == NULL, "can't open test file"); | ||
70 | MALLOC(buf, 16*1024); | ||
71 | state = S_COMMENT; | 129 | state = S_COMMENT; |
72 | test_number = 1; | 130 | line = 0; |
73 | while (fgets(buf, 16*1024, fp) != NULL) { | 131 | |
132 | while ((len = getline(&buf, &buflen, fp)) != -1) { | ||
133 | const char *msg = state2str(state); | ||
134 | CBS cbs; | ||
135 | uint8_t u8; | ||
136 | |||
137 | line++; | ||
138 | CBS_init(&cbs, buf, len); | ||
139 | |||
140 | if (!CBS_get_last_u8(&cbs, &u8)) | ||
141 | errx(1, "#%zu %s: CBB_get_last_u8", line, msg); | ||
142 | assert(u8 == '\n'); | ||
143 | |||
74 | switch (state) { | 144 | switch (state) { |
75 | case S_START: | 145 | case S_START: |
76 | if (strcmp(buf, "\n") != 0) | ||
77 | break; | ||
78 | state = S_COMMENT; | 146 | state = S_COMMENT; |
79 | break; | 147 | break; |
80 | case S_COMMENT: | 148 | case S_COMMENT: |
81 | if (strncmp(buf, "#", 1) != 0) | 149 | if (!CBS_get_u8(&cbs, &u8)) |
82 | break; | 150 | errx(1, "#%zu %s: CBB_get_u8", line, msg); |
151 | assert(u8 == '#'); | ||
152 | if (!CBS_skip(&cbs, CBS_len(&cbs))) | ||
153 | errx(1, "#%zu %s: CBB_skip", line, msg); | ||
83 | state = S_PRIVATE_KEY; | 154 | state = S_PRIVATE_KEY; |
84 | break; | 155 | break; |
85 | case S_PRIVATE_KEY: | 156 | case S_PRIVATE_KEY: |
86 | if (strncmp(buf, "private_key: ", | 157 | if (!get_string_cbs(&cbs, "private_key: ", line, msg)) |
87 | strlen("private_key: ")) != 0) | 158 | errx(1, "#%zu %s: get_string_cbs", line, msg); |
88 | break; | 159 | hex_decode_cbs(&cbs, &private_key, line, msg); |
89 | grab_data(&private_key, buf, strlen("private_key: ")); | ||
90 | p = CBS_data(&private_key); | ||
91 | state = S_CIPHERTEXT; | 160 | state = S_CIPHERTEXT; |
92 | break; | 161 | break; |
93 | case S_CIPHERTEXT: | 162 | case S_CIPHERTEXT: |
94 | if (strncmp(buf, "ciphertext: ", | 163 | if (!get_string_cbs(&cbs, "ciphertext: ", line, msg)) |
95 | strlen("ciphertext: ")) != 0) | 164 | errx(1, "#%zu %s: get_string_cbs", line, msg); |
96 | break; | 165 | hex_decode_cbs(&cbs, &ciphertext, line, msg); |
97 | grab_data(&ciphertext, buf, strlen("ciphertext: ")); | ||
98 | state = S_RESULT; | 166 | state = S_RESULT; |
99 | break; | 167 | break; |
100 | case S_RESULT: | 168 | case S_RESULT: |
101 | if (strncmp(buf, "result: pass", | 169 | if (!get_string_cbs(&cbs, "result: ", line, msg)) |
102 | strlen("result: pass")) != 0) | 170 | errx(1, "#%zu %s: get_string_cbs", line, msg); |
103 | should_fail = 1; | 171 | should_fail = get_string_cbs(&cbs, "fail", line, msg); |
104 | else | ||
105 | should_fail = 0; | ||
106 | state = S_SHARED_SECRET; | 172 | state = S_SHARED_SECRET; |
107 | break; | 173 | break; |
108 | case S_SHARED_SECRET: | 174 | case S_SHARED_SECRET: |
109 | if (strncmp(buf, "shared_secret: ", | 175 | if (!get_string_cbs(&cbs, "shared_secret: ", line, msg)) |
110 | strlen("shared_secret: ")) != 0) | 176 | errx(1, "#%zu %s: get_string_cbs", line, msg); |
111 | break; | 177 | hex_decode_cbs(&cbs, &shared_secret, line, msg); |
112 | grab_data(&shared_secret, buf, | 178 | |
113 | strlen("shared_secret: ")); | 179 | failed |= MlkemDecapFileTest(&ciphertext, &shared_secret, |
114 | MlkemDecapFileTest(&ciphertext, &shared_secret, | 180 | &private_key, should_fail, line); |
115 | &private_key, should_fail); | 181 | |
116 | free((void *)CBS_data(&ciphertext)); | ||
117 | free((void *)CBS_data(&shared_secret)); | ||
118 | free((void *)p); | ||
119 | |||
120 | test_number++; | ||
121 | state = S_START; | 182 | state = S_START; |
122 | break; | 183 | break; |
123 | } | 184 | } |
185 | if (CBS_len(&cbs) > 0) | ||
186 | errx(1, "#%zu %s: CBS_len", line, msg); | ||
124 | } | 187 | } |
125 | |||
126 | free(buf); | 188 | free(buf); |
127 | exit(failure); | 189 | |
190 | if (ferror(fp)) | ||
191 | err(1, NULL); | ||
192 | fclose(fp); | ||
193 | |||
194 | return failed; | ||
128 | } | 195 | } |