math/mpreduce.h: Missing include files.
[u/mdw/catacomb] / pub / rsa-test.c
CommitLineData
b817bfc6 1/* -*-c-*-
2 *
b817bfc6 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
35static 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
74static 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
111static 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
150static 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
186static 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
225static 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
267static 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
494static grand *fib;
495
45c0fd36 496TESTS(FUNCS)
b817bfc6 497
498static const test_chunk tests[] = {
499 TESTS(TAB)
500 { 0 }
501};
502
503int 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 -------------------------------------------------*/