X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/ba6e6b64033b1f9de49feccb5c9cd438354481f7..0f00dc4c8eb47e67bc0f148c2dd109f73a451e0a:/idea.c diff --git a/idea.c b/idea.c deleted file mode 100644 index c0f7fe7..0000000 --- a/idea.c +++ /dev/null @@ -1,275 +0,0 @@ -/* -*-c-*- - * - * $Id: idea.c,v 1.5 2004/04/08 01:36:15 mdw Exp $ - * - * Implementation of the IDEA cipher - * - * (c) 1999 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 "blkc.h" -#include "gcipher.h" -#include "idea.h" - -/*----- Global variables --------------------------------------------------*/ - -const octet idea_keysz[] = { KSZ_SET, IDEA_KEYSZ }; - -/*----- Main code ---------------------------------------------------------*/ - -/* --- @inv@ --- * - * - * Arguments: @uint16 n@ = number to invert - * - * Returns: Multiplicative inverse of @n@ %$\pmod{2^{16} + 1}$%. - * - * Use: Computes multiplicative inverses. This is handy for the - * decryption key scheduling. - */ - -static uint16 inv(uint16 n) -{ - uint32 m = 0x10001; - uint32 a = 1, b = 0; - uint32 nn = n; - - if (!nn) - nn = 0x10000; - for (;;) { - uint32 q, r, t; - if (!(r = m % nn)) - break; - q = m / nn; - m = nn; nn = r; - t = a; a = b - q * a; b = t; - } - if (a > MASK16) - a += 1; - return (U16(a)); -} - -/* --- @MUL@ --- * - * - * Arguments @x@ and @y@ are two 32-bit values to multiply. On exit, @x@ is - * the product of the two arguments. The result is not normalized back to 16 - * bits; the arguments are not expected to be normalized. - * - * This code is from `Side Channel Attack Hardening of the IDEA Cipher', - * published by Ascom Tech. - */ - -#define MUL(x, y) do { \ - unsigned _t; \ - uint32 _tt; \ - \ - x = U16(x - 1); \ - _t = U16(y - 1); \ - _tt = (uint32)x * (uint32)_t + (uint32)x + (uint32)_t + 1; \ - x = U16(_tt); \ - _t = U16(_tt >> 16); \ - x = x - _t + (x <= _t); \ -} while (0) - -/* --- @idea_init@ --- * - * - * Arguments: @idea_ctx *k@ = pointer to key block - * @const void *buf@ = pointer to key buffer - * @size_t sz@ = size of key material - * - * Returns: --- - * - * Use: Initializes an IDEA key buffer. The buffer must be exactly - * 16 bytes in size, because IDEA is only defined with a key - * size of 128 bits. - */ - -void idea_init(idea_ctx *k, const void *buf, size_t sz) -{ - KSZ_ASSERT(idea, sz); - - /* --- Unpack the encryption key --- */ - - { - const octet *p = buf; - uint16 *q = k->e; - uint32 a = LOAD32(p + 0); - uint32 b = LOAD32(p + 4); - uint32 c = LOAD32(p + 8); - uint32 d = LOAD32(p + 12); - int i; - - /* --- Main unpacking loop --- */ - - for (i = 0; i < 6; i++) { - - /* --- Spit out the next 8 subkeys --- */ - - q[0] = U16(a >> 16); - q[1] = U16(a >> 0); - q[2] = U16(b >> 16); - q[3] = U16(b >> 0); - q[4] = U16(c >> 16); - q[5] = U16(c >> 0); - q[6] = U16(d >> 16); - q[7] = U16(d >> 0); - q += 8; - - /* --- Rotate and permute the subkeys --- */ - - { - uint32 t = a; - a = U32((a << 25) | (b >> 7)); - b = U32((b << 25) | (c >> 7)); - c = U32((c << 25) | (d >> 7)); - d = U32((d << 25) | (t >> 7)); - } - } - - /* --- Write out the tail-enders --- */ - - q[0] = U16(a >> 16); - q[1] = U16(a >> 0); - q[2] = U16(b >> 16); - q[3] = U16(b >> 0); - } - - /* --- Convert this into the decryption key --- */ - - { - uint16 *p = k->e + 52; - uint16 *q = k->d; - int i; - - /* --- Translate the main round keys --- */ - - for (i = 0; i < 8; i++) { - p -= 6; - q[4] = p[0]; - q[5] = p[1]; - q[0] = inv(p[2]); - q[3] = inv(p[5]); - if (i) { - q[1] = 0x10000 - p[4]; - q[2] = 0x10000 - p[3]; - } else { - q[1] = 0x10000 - p[3]; - q[2] = 0x10000 - p[4]; - } - q += 6; - } - - /* --- Translate the tail-enders --- */ - - p -= 4; - q[0] = inv(p[0]); - q[1] = 0x10000 - p[1]; - q[2] = 0x10000 - p[2]; - q[3] = inv(p[3]); - } -} - -/* --- @ROUND@ --- */ - -#define MIX(k, a, b, c, d) do { \ - MUL(a, k[0]); \ - b += k[1]; \ - c += k[2]; \ - MUL(d, k[3]); \ -} while (0) - -#define MA(k, a, b, c, d) do { \ - unsigned _u = a ^ c; \ - unsigned _v = b ^ d; \ - MUL(_u, k[4]); \ - _v += _u; \ - MUL(_v, k[5]); \ - _u += _v; \ - a ^= _v; \ - b ^= _u; \ - c ^= _v; \ - d ^= _u; \ -} while (0); - -#define ROUND(k, a, b, c, d) do { \ - MIX(k, a, b, c, d); \ - MA(k, a, b, c, d); \ - (k) += 6; \ -} while (0) - -/* --- Encryption --- */ - -#define EBLK(k, a, b, c, d) do { \ - unsigned _a = U16(a >> 16); \ - unsigned _b = U16(a >> 0); \ - unsigned _c = U16(b >> 16); \ - unsigned _d = U16(b >> 0); \ - const uint16 *_k = (k); \ - \ - ROUND(_k, _a, _b, _c, _d); \ - ROUND(_k, _a, _c, _b, _d); \ - ROUND(_k, _a, _b, _c, _d); \ - ROUND(_k, _a, _c, _b, _d); \ - ROUND(_k, _a, _b, _c, _d); \ - ROUND(_k, _a, _c, _b, _d); \ - ROUND(_k, _a, _b, _c, _d); \ - ROUND(_k, _a, _c, _b, _d); \ - MIX (_k, _a, _c, _b, _d); \ - c = ((uint32)U16(_a) << 16) | (uint32)U16(_c); \ - d = ((uint32)U16(_b) << 16) | (uint32)U16(_d); \ -} while (0) - -#define DBLK(k, a, b) EBLK((k), (a), (b)) - -/* --- @idea_eblk@, @idea_dblk@ --- * - * - * Arguments: @const idea_ctx *k@ = pointer to a key block - * @const uint32 s[2]@ = pointer to source block - * @uint32 d[2]@ = pointer to destination block - * - * Returns: --- - * - * Use: Low-level block encryption and decryption. - */ - -void idea_eblk(const idea_ctx *k, const uint32 *s, uint32 *d) -{ - EBLK(k->e, s[0], s[1], d[0], d[1]); -} - -void idea_dblk(const idea_ctx *k, const uint32 *s, uint32 *d) -{ - EBLK(k->d, s[0], s[1], d[0], d[1]); -} - -BLKC_TEST(IDEA, idea) - -/*----- That's all, folks -------------------------------------------------*/