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