1 /* camellia-crypt-internal.c
3 Copyright (C) 2006,2007 NTT
4 (Nippon Telegraph and Telephone Corporation).
6 Copyright (C) 2010 Niels Möller
8 This file is part of GNU Nettle.
10 GNU Nettle is free software: you can redistribute it and/or
11 modify it under the terms of either:
13 * the GNU Lesser General Public License as published by the Free
14 Software Foundation; either version 3 of the License, or (at your
15 option) any later version.
19 * the GNU General Public License as published by the Free
20 Software Foundation; either version 2 of the License, or (at your
21 option) any later version.
23 or both in parallel, as here.
25 GNU Nettle is distributed in the hope that it will be useful,
26 but WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 General Public License for more details.
30 You should have received copies of the GNU General Public License and
31 the GNU Lesser General Public License along with this program. If
32 not, see http://www.gnu.org/licenses/.
36 * Algorithm Specification
37 * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
40 /* Based on camellia.c ver 1.2.0, see
41 http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/camellia-LGPL-1.2.0.tar.gz.
50 #include "camellia-internal.h"
54 #define CAMELLIA_FL(x, k) do { \
55 uint32_t __xl, __xr, __kl, __kr, __t; \
57 __xr = (x) & 0xffffffff; \
59 __kr = (k) & 0xffffffff; \
61 __xr ^= ROTL32(1, __t); \
62 __xl ^= (__xr | __kr); \
63 (x) = ((uint64_t) __xl << 32) | __xr; \
66 #define CAMELLIA_FLINV(x, k) do { \
67 uint32_t __xl, __xr, __kl, __kr, __t; \
69 __xr = (x) & 0xffffffff; \
71 __kr = (k) & 0xffffffff; \
72 __xl ^= (__xr | __kr); \
74 __xr ^= ROTL32(1, __t); \
75 (x) = ((uint64_t) __xl << 32) | __xr; \
78 #if HAVE_NATIVE_64_BIT
79 #define CAMELLIA_ROUNDSM(T, x, k, y) do { \
80 uint32_t __il, __ir; \
82 = T->sp1110[(x) & 0xff] \
83 ^ T->sp0222[((x) >> 24) & 0xff] \
84 ^ T->sp3033[((x) >> 16) & 0xff] \
85 ^ T->sp4404[((x) >> 8) & 0xff]; \
86 /* ir == (t6^t7^t8),(t5^t7^t8),(t5^t6^t8),(t5^t6^t7) */ \
88 = T->sp1110[ (x) >> 56] \
89 ^ T->sp0222[((x) >> 48) & 0xff] \
90 ^ T->sp3033[((x) >> 40) & 0xff] \
91 ^ T->sp4404[((x) >> 32) & 0xff]; \
92 /* il == (t1^t3^t4),(t1^t2^t4),(t1^t2^t3),(t2^t3^t4) */ \
94 /* ir == (t1^t3^t4^t6^t7^t8),(t1^t2^t4^t5^t7^t8), \
95 (t1^t2^t3^t5^t6^t8),(t2^t3^t4^t5^t6^t7) \
97 __il = ROTL32(24, __il); \
98 /* il == (t2^t3^t4),(t1^t3^t4),(t1^t2^t4),(t1^t2^t3) */ \
100 /* il == (t1^t2^t6^t7^t8),(t2^t3^t5^t7^t8), \
101 (t3^t4^t5^t6^t8),(t1^t4^t5^t6^t7) \
104 y ^= ((uint64_t) __ir << 32) | __il; \
106 #else /* !HAVE_NATIVE_64_BIT */
107 #define CAMELLIA_ROUNDSM(T, x, k, y) do { \
108 uint32_t __il, __ir; \
110 = T->sp1110[(x) & 0xff] \
111 ^ T->sp0222[((x) >> 24) & 0xff] \
112 ^ T->sp3033[((x) >> 16) & 0xff] \
113 ^ T->sp4404[((x) >> 8) & 0xff]; \
114 /* ir == (t6^t7^t8),(t5^t7^t8),(t5^t6^t8),(t5^t6^t7) */ \
116 = T->sp1110[ (x) >> 56] \
117 ^ T->sp0222[((x) >> 48) & 0xff] \
118 ^ T->sp3033[((x) >> 40) & 0xff] \
119 ^ T->sp4404[((x) >> 32) & 0xff]; \
120 /* il == (t1^t3^t4),(t1^t2^t4),(t1^t2^t3),(t2^t3^t4) */ \
122 __ir ^= (k) & 0xffffffff; \
124 /* ir == (t1^t3^t4^t6^t7^t8),(t1^t2^t4^t5^t7^t8), \
125 (t1^t2^t3^t5^t6^t8),(t2^t3^t4^t5^t6^t7) \
127 __il = ROTL32(24, __il); \
128 /* il == (t2^t3^t4),(t1^t3^t4),(t1^t2^t4),(t1^t2^t3) */ \
130 /* il == (t1^t2^t6^t7^t8),(t2^t3^t5^t7^t8), \
131 (t3^t4^t5^t6^t8),(t1^t4^t5^t6^t7) \
133 y ^= ((uint64_t) __ir << 32) | __il; \
138 _camellia_crypt(unsigned nkeys,
139 const uint64_t *keys,
140 const struct camellia_table *T,
141 size_t length, uint8_t *dst,
144 FOR_BLOCKS(length, dst, src, CAMELLIA_BLOCK_SIZE)
149 i0 = READ_UINT64(src);
150 i1 = READ_UINT64(src + 8);
152 /* pre whitening but absorb kw2*/
157 CAMELLIA_ROUNDSM(T, i0, keys[1], i1);
158 CAMELLIA_ROUNDSM(T, i1, keys[2], i0);
159 CAMELLIA_ROUNDSM(T, i0, keys[3], i1);
160 CAMELLIA_ROUNDSM(T, i1, keys[4], i0);
161 CAMELLIA_ROUNDSM(T, i0, keys[5], i1);
162 CAMELLIA_ROUNDSM(T, i1, keys[6], i0);
164 for (i = 0; i < nkeys - 8; i+= 8)
166 CAMELLIA_FL(i0, keys[i+7]);
167 CAMELLIA_FLINV(i1, keys[i+8]);
169 CAMELLIA_ROUNDSM(T, i0, keys[i+9], i1);
170 CAMELLIA_ROUNDSM(T, i1, keys[i+10], i0);
171 CAMELLIA_ROUNDSM(T, i0, keys[i+11], i1);
172 CAMELLIA_ROUNDSM(T, i1, keys[i+12], i0);
173 CAMELLIA_ROUNDSM(T, i0, keys[i+13], i1);
174 CAMELLIA_ROUNDSM(T, i1, keys[i+14], i0);
177 /* post whitening but kw4 */
180 WRITE_UINT64(dst , i1);
181 WRITE_UINT64(dst + 8, i0);