camellia.c
Go to the documentation of this file.
1 /**
2  * @file camellia.c
3  * @brief Camellia encryption algorithm
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2019 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneCrypto Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @section Description
28  *
29  * Camellia is an encryption algorithm designed to encipher and decipher
30  * blocks of 128 bits under control of a 128/192/256-bit secret key
31  *
32  * @author Oryx Embedded SARL (www.oryx-embedded.com)
33  * @version 1.9.6
34  **/
35 
36 //Switch to the appropriate trace level
37 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
38 
39 //Dependencies
40 #include "core/crypto.h"
41 #include "cipher/camellia.h"
42 #include "debug.h"
43 
44 //Check crypto library configuration
45 #if (CAMELLIA_SUPPORT == ENABLED)
46 
47 //Camellia round function
48 #define CAMELLIA_ROUND(left1, left2, right1, right2, k1, k2) \
49 { \
50  temp1 = left1 ^ k1; \
51  temp2 = left2 ^ k2; \
52  CAMELLIA_S(temp1, temp2); \
53  CAMELLIA_P(temp1, temp2); \
54  temp1 ^= right2; \
55  temp2 ^= right1; \
56  right1 = left1; \
57  right2 = left2; \
58  left1 = temp2; \
59  left2 = temp1; \
60 }
61 
62 //F-function
63 #define CAMELLIA_F(xl, xr, kl, kr) \
64 { \
65  xl = xl ^ kl; \
66  xl = xr ^ kr; \
67  CAMELLIA_S(xl, xr); \
68  CAMELLIA_P(xl, xr); \
69 }
70 
71 //FL-function
72 #define CAMELLIA_FL(xl, xr, kl, kr) \
73 { \
74  temp1 = (xl & kl); \
75  xr ^= ROL32(temp1, 1); \
76  xl ^= (xr | kr); \
77 }
78 
79 //Inverse FL-function
80 #define CAMELLIA_INV_FL(yl, yr, kl, kr) \
81 { \
82  yl ^= (yr | kr); \
83  temp1 = (yl & kl); \
84  yr ^= ROL32(temp1, 1); \
85 }
86 
87 //S-function
88 #define CAMELLIA_S(zl, zr) \
89 { \
90  zl = (sbox1[(zl >> 24) & 0xFF] << 24) | (sbox2[(zl >> 16) & 0xFF] << 16) | \
91  (sbox3[(zl >> 8) & 0xFF] << 8) | sbox4[zl & 0xFF]; \
92  zr = (sbox2[(zr >> 24) & 0xFF] << 24) | (sbox3[(zr >> 16) & 0xFF] << 16) | \
93  (sbox4[(zr >> 8) & 0xFF] << 8) | sbox1[zr & 0xFF]; \
94 }
95 
96 //P-function
97 #define CAMELLIA_P(zl, zr) \
98 { \
99  zl ^= ROL32(zr, 8); \
100  zr ^= ROL32(zl, 16); \
101  zl ^= ROR32(zr, 8); \
102  zr ^= ROR32(zl, 8); \
103 }
104 
105 //Key schedule related constants
106 #define KL 0
107 #define KR 4
108 #define KA 8
109 #define KB 12
110 #define L 0
111 #define R 64
112 
113 //Key schedule for 128-bit key
114 static const CamelliaSubkey ks1[] =
115 {
116  {0, KL, 0, L}, //kw1
117  {2, KL, 0, R}, //kw2
118  {4, KA, 0, L}, //k1
119  {6, KA, 0, R}, //k2
120  {8, KL, 15, L}, //k3
121  {10, KL, 15, R}, //k4
122  {12, KA, 15, L}, //k5
123  {14, KA, 15, R}, //k6
124  {16, KA, 30, L}, //ke1
125  {18, KA, 30, R}, //ke2
126  {20, KL, 45, L}, //k7
127  {22, KL, 45, R}, //k8
128  {24, KA, 45, L}, //k9
129  {26, KL, 60, R}, //k10
130  {28, KA, 60, L}, //k11
131  {30, KA, 60, R}, //k12
132  {32, KL, 77, L}, //ke3
133  {34, KL, 77, R}, //ke4
134  {36, KL, 94, L}, //k13
135  {38, KL, 94, R}, //k14
136  {40, KA, 94, L}, //k15
137  {42, KA, 94, R}, //k16
138  {44, KL, 111, L}, //k17
139  {46, KL, 111, R}, //k18
140  {48, KA, 111, L}, //kw3
141  {50, KA, 111, R}, //kw4
142 };
143 
144 //Key schedule for 192 and 256-bit keys
145 static const CamelliaSubkey ks2[] =
146 {
147  {0, KL, 0, L}, //kw1
148  {2, KL, 0, R}, //k2
149  {4, KB, 0, L}, //k1
150  {6, KB, 0, R}, //k2
151  {8, KR, 15, L}, //k3
152  {10, KR, 15, R}, //k4
153  {12, KA, 15, L}, //k5
154  {14, KA, 15, R}, //k6
155  {16, KR, 30, L}, //ke1
156  {18, KR, 30, R}, //ke2
157  {20, KB, 30, L}, //k7
158  {22, KB, 30, R}, //k8
159  {24, KL, 45, L}, //k9
160  {26, KL, 45, R}, //k10
161  {28, KA, 45, L}, //k11
162  {30, KA, 45, R}, //k12
163  {32, KL, 60, L}, //ke3
164  {34, KL, 60, R}, //ke4
165  {36, KR, 60, L}, //k13
166  {38, KR, 60, R}, //k14
167  {40, KB, 60, L}, //k15
168  {42, KB, 60, R}, //k16
169  {44, KL, 77, L}, //k17
170  {46, KL, 77, R}, //k18
171  {48, KA, 77, L}, //ke5
172  {50, KA, 77, R}, //ke6
173  {52, KR, 94, L}, //k19
174  {54, KR, 94, R}, //k20
175  {56, KA, 94, L}, //k21
176  {58, KA, 94, R}, //k22
177  {60, KL, 111, L}, //k23
178  {62, KL, 111, R}, //k24
179  {64, KB, 111, L}, //kw3
180  {66, KB, 111, R}, //kw4
181 };
182 
183 //Key schedule constants
184 static const uint32_t sigma[12] =
185 {
186  0xA09E667F, 0x3BCC908B,
187  0xB67AE858, 0x4CAA73B2,
188  0xC6EF372F, 0xE94F82BE,
189  0x54FF53A5, 0xF1D36F1C,
190  0x10E527FA, 0xDE682D1D,
191  0xB05688C2, 0xB3E6C1FD
192 };
193 
194 //Substitution table 1
195 static const uint8_t sbox1[256] =
196 {
197  0x70, 0x82, 0x2C, 0xEC, 0xB3, 0x27, 0xC0, 0xE5, 0xE4, 0x85, 0x57, 0x35, 0xEA, 0x0C, 0xAE, 0x41,
198  0x23, 0xEF, 0x6B, 0x93, 0x45, 0x19, 0xA5, 0x21, 0xED, 0x0E, 0x4F, 0x4E, 0x1D, 0x65, 0x92, 0xBD,
199  0x86, 0xB8, 0xAF, 0x8F, 0x7C, 0xEB, 0x1F, 0xCE, 0x3E, 0x30, 0xDC, 0x5F, 0x5E, 0xC5, 0x0B, 0x1A,
200  0xA6, 0xE1, 0x39, 0xCA, 0xD5, 0x47, 0x5D, 0x3D, 0xD9, 0x01, 0x5A, 0xD6, 0x51, 0x56, 0x6C, 0x4D,
201  0x8B, 0x0D, 0x9A, 0x66, 0xFB, 0xCC, 0xB0, 0x2D, 0x74, 0x12, 0x2B, 0x20, 0xF0, 0xB1, 0x84, 0x99,
202  0xDF, 0x4C, 0xCB, 0xC2, 0x34, 0x7E, 0x76, 0x05, 0x6D, 0xB7, 0xA9, 0x31, 0xD1, 0x17, 0x04, 0xD7,
203  0x14, 0x58, 0x3A, 0x61, 0xDE, 0x1B, 0x11, 0x1C, 0x32, 0x0F, 0x9C, 0x16, 0x53, 0x18, 0xF2, 0x22,
204  0xFE, 0x44, 0xCF, 0xB2, 0xC3, 0xB5, 0x7A, 0x91, 0x24, 0x08, 0xE8, 0xA8, 0x60, 0xFC, 0x69, 0x50,
205  0xAA, 0xD0, 0xA0, 0x7D, 0xA1, 0x89, 0x62, 0x97, 0x54, 0x5B, 0x1E, 0x95, 0xE0, 0xFF, 0x64, 0xD2,
206  0x10, 0xC4, 0x00, 0x48, 0xA3, 0xF7, 0x75, 0xDB, 0x8A, 0x03, 0xE6, 0xDA, 0x09, 0x3F, 0xDD, 0x94,
207  0x87, 0x5C, 0x83, 0x02, 0xCD, 0x4A, 0x90, 0x33, 0x73, 0x67, 0xF6, 0xF3, 0x9D, 0x7F, 0xBF, 0xE2,
208  0x52, 0x9B, 0xD8, 0x26, 0xC8, 0x37, 0xC6, 0x3B, 0x81, 0x96, 0x6F, 0x4B, 0x13, 0xBE, 0x63, 0x2E,
209  0xE9, 0x79, 0xA7, 0x8C, 0x9F, 0x6E, 0xBC, 0x8E, 0x29, 0xF5, 0xF9, 0xB6, 0x2F, 0xFD, 0xB4, 0x59,
210  0x78, 0x98, 0x06, 0x6A, 0xE7, 0x46, 0x71, 0xBA, 0xD4, 0x25, 0xAB, 0x42, 0x88, 0xA2, 0x8D, 0xFA,
211  0x72, 0x07, 0xB9, 0x55, 0xF8, 0xEE, 0xAC, 0x0A, 0x36, 0x49, 0x2A, 0x68, 0x3C, 0x38, 0xF1, 0xA4,
212  0x40, 0x28, 0xD3, 0x7B, 0xBB, 0xC9, 0x43, 0xC1, 0x15, 0xE3, 0xAD, 0xF4, 0x77, 0xC7, 0x80, 0x9E
213 };
214 
215 //Substitution table 2
216 static const uint8_t sbox2[256] =
217 {
218  0xE0, 0x05, 0x58, 0xD9, 0x67, 0x4E, 0x81, 0xCB, 0xC9, 0x0B, 0xAE, 0x6A, 0xD5, 0x18, 0x5D, 0x82,
219  0x46, 0xDF, 0xD6, 0x27, 0x8A, 0x32, 0x4B, 0x42, 0xDB, 0x1C, 0x9E, 0x9C, 0x3A, 0xCA, 0x25, 0x7B,
220  0x0D, 0x71, 0x5F, 0x1F, 0xF8, 0xD7, 0x3E, 0x9D, 0x7C, 0x60, 0xB9, 0xBE, 0xBC, 0x8B, 0x16, 0x34,
221  0x4D, 0xC3, 0x72, 0x95, 0xAB, 0x8E, 0xBA, 0x7A, 0xB3, 0x02, 0xB4, 0xAD, 0xA2, 0xAC, 0xD8, 0x9A,
222  0x17, 0x1A, 0x35, 0xCC, 0xF7, 0x99, 0x61, 0x5A, 0xE8, 0x24, 0x56, 0x40, 0xE1, 0x63, 0x09, 0x33,
223  0xBF, 0x98, 0x97, 0x85, 0x68, 0xFC, 0xEC, 0x0A, 0xDA, 0x6F, 0x53, 0x62, 0xA3, 0x2E, 0x08, 0xAF,
224  0x28, 0xB0, 0x74, 0xC2, 0xBD, 0x36, 0x22, 0x38, 0x64, 0x1E, 0x39, 0x2C, 0xA6, 0x30, 0xE5, 0x44,
225  0xFD, 0x88, 0x9F, 0x65, 0x87, 0x6B, 0xF4, 0x23, 0x48, 0x10, 0xD1, 0x51, 0xC0, 0xF9, 0xD2, 0xA0,
226  0x55, 0xA1, 0x41, 0xFA, 0x43, 0x13, 0xC4, 0x2F, 0xA8, 0xB6, 0x3C, 0x2B, 0xC1, 0xFF, 0xC8, 0xA5,
227  0x20, 0x89, 0x00, 0x90, 0x47, 0xEF, 0xEA, 0xB7, 0x15, 0x06, 0xCD, 0xB5, 0x12, 0x7E, 0xBB, 0x29,
228  0x0F, 0xB8, 0x07, 0x04, 0x9B, 0x94, 0x21, 0x66, 0xE6, 0xCE, 0xED, 0xE7, 0x3B, 0xFE, 0x7F, 0xC5,
229  0xA4, 0x37, 0xB1, 0x4C, 0x91, 0x6E, 0x8D, 0x76, 0x03, 0x2D, 0xDE, 0x96, 0x26, 0x7D, 0xC6, 0x5C,
230  0xD3, 0xF2, 0x4F, 0x19, 0x3F, 0xDC, 0x79, 0x1D, 0x52, 0xEB, 0xF3, 0x6D, 0x5E, 0xFB, 0x69, 0xB2,
231  0xF0, 0x31, 0x0C, 0xD4, 0xCF, 0x8C, 0xE2, 0x75, 0xA9, 0x4A, 0x57, 0x84, 0x11, 0x45, 0x1B, 0xF5,
232  0xE4, 0x0E, 0x73, 0xAA, 0xF1, 0xDD, 0x59, 0x14, 0x6C, 0x92, 0x54, 0xD0, 0x78, 0x70, 0xE3, 0x49,
233  0x80, 0x50, 0xA7, 0xF6, 0x77, 0x93, 0x86, 0x83, 0x2A, 0xC7, 0x5B, 0xE9, 0xEE, 0x8F, 0x01, 0x3D
234 };
235 
236 //Substitution table 3
237 static const uint8_t sbox3[256] =
238 {
239  0x38, 0x41, 0x16, 0x76, 0xD9, 0x93, 0x60, 0xF2, 0x72, 0xC2, 0xAB, 0x9A, 0x75, 0x06, 0x57, 0xA0,
240  0x91, 0xF7, 0xB5, 0xC9, 0xA2, 0x8C, 0xD2, 0x90, 0xF6, 0x07, 0xA7, 0x27, 0x8E, 0xB2, 0x49, 0xDE,
241  0x43, 0x5C, 0xD7, 0xC7, 0x3E, 0xF5, 0x8F, 0x67, 0x1F, 0x18, 0x6E, 0xAF, 0x2F, 0xE2, 0x85, 0x0D,
242  0x53, 0xF0, 0x9C, 0x65, 0xEA, 0xA3, 0xAE, 0x9E, 0xEC, 0x80, 0x2D, 0x6B, 0xA8, 0x2B, 0x36, 0xA6,
243  0xC5, 0x86, 0x4D, 0x33, 0xFD, 0x66, 0x58, 0x96, 0x3A, 0x09, 0x95, 0x10, 0x78, 0xD8, 0x42, 0xCC,
244  0xEF, 0x26, 0xE5, 0x61, 0x1A, 0x3F, 0x3B, 0x82, 0xB6, 0xDB, 0xD4, 0x98, 0xE8, 0x8B, 0x02, 0xEB,
245  0x0A, 0x2C, 0x1D, 0xB0, 0x6F, 0x8D, 0x88, 0x0E, 0x19, 0x87, 0x4E, 0x0B, 0xA9, 0x0C, 0x79, 0x11,
246  0x7F, 0x22, 0xE7, 0x59, 0xE1, 0xDA, 0x3D, 0xC8, 0x12, 0x04, 0x74, 0x54, 0x30, 0x7E, 0xB4, 0x28,
247  0x55, 0x68, 0x50, 0xBE, 0xD0, 0xC4, 0x31, 0xCB, 0x2A, 0xAD, 0x0F, 0xCA, 0x70, 0xFF, 0x32, 0x69,
248  0x08, 0x62, 0x00, 0x24, 0xD1, 0xFB, 0xBA, 0xED, 0x45, 0x81, 0x73, 0x6D, 0x84, 0x9F, 0xEE, 0x4A,
249  0xC3, 0x2E, 0xC1, 0x01, 0xE6, 0x25, 0x48, 0x99, 0xB9, 0xB3, 0x7B, 0xF9, 0xCE, 0xBF, 0xDF, 0x71,
250  0x29, 0xCD, 0x6C, 0x13, 0x64, 0x9B, 0x63, 0x9D, 0xC0, 0x4B, 0xB7, 0xA5, 0x89, 0x5F, 0xB1, 0x17,
251  0xF4, 0xBC, 0xD3, 0x46, 0xCF, 0x37, 0x5E, 0x47, 0x94, 0xFA, 0xFC, 0x5B, 0x97, 0xFE, 0x5A, 0xAC,
252  0x3C, 0x4C, 0x03, 0x35, 0xF3, 0x23, 0xB8, 0x5D, 0x6A, 0x92, 0xD5, 0x21, 0x44, 0x51, 0xC6, 0x7D,
253  0x39, 0x83, 0xDC, 0xAA, 0x7C, 0x77, 0x56, 0x05, 0x1B, 0xA4, 0x15, 0x34, 0x1E, 0x1C, 0xF8, 0x52,
254  0x20, 0x14, 0xE9, 0xBD, 0xDD, 0xE4, 0xA1, 0xE0, 0x8A, 0xF1, 0xD6, 0x7A, 0xBB, 0xE3, 0x40, 0x4F
255 };
256 
257 //Substitution table 4
258 static const uint8_t sbox4[256] =
259 {
260  0x70, 0x2C, 0xB3, 0xC0, 0xE4, 0x57, 0xEA, 0xAE, 0x23, 0x6B, 0x45, 0xA5, 0xED, 0x4F, 0x1D, 0x92,
261  0x86, 0xAF, 0x7C, 0x1F, 0x3E, 0xDC, 0x5E, 0x0B, 0xA6, 0x39, 0xD5, 0x5D, 0xD9, 0x5A, 0x51, 0x6C,
262  0x8B, 0x9A, 0xFB, 0xB0, 0x74, 0x2B, 0xF0, 0x84, 0xDF, 0xCB, 0x34, 0x76, 0x6D, 0xA9, 0xD1, 0x04,
263  0x14, 0x3A, 0xDE, 0x11, 0x32, 0x9C, 0x53, 0xF2, 0xFE, 0xCF, 0xC3, 0x7A, 0x24, 0xE8, 0x60, 0x69,
264  0xAA, 0xA0, 0xA1, 0x62, 0x54, 0x1E, 0xE0, 0x64, 0x10, 0x00, 0xA3, 0x75, 0x8A, 0xE6, 0x09, 0xDD,
265  0x87, 0x83, 0xCD, 0x90, 0x73, 0xF6, 0x9D, 0xBF, 0x52, 0xD8, 0xC8, 0xC6, 0x81, 0x6F, 0x13, 0x63,
266  0xE9, 0xA7, 0x9F, 0xBC, 0x29, 0xF9, 0x2F, 0xB4, 0x78, 0x06, 0xE7, 0x71, 0xD4, 0xAB, 0x88, 0x8D,
267  0x72, 0xB9, 0xF8, 0xAC, 0x36, 0x2A, 0x3C, 0xF1, 0x40, 0xD3, 0xBB, 0x43, 0x15, 0xAD, 0x77, 0x80,
268  0x82, 0xEC, 0x27, 0xE5, 0x85, 0x35, 0x0C, 0x41, 0xEF, 0x93, 0x19, 0x21, 0x0E, 0x4E, 0x65, 0xBD,
269  0xB8, 0x8F, 0xEB, 0xCE, 0x30, 0x5F, 0xC5, 0x1A, 0xE1, 0xCA, 0x47, 0x3D, 0x01, 0xD6, 0x56, 0x4D,
270  0x0D, 0x66, 0xCC, 0x2D, 0x12, 0x20, 0xB1, 0x99, 0x4C, 0xC2, 0x7E, 0x05, 0xB7, 0x31, 0x17, 0xD7,
271  0x58, 0x61, 0x1B, 0x1C, 0x0F, 0x16, 0x18, 0x22, 0x44, 0xB2, 0xB5, 0x91, 0x08, 0xA8, 0xFC, 0x50,
272  0xD0, 0x7D, 0x89, 0x97, 0x5B, 0x95, 0xFF, 0xD2, 0xC4, 0x48, 0xF7, 0xDB, 0x03, 0xDA, 0x3F, 0x94,
273  0x5C, 0x02, 0x4A, 0x33, 0x67, 0xF3, 0x7F, 0xE2, 0x9B, 0x26, 0x37, 0x3B, 0x96, 0x4B, 0xBE, 0x2E,
274  0x79, 0x8C, 0x6E, 0x8E, 0xF5, 0xB6, 0xFD, 0x59, 0x98, 0x6A, 0x46, 0xBA, 0x25, 0x42, 0xA2, 0xFA,
275  0x07, 0x55, 0xEE, 0x0A, 0x49, 0x68, 0x38, 0xA4, 0x28, 0x7B, 0xC9, 0xC1, 0xE3, 0xF4, 0xC7, 0x9E
276 };
277 
278 //Common interface for encryption algorithms
280 {
281  "CAMELLIA",
282  sizeof(CamelliaContext),
286  NULL,
287  NULL,
290 };
291 
292 
293 /**
294  * @brief Initialize a Camellia context using the supplied key
295  * @param[in] context Pointer to the Camellia context to initialize
296  * @param[in] key Pointer to the key
297  * @param[in] keyLen Length of the key
298  * @return Error code
299  **/
300 
301 error_t camelliaInit(CamelliaContext *context, const uint8_t *key, size_t keyLen)
302 {
303  uint_t i;
304  uint32_t temp1;
305  uint32_t temp2;
306  uint32_t *k;
307  const CamelliaSubkey *p;
308 
309  //Check parameters
310  if(context == NULL || key == NULL)
312 
313  //Check the length of the key
314  if(keyLen == 16)
315  {
316  //18 rounds are required for 128-bit key
317  context->nr = 18;
318  }
319  else if(keyLen == 24 || keyLen == 32)
320  {
321  //24 rounds are required for 192 and 256-bit keys
322  context->nr = 24;
323  }
324  else
325  {
326  //Report an error
328  }
329 
330  //Point to KA, KB, KL and KR
331  k = context->k;
332  //Clear key contents
333  cryptoMemset(k, 0, 64);
334  //Save the supplied secret key
335  cryptoMemcpy(k, key, keyLen);
336 
337  //192-bit keys require special processing
338  if(keyLen == 24)
339  {
340  //Form a 256-bit key
341  k[KR + 2] = ~k[KR + 0];
342  k[KR + 3] = ~k[KR + 1];
343  }
344 
345  //XOR KL and KR before applying the rounds
346  for(i = 0; i < 4; i++)
347  {
348  k[KL + i] = betoh32(k[KL + i]);
349  k[KR + i] = betoh32(k[KR + i]);
350  k[KB + i] = k[KL + i] ^ k[KR + i];
351  }
352 
353  //Generate the 128-bit keys KA and KB
354  for(i = 0; i < 6; i++)
355  {
356  //Apply round function
357  CAMELLIA_ROUND(k[KB + 0], k[KB + 1], k[KB + 2], k[KB + 3], sigma[2 * i], sigma[2 * i + 1]);
358 
359  //The 2nd round requires special processing
360  if(i == 1)
361  {
362  //The result is XORed with KL
363  k[KB + 0] ^= k[KL + 0];
364  k[KB + 1] ^= k[KL + 1];
365  k[KB + 2] ^= k[KL + 2];
366  k[KB + 3] ^= k[KL + 3];
367  }
368  //The 4th round requires special processing
369  else if(i == 3)
370  {
371  //Save KA after the 4th round
372  cryptoMemcpy(k + KA, k + KB, 16);
373  //The result is XORed with KR
374  k[KB + 0] ^= k[KR + 0];
375  k[KB + 1] ^= k[KR + 1];
376  k[KB + 2] ^= k[KR + 2];
377  k[KB + 3] ^= k[KR + 3];
378  }
379  }
380 
381  //The key schedule depends on the length of key
382  if(keyLen == 16)
383  {
384  //Key schedule for 128-bit key
385  i = arraysize(ks1);
386  p = ks1;
387  }
388  else
389  {
390  //Key schedule for 192 and 256-bit keys
391  i = arraysize(ks2);
392  p = ks2;
393  }
394 
395  //Generate subkeys
396  while(i > 0)
397  {
398  //Calculate the shift count
399  uint_t n = (p->shift + p->position) / 32;
400  uint_t m = (p->shift + p->position) % 32;
401  //Point to KL, KR, KA or KB
402  k = context->k + p->key;
403 
404  //Generate the current subkey
405  if(m == 0)
406  {
407  context->ks[p->index] = k[n % 4];
408  context->ks[p->index + 1] = k[(n + 1) % 4];
409  }
410  else
411  {
412  context->ks[p->index] = (k[n % 4] << m) | (k[(n + 1) % 4] >> (32 - m));
413  context->ks[p->index + 1] = (k[(n + 1) % 4] << m) | (k[(n + 2) % 4] >> (32 - m));
414  }
415 
416  //Next subkey
417  p++;
418  i--;
419  }
420 
421  //No error to report
422  return NO_ERROR;
423 }
424 
425 
426 /**
427  * @brief Encrypt a 16-byte block using Camellia algorithm
428  * @param[in] context Pointer to the Camellia context
429  * @param[in] input Plaintext block to encrypt
430  * @param[out] output Ciphertext block resulting from encryption
431  **/
432 
433 void camelliaEncryptBlock(CamelliaContext *context, const uint8_t *input, uint8_t *output)
434 {
435  uint_t i;
436  uint32_t temp1;
437  uint32_t temp2;
438  uint32_t *ks;
439 
440  //The plaintext is separated into two parts (L and R)
441  uint32_t left1 = LOAD32BE(input + 0);
442  uint32_t left2 = LOAD32BE(input + 4);
443  uint32_t right1 = LOAD32BE(input + 8);
444  uint32_t right2 = LOAD32BE(input + 12);
445 
446  //The key schedule must be applied in ascending order
447  ks = context->ks;
448 
449  //XOR plaintext with kw1 and kw2
450  left1 ^= ks[0];
451  left2 ^= ks[1];
452  right1 ^= ks[2];
453  right2 ^= ks[3];
454  //Advance current location in key schedule
455  ks += 4;
456 
457  //Apply round function 18 or 24 times depending on the key length
458  for(i = context->nr; i > 0; i--)
459  {
460  //Apply round function
461  CAMELLIA_ROUND(left1, left2, right1, right2, ks[0], ks[1]);
462  //Advance current location in key schedule
463  ks += 2;
464 
465  //6th, 12th and 18th rounds require special processing
466  if(i == 7 || i == 13 || i == 19)
467  {
468  //Apply FL-function
469  CAMELLIA_FL(left1, left2, ks[0], ks[1])
470  //Apply inverse FL-function
471  CAMELLIA_INV_FL(right1, right2, ks[2], ks[3])
472  //Advance current location in key schedule
473  ks += 4;
474  }
475  }
476 
477  //XOR operation with kw3 and kw4
478  right1 ^= ks[0];
479  right2 ^= ks[1];
480  left1 ^= ks[2];
481  left2 ^= ks[3];
482 
483  //The resulting value is the ciphertext
484  STORE32BE(right1, output + 0);
485  STORE32BE(right2, output + 4);
486  STORE32BE(left1, output + 8);
487  STORE32BE(left2, output + 12);
488 }
489 
490 
491 /**
492  * @brief Decrypt a 16-byte block using Camellia algorithm
493  * @param[in] context Pointer to the Camellia context
494  * @param[in] input Ciphertext block to decrypt
495  * @param[out] output Plaintext block resulting from decryption
496  **/
497 
498 void camelliaDecryptBlock(CamelliaContext *context, const uint8_t *input, uint8_t *output)
499 {
500  uint_t i;
501  uint32_t temp1;
502  uint32_t temp2;
503  uint32_t *ks;
504 
505  //The ciphertext is separated into two parts (L and R)
506  uint32_t right1 = LOAD32BE(input + 0);
507  uint32_t right2 = LOAD32BE(input + 4);
508  uint32_t left1 = LOAD32BE(input + 8);
509  uint32_t left2 = LOAD32BE(input + 12);
510 
511  //The key schedule must be applied in reverse order
512  ks = (context->nr == 18) ? (context->ks + 48) : (context->ks + 64);
513 
514  //XOR ciphertext with kw3 and kw4
515  right1 ^= ks[0];
516  right2 ^= ks[1];
517  left1 ^= ks[2];
518  left2 ^= ks[3];
519 
520  //Apply round function 18 or 24 times depending on the key length
521  for(i = context->nr; i > 0; i--)
522  {
523  //Update current location in key schedule
524  ks -= 2;
525  //Apply round function
526  CAMELLIA_ROUND(right1, right2, left1, left2, ks[0], ks[1]);
527 
528  //6th, 12th and 18th rounds require special processing
529  if(i == 7 || i == 13 || i == 19)
530  {
531  //Update current location in key schedule
532  ks -= 4;
533  //Apply FL-function
534  CAMELLIA_FL(right1, right2, ks[2], ks[3])
535  //Apply inverse FL-function
536  CAMELLIA_INV_FL(left1, left2, ks[0], ks[1])
537  }
538  }
539 
540  //Update current location in key schedule
541  ks -= 4;
542  //XOR operation with kw1 and kw2
543  left1 ^= ks[0];
544  left2 ^= ks[1];
545  right1 ^= ks[2];
546  right2 ^= ks[3];
547 
548  //The resulting value is the plaintext
549  STORE32BE(left1, output + 0);
550  STORE32BE(left2, output + 4);
551  STORE32BE(right1, output + 8);
552  STORE32BE(right2, output + 12);
553 }
554 
555 #endif
#define betoh32(value)
Definition: cpu_endian.h:430
void camelliaDecryptBlock(CamelliaContext *context, const uint8_t *input, uint8_t *output)
Decrypt a 16-byte block using Camellia algorithm.
Definition: camellia.c:498
void(* CipherAlgoEncryptBlock)(void *context, const uint8_t *input, uint8_t *output)
Definition: crypto.h:1103
#define LOAD32BE(p)
Definition: cpu_endian.h:194
#define CAMELLIA_ROUND(left1, left2, right1, right2, k1, k2)
Definition: camellia.c:48
#define KR
Definition: camellia.c:107
uint8_t p
Definition: ndp.h:298
@ CIPHER_ALGO_TYPE_BLOCK
Definition: crypto.h:1069
Structure describing subkey generation.
Definition: camellia.h:52
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
error_t
Error codes.
Definition: error.h:42
#define L
Definition: camellia.c:110
void(* CipherAlgoDecryptBlock)(void *context, const uint8_t *input, uint8_t *output)
Definition: crypto.h:1104
uint32_t ks[68]
Definition: camellia.h:69
#define KA
Definition: camellia.c:108
@ ERROR_INVALID_KEY_LENGTH
Definition: error.h:105
const CipherAlgo camelliaCipherAlgo
Definition: camellia.c:279
General definitions for cryptographic algorithms.
error_t(* CipherAlgoInit)(void *context, const uint8_t *key, size_t keyLen)
Definition: crypto.h:1100
#define KL
Definition: camellia.c:106
#define cryptoMemset(p, value, length)
Definition: crypto.h:636
error_t camelliaInit(CamelliaContext *context, const uint8_t *key, size_t keyLen)
Initialize a Camellia context using the supplied key.
Definition: camellia.c:301
#define R
Definition: camellia.c:111
uint32_t k[16]
Definition: camellia.h:68
uint8_t m
Definition: ndp.h:302
uint8_t n
#define CAMELLIA_INV_FL(yl, yr, kl, kr)
Definition: camellia.c:80
#define cryptoMemcpy(dest, src, length)
Definition: crypto.h:642
Camellia algorithm context.
Definition: camellia.h:65
Common interface for encryption algorithms.
Definition: crypto.h:1150
#define CAMELLIA_BLOCK_SIZE
Definition: camellia.h:38
unsigned int uint_t
Definition: compiler_port.h:45
#define CAMELLIA_FL(xl, xr, kl, kr)
Definition: camellia.c:72
#define STORE32BE(a, p)
Definition: cpu_endian.h:270
void camelliaEncryptBlock(CamelliaContext *context, const uint8_t *input, uint8_t *output)
Encrypt a 16-byte block using Camellia algorithm.
Definition: camellia.c:433
#define KB
Definition: camellia.c:109
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
#define arraysize(a)
Definition: os_port.h:70
Camellia encryption algorithm.