summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiels Möller <nisse@lysator.liu.se>2014-01-21 14:24:59 +0100
committerNiels Möller <nisse@lysator.liu.se>2014-01-21 14:24:59 +0100
commit38597d4e07b8b8bc3ca621652852198b90b1e911 (patch)
tree71b502dc962ce4b5dd4d4bdf113d4bdd0c933e91
parentdca9abf1c41fb1c0b51c75ca8decac4b27c26671 (diff)
parent982775563f27b0fa2b92f8d4df1a950f001949a2 (diff)
downloadnettle-38597d4e07b8b8bc3ca621652852198b90b1e911.tar.gz
Merge branch 'camellia-reorg' into master.
-rw-r--r--ChangeLog57
-rw-r--r--Makefile.in12
-rw-r--r--camellia-absorb.c135
-rw-r--r--camellia-crypt-internal.c37
-rw-r--r--camellia-internal.h57
-rw-r--r--camellia-invert-key.c (renamed from camellia-meta.c)30
-rw-r--r--camellia-set-encrypt-key.c336
-rw-r--r--camellia.h111
-rw-r--r--camellia128-crypt.c (renamed from camellia-crypt.c)13
-rw-r--r--camellia128-meta.c54
-rw-r--r--camellia128-set-decrypt-key.c45
-rw-r--r--camellia128-set-encrypt-key.c113
-rw-r--r--camellia192-meta.c54
-rw-r--r--camellia256-crypt.c46
-rw-r--r--camellia256-meta.c54
-rw-r--r--camellia256-set-decrypt-key.c (renamed from camellia-set-decrypt-key.c)42
-rw-r--r--camellia256-set-encrypt-key.c157
-rw-r--r--config.m4.in1
-rw-r--r--configure.ac4
-rw-r--r--testsuite/camellia-test.c55
-rw-r--r--x86/camellia-crypt-internal.asm26
-rw-r--r--x86_64/camellia-crypt-internal.asm30
22 files changed, 991 insertions, 478 deletions
diff --git a/ChangeLog b/ChangeLog
index 5c9ac8ae..7a038811 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,60 @@
+2014-01-21 Niels Möller <nisse@lysator.liu.se>
+
+ Merged camellia-reorg changes (starting at 2013-10-07).
+
+2013-10-10 Niels Möller <nisse@lysator.liu.se>
+
+ * Makefile.in (nettle_SOURCES): Updated list of camellia files.
+
+ * testsuite/camellia-test.c (test_invert): Updated for new
+ camellia interface.
+
+ * camellia.h: Reorganized camellia interface, with distinct
+ context structs and functions for camellia128 and camellia256.
+
+ * camellia-meta.c: Deleted file.
+ * camellia256-meta.c: New file.
+ * camellia192-meta.c: New file.
+ * camellia128-meta.c: New file.
+
+ * camellia-set-decrypt-key.c: Deleted file, code moved to:
+ * camellia128-set-decrypt-key.c: New file.
+ (camellia128_invert_key, camellia128_set_decrypt_key): New
+ functions.
+ * camellia256-set-decrypt-key.c: New file.
+ (camellia256_invert_key, camellia256_set_decrypt_key)
+ (camellia192_set_decrypt_key): New functions.
+ * camellia-invert-key.c (_camellia_invert_key): New file and
+ function.
+
+ * camellia-set-encrypt-key.c: Deleted file, code moved to:
+ * camellia128-set-encrypt-key.c: New file.
+ (camellia128_set_encrypt_key): New function.
+ * camellia256-set-encrypt-key.c: New file.
+ (_camellia256_set_encrypt_key, camellia256_set_encrypt_key)
+ (camellia192_set_encrypt_key): New functions.
+ * camellia-absorb.c (_camellia_absorb): New file and function.
+ * camellia-internal.h: Moved key schedule macros here.
+
+ * camellia-crypt.c: Deleted file, code moved to:
+ * camellia128-crypt.c (camellia128_crypt): New file and function.
+ * camellia256-crypt.c (camellia256_crypt): New file and function.
+
+2013-10-07 Niels Möller <nisse@lysator.liu.se>
+
+ * configure.ac: Delete check for ALIGNOF_UINT64_T, no longer
+ needed.
+ * config.m4.in: Likewise delete ALIGNOF_UINT64_T.
+
+ * camellia-crypt.c (camellia_crypt): Updated call to
+ _camellia_crypt.
+ * camellia-internal.h (_camellia_crypt): Updated prototype.
+ * camellia-crypt-internal.c (_camellia_crypt): Take separate
+ arguments for rounds and subkey array.
+ * x86_64/camellia-crypt-internal.asm: Likewise. Also corrected
+ .file pseudo-ops.
+ * x86/camellia-crypt-internal.asm: Likewise.
+
2014-01-20 Niels Möller <nisse@lysator.liu.se>
* poly1305-internal.c (poly1305_digest): Use union nettle_block16
diff --git a/Makefile.in b/Makefile.in
index 6a3d58d9..878d6216 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -76,9 +76,15 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c \
arctwo.c arctwo-meta.c gosthash94-meta.c \
base16-encode.c base16-decode.c base16-meta.c \
base64-encode.c base64-decode.c base64-meta.c \
- camellia-crypt.c camellia-crypt-internal.c \
- camellia-set-encrypt-key.c camellia-set-decrypt-key.c \
- camellia-table.c camellia-meta.c \
+ camellia-crypt-internal.c camellia-table.c \
+ camellia-absorb.c camellia-invert-key.c \
+ camellia128-set-encrypt-key.c camellia128-crypt.c \
+ camellia128-set-decrypt-key.c \
+ camellia128-meta.c \
+ camellia192-meta.c \
+ camellia256-set-encrypt-key.c camellia256-crypt.c \
+ camellia256-set-decrypt-key.c \
+ camellia256-meta.c \
cast128.c cast128-meta.c \
blowfish.c \
cbc.c ctr.c gcm.c gcm-aes.c \
diff --git a/camellia-absorb.c b/camellia-absorb.c
new file mode 100644
index 00000000..0d5cb769
--- /dev/null
+++ b/camellia-absorb.c
@@ -0,0 +1,135 @@
+/* camellia-absorb.c
+ *
+ * Final key setup processing for the camellia block cipher.
+ */
+/*
+ * 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This 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 this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * Algorithm Specification
+ * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
+ */
+
+/* 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 "camellia-internal.h"
+
+#include "macros.h"
+
+void
+_camellia_absorb(unsigned nkeys, uint64_t *dst, uint64_t *subkey)
+{
+ uint64_t kw2, kw4;
+ uint32_t dw, tl, tr;
+ unsigned i;
+
+ /* At this point, the subkey array contains the subkeys as described
+ in the spec, 26 for short keys and 34 for large keys. */
+
+ /* absorb kw2 to other subkeys */
+ kw2 = subkey[1];
+
+ subkey[3] ^= kw2;
+ subkey[5] ^= kw2;
+ subkey[7] ^= kw2;
+ for (i = 8; i < nkeys; i += 8)
+ {
+ /* FIXME: gcc for x86_32 is smart enough to fetch the 32 low bits
+ and xor the result into the 32 high bits, but it still generates
+ worse code than for explicit 32-bit operations. */
+ kw2 ^= (kw2 & ~subkey[i+1]) << 32;
+ dw = (kw2 & subkey[i+1]) >> 32; kw2 ^= ROTL32(1, dw);
+
+ subkey[i+3] ^= kw2;
+ subkey[i+5] ^= kw2;
+ subkey[i+7] ^= kw2;
+ }
+ subkey[i] ^= kw2;
+
+ /* absorb kw4 to other subkeys */
+ kw4 = subkey[nkeys + 1];
+
+ for (i = nkeys - 8; i > 0; i -= 8)
+ {
+ subkey[i+6] ^= kw4;
+ subkey[i+4] ^= kw4;
+ subkey[i+2] ^= kw4;
+ kw4 ^= (kw4 & ~subkey[i]) << 32;
+ dw = (kw4 & subkey[i]) >> 32; kw4 ^= ROTL32(1, dw);
+ }
+
+ subkey[6] ^= kw4;
+ subkey[4] ^= kw4;
+ subkey[2] ^= kw4;
+ subkey[0] ^= kw4;
+
+ /* key XOR is end of F-function */
+ dst[0] = subkey[0] ^ subkey[2];
+ dst[1] = subkey[3];
+
+ dst[2] = subkey[2] ^ subkey[4];
+ dst[3] = subkey[3] ^ subkey[5];
+ dst[4] = subkey[4] ^ subkey[6];
+ dst[5] = subkey[5] ^ subkey[7];
+
+ for (i = 8; i < nkeys; i += 8)
+ {
+ tl = (subkey[i+2] >> 32) ^ (subkey[i+2] & ~subkey[i]);
+ dw = tl & (subkey[i] >> 32);
+ tr = subkey[i+2] ^ ROTL32(1, dw);
+ dst[i-2] = subkey[i-2] ^ ( ((uint64_t) tl << 32) | tr);
+
+ dst[i-1] = subkey[i];
+ dst[i] = subkey[i+1];
+
+ tl = (subkey[i-1] >> 32) ^ (subkey[i-1] & ~subkey[i+1]);
+ dw = tl & (subkey[i+1] >> 32);
+ tr = subkey[i-1] ^ ROTL32(1, dw);
+ dst[i+1] = subkey[i+3] ^ ( ((uint64_t) tl << 32) | tr);
+
+ dst[i+2] = subkey[i+2] ^ subkey[i+4];
+ dst[i+3] = subkey[i+3] ^ subkey[i+5];
+ dst[i+4] = subkey[i+4] ^ subkey[i+6];
+ dst[i+5] = subkey[i+5] ^ subkey[i+7];
+ }
+ dst[i-2] = subkey[i-2];
+ dst[i-1] = subkey[i] ^ subkey[i-1];
+
+#if !HAVE_NATIVE_64_BIT
+ for (i = 0; i < nkeys; i += 8)
+ {
+ /* apply the inverse of the last half of F-function */
+ CAMELLIA_F_HALF_INV(dst[i+1]);
+ CAMELLIA_F_HALF_INV(dst[i+2]);
+ CAMELLIA_F_HALF_INV(dst[i+3]);
+ CAMELLIA_F_HALF_INV(dst[i+4]);
+ CAMELLIA_F_HALF_INV(dst[i+5]);
+ CAMELLIA_F_HALF_INV(dst[i+6]);
+ }
+#endif
+
+}
diff --git a/camellia-crypt-internal.c b/camellia-crypt-internal.c
index 69453235..2d4e85be 100644
--- a/camellia-crypt-internal.c
+++ b/camellia-crypt-internal.c
@@ -123,7 +123,8 @@
#endif
void
-_camellia_crypt(const struct camellia_ctx *ctx,
+_camellia_crypt(unsigned nkeys,
+ const uint64_t *keys,
const struct camellia_table *T,
size_t length, uint8_t *dst,
const uint8_t *src)
@@ -137,32 +138,32 @@ _camellia_crypt(const struct camellia_ctx *ctx,
i1 = READ_UINT64(src + 8);
/* pre whitening but absorb kw2*/
- i0 ^= ctx->keys[0];
+ i0 ^= keys[0];
/* main iteration */
- CAMELLIA_ROUNDSM(T, i0,ctx->keys[1], i1);
- CAMELLIA_ROUNDSM(T, i1,ctx->keys[2], i0);
- CAMELLIA_ROUNDSM(T, i0,ctx->keys[3], i1);
- CAMELLIA_ROUNDSM(T, i1,ctx->keys[4], i0);
- CAMELLIA_ROUNDSM(T, i0,ctx->keys[5], i1);
- CAMELLIA_ROUNDSM(T, i1,ctx->keys[6], i0);
+ CAMELLIA_ROUNDSM(T, i0, keys[1], i1);
+ CAMELLIA_ROUNDSM(T, i1, keys[2], i0);
+ CAMELLIA_ROUNDSM(T, i0, keys[3], i1);
+ CAMELLIA_ROUNDSM(T, i1, keys[4], i0);
+ CAMELLIA_ROUNDSM(T, i0, keys[5], i1);
+ CAMELLIA_ROUNDSM(T, i1, keys[6], i0);
- for (i = 0; i < ctx->nkeys - 8; i+= 8)
+ for (i = 0; i < nkeys - 8; i+= 8)
{
- CAMELLIA_FL(i0, ctx->keys[i+7]);
- CAMELLIA_FLINV(i1, ctx->keys[i+8]);
+ CAMELLIA_FL(i0, keys[i+7]);
+ CAMELLIA_FLINV(i1, keys[i+8]);
- CAMELLIA_ROUNDSM(T, i0,ctx->keys[i+9], i1);
- CAMELLIA_ROUNDSM(T, i1,ctx->keys[i+10], i0);
- CAMELLIA_ROUNDSM(T, i0,ctx->keys[i+11], i1);
- CAMELLIA_ROUNDSM(T, i1,ctx->keys[i+12], i0);
- CAMELLIA_ROUNDSM(T, i0,ctx->keys[i+13], i1);
- CAMELLIA_ROUNDSM(T, i1,ctx->keys[i+14], i0);
+ CAMELLIA_ROUNDSM(T, i0, keys[i+9], i1);
+ CAMELLIA_ROUNDSM(T, i1, keys[i+10], i0);
+ CAMELLIA_ROUNDSM(T, i0, keys[i+11], i1);
+ CAMELLIA_ROUNDSM(T, i1, keys[i+12], i0);
+ CAMELLIA_ROUNDSM(T, i0, keys[i+13], i1);
+ CAMELLIA_ROUNDSM(T, i1, keys[i+14], i0);
}
/* post whitening but kw4 */
- i1 ^= ctx->keys[i+7];
+ i1 ^= keys[i+7];
WRITE_UINT64(dst , i1);
WRITE_UINT64(dst + 8, i0);
diff --git a/camellia-internal.h b/camellia-internal.h
index ee41a447..824b6327 100644
--- a/camellia-internal.h
+++ b/camellia-internal.h
@@ -39,6 +39,8 @@
/* Name mangling */
#define _camellia_crypt _nettle_camellia_crypt
+#define _camellia_absorb _nettle_camellia_absorb
+#define _camellia_invert_key _nettle_camellia_invert_key
#define _camellia_table _nettle_camellia_table
/*
@@ -60,12 +62,65 @@ struct camellia_table
uint32_t sp4404[256];
};
+/* key constants */
+
+#define SIGMA1 0xA09E667F3BCC908BULL
+#define SIGMA2 0xB67AE8584CAA73B2ULL
+#define SIGMA3 0xC6EF372FE94F82BEULL
+#define SIGMA4 0x54FF53A5F1D36F1CULL
+#define SIGMA5 0x10E527FADE682D1DULL
+#define SIGMA6 0xB05688C2B3E6C1FDULL
+
+#define CAMELLIA_SP1110(INDEX) (_nettle_camellia_table.sp1110[(int)(INDEX)])
+#define CAMELLIA_SP0222(INDEX) (_nettle_camellia_table.sp0222[(int)(INDEX)])
+#define CAMELLIA_SP3033(INDEX) (_nettle_camellia_table.sp3033[(int)(INDEX)])
+#define CAMELLIA_SP4404(INDEX) (_nettle_camellia_table.sp4404[(int)(INDEX)])
+
+#define CAMELLIA_F(x, k, y) do { \
+ uint32_t __yl, __yr; \
+ uint64_t __i = (x) ^ (k); \
+ __yl \
+ = CAMELLIA_SP1110( __i & 0xff) \
+ ^ CAMELLIA_SP0222((__i >> 24) & 0xff) \
+ ^ CAMELLIA_SP3033((__i >> 16) & 0xff) \
+ ^ CAMELLIA_SP4404((__i >> 8) & 0xff); \
+ __yr \
+ = CAMELLIA_SP1110( __i >> 56) \
+ ^ CAMELLIA_SP0222((__i >> 48) & 0xff) \
+ ^ CAMELLIA_SP3033((__i >> 40) & 0xff) \
+ ^ CAMELLIA_SP4404((__i >> 32) & 0xff); \
+ __yl ^= __yr; \
+ __yr = ROTL32(24, __yr); \
+ __yr ^= __yl; \
+ (y) = ((uint64_t) __yl << 32) | __yr; \
+ } while (0)
+
+#if ! HAVE_NATIVE_64_BIT
+#define CAMELLIA_F_HALF_INV(x) do { \
+ uint32_t __t, __w; \
+ __t = (x) >> 32; \
+ __w = __t ^(x); \
+ __w = ROTL32(8, __w); \
+ (x) = ((uint64_t) __w << 32) | (__t ^ __w); \
+ } while (0)
+#endif
+
void
-_camellia_crypt(const struct camellia_ctx *ctx,
+_camellia_crypt(unsigned nkeys, const uint64_t *keys,
const struct camellia_table *T,
size_t length, uint8_t *dst,
const uint8_t *src);
+/* The initial NKEYS + 2 subkeys in SUBKEY are reduced to the final
+ NKEYS subkeys stored in DST. SUBKEY data is modified in the
+ process. */
+void
+_camellia_absorb(unsigned nkeys, uint64_t *dst, uint64_t *subkey);
+
+void
+_camellia_invert_key(unsigned nkeys,
+ uint64_t *dst, const uint64_t *src);
+
extern const struct camellia_table _camellia_table;
#endif /* NETTLE_CAMELLIA_INTERNAL_H_INCLUDED */
diff --git a/camellia-meta.c b/camellia-invert-key.c
index a8a8494b..b3b586fa 100644
--- a/camellia-meta.c
+++ b/camellia-invert-key.c
@@ -1,4 +1,7 @@
-/* camellia-meta.c */
+/* camellia-invert-key.c
+ *
+ * Inverting a key means reversing order of subkeys.
+ */
/* nettle, low-level cryptographics library
*
@@ -24,15 +27,20 @@
# include "config.h"
#endif
-#include "nettle-meta.h"
-
-#include "camellia.h"
-
-const struct nettle_cipher nettle_camellia128
-= _NETTLE_CIPHER_SEP_SET_KEY(camellia, CAMELLIA, 128);
+#include "camellia-internal.h"
-const struct nettle_cipher nettle_camellia192
-= _NETTLE_CIPHER_SEP_SET_KEY(camellia, CAMELLIA, 192);
+#define SWAP(a, b) \
+do { uint64_t t_swap = (a); (a) = (b); (b) = t_swap; } while(0)
-const struct nettle_cipher nettle_camellia256
-= _NETTLE_CIPHER_SEP_SET_KEY(camellia, CAMELLIA, 256);
+void
+_camellia_invert_key(unsigned nkeys,
+ uint64_t *dst, const uint64_t *src)
+{
+ unsigned i;
+ if (dst == src)
+ for (i = 0; i < nkeys - 1 - i; i++)
+ SWAP (dst[i], dst[nkeys - 1- i]);
+ else
+ for (i = 0; i < nkeys; i++)
+ dst[i] = src[nkeys - 1 - i];
+}
diff --git a/camellia-set-encrypt-key.c b/camellia-set-encrypt-key.c
deleted file mode 100644
index 7dd90775..00000000
--- a/camellia-set-encrypt-key.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/* camellia-set-encrypt-key.c
- *
- * Key setup for the camellia block cipher.
- */
-/*
- * 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
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This 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 this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * Algorithm Specification
- * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
- */
-
-/* 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 <limits.h>
-
-#include "camellia-internal.h"
-
-#include "macros.h"
-
-/* key constants */
-
-#define SIGMA1 0xA09E667F3BCC908BULL
-#define SIGMA2 0xB67AE8584CAA73B2ULL
-#define SIGMA3 0xC6EF372FE94F82BEULL
-#define SIGMA4 0x54FF53A5F1D36F1CULL
-#define SIGMA5 0x10E527FADE682D1DULL
-#define SIGMA6 0xB05688C2B3E6C1FDULL
-
-#define CAMELLIA_SP1110(INDEX) (_nettle_camellia_table.sp1110[(int)(INDEX)])
-#define CAMELLIA_SP0222(INDEX) (_nettle_camellia_table.sp0222[(int)(INDEX)])
-#define CAMELLIA_SP3033(INDEX) (_nettle_camellia_table.sp3033[(int)(INDEX)])
-#define CAMELLIA_SP4404(INDEX) (_nettle_camellia_table.sp4404[(int)(INDEX)])
-
-#define CAMELLIA_F(x, k, y) do { \
- uint32_t __yl, __yr; \
- uint64_t __i = (x) ^ (k); \
- __yl \
- = CAMELLIA_SP1110( __i & 0xff) \
- ^ CAMELLIA_SP0222((__i >> 24) & 0xff) \
- ^ CAMELLIA_SP3033((__i >> 16) & 0xff) \
- ^ CAMELLIA_SP4404((__i >> 8) & 0xff); \
- __yr \
- = CAMELLIA_SP1110( __i >> 56) \
- ^ CAMELLIA_SP0222((__i >> 48) & 0xff) \
- ^ CAMELLIA_SP3033((__i >> 40) & 0xff) \
- ^ CAMELLIA_SP4404((__i >> 32) & 0xff); \
- __yl ^= __yr; \
- __yr = ROTL32(24, __yr); \
- __yr ^= __yl; \
- (y) = ((uint64_t) __yl << 32) | __yr; \
- } while (0)
-
-#if ! HAVE_NATIVE_64_BIT
-#define CAMELLIA_F_HALF_INV(x) do { \
- uint32_t __t, __w; \
- __t = (x) >> 32; \
- __w = __t ^(x); \
- __w = ROTL32(8, __w); \
- (x) = ((uint64_t) __w << 32) | (__t ^ __w); \
- } while (0)
-#endif
-
-void
-camellia_set_encrypt_key(struct camellia_ctx *ctx,
- size_t length, const uint8_t *key)
-{
- uint64_t k0, k1;
-
- uint64_t subkey[34];
- uint64_t w, kw2, kw4;
-
- uint32_t dw, tl, tr;
- unsigned i;
-
- k0 = READ_UINT64(key);
- k1 = READ_UINT64(key + 8);
-
- if (length == 16)
- {
- ctx->nkeys = 24;
- /**
- * generate KL dependent subkeys
- */
- subkey[0] = k0; subkey[1] = k1;
- ROTL128(15, k0, k1);
- subkey[4] = k0; subkey[5] = k1;
- ROTL128(30, k0, k1);
- subkey[10] = k0; subkey[11] = k1;
- ROTL128(15, k0, k1);
- subkey[13] = k1;
- ROTL128(17, k0, k1);
- subkey[16] = k0; subkey[17] = k1;
- ROTL128(17, k0, k1);
- subkey[18] = k0; subkey[19] = k1;
- ROTL128(17, k0, k1);
- subkey[22] = k0; subkey[23] = k1;
-
- /* generate KA. D1 is k0, d2 is k1. */
- /* FIXME: Make notation match the spec better. */
- /* For the 128-bit case, KR = 0, the construction of KA reduces to:
-
- D1 = KL >> 64;
- W = KL & MASK64;
- D2 = F(D1, Sigma1);
- W = D2 ^ W
- D1 = F(W, Sigma2)
- D2 = D2 ^ F(D1, Sigma3);
- D1 = D1 ^ F(D2, Sigma4);
- KA = (D1 << 64) | D2;
- */
- k0 = subkey[0]; w = subkey[1];
- CAMELLIA_F(k0, SIGMA1, k1);
- w ^= k1;
- CAMELLIA_F(w, SIGMA2, k0);
- CAMELLIA_F(k0, SIGMA3, w);
- k1 ^= w;
- CAMELLIA_F(k1, SIGMA4, w);
- k0 ^= w;
-
- /* generate KA dependent subkeys */
- subkey[2] = k0; subkey[3] = k1;
- ROTL128(15, k0, k1);
- subkey[6] = k0; subkey[7] = k1;
- ROTL128(15, k0, k1);
- subkey[8] = k0; subkey[9] = k1;
- ROTL128(15, k0, k1);
- subkey[12] = k0;
- ROTL128(15, k0, k1);
- subkey[14] = k0; subkey[15] = k1;
- ROTL128(34, k0, k1);
- subkey[20] = k0; subkey[21] = k1;
- ROTL128(17, k0, k1);
- subkey[24] = k0; subkey[25] = k1;
- }
- else
- {
- uint64_t k2, k3;
-
- ctx->nkeys = 32;
- k2 = READ_UINT64(key + 16);
-
- if (length == 24)
- k3 = ~k2;
- else
- {
- assert (length == 32);
- k3 = READ_UINT64(key + 24);
- }
- /* generate KL dependent subkeys */
- subkey[0] = k0; subkey[1] = k1;
- ROTL128(45, k0, k1);
- subkey[12] = k0; subkey[13] = k1;
- ROTL128(15, k0, k1);
- subkey[16] = k0; subkey[17] = k1;
- ROTL128(17, k0, k1);
- subkey[22] = k0; subkey[23] = k1;
- ROTL128(34, k0, k1);
- subkey[30] = k0; subkey[31] = k1;
-
- /* generate KR dependent subkeys */
- ROTL128(15, k2, k3);
- subkey[4] = k2; subkey[5] = k3;
- ROTL128(15, k2, k3);
- subkey[8] = k2; subkey[9] = k3;
- ROTL128(30, k2, k3);
- subkey[18] = k2; subkey[19] = k3;
- ROTL128(34, k2, k3);
- subkey[26] = k2; subkey[27] = k3;
- ROTL128(34, k2, k3);
-
- /* generate KA */
- /* The construction of KA is done as
-
- D1 = (KL ^ KR) >> 64
- D2 = (KL ^ KR) & MASK64
- W = F(D1, SIGMA1)
- D2 = D2 ^ W
- D1 = F(D2, SIGMA2) ^ (KR >> 64)
- D2 = F(D1, SIGMA3) ^ W ^ (KR & MASK64)
- D1 = D1 ^ F(W, SIGMA2)
- D2 = D2 ^ F(D1, SIGMA3)
- D1 = D1 ^ F(D2, SIGMA4)
- */
-
- k0 = subkey[0] ^ k2;
- k1 = subkey[1] ^ k3;
-
- CAMELLIA_F(k0, SIGMA1, w);
- k1 ^= w;
-
- CAMELLIA_F(k1, SIGMA2, k0);
- k0 ^= k2;
-
- CAMELLIA_F(k0, SIGMA3, k1);
- k1 ^= w ^ k3;
-
- CAMELLIA_F(k1, SIGMA4, w);
- k0 ^= w;
-
- /* generate KB */
- k2 ^= k0; k3 ^= k1;
- CAMELLIA_F(k2, SIGMA5, w);
- k3 ^= w;
- CAMELLIA_F(k3, SIGMA6, w);
- k2 ^= w;
-
- /* generate KA dependent subkeys */
- ROTL128(15, k0, k1);
- subkey[6] = k0; subkey[7] = k1;
- ROTL128(30, k0, k1);
- subkey[14] = k0; subkey[15] = k1;
- ROTL128(32, k0, k1);
- subkey[24] = k0; subkey[25] = k1;
- ROTL128(17, k0, k1);
- subkey[28] = k0; subkey[29] = k1;
-
- /* generate KB dependent subkeys */
- subkey[2] = k2; subkey[3] = k3;
- ROTL128(30, k2, k3);
- subkey[10] = k2; subkey[11] = k3;
- ROTL128(30, k2, k3);
- subkey[20] = k2; subkey[21] = k3;
- ROTL128(51, k2, k3);
- subkey[32] = k2; subkey[33] = k3;
- }
-
- /* At this point, the subkey array contains the subkeys as described
- in the spec, 26 for short keys and 34 for large keys. */
-
- /* absorb kw2 to other subkeys */
- kw2 = subkey[1];
-
- subkey[3] ^= kw2;
- subkey[5] ^= kw2;
- subkey[7] ^= kw2;
- for (i = 8; i < ctx->nkeys; i += 8)
- {
- /* FIXME: gcc for x86_32 is smart enough to fetch the 32 low bits
- and xor the result into the 32 high bits, but it still generates
- worse code than for explicit 32-bit operations. */
- kw2 ^= (kw2 & ~subkey[i+1]) << 32;
- dw = (kw2 & subkey[i+1]) >> 32; kw2 ^= ROTL32(1, dw);
-
- subkey[i+3] ^= kw2;
- subkey[i+5] ^= kw2;
- subkey[i+7] ^= kw2;
- }
- subkey[i] ^= kw2;
-
- /* absorb kw4 to other subkeys */
- kw4 = subkey[ctx->nkeys + 1];
-
- for (i = ctx->nkeys - 8; i > 0; i -= 8)
- {
- subkey[i+6] ^= kw4;
- subkey[i+4] ^= kw4;
- subkey[i+2] ^= kw4;
- kw4 ^= (kw4 & ~subkey[i]) << 32;
- dw = (kw4 & subkey[i]) >> 32; kw4 ^= ROTL32(1, dw);
- }
-
- subkey[6] ^= kw4;
- subkey[4] ^= kw4;
- subkey[2] ^= kw4;
- subkey[0] ^= kw4;
-
- /* key XOR is end of F-function */
- ctx->keys[0] = subkey[0] ^ subkey[2];
- ctx->keys[1] = subkey[3];
-
- ctx->keys[2] = subkey[2] ^ subkey[4];
- ctx->keys[3] = subkey[3] ^ subkey[5];
- ctx->keys[4] = subkey[4] ^ subkey[6];
- ctx->keys[5] = subkey[5] ^ subkey[7];
-
- for (i = 8; i < ctx->nkeys; i += 8)
- {
- tl = (subkey[i+2] >> 32) ^ (subkey[i+2] & ~subkey[i]);
- dw = tl & (subkey[i] >> 32);
- tr = subkey[i+2] ^ ROTL32(1, dw);
- ctx->keys[i-2] = subkey[i-2] ^ ( ((uint64_t) tl << 32) | tr);
-
- ctx->keys[i-1] = subkey[i];
- ctx->keys[i] = subkey[i+1];
-
- tl = (subkey[i-1] >> 32) ^ (subkey[i-1] & ~subkey[i+1]);
- dw = tl & (subkey[i+1] >> 32);
- tr = subkey[i-1] ^ ROTL32(1, dw);
- ctx->keys[i+1] = subkey[i+3] ^ ( ((uint64_t) tl << 32) | tr);
-
- ctx->keys[i+2] = subkey[i+2] ^ subkey[i+4];
- ctx->keys[i+3] = subkey[i+3] ^ subkey[i+5];
- ctx->keys[i+4] = subkey[i+4] ^ subkey[i+6];
- ctx->keys[i+5] = subkey[i+5] ^ subkey[i+7];
- }
- ctx->keys[i-2] = subkey[i-2];
- ctx->keys[i-1] = subkey[i] ^ subkey[i-1];
-
-#if !HAVE_NATIVE_64_BIT
- for (i = 0; i < ctx->nkeys; i += 8)
- {
- /* apply the inverse of the last half of F-function */
- CAMELLIA_F_HALF_INV(ctx->keys[i+1]);
- CAMELLIA_F_HALF_INV(ctx->keys[i+2]);
- CAMELLIA_F_HALF_INV(ctx->keys[i+3]);
- CAMELLIA_F_HALF_INV(ctx->keys[i+4]);
- CAMELLIA_F_HALF_INV(ctx->keys[i+5]);
- CAMELLIA_F_HALF_INV(ctx->keys[i+6]);
- }
-#endif
-}
diff --git a/camellia.h b/camellia.h
index c0b45761..dcc43ae7 100644
--- a/camellia.h
+++ b/camellia.h
@@ -3,7 +3,7 @@
* Copyright (C) 2006,2007
* NTT (Nippon Telegraph and Telephone Corporation).
*
- * Copyright (C) 2010 Niels Möller
+ * Copyright (C) 2010, 2013 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
@@ -30,51 +30,100 @@ extern "C" {
#endif
/* Name mangling */
-#define camellia_set_encrypt_key nettle_camellia_set_encrypt_key
-#define camellia_set_decrypt_key nettle_camellia_set_decrypt_key
-#define camellia_invert_key nettle_camellia_invert_key
-#define camellia_crypt nettle_camellia_crypt
-#define camellia_crypt nettle_camellia_crypt
+#define camellia128_set_encrypt_key nettle_camellia128_set_encrypt_key
+#define camellia128_set_decrypt_key nettle_camellia_set_decrypt_key
+#define camellia128_invert_key nettle_camellia128_invert_key
+#define camellia128_crypt nettle_camellia128_crypt
+
+#define camellia192_set_encrypt_key nettle_camellia192_set_encrypt_key
+#define camellia192_set_decrypt_key nettle_camellia192_set_decrypt_key
+
+#define camellia256_set_encrypt_key nettle_camellia256_set_encrypt_key
+#define camellia256_set_decrypt_key nettle_camellia256_set_decrypt_key
+#define camellia256_invert_key nettle_camellia256_invert_key
+#define camellia256_crypt nettle_camellia256_crypt
+
#define CAMELLIA_BLOCK_SIZE 16
/* 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
+#define CAMELLIA128_KEY_SIZE 16
+#define CAMELLIA192_KEY_SIZE 24
+#define CAMELLIA256_KEY_SIZE 32
-struct camellia_ctx
+/* 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 with the round keys, so that subkey
+ #1 and the last one (#25 or #33) is not used. The result is that we
+ have only 24 or 32 subkeys at the end of key setup. */
+
+#define _CAMELLIA128_NKEYS 24
+#define _CAMELLIA256_NKEYS 32
+
+struct camellia128_ctx
{
- /* Number of subkeys. */
- unsigned nkeys;
+ uint64_t keys[_CAMELLIA128_NKEYS];
+};
+
+void
+camellia128_set_encrypt_key(struct camellia128_ctx *ctx,
+ const uint8_t *key);
+
+void
+camellia128_set_decrypt_key(struct camellia128_ctx *ctx,
+ const uint8_t *key);
+
+void
+camellia128_invert_key(struct camellia128_ctx *dst,
+ const struct camellia128_ctx *src);
- /* 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 with the round keys, so that subkey
- #1 and the last one (#25 or #33) is not used. The result is that
- we have only 24 or 32 subkeys at the end of key setup. */
- uint64_t keys[32];
+void
+camellia128_crypt(const struct camellia128_ctx *ctx,
+ size_t length, uint8_t *dst,
+ const uint8_t *src);
+
+struct camellia256_ctx
+{
+ uint64_t keys[_CAMELLIA256_NKEYS];
};
void
-camellia_set_encrypt_key(struct camellia_ctx *ctx,
- size_t length, const uint8_t *key);
+camellia256_set_encrypt_key(struct camellia256_ctx *ctx,
+ const uint8_t *key);
void
-camellia_set_decrypt_key(struct camellia_ctx *ctx,
- size_t length, const uint8_t *key);
+camellia256_set_decrypt_key(struct camellia256_ctx *ctx,
+ const uint8_t *key);
void
-camellia_invert_key(struct camellia_ctx *dst,
- const struct camellia_ctx *src);
+camellia256_invert_key(struct camellia256_ctx *dst,
+ const struct camellia256_ctx *src);
void
-camellia_crypt(const struct camellia_ctx *ctx,
- size_t length, uint8_t *dst,
- const uint8_t *src);
+camellia256_crypt(const struct camellia256_ctx *ctx,
+ size_t length, uint8_t *dst,
+ const uint8_t *src);
+
+/* camellia192 is the same as camellia256, except for the key
+ schedule. */
+/* Slightly ugly with a #define on a struct tag, since it might cause
+ surprises if also used as a name of a variable. */
+#define camellia192_ctx camellia256_ctx
+
+void
+camellia192_set_encrypt_key(struct camellia256_ctx *ctx,
+ const uint8_t *key);
+
+void
+camellia192_set_decrypt_key(struct camellia256_ctx *ctx,
+ const uint8_t *key);
+
+#define camellia192_invert_key camellia256_invert_key
+#define camellia192_crypt camellia256_crypt
+
#ifdef __cplusplus
}
#endif
diff --git a/camellia-crypt.c b/camellia128-crypt.c
index def5d845..b9f355e9 100644
--- a/camellia-crypt.c
+++ b/camellia128-crypt.c
@@ -1,11 +1,11 @@
-/* camellia-encrypt.c
+/* camellia128-crypt.c
*
* Crypt function for the camellia block cipher.
*/
/* nettle, low-level cryptographics library
*
- * Copyright (C) 2010 Niels Möller
+ * Copyright (C) 2010, 2013 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
@@ -35,11 +35,12 @@
implementations of _nettle_camellia_crypt to get the table pointer.
For PIC code, the details can be complex and system dependent. */
void
-camellia_crypt(const struct camellia_ctx *ctx,
- size_t length, uint8_t *dst,
- const uint8_t *src)
+camellia128_crypt(const struct camellia128_ctx *ctx,
+ size_t length, uint8_t *dst,
+ const uint8_t *src)
{
assert(!(length % CAMELLIA_BLOCK_SIZE) );
- _camellia_crypt(ctx, &_camellia_table,
+ _camellia_crypt(_CAMELLIA128_NKEYS, ctx->keys,
+ &_camellia_table,
length, dst, src);
}
diff --git a/camellia128-meta.c b/camellia128-meta.c
new file mode 100644
index 00000000..cac7b485
--- /dev/null
+++ b/camellia128-meta.c
@@ -0,0 +1,54 @@
+/* camellia128-meta.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2010, 2013 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02111-1301, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "nettle-meta.h"
+
+#include "camellia.h"
+
+static void
+camellia128_set_encrypt_key_wrapper (void *ctx, size_t length, const uint8_t *key)
+{
+ assert (length == CAMELLIA128_KEY_SIZE);
+ camellia128_set_encrypt_key (ctx, key);
+}
+
+static void
+camellia128_set_decrypt_key_wrapper (void *ctx, size_t length, const uint8_t *key)
+{
+ assert (length == CAMELLIA128_KEY_SIZE);
+ camellia128_set_decrypt_key (ctx, key);
+}
+
+const struct nettle_cipher nettle_camellia128 =
+ { "camellia128", sizeof(struct camellia128_ctx),
+ CAMELLIA_BLOCK_SIZE, CAMELLIA128_KEY_SIZE,
+ camellia128_set_encrypt_key_wrapper,
+ camellia128_set_decrypt_key_wrapper,
+ (nettle_crypt_func *) camellia128_crypt,
+ (nettle_crypt_func *) camellia128_crypt
+ };
diff --git a/camellia128-set-decrypt-key.c b/camellia128-set-decrypt-key.c
new file mode 100644
index 00000000..afd93751
--- /dev/null
+++ b/camellia128-set-decrypt-key.c
@@ -0,0 +1,45 @@
+/* camellia128-set-decrypt-key.c
+ *
+ * Inverse key setup for the camellia block cipher.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2010, 2013 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02111-1301, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "camellia-internal.h"
+
+void
+camellia128_invert_key(struct camellia128_ctx *dst,
+ const struct camellia128_ctx *src)
+{
+ _camellia_invert_key (_CAMELLIA128_NKEYS, dst->keys, src->keys);
+}
+
+void
+camellia128_set_decrypt_key(struct camellia128_ctx *ctx,
+ const uint8_t *key)
+{
+ camellia128_set_encrypt_key(ctx, key);
+ camellia128_invert_key(ctx, ctx);
+}
diff --git a/camellia128-set-encrypt-key.c b/camellia128-set-encrypt-key.c
new file mode 100644
index 00000000..715828b4
--- /dev/null
+++ b/camellia128-set-encrypt-key.c
@@ -0,0 +1,113 @@
+/* camellia128-set-encrypt-key.c
+ *
+ * Key setup for the camellia block cipher.
+ */
+/*
+ * Copyright (C) 2006,2007
+ * NTT (Nippon Telegraph and Telephone Corporation).
+ *
+ * Copyright (C) 2010, 2013 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This 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 this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * Algorithm Specification
+ * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
+ */
+
+/* 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 <limits.h>
+
+#include "camellia-internal.h"
+
+#include "macros.h"
+
+void
+camellia128_set_encrypt_key (struct camellia128_ctx *ctx,
+ const uint8_t *key)
+{
+ uint64_t k0, k1;
+
+ uint64_t subkey[_CAMELLIA128_NKEYS + 2];
+ uint64_t w;
+
+ k0 = READ_UINT64(key);
+ k1 = READ_UINT64(key + 8);
+
+ /**
+ * generate KL dependent subkeys
+ */
+ subkey[0] = k0; subkey[1] = k1;
+ ROTL128(15, k0, k1);
+ subkey[4] = k0; subkey[5] = k1;
+ ROTL128(30, k0, k1);
+ subkey[10] = k0; subkey[11] = k1;
+ ROTL128(15, k0, k1);
+ subkey[13] = k1;
+ ROTL128(17, k0, k1);
+ subkey[16] = k0; subkey[17] = k1;
+ ROTL128(17, k0, k1);
+ subkey[18] = k0; subkey[19] = k1;
+ ROTL128(17, k0, k1);
+ subkey[22] = k0; subkey[23] = k1;
+
+ /* generate KA. D1 is k0, d2 is k1. */
+ /* FIXME: Make notation match the spec better. */
+ /* For the 128-bit case, KR = 0, the construction of KA reduces to:
+
+ D1 = KL >> 64;
+ W = KL & MASK64;
+ D2 = F(D1, Sigma1);
+ W = D2 ^ W
+ D1 = F(W, Sigma2)
+ D2 = D2 ^ F(D1, Sigma3);
+ D1 = D1 ^ F(D2, Sigma4);
+ KA = (D1 << 64) | D2;
+ */
+ k0 = subkey[0]; w = subkey[1];
+ CAMELLIA_F(k0, SIGMA1, k1);
+ w ^= k1;
+ CAMELLIA_F(w, SIGMA2, k0);
+ CAMELLIA_F(k0, SIGMA3, w);
+ k1 ^= w;
+ CAMELLIA_F(k1, SIGMA4, w);
+ k0 ^= w;
+
+ /* generate KA dependent subkeys */
+ subkey[2] = k0; subkey[3] = k1;
+ ROTL128(15, k0, k1);
+ subkey[6] = k0; subkey[7] = k1;
+ ROTL128(15, k0, k1);
+ subkey[8] = k0; subkey[9] = k1;
+ ROTL128(15, k0, k1);
+ subkey[12] = k0;
+ ROTL128(15, k0, k1);
+ subkey[14] = k0; subkey[15] = k1;
+ ROTL128(34, k0, k1);
+ subkey[20] = k0; subkey[21] = k1;
+ ROTL128(17, k0, k1);
+ subkey[24] = k0; subkey[25] = k1;
+
+ /* Common final processing */
+ _camellia_absorb (_CAMELLIA128_NKEYS, ctx->keys, subkey);
+}
diff --git a/camellia192-meta.c b/camellia192-meta.c
new file mode 100644
index 00000000..bdb5c130
--- /dev/null
+++ b/camellia192-meta.c
@@ -0,0 +1,54 @@
+/* camellia192-meta.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2010, 2013 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02111-1301, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "nettle-meta.h"
+
+#include "camellia.h"
+
+static void
+camellia192_set_encrypt_key_wrapper (void *ctx, size_t length, const uint8_t *key)
+{
+ assert (length == CAMELLIA192_KEY_SIZE);
+ camellia192_set_encrypt_key (ctx, key);
+}
+
+static void
+camellia192_set_decrypt_key_wrapper (void *ctx, size_t length, const uint8_t *key)
+{
+ assert (length == CAMELLIA192_KEY_SIZE);
+ camellia192_set_decrypt_key (ctx, key);
+}
+
+const struct nettle_cipher nettle_camellia192 =
+ { "camellia192", sizeof(struct camellia256_ctx),
+ CAMELLIA_BLOCK_SIZE, CAMELLIA192_KEY_SIZE,
+ camellia192_set_encrypt_key_wrapper,
+ camellia192_set_decrypt_key_wrapper,
+ (nettle_crypt_func *) camellia256_crypt,
+ (nettle_crypt_func *) camellia256_crypt
+ };
diff --git a/camellia256-crypt.c b/camellia256-crypt.c
new file mode 100644
index 00000000..de6d4daf
--- /dev/null
+++ b/camellia256-crypt.c
@@ -0,0 +1,46 @@
+/* camellia256-crypt.c
+ *
+ * Crypt function for the camellia block cipher.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2010, 2013 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02111-1301, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "camellia-internal.h"
+
+/* The main point on this function is to help the assembler
+ implementations of _nettle_camellia_crypt to get the table pointer.
+ For PIC code, the details can be complex and system dependent. */
+void
+camellia256_crypt(const struct camellia256_ctx *ctx,
+ size_t length, uint8_t *dst,
+ const uint8_t *src)
+{
+ assert(!(length % CAMELLIA_BLOCK_SIZE) );
+ _camellia_crypt(_CAMELLIA256_NKEYS, ctx->keys,
+ &_camellia_table,
+ length, dst, src);
+}
diff --git a/camellia256-meta.c b/camellia256-meta.c
new file mode 100644
index 00000000..1a1e2a2d
--- /dev/null
+++ b/camellia256-meta.c
@@ -0,0 +1,54 @@
+/* camellia256-meta.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2010, 2013 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02111-1301, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "nettle-meta.h"
+
+#include "camellia.h"
+
+static void
+camellia256_set_encrypt_key_wrapper (void *ctx, size_t length, const uint8_t *key)
+{
+ assert (length == CAMELLIA256_KEY_SIZE);
+ camellia256_set_encrypt_key (ctx, key);
+}
+
+static void
+camellia256_set_decrypt_key_wrapper (void *ctx, size_t length, const uint8_t *key)
+{
+ assert (length == CAMELLIA256_KEY_SIZE);
+ camellia256_set_decrypt_key (ctx, key);
+}
+
+const struct nettle_cipher nettle_camellia256 =
+ { "camellia256", sizeof(struct camellia256_ctx),
+ CAMELLIA_BLOCK_SIZE, CAMELLIA256_KEY_SIZE,
+ camellia256_set_encrypt_key_wrapper,
+ camellia256_set_decrypt_key_wrapper,
+ (nettle_crypt_func *) camellia256_crypt,
+ (nettle_crypt_func *) camellia256_crypt
+ };
diff --git a/camellia-set-decrypt-key.c b/camellia256-set-decrypt-key.c
index 329fa3c9..134fc311 100644
--- a/camellia-set-decrypt-key.c
+++ b/camellia256-set-decrypt-key.c
@@ -1,11 +1,11 @@
-/* camellia-set-decrypt-key.c
+/* camellia256-set-decrypt-key.c
*
* Inverse key setup for the camellia block cipher.
*/
/* nettle, low-level cryptographics library
*
- * Copyright (C) 2010 Niels Möller
+ * Copyright (C) 2010, 2013 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
@@ -27,35 +27,27 @@
# include "config.h"
#endif
-#include "camellia.h"
-
-#define SWAP(a, b) \
-do { uint64_t t_swap = (a); (a) = (b); (b) = t_swap; } while(0)
+#include "camellia-internal.h"
void
-camellia_invert_key(struct camellia_ctx *dst,
- const struct camellia_ctx *src)
+camellia256_invert_key(struct camellia256_ctx *dst,
+ const struct camellia256_ctx *src)
{
- unsigned nkeys = src->nkeys;
- unsigned i;
- if (dst == src)
- {
- for (i = 0; i < nkeys - 1 - i; i++)
- SWAP(dst->keys[i], dst->keys[nkeys - 1 - i]);
- }
- else
- {
- dst->nkeys = nkeys;
+ _camellia_invert_key (_CAMELLIA256_NKEYS, dst->keys, src->keys);
+}
- for (i = 0; i < nkeys; i++)
- dst->keys[i] = src->keys[nkeys - 1 - i];
- }
+void
+camellia256_set_decrypt_key(struct camellia256_ctx *ctx,
+ const uint8_t *key)
+{
+ camellia256_set_encrypt_key(ctx, key);
+ camellia256_invert_key(ctx, ctx);
}
void
-camellia_set_decrypt_key(struct camellia_ctx *ctx,
- size_t length, const uint8_t *key)
+camellia192_set_decrypt_key(struct camellia256_ctx *ctx,
+ const uint8_t *key)
{
- camellia_set_encrypt_key(ctx, length, key);
- camellia_invert_key(ctx, ctx);
+ camellia192_set_encrypt_key(ctx, key);
+ camellia256_invert_key(ctx, ctx);
}
diff --git a/camellia256-set-encrypt-key.c b/camellia256-set-encrypt-key.c
new file mode 100644
index 00000000..189ff5d2
--- /dev/null
+++ b/camellia256-set-encrypt-key.c
@@ -0,0 +1,157 @@
+/* camellia256-set-encrypt-key.c
+ *
+ * Key setup for the camellia block cipher.
+ */
+/*
+ * Copyright (C) 2006,2007
+ * NTT (Nippon Telegraph and Telephone Corporation).
+ *
+ * Copyright (C) 2010, 2013 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
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This 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 this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * Algorithm Specification
+ * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
+ */
+
+/* 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 <limits.h>
+
+#include "camellia-internal.h"
+
+#include "macros.h"
+
+static void
+_camellia256_set_encrypt_key (struct camellia256_ctx *ctx,
+ uint64_t k0, uint64_t k1,
+ uint64_t k2, uint64_t k3)
+{
+ uint64_t subkey[_CAMELLIA256_NKEYS + 2];
+ uint64_t w;
+
+ /* generate KL dependent subkeys */
+ subkey[0] = k0; subkey[1] = k1;
+ ROTL128(45, k0, k1);
+ subkey[12] = k0; subkey[13] = k1;
+ ROTL128(15, k0, k1);
+ subkey[16] = k0; subkey[17] = k1;
+ ROTL128(17, k0, k1);
+ subkey[22] = k0; subkey[23] = k1;
+ ROTL128(34, k0, k1);
+ subkey[30] = k0; subkey[31] = k1;
+
+ /* generate KR dependent subkeys */
+ ROTL128(15, k2, k3);
+ subkey[4] = k2; subkey[5] = k3;
+ ROTL128(15, k2, k3);
+ subkey[8] = k2; subkey[9] = k3;
+ ROTL128(30, k2, k3);
+ subkey[18] = k2; subkey[19] = k3;
+ ROTL128(34, k2, k3);
+ subkey[26] = k2; subkey[27] = k3;
+ ROTL128(34, k2, k3);
+
+ /* generate KA */
+ /* The construction of KA is done as
+
+ D1 = (KL ^ KR) >> 64
+ D2 = (KL ^ KR) & MASK64
+ W = F(D1, SIGMA1)
+ D2 = D2 ^ W
+ D1 = F(D2, SIGMA2) ^ (KR >> 64)
+ D2 = F(D1, SIGMA3) ^ W ^ (KR & MASK64)
+ D1 = D1 ^ F(W, SIGMA2)
+ D2 = D2 ^ F(D1, SIGMA3)
+ D1 = D1 ^ F(D2, SIGMA4)
+ */
+
+ k0 = subkey[0] ^ k2;
+ k1 = subkey[1] ^ k3;
+
+ CAMELLIA_F(k0, SIGMA1, w);
+ k1 ^= w;
+
+ CAMELLIA_F(k1, SIGMA2, k0);
+ k0 ^= k2;
+
+ CAMELLIA_F(k0, SIGMA3, k1);
+ k1 ^= w ^ k3;
+
+ CAMELLIA_F(k1, SIGMA4, w);
+ k0 ^= w;
+
+ /* generate KB */
+ k2 ^= k0; k3 ^= k1;
+ CAMELLIA_F(k2, SIGMA5, w);
+ k3 ^= w;
+ CAMELLIA_F(k3, SIGMA6, w);
+ k2 ^= w;
+
+ /* generate KA dependent subkeys */
+ ROTL128(15, k0, k1);
+ subkey[6] = k0; subkey[7] = k1;
+ ROTL128(30, k0, k1);
+ subkey[14] = k0; subkey[15] = k1;
+ ROTL128(32, k0, k1);
+ subkey[24] = k0; subkey[25] = k1;
+ ROTL128(17, k0, k1);
+ subkey[28] = k0; subkey[29] = k1;
+
+ /* generate KB dependent subkeys */
+ subkey[2] = k2; subkey[3] = k3;
+ ROTL128(30, k2, k3);
+ subkey[10] = k2; subkey[11] = k3;
+ ROTL128(30, k2, k3);
+ subkey[20] = k2; subkey[21] = k3;
+ ROTL128(51, k2, k3);
+ subkey[32] = k2; subkey[33] = k3;
+
+ /* Common final processing */
+ _camellia_absorb (_CAMELLIA256_NKEYS, ctx->keys, subkey);
+}
+
+void
+camellia256_set_encrypt_key(struct camellia256_ctx *ctx,
+ const uint8_t *key)
+{
+ uint64_t k0, k1, k2, k3;
+ k0 = READ_UINT64(key);
+ k1 = READ_UINT64(key + 8);
+ k2 = READ_UINT64(key + 16);
+ k3 = READ_UINT64(key + 24);
+
+ _camellia256_set_encrypt_key (ctx, k0, k1, k2, k3);
+}
+
+void
+camellia192_set_encrypt_key(struct camellia256_ctx *ctx,
+ const uint8_t *key)
+{
+ uint64_t k0, k1, k2;
+ k0 = READ_UINT64(key);
+ k1 = READ_UINT64(key + 8);
+ k2 = READ_UINT64(key + 16);
+
+ _camellia256_set_encrypt_key (ctx, k0, k1, k2, ~k2);
+}
diff --git a/config.m4.in b/config.m4.in
index da57e253..bcfb95e5 100644
--- a/config.m4.in
+++ b/config.m4.in
@@ -4,7 +4,6 @@ define(<ELF_STYLE>, <@ASM_ELF_STYLE@>)dnl
define(<TYPE_FUNCTION>, <@ASM_TYPE_FUNCTION@>)dnl
define(<TYPE_PROGBITS>, <@ASM_TYPE_PROGBITS@>)dnl
define(<ALIGN_LOG>, <@ASM_ALIGN_LOG@>)dnl
-define(<ALIGNOF_UINT64_T>, <@ALIGNOF_UINT64_T@>)dnl
define(<W64_ABI>, <@W64_ABI@>)dnl
define(<RODATA>, <@ASM_RODATA@>)dnl
divert(1)
diff --git a/configure.ac b/configure.ac
index d54e91d3..6c4b1d28 100644
--- a/configure.ac
+++ b/configure.ac
@@ -629,10 +629,6 @@ AC_TYPE_UID_T
AC_TYPE_SIZE_T
AC_HEADER_TIME
AC_CHECK_SIZEOF(long)
-AC_CHECK_ALIGNOF(uint64_t)
-
-ALIGNOF_UINT64_T="$ac_cv_alignof_uint64_t"
-AC_SUBST(ALIGNOF_UINT64_T)
AC_CHECK_HEADERS([openssl/blowfish.h openssl/des.h openssl/cast.h openssl/aes.h openssl/ecdsa.h],,
[enable_openssl=no
diff --git a/testsuite/camellia-test.c b/testsuite/camellia-test.c
index 9a1cb8ca..f6c850a5 100644
--- a/testsuite/camellia-test.c
+++ b/testsuite/camellia-test.c
@@ -6,8 +6,6 @@ test_invert(const struct tstring *key,
const struct tstring *cleartext,
const struct tstring *ciphertext)
{
- struct camellia_ctx encrypt;
- struct camellia_ctx decrypt;
uint8_t *data;
size_t length;
@@ -16,22 +14,49 @@ test_invert(const struct tstring *key,
data = xalloc(length);
- camellia_set_encrypt_key (&encrypt, key->length, key->data);
- camellia_crypt (&encrypt, length, data, cleartext->data);
-
- if (!MEMEQ(length, data, ciphertext->data))
+ if (key->length == 16)
{
- tstring_print_hex(cleartext);
- fprintf(stderr, "\nOutput: ");
- print_hex(length, data);
- fprintf(stderr, "\nExpected:");
- tstring_print_hex(ciphertext);
- fprintf(stderr, "\n");
- FAIL();
+ struct camellia128_ctx encrypt;
+ struct camellia128_ctx decrypt;
+
+ camellia128_set_encrypt_key (&encrypt, key->data);
+ camellia128_crypt (&encrypt, length, data, cleartext->data);
+
+ if (!MEMEQ(length, data, ciphertext->data))
+ {
+ fail_encrypt:
+ tstring_print_hex(cleartext);
+ fprintf(stderr, "\nOutput: ");
+ print_hex(length, data);
+ fprintf(stderr, "\nExpected:");
+ tstring_print_hex(ciphertext);
+ fprintf(stderr, "\n");
+ FAIL();
+ }
+
+ camellia128_invert_key (&decrypt, &encrypt);
+ camellia128_crypt (&decrypt, length, data, data);
}
+ else
+ {
+ struct camellia256_ctx encrypt;
+ struct camellia256_ctx decrypt;
- camellia_invert_key (&decrypt, &encrypt);
- camellia_crypt (&decrypt, length, data, data);
+ if (key->length == 24)
+ camellia192_set_encrypt_key (&encrypt, key->data);
+ else if (key->length == 32)
+ camellia256_set_encrypt_key (&encrypt, key->data);
+ else
+ abort ();
+
+ camellia256_crypt (&encrypt, length, data, cleartext->data);
+
+ if (!MEMEQ(length, data, ciphertext->data))
+ goto fail_encrypt;
+
+ camellia256_invert_key (&decrypt, &encrypt);
+ camellia256_crypt (&decrypt, length, data, data);
+ }
if (!MEMEQ(length, data, cleartext->data))
{
diff --git a/x86/camellia-crypt-internal.asm b/x86/camellia-crypt-internal.asm
index 6fc94c01..77921fa4 100644
--- a/x86/camellia-crypt-internal.asm
+++ b/x86/camellia-crypt-internal.asm
@@ -40,11 +40,12 @@ define(<FRAME_H1>, <12(%esp)>)
define(<FRAME_CNT>, <16(%esp)>)
C Arguments on stack.
-define(<FRAME_CTX>, <40(%esp)>)
-define(<FRAME_TABLE>, <44(%esp)>)
-define(<FRAME_LENGTH>, <48(%esp)>)
-define(<FRAME_DST>, <52(%esp)>)
-define(<FRAME_SRC>, <56(%esp)>)
+define(<FRAME_NKEYS>, <40(%esp)>)
+define(<FRAME_KEYS>, <44(%esp)>)
+define(<FRAME_TABLE>, <48(%esp)>)
+define(<FRAME_LENGTH>, <52(%esp)>)
+define(<FRAME_DST>, <56(%esp)>)
+define(<FRAME_SRC>, <60(%esp)>)
define(<SP1110>, <(T,$1,4)>)
define(<SP0222>, <1024(T,$1,4)>)
@@ -134,9 +135,9 @@ define(<FLINV>, <
xorl TMP, $1
>)
-.file "camellia-encrypt-internal.asm"
+.file "camellia-crypt-internal.asm"
- C _camellia_crypt(struct camellia_context *ctx,
+ C _camellia_crypt(unsigned nkeys, const uint64_t *keys,
C const struct camellia_table *T,
C size_t length, uint8_t *dst,
C uint8_t *src)
@@ -167,14 +168,13 @@ PROLOGUE(_nettle_camellia_crypt)
movl 12(TMP), L1
bswap L1
addl $16, FRAME_SRC
- movl FRAME_CTX, KEY
- movl (KEY), TMP
+ movl FRAME_KEYS, KEY
+ movl FRAME_NKEYS, TMP
subl $8, TMP
movl TMP, FRAME_CNT
- C Whitening using first subkey
- addl $ALIGNOF_UINT64_T + 8, KEY
- xorl -8(KEY), L0
- xorl -4(KEY), H0
+ xorl (KEY), L0
+ xorl 4(KEY), H0
+ addl $8, KEY
movl FRAME_TABLE, T
diff --git a/x86_64/camellia-crypt-internal.asm b/x86_64/camellia-crypt-internal.asm
index 05409702..b8d201e3 100644
--- a/x86_64/camellia-crypt-internal.asm
+++ b/x86_64/camellia-crypt-internal.asm
@@ -26,16 +26,17 @@ C Camellia-256 543 461
C Register usage:
-define(<CTX>, <%rdi>)
-define(<TABLE>, <%rsi>)
-define(<LENGTH>, <%rdx>)
-define(<DST>, <%rcx>)
-define(<SRC>, <%r8>)
+define(<NKEYS>, <%rdi>)
+define(<KEYS>, <%rsi>)
+define(<TABLE>, <%rdx>)
+define(<LENGTH>, <%rcx>)
+define(<DST>, <%r8>)
+define(<SRC>, <%r9>)
C Camellia state
define(<I0>, <%rax>)
define(<I1>, <%rbx>) C callee-save
-define(<KEY>, <%r9>)
+define(<KEY>, <%r13>) C callee-save
define(<TMP>, <%rbp>) C callee-save
define(<CNT>, <%r10>)
define(<IL>, <%r11>)
@@ -114,9 +115,9 @@ C xorl XREG(TMP), XREG($1)
xor TMP, $1
>)
- .file "camellia-encrypt-internal.asm"
+ .file "camellia-crypt-internal.asm"
- C _camellia_crypt(struct camellia_context *ctx,
+ C _camellia_crypt(unsigned nkeys, const uint64_t *keys,
C const struct camellia_table *T,
C size_t length, uint8_t *dst,
C uint8_t *src)
@@ -131,7 +132,8 @@ PROLOGUE(_nettle_camellia_crypt)
push %rbx
push %rbp
push %r12
-
+ push %r13
+ sub $8, NKEYS
.Lblock_loop:
C Load data, note that we'll happily do unaligned loads
mov (SRC), I0
@@ -139,13 +141,12 @@ PROLOGUE(_nettle_camellia_crypt)
mov 8(SRC), I1
bswap I1
add $16, SRC
- mov CTX, KEY
- movl (KEY), XREG(CNT)
- sub $8, CNT
+ mov XREG(NKEYS), XREG(CNT)
+ mov KEYS, KEY
C Whitening using first subkey
- xor 8(KEY), I0
- add $16, KEY
+ xor (KEY), I0
+ add $8, KEY
ROUND(I0, I1, 0)
ROUND(I1, I0, 8)
@@ -178,6 +179,7 @@ PROLOGUE(_nettle_camellia_crypt)
ja .Lblock_loop
+ pop %r13
pop %r12
pop %rbp
pop %rbx