From 51a0f80584415b57d188db22b77a4cd5451b70cd Mon Sep 17 00:00:00 2001 From: mdw Date: Fri, 6 Apr 2001 22:05:11 +0000 Subject: [PATCH] Add support for SSL pseudo-random function. --- Makefile.m4 | 10 +- sslprf.c | 366 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ sslprf.h | 145 +++++++++++++++++++++++ tests/sslprf | 11 ++ 4 files changed, 529 insertions(+), 3 deletions(-) create mode 100644 sslprf.c create mode 100644 sslprf.h create mode 100644 tests/sslprf diff --git a/Makefile.m4 b/Makefile.m4 index 600b3d6..2a0ac39 100644 --- a/Makefile.m4 +++ b/Makefile.m4 @@ -1,6 +1,6 @@ ## -*-makefile-*- ## -## $Id: Makefile.m4,v 1.49 2001/04/04 20:10:52 mdw Exp $ +## $Id: Makefile.m4,v 1.50 2001/04/06 22:05:10 mdw Exp $ ## ## Makefile for Catacomb ## @@ -29,6 +29,9 @@ ##----- Revision history ---------------------------------------------------- ## ## $Log: Makefile.m4,v $ +## Revision 1.50 2001/04/06 22:05:10 mdw +## Add support for SSL pseudo-random function. +## ## Revision 1.49 2001/04/04 20:10:52 mdw ## Add support for the TLS pseudo-random function. ## @@ -281,7 +284,7 @@ pkginclude_HEADERS = \ primetab.h pfilt.h rabin.h \ pgen.h prim.h strongprime.h limlee.h keycheck.h \ bbs.h rsa.h dh.h dsarand.h dsa.h \ - oaep.h pkcs1.h pss.h tlsprf.h \ + oaep.h pkcs1.h pss.h tlsprf.h sslprf.h \ gfshare.h share.h \ rho.h \ allwithsuffix(`ciphers', `cipher_modes', `.h') \ @@ -320,7 +323,7 @@ libcatacomb_la_SOURCES = \ lcrand.c fibrand.c rc4.c seal.c rand.c noise.c fipstest.c maurer.c \ arena.c \ passphrase.c pixie-client.c pixie-common.c lmem.c \ - oaep.c pkcs1.c pss.c tlsprf.c \ + oaep.c pkcs1.c pss.c tlsprf.c sslprf.c \ gfshare.c \ MP_SOURCES karatsuba.h \ des-base.c des-base.h \ @@ -439,6 +442,7 @@ adorn(`nl`'CTESTRIG(', join(`hashes', `-', `hash_modes'), `)') CTESTRIG(lcrand) CTESTRIG(oaep) CTESTRIG(tlsprf) +CTESTRIG(sslprf) CTESTRIG(mpx) CTESTRIG(mpx-kmul) CTESTRIG(mpx-ksqr) diff --git a/sslprf.c b/sslprf.c new file mode 100644 index 0000000..e9682e5 --- /dev/null +++ b/sslprf.c @@ -0,0 +1,366 @@ +/* -*-c-*- + * + * $Id: sslprf.c,v 1.1 2001/04/06 22:05:10 mdw Exp $ + * + * The SSL pseudo-random function + * + * (c) 2001 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. + */ + +/*----- Revision history --------------------------------------------------* + * + * $Log: sslprf.c,v $ + * Revision 1.1 2001/04/06 22:05:10 mdw + * Add support for SSL pseudo-random function. + * + */ + +/*----- Header files ------------------------------------------------------*/ + +#include +#include +#include + +#include "arena.h" +#include "ghash.h" +#include "grand.h" +#include "paranoia.h" +#include "sslprf.h" + +/*----- Main code ---------------------------------------------------------*/ + +/* --- @step@ --- * + * + * Arguments: @sslprf_ctx *c@ = pointer to context structure + * + * Returns: --- + * + * Use: Steps the generator. + */ + +static void step(sslprf_ctx *c) +{ + octet buf[64]; + size_t n, sz; + octet x; + ghash *h, *hh; + octet *p; + + h = c->ci->init(); + x = 'A' + c->i - 1; + for (sz = c->i++; sz > 0; sz -= n) { + n = sz; + if (n > sizeof(buf)) + n = sizeof(buf); + memset(buf, x, n); + h->ops->hash(h, buf, n); + } + h->ops->hash(h, c->k, c->ksz); + h->ops->hash(h, c->sd, c->sdsz); + p = h->ops->done(h, 0); + + hh = c->co->init(); + hh->ops->hash(hh, c->k, c->ksz); + hh->ops->hash(hh, p, c->ihashsz); + c->p = hh->ops->done(hh, 0); + h->ops->destroy(h); + + c->h = hh; + c->sz = c->ohashsz; +} + +/* --- @sslprf_init@ --- * + * + * Arguments: @sslprf_ctx *c@ = pointer to a context structure + * @const gchash *hco, *hci@ = outer and inner hash functions + * @const void *k@ = pointer to secret buffer + * @size_t ksz@ = size of the secret + * @const void *sd@ = pointer to seed buffer + * @size_t sdsz@ = size of the seed + * + * Returns: --- + * + * Use: Initializes an SSL generator context. + */ + +void sslprf_init(sslprf_ctx *c, const gchash *hco, const gchash *hci, + const void *k, size_t ksz, + const void *sd, size_t sdsz) +{ + c->co = hco; c->ci = hci; + c->ohashsz = hco->hashsz; c->ihashsz = hci->hashsz; + c->k = k; c->ksz = ksz; c->sd = sd; c->sdsz = sdsz; + c->i = 1; + step(c); +} + +/* --- @sslprf_encrypt@ --- * + * + * Arguments: @sslprf_ctx *c@ = pointer to a context structure + * @const void *src@ = pointer to source buffer + * @void *dest@ = pointer to destination buffer + * @size_t sz@ = size of the buffers + * + * Returns: --- + * + * Use: Encrypts data using the SSL pseudo-random function. If the + * destination pointer is null, the generator is spun and no + * output is produced; if the source pointer is null, raw output + * from the generator is written; otherwise, the source data is + * XORed with the generator output. + */ + +void sslprf_encrypt(sslprf_ctx *c, const void *src, void *dest, size_t sz) +{ + const octet *s = src; + octet *d = dest; + size_t i, n; + + while (sz) { + if (!c->sz) { + c->h->ops->destroy(c->h); + step(c); + } + n = c->sz; + if (n > sz) + n = sz; + if (d) { + if (!s) + memcpy(d, c->p, n); + else { + for (i = 0; i < n; i++) d[i] = s[i] ^ c->p[i]; + s += n; + } + d += n; + } + c->p += n; + c->sz -= n; + sz -= n; + } +} + +/* --- @sslprf_free@ --- * + * + * Arguments: @sslprf_ctx@ = pointer to a context + * + * Returns: --- + * + * Use: Frees resources held in an SSL generator context. + */ + +void sslprf_free(sslprf_ctx *c) +{ + c->h->ops->destroy(c->h); +} + +/* --- Generic random number generator --- */ + +typedef struct grctx { + grand r; + grand_ops ops; + sslprf_ctx prf; +} grctx; + +static void grdestroy(grand *r) +{ + grctx *g = (grctx *)r; + xfree((char *)g->ops.name); + xfree((octet *)g->prf.sd); + sslprf_free(&g->prf); + BURN(*g); + S_DESTROY(g); +} + +static void seed(grctx *g, const void *p, size_t sz) +{ + octet *q; + xfree((octet *)g->prf.sd); + g->prf.sd = q = xmalloc(sz); + memcpy(q, p, sz); + g->prf.sdsz = sz; +} + +static int grmisc(grand *r, unsigned op, ...) +{ + grctx *g = (grctx *)r; + va_list ap; + int rc = 0; + uint32 i; + octet buf[4]; + va_start(ap, op); + + switch (op) { + case GRAND_CHECK: + switch (va_arg(ap, unsigned)) { + case GRAND_CHECK: + case GRAND_SEEDINT: + case GRAND_SEEDUINT32: + case GRAND_SEEDBLOCK: + case GRAND_SEEDRAND: + rc = 1; + break; + default: + rc = 0; + break; + } + break; + case GRAND_SEEDINT: + i = va_arg(ap, unsigned); + STORE32(buf, i); + seed(g, buf, sizeof(buf)); + break; + case GRAND_SEEDUINT32: + i = va_arg(ap, uint32); + STORE32(buf, i); + seed(g, buf, sizeof(buf)); + break; + case GRAND_SEEDBLOCK: { + const void *p = va_arg(ap, const void *); + size_t sz = va_arg(ap, size_t); + seed(g, p, sz); + } break; + case GRAND_SEEDRAND: { + grand *rr = va_arg(ap, grand *); + octet buf[16]; + rr->ops->fill(rr, buf, sizeof(buf)); + seed(g, buf, sizeof(buf)); + } break; + default: + GRAND_BADOP; + break; + } + + va_end(ap); + return (rc); +} + +static octet grbyte(grand *r) +{ + grctx *g = (grctx *)r; + octet o; + sslprf_encrypt(&g->prf, 0, &o, 1); + return (o); +} + +static uint32 grword(grand *r) +{ + grctx *g = (grctx *)r; + octet b[4]; + sslprf_encrypt(&g->prf, 0, &b, sizeof(b)); + return (LOAD32(b)); +} + +static void grfill(grand *r, void *p, size_t sz) +{ + grctx *g = (grctx *)r; + sslprf_encrypt(&g->prf, 0, p, sz); +} + +static const grand_ops grops = { + "", + GRAND_CRYPTO, 0, + grmisc, grdestroy, + grword, grbyte, grword, grand_range, grfill +}; + +/* ---@sslprf_rand@ --- * + * + * Arguments: @const gchash *hco, const gchash *hci@ = hash functions + * @const void *k@ = pointer to the key material + * @size_t ksz@ = size of the key material + * @const void *sd@ = pointer to the seed material + * @size_t sdsz@ = size of the seed material + * + * Returns: Pointer to generic random number generator interface. + * + * Use: Creates a generic generator which does TLS data expansion. + */ + +grand *sslprf_rand(const gchash *hco, const gchash *hci, + const void *k, size_t ksz, + const void *sd, size_t sdsz) +{ + grctx *g = S_CREATE(grctx); + dstr d = DSTR_INIT; + octet *q = xmalloc(sdsz); + memcpy(q, sd, sdsz); + dstr_putf(&d, "sslprf(%s,%s)", hco->name, hci->name); + g->ops = grops; + g->ops.name = xstrdup(d.buf); + g->r.ops = &g->ops; + dstr_destroy(&d); + sslprf_init(&g->prf, hco, hci, k, ksz, q, sdsz); + return (&g->r); +} + +/*----- Test rig ----------------------------------------------------------*/ + +#ifdef TEST_RIG + +#include +#include + +#include +#include + +#include "sha.h" +#include "md5.h" + +static int v_generate(dstr *v) +{ + grand *g; + dstr d = DSTR_INIT; + int ok = 1; + + g = sslprf_rand(&md5, &sha, v[0].buf, v[0].len, v[1].buf, v[1].len); + dstr_ensure(&d, v[2].len); + d.len = v[2].len; + g->ops->fill(g, d.buf, d.len); + g->ops->destroy(g); + if (memcmp(v[2].buf, d.buf, d.len) != 0) { + ok = 0; + printf("\nfail sslprf:" + "\n\tkey = "); + type_hex.dump(&v[0], stdout); + printf("\n\tseed = "); type_hex.dump(&v[1], stdout); + printf("\n\texpected = "); type_hex.dump(&v[2], stdout); + printf("\n\tcalculated = "); type_hex.dump(&d, stdout); + putchar('\n'); + } + return (ok); +} + +static test_chunk defs[] = { + { "sslprf", v_generate, { &type_hex, &type_hex, &type_hex, 0 } }, + { 0, 0, { 0 } } +}; + +int main(int argc, char *argv[]) +{ + test_run(argc, argv, defs, SRCDIR"/tests/sslprf"); + return (0); +} + +#endif + +/*----- That's all, folks -------------------------------------------------*/ diff --git a/sslprf.h b/sslprf.h new file mode 100644 index 0000000..a46bc0f --- /dev/null +++ b/sslprf.h @@ -0,0 +1,145 @@ +/* -*-c-*- + * + * $Id: sslprf.h,v 1.1 2001/04/06 22:05:10 mdw Exp $ + * + * The SSL pseudo-random function + * + * (c) 2001 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. + */ + +/*----- Revision history --------------------------------------------------* + * + * $Log: sslprf.h,v $ + * Revision 1.1 2001/04/06 22:05:10 mdw + * Add support for SSL pseudo-random function. + * + */ + +#ifndef CATACOMB_SSLPRF_H +#define CATACOMB_SSLPRF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----- Header files ------------------------------------------------------*/ + +#ifndef CATACOMB_GMAC_H +# include "gmac.h" +#endif + +#ifndef CATACOMB_GRAND_H +# include "grand.h" +#endif + +/*----- Data structures ---------------------------------------------------*/ + +typedef struct sslprf_ctx { + const gchash *co, *ci; /* Outer and inner hash functions */ + size_t ohashsz, ihashsz; /* Size of the hash outputs */ + ghash *h; /* Hash context from last time */ + const octet *k; /* Pointer to the secret */ + size_t ksz; /* Size of the secret buffer */ + const octet *sd; /* Pointer to the seed */ + size_t sdsz; /* Size of the seed buffer */ + unsigned i; /* Which iteration this is */ + octet *p; /* Pointer to output buffer */ + size_t sz; /* How many bytes are left */ +} sslprf_ctx; + +/*----- Functions provided ------------------------------------------------*/ + +/* --- @sslprf_init@ --- * + * + * Arguments: @sslprf_ctx *c@ = pointer to a context structure + * @const gchash *hco, *hci@ = outer and inner hash functions + * @const void *k@ = pointer to secret buffer + * @size_t ksz@ = size of the secret + * @const void *sd@ = pointer to seed buffer + * @size_t sdsz@ = size of the seed + * + * Returns: --- + * + * Use: Initializes an SSL generator context. + */ + +extern void sslprf_init(sslprf_ctx */*c*/, + const gchash */*hco*/, const gchash */*hci*/, + const void */*k*/, size_t /*ksz*/, + const void */*sd*/, size_t /*sdsz*/); + +/* --- @sslprf_encrypt@ --- * + * + * Arguments: @sslprf_ctx *c@ = pointer to a context structure + * @const void *src@ = pointer to source buffer + * @void *dest@ = pointer to destination buffer + * @size_t sz@ = size of the buffers + * + * Returns: --- + * + * Use: Encrypts data using the SSL pseudo-random function. If the + * destination pointer is null, the generator is spun and no + * output is produced; if the source pointer is null, raw output + * from the generator is written; otherwise, the source data is + * XORed with the generator output. + */ + +extern void sslprf_encrypt(sslprf_ctx */*c*/, + const void */*src*/, void */*dest*/, + size_t /*sz*/); + +/* --- @sslprf_free@ --- * + * + * Arguments: @sslprf_ctx@ = pointer to a context + * + * Returns: --- + * + * Use: Frees resources held in an SSL generator context. + */ + +extern void sslprf_free(sslprf_ctx */*c*/); + +/* ---@sslprf_rand@ --- * + * + * Arguments: @const gchash *hco, const gchash *hci@ = hash functions + * @const void *k@ = pointer to the key material + * @size_t ksz@ = size of the key material + * @const void *sd@ = pointer to the seed material + * @size_t sdsz@ = size of the seed material + * + * Returns: Pointer to generic random number generator interface. + * + * Use: Creates a generic generator which does TLS data expansion. + */ + +extern grand *sslprf_rand(const gchash */*hco*/, const gchash */*hci*/, + const void */*k*/, size_t /*ksz*/, + const void */*sd*/, size_t /*sdsz*/); + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/tests/sslprf b/tests/sslprf new file mode 100644 index 0000000..b24813d --- /dev/null +++ b/tests/sslprf @@ -0,0 +1,11 @@ +# $Id: sslprf,v 1.1 2001/04/06 22:05:11 mdw Exp $ +# +# SSL pseudo-random function + +sslprf { + # --- Generated using SSLeay --- + + 4837879a5040b1499a9cae62747e4857b090a0334683d8492d1d87933b58fa07523d4b8d0df762b62caddf7ac1304cd9 3ace3cb1ee080975da0dc748207c2bc0eb995746d0b37ab4789932a32ec5347b3ace3cb100000000b28539b8285cbc37622b65d8efcba4ad13eb42712c47d6f5 c15e3166e8a743e6b5da7d9cbcc08c2e4107887a70f2a4e16b54243276c48894569f2916c6cb610bb84b766b7283dca0a346fcce41683ec01f06c17e91758d5d31fbd1ca0a7d75b909035f04786f41efde988d20f5d1fecad337a3a23a16fde1beae5400bc3f357c; + + 53a82e555607a83890bfc633ff7f1d9ecc7d225f450dff3a8d46dd370033968fc456ae8b6fe3639c71fa2ba9d0f798aa 3ace3ca4ac5e36c228a5ce350f22261eadacdc48873b317843061aa679ed15e63ace3ca4000000009ba10a4a1837535a372de6784f037f6cc36c3113cdcc1465 798b2f8eee4cd6b35a220f8d446672762e8dd53bae7bd773877a1dfe0aa446b4274bafd546e94b1bbe4c2d56a6e60d06871b117a7d562859f36ce2082def1c134b1c117022fe449b2da85e6d2c8e763bec6e35889a315d8686e391c277377beb037dd91accddacd1; +} -- 2.11.0