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 -------------------------------------------------*/