X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/d03ab969116fe715d569304c1c474749b2f64529..f0c52873e4c1e3a16bb2d5a086df2526f698e4ac:/ofb.h diff --git a/ofb.h b/ofb.h index 85ff08c..970acf7 100644 --- a/ofb.h +++ b/ofb.h @@ -1,13 +1,13 @@ /* -*-c-*- * - * $Id: ofb.h,v 1.1 1999/09/03 08:41:12 mdw Exp $ + * $Id: ofb.h,v 1.5 2004/04/08 01:36:15 mdw Exp $ * * Output feedback for block ciphers * * (c) 1999 Straylight/Edgeware */ -/*----- Licensing notice --------------------------------------------------* +/*----- Licensing notice --------------------------------------------------* * * This file is part of Catacomb. * @@ -15,28 +15,20 @@ * 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: ofb.h,v $ - * Revision 1.1 1999/09/03 08:41:12 mdw - * Initial import. - * - */ - -#ifndef OFB_H -#define OFB_H +#ifndef CATACOMB_OFB_H +#define CATACOMB_OFB_H #ifdef __cplusplus extern "C" { @@ -44,16 +36,16 @@ /*----- Header files ------------------------------------------------------*/ -#include +#include #include -#ifndef BLKC_H -# include "blkc.h" +#ifndef CATACOMB_GCIPHER_H +# include "gcipher.h" #endif -#ifndef PARANOIA_H -# include "paranoia.h" +#ifndef CATACOMB_GRAND_H +# include "grand.h" #endif /*----- Macros ------------------------------------------------------------*/ @@ -67,44 +59,18 @@ #define OFB_DECL(PRE, pre) \ \ -typedef struct pre ## _ofbctx { \ - pre ## _ctx ctx; /* Underlying cipher context */ \ - int off; /* Current offset in buffer */ \ - octet iv[PRE ## _BLKSZ]; /* Output buffer and IV */ \ -} pre ## _ofbctx; \ - \ -extern void pre ## _ofbgetiv(const pre ## _ofbctx */*ctx*/, \ - void */*iv*/); \ +/* --- Output feedback context --- */ \ \ -extern void pre ## _ofbsetiv(pre ## _ofbctx */*ctx*/, \ - const void */*iv*/); \ - \ -extern void pre ## _ofbbdry(pre ## _ofbctx */*ctx*/); \ - \ -extern void pre ## _ofbsetkey(pre ## _ofbctx */*ctx*/, \ - const pre ## _ctx */*k*/); \ - \ -extern void pre ## _ofbinit(pre ## _ofbctx */*ctx*/, \ - const void */*key*/, size_t /*sz*/, \ - const void */*iv*/); \ - \ -extern void pre ## _ofbencrypt(pre ## _ofbctx */*ctx*/, \ - const void */*src*/, void */*dest*/, \ - size_t /*sz*/); - -/* --- @OFB_DEF@ --- * - * - * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher - * - * Use: Creates definitions for output feedback mode. - */ - -#define OFB_DEF(PRE, pre) \ +typedef struct pre##_ofbctx { \ + pre##_ctx ctx; /* Underlying cipher context */ \ + unsigned off; /* Current offset in buffer */ \ + octet iv[PRE##_BLKSZ]; /* Output buffer and IV */ \ +} pre##_ofbctx; \ \ /* --- @pre_ofbgetiv@ --- * \ * \ * Arguments: @const pre_ofbctx *ctx@ = pointer to OFB context block \ - * @void *iv#@ = pointer to output data block \ + * @void *iv@ = pointer to output data block \ * \ * Returns: --- \ * \ @@ -114,14 +80,8 @@ extern void pre ## _ofbencrypt(pre ## _ofbctx */*ctx*/, \ * decryption. \ */ \ \ -void pre ## _ofbgetiv(const pre ## _ofbctx *ctx, void *iv) \ -{ \ - octet *p = iv; \ - int off = ctx->off; \ - int rest = PRE ## _BLKSZ - off; \ - memcpy(p, ctx->iv + off, rest); \ - memcpy(p + rest, ctx->iv, off); \ -} \ +extern void pre##_ofbgetiv(const pre##_ofbctx */*ctx*/, \ + void */*iv*/); \ \ /* --- @pre_ofbsetiv@ --- * \ * \ @@ -133,14 +93,8 @@ void pre ## _ofbgetiv(const pre ## _ofbctx *ctx, void *iv) \ * Use: Sets the IV to use for subsequent encryption. \ */ \ \ -void pre ## _ofbsetiv(pre ## _ofbctx *ctx, const void *iv) \ -{ \ - uint32 niv[PRE ## _BLKSZ / 4]; \ - BLKC_LOAD(PRE, niv, iv); \ - pre ## _eblk(&ctx->ctx, niv, niv); \ - BLKC_STORE(PRE, ctx->iv, niv); \ - ctx->off = 0; \ -} \ +extern void pre##_ofbsetiv(pre##_ofbctx */*ctx*/, \ + const void */*iv*/); \ \ /* --- @pre_ofbbdry@ --- * \ * \ @@ -152,13 +106,7 @@ void pre ## _ofbsetiv(pre ## _ofbctx *ctx, const void *iv) \ * decryption must place a similar boundary. \ */ \ \ -void pre ## _ofbbdry(pre ## _ofbctx *ctx) \ -{ \ - octet iv[PRE ## _BLKSZ]; \ - pre ## _ofbgetiv(ctx, iv); \ - pre ## _ofbsetiv(ctx, iv); \ - BURN(iv); \ -} \ +extern void pre##_ofbbdry(pre##_ofbctx */*ctx*/); \ \ /* --- @pre_ofbsetkey@ --- * \ * \ @@ -170,10 +118,8 @@ void pre ## _ofbbdry(pre ## _ofbctx *ctx) \ * Use: Sets the OFB context to use a different cipher key. \ */ \ \ -void pre ## _ofbsetkey(pre ## _ofbctx *ctx, const pre ## _ctx *k) \ -{ \ - ctx->ctx = *k; \ -} \ +extern void pre##_ofbsetkey(pre##_ofbctx */*ctx*/, \ + const pre##_ctx */*k*/); \ \ /* --- @pre_ofbinit@ --- * \ * \ @@ -191,14 +137,9 @@ void pre ## _ofbsetkey(pre ## _ofbctx *ctx, const pre ## _ctx *k) \ * and @pre_ofbsetiv@. \ */ \ \ -void pre ## _ofbinit(pre ## _ofbctx *ctx, \ - const void *key, size_t sz, \ - const void *iv) \ -{ \ - static octet zero[PRE ## _BLKSZ] = { 0 }; \ - pre ## _init(&ctx->ctx, key, sz); \ - pre ## _ofbsetiv(ctx, iv ? iv : zero); \ -} \ +extern void pre##_ofbinit(pre##_ofbctx */*ctx*/, \ + const void */*key*/, size_t /*sz*/, \ + const void */*iv*/); \ \ /* --- @pre_ofbencrypt@ --- * \ * \ @@ -216,186 +157,26 @@ void pre ## _ofbinit(pre ## _ofbctx *ctx, \ * cipher as a random data generator. \ */ \ \ -void pre ## _ofbencrypt(pre ## _ofbctx *ctx, \ - const void *src, void *dest, \ - size_t sz) \ -{ \ - const octet *s = src; \ - octet *d = dest; \ - int off = ctx->off; \ - \ - /* --- Empty blocks are trivial --- */ \ - \ - if (!sz) \ - return; \ - \ - /* --- If I can deal with the block from my buffer, do that --- */ \ - \ - if (sz < PRE ## _BLKSZ - off) \ - goto small; \ - \ - /* --- Finish off what's left in my buffer --- */ \ - \ - if (!d) \ - sz -= off; \ - else { \ - while (off < PRE ## _BLKSZ) { \ - register octet x = s ? *s++ : 0; \ - *d++ = ctx->iv[off++] ^ x; \ - sz--; \ - } \ - } \ - \ - /* --- Main encryption loop --- */ \ - \ - { \ - uint32 iv[PRE ## _BLKSZ / 4]; \ - BLKC_LOAD(PRE, iv, ctx->iv); \ - \ - for (;;) { \ - pre ## _eblk(&ctx->ctx, iv, iv); \ - if (sz < PRE ## _BLKSZ) \ - break; \ - if (d) { \ - if (!s) \ - BLKC_STORE(PRE, d, iv); \ - else { \ - uint32 x[PRE ## _BLKSZ / 4]; \ - BLKC_LOAD(PRE, x, s); \ - BLKC_XSTORE(PRE, d, iv, x); \ - s += PRE ## _BLKSZ; \ - } \ - d += PRE ## _BLKSZ; \ - } \ - sz -= PRE ## _BLKSZ; \ - } \ - \ - BLKC_STORE(PRE, ctx->iv, iv); \ - off = 0; \ - } \ - \ - /* --- Tidying up the tail end --- */ \ - \ - if (sz) { \ - small: \ - if (!d) \ - off += sz; \ - else do { \ - register octet x = s ? *s++ : 0; \ - *d++ = ctx->iv[off++] ^ x; \ - sz--; \ - } while (sz); \ - } \ +extern void pre##_ofbencrypt(pre##_ofbctx */*ctx*/, \ + const void */*src*/, void */*dest*/, \ + size_t /*sz*/); \ \ - /* --- Done --- */ \ - \ - ctx->off = off; \ - return; \ -} \ - \ -OFB_TEST(PRE, pre) - -/*----- Test rig ----------------------------------------------------------*/ - -#ifdef TEST_RIG - -#include - -#include "daftstory.h" - -/* --- @OFB_TEST@ --- * - * - * Arguments: @PRE@, @pre@ = prefixes for block cipher definitions - * - * Use: Standard test rig for OFB functions. - */ - -#define OFB_TEST(PRE, pre) \ - \ -/* --- Initial plaintext for the test --- */ \ - \ -static const octet text[] = TEXT; \ - \ -/* --- Key and IV to use --- */ \ - \ -static const octet key[] = KEY; \ -static const octet iv[] = IV; \ - \ -/* --- Buffers for encryption and decryption output --- */ \ - \ -static octet ct[sizeof(text)]; \ -static octet pt[sizeof(text)]; \ - \ -static void hexdump(const octet *p, size_t sz) \ -{ \ - const octet *q = p + sz; \ - for (sz = 0; p < q; p++, sz++) { \ - printf("%02x", *p); \ - if ((sz + 1) % PRE ## _BLKSZ == 0) \ - putchar(':'); \ - } \ -} \ - \ -int main(void) \ -{ \ - size_t sz = 0, rest; \ - pre ## _ofbctx ctx; \ - int status = 0; \ - int done = 0; \ - pre ## _ctx k; \ - \ - size_t keysz = PRE ## _KEYSZ ? \ - PRE ## _KEYSZ : strlen((const char *)key); \ - \ - fputs(#pre "-ofb: ", stdout); \ +/* --- @pre_ofbrand@ --- * \ + * \ + * Arguments: @const void *k@ = pointer to key material \ + * @size_t sz@ = size of key material \ + * \ + * Returns: Pointer to generic random number generator interface. \ + * \ + * Use: Creates a random number interface wrapper around an \ + * OFB-mode block cipher. \ + */ \ \ - pre ## _init(&k, key, keysz); \ - pre ## _ofbsetkey(&ctx, &k); \ +extern grand *pre##_ofbrand(const void */*k*/, size_t /*sz*/); \ \ - while (sz <= sizeof(text)) { \ - rest = sizeof(text) - sz; \ - memcpy(ct, text, sizeof(text)); \ - pre ## _ofbsetiv(&ctx, iv); \ - pre ## _ofbencrypt(&ctx, ct, ct, sz); \ - pre ## _ofbencrypt(&ctx, ct + sz, ct + sz, rest); \ - memcpy(pt, ct, sizeof(text)); \ - pre ## _ofbsetiv(&ctx, iv); \ - pre ## _ofbencrypt(&ctx, pt, pt, rest); \ - pre ## _ofbencrypt(&ctx, pt + rest, pt + rest, sz); \ - if (memcmp(pt, text, sizeof(text)) == 0) { \ - done++; \ - if (sizeof(text) < 40 || done % 8 == 0) \ - fputc('.', stdout); \ - if (done % 480 == 0) \ - fputs("\n\t", stdout); \ - fflush(stdout); \ - } else { \ - printf("\nError (sz = %lu)\n", (unsigned long)sz); \ - status = 1; \ - printf("\tplaintext = "); hexdump(text, sz); \ - printf(", "); hexdump(text + sz, rest); \ - fputc('\n', stdout); \ - printf("\tciphertext = "); hexdump(ct, sz); \ - printf(", "); hexdump(ct + sz, rest); \ - fputc('\n', stdout); \ - printf("\trecovered text = "); hexdump(pt, sz); \ - printf(", "); hexdump(pt + sz, rest); \ - fputc('\n', stdout); \ - fputc('\n', stdout); \ - } \ - if (sz < 63) \ - sz++; \ - else \ - sz += 9; \ - } \ +/* --- Generic cipher interface --- */ \ \ - fputs(status ? " failed\n" : " ok\n", stdout); \ - return (status); \ -} - -#else -# define OFB_TEST(PRE, pre) -#endif +extern const gccipher pre##_ofb; /*----- That's all, folks -------------------------------------------------*/