]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
* Makefile.in (nettle_SOURCES): Added camellia.c and
authorNiels Möller <nisse@lysator.liu.se>
Wed, 7 Jul 2010 19:17:56 +0000 (21:17 +0200)
committerNiels Möller <nisse@lysator.liu.se>
Wed, 7 Jul 2010 19:17:56 +0000 (21:17 +0200)
camellia-meta.c.
(HEADERS): Added camellia.h.

* camellia-meta.c: New file.

* camellia.h: Rewrote interface to match nettle conventions.

* camellia.c: Converted to nettle conventions.
(camellia_encrypt128, camellia_encrypt256): Unified to new
function...
(camellia_encrypt): ...New function, with a loop doing 6
regular rounds, one FL round and one FLINV round per iteration,
with iteration count depending on the key size.

Rev: nettle/ChangeLog:1.89
Rev: nettle/Makefile.in:1.25
Rev: nettle/camellia-meta.c:1.1
Rev: nettle/camellia.c:1.2
Rev: nettle/camellia.h:1.2

ChangeLog
Makefile.in
camellia-meta.c [new file with mode: 0644]
camellia.c
camellia.h

index e701f0f22dbad2e7c6360660e4604e5edb5e94df..565f7511e1c5c373019ae5853a2474c5fdf7def9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+2010-07-07  Niels Möller  <nisse@lysator.liu.se>
+
+       * Makefile.in (nettle_SOURCES): Added camellia.c and
+       camellia-meta.c.
+       (HEADERS): Added camellia.h.
+
+       * nettle-meta.h (nettle_camellia128): Declare.
+       (nettle_camellia192): Likewise.
+       (nettle_camellia256): Likewise.
+
+       * camellia-meta.c: New file.
+
+       * camellia.h: Rewrote interface to match nettle conventions.
+
+       * camellia.c: Converted to nettle conventions.
+       (camellia_encrypt128, camellia_encrypt256): Unified to new
+       function...
+       (camellia_encrypt): ...New function, with a loop doing 6
+       regular rounds, one FL round and one FLINV round per iteration,
+       with iteration count depending on the key size.
+
+       (camellia_decrypt128, camellia_decrypt256): Similarly unified
+       as...
+       (camellia_decrypt): ...New function, analogous to
+       camellia_encrypt.
+
+2010-07-06  Niels Möller  <nisse@lysator.liu.se>
+
+       * camellia.c, camellia.h: New files, copied from
+       http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/camellia-LGPL-1.2.0.tar.gz.
+
+       * testsuite/camellia-test.c: New file.
+
 2010-07-05  Niels Möller  <nisse@lysator.liu.se>
 
        * nettle.texinfo: Document new conventions for weak key and des
index 212e7de032b92989523ac9dc0a74cefc7d1fb8a2..837e8cbcf28e00e148ae97ed359d3832974b854e 100644 (file)
@@ -55,7 +55,7 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c \
                 arctwo.c arctwo-meta.c \
                 base16-encode.c base16-decode.c base16-meta.c \
                  base64-encode.c base64-decode.c base64-meta.c \
-                cast128.c cast128-meta.c \
+                camellia.c camellia-meta.c cast128.c cast128-meta.c \
                 blowfish.c \
                 cbc.c ctr.c \
                 des.c \
@@ -97,7 +97,7 @@ hogweed_SOURCES = sexp.c sexp-format.c \
                  der-iterator.c der2rsa.c der2dsa.c
 
 HEADERS = aes.h arcfour.h arctwo.h asn1.h bignum.h blowfish.h \
-         base16.h base64.h buffer.h cast128.h \
+         base16.h base64.h buffer.h camellia.h cast128.h \
          cbc.h ctr.h \
          des.h des-compat.h dsa.h \
          hmac.h \
diff --git a/camellia-meta.c b/camellia-meta.c
new file mode 100644 (file)
index 0000000..0311af3
--- /dev/null
@@ -0,0 +1,38 @@
+/* camellia-meta.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2010 Niels Möller
+ *  
+ * The nettle library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ * 
+ * The nettle library 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 Lesser General Public
+ * License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the nettle library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "nettle-meta.h"
+
+#include "camellia.h"
+
+const struct nettle_cipher nettle_camellia128
+= _NETTLE_CIPHER(camellia, CAMELLIA, 128);
+
+const struct nettle_cipher nettle_camellia192
+= _NETTLE_CIPHER(camellia, CAMELLIA, 192);
+
+const struct nettle_cipher nettle_camellia256
+= _NETTLE_CIPHER(camellia, CAMELLIA, 256);
index 79cd49b7cd6d7d9c56adc4aee4fc96e492dfad3d..d62d2268da71a2480782af8b46b1bedbf274465d 100644 (file)
@@ -3,6 +3,8 @@
  * Copyright (C) 2006,2007
  * NTT (Nippon Telegraph and Telephone Corporation).
  *
+ * Copyright (C) 2010 Niels Möller
+ *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  *  http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
  */
 
-#include <string.h>
-#include <stdlib.h>
+/* Based on camellia.c ver 1.2.0, see
+   http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/camellia-LGPL-1.2.0.tar.gz.
+ */
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
 
 #include "camellia.h"
 
-/* u32 must be 32bit word */
-typedef unsigned int u32;
-typedef unsigned char u8;
+#include "macros.h"
 
 /* key constants */
 
@@ -52,30 +58,8 @@ typedef unsigned char u8;
  */
 
 
-#if defined(_MSC_VER)
-
-# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
-# define GETU32(p) SWAP(*((u32 *)(p)))
-# define PUTU32(ct, st) {*((u32 *)(ct)) = SWAP((st));}
-
-#else /* not MS-VC */
-
-# define GETU32(pt)                            \
-    (((u32)(pt)[0] << 24)                      \
-     ^ ((u32)(pt)[1] << 16)                    \
-     ^ ((u32)(pt)[2] <<  8)                    \
-     ^ ((u32)(pt)[3]))
-
-# define PUTU32(ct, st)  {                     \
-       (ct)[0] = (u8)((st) >> 24);             \
-       (ct)[1] = (u8)((st) >> 16);             \
-       (ct)[2] = (u8)((st) >>  8);             \
-       (ct)[3] = (u8)(st); }
-
-#endif
-
-#define CamelliaSubkeyL(INDEX) (subkey[(INDEX)*2])
-#define CamelliaSubkeyR(INDEX) (subkey[(INDEX)*2 + 1])
+#define CamelliaSubkeyL(INDEX) ((ctx)->keys[(INDEX)][0])
+#define CamelliaSubkeyR(INDEX) ((ctx)->keys[(INDEX)][1])
 
 /* rotation right shift 1byte */
 #define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24))
@@ -151,25 +135,34 @@ typedef unsigned char u8;
 
 #define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1)       \
     do {                                                               \
-       ir = CAMELLIA_SP1110(xr & 0xff)                                 \
-           ^ CAMELLIA_SP0222((xr >> 24) & 0xff)                        \
-           ^ CAMELLIA_SP3033((xr >> 16) & 0xff)                        \
-           ^ CAMELLIA_SP4404((xr >> 8) & 0xff);                        \
-       il = CAMELLIA_SP1110((xl >> 24) & 0xff)                         \
-           ^ CAMELLIA_SP0222((xl >> 16) & 0xff)                        \
-           ^ CAMELLIA_SP3033((xl >> 8) & 0xff)                         \
-           ^ CAMELLIA_SP4404(xl & 0xff);                               \
+        ir = CAMELLIA_SP1110(xr & 0xff)                        /* t8 */        \
+           ^ CAMELLIA_SP0222((xr >> 24) & 0xff)        /* t5 */        \
+           ^ CAMELLIA_SP3033((xr >> 16) & 0xff)        /* t6 */        \
+           ^ CAMELLIA_SP4404((xr >> 8) & 0xff);        /* t7 */        \
+       /* ir == (t6^t7^t8),(t5^t7^t8),(t5^t6^t8),(t5^t6^t7) */         \
+       il = CAMELLIA_SP1110((xl >> 24) & 0xff)         /* t1 */        \
+           ^ CAMELLIA_SP0222((xl >> 16) & 0xff)        /* t2 */        \
+           ^ CAMELLIA_SP3033((xl >> 8) & 0xff)         /* t3 */        \
+           ^ CAMELLIA_SP4404(xl & 0xff);               /* t4 */        \
+       /* il == (t1^t3^t4),(t1^t2^t4),(t1^t2^t3),(t2^t3^t4) */         \
        il ^= kl;                                                       \
        ir ^= kr;                                                       \
        ir ^= il;                                                       \
+       /* ir == (t1^t3^t4^t6^t7^t8),(t1^t2^t4^t5^t7^t8),               \
+                (t1^t2^t3^t5^t6^t8),(t2^t3^t4^t5^t6^t7)                \
+             == y1,y2,y3,y4 */                                         \
        il = CAMELLIA_RR8(il);                                          \
+       /* il == (t2^t3^t4),(t1^t3^t4),(t1^t2^t4),(t1^t2^t3) */         \
        il ^= ir;                                                       \
+       /* il == (t1^t2^t6^t7^t8),(t2^t3^t5^t7^t8),                     \
+                (t3^t4^t5^t6^t8),(t1^t4^t5^t6^t7)                      \
+             == y5,y6,y7,y8 */                                         \
        yl ^= ir;                                                       \
        yr ^= il;                                                       \
     } while(0)
 
 
-static const u32 camellia_sp1110[256] = {
+static const uint32_t camellia_sp1110[256] = {
     0x70707000,0x82828200,0x2c2c2c00,0xececec00,
     0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500,
     0xe4e4e400,0x85858500,0x57575700,0x35353500,
@@ -236,7 +229,7 @@ static const u32 camellia_sp1110[256] = {
     0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00,
 };
 
-static const u32 camellia_sp0222[256] = {
+static const uint32_t camellia_sp0222[256] = {
     0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9,
     0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb,
     0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a,
@@ -303,7 +296,7 @@ static const u32 camellia_sp0222[256] = {
     0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d,
 };
 
-static const u32 camellia_sp3033[256] = {
+static const uint32_t camellia_sp3033[256] = {
     0x38003838,0x41004141,0x16001616,0x76007676,
     0xd900d9d9,0x93009393,0x60006060,0xf200f2f2,
     0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a,
@@ -370,7 +363,7 @@ static const u32 camellia_sp3033[256] = {
     0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f,
 };
 
-static const u32 camellia_sp4404[256] = {
+static const uint32_t camellia_sp4404[256] = {
     0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0,
     0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae,
     0x23230023,0x6b6b006b,0x45450045,0xa5a500a5,
@@ -441,24 +434,26 @@ static const u32 camellia_sp4404[256] = {
 /**
  * Stuff related to the Camellia key schedule
  */
-#define subl(x) subL[(x)]
-#define subr(x) subR[(x)]
+#define subl(x) sub[(x)][0]
+#define subr(x) sub[(x)][1]
 
-void camellia_setup128(const unsigned char *key, u32 *subkey)
+static void
+camellia_setup128(struct camellia_ctx *ctx, uint32_t *key)
 {
-    u32 kll, klr, krl, krr;
-    u32 il, ir, t0, t1, w0, w1;
-    u32 kw4l, kw4r, dw, tl, tr;
-    u32 subL[26];
-    u32 subR[26];
+    uint32_t kll, klr, krl, krr;
+    uint32_t il, ir, t0, t1, w0, w1;
+    uint32_t kw4l, kw4r, dw, tl, tr;
+
+    /* Subkeys according to the spec. */
+    uint32_t sub[26][2];
 
     /**
-     *  k == kll || klr || krl || krr (|| is concatination)
+     *  k == k0 || klr || krl || krr (|| is concatination)
      */
-    kll = GETU32(key     );
-    klr = GETU32(key +  4);
-    krl = GETU32(key +  8);
-    krr = GETU32(key + 12);
+    kll = key[0];
+    klr = key[1];
+    krl = key[2];
+    krr = key[3];
     /**
      * generate KL dependent subkeys
      */
@@ -655,28 +650,30 @@ void camellia_setup128(const unsigned char *key, u32 *subkey)
     return;
 }
 
-void camellia_setup256(const unsigned char *key, u32 *subkey)
+static void
+camellia_setup256(struct camellia_ctx *ctx, uint32_t *key)
 {
-    u32 kll,klr,krl,krr;           /* left half of key */
-    u32 krll,krlr,krrl,krrr;       /* right half of key */
-    u32 il, ir, t0, t1, w0, w1;    /* temporary variables */
-    u32 kw4l, kw4r, dw, tl, tr;
-    u32 subL[34];
-    u32 subR[34];
+    uint32_t kll,klr,krl,krr;           /* left half of key */
+    uint32_t krll,krlr,krrl,krrr;       /* right half of key */
+    uint32_t il, ir, t0, t1, w0, w1;    /* temporary variables */
+    uint32_t kw4l, kw4r, dw, tl, tr;
+
+    /* Subkeys according to the spec. */
+    uint32_t sub[34][2];
 
     /**
      *  key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
      *  (|| is concatination)
      */
 
-    kll  = GETU32(key     );
-    klr  = GETU32(key +  4);
-    krl  = GETU32(key +  8);
-    krr  = GETU32(key + 12);
-    krll = GETU32(key + 16);
-    krlr = GETU32(key + 20);
-    krrl = GETU32(key + 24);
-    krrr = GETU32(key + 28);
+    kll  = key[0];
+    klr  = key[1];
+    krl  = key[2];
+    krr  = key[3];
+    krll = key[4];
+    krlr = key[5];
+    krrl = key[6];
+    krrr = key[7];
 
     /* generate KL dependent subkeys */
     subl(0) = kll; subr(0) = klr;
@@ -941,521 +938,196 @@ void camellia_setup256(const unsigned char *key, u32 *subkey)
     return;
 }
 
-void camellia_setup192(const unsigned char *key, u32 *subkey)
-{
-    unsigned char kk[32];
-    u32 krll, krlr, krrl,krrr;
-
-    memcpy(kk, key, 24);
-    memcpy((unsigned char *)&krll, key+16,4);
-    memcpy((unsigned char *)&krlr, key+20,4);
-    krrl = ~krll;
-    krrr = ~krlr;
-    memcpy(kk+24, (unsigned char *)&krrl, 4);
-    memcpy(kk+28, (unsigned char *)&krrr, 4);
-    camellia_setup256(kk, subkey);
-    return;
-}
-
-
-/**
- * Stuff related to camellia encryption/decryption
- *
- * "io" must be 4byte aligned and big-endian data.
- */
-void camellia_encrypt128(const u32 *subkey, u32 *io)
-{
-    u32 il, ir, t0, t1;
-
-    /* pre whitening but absorb kw2*/
-    io[0] ^= CamelliaSubkeyL(0);
-    io[1] ^= CamelliaSubkeyR(0);
-    /* main iteration */
-
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(2),CamelliaSubkeyR(2),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(3),CamelliaSubkeyR(3),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(4),CamelliaSubkeyR(4),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(5),CamelliaSubkeyR(5),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(6),CamelliaSubkeyR(6),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(7),CamelliaSubkeyR(7),
-                    io[0],io[1],il,ir,t0,t1);
-
-    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-                CamelliaSubkeyL(8),CamelliaSubkeyR(8),
-                CamelliaSubkeyL(9),CamelliaSubkeyR(9),
-                t0,t1,il,ir);
-
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(10),CamelliaSubkeyR(10),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(11),CamelliaSubkeyR(11),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(12),CamelliaSubkeyR(12),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(13),CamelliaSubkeyR(13),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(14),CamelliaSubkeyR(14),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(15),CamelliaSubkeyR(15),
-                    io[0],io[1],il,ir,t0,t1);
-
-    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-                CamelliaSubkeyL(16),CamelliaSubkeyR(16),
-                CamelliaSubkeyL(17),CamelliaSubkeyR(17),
-                t0,t1,il,ir);
-
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(18),CamelliaSubkeyR(18),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(19),CamelliaSubkeyR(19),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(20),CamelliaSubkeyR(20),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(21),CamelliaSubkeyR(21),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(22),CamelliaSubkeyR(22),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(23),CamelliaSubkeyR(23),
-                    io[0],io[1],il,ir,t0,t1);
-
-    /* post whitening but kw4 */
-    io[2] ^= CamelliaSubkeyL(24);
-    io[3] ^= CamelliaSubkeyR(24);
-
-    t0 = io[0];
-    t1 = io[1];
-    io[0] = io[2];
-    io[1] = io[3];
-    io[2] = t0;
-    io[3] = t1;
-       
-    return;
-}
-
-void camellia_decrypt128(const u32 *subkey, u32 *io)
-{
-    u32 il,ir,t0,t1;               /* temporary valiables */
-    
-    /* pre whitening but absorb kw2*/
-    io[0] ^= CamelliaSubkeyL(24);
-    io[1] ^= CamelliaSubkeyR(24);
-
-    /* main iteration */
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(23),CamelliaSubkeyR(23),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(22),CamelliaSubkeyR(22),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(21),CamelliaSubkeyR(21),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(20),CamelliaSubkeyR(20),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(19),CamelliaSubkeyR(19),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(18),CamelliaSubkeyR(18),
-                    io[0],io[1],il,ir,t0,t1);
-
-    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-                CamelliaSubkeyL(17),CamelliaSubkeyR(17),
-                CamelliaSubkeyL(16),CamelliaSubkeyR(16),
-                t0,t1,il,ir);
-
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(15),CamelliaSubkeyR(15),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(14),CamelliaSubkeyR(14),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(13),CamelliaSubkeyR(13),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(12),CamelliaSubkeyR(12),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(11),CamelliaSubkeyR(11),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(10),CamelliaSubkeyR(10),
-                    io[0],io[1],il,ir,t0,t1);
-
-    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-                CamelliaSubkeyL(9),CamelliaSubkeyR(9),
-                CamelliaSubkeyL(8),CamelliaSubkeyR(8),
-                t0,t1,il,ir);
-
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(7),CamelliaSubkeyR(7),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(6),CamelliaSubkeyR(6),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(5),CamelliaSubkeyR(5),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(4),CamelliaSubkeyR(4),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(3),CamelliaSubkeyR(3),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(2),CamelliaSubkeyR(2),
-                    io[0],io[1],il,ir,t0,t1);
-
-    /* post whitening but kw4 */
-    io[2] ^= CamelliaSubkeyL(0);
-    io[3] ^= CamelliaSubkeyR(0);
-
-    t0 = io[0];
-    t1 = io[1];
-    io[0] = io[2];
-    io[1] = io[3];
-    io[2] = t0;
-    io[3] = t1;
-
-    return;
-}
-
-/**
- * stuff for 192 and 256bit encryption/decryption
- */
-void camellia_encrypt256(const u32 *subkey, u32 *io)
-{
-    u32 il,ir,t0,t1;           /* temporary valiables */
-
-    /* pre whitening but absorb kw2*/
-    io[0] ^= CamelliaSubkeyL(0);
-    io[1] ^= CamelliaSubkeyR(0);
-
-    /* main iteration */
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(2),CamelliaSubkeyR(2),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(3),CamelliaSubkeyR(3),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(4),CamelliaSubkeyR(4),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(5),CamelliaSubkeyR(5),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(6),CamelliaSubkeyR(6),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(7),CamelliaSubkeyR(7),
-                    io[0],io[1],il,ir,t0,t1);
-
-    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-                CamelliaSubkeyL(8),CamelliaSubkeyR(8),
-                CamelliaSubkeyL(9),CamelliaSubkeyR(9),
-                t0,t1,il,ir);
-
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(10),CamelliaSubkeyR(10),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(11),CamelliaSubkeyR(11),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(12),CamelliaSubkeyR(12),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(13),CamelliaSubkeyR(13),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(14),CamelliaSubkeyR(14),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(15),CamelliaSubkeyR(15),
-                    io[0],io[1],il,ir,t0,t1);
-
-    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-                CamelliaSubkeyL(16),CamelliaSubkeyR(16),
-                CamelliaSubkeyL(17),CamelliaSubkeyR(17),
-                t0,t1,il,ir);
-
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(18),CamelliaSubkeyR(18),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(19),CamelliaSubkeyR(19),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(20),CamelliaSubkeyR(20),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(21),CamelliaSubkeyR(21),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(22),CamelliaSubkeyR(22),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(23),CamelliaSubkeyR(23),
-                    io[0],io[1],il,ir,t0,t1);
-
-    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-                CamelliaSubkeyL(24),CamelliaSubkeyR(24),
-                CamelliaSubkeyL(25),CamelliaSubkeyR(25),
-                t0,t1,il,ir);
-
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(26),CamelliaSubkeyR(26),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(27),CamelliaSubkeyR(27),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(28),CamelliaSubkeyR(28),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(29),CamelliaSubkeyR(29),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(30),CamelliaSubkeyR(30),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(31),CamelliaSubkeyR(31),
-                    io[0],io[1],il,ir,t0,t1);
-
-    /* post whitening but kw4 */
-    io[2] ^= CamelliaSubkeyL(32);
-    io[3] ^= CamelliaSubkeyR(32);
-
-    t0 = io[0];
-    t1 = io[1];
-    io[0] = io[2];
-    io[1] = io[3];
-    io[2] = t0;
-    io[3] = t1;
-
-    return;
-}
-
-void camellia_decrypt256(const u32 *subkey, u32 *io)
+void
+camellia_set_key(struct camellia_ctx *ctx,
+                unsigned length, const uint8_t *key)
 {
-    u32 il,ir,t0,t1;           /* temporary valiables */
-
-    /* pre whitening but absorb kw2*/
-    io[0] ^= CamelliaSubkeyL(32);
-    io[1] ^= CamelliaSubkeyR(32);
-       
-    /* main iteration */
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(31),CamelliaSubkeyR(31),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(30),CamelliaSubkeyR(30),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(29),CamelliaSubkeyR(29),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(28),CamelliaSubkeyR(28),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(27),CamelliaSubkeyR(27),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(26),CamelliaSubkeyR(26),
-                    io[0],io[1],il,ir,t0,t1);
-
-    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-                CamelliaSubkeyL(25),CamelliaSubkeyR(25),
-                CamelliaSubkeyL(24),CamelliaSubkeyR(24),
-                t0,t1,il,ir);
-
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(23),CamelliaSubkeyR(23),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(22),CamelliaSubkeyR(22),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(21),CamelliaSubkeyR(21),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(20),CamelliaSubkeyR(20),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(19),CamelliaSubkeyR(19),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(18),CamelliaSubkeyR(18),
-                    io[0],io[1],il,ir,t0,t1);
-
-    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-                CamelliaSubkeyL(17),CamelliaSubkeyR(17),
-                CamelliaSubkeyL(16),CamelliaSubkeyR(16),
-                t0,t1,il,ir);
-
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(15),CamelliaSubkeyR(15),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(14),CamelliaSubkeyR(14),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(13),CamelliaSubkeyR(13),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(12),CamelliaSubkeyR(12),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(11),CamelliaSubkeyR(11),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(10),CamelliaSubkeyR(10),
-                    io[0],io[1],il,ir,t0,t1);
-
-    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-                CamelliaSubkeyL(9),CamelliaSubkeyR(9),
-                CamelliaSubkeyL(8),CamelliaSubkeyR(8),
-                t0,t1,il,ir);
-
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(7),CamelliaSubkeyR(7),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(6),CamelliaSubkeyR(6),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(5),CamelliaSubkeyR(5),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(4),CamelliaSubkeyR(4),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(3),CamelliaSubkeyR(3),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(2),CamelliaSubkeyR(2),
-                    io[0],io[1],il,ir,t0,t1);
-
-    /* post whitening but kw4 */
-    io[2] ^= CamelliaSubkeyL(0);
-    io[3] ^= CamelliaSubkeyR(0);
-
-    t0 = io[0];
-    t1 = io[1];
-    io[0] = io[2];
-    io[1] = io[3];
-    io[2] = t0;
-    io[3] = t1;
-
-    return;
-}
-
-/***
- *
- * API for compatibility
- */
-
-void Camellia_Ekeygen(const int keyBitLength, 
-                     const unsigned char *rawKey, 
-                     KEY_TABLE_TYPE keyTable)
-{
-    switch(keyBitLength) {
-    case 128:
-       camellia_setup128(rawKey, keyTable);
-       break;
-    case 192:
-       camellia_setup192(rawKey, keyTable);
-       break;
-    case 256:
-       camellia_setup256(rawKey, keyTable);
-       break;
-    default:
-       break;
+  uint32_t k[8];
+  k[0] = READ_UINT32(key);
+  k[1] = READ_UINT32(key +  4);
+  k[2] = READ_UINT32(key +  8);
+  k[3] = READ_UINT32(key + 12);
+  
+  if (length == 16)
+    {
+      ctx->camellia128 = 1;
+      camellia_setup128(ctx, k);
     }
-}
-
+  else
+    {
+      ctx->camellia128 = 0;
+      k[4] = READ_UINT32(key + 16);
+      k[5] = READ_UINT32(key + 20);
+
+      if (length == 24)
+       {
+         k[6] = ~k[4];
+         k[7] = ~k[5];
+       }
+      else
+       {
+         assert (length == 32);
+         k[6] = READ_UINT32(key + 24);
+         k[7] = READ_UINT32(key + 28);
+       }
+      camellia_setup256(ctx, k);
+    }
+}      
 
-void Camellia_EncryptBlock(const int keyBitLength, 
-                          const unsigned char *plaintext, 
-                          const KEY_TABLE_TYPE keyTable, 
-                          unsigned char *ciphertext)
+void
+camellia_encrypt(const struct camellia_ctx *ctx,
+                unsigned length, uint8_t *dst,
+                const uint8_t *src)
 {
-    u32 tmp[4];
-
-    tmp[0] = GETU32(plaintext);
-    tmp[1] = GETU32(plaintext + 4);
-    tmp[2] = GETU32(plaintext + 8);
-    tmp[3] = GETU32(plaintext + 12);
-
-    switch (keyBitLength) {
-    case 128:
-       camellia_encrypt128(keyTable, tmp);
-       break;
-    case 192:
-       /* fall through */
-    case 256:
-       camellia_encrypt256(keyTable, tmp);
-       break;
-    default:
-       break;
+  FOR_BLOCKS(length, dst, src, CAMELLIA_BLOCK_SIZE)
+    {
+      uint32_t i0,i1,i2,i3;
+      uint32_t il,ir,t0,t1;
+      unsigned i;
+
+      i0 = READ_UINT32(src);
+      i1 = READ_UINT32(src +  4);
+      i2 = READ_UINT32(src +  8);
+      i3 = READ_UINT32(src + 12);
+      
+      /* pre whitening but absorb kw2*/
+      i0 ^= CamelliaSubkeyL(0);
+      i1 ^= CamelliaSubkeyR(0);
+
+      /* main iteration */
+
+      CAMELLIA_ROUNDSM(i0,i1,
+                      CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+                      i2,i3,il,ir,t0,t1);
+      CAMELLIA_ROUNDSM(i2,i3,
+                      CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+                      i0,i1,il,ir,t0,t1);
+      CAMELLIA_ROUNDSM(i0,i1,
+                      CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+                      i2,i3,il,ir,t0,t1);
+      CAMELLIA_ROUNDSM(i2,i3,
+                      CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+                      i0,i1,il,ir,t0,t1);
+      CAMELLIA_ROUNDSM(i0,i1,
+                      CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+                      i2,i3,il,ir,t0,t1);
+      CAMELLIA_ROUNDSM(i2,i3,
+                      CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+                      i0,i1,il,ir,t0,t1);
+
+      for (i = 0; i < 16 + 8 * !ctx->camellia128; i+= 8)
+       {
+         CAMELLIA_FLS(i0,i1,i2,i3,
+                      CamelliaSubkeyL(i+8),CamelliaSubkeyR(i+8),
+                      CamelliaSubkeyL(i+9),CamelliaSubkeyR(i+9),
+                      t0,t1,il,ir);
+
+         CAMELLIA_ROUNDSM(i0,i1,
+                          CamelliaSubkeyL(i+10),CamelliaSubkeyR(i+10),
+                          i2,i3,il,ir,t0,t1);
+         CAMELLIA_ROUNDSM(i2,i3,
+                          CamelliaSubkeyL(i+11),CamelliaSubkeyR(i+11),
+                          i0,i1,il,ir,t0,t1);
+         CAMELLIA_ROUNDSM(i0,i1,
+                          CamelliaSubkeyL(i+12),CamelliaSubkeyR(i+12),
+                          i2,i3,il,ir,t0,t1);
+         CAMELLIA_ROUNDSM(i2,i3,
+                          CamelliaSubkeyL(i+13),CamelliaSubkeyR(i+13),
+                          i0,i1,il,ir,t0,t1);
+         CAMELLIA_ROUNDSM(i0,i1,
+                          CamelliaSubkeyL(i+14),CamelliaSubkeyR(i+14),
+                          i2,i3,il,ir,t0,t1);
+         CAMELLIA_ROUNDSM(i2,i3,
+                          CamelliaSubkeyL(i+15),CamelliaSubkeyR(i+15),
+                          i0,i1,il,ir,t0,t1);
+       }
+
+      /* post whitening but kw4 */
+      i2 ^= CamelliaSubkeyL(i+8);
+      i3 ^= CamelliaSubkeyR(i+8);
+
+      WRITE_UINT32(dst     , i2);
+      WRITE_UINT32(dst +  4, i3);
+      WRITE_UINT32(dst +  8, i0);
+      WRITE_UINT32(dst + 12, i1);
     }
-
-    PUTU32(ciphertext, tmp[0]);
-    PUTU32(ciphertext + 4, tmp[1]);
-    PUTU32(ciphertext + 8, tmp[2]);
-    PUTU32(ciphertext + 12, tmp[3]);
 }
 
-void Camellia_DecryptBlock(const int keyBitLength, 
-                          const unsigned char *ciphertext, 
-                          const KEY_TABLE_TYPE keyTable, 
-                          unsigned char *plaintext)
+void
+camellia_decrypt(const struct camellia_ctx *ctx,
+                unsigned length, uint8_t *dst,
+                const uint8_t *src)
 {
-    u32 tmp[4];
-
-    tmp[0] = GETU32(ciphertext);
-    tmp[1] = GETU32(ciphertext + 4);
-    tmp[2] = GETU32(ciphertext + 8);
-    tmp[3] = GETU32(ciphertext + 12);
-
-    switch (keyBitLength) {
-    case 128:
-       camellia_decrypt128(keyTable, tmp);
-       break;
-    case 192:
-       /* fall through */
-    case 256:
-       camellia_decrypt256(keyTable, tmp);
-       break;
-    default:
-       break;
+  FOR_BLOCKS(length, dst, src, CAMELLIA_BLOCK_SIZE)
+    {
+      uint32_t i0,i1,i2,i3;
+      uint32_t il,ir,t0,t1;
+      unsigned i;
+
+      i0 = READ_UINT32(src);
+      i1 = READ_UINT32(src +  4);
+      i2 = READ_UINT32(src +  8);
+      i3 = READ_UINT32(src + 12);
+      
+      i = ctx->camellia128 ? 24 : 32;
+
+      /* pre whitening but absorb kw2*/
+      i0 ^= CamelliaSubkeyL(i);
+      i1 ^= CamelliaSubkeyR(i);
+      /* main iteration */
+
+      for (i -= 8; i >= 8; i -= 8)
+       {         
+         CAMELLIA_ROUNDSM(i0,i1,
+                          CamelliaSubkeyL(i+7),CamelliaSubkeyR(i+7),
+                          i2,i3,il,ir,t0,t1);
+         CAMELLIA_ROUNDSM(i2,i3,
+                          CamelliaSubkeyL(i+6),CamelliaSubkeyR(i+6),
+                          i0,i1,il,ir,t0,t1);
+         CAMELLIA_ROUNDSM(i0,i1,
+                          CamelliaSubkeyL(i+5),CamelliaSubkeyR(i+5),
+                          i2,i3,il,ir,t0,t1);
+         CAMELLIA_ROUNDSM(i2,i3,
+                          CamelliaSubkeyL(i+4),CamelliaSubkeyR(i+4),
+                          i0,i1,il,ir,t0,t1);
+         CAMELLIA_ROUNDSM(i0,i1,
+                          CamelliaSubkeyL(i+3),CamelliaSubkeyR(i+3),
+                          i2,i3,il,ir,t0,t1);
+         CAMELLIA_ROUNDSM(i2,i3,
+                          CamelliaSubkeyL(i+2),CamelliaSubkeyR(i+2),
+                          i0,i1,il,ir,t0,t1);
+
+         CAMELLIA_FLS(i0,i1,i2,i3,
+                      CamelliaSubkeyL(i+1),CamelliaSubkeyR(i+1),
+                      CamelliaSubkeyL(i),CamelliaSubkeyR(i),
+                      t0,t1,il,ir);
+       }
+      CAMELLIA_ROUNDSM(i0,i1,
+                      CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+                      i2,i3,il,ir,t0,t1);
+      CAMELLIA_ROUNDSM(i2,i3,
+                      CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+                      i0,i1,il,ir,t0,t1);
+      CAMELLIA_ROUNDSM(i0,i1,
+                      CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+                      i2,i3,il,ir,t0,t1);
+      CAMELLIA_ROUNDSM(i2,i3,
+                      CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+                      i0,i1,il,ir,t0,t1);
+      CAMELLIA_ROUNDSM(i0,i1,
+                      CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+                      i2,i3,il,ir,t0,t1);
+      CAMELLIA_ROUNDSM(i2,i3,
+                      CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+                      i0,i1,il,ir,t0,t1);
+
+      /* post whitening but kw4 */
+      i2 ^= CamelliaSubkeyL(0);
+      i3 ^= CamelliaSubkeyR(0);
+
+      WRITE_UINT32(dst     , i2);
+      WRITE_UINT32(dst +  4, i3);
+      WRITE_UINT32(dst +  8, i0);
+      WRITE_UINT32(dst + 12, i1);
     }
-    PUTU32(plaintext, tmp[0]);
-    PUTU32(plaintext + 4, tmp[1]);
-    PUTU32(plaintext + 8, tmp[2]);
-    PUTU32(plaintext + 12, tmp[3]);
 }
index 1ac16606106ce3dd0a2762c17110609ee6a5bd07..9f9ccc2e0f2c5bcdd0bb6e87710d0e8649746233 100644 (file)
@@ -1,8 +1,10 @@
-/* camellia.h  ver 1.2.0
+/* camellia.h
  *
  * Copyright (C) 2006,2007
  * NTT (Nippon Telegraph and Telephone Corporation).
  *
+ * Copyright (C) 2010 Niels Möller
+ *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#ifndef HEADER_CAMELLIA_H
-#define HEADER_CAMELLIA_H
+#ifndef NETTLE_CAMELLIA_H_INCLUDED
+#define NETTLE_CAMELLIA_H_INCLUDED
 
-#ifdef  __cplusplus
+#include "nettle-types.h"
+
+#ifdef __cplusplus
 extern "C" {
 #endif
 
+/* Name mangling */
+#define camellia_set_key nettle_camellia_set_key
+#define camellia_encrypt nettle_camellia_encrypt
+#define camellia_decrypt nettle_camellia_decrypt
+
 #define CAMELLIA_BLOCK_SIZE 16
-#define CAMELLIA_TABLE_BYTE_LEN 272
-#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4)
+/* Valid key sizes are 128, 192 or 256 bits (16, 24 or 32 bytes) */
+#define CAMELLIA_MIN_KEY_SIZE 16
+#define CAMELLIA_MAX_KEY_SIZE 32
+#define CAMELLIA_KEY_SIZE 32
 
-typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN];
+struct camellia_ctx
+{
+  int camellia128;
 
+  /* For 128-bit keys, there are 18 regular rounds, pre- and
+     post-whitening, and two FL and FLINV rounds, using a total of 26
+     subkeys, each of 64 bit. For 192- and 256-bit keys, there are 6
+     additional regular rounds and one additional FL and FLINV, using
+     a total of 34 subkeys. */
+  /* The clever combination of subkeys imply one of the pre- and
+     post-whitening keys is folded fith the round keys, so that subkey
+     subkey #1 and the last one (#25 or #33) is not used. FIXME:
+     Renumber to eliminate them. */
+  /* FIXME: For 64-bit machines, don't split in 32-bit halves. */
+  uint32_t keys[34][2];
+};
 
-void Camellia_Ekeygen(const int keyBitLength,
-                     const unsigned char *rawKey, 
-                     KEY_TABLE_TYPE keyTable);
+void
+camellia_set_key(struct camellia_ctx *ctx,
+                unsigned length, const uint8_t *key);
 
-void Camellia_EncryptBlock(const int keyBitLength,
-                          const unsigned char *plaintext, 
-                          const KEY_TABLE_TYPE keyTable, 
-                          unsigned char *cipherText);
+void
+camellia_encrypt(const struct camellia_ctx *ctx,
+                unsigned length, uint8_t *dst,
+                const uint8_t *src);
+void
+camellia_decrypt(const struct camellia_ctx *ctx,
+                unsigned length, uint8_t *dst,
+                const uint8_t *src);
 
-void Camellia_DecryptBlock(const int keyBitLength, 
-                          const unsigned char *cipherText, 
-                          const KEY_TABLE_TYPE keyTable, 
-                          unsigned char *plaintext);
+#if 0
+/* FIXME: Use a single crypt function, and let key setup for
+   decryption reverse the order of the subkeys. */
 
+void
+camellia_set_encrypt_key(struct camellia_ctx *ctx,
+                        unsigned length, const uint8_t *key);
 
+void
+camellia_set_decrypt_key(struct camellia_ctx *ctx,
+                        unsigned length, const uint8_t *key);
+
+void
+camellia_crypt(struct camellia_ctx *ctx,
+              unsigned length, uint8_t *dst,
+              const uint8_t *src);
+
+void
+camellia_invert_key(struct camellia_ctx *dst,
+                   const struct camellia_ctx *src);
+
+#endif
 #ifdef  __cplusplus
 }
 #endif
 
-#endif /* HEADER_CAMELLIA_H */
+#endif /* NETTLE_CAMELLIA_H_INCLUDED */