summaryrefslogtreecommitdiff
path: root/src/regress/lib/libcrypto/mlkem/mlkem768_decap_tests.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/regress/lib/libcrypto/mlkem/mlkem768_decap_tests.c')
-rw-r--r--src/regress/lib/libcrypto/mlkem/mlkem768_decap_tests.c201
1 files changed, 134 insertions, 67 deletions
diff --git a/src/regress/lib/libcrypto/mlkem/mlkem768_decap_tests.c b/src/regress/lib/libcrypto/mlkem/mlkem768_decap_tests.c
index 96dc435c4d..a88e487494 100644
--- a/src/regress/lib/libcrypto/mlkem/mlkem768_decap_tests.c
+++ b/src/regress/lib/libcrypto/mlkem/mlkem768_decap_tests.c
@@ -1,7 +1,8 @@
1/* $OpenBSD: mlkem768_decap_tests.c,v 1.2 2024/12/14 19:16:24 tb Exp $ */ 1/* $OpenBSD: mlkem768_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
29static void 31static int
30MlkemDecapFileTest(CBS *c, CBS *k, CBS *dk, int should_fail) 32MlkemDecapFileTest(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 MLKEM768_private_key priv; 35 struct MLKEM768_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 = MLKEM768_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 (!MLKEM768_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 (!MLKEM768_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 = MLKEM768_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
92static const char *
93state2str(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
58int 107int
59main(int argc, char **argv) 108main(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}