chiark / gitweb /
rand/rand.c (rand_gate): Evolve r->ibits in a more sensible manner.
[catacomb] / pub / rsa-test.c
1 /* -*-c-*-
2  *
3  * Testing RSA padding operations
4  *
5  * (c) 2004 Straylight/Edgeware
6  */
7
8 /*----- Licensing notice --------------------------------------------------*
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.
16  *
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.
21  *
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);
66   return (ok);
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);
108   return (ok);
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);
147   return (ok);
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);
264   return (ok);
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)
292       fprintf(stderr, "\n*** expected failure\n");
293     else {
294       fprintf(stderr, "\n*** expected = %d: ", rc); type_hex.dump(p, stderr);
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);
304   return (ok);
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                                                        \
321   &rp,
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                                                         \
331   &rp,
332 #define TAB_pub                                                         \
333   &type_mp, &type_mp,
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
496 TESTS(FUNCS)
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);
507   test_run(argc, argv, tests, SRCDIR "/t/rsa");
508   GR_DESTROY(fib);
509   return (0);
510 }
511
512 /*----- That's all, folks -------------------------------------------------*/