5 * Testing RSA padding operations
7 * (c) 2004 Straylight/Edgeware
10 /*----- Licensing notice --------------------------------------------------*
12 * This file is part of Catacomb.
14 * Catacomb is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU Library General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
19 * Catacomb is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Library General Public License for more details.
24 * You should have received a copy of the GNU Library General Public
25 * License along with Catacomb; if not, write to the Free
26 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
30 /*----- Header files ------------------------------------------------------*/
35 /*----- Main code ---------------------------------------------------------*/
37 static int tencpad(int nbits,
38 dstr *p, int rc, mp *c,
39 const char *ename, dstr *eparam, rsa_pad *e, void *earg)
41 size_t n = (nbits + 7)/8;
46 d = e(MP_NEW, p->buf, p->len, q, n, nbits, earg);
47 if (!d == !rc || (!rc && !MP_EQ(d, c))) {
49 fprintf(stderr, "*** %s padding failed!\n", ename);
50 fprintf(stderr, "*** padding bits = %d\n", nbits);
52 fprintf(stderr, "*** encoding parameters = ");
53 type_hex.dump(eparam, stderr);
56 fprintf(stderr, "*** input message = "); type_hex.dump(p, stderr);
58 fprintf(stderr, "\n*** expected failure\n");
60 MP_EPRINTX("\n*** expected", c);
61 MP_EPRINTX("*** computed", d);
67 assert(mparena_count(MPARENA_GLOBAL) == 0);
71 #define tsigpad tencpad
73 #define DSTR_EQ(x, y) \
74 ((x)->len == (y)->len && !memcmp((x)->buf, (y)->buf, (x)->len))
76 static int tdecpad(int nbits,
77 mp *c, int rc, dstr *p,
78 const char *ename, dstr *eparam,
79 rsa_decunpad *e, void *earg)
82 int n = (nbits + 7)/8;
86 n = e(c, (octet *)d.buf, n, nbits, earg);
89 if (n != rc || (rc >= 0 && !DSTR_EQ(&d, p))) {
91 fprintf(stderr, "*** %s encryption unpadding failed!\n", ename);
92 fprintf(stderr, "*** padding bits = %d\n", nbits);
94 fprintf(stderr, "*** encoding parameters = ");
95 type_hex.dump(eparam, stderr);
98 MP_EPRINTX("*** input", c);
100 fprintf(stderr, "*** expected failure\n");
102 fprintf(stderr, "*** expected: %d = ", rc); type_hex.dump(p, stderr);
103 fprintf(stderr, "\n*** computed: %d = ", n); type_hex.dump(&d, stderr);
104 fprintf(stderr, "\n");
109 assert(mparena_count(MPARENA_GLOBAL) == 0);
113 static int tvrfpad(int nbits,
114 mp *c, dstr *m, int rc, dstr *p,
115 const char *ename, dstr *eparam,
116 rsa_vrfunpad *e, void *earg)
119 int n = (nbits + 7)/8;
123 n = e(c, m->len ? (octet *)m->buf : 0, m->len,
124 (octet *)d.buf, n, nbits, earg);
127 if (n != rc || (rc >= 0 && !DSTR_EQ(&d, p))) {
129 fprintf(stderr, "*** %s signature unpadding failed!\n", ename);
130 fprintf(stderr, "*** padding bits = %d\n", nbits);
131 MP_EPRINTX("*** input", c);
133 fprintf(stderr, "*** encoding parameters = ");
134 type_hex.dump(eparam, stderr);
137 fprintf(stderr, "*** message = "); type_hex.dump(m, stderr);
139 fprintf(stderr, "\n*** expected failure\n");
141 fprintf(stderr, "\n*** expected = %d: ", rc); type_hex.dump(p, stderr);
142 fprintf(stderr, "\n*** computed = %d: ", n); type_hex.dump(&d, stderr);
143 fprintf(stderr, "\n");
148 assert(mparena_count(MPARENA_GLOBAL) == 0);
152 static int tencpub(rsa_pub *rp,
153 dstr *p, int rc, mp *c,
154 const char *ename, dstr *eparam, rsa_pad *e, void *earg)
160 rsa_pubcreate(&rpc, rp);
161 d = rsa_encrypt(&rpc, MP_NEW, p->buf, p->len, e, earg);
162 if (!d == !rc || (!rc && !MP_EQ(d, c))) {
164 fprintf(stderr, "*** encrypt with %s padding failed!\n", ename);
165 MP_EPRINTX("*** key.n", rp->n);
166 MP_EPRINTX("*** key.e", rp->e);
168 fprintf(stderr, "*** encoding parameters = ");
169 type_hex.dump(eparam, stderr);
172 fprintf(stderr, "*** input message = "); type_hex.dump(p, stderr);
174 fprintf(stderr, "\n*** expected failure\n");
176 MP_EPRINTX("\n*** expected", c);
177 MP_EPRINTX("*** computed", d);
180 rsa_pubdestroy(&rpc);
184 assert(mparena_count(MPARENA_GLOBAL) == 0);
188 static int tsigpriv(rsa_priv *rp,
189 dstr *p, int rc, mp *c,
190 const char *ename, dstr *eparam, rsa_pad *e, void *earg)
193 grand *r = fibrand_create(0);
197 rsa_privcreate(&rpc, rp, r);
198 d = rsa_sign(&rpc, MP_NEW, p->buf, p->len, e, earg);
199 if (!d == !rc || (!rc && !MP_EQ(d, c))) {
201 fprintf(stderr, "*** sign with %s padding failed!\n", ename);
202 MP_EPRINTX("*** key.n", rp->n);
203 MP_EPRINTX("*** key.d", rp->d);
204 MP_EPRINTX("*** key.e", rp->e);
206 fprintf(stderr, "*** encoding parameters = ");
207 type_hex.dump(eparam, stderr);
210 fprintf(stderr, "*** input message = "); type_hex.dump(p, stderr);
212 fprintf(stderr, "\n*** expected failure\n");
214 MP_EPRINTX("\n*** expected", c);
215 MP_EPRINTX("\n*** computed", d);
218 rsa_privdestroy(&rpc);
223 assert(mparena_count(MPARENA_GLOBAL) == 0);
227 static int tdecpriv(rsa_priv *rp,
228 mp *c, int rc, dstr *p,
229 const char *ename, dstr *eparam,
230 rsa_decunpad *e, void *earg)
234 grand *r = fibrand_create(0);
238 rsa_privcreate(&rpc, rp, r);
239 n = rsa_decrypt(&rpc, c, &d, e, earg);
240 if (n != rc || (rc >= 0 && !DSTR_EQ(&d, p))) {
242 fprintf(stderr, "*** decryption with %s padding failed!\n", ename);
243 MP_EPRINTX("*** key.n", rp->n);
244 MP_EPRINTX("*** key.d", rp->d);
245 MP_EPRINTX("*** key.e", rp->e);
247 fprintf(stderr, "*** encoding parameters = ");
248 type_hex.dump(eparam, stderr);
251 MP_EPRINTX("*** input", c);
253 fprintf(stderr, "*** expected failure\n");
255 fprintf(stderr, "*** expected = %d: ", rc); type_hex.dump(p, stderr);
256 fprintf(stderr, "\n*** computed = %d: ", n); type_hex.dump(&d, stderr);
257 fprintf(stderr, "\n");
260 rsa_privdestroy(&rpc);
265 assert(mparena_count(MPARENA_GLOBAL) == 0);
269 static int tvrfpub(rsa_pub *rp,
270 mp *c, dstr *m, int rc, dstr *p,
271 const char *ename, dstr *eparam,
272 rsa_vrfunpad *e, void *earg)
279 rsa_pubcreate(&rpc, rp);
280 n = rsa_verify(&rpc, c, m->len ? m->buf : 0, m->len, &d, e, earg);
281 if (n != rc || (rc >= 0 && !DSTR_EQ(&d, p))) {
283 fprintf(stderr, "*** verification with %s padding failed!\n", ename);
284 MP_EPRINTX("*** key.n", rp->n);
285 MP_EPRINTX("*** key.e", rp->e);
287 fprintf(stderr, "*** encoding parameters = ");
288 type_hex.dump(eparam, stderr);
291 MP_EPRINTX("*** input", c);
292 fprintf(stderr, "*** message = "); type_hex.dump(m, stderr);
294 fprintf(stderr, "\n*** expected failure\n");
296 fprintf(stderr, "\n*** expected = %d: ", rc); type_hex.dump(p, stderr);
297 fprintf(stderr, "\n*** computed = %d: ", n); type_hex.dump(&d, stderr);
298 fprintf(stderr, "\n");
301 rsa_pubdestroy(&rpc);
305 assert(mparena_count(MPARENA_GLOBAL) == 0);
309 /*----- Deep magic --------------------------------------------------------*
311 * Wahey! Whacko macro programming on curry and lager. There's nothing like
318 rp.n = *(mp **)v++->buf; \
319 rp.e = *(mp **)v++->buf; \
320 rp.d = *(mp **)v++->buf; \
325 &type_mp, &type_mp, &type_mp,
330 rp.n = *(mp **)v++->buf; \
331 rp.e = *(mp **)v++->buf;
340 nbits = *(int *)v++->buf;
352 rc = *(int *)v++->buf; \
353 c = *(mp **)v++->buf;
357 &type_hex, &type_int, &type_mp,
359 #define DECL_sig DECL_enc
360 #define FUNC_sig FUNC_enc
361 #define ARG_sig ARG_enc
362 #define TAB_sig TAB_enc
369 c = *(mp **)v++->buf; \
370 rc = *(int *)v++->buf; \
375 &type_mp, &type_int, &type_hex,
383 c = *(mp **)v++->buf; \
385 rc = *(int *)v++->buf; \
390 &type_mp, &type_hex, &type_int, &type_hex,
401 "pkcs1", ep, pkcs1_cryptencode, &p1
405 #define DECL_p1sig DECL_p1enc
406 #define FUNC_p1sig FUNC_p1enc
408 "pkcs1", ep, pkcs1_sigencode, &p1
409 #define TAB_p1sig TAB_p1enc
411 #define DECL_p1dec DECL_p1enc
412 #define FUNC_p1dec FUNC_p1enc
414 "pkcs1", ep, pkcs1_cryptdecode, &p1
415 #define TAB_p1dec TAB_p1enc
417 #define DECL_p1vrf DECL_p1enc
418 #define FUNC_p1vrf FUNC_p1enc
420 "pkcs1", ep, pkcs1_sigdecode, &p1
421 #define TAB_p1vrf TAB_p1enc
423 #define DECL_oaepenc \
426 #define FUNC_oaepenc \
428 o.cc = gcipher_byname(v++->buf); \
429 o.ch = ghash_byname(v++->buf); \
433 #define ARG_oaepenc \
434 "oaep", ep, oaep_encode, &o
435 #define TAB_oaepenc \
436 &type_string, &type_string, &type_hex
438 #define DECL_oaepdec DECL_oaepenc
439 #define FUNC_oaepdec FUNC_oaepenc
440 #define ARG_oaepdec \
441 "oaep", ep, oaep_decode, &o
442 #define TAB_oaepdec TAB_oaepenc
444 #define DECL_psssig \
446 #define FUNC_psssig \
448 pp.cc = gcipher_byname(v++->buf); \
449 pp.ch = ghash_byname(v++->buf); \
450 pp.ssz = *(int *)v++->buf;
452 "pss", 0, pss_encode, &pp
454 &type_string, &type_string, &type_int
456 #define DECL_pssvrf DECL_psssig
457 #define FUNC_pssvrf FUNC_psssig
459 "pss", 0, pss_decode, &pp
460 #define TAB_pssvrf TAB_psssig
463 DO(pad, enc, p1enc) \
464 DO(pad, dec, p1dec) \
465 DO(pad, sig, p1sig) \
466 DO(pad, vrf, p1vrf) \
467 DO(pub, enc, p1enc) \
468 DO(priv, dec, p1dec) \
469 DO(priv, sig, p1sig) \
470 DO(pub, vrf, p1vrf) \
471 DO(pad, enc, oaepenc) \
472 DO(pad, dec, oaepdec) \
473 DO(pub, enc, oaepenc) \
474 DO(priv, dec, oaepdec) \
475 DO(pad, sig, psssig) \
476 DO(pad, vrf, pssvrf) \
477 DO(priv, sig, psssig) \
480 #define FUNCS(key, op, enc) \
481 int t_##key##_##enc(dstr *v) \
486 fib->ops->misc(fib, GRAND_SEEDINT, 14); \
490 return (t##op##key(ARG_##key ARG_##op ARG_##enc)); \
493 #define TAB(key, op, enc) \
494 { #enc "-" #key, t_##key##_##enc, { TAB_##key TAB_##op TAB_##enc } },
500 static const test_chunk tests[] = {
505 int main(int argc, char *argv[])
508 fib = fibrand_create(0);
509 test_run(argc, argv, tests, SRCDIR "/tests/rsa");
514 /*----- That's all, folks -------------------------------------------------*/