X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/ba6e6b64033b1f9de49feccb5c9cd438354481f7..0f00dc4c8eb47e67bc0f148c2dd109f73a451e0a:/tlsprf.c?ds=sidebyside diff --git a/tlsprf.c b/tlsprf.c deleted file mode 100644 index 04c4c25..0000000 --- a/tlsprf.c +++ /dev/null @@ -1,542 +0,0 @@ -/* -*-c-*- - * - * $Id: tlsprf.c,v 1.3 2004/04/08 01:36:15 mdw Exp $ - * - * The TLS 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. - */ - -/*----- Header files ------------------------------------------------------*/ - -#include -#include -#include - -#include "arena.h" -#include "gmac.h" -#include "grand.h" -#include "paranoia.h" -#include "tlsprf.h" - -/*----- The data expansion function ---------------------------------------*/ - -/* --- @tlsdx_init@ --- * - * - * Arguments: @tlsdx_ctx *c@ = pointer to a context - * @gmac *m@ = pointer to a generic MAC instance - * @const void *sd@ = pointer to the seed block - * @size_t sdsz@ = size of the seed block - * - * Returns: --- - * - * Use: Initializes a context for the TLS data expansion function. - * This doesn't take ownership of the MAC instance or the seed - * memory, nor does it allocate copies. - */ - -void tlsdx_init(tlsdx_ctx *c, gmac *m, const void *sd, size_t sdsz) -{ - c->k = m; - c->hashsz = GM_CLASS(c->k)->hashsz; - c->sd = sd; c->sdsz = sdsz; - - c->i = GM_INIT(c->k); - GH_HASH(c->i, sd, sdsz); - c->ai = GH_DONE(c->i, 0); - c->o = GM_INIT(c->k); - GH_HASH(c->o, c->ai, c->hashsz); - GH_HASH(c->o, sd, sdsz); - c->p = GH_DONE(c->o, 0); - c->sz = c->hashsz; -} - -/* --- @tlsdx_encrypt@ --- * - * - * Arguments: @tlsdx_ctx *c@ = pointer to a context - * @const void *src@ = pointer to source data - * @void *dest@ = pointer to destination buffer - * @size_t sz@ = size of buffer - * - * Returns: --- - * - * Use: Encrypts data using the TLS data expansion 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 tlsdx_encrypt(tlsdx_ctx *c, const void *src, void *dest, size_t sz) -{ - const octet *s = src; - octet *d = dest; - ghash *h; - size_t i; - size_t n; - - while (sz) { - if (c->sz) - n = c->sz; - else { - h = GM_INIT(c->k); - GH_HASH(h, c->ai, c->hashsz); - c->ai = GH_DONE(h, 0); - GH_DESTROY(c->i); - c->i = h; - GH_DESTROY(c->o); - h = c->o = GM_INIT(c->k); - GH_HASH(h, c->ai, c->hashsz); - GH_HASH(h, c->sd, c->sdsz); - c->p = GH_DONE(h, 0); - c->sz = n = c->hashsz; - } - 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; - } -} - -/* --- @tlsdx_free@ --- * - * - * Arguments: @tlsdx_ctx *c@ = pointer to the context block - * - * Returns: --- - * - * Use: Frees a context for the TLS data expansion function - */ - -void tlsdx_free(tlsdx_ctx *c) -{ - GH_DESTROY(c->i); - GH_DESTROY(c->o); -} - -/* --- Generic random number generator --- */ - -typedef struct dx_grctx { - grand r; - grand_ops ops; - tlsdx_ctx dx; -} dx_grctx; - -static void dx_grdestroy(grand *r) -{ - dx_grctx *g = (dx_grctx *)r; - xfree((char *)g->ops.name); - xfree((octet *)g->dx.sd); - g->dx.k->ops->destroy(g->dx.k); - tlsdx_free(&g->dx); - BURN(*g); - S_DESTROY(g); -} - -static void dx_seed(dx_grctx *g, const void *p, size_t sz) -{ - octet *q; - xfree((octet *)g->dx.sd); - g->dx.sd = q = xmalloc(sz); - memcpy(q, p, sz); - g->dx.sdsz = sz; -} - -static int dx_grmisc(grand *r, unsigned op, ...) -{ - dx_grctx *g = (dx_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); - dx_seed(g, buf, sizeof(buf)); - break; - case GRAND_SEEDUINT32: - i = va_arg(ap, uint32); - STORE32(buf, i); - dx_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); - dx_seed(g, p, sz); - } break; - case GRAND_SEEDRAND: { - grand *rr = va_arg(ap, grand *); - octet buf[16]; - rr->ops->fill(rr, buf, sizeof(buf)); - dx_seed(g, buf, sizeof(buf)); - } break; - default: - GRAND_BADOP; - break; - } - - va_end(ap); - return (rc); -} - -static octet dx_grbyte(grand *r) -{ - dx_grctx *g = (dx_grctx *)r; - octet o; - tlsdx_encrypt(&g->dx, 0, &o, 1); - return (o); -} - -static uint32 dx_grword(grand *r) -{ - dx_grctx *g = (dx_grctx *)r; - octet b[4]; - tlsdx_encrypt(&g->dx, 0, &b, sizeof(b)); - return (LOAD32(b)); -} - -static void dx_grfill(grand *r, void *p, size_t sz) -{ - dx_grctx *g = (dx_grctx *)r; - tlsdx_encrypt(&g->dx, 0, p, sz); -} - -static const grand_ops dx_grops = { - "", - GRAND_CRYPTO, 0, - dx_grmisc, dx_grdestroy, - dx_grword, dx_grbyte, dx_grword, grand_range, dx_grfill -}; - -/* ---@tlsdx_rand@ --- * - * - * Arguments: @const gcmac *mc@ = MAC function to use - * @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 *tlsdx_rand(const gcmac *mc, const void *k, size_t ksz, - const void *sd, size_t sdsz) -{ - dx_grctx *g = S_CREATE(dx_grctx); - dstr d = DSTR_INIT; - gmac *m = GM_KEY(mc, k, ksz); - octet *q = xmalloc(sdsz); - memcpy(q, sd, sdsz); - dstr_putf(&d, "tlsdx(%s)", mc->name); - g->ops = dx_grops; - g->ops.name = xstrdup(d.buf); - g->r.ops = &g->ops; - dstr_destroy(&d); - tlsdx_init(&g->dx, m, q, sdsz); - return (&g->r); -} - -/* --- The actual very paranoid PRF ---------------------------------------*/ - -/* --- @tlsprf_init@ --- * - * - * Arguments: @tlsprf_ctx *c@ = pointer to context block - * @const gcmac *mcx, *mcy@ = left and right MAC 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: --- - * - * Use: Initializes a TLS PRF context. - */ - -void tlsprf_init(tlsprf_ctx *c, const gcmac *mcx, const gcmac *mcy, - const void *k, size_t ksz, const void *sd, size_t sdsz) -{ - size_t n = (ksz + 1)/2; - const octet *kk = k; - tlsdx_init(&c->px, mcx->key(kk, n), sd, sdsz); - tlsdx_init(&c->py, mcy->key(kk + ksz - n, n), sd, sdsz); -} - -/* --- @tlsprf_encrypt@ --- * - * - * Arguments: @tlsprf_ctx *c@ = pointer to a context - * @const void *src@ = pointer to source data - * @void *dest@ = pointer to destination buffer - * @size_t sz@ = size of buffer - * - * Returns: --- - * - * Use: Encrypts data using the TLS 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 tlsprf_encrypt(tlsprf_ctx *c, const void *src, void *dest, size_t sz) -{ - tlsdx_encrypt(&c->px, src, dest, sz); - tlsdx_encrypt(&c->py, dest, dest, sz); -} - -/* --- @tlsprf_free@ --- * - * - * Arguments: @tlsprf_ctx *c@ = pointer to a context - * - * Returns: --- - * - * Use: Frees a TLS PRF context. - */ - -void tlsprf_free(tlsprf_ctx *c) -{ - c->px.k->ops->destroy(c->px.k); - c->py.k->ops->destroy(c->py.k); - tlsdx_free(&c->px); - tlsdx_free(&c->py); -} - -/* --- Generic random number generator --- */ - -typedef struct prf_grctx { - grand r; - grand_ops ops; - tlsprf_ctx prf; -} prf_grctx; - -static void prf_grdestroy(grand *r) -{ - prf_grctx *g = (prf_grctx *)r; - xfree((char *)g->ops.name); - xfree((octet *)g->prf.px.sd); - tlsprf_free(&g->prf); - BURN(*g); - S_DESTROY(g); -} - -static void prf_seed(prf_grctx *g, const void *p, size_t sz) -{ - octet *q; - - xfree((octet *)g->prf.px.sz); - g->prf.px.sd = g->prf.py.sd = q = xmalloc(sz); - memcpy(q, p, sz); - g->prf.px.sdsz = g->prf.py.sdsz = sz; -} - -static int prf_grmisc(grand *r, unsigned op, ...) -{ - prf_grctx *g = (prf_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); - prf_seed(g, buf, sizeof(buf)); - break; - case GRAND_SEEDUINT32: - i = va_arg(ap, uint32); - STORE32(buf, i); - prf_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); - prf_seed(g, p, sz); - } break; - case GRAND_SEEDRAND: { - grand *rr = va_arg(ap, grand *); - octet buf[16]; - rr->ops->fill(rr, buf, sizeof(buf)); - prf_seed(g, buf, sizeof(buf)); - } break; - default: - GRAND_BADOP; - break; - } - - va_end(ap); - return (rc); -} - -static octet prf_grbyte(grand *r) -{ - prf_grctx *g = (prf_grctx *)r; - octet o; - tlsprf_encrypt(&g->prf, 0, &o, 1); - return (o); -} - -static uint32 prf_grword(grand *r) -{ - prf_grctx *g = (prf_grctx *)r; - octet b[4]; - tlsprf_encrypt(&g->prf, 0, &b, sizeof(b)); - return (LOAD32(b)); -} - -static void prf_grfill(grand *r, void *p, size_t sz) -{ - prf_grctx *g = (prf_grctx *)r; - tlsprf_encrypt(&g->prf, 0, p, sz); -} - -static const grand_ops prf_grops = { - "", - GRAND_CRYPTO, 0, - prf_grmisc, prf_grdestroy, - prf_grword, prf_grbyte, prf_grword, grand_range, prf_grfill -}; - -/* ---@tlsprf_rand@ --- * - * - * Arguments: @const gcmac *mcx, *mcy@ = MAC function to use - * @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 *tlsprf_rand(const gcmac *mcx, const gcmac *mcy, - const void *k, size_t ksz, const void *sd, size_t sdsz) -{ - prf_grctx *g = S_CREATE(prf_grctx); - dstr d = DSTR_INIT; - octet *q = xmalloc(sdsz); - memcpy(q, sd, sdsz); - dstr_putf(&d, "tlsprf(%s,%s)", mcx->name, mcy->name); - g->ops = prf_grops; - g->ops.name = xstrdup(d.buf); - g->r.ops = &g->ops; - dstr_destroy(&d); - tlsprf_init(&g->prf, mcx, mcy, k, ksz, q, sdsz); - return (&g->r); -} - -/*----- Test rig ----------------------------------------------------------*/ - -#ifdef TEST_RIG - -#include -#include - -#include -#include - -#include "sha-hmac.h" -#include "md5-hmac.h" - -static int v_generate(dstr *v) -{ - grand *g; - dstr d = DSTR_INIT; - int ok = 1; - - g = tlsprf_rand(&md5_hmac, &sha_hmac, - 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 tlsprf:" - "\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[] = { - { "tlsprf", 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/tlsprf"); - return (0); -} - -#endif - -/*----- That's all, folks -------------------------------------------------*/