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-2024 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.4.4
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 = (sbox1[(zl >> 24) & 0xFF] << 24) | (sbox2[(zl >> 16) & 0xFF] << 16) | \
76  (sbox3[(zl >> 8) & 0xFF] << 8) | sbox4[zl & 0xFF]; \
77  zr = (sbox2[(zr >> 24) & 0xFF] << 24) | (sbox3[(zr >> 16) & 0xFF] << 16) | \
78  (sbox4[(zr >> 8) & 0xFF] << 8) | sbox1[zr & 0xFF]; \
79 }
80 
81 //P-function
82 #define P(zl, zr) \
83 { \
84  zl ^= ROL32(zr, 8); \
85  zr ^= ROL32(zl, 16); \
86  zl ^= ROR32(zr, 8); \
87  zr ^= ROR32(zl, 8); \
88 }
89 
90 //Round function
91 #define ROUND(left1, left2, right1, right2, k1, k2) \
92 { \
93  temp1 = left1 ^ k1; \
94  temp2 = left2 ^ k2; \
95  S(temp1, temp2); \
96  P(temp1, temp2); \
97  temp1 ^= right2; \
98  temp2 ^= right1; \
99  right1 = left1; \
100  right2 = left2; \
101  left1 = temp2; \
102  left2 = temp1; \
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 //Camellia128-CBC OID (1.2.392.200011.61.1.1.1.2)
279 const uint8_t CAMELLIA128_CBC_OID[11] = {0x2A, 0x83, 0x08, 0x8C, 0x9A, 0x4B, 0x3D, 0x01, 0x01, 0x01, 0x02};
280 //Camellia192-CBC OID (1.2.392.200011.61.1.1.1.3)
281 const uint8_t CAMELLIA192_CBC_OID[11] = {0x2A, 0x83, 0x08, 0x8C, 0x9A, 0x4B, 0x3D, 0x01, 0x01, 0x01, 0x03};
282 //Camellia256-CBC OID (1.2.392.200011.61.1.1.1.4)
283 const uint8_t CAMELLIA256_CBC_OID[11] = {0x2A, 0x83, 0x08, 0x8C, 0x9A, 0x4B, 0x3D, 0x01, 0x01, 0x01, 0x04};
284 
285 //Common interface for encryption algorithms
287 {
288  "Camellia",
289  sizeof(CamelliaContext),
293  NULL,
294  NULL,
298 };
299 
300 
301 /**
302  * @brief Initialize a Camellia context using the supplied key
303  * @param[in] context Pointer to the Camellia context to initialize
304  * @param[in] key Pointer to the key
305  * @param[in] keyLen Length of the key
306  * @return Error code
307  **/
308 
309 error_t camelliaInit(CamelliaContext *context, const uint8_t *key,
310  size_t keyLen)
311 {
312  uint_t i;
313  uint32_t temp1;
314  uint32_t temp2;
315  uint32_t *k;
316  const CamelliaSubkey *p;
317 
318  //Check parameters
319  if(context == NULL || key == NULL)
321 
322  //Check the length of the key
323  if(keyLen == 16)
324  {
325  //18 rounds are required for 128-bit key
326  context->nr = 18;
327  }
328  else if(keyLen == 24 || keyLen == 32)
329  {
330  //24 rounds are required for 192 and 256-bit keys
331  context->nr = 24;
332  }
333  else
334  {
335  //Report an error
337  }
338 
339  //Point to KA, KB, KL and KR
340  k = context->k;
341  //Clear key contents
342  osMemset(k, 0, 64);
343  //Save the supplied secret key
344  osMemcpy(k, key, keyLen);
345 
346  //192-bit keys require special processing
347  if(keyLen == 24)
348  {
349  //Form a 256-bit key
350  k[KR + 2] = ~k[KR + 0];
351  k[KR + 3] = ~k[KR + 1];
352  }
353 
354  //XOR KL and KR before applying the rounds
355  for(i = 0; i < 4; i++)
356  {
357  k[KL + i] = betoh32(k[KL + i]);
358  k[KR + i] = betoh32(k[KR + i]);
359  k[KB + i] = k[KL + i] ^ k[KR + i];
360  }
361 
362  //Generate the 128-bit keys KA and KB
363  for(i = 0; i < 6; i++)
364  {
365  //Apply round function
366  ROUND(k[KB + 0], k[KB + 1], k[KB + 2], k[KB + 3], sigma[2 * i], sigma[2 * i + 1]);
367 
368  //The 2nd round requires special processing
369  if(i == 1)
370  {
371  //The result is XORed with KL
372  k[KB + 0] ^= k[KL + 0];
373  k[KB + 1] ^= k[KL + 1];
374  k[KB + 2] ^= k[KL + 2];
375  k[KB + 3] ^= k[KL + 3];
376  }
377  //The 4th round requires special processing
378  else if(i == 3)
379  {
380  //Save KA after the 4th round
381  osMemcpy(k + KA, k + KB, 16);
382 
383  //The result is XORed with KR
384  k[KB + 0] ^= k[KR + 0];
385  k[KB + 1] ^= k[KR + 1];
386  k[KB + 2] ^= k[KR + 2];
387  k[KB + 3] ^= k[KR + 3];
388  }
389  }
390 
391  //The key schedule depends on the length of key
392  if(keyLen == 16)
393  {
394  //Key schedule for 128-bit key
395  i = arraysize(ks1);
396  p = ks1;
397  }
398  else
399  {
400  //Key schedule for 192 and 256-bit keys
401  i = arraysize(ks2);
402  p = ks2;
403  }
404 
405  //Generate subkeys
406  while(i > 0)
407  {
408  //Calculate the shift count
409  uint_t n = (p->shift + p->position) / 32;
410  uint_t m = (p->shift + p->position) % 32;
411 
412  //Point to KL, KR, KA or KB
413  k = context->k + p->key;
414 
415  //Generate the current subkey
416  if(m == 0)
417  {
418  context->ks[p->index] = k[n % 4];
419  context->ks[p->index + 1] = k[(n + 1) % 4];
420  }
421  else
422  {
423  context->ks[p->index] = (k[n % 4] << m) | (k[(n + 1) % 4] >> (32 - m));
424  context->ks[p->index + 1] = (k[(n + 1) % 4] << m) | (k[(n + 2) % 4] >> (32 - m));
425  }
426 
427  //Next subkey
428  p++;
429  i--;
430  }
431 
432  //No error to report
433  return NO_ERROR;
434 }
435 
436 
437 /**
438  * @brief Encrypt a 16-byte block using Camellia algorithm
439  * @param[in] context Pointer to the Camellia context
440  * @param[in] input Plaintext block to encrypt
441  * @param[out] output Ciphertext block resulting from encryption
442  **/
443 
444 void camelliaEncryptBlock(CamelliaContext *context, const uint8_t *input,
445  uint8_t *output)
446 {
447  uint_t i;
448  uint32_t temp1;
449  uint32_t temp2;
450  uint32_t *ks;
451 
452  //The plaintext is separated into two parts (L and R)
453  uint32_t left1 = LOAD32BE(input + 0);
454  uint32_t left2 = LOAD32BE(input + 4);
455  uint32_t right1 = LOAD32BE(input + 8);
456  uint32_t right2 = LOAD32BE(input + 12);
457 
458  //The key schedule must be applied in ascending order
459  ks = context->ks;
460 
461  //XOR plaintext with kw1 and kw2
462  left1 ^= ks[0];
463  left2 ^= ks[1];
464  right1 ^= ks[2];
465  right2 ^= ks[3];
466 
467  //Advance current location in key schedule
468  ks += 4;
469 
470  //Apply round function 18 or 24 times depending on the key length
471  for(i = context->nr; i > 0; i--)
472  {
473  //Apply round function
474  ROUND(left1, left2, right1, right2, ks[0], ks[1]);
475 
476  //Advance current location in key schedule
477  ks += 2;
478 
479  //6th, 12th and 18th rounds require special processing
480  if(i == 7 || i == 13 || i == 19)
481  {
482  //Apply FL-function
483  FL(left1, left2, ks[0], ks[1])
484  //Apply inverse FL-function
485  FL_INV(right1, right2, ks[2], ks[3])
486  //Advance current location in key schedule
487  ks += 4;
488  }
489  }
490 
491  //XOR operation with kw3 and kw4
492  right1 ^= ks[0];
493  right2 ^= ks[1];
494  left1 ^= ks[2];
495  left2 ^= ks[3];
496 
497  //The resulting value is the ciphertext
498  STORE32BE(right1, output + 0);
499  STORE32BE(right2, output + 4);
500  STORE32BE(left1, output + 8);
501  STORE32BE(left2, output + 12);
502 }
503 
504 
505 /**
506  * @brief Decrypt a 16-byte block using Camellia algorithm
507  * @param[in] context Pointer to the Camellia context
508  * @param[in] input Ciphertext block to decrypt
509  * @param[out] output Plaintext block resulting from decryption
510  **/
511 
512 void camelliaDecryptBlock(CamelliaContext *context, const uint8_t *input,
513  uint8_t *output)
514 {
515  uint_t i;
516  uint32_t temp1;
517  uint32_t temp2;
518  uint32_t *ks;
519 
520  //The ciphertext is separated into two parts (L and R)
521  uint32_t right1 = LOAD32BE(input + 0);
522  uint32_t right2 = LOAD32BE(input + 4);
523  uint32_t left1 = LOAD32BE(input + 8);
524  uint32_t left2 = LOAD32BE(input + 12);
525 
526  //The key schedule must be applied in reverse order
527  ks = (context->nr == 18) ? (context->ks + 48) : (context->ks + 64);
528 
529  //XOR ciphertext with kw3 and kw4
530  right1 ^= ks[0];
531  right2 ^= ks[1];
532  left1 ^= ks[2];
533  left2 ^= ks[3];
534 
535  //Apply round function 18 or 24 times depending on the key length
536  for(i = context->nr; i > 0; i--)
537  {
538  //Update current location in key schedule
539  ks -= 2;
540 
541  //Apply round function
542  ROUND(right1, right2, left1, left2, ks[0], ks[1]);
543 
544  //6th, 12th and 18th rounds require special processing
545  if(i == 7 || i == 13 || i == 19)
546  {
547  //Update current location in key schedule
548  ks -= 4;
549  //Apply FL-function
550  FL(right1, right2, ks[2], ks[3])
551  //Apply inverse FL-function
552  FL_INV(left1, left2, ks[0], ks[1])
553  }
554  }
555 
556  //Update current location in key schedule
557  ks -= 4;
558 
559  //XOR operation with kw1 and kw2
560  left1 ^= ks[0];
561  left2 ^= ks[1];
562  right1 ^= ks[2];
563  right2 ^= ks[3];
564 
565  //The resulting value is the plaintext
566  STORE32BE(left1, output + 0);
567  STORE32BE(left2, output + 4);
568  STORE32BE(right1, output + 8);
569  STORE32BE(right2, output + 12);
570 }
571 
572 
573 /**
574  * @brief Release Camellia context
575  * @param[in] context Pointer to the Camellia context
576  **/
577 
579 {
580  //Clear Camellia context
581  osMemset(context, 0, sizeof(CamelliaContext));
582 }
583 
584 #endif
#define betoh32(value)
Definition: cpu_endian.h:454
void camelliaDecryptBlock(CamelliaContext *context, const uint8_t *input, uint8_t *output)
Decrypt a 16-byte block using Camellia algorithm.
Definition: camellia.c:512
void(* CipherAlgoEncryptBlock)(void *context, const uint8_t *input, uint8_t *output)
Definition: crypto.h:1009
#define LOAD32BE(p)
Definition: cpu_endian.h:210
#define KR
Definition: camellia.c:107
uint8_t p
Definition: ndp.h:300
@ CIPHER_ALGO_TYPE_BLOCK
Definition: crypto.h:953
Structure describing subkey generation.
Definition: camellia.h:53
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
error_t
Error codes.
Definition: error.h:43
#define L
Definition: camellia.c:110
void(* CipherAlgoDecryptBlock)(void *context, const uint8_t *input, uint8_t *output)
Definition: crypto.h:1012
uint32_t ks[68]
Definition: camellia.h:69
#define KA
Definition: camellia.c:108
@ ERROR_INVALID_KEY_LENGTH
Definition: error.h:107
const CipherAlgo camelliaCipherAlgo
Definition: camellia.c:286
General definitions for cryptographic algorithms.
const uint8_t CAMELLIA256_CBC_OID[11]
Definition: camellia.c:283
error_t(* CipherAlgoInit)(void *context, const uint8_t *key, size_t keyLen)
Definition: crypto.h:1000
#define KL
Definition: camellia.c:106
error_t camelliaInit(CamelliaContext *context, const uint8_t *key, size_t keyLen)
Initialize a Camellia context using the supplied key.
Definition: camellia.c:309
#define R
Definition: camellia.c:111
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:1068
#define CAMELLIA_BLOCK_SIZE
Definition: camellia.h:38
const uint8_t CAMELLIA128_CBC_OID[11]
Definition: camellia.c:279
#define FL_INV(yl, yr, kl, kr)
Definition: camellia.c:65
unsigned int uint_t
Definition: compiler_port.h:50
#define osMemset(p, value, length)
Definition: os_port.h:135
void(* CipherAlgoDeinit)(void *context)
Definition: crypto.h:1015
#define ROUND(left1, left2, right1, right2, k1, k2)
Definition: camellia.c:91
void camelliaDeinit(CamelliaContext *context)
Release Camellia context.
Definition: camellia.c:578
const uint8_t CAMELLIA192_CBC_OID[11]
Definition: camellia.c:281
#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:444
#define KB
Definition: camellia.c:109
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
#define arraysize(a)
Definition: os_port.h:71
Camellia encryption algorithm.