3 * Testing RSA padding operations
5 * (c) 2004 Straylight/Edgeware
8 /*----- Licensing notice --------------------------------------------------*
10 * This file is part of Catacomb.
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.
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.
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,
28 /*----- Header files ------------------------------------------------------*/
33 /*----- Main code ---------------------------------------------------------*/
35 static int tencpad(int nbits,
36 dstr *p, int rc, mp *c,
37 const char *ename, dstr *eparam, rsa_pad *e, void *earg)
39 size_t n = (nbits + 7)/8;
44 d = e(MP_NEW, p->buf, p->len, q, n, nbits, earg);
45 if (!d == !rc || (!rc && !MP_EQ(d, c))) {
47 fprintf(stderr, "*** %s padding failed!\n", ename);
48 fprintf(stderr, "*** padding bits = %d\n", nbits);
50 fprintf(stderr, "*** encoding parameters = ");
51 type_hex.dump(eparam, stderr);
54 fprintf(stderr, "*** input message = "); type_hex.dump(p, stderr);
56 fprintf(stderr, "\n*** expected failure\n");
58 MP_EPRINTX("\n*** expected", c);
59 MP_EPRINTX("*** computed", d);
65 assert(mparena_count(MPARENA_GLOBAL) == 0);
69 #define tsigpad tencpad
71 #define DSTR_EQ(x, y) \
72 ((x)->len == (y)->len && !memcmp((x)->buf, (y)->buf, (x)->len))
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)
80 int n = (nbits + 7)/8;
84 n = e(c, (octet *)d.buf, n, nbits, earg);
87 if (n != rc || (rc >= 0 && !DSTR_EQ(&d, p))) {
89 fprintf(stderr, "*** %s encryption unpadding failed!\n", ename);
90 fprintf(stderr, "*** padding bits = %d\n", nbits);
92 fprintf(stderr, "*** encoding parameters = ");
93 type_hex.dump(eparam, stderr);
96 MP_EPRINTX("*** input", c);
98 fprintf(stderr, "*** expected failure\n");
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");
107 assert(mparena_count(MPARENA_GLOBAL) == 0);
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)
117 int n = (nbits + 7)/8;
121 n = e(c, m->len ? (octet *)m->buf : 0, m->len,
122 (octet *)d.buf, n, nbits, earg);
125 if (n != rc || (rc >= 0 && !DSTR_EQ(&d, p))) {
127 fprintf(stderr, "*** %s signature unpadding failed!\n", ename);
128 fprintf(stderr, "*** padding bits = %d\n", nbits);
129 MP_EPRINTX("*** input", c);
131 fprintf(stderr, "*** encoding parameters = ");
132 type_hex.dump(eparam, stderr);
135 fprintf(stderr, "*** message = "); type_hex.dump(m, stderr);
137 fprintf(stderr, "\n*** expected failure\n");
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");
146 assert(mparena_count(MPARENA_GLOBAL) == 0);
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)
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))) {
162 fprintf(stderr, "*** encrypt with %s padding failed!\n", ename);
163 MP_EPRINTX("*** key.n", rp->n);
164 MP_EPRINTX("*** key.e", rp->e);
166 fprintf(stderr, "*** encoding parameters = ");
167 type_hex.dump(eparam, stderr);
170 fprintf(stderr, "*** input message = "); type_hex.dump(p, stderr);
172 fprintf(stderr, "\n*** expected failure\n");
174 MP_EPRINTX("\n*** expected", c);
175 MP_EPRINTX("*** computed", d);
178 rsa_pubdestroy(&rpc);
182 assert(mparena_count(MPARENA_GLOBAL) == 0);
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)
191 grand *r = fibrand_create(0);
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))) {
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);
204 fprintf(stderr, "*** encoding parameters = ");
205 type_hex.dump(eparam, stderr);
208 fprintf(stderr, "*** input message = "); type_hex.dump(p, stderr);
210 fprintf(stderr, "\n*** expected failure\n");
212 MP_EPRINTX("\n*** expected", c);
213 MP_EPRINTX("\n*** computed", d);
216 rsa_privdestroy(&rpc);
221 assert(mparena_count(MPARENA_GLOBAL) == 0);
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)
232 grand *r = fibrand_create(0);
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))) {
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);
245 fprintf(stderr, "*** encoding parameters = ");
246 type_hex.dump(eparam, stderr);
249 MP_EPRINTX("*** input", c);
251 fprintf(stderr, "*** expected failure\n");
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");
258 rsa_privdestroy(&rpc);
263 assert(mparena_count(MPARENA_GLOBAL) == 0);
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)
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))) {
281 fprintf(stderr, "*** verification with %s padding failed!\n", ename);
282 MP_EPRINTX("*** key.n", rp->n);
283 MP_EPRINTX("*** key.e", rp->e);
285 fprintf(stderr, "*** encoding parameters = ");
286 type_hex.dump(eparam, stderr);
289 MP_EPRINTX("*** input", c);
290 fprintf(stderr, "*** message = "); type_hex.dump(m, stderr);
292 fprintf(stderr, "\n*** expected failure\n");
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");
299 rsa_pubdestroy(&rpc);
303 assert(mparena_count(MPARENA_GLOBAL) == 0);
307 /*----- Deep magic --------------------------------------------------------*
309 * Wahey! Whacko macro programming on curry and lager. There's nothing like
316 rp.n = *(mp **)v++->buf; \
317 rp.e = *(mp **)v++->buf; \
318 rp.d = *(mp **)v++->buf; \
323 &type_mp, &type_mp, &type_mp,
328 rp.n = *(mp **)v++->buf; \
329 rp.e = *(mp **)v++->buf;
338 nbits = *(int *)v++->buf;
350 rc = *(int *)v++->buf; \
351 c = *(mp **)v++->buf;
355 &type_hex, &type_int, &type_mp,
357 #define DECL_sig DECL_enc
358 #define FUNC_sig FUNC_enc
359 #define ARG_sig ARG_enc
360 #define TAB_sig TAB_enc
367 c = *(mp **)v++->buf; \
368 rc = *(int *)v++->buf; \
373 &type_mp, &type_int, &type_hex,
381 c = *(mp **)v++->buf; \
383 rc = *(int *)v++->buf; \
388 &type_mp, &type_hex, &type_int, &type_hex,
399 "pkcs1", ep, pkcs1_cryptencode, &p1
403 #define DECL_p1sig DECL_p1enc
404 #define FUNC_p1sig FUNC_p1enc
406 "pkcs1", ep, pkcs1_sigencode, &p1
407 #define TAB_p1sig TAB_p1enc
409 #define DECL_p1dec DECL_p1enc
410 #define FUNC_p1dec FUNC_p1enc
412 "pkcs1", ep, pkcs1_cryptdecode, &p1
413 #define TAB_p1dec TAB_p1enc
415 #define DECL_p1vrf DECL_p1enc
416 #define FUNC_p1vrf FUNC_p1enc
418 "pkcs1", ep, pkcs1_sigdecode, &p1
419 #define TAB_p1vrf TAB_p1enc
421 #define DECL_oaepenc \
424 #define FUNC_oaepenc \
426 o.cc = gcipher_byname(v++->buf); \
427 o.ch = ghash_byname(v++->buf); \
431 #define ARG_oaepenc \
432 "oaep", ep, oaep_encode, &o
433 #define TAB_oaepenc \
434 &type_string, &type_string, &type_hex
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
442 #define DECL_psssig \
444 #define FUNC_psssig \
446 pp.cc = gcipher_byname(v++->buf); \
447 pp.ch = ghash_byname(v++->buf); \
448 pp.ssz = *(int *)v++->buf;
450 "pss", 0, pss_encode, &pp
452 &type_string, &type_string, &type_int
454 #define DECL_pssvrf DECL_psssig
455 #define FUNC_pssvrf FUNC_psssig
457 "pss", 0, pss_decode, &pp
458 #define TAB_pssvrf TAB_psssig
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) \
478 #define FUNCS(key, op, enc) \
479 int t_##key##_##enc(dstr *v) \
484 fib->ops->misc(fib, GRAND_SEEDINT, 14); \
488 return (t##op##key(ARG_##key ARG_##op ARG_##enc)); \
491 #define TAB(key, op, enc) \
492 { #enc "-" #key, t_##key##_##enc, { TAB_##key TAB_##op TAB_##enc } },
498 static const test_chunk tests[] = {
503 int main(int argc, char *argv[])
506 fib = fibrand_create(0);
507 test_run(argc, argv, tests, SRCDIR "/t/rsa");
512 /*----- That's all, folks -------------------------------------------------*/