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