Imported Upstream version 3.2
[platform/upstream/nettle.git] / camellia-crypt-internal.c
1 /* camellia-crypt-internal.c
2
3    Copyright (C) 2006,2007 NTT
4    (Nippon Telegraph and Telephone Corporation).
5
6    Copyright (C) 2010 Niels Möller
7
8    This file is part of GNU Nettle.
9
10    GNU Nettle is free software: you can redistribute it and/or
11    modify it under the terms of either:
12
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.
16
17    or
18
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.
22
23    or both in parallel, as here.
24
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.
29
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/.
33 */
34
35 /*
36  * Algorithm Specification 
37  *  http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
38  */
39
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.
42  */
43 #if HAVE_CONFIG_H
44 # include "config.h"
45 #endif
46
47 #include <assert.h>
48 #include <limits.h>
49
50 #include "camellia-internal.h"
51
52 #include "macros.h"
53
54 #define CAMELLIA_FL(x, k) do {                  \
55   uint32_t __xl, __xr, __kl, __kr, __t;         \
56   __xl = (x) >> 32;                             \
57   __xr = (x) & 0xffffffff;                      \
58   __kl = (k) >> 32;                             \
59   __kr = (k) & 0xffffffff;                      \
60   __t = __xl & __kl;                            \
61   __xr ^= ROTL32(1, __t);                       \
62   __xl ^= (__xr | __kr);                        \
63   (x) = ((uint64_t) __xl << 32) | __xr;         \
64 } while (0)
65
66 #define CAMELLIA_FLINV(x, k) do {               \
67   uint32_t __xl, __xr, __kl, __kr, __t;         \
68   __xl = (x) >> 32;                             \
69   __xr = (x) & 0xffffffff;                      \
70   __kl = (k) >> 32;                             \
71   __kr = (k) & 0xffffffff;                      \
72   __xl ^= (__xr | __kr);                        \
73   __t = __xl & __kl;                            \
74   __xr ^= ROTL32(1, __t);                       \
75   (x) = ((uint64_t) __xl << 32) | __xr;         \
76 } while (0)
77
78 #if HAVE_NATIVE_64_BIT
79 #define CAMELLIA_ROUNDSM(T, x, k, y) do {                       \
80     uint32_t __il, __ir;                                        \
81     __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) */     \
87     __il                                                        \
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) */     \
93     __ir ^= __il;                                               \
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)                  \
96        == y1,y2,y3,y4 */                                        \
97     __il = ROTL32(24, __il);                                    \
98     /* il == (t2^t3^t4),(t1^t3^t4),(t1^t2^t4),(t1^t2^t3) */     \
99     __il ^= __ir;                                               \
100     /* il == (t1^t2^t6^t7^t8),(t2^t3^t5^t7^t8),                 \
101        (t3^t4^t5^t6^t8),(t1^t4^t5^t6^t7)                        \
102        == y5,y6,y7,y8 */                                        \
103     y ^= (k);                                                   \
104     y ^= ((uint64_t) __ir << 32) | __il;                        \
105   } while (0)
106 #else /* !HAVE_NATIVE_64_BIT */
107 #define CAMELLIA_ROUNDSM(T, x, k, y) do {                       \
108     uint32_t __il, __ir;                                        \
109     __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) */     \
115     __il                                                        \
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) */     \
121     __il ^= (k) >> 32;                                          \
122     __ir ^= (k) & 0xffffffff;                                   \
123     __ir ^= __il;                                               \
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)                  \
126        == y1,y2,y3,y4 */                                        \
127     __il = ROTL32(24, __il);                                    \
128     /* il == (t2^t3^t4),(t1^t3^t4),(t1^t2^t4),(t1^t2^t3) */     \
129     __il ^= __ir;                                               \
130     /* il == (t1^t2^t6^t7^t8),(t2^t3^t5^t7^t8),                 \
131        (t3^t4^t5^t6^t8),(t1^t4^t5^t6^t7)                        \
132        == y5,y6,y7,y8 */                                        \
133     y ^= ((uint64_t) __ir << 32) | __il;                        \
134   } while (0)
135 #endif
136
137 void
138 _camellia_crypt(unsigned nkeys,
139                 const uint64_t *keys,
140                 const struct camellia_table *T,
141                 size_t length, uint8_t *dst,
142                 const uint8_t *src)
143 {
144   FOR_BLOCKS(length, dst, src, CAMELLIA_BLOCK_SIZE)
145     {
146       uint64_t i0,i1;
147       unsigned i;
148
149       i0 = READ_UINT64(src);
150       i1 = READ_UINT64(src +  8);
151       
152       /* pre whitening but absorb kw2*/
153       i0 ^= keys[0];
154
155       /* main iteration */
156
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);
163       
164       for (i = 0; i < nkeys - 8; i+= 8)
165         {
166           CAMELLIA_FL(i0, keys[i+7]);
167           CAMELLIA_FLINV(i1, keys[i+8]);
168           
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);
175         }
176
177       /* post whitening but kw4 */
178       i1 ^= keys[i+7];
179
180       WRITE_UINT64(dst     , i1);
181       WRITE_UINT64(dst +  8, i0);
182     }
183 }