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