b817bfc6 |
1 | /* -*-c-*- |
b817bfc6 |
2 | * |
3 | * Testing RSA padding operations |
4 | * |
5 | * (c) 2004 Straylight/Edgeware |
6 | */ |
7 | |
45c0fd36 |
8 | /*----- Licensing notice --------------------------------------------------* |
b817bfc6 |
9 | * |
10 | * This file is part of Catacomb. |
11 | * |
12 | * Catacomb is free software; you can redistribute it and/or modify |
13 | * it under the terms of the GNU Library General Public License as |
14 | * published by the Free Software Foundation; either version 2 of the |
15 | * License, or (at your option) any later version. |
45c0fd36 |
16 | * |
b817bfc6 |
17 | * Catacomb is distributed in the hope that it will be useful, |
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
20 | * GNU Library General Public License for more details. |
45c0fd36 |
21 | * |
b817bfc6 |
22 | * You should have received a copy of the GNU Library General Public |
23 | * License along with Catacomb; if not, write to the Free |
24 | * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, |
25 | * MA 02111-1307, USA. |
26 | */ |
27 | |
28 | /*----- Header files ------------------------------------------------------*/ |
29 | |
30 | #include "fibrand.h" |
31 | #include "rsa.h" |
32 | |
33 | /*----- Main code ---------------------------------------------------------*/ |
34 | |
35 | static int tencpad(int nbits, |
36 | dstr *p, int rc, mp *c, |
37 | const char *ename, dstr *eparam, rsa_pad *e, void *earg) |
38 | { |
39 | size_t n = (nbits + 7)/8; |
40 | void *q = xmalloc(n); |
41 | mp *d; |
42 | int ok = 1; |
43 | |
44 | d = e(MP_NEW, p->buf, p->len, q, n, nbits, earg); |
45 | if (!d == !rc || (!rc && !MP_EQ(d, c))) { |
46 | ok = 0; |
47 | fprintf(stderr, "*** %s padding failed!\n", ename); |
48 | fprintf(stderr, "*** padding bits = %d\n", nbits); |
49 | if (eparam) { |
50 | fprintf(stderr, "*** encoding parameters = "); |
51 | type_hex.dump(eparam, stderr); |
52 | fputc('\n', stderr); |
53 | } |
54 | fprintf(stderr, "*** input message = "); type_hex.dump(p, stderr); |
55 | if (rc) |
56 | fprintf(stderr, "\n*** expected failure\n"); |
57 | else { |
58 | MP_EPRINTX("\n*** expected", c); |
59 | MP_EPRINTX("*** computed", d); |
60 | } |
61 | } |
62 | mp_drop(d); |
63 | mp_drop(c); |
64 | xfree(q); |
65 | assert(mparena_count(MPARENA_GLOBAL) == 0); |
45c0fd36 |
66 | return (ok); |
b817bfc6 |
67 | } |
68 | |
69 | #define tsigpad tencpad |
70 | |
71 | #define DSTR_EQ(x, y) \ |
72 | ((x)->len == (y)->len && !memcmp((x)->buf, (y)->buf, (x)->len)) |
73 | |
74 | static int tdecpad(int nbits, |
75 | mp *c, int rc, dstr *p, |
76 | const char *ename, dstr *eparam, |
77 | rsa_decunpad *e, void *earg) |
78 | { |
79 | dstr d = DSTR_INIT; |
80 | int n = (nbits + 7)/8; |
81 | int ok = 1; |
82 | |
83 | dstr_ensure(&d, n); |
84 | n = e(c, (octet *)d.buf, n, nbits, earg); |
85 | if (n >= 0) |
86 | d.len += n; |
87 | if (n != rc || (rc >= 0 && !DSTR_EQ(&d, p))) { |
88 | ok = 0; |
89 | fprintf(stderr, "*** %s encryption unpadding failed!\n", ename); |
90 | fprintf(stderr, "*** padding bits = %d\n", nbits); |
91 | if (eparam) { |
92 | fprintf(stderr, "*** encoding parameters = "); |
93 | type_hex.dump(eparam, stderr); |
94 | fputc('\n', stderr); |
95 | } |
96 | MP_EPRINTX("*** input", c); |
97 | if (rc < 0) |
98 | fprintf(stderr, "*** expected failure\n"); |
99 | else { |
100 | fprintf(stderr, "*** expected: %d = ", rc); type_hex.dump(p, stderr); |
101 | fprintf(stderr, "\n*** computed: %d = ", n); type_hex.dump(&d, stderr); |
102 | fprintf(stderr, "\n"); |
103 | } |
104 | } |
105 | mp_drop(c); |
106 | dstr_destroy(&d); |
107 | assert(mparena_count(MPARENA_GLOBAL) == 0); |
45c0fd36 |
108 | return (ok); |
b817bfc6 |
109 | } |
110 | |
111 | static int tvrfpad(int nbits, |
112 | mp *c, dstr *m, int rc, dstr *p, |
113 | const char *ename, dstr *eparam, |
114 | rsa_vrfunpad *e, void *earg) |
115 | { |
116 | dstr d = DSTR_INIT; |
117 | int n = (nbits + 7)/8; |
118 | int ok = 1; |
119 | |
120 | dstr_ensure(&d, n); |
121 | n = e(c, m->len ? (octet *)m->buf : 0, m->len, |
122 | (octet *)d.buf, n, nbits, earg); |
123 | if (n >= 0) |
124 | d.len += n; |
125 | if (n != rc || (rc >= 0 && !DSTR_EQ(&d, p))) { |
126 | ok = 0; |
127 | fprintf(stderr, "*** %s signature unpadding failed!\n", ename); |
128 | fprintf(stderr, "*** padding bits = %d\n", nbits); |
129 | MP_EPRINTX("*** input", c); |
130 | if (eparam) { |
131 | fprintf(stderr, "*** encoding parameters = "); |
132 | type_hex.dump(eparam, stderr); |
133 | fputc('\n', stderr); |
134 | } |
135 | fprintf(stderr, "*** message = "); type_hex.dump(m, stderr); |
136 | if (rc < 0) |
137 | fprintf(stderr, "\n*** expected failure\n"); |
138 | else { |
139 | fprintf(stderr, "\n*** expected = %d: ", rc); type_hex.dump(p, stderr); |
140 | fprintf(stderr, "\n*** computed = %d: ", n); type_hex.dump(&d, stderr); |
141 | fprintf(stderr, "\n"); |
142 | } |
143 | } |
144 | mp_drop(c); |
145 | dstr_destroy(&d); |
146 | assert(mparena_count(MPARENA_GLOBAL) == 0); |
45c0fd36 |
147 | return (ok); |
b817bfc6 |
148 | } |
149 | |
150 | static int tencpub(rsa_pub *rp, |
151 | dstr *p, int rc, mp *c, |
152 | const char *ename, dstr *eparam, rsa_pad *e, void *earg) |
153 | { |
154 | mp *d; |
155 | rsa_pubctx rpc; |
156 | int ok = 1; |
157 | |
158 | rsa_pubcreate(&rpc, rp); |
159 | d = rsa_encrypt(&rpc, MP_NEW, p->buf, p->len, e, earg); |
160 | if (!d == !rc || (!rc && !MP_EQ(d, c))) { |
161 | ok = 0; |
162 | fprintf(stderr, "*** encrypt with %s padding failed!\n", ename); |
163 | MP_EPRINTX("*** key.n", rp->n); |
164 | MP_EPRINTX("*** key.e", rp->e); |
165 | if (eparam) { |
166 | fprintf(stderr, "*** encoding parameters = "); |
167 | type_hex.dump(eparam, stderr); |
168 | fputc('\n', stderr); |
169 | } |
170 | fprintf(stderr, "*** input message = "); type_hex.dump(p, stderr); |
171 | if (rc) |
172 | fprintf(stderr, "\n*** expected failure\n"); |
173 | else { |
174 | MP_EPRINTX("\n*** expected", c); |
175 | MP_EPRINTX("*** computed", d); |
176 | } |
177 | } |
178 | rsa_pubdestroy(&rpc); |
179 | rsa_pubfree(rp); |
180 | mp_drop(d); |
181 | mp_drop(c); |
182 | assert(mparena_count(MPARENA_GLOBAL) == 0); |
183 | return (ok); |
184 | } |
185 | |
186 | static int tsigpriv(rsa_priv *rp, |
187 | dstr *p, int rc, mp *c, |
188 | const char *ename, dstr *eparam, rsa_pad *e, void *earg) |
189 | { |
190 | mp *d; |
191 | grand *r = fibrand_create(0); |
192 | rsa_privctx rpc; |
193 | int ok = 1; |
194 | |
195 | rsa_privcreate(&rpc, rp, r); |
196 | d = rsa_sign(&rpc, MP_NEW, p->buf, p->len, e, earg); |
197 | if (!d == !rc || (!rc && !MP_EQ(d, c))) { |
198 | ok = 0; |
199 | fprintf(stderr, "*** sign with %s padding failed!\n", ename); |
200 | MP_EPRINTX("*** key.n", rp->n); |
201 | MP_EPRINTX("*** key.d", rp->d); |
202 | MP_EPRINTX("*** key.e", rp->e); |
203 | if (eparam) { |
204 | fprintf(stderr, "*** encoding parameters = "); |
205 | type_hex.dump(eparam, stderr); |
206 | fputc('\n', stderr); |
207 | } |
208 | fprintf(stderr, "*** input message = "); type_hex.dump(p, stderr); |
209 | if (rc) |
210 | fprintf(stderr, "\n*** expected failure\n"); |
211 | else { |
212 | MP_EPRINTX("\n*** expected", c); |
213 | MP_EPRINTX("\n*** computed", d); |
214 | } |
215 | } |
216 | rsa_privdestroy(&rpc); |
217 | rsa_privfree(rp); |
218 | mp_drop(d); |
219 | mp_drop(c); |
220 | GR_DESTROY(r); |
221 | assert(mparena_count(MPARENA_GLOBAL) == 0); |
222 | return (ok); |
223 | } |
224 | |
225 | static int tdecpriv(rsa_priv *rp, |
226 | mp *c, int rc, dstr *p, |
227 | const char *ename, dstr *eparam, |
228 | rsa_decunpad *e, void *earg) |
229 | { |
230 | rsa_privctx rpc; |
231 | dstr d = DSTR_INIT; |
232 | grand *r = fibrand_create(0); |
233 | int n; |
234 | int ok = 1; |
235 | |
236 | rsa_privcreate(&rpc, rp, r); |
237 | n = rsa_decrypt(&rpc, c, &d, e, earg); |
238 | if (n != rc || (rc >= 0 && !DSTR_EQ(&d, p))) { |
239 | ok = 0; |
240 | fprintf(stderr, "*** decryption with %s padding failed!\n", ename); |
241 | MP_EPRINTX("*** key.n", rp->n); |
242 | MP_EPRINTX("*** key.d", rp->d); |
243 | MP_EPRINTX("*** key.e", rp->e); |
244 | if (eparam) { |
245 | fprintf(stderr, "*** encoding parameters = "); |
246 | type_hex.dump(eparam, stderr); |
247 | fputc('\n', stderr); |
248 | } |
249 | MP_EPRINTX("*** input", c); |
250 | if (rc < 0) |
251 | fprintf(stderr, "*** expected failure\n"); |
252 | else { |
253 | fprintf(stderr, "*** expected = %d: ", rc); type_hex.dump(p, stderr); |
254 | fprintf(stderr, "\n*** computed = %d: ", n); type_hex.dump(&d, stderr); |
255 | fprintf(stderr, "\n"); |
256 | } |
257 | } |
258 | rsa_privdestroy(&rpc); |
259 | rsa_privfree(rp); |
260 | mp_drop(c); |
261 | dstr_destroy(&d); |
262 | GR_DESTROY(r); |
263 | assert(mparena_count(MPARENA_GLOBAL) == 0); |
45c0fd36 |
264 | return (ok); |
b817bfc6 |
265 | } |
266 | |
267 | static int tvrfpub(rsa_pub *rp, |
268 | mp *c, dstr *m, int rc, dstr *p, |
269 | const char *ename, dstr *eparam, |
270 | rsa_vrfunpad *e, void *earg) |
271 | { |
272 | rsa_pubctx rpc; |
273 | dstr d = DSTR_INIT; |
274 | int n; |
275 | int ok = 1; |
276 | |
277 | rsa_pubcreate(&rpc, rp); |
278 | n = rsa_verify(&rpc, c, m->len ? m->buf : 0, m->len, &d, e, earg); |
279 | if (n != rc || (rc >= 0 && !DSTR_EQ(&d, p))) { |
280 | ok = 0; |
281 | fprintf(stderr, "*** verification with %s padding failed!\n", ename); |
282 | MP_EPRINTX("*** key.n", rp->n); |
283 | MP_EPRINTX("*** key.e", rp->e); |
284 | if (eparam) { |
285 | fprintf(stderr, "*** encoding parameters = "); |
286 | type_hex.dump(eparam, stderr); |
287 | fputc('\n', stderr); |
288 | } |
289 | MP_EPRINTX("*** input", c); |
290 | fprintf(stderr, "*** message = "); type_hex.dump(m, stderr); |
291 | if (rc < 0) |
3fc3abb6 |
292 | fprintf(stderr, "\n*** expected failure\n"); |
b817bfc6 |
293 | else { |
3fc3abb6 |
294 | fprintf(stderr, "\n*** expected = %d: ", rc); type_hex.dump(p, stderr); |
b817bfc6 |
295 | fprintf(stderr, "\n*** computed = %d: ", n); type_hex.dump(&d, stderr); |
296 | fprintf(stderr, "\n"); |
297 | } |
298 | } |
299 | rsa_pubdestroy(&rpc); |
300 | rsa_pubfree(rp); |
301 | mp_drop(c); |
302 | dstr_destroy(&d); |
303 | assert(mparena_count(MPARENA_GLOBAL) == 0); |
45c0fd36 |
304 | return (ok); |
b817bfc6 |
305 | } |
306 | |
307 | /*----- Deep magic --------------------------------------------------------* |
308 | * |
309 | * Wahey! Whacko macro programming on curry and lager. There's nothing like |
310 | * it. |
311 | */ |
312 | |
313 | #define DECL_priv \ |
314 | rsa_priv rp = { 0 }; |
315 | #define FUNC_priv \ |
316 | rp.n = *(mp **)v++->buf; \ |
317 | rp.e = *(mp **)v++->buf; \ |
318 | rp.d = *(mp **)v++->buf; \ |
319 | rsa_recover(&rp); |
320 | #define ARG_priv \ |
45c0fd36 |
321 | &rp, |
b817bfc6 |
322 | #define TAB_priv \ |
323 | &type_mp, &type_mp, &type_mp, |
324 | |
325 | #define DECL_pub \ |
326 | rsa_pub rp; |
327 | #define FUNC_pub \ |
328 | rp.n = *(mp **)v++->buf; \ |
329 | rp.e = *(mp **)v++->buf; |
330 | #define ARG_pub \ |
45c0fd36 |
331 | &rp, |
b817bfc6 |
332 | #define TAB_pub \ |
45c0fd36 |
333 | &type_mp, &type_mp, |
b817bfc6 |
334 | |
335 | #define DECL_pad \ |
336 | int nbits; |
337 | #define FUNC_pad \ |
338 | nbits = *(int *)v++->buf; |
339 | #define ARG_pad \ |
340 | nbits, |
341 | #define TAB_pad \ |
342 | &type_int, |
343 | |
344 | #define DECL_enc \ |
345 | dstr *p; \ |
346 | int rc; \ |
347 | mp *c; |
348 | #define FUNC_enc \ |
349 | p = v++; \ |
350 | rc = *(int *)v++->buf; \ |
351 | c = *(mp **)v++->buf; |
352 | #define ARG_enc \ |
353 | p, rc, c, |
354 | #define TAB_enc \ |
355 | &type_hex, &type_int, &type_mp, |
356 | |
357 | #define DECL_sig DECL_enc |
358 | #define FUNC_sig FUNC_enc |
359 | #define ARG_sig ARG_enc |
360 | #define TAB_sig TAB_enc |
361 | |
362 | #define DECL_dec \ |
363 | mp *c; \ |
364 | int rc; \ |
365 | dstr *p; |
366 | #define FUNC_dec \ |
367 | c = *(mp **)v++->buf; \ |
368 | rc = *(int *)v++->buf; \ |
369 | p = v++; |
370 | #define ARG_dec \ |
371 | c, rc, p, |
372 | #define TAB_dec \ |
373 | &type_mp, &type_int, &type_hex, |
374 | |
375 | #define DECL_vrf \ |
376 | mp *c; \ |
377 | dstr *m; \ |
378 | int rc; \ |
379 | dstr *p; |
380 | #define FUNC_vrf \ |
381 | c = *(mp **)v++->buf; \ |
382 | m = v++; \ |
383 | rc = *(int *)v++->buf; \ |
384 | p = v++; |
385 | #define ARG_vrf \ |
386 | c, m, rc, p, |
387 | #define TAB_vrf \ |
388 | &type_mp, &type_hex, &type_int, &type_hex, |
389 | |
390 | #define DECL_p1enc \ |
391 | pkcs1 p1; \ |
392 | dstr *ep; |
393 | #define FUNC_p1enc \ |
394 | p1.r = fib; \ |
395 | ep = v++; \ |
396 | p1.ep = ep->buf; \ |
397 | p1.epsz = ep->len; |
398 | #define ARG_p1enc \ |
399 | "pkcs1", ep, pkcs1_cryptencode, &p1 |
400 | #define TAB_p1enc \ |
401 | &type_hex |
402 | |
403 | #define DECL_p1sig DECL_p1enc |
404 | #define FUNC_p1sig FUNC_p1enc |
405 | #define ARG_p1sig \ |
406 | "pkcs1", ep, pkcs1_sigencode, &p1 |
407 | #define TAB_p1sig TAB_p1enc |
408 | |
409 | #define DECL_p1dec DECL_p1enc |
410 | #define FUNC_p1dec FUNC_p1enc |
411 | #define ARG_p1dec \ |
412 | "pkcs1", ep, pkcs1_cryptdecode, &p1 |
413 | #define TAB_p1dec TAB_p1enc |
414 | |
415 | #define DECL_p1vrf DECL_p1enc |
416 | #define FUNC_p1vrf FUNC_p1enc |
417 | #define ARG_p1vrf \ |
418 | "pkcs1", ep, pkcs1_sigdecode, &p1 |
419 | #define TAB_p1vrf TAB_p1enc |
420 | |
421 | #define DECL_oaepenc \ |
422 | oaep o; \ |
423 | dstr *ep; |
424 | #define FUNC_oaepenc \ |
425 | o.r = fib; \ |
426 | o.cc = gcipher_byname(v++->buf); \ |
427 | o.ch = ghash_byname(v++->buf); \ |
428 | ep = v++; \ |
429 | o.ep = ep->buf; \ |
430 | o.epsz = ep->len; |
431 | #define ARG_oaepenc \ |
432 | "oaep", ep, oaep_encode, &o |
433 | #define TAB_oaepenc \ |
434 | &type_string, &type_string, &type_hex |
435 | |
436 | #define DECL_oaepdec DECL_oaepenc |
437 | #define FUNC_oaepdec FUNC_oaepenc |
438 | #define ARG_oaepdec \ |
439 | "oaep", ep, oaep_decode, &o |
440 | #define TAB_oaepdec TAB_oaepenc |
441 | |
442 | #define DECL_psssig \ |
443 | pss pp; |
444 | #define FUNC_psssig \ |
445 | pp.r = fib; \ |
446 | pp.cc = gcipher_byname(v++->buf); \ |
447 | pp.ch = ghash_byname(v++->buf); \ |
448 | pp.ssz = *(int *)v++->buf; |
449 | #define ARG_psssig \ |
450 | "pss", 0, pss_encode, &pp |
451 | #define TAB_psssig \ |
452 | &type_string, &type_string, &type_int |
453 | |
454 | #define DECL_pssvrf DECL_psssig |
455 | #define FUNC_pssvrf FUNC_psssig |
456 | #define ARG_pssvrf \ |
457 | "pss", 0, pss_decode, &pp |
458 | #define TAB_pssvrf TAB_psssig |
459 | |
460 | #define TESTS(DO) \ |
461 | DO(pad, enc, p1enc) \ |
462 | DO(pad, dec, p1dec) \ |
463 | DO(pad, sig, p1sig) \ |
464 | DO(pad, vrf, p1vrf) \ |
465 | DO(pub, enc, p1enc) \ |
466 | DO(priv, dec, p1dec) \ |
467 | DO(priv, sig, p1sig) \ |
468 | DO(pub, vrf, p1vrf) \ |
469 | DO(pad, enc, oaepenc) \ |
470 | DO(pad, dec, oaepdec) \ |
471 | DO(pub, enc, oaepenc) \ |
472 | DO(priv, dec, oaepdec) \ |
473 | DO(pad, sig, psssig) \ |
474 | DO(pad, vrf, pssvrf) \ |
475 | DO(priv, sig, psssig) \ |
476 | DO(pub, vrf, pssvrf) |
477 | |
478 | #define FUNCS(key, op, enc) \ |
479 | int t_##key##_##enc(dstr *v) \ |
480 | { \ |
481 | DECL_##key \ |
482 | DECL_##op \ |
483 | DECL_##enc \ |
484 | fib->ops->misc(fib, GRAND_SEEDINT, 14); \ |
485 | FUNC_##key \ |
486 | FUNC_##op \ |
487 | FUNC_##enc \ |
488 | return (t##op##key(ARG_##key ARG_##op ARG_##enc)); \ |
489 | } |
490 | |
491 | #define TAB(key, op, enc) \ |
492 | { #enc "-" #key, t_##key##_##enc, { TAB_##key TAB_##op TAB_##enc } }, |
493 | |
494 | static grand *fib; |
495 | |
45c0fd36 |
496 | TESTS(FUNCS) |
b817bfc6 |
497 | |
498 | static const test_chunk tests[] = { |
499 | TESTS(TAB) |
500 | { 0 } |
501 | }; |
502 | |
503 | int main(int argc, char *argv[]) |
504 | { |
505 | sub_init(); |
506 | fib = fibrand_create(0); |
0f00dc4c |
507 | test_run(argc, argv, tests, SRCDIR "/t/rsa"); |
b817bfc6 |
508 | GR_DESTROY(fib); |
509 | return (0); |
510 | } |
511 | |
512 | /*----- That's all, folks -------------------------------------------------*/ |