X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb/blobdiff_plain/98421fc1a6832ad5de4b3f6171852437aa3e0fb2..a90d420cbe87490c844ae422c966e746d3134b07:/symm/cbc-def.h diff --git a/symm/cbc-def.h b/symm/cbc-def.h index 56c8f054..480f5796 100644 --- a/symm/cbc-def.h +++ b/symm/cbc-def.h @@ -64,7 +64,9 @@ * Use: Creates an implementation for CBC stealing mode. */ -#define CBC_DEF(PRE, pre) \ +#define CBC_DEF(PRE, pre) CBC_DEFX(PRE, pre, #pre, #pre) + +#define CBC_DEFX(PRE, pre, name, fname) \ \ /* --- @pre_cbcgetiv@ --- * \ * \ @@ -79,9 +81,7 @@ */ \ \ void pre##_cbcgetiv(const pre##_cbcctx *ctx, void *iv) \ -{ \ - BLKC_STORE(PRE, iv, ctx->iv); \ -} \ + { BLKC_STORE(PRE, iv, ctx->a); } \ \ /* --- @pre_cbcsetiv@ --- * \ * \ @@ -94,9 +94,7 @@ void pre##_cbcgetiv(const pre##_cbcctx *ctx, void *iv) \ */ \ \ void pre##_cbcsetiv(pre##_cbcctx *ctx, const void *iv) \ -{ \ - BLKC_LOAD(PRE, ctx->iv, iv); \ -} \ + { BLKC_LOAD(PRE, ctx->a, iv); } \ \ /* --- @pre_cbcsetkey@ --- * \ * \ @@ -109,9 +107,7 @@ void pre##_cbcsetiv(pre##_cbcctx *ctx, const void *iv) \ */ \ \ void pre##_cbcsetkey(pre##_cbcctx *ctx, const pre##_ctx *k) \ -{ \ - ctx->ctx = *k; \ -} \ + { ctx->ctx = *k; } \ \ /* --- @pre_cbcinit@ --- * \ * \ @@ -129,12 +125,13 @@ void pre##_cbcsetkey(pre##_cbcctx *ctx, const pre##_ctx *k) \ */ \ \ void pre##_cbcinit(pre##_cbcctx *ctx, \ - const void *key, size_t sz, \ - const void *iv) \ + const void *key, size_t sz, \ + const void *iv) \ { \ static const octet zero[PRE##_BLKSZ] = { 0 }; \ + \ pre##_init(&ctx->ctx, key, sz); \ - BLKC_LOAD(PRE, ctx->iv, iv ? iv : zero); \ + BLKC_LOAD(PRE, ctx->a, iv ? iv : zero); \ } \ \ /* --- @pre_cbcencrypt@ --- * \ @@ -153,16 +150,18 @@ void pre##_cbcinit(pre##_cbcctx *ctx, \ */ \ \ void pre##_cbcencrypt(pre##_cbcctx *ctx, \ - const void *src, void *dest, \ - size_t sz) \ + const void *src, void *dest, \ + size_t sz) \ { \ const octet *s = src; \ octet *d = dest; \ + octet b[PRE##_BLKSZ], bb[PRE##_BLKSZ]; \ + octet y; \ + unsigned i; \ \ /* --- Empty blocks are trivial --- */ \ \ - if (!sz) \ - return; \ + if (!sz) return; \ \ /* --- Extra magical case for a short block --- * \ * \ @@ -172,18 +171,13 @@ void pre##_cbcencrypt(pre##_cbcctx *ctx, \ */ \ \ if (sz < PRE##_BLKSZ) { \ - octet b[PRE##_BLKSZ]; \ - unsigned i; \ - \ - pre##_eblk(&ctx->ctx, ctx->iv, ctx->iv); \ - BLKC_STORE(PRE, b, ctx->iv); \ - if (d) { \ - for (i = 0; i < sz; i++) \ - d[i] = b[i] ^ (s ? s[i] : 0); \ - } \ + pre##_eblk(&ctx->ctx, ctx->a, ctx->a); \ + BLKC_STORE(PRE, b, ctx->a); \ + if (!d) d = bb; \ + for (i = 0; i < sz; i++) d[i] = b[i] ^ (s ? s[i] : 0); \ memmove(b, b + sz, PRE##_BLKSZ - sz); \ memcpy(b + PRE##_BLKSZ - sz, d, sz); \ - BLKC_LOAD(PRE, ctx->iv, b); \ + BLKC_LOAD(PRE, ctx->a, b); \ return; \ } \ \ @@ -194,16 +188,10 @@ void pre##_cbcencrypt(pre##_cbcctx *ctx, \ * and keep a copy of the ciphertext for the next block. \ */ \ \ - while (sz >= 2 * PRE##_BLKSZ || sz == PRE##_BLKSZ) { \ - if (s) { \ - BLKC_XLOAD(PRE, ctx->iv, s); \ - s += PRE##_BLKSZ; \ - } \ - pre##_eblk(&ctx->ctx, ctx->iv, ctx->iv); \ - if (d) { \ - BLKC_STORE(PRE, d, ctx->iv); \ - d += PRE##_BLKSZ; \ - } \ + while (sz >= 2*PRE##_BLKSZ || sz == PRE##_BLKSZ) { \ + if (s) { BLKC_XLOAD(PRE, ctx->a, s); s += PRE##_BLKSZ; } \ + pre##_eblk(&ctx->ctx, ctx->a, ctx->a); \ + if (d) { BLKC_STORE(PRE, d, ctx->a); d += PRE##_BLKSZ; } \ sz -= PRE##_BLKSZ; \ } \ \ @@ -213,8 +201,6 @@ void pre##_cbcencrypt(pre##_cbcctx *ctx, \ */ \ \ if (sz) { \ - octet b[PRE##_BLKSZ]; \ - unsigned i; \ \ /* --- Let @sz@ be the size of the partial block --- */ \ \ @@ -228,9 +214,9 @@ void pre##_cbcencrypt(pre##_cbcctx *ctx, \ * block. \ */ \ \ - if (s) BLKC_XLOAD(PRE, ctx->iv, s); \ - pre##_eblk(&ctx->ctx, ctx->iv, ctx->iv); \ - BLKC_STORE(PRE, b, ctx->iv); \ + if (s) BLKC_XLOAD(PRE, ctx->a, s); \ + pre##_eblk(&ctx->ctx, ctx->a, ctx->a); \ + BLKC_STORE(PRE, b, ctx->a); \ \ /* --- Second stage --- * \ * \ @@ -242,13 +228,13 @@ void pre##_cbcencrypt(pre##_cbcctx *ctx, \ if (s) s += PRE##_BLKSZ; \ if (d) d += PRE##_BLKSZ; \ for (i = 0; i < sz; i++) { \ - register octet x = b[i]; \ + y = b[i]; \ if (s) b[i] ^= s[i]; \ - if (d) d[i] = x; \ + if (d) d[i] = y; \ } \ - BLKC_LOAD(PRE, ctx->iv, b); \ - pre##_eblk(&ctx->ctx, ctx->iv, ctx->iv); \ - if (d) BLKC_STORE(PRE, d - PRE##_BLKSZ, ctx->iv); \ + BLKC_LOAD(PRE, ctx->a, b); \ + pre##_eblk(&ctx->ctx, ctx->a, ctx->a); \ + if (d) BLKC_STORE(PRE, d - PRE##_BLKSZ, ctx->a); \ } \ \ /* --- Done --- */ \ @@ -272,16 +258,19 @@ void pre##_cbcencrypt(pre##_cbcctx *ctx, \ */ \ \ void pre##_cbcdecrypt(pre##_cbcctx *ctx, \ - const void *src, void *dest, \ - size_t sz) \ + const void *src, void *dest, \ + size_t sz) \ { \ const octet *s = src; \ octet *d = dest; \ + uint32 t[PRE##_BLKSZ/4], u[PRE##_BLKSZ/4]; \ + octet b[PRE##_BLKSZ], c[PRE##_BLKSZ]; \ + octet y; \ + unsigned i; \ \ /* --- Empty blocks are trivial --- */ \ \ - if (!sz) \ - return; \ + if (!sz) return; \ \ /* --- Extra magical case for a short block --- * \ * \ @@ -291,19 +280,12 @@ void pre##_cbcdecrypt(pre##_cbcctx *ctx, \ */ \ \ if (sz < PRE##_BLKSZ) { \ - octet b[PRE##_BLKSZ], c[PRE##_BLKSZ]; \ - unsigned i; \ - \ - pre##_eblk(&ctx->ctx, ctx->iv, ctx->iv); \ - BLKC_STORE(PRE, b, ctx->iv); \ - for (i = 0; i < sz; i++) { \ - register octet x = s[i]; \ - d[i] = b[i] ^ x; \ - c[i] = x; \ - } \ + pre##_eblk(&ctx->ctx, ctx->a, ctx->a); \ + BLKC_STORE(PRE, b, ctx->a); \ + for (i = 0; i < sz; i++) { y = s[i]; d[i] = b[i] ^ y; c[i] = y; } \ memmove(b, b + sz, PRE##_BLKSZ - sz); \ memcpy(b + PRE##_BLKSZ - sz, c, sz); \ - BLKC_LOAD(PRE, ctx->iv, b); \ + BLKC_LOAD(PRE, ctx->a, b); \ return; \ } \ \ @@ -314,14 +296,11 @@ void pre##_cbcdecrypt(pre##_cbcctx *ctx, \ * and keep a copy of the ciphertext for the next block. \ */ \ \ - while (sz >= 2 * PRE##_BLKSZ || sz == PRE##_BLKSZ) { \ - uint32 b[PRE##_BLKSZ / 4], niv[PRE##_BLKSZ / 4]; \ - BLKC_LOAD(PRE, niv, s); \ - pre##_dblk(&ctx->ctx, niv, b); \ - BLKC_XSTORE(PRE, d, b, ctx->iv); \ - BLKC_MOVE(PRE, ctx->iv, niv); \ - s += PRE##_BLKSZ; \ - d += PRE##_BLKSZ; \ + while (sz >= 2*PRE##_BLKSZ || sz == PRE##_BLKSZ) { \ + BLKC_LOAD(PRE, t, s); s += PRE##_BLKSZ; \ + pre##_dblk(&ctx->ctx, t, u); \ + BLKC_XSTORE(PRE, d, u, ctx->a); d += PRE##_BLKSZ; \ + BLKC_MOVE(PRE, ctx->a, t); \ sz -= PRE##_BLKSZ; \ } \ \ @@ -331,9 +310,6 @@ void pre##_cbcdecrypt(pre##_cbcctx *ctx, \ */ \ \ if (sz) { \ - octet b[PRE##_BLKSZ]; \ - uint32 bk[PRE##_BLKSZ / 4], niv[PRE##_BLKSZ / 4]; \ - unsigned i; \ \ /* --- Let @sz@ be the size of the partial block --- */ \ \ @@ -345,8 +321,8 @@ void pre##_cbcdecrypt(pre##_cbcctx *ctx, \ * is carried over for the next encryption operation. \ */ \ \ - BLKC_LOAD(PRE, niv, s); \ - pre##_dblk(&ctx->ctx, niv, bk); \ + BLKC_LOAD(PRE, t, s); \ + pre##_dblk(&ctx->ctx, t, u); \ \ /* --- Second stage --- * \ * \ @@ -356,14 +332,10 @@ void pre##_cbcdecrypt(pre##_cbcctx *ctx, \ * three. \ */ \ \ - BLKC_STORE(PRE, b, bk); \ + BLKC_STORE(PRE, b, u); \ s += PRE##_BLKSZ; \ d += PRE##_BLKSZ; \ - for (i = 0; i < sz; i++) { \ - register octet x = s[i]; \ - d[i] = b[i] ^ x; \ - b[i] = x; \ - } \ + for (i = 0; i < sz; i++) { y = s[i]; d[i] = b[i] ^ y; b[i] = y; } \ \ /* --- Third stage --- * \ * \ @@ -371,10 +343,10 @@ void pre##_cbcdecrypt(pre##_cbcctx *ctx, \ * recover the complete plaintext block. \ */ \ \ - BLKC_LOAD(PRE, bk, b); \ - pre##_dblk(&ctx->ctx, bk, bk); \ - BLKC_XSTORE(PRE, d - PRE##_BLKSZ, bk, ctx->iv); \ - BLKC_MOVE(PRE, ctx->iv, niv); \ + BLKC_LOAD(PRE, u, b); \ + pre##_dblk(&ctx->ctx, u, u); \ + BLKC_XSTORE(PRE, d - PRE##_BLKSZ, u, ctx->a); \ + BLKC_MOVE(PRE, ctx->a, t); \ } \ \ /* --- Done --- */ \ @@ -400,29 +372,16 @@ static gcipher *ginit(const void *k, size_t sz) \ } \ \ static void gencrypt(gcipher *c, const void *s, void *t, size_t sz) \ -{ \ - gctx *g = (gctx *)c; \ - pre##_cbcencrypt(&g->k, s, t, sz); \ -} \ + { gctx *g = (gctx *)c; pre##_cbcencrypt(&g->k, s, t, sz); } \ \ static void gdecrypt(gcipher *c, const void *s, void *t, size_t sz) \ -{ \ - gctx *g = (gctx *)c; \ - pre##_cbcdecrypt(&g->k, s, t, sz); \ -} \ + { gctx *g = (gctx *)c; pre##_cbcdecrypt(&g->k, s, t, sz); } \ \ static void gdestroy(gcipher *c) \ -{ \ - gctx *g = (gctx *)c; \ - BURN(*g); \ - S_DESTROY(g); \ -} \ + { gctx *g = (gctx *)c; BURN(*g); S_DESTROY(g); } \ \ static void gsetiv(gcipher *c, const void *iv) \ -{ \ - gctx *g = (gctx *)c; \ - pre##_cbcsetiv(&g->k, iv); \ -} \ + { gctx *g = (gctx *)c; pre##_cbcsetiv(&g->k, iv); } \ \ static const gcipher_ops gops = { \ &pre##_cbc, \ @@ -430,19 +389,19 @@ static const gcipher_ops gops = { \ }; \ \ const gccipher pre##_cbc = { \ - #pre "-cbc", pre##_keysz, PRE##_BLKSZ, \ + name "-cbc", pre##_keysz, PRE##_BLKSZ, \ ginit \ }; \ \ -CBC_TEST(PRE, pre) +CBC_TESTX(PRE, pre, name, fname) /*----- Test rig ----------------------------------------------------------*/ -#ifdef TEST_RIG +#define CBC_TEST(PRE, pre) CBC_TESTX(PRE, pre, #pre, #pre) -#include +#ifdef TEST_RIG -#include "daftstory.h" +#include "modes-test.h" /* --- @CBC_TEST@ --- * * @@ -451,91 +410,34 @@ CBC_TEST(PRE, pre) * Use: Standard test rig for CBC functions. */ -#define CBC_TEST(PRE, pre) \ - \ -/* --- Initial plaintext for the test --- */ \ +#define CBC_TESTX(PRE, pre, name, fname) \ \ -static const octet text[] = TEXT; \ +static pre##_ctx key; \ +static pre##_cbcctx ctx; \ \ -/* --- Key and IV to use --- */ \ +static void pre##_cbc_test_setup(const octet *k, size_t ksz) \ + { pre##_init(&key, k, ksz); pre##_cbcsetkey(&ctx, &key); } \ \ -static const octet key[] = KEY; \ -static const octet iv[] = IV; \ +static void pre##_cbc_test_reset(const octet *iv) \ + { pre##_cbcsetiv(&ctx, iv); } \ \ -/* --- Buffers for encryption and decryption output --- */ \ +static void pre##_cbc_test_enc(const octet *s, octet *d, size_t sz) \ + { pre##_cbcencrypt(&ctx, s, d, sz); } \ \ -static octet ct[sizeof(text)]; \ -static octet pt[sizeof(text)]; \ +static void pre##_cbc_test_dec(const octet *s, octet *d, size_t sz) \ + { pre##_cbcdecrypt(&ctx, s, d, sz); } \ \ -static void hexdump(const octet *p, size_t sz, size_t off) \ +int main(int argc, char *argv[]) \ { \ - const octet *q = p + sz; \ - for (sz = 0; p < q; p++, sz++) { \ - printf("%02x", *p); \ - if ((off + sz + 1) % PRE##_BLKSZ == 0) \ - putchar(':'); \ - } \ -} \ - \ -int main(void) \ -{ \ - size_t sz = 0, rest; \ - pre##_cbcctx ctx; \ - pre##_ctx k; \ - int status = 0; \ - int done = 0; \ - \ - size_t keysz = PRE##_KEYSZ ? \ - PRE##_KEYSZ : strlen((const char *)key); \ - \ - fputs(#pre "-cbc: ", stdout); \ - \ - pre##_init(&k, key, keysz); \ - pre##_cbcsetkey(&ctx, &k); \ - \ - while (sz <= sizeof(text)) { \ - rest = sizeof(text) - sz; \ - memcpy(ct, text, sizeof(text)); \ - pre##_cbcsetiv(&ctx, iv); \ - pre##_cbcencrypt(&ctx, ct, ct, sz); \ - pre##_cbcencrypt(&ctx, ct + sz, ct + sz, rest); \ - memcpy(pt, ct, sizeof(text)); \ - pre##_cbcsetiv(&ctx, iv); \ - pre##_cbcdecrypt(&ctx, pt, pt, sz); \ - pre##_cbcdecrypt(&ctx, pt + sz, pt + sz, rest); \ - 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, 0); \ - printf(", "); hexdump(text + sz, rest, sz); \ - fputc('\n', stdout); \ - printf("\tciphertext = "); hexdump(ct, sz, 0); \ - printf(", "); hexdump(ct + sz, rest, sz); \ - fputc('\n', stdout); \ - printf("\trecovered text = "); hexdump(pt, sz, 0); \ - printf(", "); hexdump(pt + sz, rest, sz); \ - fputc('\n', stdout); \ - fputc('\n', stdout); \ - } \ - if (sz < 63) \ - sz++; \ - else \ - sz += 9; \ - } \ - \ - fputs(status ? " failed\n" : " ok\n", stdout); \ - return (status); \ + return test_encmode(fname "-cbc", PRE##_KEYSZ, PRE##_BLKSZ, \ + 1, TEMF_REFALIGN, \ + pre##_cbc_test_setup, pre##_cbc_test_reset, \ + pre##_cbc_test_enc, pre##_cbc_test_dec, \ + argc, argv); \ } #else -# define CBC_TEST(PRE, pre) +# define CBC_TESTX(PRE, pre, name, fname) #endif /*----- That's all, folks -------------------------------------------------*/