1/*
2 * Camellia implementation
3 *
4 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19/*
20 * The Camellia block cipher was designed by NTT and Mitsubishi Electric
21 * Corporation.
22 *
23 * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/01espec.pdf
24 */
25
26#include "common.h"
27
28#if defined(MBEDTLS_CAMELLIA_C)
29
30#include "mbedtls/camellia.h"
31#include "mbedtls/platform_util.h"
32
33#include <string.h>
34
35#include "mbedtls/platform.h"
36
37#if !defined(MBEDTLS_CAMELLIA_ALT)
38
39/* Parameter validation macros */
40#define CAMELLIA_VALIDATE_RET(cond) \
41 MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA)
42#define CAMELLIA_VALIDATE(cond) \
43 MBEDTLS_INTERNAL_VALIDATE(cond)
44
45static const unsigned char SIGMA_CHARS[6][8] =
46{
47 { 0xa0, 0x9e, 0x66, 0x7f, 0x3b, 0xcc, 0x90, 0x8b },
48 { 0xb6, 0x7a, 0xe8, 0x58, 0x4c, 0xaa, 0x73, 0xb2 },
49 { 0xc6, 0xef, 0x37, 0x2f, 0xe9, 0x4f, 0x82, 0xbe },
50 { 0x54, 0xff, 0x53, 0xa5, 0xf1, 0xd3, 0x6f, 0x1c },
51 { 0x10, 0xe5, 0x27, 0xfa, 0xde, 0x68, 0x2d, 0x1d },
52 { 0xb0, 0x56, 0x88, 0xc2, 0xb3, 0xe6, 0xc1, 0xfd }
53};
54
55#if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY)
56
57static const unsigned char FSb[256] =
58{
59 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65,
60 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189,
61 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26,
62 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77,
63 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153,
64 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215,
65 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34,
66 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80,
67 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210,
68 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148,
69 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226,
70 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46,
71 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89,
72 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250,
73 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164,
74 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158
75};
76
77#define SBOX1(n) FSb[(n)]
78#define SBOX2(n) (unsigned char) ((FSb[(n)] >> 7 ^ FSb[(n)] << 1) & 0xff)
79#define SBOX3(n) (unsigned char) ((FSb[(n)] >> 1 ^ FSb[(n)] << 7) & 0xff)
80#define SBOX4(n) FSb[((n) << 1 ^ (n) >> 7) &0xff]
81
82#else /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
83
84static const unsigned char FSb[256] =
85{
86 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65,
87 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189,
88 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26,
89 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77,
90 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153,
91 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215,
92 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34,
93 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80,
94 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210,
95 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148,
96 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226,
97 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46,
98 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89,
99 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250,
100 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164,
101 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158
102};
103
104static const unsigned char FSb2[256] =
105{
106 224, 5, 88, 217, 103, 78, 129, 203, 201, 11, 174, 106, 213, 24, 93, 130,
107 70, 223, 214, 39, 138, 50, 75, 66, 219, 28, 158, 156, 58, 202, 37, 123,
108 13, 113, 95, 31, 248, 215, 62, 157, 124, 96, 185, 190, 188, 139, 22, 52,
109 77, 195, 114, 149, 171, 142, 186, 122, 179, 2, 180, 173, 162, 172, 216, 154,
110 23, 26, 53, 204, 247, 153, 97, 90, 232, 36, 86, 64, 225, 99, 9, 51,
111 191, 152, 151, 133, 104, 252, 236, 10, 218, 111, 83, 98, 163, 46, 8, 175,
112 40, 176, 116, 194, 189, 54, 34, 56, 100, 30, 57, 44, 166, 48, 229, 68,
113 253, 136, 159, 101, 135, 107, 244, 35, 72, 16, 209, 81, 192, 249, 210, 160,
114 85, 161, 65, 250, 67, 19, 196, 47, 168, 182, 60, 43, 193, 255, 200, 165,
115 32, 137, 0, 144, 71, 239, 234, 183, 21, 6, 205, 181, 18, 126, 187, 41,
116 15, 184, 7, 4, 155, 148, 33, 102, 230, 206, 237, 231, 59, 254, 127, 197,
117 164, 55, 177, 76, 145, 110, 141, 118, 3, 45, 222, 150, 38, 125, 198, 92,
118 211, 242, 79, 25, 63, 220, 121, 29, 82, 235, 243, 109, 94, 251, 105, 178,
119 240, 49, 12, 212, 207, 140, 226, 117, 169, 74, 87, 132, 17, 69, 27, 245,
120 228, 14, 115, 170, 241, 221, 89, 20, 108, 146, 84, 208, 120, 112, 227, 73,
121 128, 80, 167, 246, 119, 147, 134, 131, 42, 199, 91, 233, 238, 143, 1, 61
122};
123
124static const unsigned char FSb3[256] =
125{
126 56, 65, 22, 118, 217, 147, 96, 242, 114, 194, 171, 154, 117, 6, 87, 160,
127 145, 247, 181, 201, 162, 140, 210, 144, 246, 7, 167, 39, 142, 178, 73, 222,
128 67, 92, 215, 199, 62, 245, 143, 103, 31, 24, 110, 175, 47, 226, 133, 13,
129 83, 240, 156, 101, 234, 163, 174, 158, 236, 128, 45, 107, 168, 43, 54, 166,
130 197, 134, 77, 51, 253, 102, 88, 150, 58, 9, 149, 16, 120, 216, 66, 204,
131 239, 38, 229, 97, 26, 63, 59, 130, 182, 219, 212, 152, 232, 139, 2, 235,
132 10, 44, 29, 176, 111, 141, 136, 14, 25, 135, 78, 11, 169, 12, 121, 17,
133 127, 34, 231, 89, 225, 218, 61, 200, 18, 4, 116, 84, 48, 126, 180, 40,
134 85, 104, 80, 190, 208, 196, 49, 203, 42, 173, 15, 202, 112, 255, 50, 105,
135 8, 98, 0, 36, 209, 251, 186, 237, 69, 129, 115, 109, 132, 159, 238, 74,
136 195, 46, 193, 1, 230, 37, 72, 153, 185, 179, 123, 249, 206, 191, 223, 113,
137 41, 205, 108, 19, 100, 155, 99, 157, 192, 75, 183, 165, 137, 95, 177, 23,
138 244, 188, 211, 70, 207, 55, 94, 71, 148, 250, 252, 91, 151, 254, 90, 172,
139 60, 76, 3, 53, 243, 35, 184, 93, 106, 146, 213, 33, 68, 81, 198, 125,
140 57, 131, 220, 170, 124, 119, 86, 5, 27, 164, 21, 52, 30, 28, 248, 82,
141 32, 20, 233, 189, 221, 228, 161, 224, 138, 241, 214, 122, 187, 227, 64, 79
142};
143
144static const unsigned char FSb4[256] =
145{
146 112, 44, 179, 192, 228, 87, 234, 174, 35, 107, 69, 165, 237, 79, 29, 146,
147 134, 175, 124, 31, 62, 220, 94, 11, 166, 57, 213, 93, 217, 90, 81, 108,
148 139, 154, 251, 176, 116, 43, 240, 132, 223, 203, 52, 118, 109, 169, 209, 4,
149 20, 58, 222, 17, 50, 156, 83, 242, 254, 207, 195, 122, 36, 232, 96, 105,
150 170, 160, 161, 98, 84, 30, 224, 100, 16, 0, 163, 117, 138, 230, 9, 221,
151 135, 131, 205, 144, 115, 246, 157, 191, 82, 216, 200, 198, 129, 111, 19, 99,
152 233, 167, 159, 188, 41, 249, 47, 180, 120, 6, 231, 113, 212, 171, 136, 141,
153 114, 185, 248, 172, 54, 42, 60, 241, 64, 211, 187, 67, 21, 173, 119, 128,
154 130, 236, 39, 229, 133, 53, 12, 65, 239, 147, 25, 33, 14, 78, 101, 189,
155 184, 143, 235, 206, 48, 95, 197, 26, 225, 202, 71, 61, 1, 214, 86, 77,
156 13, 102, 204, 45, 18, 32, 177, 153, 76, 194, 126, 5, 183, 49, 23, 215,
157 88, 97, 27, 28, 15, 22, 24, 34, 68, 178, 181, 145, 8, 168, 252, 80,
158 208, 125, 137, 151, 91, 149, 255, 210, 196, 72, 247, 219, 3, 218, 63, 148,
159 92, 2, 74, 51, 103, 243, 127, 226, 155, 38, 55, 59, 150, 75, 190, 46,
160 121, 140, 110, 142, 245, 182, 253, 89, 152, 106, 70, 186, 37, 66, 162, 250,
161 7, 85, 238, 10, 73, 104, 56, 164, 40, 123, 201, 193, 227, 244, 199, 158
162};
163
164#define SBOX1(n) FSb[(n)]
165#define SBOX2(n) FSb2[(n)]
166#define SBOX3(n) FSb3[(n)]
167#define SBOX4(n) FSb4[(n)]
168
169#endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
170
171static const unsigned char shifts[2][4][4] =
172{
173 {
174 { 1, 1, 1, 1 }, /* KL */
175 { 0, 0, 0, 0 }, /* KR */
176 { 1, 1, 1, 1 }, /* KA */
177 { 0, 0, 0, 0 } /* KB */
178 },
179 {
180 { 1, 0, 1, 1 }, /* KL */
181 { 1, 1, 0, 1 }, /* KR */
182 { 1, 1, 1, 0 }, /* KA */
183 { 1, 1, 0, 1 } /* KB */
184 }
185};
186
187static const signed char indexes[2][4][20] =
188{
189 {
190 { 0, 1, 2, 3, 8, 9, 10, 11, 38, 39,
191 36, 37, 23, 20, 21, 22, 27, -1, -1, 26 }, /* KL -> RK */
192 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
193 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /* KR -> RK */
194 { 4, 5, 6, 7, 12, 13, 14, 15, 16, 17,
195 18, 19, -1, 24, 25, -1, 31, 28, 29, 30 }, /* KA -> RK */
196 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
197 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } /* KB -> RK */
198 },
199 {
200 { 0, 1, 2, 3, 61, 62, 63, 60, -1, -1,
201 -1, -1, 27, 24, 25, 26, 35, 32, 33, 34 }, /* KL -> RK */
202 { -1, -1, -1, -1, 8, 9, 10, 11, 16, 17,
203 18, 19, -1, -1, -1, -1, 39, 36, 37, 38 }, /* KR -> RK */
204 { -1, -1, -1, -1, 12, 13, 14, 15, 58, 59,
205 56, 57, 31, 28, 29, 30, -1, -1, -1, -1 }, /* KA -> RK */
206 { 4, 5, 6, 7, 65, 66, 67, 64, 20, 21,
207 22, 23, -1, -1, -1, -1, 43, 40, 41, 42 } /* KB -> RK */
208 }
209};
210
211static const signed char transposes[2][20] =
212{
213 {
214 21, 22, 23, 20,
215 -1, -1, -1, -1,
216 18, 19, 16, 17,
217 11, 8, 9, 10,
218 15, 12, 13, 14
219 },
220 {
221 25, 26, 27, 24,
222 29, 30, 31, 28,
223 18, 19, 16, 17,
224 -1, -1, -1, -1,
225 -1, -1, -1, -1
226 }
227};
228
229/* Shift macro for 128 bit strings with rotation smaller than 32 bits (!) */
230#define ROTL(DEST, SRC, SHIFT) \
231 { \
232 (DEST)[0] = (SRC)[0] << (SHIFT) ^ (SRC)[1] >> (32 - (SHIFT)); \
233 (DEST)[1] = (SRC)[1] << (SHIFT) ^ (SRC)[2] >> (32 - (SHIFT)); \
234 (DEST)[2] = (SRC)[2] << (SHIFT) ^ (SRC)[3] >> (32 - (SHIFT)); \
235 (DEST)[3] = (SRC)[3] << (SHIFT) ^ (SRC)[0] >> (32 - (SHIFT)); \
236 }
237
238#define FL(XL, XR, KL, KR) \
239 { \
240 (XR) = ((((XL) &(KL)) << 1) | (((XL) &(KL)) >> 31)) ^ (XR); \
241 (XL) = ((XR) | (KR)) ^ (XL); \
242 }
243
244#define FLInv(YL, YR, KL, KR) \
245 { \
246 (YL) = ((YR) | (KR)) ^ (YL); \
247 (YR) = ((((YL) &(KL)) << 1) | (((YL) &(KL)) >> 31)) ^ (YR); \
248 }
249
250#define SHIFT_AND_PLACE(INDEX, OFFSET) \
251 { \
252 TK[0] = KC[(OFFSET) * 4 + 0]; \
253 TK[1] = KC[(OFFSET) * 4 + 1]; \
254 TK[2] = KC[(OFFSET) * 4 + 2]; \
255 TK[3] = KC[(OFFSET) * 4 + 3]; \
256 \
257 for (i = 1; i <= 4; i++) \
258 if (shifts[(INDEX)][(OFFSET)][i -1]) \
259 ROTL(TK + i * 4, TK, (15 * i) % 32); \
260 \
261 for (i = 0; i < 20; i++) \
262 if (indexes[(INDEX)][(OFFSET)][i] != -1) { \
263 RK[indexes[(INDEX)][(OFFSET)][i]] = TK[i]; \
264 } \
265 }
266
267static void camellia_feistel(const uint32_t x[2], const uint32_t k[2],
268 uint32_t z[2])
269{
270 uint32_t I0, I1;
271 I0 = x[0] ^ k[0];
272 I1 = x[1] ^ k[1];
273
274 I0 = ((uint32_t) SBOX1(MBEDTLS_BYTE_3(I0)) << 24) |
275 ((uint32_t) SBOX2(MBEDTLS_BYTE_2(I0)) << 16) |
276 ((uint32_t) SBOX3(MBEDTLS_BYTE_1(I0)) << 8) |
277 ((uint32_t) SBOX4(MBEDTLS_BYTE_0(I0)));
278 I1 = ((uint32_t) SBOX2(MBEDTLS_BYTE_3(I1)) << 24) |
279 ((uint32_t) SBOX3(MBEDTLS_BYTE_2(I1)) << 16) |
280 ((uint32_t) SBOX4(MBEDTLS_BYTE_1(I1)) << 8) |
281 ((uint32_t) SBOX1(MBEDTLS_BYTE_0(I1)));
282
283 I0 ^= (I1 << 8) | (I1 >> 24);
284 I1 ^= (I0 << 16) | (I0 >> 16);
285 I0 ^= (I1 >> 8) | (I1 << 24);
286 I1 ^= (I0 >> 8) | (I0 << 24);
287
288 z[0] ^= I1;
289 z[1] ^= I0;
290}
291
292void mbedtls_camellia_init(mbedtls_camellia_context *ctx)
293{
294 CAMELLIA_VALIDATE(ctx != NULL);
295 memset(ctx, 0, sizeof(mbedtls_camellia_context));
296}
297
298void mbedtls_camellia_free(mbedtls_camellia_context *ctx)
299{
300 if (ctx == NULL) {
301 return;
302 }
303
304 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_camellia_context));
305}
306
307/*
308 * Camellia key schedule (encryption)
309 */
310int mbedtls_camellia_setkey_enc(mbedtls_camellia_context *ctx,
311 const unsigned char *key,
312 unsigned int keybits)
313{
314 int idx;
315 size_t i;
316 uint32_t *RK;
317 unsigned char t[64];
318 uint32_t SIGMA[6][2];
319 uint32_t KC[16];
320 uint32_t TK[20];
321
322 CAMELLIA_VALIDATE_RET(ctx != NULL);
323 CAMELLIA_VALIDATE_RET(key != NULL);
324
325 RK = ctx->rk;
326
327 memset(t, 0, 64);
328 memset(RK, 0, sizeof(ctx->rk));
329
330 switch (keybits) {
331 case 128: ctx->nr = 3; idx = 0; break;
332 case 192:
333 case 256: ctx->nr = 4; idx = 1; break;
334 default: return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
335 }
336
337 for (i = 0; i < keybits / 8; ++i) {
338 t[i] = key[i];
339 }
340
341 if (keybits == 192) {
342 for (i = 0; i < 8; i++) {
343 t[24 + i] = ~t[16 + i];
344 }
345 }
346
347 /*
348 * Prepare SIGMA values
349 */
350 for (i = 0; i < 6; i++) {
351 SIGMA[i][0] = MBEDTLS_GET_UINT32_BE(SIGMA_CHARS[i], 0);
352 SIGMA[i][1] = MBEDTLS_GET_UINT32_BE(SIGMA_CHARS[i], 4);
353 }
354
355 /*
356 * Key storage in KC
357 * Order: KL, KR, KA, KB
358 */
359 memset(KC, 0, sizeof(KC));
360
361 /* Store KL, KR */
362 for (i = 0; i < 8; i++) {
363 KC[i] = MBEDTLS_GET_UINT32_BE(t, i * 4);
364 }
365
366 /* Generate KA */
367 for (i = 0; i < 4; ++i) {
368 KC[8 + i] = KC[i] ^ KC[4 + i];
369 }
370
371 camellia_feistel(KC + 8, SIGMA[0], KC + 10);
372 camellia_feistel(KC + 10, SIGMA[1], KC + 8);
373
374 for (i = 0; i < 4; ++i) {
375 KC[8 + i] ^= KC[i];
376 }
377
378 camellia_feistel(KC + 8, SIGMA[2], KC + 10);
379 camellia_feistel(KC + 10, SIGMA[3], KC + 8);
380
381 if (keybits > 128) {
382 /* Generate KB */
383 for (i = 0; i < 4; ++i) {
384 KC[12 + i] = KC[4 + i] ^ KC[8 + i];
385 }
386
387 camellia_feistel(KC + 12, SIGMA[4], KC + 14);
388 camellia_feistel(KC + 14, SIGMA[5], KC + 12);
389 }
390
391 /*
392 * Generating subkeys
393 */
394
395 /* Manipulating KL */
396 SHIFT_AND_PLACE(idx, 0);
397
398 /* Manipulating KR */
399 if (keybits > 128) {
400 SHIFT_AND_PLACE(idx, 1);
401 }
402
403 /* Manipulating KA */
404 SHIFT_AND_PLACE(idx, 2);
405
406 /* Manipulating KB */
407 if (keybits > 128) {
408 SHIFT_AND_PLACE(idx, 3);
409 }
410
411 /* Do transpositions */
412 for (i = 0; i < 20; i++) {
413 if (transposes[idx][i] != -1) {
414 RK[32 + 12 * idx + i] = RK[transposes[idx][i]];
415 }
416 }
417
418 return 0;
419}
420
421/*
422 * Camellia key schedule (decryption)
423 */
424int mbedtls_camellia_setkey_dec(mbedtls_camellia_context *ctx,
425 const unsigned char *key,
426 unsigned int keybits)
427{
428 int idx, ret;
429 size_t i;
430 mbedtls_camellia_context cty;
431 uint32_t *RK;
432 uint32_t *SK;
433 CAMELLIA_VALIDATE_RET(ctx != NULL);
434 CAMELLIA_VALIDATE_RET(key != NULL);
435
436 mbedtls_camellia_init(&cty);
437
438 /* Also checks keybits */
439 if ((ret = mbedtls_camellia_setkey_enc(&cty, key, keybits)) != 0) {
440 goto exit;
441 }
442
443 ctx->nr = cty.nr;
444 idx = (ctx->nr == 4);
445
446 RK = ctx->rk;
447 SK = cty.rk + 24 * 2 + 8 * idx * 2;
448
449 *RK++ = *SK++;
450 *RK++ = *SK++;
451 *RK++ = *SK++;
452 *RK++ = *SK++;
453
454 for (i = 22 + 8 * idx, SK -= 6; i > 0; i--, SK -= 4) {
455 *RK++ = *SK++;
456 *RK++ = *SK++;
457 }
458
459 SK -= 2;
460
461 *RK++ = *SK++;
462 *RK++ = *SK++;
463 *RK++ = *SK++;
464 *RK++ = *SK++;
465
466exit:
467 mbedtls_camellia_free(&cty);
468
469 return ret;
470}
471
472/*
473 * Camellia-ECB block encryption/decryption
474 */
475int mbedtls_camellia_crypt_ecb(mbedtls_camellia_context *ctx,
476 int mode,
477 const unsigned char input[16],
478 unsigned char output[16])
479{
480 int NR;
481 uint32_t *RK, X[4];
482 CAMELLIA_VALIDATE_RET(ctx != NULL);
483 CAMELLIA_VALIDATE_RET(mode == MBEDTLS_CAMELLIA_ENCRYPT ||
484 mode == MBEDTLS_CAMELLIA_DECRYPT);
485 CAMELLIA_VALIDATE_RET(input != NULL);
486 CAMELLIA_VALIDATE_RET(output != NULL);
487
488 ((void) mode);
489
490 NR = ctx->nr;
491 RK = ctx->rk;
492
493 X[0] = MBEDTLS_GET_UINT32_BE(input, 0);
494 X[1] = MBEDTLS_GET_UINT32_BE(input, 4);
495 X[2] = MBEDTLS_GET_UINT32_BE(input, 8);
496 X[3] = MBEDTLS_GET_UINT32_BE(input, 12);
497
498 X[0] ^= *RK++;
499 X[1] ^= *RK++;
500 X[2] ^= *RK++;
501 X[3] ^= *RK++;
502
503 while (NR) {
504 --NR;
505 camellia_feistel(X, RK, X + 2);
506 RK += 2;
507 camellia_feistel(X + 2, RK, X);
508 RK += 2;
509 camellia_feistel(X, RK, X + 2);
510 RK += 2;
511 camellia_feistel(X + 2, RK, X);
512 RK += 2;
513 camellia_feistel(X, RK, X + 2);
514 RK += 2;
515 camellia_feistel(X + 2, RK, X);
516 RK += 2;
517
518 if (NR) {
519 FL(X[0], X[1], RK[0], RK[1]);
520 RK += 2;
521 FLInv(X[2], X[3], RK[0], RK[1]);
522 RK += 2;
523 }
524 }
525
526 X[2] ^= *RK++;
527 X[3] ^= *RK++;
528 X[0] ^= *RK++;
529 X[1] ^= *RK++;
530
531 MBEDTLS_PUT_UINT32_BE(X[2], output, 0);
532 MBEDTLS_PUT_UINT32_BE(X[3], output, 4);
533 MBEDTLS_PUT_UINT32_BE(X[0], output, 8);
534 MBEDTLS_PUT_UINT32_BE(X[1], output, 12);
535
536 return 0;
537}
538
539#if defined(MBEDTLS_CIPHER_MODE_CBC)
540/*
541 * Camellia-CBC buffer encryption/decryption
542 */
543int mbedtls_camellia_crypt_cbc(mbedtls_camellia_context *ctx,
544 int mode,
545 size_t length,
546 unsigned char iv[16],
547 const unsigned char *input,
548 unsigned char *output)
549{
550 int i;
551 unsigned char temp[16];
552 CAMELLIA_VALIDATE_RET(ctx != NULL);
553 CAMELLIA_VALIDATE_RET(mode == MBEDTLS_CAMELLIA_ENCRYPT ||
554 mode == MBEDTLS_CAMELLIA_DECRYPT);
555 CAMELLIA_VALIDATE_RET(iv != NULL);
556 CAMELLIA_VALIDATE_RET(length == 0 || input != NULL);
557 CAMELLIA_VALIDATE_RET(length == 0 || output != NULL);
558
559 if (length % 16) {
560 return MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH;
561 }
562
563 if (mode == MBEDTLS_CAMELLIA_DECRYPT) {
564 while (length > 0) {
565 memcpy(temp, input, 16);
566 mbedtls_camellia_crypt_ecb(ctx, mode, input, output);
567
568 for (i = 0; i < 16; i++) {
569 output[i] = (unsigned char) (output[i] ^ iv[i]);
570 }
571
572 memcpy(iv, temp, 16);
573
574 input += 16;
575 output += 16;
576 length -= 16;
577 }
578 } else {
579 while (length > 0) {
580 for (i = 0; i < 16; i++) {
581 output[i] = (unsigned char) (input[i] ^ iv[i]);
582 }
583
584 mbedtls_camellia_crypt_ecb(ctx, mode, output, output);
585 memcpy(iv, output, 16);
586
587 input += 16;
588 output += 16;
589 length -= 16;
590 }
591 }
592
593 return 0;
594}
595#endif /* MBEDTLS_CIPHER_MODE_CBC */
596
597#if defined(MBEDTLS_CIPHER_MODE_CFB)
598/*
599 * Camellia-CFB128 buffer encryption/decryption
600 */
601int mbedtls_camellia_crypt_cfb128(mbedtls_camellia_context *ctx,
602 int mode,
603 size_t length,
604 size_t *iv_off,
605 unsigned char iv[16],
606 const unsigned char *input,
607 unsigned char *output)
608{
609 int c;
610 size_t n;
611 CAMELLIA_VALIDATE_RET(ctx != NULL);
612 CAMELLIA_VALIDATE_RET(mode == MBEDTLS_CAMELLIA_ENCRYPT ||
613 mode == MBEDTLS_CAMELLIA_DECRYPT);
614 CAMELLIA_VALIDATE_RET(iv != NULL);
615 CAMELLIA_VALIDATE_RET(iv_off != NULL);
616 CAMELLIA_VALIDATE_RET(length == 0 || input != NULL);
617 CAMELLIA_VALIDATE_RET(length == 0 || output != NULL);
618
619 n = *iv_off;
620 if (n >= 16) {
621 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
622 }
623
624 if (mode == MBEDTLS_CAMELLIA_DECRYPT) {
625 while (length--) {
626 if (n == 0) {
627 mbedtls_camellia_crypt_ecb(ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv);
628 }
629
630 c = *input++;
631 *output++ = (unsigned char) (c ^ iv[n]);
632 iv[n] = (unsigned char) c;
633
634 n = (n + 1) & 0x0F;
635 }
636 } else {
637 while (length--) {
638 if (n == 0) {
639 mbedtls_camellia_crypt_ecb(ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv);
640 }
641
642 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
643
644 n = (n + 1) & 0x0F;
645 }
646 }
647
648 *iv_off = n;
649
650 return 0;
651}
652#endif /* MBEDTLS_CIPHER_MODE_CFB */
653
654#if defined(MBEDTLS_CIPHER_MODE_CTR)
655/*
656 * Camellia-CTR buffer encryption/decryption
657 */
658int mbedtls_camellia_crypt_ctr(mbedtls_camellia_context *ctx,
659 size_t length,
660 size_t *nc_off,
661 unsigned char nonce_counter[16],
662 unsigned char stream_block[16],
663 const unsigned char *input,
664 unsigned char *output)
665{
666 int c, i;
667 size_t n;
668 CAMELLIA_VALIDATE_RET(ctx != NULL);
669 CAMELLIA_VALIDATE_RET(nonce_counter != NULL);
670 CAMELLIA_VALIDATE_RET(stream_block != NULL);
671 CAMELLIA_VALIDATE_RET(nc_off != NULL);
672 CAMELLIA_VALIDATE_RET(length == 0 || input != NULL);
673 CAMELLIA_VALIDATE_RET(length == 0 || output != NULL);
674
675 n = *nc_off;
676 if (n >= 16) {
677 return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA;
678 }
679
680 while (length--) {
681 if (n == 0) {
682 mbedtls_camellia_crypt_ecb(ctx, MBEDTLS_CAMELLIA_ENCRYPT, nonce_counter,
683 stream_block);
684
685 for (i = 16; i > 0; i--) {
686 if (++nonce_counter[i - 1] != 0) {
687 break;
688 }
689 }
690 }
691 c = *input++;
692 *output++ = (unsigned char) (c ^ stream_block[n]);
693
694 n = (n + 1) & 0x0F;
695 }
696
697 *nc_off = n;
698
699 return 0;
700}
701#endif /* MBEDTLS_CIPHER_MODE_CTR */
702#endif /* !MBEDTLS_CAMELLIA_ALT */
703
704#if defined(MBEDTLS_SELF_TEST)
705
706/*
707 * Camellia test vectors from:
708 *
709 * http://info.isl.ntt.co.jp/crypt/eng/camellia/technology.html:
710 * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/intermediate.txt
711 * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/t_camellia.txt
712 * (For each bitlength: Key 0, Nr 39)
713 */
714#define CAMELLIA_TESTS_ECB 2
715
716static const unsigned char camellia_test_ecb_key[3][CAMELLIA_TESTS_ECB][32] =
717{
718 {
719 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
720 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
721 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
722 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
723 },
724 {
725 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
726 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
727 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
728 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
729 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
730 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
731 },
732 {
733 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
734 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
735 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
736 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
737 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
738 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
739 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
740 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
741 },
742};
743
744static const unsigned char camellia_test_ecb_plain[CAMELLIA_TESTS_ECB][16] =
745{
746 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
747 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
748 { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
749 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
750};
751
752static const unsigned char camellia_test_ecb_cipher[3][CAMELLIA_TESTS_ECB][16] =
753{
754 {
755 { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73,
756 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 },
757 { 0x38, 0x3C, 0x6C, 0x2A, 0xAB, 0xEF, 0x7F, 0xDE,
758 0x25, 0xCD, 0x47, 0x0B, 0xF7, 0x74, 0xA3, 0x31 }
759 },
760 {
761 { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8,
762 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 },
763 { 0xD1, 0x76, 0x3F, 0xC0, 0x19, 0xD7, 0x7C, 0xC9,
764 0x30, 0xBF, 0xF2, 0xA5, 0x6F, 0x7C, 0x93, 0x64 }
765 },
766 {
767 { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c,
768 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 },
769 { 0x05, 0x03, 0xFB, 0x10, 0xAB, 0x24, 0x1E, 0x7C,
770 0xF4, 0x5D, 0x8C, 0xDE, 0xEE, 0x47, 0x43, 0x35 }
771 }
772};
773
774#if defined(MBEDTLS_CIPHER_MODE_CBC)
775#define CAMELLIA_TESTS_CBC 3
776
777static const unsigned char camellia_test_cbc_key[3][32] =
778{
779 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
780 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }
781 ,
782 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
783 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
784 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }
785 ,
786 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
787 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
788 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
789 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
790};
791
792static const unsigned char camellia_test_cbc_iv[16] =
793
794{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
795 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }
796;
797
798static const unsigned char camellia_test_cbc_plain[CAMELLIA_TESTS_CBC][16] =
799{
800 { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
801 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A },
802 { 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
803 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51 },
804 { 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
805 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF }
806
807};
808
809static const unsigned char camellia_test_cbc_cipher[3][CAMELLIA_TESTS_CBC][16] =
810{
811 {
812 { 0x16, 0x07, 0xCF, 0x49, 0x4B, 0x36, 0xBB, 0xF0,
813 0x0D, 0xAE, 0xB0, 0xB5, 0x03, 0xC8, 0x31, 0xAB },
814 { 0xA2, 0xF2, 0xCF, 0x67, 0x16, 0x29, 0xEF, 0x78,
815 0x40, 0xC5, 0xA5, 0xDF, 0xB5, 0x07, 0x48, 0x87 },
816 { 0x0F, 0x06, 0x16, 0x50, 0x08, 0xCF, 0x8B, 0x8B,
817 0x5A, 0x63, 0x58, 0x63, 0x62, 0x54, 0x3E, 0x54 }
818 },
819 {
820 { 0x2A, 0x48, 0x30, 0xAB, 0x5A, 0xC4, 0xA1, 0xA2,
821 0x40, 0x59, 0x55, 0xFD, 0x21, 0x95, 0xCF, 0x93 },
822 { 0x5D, 0x5A, 0x86, 0x9B, 0xD1, 0x4C, 0xE5, 0x42,
823 0x64, 0xF8, 0x92, 0xA6, 0xDD, 0x2E, 0xC3, 0xD5 },
824 { 0x37, 0xD3, 0x59, 0xC3, 0x34, 0x98, 0x36, 0xD8,
825 0x84, 0xE3, 0x10, 0xAD, 0xDF, 0x68, 0xC4, 0x49 }
826 },
827 {
828 { 0xE6, 0xCF, 0xA3, 0x5F, 0xC0, 0x2B, 0x13, 0x4A,
829 0x4D, 0x2C, 0x0B, 0x67, 0x37, 0xAC, 0x3E, 0xDA },
830 { 0x36, 0xCB, 0xEB, 0x73, 0xBD, 0x50, 0x4B, 0x40,
831 0x70, 0xB1, 0xB7, 0xDE, 0x2B, 0x21, 0xEB, 0x50 },
832 { 0xE3, 0x1A, 0x60, 0x55, 0x29, 0x7D, 0x96, 0xCA,
833 0x33, 0x30, 0xCD, 0xF1, 0xB1, 0x86, 0x0A, 0x83 }
834 }
835};
836#endif /* MBEDTLS_CIPHER_MODE_CBC */
837
838#if defined(MBEDTLS_CIPHER_MODE_CTR)
839/*
840 * Camellia-CTR test vectors from:
841 *
842 * http://www.faqs.org/rfcs/rfc5528.html
843 */
844
845static const unsigned char camellia_test_ctr_key[3][16] =
846{
847 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
848 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
849 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
850 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
851 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
852 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
853};
854
855static const unsigned char camellia_test_ctr_nonce_counter[3][16] =
856{
857 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
858 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
859 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
860 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
861 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
862 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
863};
864
865static const unsigned char camellia_test_ctr_pt[3][48] =
866{
867 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
868 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
869
870 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
871 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
872 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
873 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
874
875 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
876 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
877 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
878 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
879 0x20, 0x21, 0x22, 0x23 }
880};
881
882static const unsigned char camellia_test_ctr_ct[3][48] =
883{
884 { 0xD0, 0x9D, 0xC2, 0x9A, 0x82, 0x14, 0x61, 0x9A,
885 0x20, 0x87, 0x7C, 0x76, 0xDB, 0x1F, 0x0B, 0x3F },
886 { 0xDB, 0xF3, 0xC7, 0x8D, 0xC0, 0x83, 0x96, 0xD4,
887 0xDA, 0x7C, 0x90, 0x77, 0x65, 0xBB, 0xCB, 0x44,
888 0x2B, 0x8E, 0x8E, 0x0F, 0x31, 0xF0, 0xDC, 0xA7,
889 0x2C, 0x74, 0x17, 0xE3, 0x53, 0x60, 0xE0, 0x48 },
890 { 0xB1, 0x9D, 0x1F, 0xCD, 0xCB, 0x75, 0xEB, 0x88,
891 0x2F, 0x84, 0x9C, 0xE2, 0x4D, 0x85, 0xCF, 0x73,
892 0x9C, 0xE6, 0x4B, 0x2B, 0x5C, 0x9D, 0x73, 0xF1,
893 0x4F, 0x2D, 0x5D, 0x9D, 0xCE, 0x98, 0x89, 0xCD,
894 0xDF, 0x50, 0x86, 0x96 }
895};
896
897static const int camellia_test_ctr_len[3] =
898{ 16, 32, 36 };
899#endif /* MBEDTLS_CIPHER_MODE_CTR */
900
901/*
902 * Checkup routine
903 */
904int mbedtls_camellia_self_test(int verbose)
905{
906 int i, j, u, v;
907 unsigned char key[32];
908 unsigned char buf[64];
909 unsigned char src[16];
910 unsigned char dst[16];
911#if defined(MBEDTLS_CIPHER_MODE_CBC)
912 unsigned char iv[16];
913#endif
914#if defined(MBEDTLS_CIPHER_MODE_CTR)
915 size_t offset, len;
916 unsigned char nonce_counter[16];
917 unsigned char stream_block[16];
918#endif
919 int ret = 1;
920
921 mbedtls_camellia_context ctx;
922
923 mbedtls_camellia_init(&ctx);
924 memset(key, 0, 32);
925
926 for (j = 0; j < 6; j++) {
927 u = j >> 1;
928 v = j & 1;
929
930 if (verbose != 0) {
931 mbedtls_printf(" CAMELLIA-ECB-%3d (%s): ", 128 + u * 64,
932 (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
933 }
934
935 for (i = 0; i < CAMELLIA_TESTS_ECB; i++) {
936 memcpy(key, camellia_test_ecb_key[u][i], 16 + 8 * u);
937
938 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
939 mbedtls_camellia_setkey_dec(&ctx, key, 128 + u * 64);
940 memcpy(src, camellia_test_ecb_cipher[u][i], 16);
941 memcpy(dst, camellia_test_ecb_plain[i], 16);
942 } else { /* MBEDTLS_CAMELLIA_ENCRYPT */
943 mbedtls_camellia_setkey_enc(&ctx, key, 128 + u * 64);
944 memcpy(src, camellia_test_ecb_plain[i], 16);
945 memcpy(dst, camellia_test_ecb_cipher[u][i], 16);
946 }
947
948 mbedtls_camellia_crypt_ecb(&ctx, v, src, buf);
949
950 if (memcmp(buf, dst, 16) != 0) {
951 if (verbose != 0) {
952 mbedtls_printf("failed\n");
953 }
954 goto exit;
955 }
956 }
957
958 if (verbose != 0) {
959 mbedtls_printf("passed\n");
960 }
961 }
962
963 if (verbose != 0) {
964 mbedtls_printf("\n");
965 }
966
967#if defined(MBEDTLS_CIPHER_MODE_CBC)
968 /*
969 * CBC mode
970 */
971 for (j = 0; j < 6; j++) {
972 u = j >> 1;
973 v = j & 1;
974
975 if (verbose != 0) {
976 mbedtls_printf(" CAMELLIA-CBC-%3d (%s): ", 128 + u * 64,
977 (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
978 }
979
980 memcpy(src, camellia_test_cbc_iv, 16);
981 memcpy(dst, camellia_test_cbc_iv, 16);
982 memcpy(key, camellia_test_cbc_key[u], 16 + 8 * u);
983
984 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
985 mbedtls_camellia_setkey_dec(&ctx, key, 128 + u * 64);
986 } else {
987 mbedtls_camellia_setkey_enc(&ctx, key, 128 + u * 64);
988 }
989
990 for (i = 0; i < CAMELLIA_TESTS_CBC; i++) {
991
992 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
993 memcpy(iv, src, 16);
994 memcpy(src, camellia_test_cbc_cipher[u][i], 16);
995 memcpy(dst, camellia_test_cbc_plain[i], 16);
996 } else { /* MBEDTLS_CAMELLIA_ENCRYPT */
997 memcpy(iv, dst, 16);
998 memcpy(src, camellia_test_cbc_plain[i], 16);
999 memcpy(dst, camellia_test_cbc_cipher[u][i], 16);
1000 }
1001
1002 mbedtls_camellia_crypt_cbc(&ctx, v, 16, iv, src, buf);
1003
1004 if (memcmp(buf, dst, 16) != 0) {
1005 if (verbose != 0) {
1006 mbedtls_printf("failed\n");
1007 }
1008 goto exit;
1009 }
1010 }
1011
1012 if (verbose != 0) {
1013 mbedtls_printf("passed\n");
1014 }
1015 }
1016#endif /* MBEDTLS_CIPHER_MODE_CBC */
1017
1018 if (verbose != 0) {
1019 mbedtls_printf("\n");
1020 }
1021
1022#if defined(MBEDTLS_CIPHER_MODE_CTR)
1023 /*
1024 * CTR mode
1025 */
1026 for (i = 0; i < 6; i++) {
1027 u = i >> 1;
1028 v = i & 1;
1029
1030 if (verbose != 0) {
1031 mbedtls_printf(" CAMELLIA-CTR-128 (%s): ",
1032 (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
1033 }
1034
1035 memcpy(nonce_counter, camellia_test_ctr_nonce_counter[u], 16);
1036 memcpy(key, camellia_test_ctr_key[u], 16);
1037
1038 offset = 0;
1039 mbedtls_camellia_setkey_enc(&ctx, key, 128);
1040
1041 if (v == MBEDTLS_CAMELLIA_DECRYPT) {
1042 len = camellia_test_ctr_len[u];
1043 memcpy(buf, camellia_test_ctr_ct[u], len);
1044
1045 mbedtls_camellia_crypt_ctr(&ctx, len, &offset, nonce_counter, stream_block,
1046 buf, buf);
1047
1048 if (memcmp(buf, camellia_test_ctr_pt[u], len) != 0) {
1049 if (verbose != 0) {
1050 mbedtls_printf("failed\n");
1051 }
1052 goto exit;
1053 }
1054 } else {
1055 len = camellia_test_ctr_len[u];
1056 memcpy(buf, camellia_test_ctr_pt[u], len);
1057
1058 mbedtls_camellia_crypt_ctr(&ctx, len, &offset, nonce_counter, stream_block,
1059 buf, buf);
1060
1061 if (memcmp(buf, camellia_test_ctr_ct[u], len) != 0) {
1062 if (verbose != 0) {
1063 mbedtls_printf("failed\n");
1064 }
1065 goto exit;
1066 }
1067 }
1068
1069 if (verbose != 0) {
1070 mbedtls_printf("passed\n");
1071 }
1072 }
1073
1074 if (verbose != 0) {
1075 mbedtls_printf("\n");
1076 }
1077#endif /* MBEDTLS_CIPHER_MODE_CTR */
1078
1079 ret = 0;
1080
1081exit:
1082 mbedtls_camellia_free(&ctx);
1083 return ret;
1084}
1085
1086#endif /* MBEDTLS_SELF_TEST */
1087
1088#endif /* MBEDTLS_CAMELLIA_C */
1089