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