+++ /dev/null
-/* -*-c-*-
- *
- * $Id$
- *
- * Testing RSA padding operations
- *
- * (c) 2004 Straylight/Edgeware
- */
-
-/*----- Licensing notice --------------------------------------------------*
- *
- * This file is part of Catacomb.
- *
- * Catacomb is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * Catacomb is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with Catacomb; if not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA 02111-1307, USA.
- */
-
-/*----- Header files ------------------------------------------------------*/
-
-#include "fibrand.h"
-#include "rsa.h"
-
-/*----- Main code ---------------------------------------------------------*/
-
-static int tencpad(int nbits,
- dstr *p, int rc, mp *c,
- const char *ename, dstr *eparam, rsa_pad *e, void *earg)
-{
- size_t n = (nbits + 7)/8;
- void *q = xmalloc(n);
- mp *d;
- int ok = 1;
-
- d = e(MP_NEW, p->buf, p->len, q, n, nbits, earg);
- if (!d == !rc || (!rc && !MP_EQ(d, c))) {
- ok = 0;
- fprintf(stderr, "*** %s padding failed!\n", ename);
- fprintf(stderr, "*** padding bits = %d\n", nbits);
- if (eparam) {
- fprintf(stderr, "*** encoding parameters = ");
- type_hex.dump(eparam, stderr);
- fputc('\n', stderr);
- }
- fprintf(stderr, "*** input message = "); type_hex.dump(p, stderr);
- if (rc)
- fprintf(stderr, "\n*** expected failure\n");
- else {
- MP_EPRINTX("\n*** expected", c);
- MP_EPRINTX("*** computed", d);
- }
- }
- mp_drop(d);
- mp_drop(c);
- xfree(q);
- assert(mparena_count(MPARENA_GLOBAL) == 0);
- return (ok);
-}
-
-#define tsigpad tencpad
-
-#define DSTR_EQ(x, y) \
- ((x)->len == (y)->len && !memcmp((x)->buf, (y)->buf, (x)->len))
-
-static int tdecpad(int nbits,
- mp *c, int rc, dstr *p,
- const char *ename, dstr *eparam,
- rsa_decunpad *e, void *earg)
-{
- dstr d = DSTR_INIT;
- int n = (nbits + 7)/8;
- int ok = 1;
-
- dstr_ensure(&d, n);
- n = e(c, (octet *)d.buf, n, nbits, earg);
- if (n >= 0)
- d.len += n;
- if (n != rc || (rc >= 0 && !DSTR_EQ(&d, p))) {
- ok = 0;
- fprintf(stderr, "*** %s encryption unpadding failed!\n", ename);
- fprintf(stderr, "*** padding bits = %d\n", nbits);
- if (eparam) {
- fprintf(stderr, "*** encoding parameters = ");
- type_hex.dump(eparam, stderr);
- fputc('\n', stderr);
- }
- MP_EPRINTX("*** input", c);
- if (rc < 0)
- fprintf(stderr, "*** expected failure\n");
- else {
- fprintf(stderr, "*** expected: %d = ", rc); type_hex.dump(p, stderr);
- fprintf(stderr, "\n*** computed: %d = ", n); type_hex.dump(&d, stderr);
- fprintf(stderr, "\n");
- }
- }
- mp_drop(c);
- dstr_destroy(&d);
- assert(mparena_count(MPARENA_GLOBAL) == 0);
- return (ok);
-}
-
-static int tvrfpad(int nbits,
- mp *c, dstr *m, int rc, dstr *p,
- const char *ename, dstr *eparam,
- rsa_vrfunpad *e, void *earg)
-{
- dstr d = DSTR_INIT;
- int n = (nbits + 7)/8;
- int ok = 1;
-
- dstr_ensure(&d, n);
- n = e(c, m->len ? (octet *)m->buf : 0, m->len,
- (octet *)d.buf, n, nbits, earg);
- if (n >= 0)
- d.len += n;
- if (n != rc || (rc >= 0 && !DSTR_EQ(&d, p))) {
- ok = 0;
- fprintf(stderr, "*** %s signature unpadding failed!\n", ename);
- fprintf(stderr, "*** padding bits = %d\n", nbits);
- MP_EPRINTX("*** input", c);
- if (eparam) {
- fprintf(stderr, "*** encoding parameters = ");
- type_hex.dump(eparam, stderr);
- fputc('\n', stderr);
- }
- fprintf(stderr, "*** message = "); type_hex.dump(m, stderr);
- if (rc < 0)
- fprintf(stderr, "\n*** expected failure\n");
- else {
- fprintf(stderr, "\n*** expected = %d: ", rc); type_hex.dump(p, stderr);
- fprintf(stderr, "\n*** computed = %d: ", n); type_hex.dump(&d, stderr);
- fprintf(stderr, "\n");
- }
- }
- mp_drop(c);
- dstr_destroy(&d);
- assert(mparena_count(MPARENA_GLOBAL) == 0);
- return (ok);
-}
-
-static int tencpub(rsa_pub *rp,
- dstr *p, int rc, mp *c,
- const char *ename, dstr *eparam, rsa_pad *e, void *earg)
-{
- mp *d;
- rsa_pubctx rpc;
- int ok = 1;
-
- rsa_pubcreate(&rpc, rp);
- d = rsa_encrypt(&rpc, MP_NEW, p->buf, p->len, e, earg);
- if (!d == !rc || (!rc && !MP_EQ(d, c))) {
- ok = 0;
- fprintf(stderr, "*** encrypt with %s padding failed!\n", ename);
- MP_EPRINTX("*** key.n", rp->n);
- MP_EPRINTX("*** key.e", rp->e);
- if (eparam) {
- fprintf(stderr, "*** encoding parameters = ");
- type_hex.dump(eparam, stderr);
- fputc('\n', stderr);
- }
- fprintf(stderr, "*** input message = "); type_hex.dump(p, stderr);
- if (rc)
- fprintf(stderr, "\n*** expected failure\n");
- else {
- MP_EPRINTX("\n*** expected", c);
- MP_EPRINTX("*** computed", d);
- }
- }
- rsa_pubdestroy(&rpc);
- rsa_pubfree(rp);
- mp_drop(d);
- mp_drop(c);
- assert(mparena_count(MPARENA_GLOBAL) == 0);
- return (ok);
-}
-
-static int tsigpriv(rsa_priv *rp,
- dstr *p, int rc, mp *c,
- const char *ename, dstr *eparam, rsa_pad *e, void *earg)
-{
- mp *d;
- grand *r = fibrand_create(0);
- rsa_privctx rpc;
- int ok = 1;
-
- rsa_privcreate(&rpc, rp, r);
- d = rsa_sign(&rpc, MP_NEW, p->buf, p->len, e, earg);
- if (!d == !rc || (!rc && !MP_EQ(d, c))) {
- ok = 0;
- fprintf(stderr, "*** sign with %s padding failed!\n", ename);
- MP_EPRINTX("*** key.n", rp->n);
- MP_EPRINTX("*** key.d", rp->d);
- MP_EPRINTX("*** key.e", rp->e);
- if (eparam) {
- fprintf(stderr, "*** encoding parameters = ");
- type_hex.dump(eparam, stderr);
- fputc('\n', stderr);
- }
- fprintf(stderr, "*** input message = "); type_hex.dump(p, stderr);
- if (rc)
- fprintf(stderr, "\n*** expected failure\n");
- else {
- MP_EPRINTX("\n*** expected", c);
- MP_EPRINTX("\n*** computed", d);
- }
- }
- rsa_privdestroy(&rpc);
- rsa_privfree(rp);
- mp_drop(d);
- mp_drop(c);
- GR_DESTROY(r);
- assert(mparena_count(MPARENA_GLOBAL) == 0);
- return (ok);
-}
-
-static int tdecpriv(rsa_priv *rp,
- mp *c, int rc, dstr *p,
- const char *ename, dstr *eparam,
- rsa_decunpad *e, void *earg)
-{
- rsa_privctx rpc;
- dstr d = DSTR_INIT;
- grand *r = fibrand_create(0);
- int n;
- int ok = 1;
-
- rsa_privcreate(&rpc, rp, r);
- n = rsa_decrypt(&rpc, c, &d, e, earg);
- if (n != rc || (rc >= 0 && !DSTR_EQ(&d, p))) {
- ok = 0;
- fprintf(stderr, "*** decryption with %s padding failed!\n", ename);
- MP_EPRINTX("*** key.n", rp->n);
- MP_EPRINTX("*** key.d", rp->d);
- MP_EPRINTX("*** key.e", rp->e);
- if (eparam) {
- fprintf(stderr, "*** encoding parameters = ");
- type_hex.dump(eparam, stderr);
- fputc('\n', stderr);
- }
- MP_EPRINTX("*** input", c);
- if (rc < 0)
- fprintf(stderr, "*** expected failure\n");
- else {
- fprintf(stderr, "*** expected = %d: ", rc); type_hex.dump(p, stderr);
- fprintf(stderr, "\n*** computed = %d: ", n); type_hex.dump(&d, stderr);
- fprintf(stderr, "\n");
- }
- }
- rsa_privdestroy(&rpc);
- rsa_privfree(rp);
- mp_drop(c);
- dstr_destroy(&d);
- GR_DESTROY(r);
- assert(mparena_count(MPARENA_GLOBAL) == 0);
- return (ok);
-}
-
-static int tvrfpub(rsa_pub *rp,
- mp *c, dstr *m, int rc, dstr *p,
- const char *ename, dstr *eparam,
- rsa_vrfunpad *e, void *earg)
-{
- rsa_pubctx rpc;
- dstr d = DSTR_INIT;
- int n;
- int ok = 1;
-
- rsa_pubcreate(&rpc, rp);
- n = rsa_verify(&rpc, c, m->len ? m->buf : 0, m->len, &d, e, earg);
- if (n != rc || (rc >= 0 && !DSTR_EQ(&d, p))) {
- ok = 0;
- fprintf(stderr, "*** verification with %s padding failed!\n", ename);
- MP_EPRINTX("*** key.n", rp->n);
- MP_EPRINTX("*** key.e", rp->e);
- if (eparam) {
- fprintf(stderr, "*** encoding parameters = ");
- type_hex.dump(eparam, stderr);
- fputc('\n', stderr);
- }
- MP_EPRINTX("*** input", c);
- fprintf(stderr, "*** message = "); type_hex.dump(m, stderr);
- if (rc < 0)
- fprintf(stderr, "\n*** expected failure\n");
- else {
- fprintf(stderr, "\n*** expected = %d: ", rc); type_hex.dump(p, stderr);
- fprintf(stderr, "\n*** computed = %d: ", n); type_hex.dump(&d, stderr);
- fprintf(stderr, "\n");
- }
- }
- rsa_pubdestroy(&rpc);
- rsa_pubfree(rp);
- mp_drop(c);
- dstr_destroy(&d);
- assert(mparena_count(MPARENA_GLOBAL) == 0);
- return (ok);
-}
-
-/*----- Deep magic --------------------------------------------------------*
- *
- * Wahey! Whacko macro programming on curry and lager. There's nothing like
- * it.
- */
-
-#define DECL_priv \
- rsa_priv rp = { 0 };
-#define FUNC_priv \
- rp.n = *(mp **)v++->buf; \
- rp.e = *(mp **)v++->buf; \
- rp.d = *(mp **)v++->buf; \
- rsa_recover(&rp);
-#define ARG_priv \
- &rp,
-#define TAB_priv \
- &type_mp, &type_mp, &type_mp,
-
-#define DECL_pub \
- rsa_pub rp;
-#define FUNC_pub \
- rp.n = *(mp **)v++->buf; \
- rp.e = *(mp **)v++->buf;
-#define ARG_pub \
- &rp,
-#define TAB_pub \
- &type_mp, &type_mp,
-
-#define DECL_pad \
- int nbits;
-#define FUNC_pad \
- nbits = *(int *)v++->buf;
-#define ARG_pad \
- nbits,
-#define TAB_pad \
- &type_int,
-
-#define DECL_enc \
- dstr *p; \
- int rc; \
- mp *c;
-#define FUNC_enc \
- p = v++; \
- rc = *(int *)v++->buf; \
- c = *(mp **)v++->buf;
-#define ARG_enc \
- p, rc, c,
-#define TAB_enc \
- &type_hex, &type_int, &type_mp,
-
-#define DECL_sig DECL_enc
-#define FUNC_sig FUNC_enc
-#define ARG_sig ARG_enc
-#define TAB_sig TAB_enc
-
-#define DECL_dec \
- mp *c; \
- int rc; \
- dstr *p;
-#define FUNC_dec \
- c = *(mp **)v++->buf; \
- rc = *(int *)v++->buf; \
- p = v++;
-#define ARG_dec \
- c, rc, p,
-#define TAB_dec \
- &type_mp, &type_int, &type_hex,
-
-#define DECL_vrf \
- mp *c; \
- dstr *m; \
- int rc; \
- dstr *p;
-#define FUNC_vrf \
- c = *(mp **)v++->buf; \
- m = v++; \
- rc = *(int *)v++->buf; \
- p = v++;
-#define ARG_vrf \
- c, m, rc, p,
-#define TAB_vrf \
- &type_mp, &type_hex, &type_int, &type_hex,
-
-#define DECL_p1enc \
- pkcs1 p1; \
- dstr *ep;
-#define FUNC_p1enc \
- p1.r = fib; \
- ep = v++; \
- p1.ep = ep->buf; \
- p1.epsz = ep->len;
-#define ARG_p1enc \
- "pkcs1", ep, pkcs1_cryptencode, &p1
-#define TAB_p1enc \
- &type_hex
-
-#define DECL_p1sig DECL_p1enc
-#define FUNC_p1sig FUNC_p1enc
-#define ARG_p1sig \
- "pkcs1", ep, pkcs1_sigencode, &p1
-#define TAB_p1sig TAB_p1enc
-
-#define DECL_p1dec DECL_p1enc
-#define FUNC_p1dec FUNC_p1enc
-#define ARG_p1dec \
- "pkcs1", ep, pkcs1_cryptdecode, &p1
-#define TAB_p1dec TAB_p1enc
-
-#define DECL_p1vrf DECL_p1enc
-#define FUNC_p1vrf FUNC_p1enc
-#define ARG_p1vrf \
- "pkcs1", ep, pkcs1_sigdecode, &p1
-#define TAB_p1vrf TAB_p1enc
-
-#define DECL_oaepenc \
- oaep o; \
- dstr *ep;
-#define FUNC_oaepenc \
- o.r = fib; \
- o.cc = gcipher_byname(v++->buf); \
- o.ch = ghash_byname(v++->buf); \
- ep = v++; \
- o.ep = ep->buf; \
- o.epsz = ep->len;
-#define ARG_oaepenc \
- "oaep", ep, oaep_encode, &o
-#define TAB_oaepenc \
- &type_string, &type_string, &type_hex
-
-#define DECL_oaepdec DECL_oaepenc
-#define FUNC_oaepdec FUNC_oaepenc
-#define ARG_oaepdec \
- "oaep", ep, oaep_decode, &o
-#define TAB_oaepdec TAB_oaepenc
-
-#define DECL_psssig \
- pss pp;
-#define FUNC_psssig \
- pp.r = fib; \
- pp.cc = gcipher_byname(v++->buf); \
- pp.ch = ghash_byname(v++->buf); \
- pp.ssz = *(int *)v++->buf;
-#define ARG_psssig \
- "pss", 0, pss_encode, &pp
-#define TAB_psssig \
- &type_string, &type_string, &type_int
-
-#define DECL_pssvrf DECL_psssig
-#define FUNC_pssvrf FUNC_psssig
-#define ARG_pssvrf \
- "pss", 0, pss_decode, &pp
-#define TAB_pssvrf TAB_psssig
-
-#define TESTS(DO) \
- DO(pad, enc, p1enc) \
- DO(pad, dec, p1dec) \
- DO(pad, sig, p1sig) \
- DO(pad, vrf, p1vrf) \
- DO(pub, enc, p1enc) \
- DO(priv, dec, p1dec) \
- DO(priv, sig, p1sig) \
- DO(pub, vrf, p1vrf) \
- DO(pad, enc, oaepenc) \
- DO(pad, dec, oaepdec) \
- DO(pub, enc, oaepenc) \
- DO(priv, dec, oaepdec) \
- DO(pad, sig, psssig) \
- DO(pad, vrf, pssvrf) \
- DO(priv, sig, psssig) \
- DO(pub, vrf, pssvrf)
-
-#define FUNCS(key, op, enc) \
- int t_##key##_##enc(dstr *v) \
- { \
- DECL_##key \
- DECL_##op \
- DECL_##enc \
- fib->ops->misc(fib, GRAND_SEEDINT, 14); \
- FUNC_##key \
- FUNC_##op \
- FUNC_##enc \
- return (t##op##key(ARG_##key ARG_##op ARG_##enc)); \
- }
-
-#define TAB(key, op, enc) \
- { #enc "-" #key, t_##key##_##enc, { TAB_##key TAB_##op TAB_##enc } },
-
-static grand *fib;
-
-TESTS(FUNCS)
-
-static const test_chunk tests[] = {
- TESTS(TAB)
- { 0 }
-};
-
-int main(int argc, char *argv[])
-{
- sub_init();
- fib = fibrand_create(0);
- test_run(argc, argv, tests, SRCDIR "/tests/rsa");
- GR_DESTROY(fib);
- return (0);
-}
-
-/*----- That's all, folks -------------------------------------------------*/