diff options
author | jsing <> | 2024-03-30 00:36:14 +0000 |
---|---|---|
committer | jsing <> | 2024-03-30 00:36:14 +0000 |
commit | f93ebad367414e3ee827e03ec992d0424605943c (patch) | |
tree | 4164f8ee7c42395b982b356d27a859b7fab9608b | |
parent | 0ec9ff0c1e847d54b79c84237ed21fe4ab857b7c (diff) | |
download | openbsd-f93ebad367414e3ee827e03ec992d0424605943c.tar.gz openbsd-f93ebad367414e3ee827e03ec992d0424605943c.tar.bz2 openbsd-f93ebad367414e3ee827e03ec992d0424605943c.zip |
Add initial regress for RSA padding.
-rw-r--r-- | src/regress/lib/libcrypto/rsa/Makefile | 5 | ||||
-rw-r--r-- | src/regress/lib/libcrypto/rsa/rsa_padding_test.c | 325 |
2 files changed, 328 insertions, 2 deletions
diff --git a/src/regress/lib/libcrypto/rsa/Makefile b/src/regress/lib/libcrypto/rsa/Makefile index 53065e6408..494d40d867 100644 --- a/src/regress/lib/libcrypto/rsa/Makefile +++ b/src/regress/lib/libcrypto/rsa/Makefile | |||
@@ -1,6 +1,7 @@ | |||
1 | # $OpenBSD: Makefile,v 1.3 2024/03/30 00:34:40 jsing Exp $ | 1 | # $OpenBSD: Makefile,v 1.4 2024/03/30 00:36:14 jsing Exp $ |
2 | 2 | ||
3 | PROG= rsa_test | 3 | PROGS= rsa_test \ |
4 | rsa_padding_test | ||
4 | LDADD= -lcrypto | 5 | LDADD= -lcrypto |
5 | DPADD= ${LIBCRYPTO} | 6 | DPADD= ${LIBCRYPTO} |
6 | WARNINGS= Yes | 7 | WARNINGS= Yes |
diff --git a/src/regress/lib/libcrypto/rsa/rsa_padding_test.c b/src/regress/lib/libcrypto/rsa/rsa_padding_test.c new file mode 100644 index 0000000000..64357bf405 --- /dev/null +++ b/src/regress/lib/libcrypto/rsa/rsa_padding_test.c | |||
@@ -0,0 +1,325 @@ | |||
1 | /* $OpenBSD: rsa_padding_test.c,v 1.1 2024/03/30 00:36:14 jsing Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2024 Joel Sing <jsing@openbsd.org> | ||
4 | * | ||
5 | * Permission to use, copy, modify, and distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | */ | ||
17 | |||
18 | #include <stdint.h> | ||
19 | #include <string.h> | ||
20 | |||
21 | #include <openssl/err.h> | ||
22 | #include <openssl/rsa.h> | ||
23 | |||
24 | #if 0 | ||
25 | static void | ||
26 | hexdump(const unsigned char *buf, size_t len) | ||
27 | { | ||
28 | size_t i; | ||
29 | |||
30 | for (i = 1; i <= len; i++) | ||
31 | fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); | ||
32 | |||
33 | fprintf(stderr, "\n"); | ||
34 | } | ||
35 | #endif | ||
36 | |||
37 | struct pkcs1_test { | ||
38 | uint8_t in[128]; | ||
39 | size_t in_len; | ||
40 | int want; | ||
41 | int want_error; | ||
42 | }; | ||
43 | |||
44 | static const struct pkcs1_test pkcs1_type1_tests[] = { | ||
45 | { | ||
46 | .in = { | ||
47 | 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
48 | 0xff, 0xff, 0xff, 0xff, 0x00, 0x6f, 0x6f, 0x6f, | ||
49 | 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, | ||
50 | 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, | ||
51 | }, | ||
52 | .in_len = 32, | ||
53 | .want = 19, | ||
54 | }, | ||
55 | { | ||
56 | .in = { | ||
57 | 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
58 | 0xff, 0xff, 0x00, | ||
59 | }, | ||
60 | .in_len = 11, | ||
61 | .want = 0, | ||
62 | }, | ||
63 | { | ||
64 | .in = { | ||
65 | 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
66 | 0xff, 0xff, 0x00, 0xff, | ||
67 | }, | ||
68 | .in_len = 12, | ||
69 | .want = 1, | ||
70 | }, | ||
71 | { | ||
72 | /* Insufficient padding bytes (< 8). */ | ||
73 | .in = { | ||
74 | 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
75 | 0xff, 0x00, 0xff, 0xff, | ||
76 | }, | ||
77 | .in_len = 12, | ||
78 | .want = -1, | ||
79 | .want_error = RSA_R_BAD_PAD_BYTE_COUNT, | ||
80 | }, | ||
81 | { | ||
82 | /* Incorrect padding type (0x00). */ | ||
83 | .in = { | ||
84 | 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
85 | 0xff, 0xff, 0x00, 0xff, | ||
86 | }, | ||
87 | .in_len = 12, | ||
88 | .want = -1, | ||
89 | .want_error = RSA_R_BLOCK_TYPE_IS_NOT_01, | ||
90 | }, | ||
91 | { | ||
92 | /* Incorrect padding type (0x02). */ | ||
93 | .in = { | ||
94 | 0x00, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
95 | 0xff, 0xff, 0x00, 0xff, | ||
96 | }, | ||
97 | .in_len = 12, | ||
98 | .want = -1, | ||
99 | .want_error = RSA_R_BLOCK_TYPE_IS_NOT_01, | ||
100 | }, | ||
101 | { | ||
102 | /* Non-padding byte before end of padding marker. */ | ||
103 | .in = { | ||
104 | 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
105 | 0xff, 0xfe, 0x00, 0xff, | ||
106 | }, | ||
107 | .in_len = 12, | ||
108 | .want = -1, | ||
109 | .want_error = RSA_R_BAD_FIXED_HEADER_DECRYPT, | ||
110 | }, | ||
111 | { | ||
112 | /* No end of padding marker. */ | ||
113 | .in = { | ||
114 | 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
115 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
116 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
117 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
118 | }, | ||
119 | .in_len = 32, | ||
120 | .want = -1, | ||
121 | .want_error = RSA_R_NULL_BEFORE_BLOCK_MISSING, | ||
122 | }, | ||
123 | }; | ||
124 | |||
125 | #define N_PKCS1_TYPE1_TESTS \ | ||
126 | (sizeof(pkcs1_type1_tests) / sizeof(pkcs1_type1_tests[0])) | ||
127 | |||
128 | static int | ||
129 | test_pkcs1_type1(void) | ||
130 | { | ||
131 | const struct pkcs1_test *pt; | ||
132 | uint8_t buf[32], in[19], out[512]; | ||
133 | int pad_len; | ||
134 | long err; | ||
135 | size_t i; | ||
136 | int failed = 1; | ||
137 | |||
138 | memset(in, 0x6f, sizeof(in)); | ||
139 | |||
140 | if (!RSA_padding_add_PKCS1_type_1(buf, sizeof(buf), in, sizeof(in))) { | ||
141 | fprintf(stderr, "FAIL: failed to add PKCS1 type 1 padding\n"); | ||
142 | goto failed; | ||
143 | } | ||
144 | |||
145 | pad_len = RSA_padding_check_PKCS1_type_1(out, sizeof(out) - 1, | ||
146 | buf + 1, sizeof(buf) - 1, sizeof(buf)); | ||
147 | if (pad_len != sizeof(in)) { | ||
148 | fprintf(stderr, "FAIL: failed to check PKCS1 type 1 padding\n"); | ||
149 | ERR_print_errors_fp(stderr); | ||
150 | goto failed; | ||
151 | } | ||
152 | |||
153 | for (i = 0; i < N_PKCS1_TYPE1_TESTS; i++) { | ||
154 | pt = &pkcs1_type1_tests[i]; | ||
155 | |||
156 | ERR_clear_error(); | ||
157 | |||
158 | pad_len = RSA_padding_check_PKCS1_type_1(out, sizeof(out) - 1, | ||
159 | pt->in + 1, pt->in_len - 1, pt->in_len); | ||
160 | |||
161 | if (pad_len != pt->want) { | ||
162 | fprintf(stderr, "FAIL: test %zu - failed to check " | ||
163 | "PKCS1 type 1 padding (%d != %d)\n", i, pad_len, | ||
164 | pt->want); | ||
165 | ERR_print_errors_fp(stderr); | ||
166 | goto failed; | ||
167 | } | ||
168 | |||
169 | err = ERR_peek_error(); | ||
170 | if (pt->want == -1 && ERR_GET_REASON(err) != pt->want_error) { | ||
171 | fprintf(stderr, "FAIL: test %zu - PKCS1 type 1 padding " | ||
172 | "check failed with error reason %i, want %i\n", | ||
173 | i, ERR_GET_REASON(err), pt->want_error); | ||
174 | ERR_print_errors_fp(stderr); | ||
175 | goto failed; | ||
176 | } | ||
177 | } | ||
178 | |||
179 | failed = 0; | ||
180 | |||
181 | failed: | ||
182 | return failed; | ||
183 | } | ||
184 | |||
185 | static const struct pkcs1_test pkcs1_type2_tests[] = { | ||
186 | { | ||
187 | .in = { | ||
188 | 0x00, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
189 | 0xff, 0xff, 0xff, 0xff, 0x00, 0x6f, 0x6f, 0x6f, | ||
190 | 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, | ||
191 | 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, | ||
192 | }, | ||
193 | .in_len = 32, | ||
194 | .want = 19, | ||
195 | }, | ||
196 | { | ||
197 | .in = { | ||
198 | 0x00, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
199 | 0xff, 0xff, 0x00, | ||
200 | }, | ||
201 | .in_len = 11, | ||
202 | .want = 0, | ||
203 | }, | ||
204 | { | ||
205 | .in = { | ||
206 | 0x00, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
207 | 0xff, 0xff, 0x00, 0xff, | ||
208 | }, | ||
209 | .in_len = 12, | ||
210 | .want = 1, | ||
211 | }, | ||
212 | { | ||
213 | /* Insufficient padding bytes (< 8). */ | ||
214 | .in = { | ||
215 | 0x00, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
216 | 0xff, 0x00, 0xff, 0xff, | ||
217 | }, | ||
218 | .in_len = 12, | ||
219 | .want = -1, | ||
220 | .want_error = RSA_R_BAD_PAD_BYTE_COUNT, | ||
221 | }, | ||
222 | { | ||
223 | /* Incorrect padding type (0x00). */ | ||
224 | .in = { | ||
225 | 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
226 | 0xff, 0xff, 0x00, 0xff, | ||
227 | }, | ||
228 | .in_len = 12, | ||
229 | .want = -1, | ||
230 | .want_error = RSA_R_BLOCK_TYPE_IS_NOT_02, | ||
231 | }, | ||
232 | { | ||
233 | /* Incorrect padding type (0x01). */ | ||
234 | .in = { | ||
235 | 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
236 | 0xff, 0xff, 0x00, 0xff, | ||
237 | }, | ||
238 | .in_len = 12, | ||
239 | .want = -1, | ||
240 | .want_error = RSA_R_BLOCK_TYPE_IS_NOT_02, | ||
241 | }, | ||
242 | { | ||
243 | /* No end of padding marker. */ | ||
244 | .in = { | ||
245 | 0x00, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
246 | 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0x6f, 0x6f, | ||
247 | 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, | ||
248 | 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, | ||
249 | }, | ||
250 | .in_len = 32, | ||
251 | .want = -1, | ||
252 | .want_error = RSA_R_NULL_BEFORE_BLOCK_MISSING, | ||
253 | }, | ||
254 | }; | ||
255 | |||
256 | #define N_PKCS1_TYPE2_TESTS \ | ||
257 | (sizeof(pkcs1_type2_tests) / sizeof(pkcs1_type2_tests[0])) | ||
258 | |||
259 | static int | ||
260 | test_pkcs1_type2(void) | ||
261 | { | ||
262 | const struct pkcs1_test *pt; | ||
263 | uint8_t buf[32], in[19], out[32]; | ||
264 | int pad_len; | ||
265 | long err; | ||
266 | size_t i; | ||
267 | int failed = 1; | ||
268 | |||
269 | memset(in, 0x6f, sizeof(in)); | ||
270 | |||
271 | if (!RSA_padding_add_PKCS1_type_2(buf, sizeof(buf), in, sizeof(in))) { | ||
272 | fprintf(stderr, "FAIL: failed to add PKCS1 type 2 padding\n"); | ||
273 | goto failed; | ||
274 | } | ||
275 | |||
276 | pad_len = RSA_padding_check_PKCS1_type_2(out, sizeof(out) - 1, | ||
277 | buf + 1, sizeof(buf) - 1, sizeof(out)); | ||
278 | if (pad_len != sizeof(in)) { | ||
279 | fprintf(stderr, "FAIL: failed to check PKCS1 type 2 padding\n"); | ||
280 | ERR_print_errors_fp(stderr); | ||
281 | goto failed; | ||
282 | } | ||
283 | |||
284 | for (i = 0; i < N_PKCS1_TYPE2_TESTS; i++) { | ||
285 | pt = &pkcs1_type2_tests[i]; | ||
286 | |||
287 | ERR_clear_error(); | ||
288 | |||
289 | pad_len = RSA_padding_check_PKCS1_type_2(out, sizeof(out) - 1, | ||
290 | pt->in + 1, pt->in_len - 1, pt->in_len); | ||
291 | |||
292 | if (pad_len != pt->want) { | ||
293 | fprintf(stderr, "FAIL: test %zu - failed to check " | ||
294 | "PKCS1 type 2 padding (%d != %d)\n", i, pad_len, | ||
295 | pt->want); | ||
296 | ERR_print_errors_fp(stderr); | ||
297 | goto failed; | ||
298 | } | ||
299 | |||
300 | err = ERR_peek_error(); | ||
301 | if (pt->want == -1 && ERR_GET_REASON(err) != pt->want_error) { | ||
302 | fprintf(stderr, "FAIL: test %zu - PKCS1 type 2 padding " | ||
303 | "check failed with error reason %i, want %i\n", | ||
304 | i, ERR_GET_REASON(err), pt->want_error); | ||
305 | ERR_print_errors_fp(stderr); | ||
306 | goto failed; | ||
307 | } | ||
308 | } | ||
309 | |||
310 | failed = 0; | ||
311 | |||
312 | failed: | ||
313 | return failed; | ||
314 | } | ||
315 | |||
316 | int | ||
317 | main(int argc, char **argv) | ||
318 | { | ||
319 | int failed = 0; | ||
320 | |||
321 | failed |= test_pkcs1_type1(); | ||
322 | failed |= test_pkcs1_type2(); | ||
323 | |||
324 | return failed; | ||
325 | } | ||