X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/ba6e6b64033b1f9de49feccb5c9cd438354481f7..0f00dc4c8eb47e67bc0f148c2dd109f73a451e0a:/symm/mars-mktab.c diff --git a/symm/mars-mktab.c b/symm/mars-mktab.c new file mode 100644 index 0000000..750f727 --- /dev/null +++ b/symm/mars-mktab.c @@ -0,0 +1,315 @@ +/* -*-c-*- + * + * Generate the MARS S-box table + * + * (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 + +#include + +#include "sha.h" + +/*----- SHA-1 (quick version) ---------------------------------------------*/ + +/* --- @sha_compress@ --- * + * + * Arguments: @sha_ctx *ctx@ = pointer to context block + * @const void *sbuf@ = pointer to buffer of appropriate size + * + * Returns: --- + * + * Use: SHA-1 compression function. + */ + +void sha_compress(sha_ctx *ctx, const void *sbuf) +{ + uint32 a, b, c, d, e; + uint32 buf[80]; + + /* --- Fetch the chaining variables --- */ + + a = ctx->a; + b = ctx->b; + c = ctx->c; + d = ctx->d; + e = ctx->e; + + /* --- Fetch and expand the buffer contents --- */ + + { + int i; + const octet *p; + + for (i = 0, p = sbuf; i < 16; i++, p += 4) + buf[i] = LOAD32(p); + for (i = 16; i < 80; i++) { + uint32 x = buf[i - 3] ^ buf[i - 8] ^ buf[i - 14] ^ buf[i - 16]; + buf[i] = ROL32(x, 1); + } + } + + /* --- Definitions for round functions --- */ + +#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define G(x, y, z) ((x) ^ (y) ^ (z)) +#define H(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) + +#define T(v, w, x, y, z, i, f, k) do { \ + uint32 _x; \ + z = ROL32(v, 5) + f(w, x, y) + z + buf[i] + k; \ + w = ROR32(w, 2); \ + _x = v; v = z; z = y; y = x; x = w; w = _x; \ +} while (0) + +#define FF(v, w, x, y, z, i) T(v, w, x, y, z, i, F, 0x5a827999) +#define GG(v, w, x, y, z, i) T(v, w, x, y, z, i, G, 0x6ed9eba1) +#define HH(v, w, x, y, z, i) T(v, w, x, y, z, i, H, 0x8f1bbcdc) +#define II(v, w, x, y, z, i) T(v, w, x, y, z, i, G, 0xca62c1d6) + + /* --- The main compression function --- */ + + { + unsigned i; + for (i = 0; i < 20; i++) + FF(a, b, c, d, e, i); + for (i = 20; i < 40; i++) + GG(a, b, c, d, e, i); + for (i = 40; i < 60; i++) + HH(a, b, c, d, e, i); + for (i = 60; i < 80; i++) + II(a, b, c, d, e, i); + } + + ctx->a += a; + ctx->b += b; + ctx->c += c; + ctx->d += d; + ctx->e += e; +} + +/* --- @sha_init@ --- * + * + * Arguments: @sha_ctx *ctx@ = pointer to context block to initialize + * + * Returns: --- + * + * Use: Initializes a context block ready for hashing. + */ + +void sha_init(sha_ctx *ctx) +{ + ctx->a = 0x67452301; + ctx->b = 0xefcdab89; + ctx->c = 0x98badcfe; + ctx->d = 0x10325476; + ctx->e = 0xc3d2e1f0; + ctx->off = 0; + ctx->nl = ctx->nh = 0; +} + +/* --- @sha_hash@ --- * + * + * Arguments: @sha_ctx *ctx@ = pointer to context block + * @const void *buf@ = buffer of data to hash + * @size_t sz@ = size of buffer to hash + * + * Returns: --- + * + * Use: Hashes a buffer of data. The buffer may be of any size and + * alignment. + */ + +void sha_hash(sha_ctx *ctx, const void *buf, size_t sz) +{ + sha_ctx *_bctx = (ctx); + size_t _bsz = (sz); + const octet *_bbuf = (octet *) (buf); + + { + uint32 _l = ((uint32) ((_bsz) & MASK32)); + uint32 _h = ((_bsz & ~MASK32) >> 16) >> 16; + _bctx->nh += _h; + _bctx->nl += _l; + if (_bctx->nl < _l || _bctx->nl & ~MASK32) + _bctx->nh++; + } + if (_bctx->off + _bsz < SHA_BUFSZ) { + memcpy(_bctx->buf + _bctx->off, _bbuf, _bsz); + _bctx->off += _bsz; + } else { + if (_bctx->off) { + size_t s = SHA_BUFSZ - _bctx->off; + memcpy(_bctx->buf + _bctx->off, _bbuf, s); + sha_compress(_bctx, _bctx->buf); + _bsz -= s; + _bbuf += s; + } + while (_bsz >= SHA_BUFSZ) { + sha_compress(_bctx, _bbuf); + _bsz -= SHA_BUFSZ; + _bbuf += SHA_BUFSZ; + } + if (_bsz) + memcpy(_bctx->buf, _bbuf, _bsz); + _bctx->off = _bsz; + } +} + +/* --- @sha_done@ --- * + * + * Arguments: @sha_ctx *ctx@ = pointer to context block + * @void *hash@ = pointer to output buffer + * + * Returns: --- + * + * Use: Returns the hash of the data read so far. + */ + +void sha_done(sha_ctx *ctx, void *hash) +{ + octet *p = hash; + { + sha_ctx *_pctx = (ctx); + _pctx->buf[_pctx->off] = 0x80; + _pctx->off++; + if (_pctx->off > SHA_BUFSZ - 8) { + if (_pctx->off < SHA_BUFSZ) + memset(_pctx->buf + _pctx->off, 0, SHA_BUFSZ - _pctx->off); + sha_compress(_pctx, _pctx->buf); + memset(_pctx->buf, 0, SHA_BUFSZ - 8); + } else + memset(_pctx->buf + _pctx->off, 0, SHA_BUFSZ - _pctx->off - 8); + } + STORE32(ctx->buf + SHA_BUFSZ - 8, (ctx->nl >> 29) | (ctx->nh << 3)); + STORE32(ctx->buf + SHA_BUFSZ - 4, ctx->nl << 3); + sha_compress(ctx, ctx->buf); + STORE32(p + 0, ctx->a); + STORE32(p + 4, ctx->b); + STORE32(p + 8, ctx->c); + STORE32(p + 12, ctx->d); + STORE32(p + 16, ctx->e); +} + +/*----- Main code ---------------------------------------------------------*/ + +static void mks(uint32 c3, uint32 *s) +{ + octet ibuf[16], obuf[20]; + sha_ctx h; + unsigned i, j; + + STORE32_L(ibuf + 4, 0xb7e15162); + STORE32_L(ibuf + 8, 0x243f6a88); + STORE32_L(ibuf + 12, c3); + + for (i = 0; i < 510; i += 5) { + STORE32_L(ibuf, i); + sha_init(&h); + sha_hash(&h, ibuf, sizeof(ibuf)); + sha_done(&h, obuf); + for (j = 0; j < 5; j++) + *s++ = LOAD32_L(obuf + (4 * j)); + } + STORE32_L(ibuf, i); + sha_init(&h); + sha_hash(&h, ibuf, sizeof(ibuf)); + sha_done(&h, obuf); + for (j = 0; i < 512; j++, i++) + *s++ = LOAD32_L(obuf + (4 * j)); +} + +static void fix(uint32 *s) +{ + unsigned i, j, n; + uint32 d; + + for (i = 0; i < 512; i++) { + for (j = i & ~255u; j < ((i + 255) & ~255u); j++) { + if (i == j) + continue; + d = s[i] ^ s[j]; + n = 0; + if (!(d & 0xff000000)) n++; + if (!(d & 0x00ff0000)) n++; + if (!(d & 0x0000ff00)) n++; + if (!(d & 0x000000ff)) n++; + if (n >= 2) { + s[i] = U32(s[i] * 3); + goto fixed; + } + } + fixed:; + } +} + +int main(void) +{ + uint32 s[512]; + unsigned i; + + mks(0x02917d59, s); + fix(s); + + puts("\ +/* -*-c-*-\n\ + *\n\ + * MARS tables [generated]\n\ + */\n\ +\n\ +#ifndef CATACOMB_MARS_TAB_H\n\ +#define CATACOMB_MARS_TAB_H\n\ +"); + + fputs("\ +/* --- The S-box --- */\n\ +\n\ +#define MARS_S { \\\n\ + ", stdout); + for (i = 0; i < 512; i++) { + printf("0x%08lx", (unsigned long)s[i]); + if (i == 511) + fputs(" \\\n}\n\n", stdout); + else if (i % 4 == 3) + fputs(", \\\n ", stdout); + else + fputs(", ", stdout); + } + + puts("#endif"); + + if (fclose(stdout)) { + fprintf(stderr, "error writing data\n"); + exit(EXIT_FAILURE); + } + + return (0); +} + +/*----- That's all, folks -------------------------------------------------*/