blob: 89001bd152af1171b3223d86c64a2811a4f019e5 [file] [log] [blame]
Paul Bakker38119b12009-01-10 23:31:23 +00001/*
2 * Camellia implementation
3 *
Paul Bakker84f12b72010-07-18 10:13:04 +00004 * Copyright (C) 2006-2010, Brainspark B.V.
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
Paul Bakker84f12b72010-07-18 10:13:04 +00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
Paul Bakkerb96f1542010-07-18 20:36:00 +00008 *
Paul Bakker77b385e2009-07-28 17:23:11 +00009 * All rights reserved.
Paul Bakker38119b12009-01-10 23:31:23 +000010 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (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 along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25/*
Paul Bakkerb5ef0ba2009-01-11 20:25:36 +000026 * The Camellia block cipher was designed by NTT and Mitsubishi Electric
27 * Corporation.
Paul Bakker38119b12009-01-10 23:31:23 +000028 *
Paul Bakkerb5ef0ba2009-01-11 20:25:36 +000029 * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/01espec.pdf
Paul Bakker38119b12009-01-10 23:31:23 +000030 */
31
32#include "polarssl/config.h"
33
34#if defined(POLARSSL_CAMELLIA_C)
35
36#include "polarssl/camellia.h"
37
38#include <string.h>
39
Paul Bakker38119b12009-01-10 23:31:23 +000040/*
41 * 32-bit integer manipulation macros (big endian)
42 */
43#ifndef GET_ULONG_BE
44#define GET_ULONG_BE(n,b,i) \
45{ \
46 (n) = ( (unsigned long) (b)[(i) ] << 24 ) \
Paul Bakkerc81f6c32009-05-03 13:09:15 +000047 | ( (unsigned long) (b)[(i) + 1] << 16 ) \
48 | ( (unsigned long) (b)[(i) + 2] << 8 ) \
49 | ( (unsigned long) (b)[(i) + 3] ); \
Paul Bakker38119b12009-01-10 23:31:23 +000050}
51#endif
52
53#ifndef PUT_ULONG_BE
54#define PUT_ULONG_BE(n,b,i) \
55{ \
56 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
57 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
58 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
59 (b)[(i) + 3] = (unsigned char) ( (n) ); \
60}
61#endif
62
63static const unsigned char SIGMA_CHARS[6][8] =
64{
Paul Bakkerc81f6c32009-05-03 13:09:15 +000065 { 0xa0, 0x9e, 0x66, 0x7f, 0x3b, 0xcc, 0x90, 0x8b },
66 { 0xb6, 0x7a, 0xe8, 0x58, 0x4c, 0xaa, 0x73, 0xb2 },
67 { 0xc6, 0xef, 0x37, 0x2f, 0xe9, 0x4f, 0x82, 0xbe },
68 { 0x54, 0xff, 0x53, 0xa5, 0xf1, 0xd3, 0x6f, 0x1c },
69 { 0x10, 0xe5, 0x27, 0xfa, 0xde, 0x68, 0x2d, 0x1d },
70 { 0xb0, 0x56, 0x88, 0xc2, 0xb3, 0xe6, 0xc1, 0xfd }
Paul Bakker38119b12009-01-10 23:31:23 +000071};
72
Paul Bakkerfa049db2009-01-12 22:12:03 +000073#ifdef POLARSSL_CAMELLIA_SMALL_MEMORY
74
75static const unsigned char FSb[256] =
Paul Bakker38119b12009-01-10 23:31:23 +000076{
Paul Bakkerc81f6c32009-05-03 13:09:15 +000077 112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65,
78 35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189,
79 134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26,
80 166,225, 57,202,213, 71, 93, 61,217, 1, 90,214, 81, 86,108, 77,
81 139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153,
82 223, 76,203,194, 52,126,118, 5,109,183,169, 49,209, 23, 4,215,
83 20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34,
84 254, 68,207,178,195,181,122,145, 36, 8,232,168, 96,252,105, 80,
85 170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210,
86 16,196, 0, 72,163,247,117,219,138, 3,230,218, 9, 63,221,148,
87 135, 92,131, 2,205, 74,144, 51,115,103,246,243,157,127,191,226,
88 82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46,
89 233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89,
90 120,152, 6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250,
91 114, 7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164,
92 64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158
Paul Bakker38119b12009-01-10 23:31:23 +000093};
94
95#define SBOX1(n) FSb[(n)]
96#define SBOX2(n) (unsigned char)((FSb[(n)] >> 7 ^ FSb[(n)] << 1) & 0xff)
97#define SBOX3(n) (unsigned char)((FSb[(n)] >> 1 ^ FSb[(n)] << 7) & 0xff)
Paul Bakkerfa049db2009-01-12 22:12:03 +000098#define SBOX4(n) FSb[((n) << 1 ^ (n) >> 7) &0xff]
99
100#else
101
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000102static const unsigned char FSb[256] =
103{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000104 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65,
105 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189,
106 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26,
107 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77,
108 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153,
109 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215,
110 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34,
111 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80,
112 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210,
113 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148,
114 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226,
115 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46,
116 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89,
117 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250,
118 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164,
119 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000120};
121
122static const unsigned char FSb2[256] =
123{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000124 224, 5, 88, 217, 103, 78, 129, 203, 201, 11, 174, 106, 213, 24, 93, 130,
125 70, 223, 214, 39, 138, 50, 75, 66, 219, 28, 158, 156, 58, 202, 37, 123,
126 13, 113, 95, 31, 248, 215, 62, 157, 124, 96, 185, 190, 188, 139, 22, 52,
127 77, 195, 114, 149, 171, 142, 186, 122, 179, 2, 180, 173, 162, 172, 216, 154,
128 23, 26, 53, 204, 247, 153, 97, 90, 232, 36, 86, 64, 225, 99, 9, 51,
129 191, 152, 151, 133, 104, 252, 236, 10, 218, 111, 83, 98, 163, 46, 8, 175,
130 40, 176, 116, 194, 189, 54, 34, 56, 100, 30, 57, 44, 166, 48, 229, 68,
131 253, 136, 159, 101, 135, 107, 244, 35, 72, 16, 209, 81, 192, 249, 210, 160,
132 85, 161, 65, 250, 67, 19, 196, 47, 168, 182, 60, 43, 193, 255, 200, 165,
133 32, 137, 0, 144, 71, 239, 234, 183, 21, 6, 205, 181, 18, 126, 187, 41,
134 15, 184, 7, 4, 155, 148, 33, 102, 230, 206, 237, 231, 59, 254, 127, 197,
135 164, 55, 177, 76, 145, 110, 141, 118, 3, 45, 222, 150, 38, 125, 198, 92,
136 211, 242, 79, 25, 63, 220, 121, 29, 82, 235, 243, 109, 94, 251, 105, 178,
137 240, 49, 12, 212, 207, 140, 226, 117, 169, 74, 87, 132, 17, 69, 27, 245,
138 228, 14, 115, 170, 241, 221, 89, 20, 108, 146, 84, 208, 120, 112, 227, 73,
139 128, 80, 167, 246, 119, 147, 134, 131, 42, 199, 91, 233, 238, 143, 1, 61
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000140};
141
142static const unsigned char FSb3[256] =
143{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000144 56, 65, 22, 118, 217, 147, 96, 242, 114, 194, 171, 154, 117, 6, 87, 160,
145 145, 247, 181, 201, 162, 140, 210, 144, 246, 7, 167, 39, 142, 178, 73, 222,
146 67, 92, 215, 199, 62, 245, 143, 103, 31, 24, 110, 175, 47, 226, 133, 13,
147 83, 240, 156, 101, 234, 163, 174, 158, 236, 128, 45, 107, 168, 43, 54, 166,
148 197, 134, 77, 51, 253, 102, 88, 150, 58, 9, 149, 16, 120, 216, 66, 204,
149 239, 38, 229, 97, 26, 63, 59, 130, 182, 219, 212, 152, 232, 139, 2, 235,
150 10, 44, 29, 176, 111, 141, 136, 14, 25, 135, 78, 11, 169, 12, 121, 17,
151 127, 34, 231, 89, 225, 218, 61, 200, 18, 4, 116, 84, 48, 126, 180, 40,
152 85, 104, 80, 190, 208, 196, 49, 203, 42, 173, 15, 202, 112, 255, 50, 105,
153 8, 98, 0, 36, 209, 251, 186, 237, 69, 129, 115, 109, 132, 159, 238, 74,
154 195, 46, 193, 1, 230, 37, 72, 153, 185, 179, 123, 249, 206, 191, 223, 113,
155 41, 205, 108, 19, 100, 155, 99, 157, 192, 75, 183, 165, 137, 95, 177, 23,
156 244, 188, 211, 70, 207, 55, 94, 71, 148, 250, 252, 91, 151, 254, 90, 172,
157 60, 76, 3, 53, 243, 35, 184, 93, 106, 146, 213, 33, 68, 81, 198, 125,
158 57, 131, 220, 170, 124, 119, 86, 5, 27, 164, 21, 52, 30, 28, 248, 82,
159 32, 20, 233, 189, 221, 228, 161, 224, 138, 241, 214, 122, 187, 227, 64, 79
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000160};
161
162static const unsigned char FSb4[256] =
163{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000164 112, 44, 179, 192, 228, 87, 234, 174, 35, 107, 69, 165, 237, 79, 29, 146,
165 134, 175, 124, 31, 62, 220, 94, 11, 166, 57, 213, 93, 217, 90, 81, 108,
166 139, 154, 251, 176, 116, 43, 240, 132, 223, 203, 52, 118, 109, 169, 209, 4,
167 20, 58, 222, 17, 50, 156, 83, 242, 254, 207, 195, 122, 36, 232, 96, 105,
168 170, 160, 161, 98, 84, 30, 224, 100, 16, 0, 163, 117, 138, 230, 9, 221,
169 135, 131, 205, 144, 115, 246, 157, 191, 82, 216, 200, 198, 129, 111, 19, 99,
170 233, 167, 159, 188, 41, 249, 47, 180, 120, 6, 231, 113, 212, 171, 136, 141,
171 114, 185, 248, 172, 54, 42, 60, 241, 64, 211, 187, 67, 21, 173, 119, 128,
172 130, 236, 39, 229, 133, 53, 12, 65, 239, 147, 25, 33, 14, 78, 101, 189,
173 184, 143, 235, 206, 48, 95, 197, 26, 225, 202, 71, 61, 1, 214, 86, 77,
174 13, 102, 204, 45, 18, 32, 177, 153, 76, 194, 126, 5, 183, 49, 23, 215,
175 88, 97, 27, 28, 15, 22, 24, 34, 68, 178, 181, 145, 8, 168, 252, 80,
176 208, 125, 137, 151, 91, 149, 255, 210, 196, 72, 247, 219, 3, 218, 63, 148,
177 92, 2, 74, 51, 103, 243, 127, 226, 155, 38, 55, 59, 150, 75, 190, 46,
178 121, 140, 110, 142, 245, 182, 253, 89, 152, 106, 70, 186, 37, 66, 162, 250,
179 7, 85, 238, 10, 73, 104, 56, 164, 40, 123, 201, 193, 227, 244, 199, 158
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000180};
181
182#define SBOX1(n) FSb[(n)]
183#define SBOX2(n) FSb2[(n)]
184#define SBOX3(n) FSb3[(n)]
185#define SBOX4(n) FSb4[(n)]
Paul Bakker38119b12009-01-10 23:31:23 +0000186
Paul Bakkerfa049db2009-01-12 22:12:03 +0000187#endif
188
Paul Bakker38119b12009-01-10 23:31:23 +0000189static const unsigned char shifts[2][4][4] =
190{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000191 {
192 { 1, 1, 1, 1 }, /* KL */
193 { 0, 0, 0, 0 }, /* KR */
194 { 1, 1, 1, 1 }, /* KA */
195 { 0, 0, 0, 0 } /* KB */
196 },
197 {
198 { 1, 0, 1, 1 }, /* KL */
199 { 1, 1, 0, 1 }, /* KR */
200 { 1, 1, 1, 0 }, /* KA */
201 { 1, 1, 0, 1 } /* KB */
202 }
Paul Bakker38119b12009-01-10 23:31:23 +0000203};
204
Paul Bakker026c03b2009-03-28 17:53:03 +0000205static const signed char indexes[2][4][20] =
Paul Bakker38119b12009-01-10 23:31:23 +0000206{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000207 {
208 { 0, 1, 2, 3, 8, 9, 10, 11, 38, 39,
209 36, 37, 23, 20, 21, 22, 27, -1, -1, 26 }, /* KL -> RK */
210 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
211 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /* KR -> RK */
212 { 4, 5, 6, 7, 12, 13, 14, 15, 16, 17,
213 18, 19, -1, 24, 25, -1, 31, 28, 29, 30 }, /* KA -> RK */
214 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
215 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } /* KB -> RK */
216 },
217 {
218 { 0, 1, 2, 3, 61, 62, 63, 60, -1, -1,
219 -1, -1, 27, 24, 25, 26, 35, 32, 33, 34 }, /* KL -> RK */
220 { -1, -1, -1, -1, 8, 9, 10, 11, 16, 17,
221 18, 19, -1, -1, -1, -1, 39, 36, 37, 38 }, /* KR -> RK */
222 { -1, -1, -1, -1, 12, 13, 14, 15, 58, 59,
223 56, 57, 31, 28, 29, 30, -1, -1, -1, -1 }, /* KA -> RK */
224 { 4, 5, 6, 7, 65, 66, 67, 64, 20, 21,
225 22, 23, -1, -1, -1, -1, 43, 40, 41, 42 } /* KB -> RK */
226 }
Paul Bakker38119b12009-01-10 23:31:23 +0000227};
228
Paul Bakker026c03b2009-03-28 17:53:03 +0000229static const signed char transposes[2][20] =
Paul Bakker38119b12009-01-10 23:31:23 +0000230{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000231 {
232 21, 22, 23, 20,
233 -1, -1, -1, -1,
234 18, 19, 16, 17,
235 11, 8, 9, 10,
236 15, 12, 13, 14
237 },
238 {
239 25, 26, 27, 24,
240 29, 30, 31, 28,
241 18, 19, 16, 17,
242 -1, -1, -1, -1,
243 -1, -1, -1, -1
244 }
Paul Bakker38119b12009-01-10 23:31:23 +0000245};
246
Paul Bakkerc32c6b52009-01-11 21:36:43 +0000247/* Shift macro for 128 bit strings with rotation smaller than 32 bits (!) */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000248#define ROTL(DEST, SRC, SHIFT) \
249{ \
250 (DEST)[0] = (SRC)[0] << (SHIFT) ^ (SRC)[1] >> (32 - (SHIFT)); \
251 (DEST)[1] = (SRC)[1] << (SHIFT) ^ (SRC)[2] >> (32 - (SHIFT)); \
252 (DEST)[2] = (SRC)[2] << (SHIFT) ^ (SRC)[3] >> (32 - (SHIFT)); \
253 (DEST)[3] = (SRC)[3] << (SHIFT) ^ (SRC)[0] >> (32 - (SHIFT)); \
Paul Bakker38119b12009-01-10 23:31:23 +0000254}
255
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000256#define FL(XL, XR, KL, KR) \
257{ \
258 (XR) = ((((XL) & (KL)) << 1) | (((XL) & (KL)) >> 31)) ^ (XR); \
259 (XL) = ((XR) | (KR)) ^ (XL); \
Paul Bakker38119b12009-01-10 23:31:23 +0000260}
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000261
262#define FLInv(YL, YR, KL, KR) \
263{ \
264 (YL) = ((YR) | (KR)) ^ (YL); \
265 (YR) = ((((YL) & (KL)) << 1) | (((YL) & (KL)) >> 31)) ^ (YR); \
Paul Bakker38119b12009-01-10 23:31:23 +0000266}
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000267
268#define SHIFT_AND_PLACE(INDEX, OFFSET) \
269{ \
270 TK[0] = KC[(OFFSET) * 4 + 0]; \
271 TK[1] = KC[(OFFSET) * 4 + 1]; \
272 TK[2] = KC[(OFFSET) * 4 + 2]; \
273 TK[3] = KC[(OFFSET) * 4 + 3]; \
274 \
275 for ( i = 1; i <= 4; i++ ) \
276 if (shifts[(INDEX)][(OFFSET)][i -1]) \
277 ROTL(TK + i * 4, TK, (15 * i) % 32); \
278 \
279 for ( i = 0; i < 20; i++ ) \
280 if (indexes[(INDEX)][(OFFSET)][i] != -1) { \
281 RK[indexes[(INDEX)][(OFFSET)][i]] = TK[ i ]; \
282 } \
Paul Bakker38119b12009-01-10 23:31:23 +0000283}
284
Paul Bakkerff60ee62010-03-16 21:09:09 +0000285static void camellia_feistel(const uint32_t x[2], const uint32_t k[2], uint32_t z[2])
Paul Bakker38119b12009-01-10 23:31:23 +0000286{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000287 uint32_t I0, I1;
288 I0 = x[0] ^ k[0];
289 I1 = x[1] ^ k[1];
Paul Bakker38119b12009-01-10 23:31:23 +0000290
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000291 I0 = (SBOX1((I0 >> 24) & 0xFF) << 24) |
292 (SBOX2((I0 >> 16) & 0xFF) << 16) |
293 (SBOX3((I0 >> 8) & 0xFF) << 8) |
294 (SBOX4((I0 ) & 0xFF) );
295 I1 = (SBOX2((I1 >> 24) & 0xFF) << 24) |
296 (SBOX3((I1 >> 16) & 0xFF) << 16) |
297 (SBOX4((I1 >> 8) & 0xFF) << 8) |
298 (SBOX1((I1 ) & 0xFF) );
Paul Bakker38119b12009-01-10 23:31:23 +0000299
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000300 I0 ^= (I1 << 8) | (I1 >> 24);
301 I1 ^= (I0 << 16) | (I0 >> 16);
302 I0 ^= (I1 >> 8) | (I1 << 24);
303 I1 ^= (I0 >> 8) | (I0 << 24);
Paul Bakker38119b12009-01-10 23:31:23 +0000304
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000305 z[0] ^= I1;
306 z[1] ^= I0;
Paul Bakker38119b12009-01-10 23:31:23 +0000307}
308
309/*
310 * Camellia key schedule (encryption)
311 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000312int camellia_setkey_enc( camellia_context *ctx, const unsigned char *key, int keysize )
Paul Bakker38119b12009-01-10 23:31:23 +0000313{
314 int i, idx;
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000315 uint32_t *RK;
Paul Bakker38119b12009-01-10 23:31:23 +0000316 unsigned char t[64];
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000317 uint32_t SIGMA[6][2];
318 uint32_t KC[16];
319 uint32_t TK[20];
Paul Bakker38119b12009-01-10 23:31:23 +0000320
321 RK = ctx->rk;
322
323 memset(t, 0, 64);
324 memset(RK, 0, sizeof(ctx->rk));
325
326 switch( keysize )
327 {
328 case 128: ctx->nr = 3; idx = 0; break;
329 case 192:
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000330 case 256: ctx->nr = 4; idx = 1; break;
Paul Bakker2b222c82009-07-27 21:03:45 +0000331 default : return( POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH );
Paul Bakker38119b12009-01-10 23:31:23 +0000332 }
333
334 for( i = 0; i < keysize / 8; ++i)
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000335 t[i] = key[i];
Paul Bakker38119b12009-01-10 23:31:23 +0000336
337 if (keysize == 192) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000338 for (i = 0; i < 8; i++)
339 t[24 + i] = ~t[16 + i];
Paul Bakker38119b12009-01-10 23:31:23 +0000340 }
341
Paul Bakker38119b12009-01-10 23:31:23 +0000342 /*
343 * Prepare SIGMA values
344 */
Paul Bakker38119b12009-01-10 23:31:23 +0000345 for (i = 0; i < 6; i++) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000346 GET_ULONG_BE(SIGMA[i][0], SIGMA_CHARS[i], 0);
347 GET_ULONG_BE(SIGMA[i][1], SIGMA_CHARS[i], 4);
Paul Bakker38119b12009-01-10 23:31:23 +0000348 }
349
350 /*
351 * Key storage in KC
352 * Order: KL, KR, KA, KB
353 */
Paul Bakker38119b12009-01-10 23:31:23 +0000354 memset(KC, 0, sizeof(KC));
355
356 /* Store KL, KR */
357 for (i = 0; i < 8; i++)
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000358 GET_ULONG_BE(KC[i], t, i * 4);
Paul Bakker38119b12009-01-10 23:31:23 +0000359
360 /* Generate KA */
361 for( i = 0; i < 4; ++i)
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000362 KC[8 + i] = KC[i] ^ KC[4 + i];
Paul Bakker38119b12009-01-10 23:31:23 +0000363
364 camellia_feistel(KC + 8, SIGMA[0], KC + 10);
365 camellia_feistel(KC + 10, SIGMA[1], KC + 8);
366
367 for( i = 0; i < 4; ++i)
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000368 KC[8 + i] ^= KC[i];
Paul Bakker38119b12009-01-10 23:31:23 +0000369
370 camellia_feistel(KC + 8, SIGMA[2], KC + 10);
371 camellia_feistel(KC + 10, SIGMA[3], KC + 8);
372
373 if (keysize > 128) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000374 /* Generate KB */
375 for( i = 0; i < 4; ++i)
376 KC[12 + i] = KC[4 + i] ^ KC[8 + i];
Paul Bakker38119b12009-01-10 23:31:23 +0000377
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000378 camellia_feistel(KC + 12, SIGMA[4], KC + 14);
379 camellia_feistel(KC + 14, SIGMA[5], KC + 12);
Paul Bakker38119b12009-01-10 23:31:23 +0000380 }
381
382 /*
383 * Generating subkeys
384 */
Paul Bakker38119b12009-01-10 23:31:23 +0000385
386 /* Manipulating KL */
387 SHIFT_AND_PLACE(idx, 0);
388
389 /* Manipulating KR */
390 if (keysize > 128) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000391 SHIFT_AND_PLACE(idx, 1);
Paul Bakker38119b12009-01-10 23:31:23 +0000392 }
393
394 /* Manipulating KA */
395 SHIFT_AND_PLACE(idx, 2);
396
397 /* Manipulating KB */
398 if (keysize > 128) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000399 SHIFT_AND_PLACE(idx, 3);
Paul Bakker38119b12009-01-10 23:31:23 +0000400 }
401
402 /* Do transpositions */
403 for ( i = 0; i < 20; i++ ) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000404 if (transposes[idx][i] != -1) {
405 RK[32 + 12 * idx + i] = RK[transposes[idx][i]];
406 }
Paul Bakker38119b12009-01-10 23:31:23 +0000407 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000408
409 return( 0 );
Paul Bakker38119b12009-01-10 23:31:23 +0000410}
411
412/*
413 * Camellia key schedule (decryption)
414 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000415int camellia_setkey_dec( camellia_context *ctx, const unsigned char *key, int keysize )
Paul Bakker38119b12009-01-10 23:31:23 +0000416{
417 int i, idx;
418 camellia_context cty;
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000419 uint32_t *RK;
420 uint32_t *SK;
Paul Bakker2b222c82009-07-27 21:03:45 +0000421 int ret;
Paul Bakker38119b12009-01-10 23:31:23 +0000422
423 switch( keysize )
424 {
425 case 128: ctx->nr = 3; idx = 0; break;
426 case 192:
427 case 256: ctx->nr = 4; idx = 1; break;
Paul Bakker2b222c82009-07-27 21:03:45 +0000428 default : return( POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH );
Paul Bakker38119b12009-01-10 23:31:23 +0000429 }
430
431 RK = ctx->rk;
432
Paul Bakker2b222c82009-07-27 21:03:45 +0000433 ret = camellia_setkey_enc(&cty, key, keysize);
434 if( ret != 0 )
435 return( ret );
Paul Bakker38119b12009-01-10 23:31:23 +0000436
437 SK = cty.rk + 24 * 2 + 8 * idx * 2;
438
439 *RK++ = *SK++;
440 *RK++ = *SK++;
441 *RK++ = *SK++;
442 *RK++ = *SK++;
443
444 for (i = 22 + 8 * idx, SK -= 6; i > 0; i--, SK -= 4)
445 {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000446 *RK++ = *SK++;
447 *RK++ = *SK++;
Paul Bakker38119b12009-01-10 23:31:23 +0000448 }
449
450 SK -= 2;
451
452 *RK++ = *SK++;
453 *RK++ = *SK++;
454 *RK++ = *SK++;
455 *RK++ = *SK++;
456
457 memset( &cty, 0, sizeof( camellia_context ) );
Paul Bakker2b222c82009-07-27 21:03:45 +0000458
459 return( 0 );
Paul Bakker38119b12009-01-10 23:31:23 +0000460}
461
462/*
463 * Camellia-ECB block encryption/decryption
464 */
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000465int camellia_crypt_ecb( camellia_context *ctx,
Paul Bakker38119b12009-01-10 23:31:23 +0000466 int mode,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000467 const unsigned char input[16],
Paul Bakker38119b12009-01-10 23:31:23 +0000468 unsigned char output[16] )
469{
Paul Bakker026c03b2009-03-28 17:53:03 +0000470 int NR;
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000471 uint32_t *RK, X[4];
Paul Bakker38119b12009-01-10 23:31:23 +0000472
Paul Bakkerc2547b02009-07-20 20:40:52 +0000473 ( (void) mode );
474
Paul Bakker38119b12009-01-10 23:31:23 +0000475 NR = ctx->nr;
476 RK = ctx->rk;
477
Paul Bakker38119b12009-01-10 23:31:23 +0000478 GET_ULONG_BE( X[0], input, 0 );
479 GET_ULONG_BE( X[1], input, 4 );
480 GET_ULONG_BE( X[2], input, 8 );
481 GET_ULONG_BE( X[3], input, 12 );
482
483 X[0] ^= *RK++;
484 X[1] ^= *RK++;
485 X[2] ^= *RK++;
486 X[3] ^= *RK++;
487
488 while (NR) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000489 --NR;
490 camellia_feistel(X, RK, X + 2);
491 RK += 2;
492 camellia_feistel(X + 2, RK, X);
493 RK += 2;
494 camellia_feistel(X, RK, X + 2);
495 RK += 2;
496 camellia_feistel(X + 2, RK, X);
497 RK += 2;
498 camellia_feistel(X, RK, X + 2);
499 RK += 2;
500 camellia_feistel(X + 2, RK, X);
501 RK += 2;
Paul Bakker38119b12009-01-10 23:31:23 +0000502
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000503 if (NR) {
504 FL(X[0], X[1], RK[0], RK[1]);
505 RK += 2;
506 FLInv(X[2], X[3], RK[0], RK[1]);
507 RK += 2;
508 }
Paul Bakker38119b12009-01-10 23:31:23 +0000509 }
510
511 X[2] ^= *RK++;
512 X[3] ^= *RK++;
513 X[0] ^= *RK++;
514 X[1] ^= *RK++;
515
516 PUT_ULONG_BE( X[2], output, 0 );
517 PUT_ULONG_BE( X[3], output, 4 );
518 PUT_ULONG_BE( X[0], output, 8 );
519 PUT_ULONG_BE( X[1], output, 12 );
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000520
521 return( 0 );
Paul Bakker38119b12009-01-10 23:31:23 +0000522}
523
524/*
525 * Camellia-CBC buffer encryption/decryption
526 */
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000527int camellia_crypt_cbc( camellia_context *ctx,
Paul Bakker38119b12009-01-10 23:31:23 +0000528 int mode,
529 int length,
530 unsigned char iv[16],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000531 const unsigned char *input,
Paul Bakker38119b12009-01-10 23:31:23 +0000532 unsigned char *output )
533{
534 int i;
535 unsigned char temp[16];
536
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000537 if( length % 16 )
538 return( POLARSSL_ERR_CAMELLIA_INVALID_INPUT_LENGTH );
539
Paul Bakker38119b12009-01-10 23:31:23 +0000540 if( mode == CAMELLIA_DECRYPT )
541 {
542 while( length > 0 )
543 {
544 memcpy( temp, input, 16 );
545 camellia_crypt_ecb( ctx, mode, input, output );
546
547 for( i = 0; i < 16; i++ )
548 output[i] = (unsigned char)( output[i] ^ iv[i] );
549
550 memcpy( iv, temp, 16 );
551
552 input += 16;
553 output += 16;
554 length -= 16;
555 }
556 }
557 else
558 {
559 while( length > 0 )
560 {
561 for( i = 0; i < 16; i++ )
562 output[i] = (unsigned char)( input[i] ^ iv[i] );
563
564 camellia_crypt_ecb( ctx, mode, output, output );
565 memcpy( iv, output, 16 );
566
567 input += 16;
568 output += 16;
569 length -= 16;
570 }
571 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000572
573 return( 0 );
Paul Bakker38119b12009-01-10 23:31:23 +0000574}
575
576/*
577 * Camellia-CFB128 buffer encryption/decryption
578 */
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000579int camellia_crypt_cfb128( camellia_context *ctx,
Paul Bakker38119b12009-01-10 23:31:23 +0000580 int mode,
581 int length,
582 int *iv_off,
583 unsigned char iv[16],
Paul Bakkerff60ee62010-03-16 21:09:09 +0000584 const unsigned char *input,
Paul Bakker38119b12009-01-10 23:31:23 +0000585 unsigned char *output )
586{
587 int c, n = *iv_off;
588
589 if( mode == CAMELLIA_DECRYPT )
590 {
591 while( length-- )
592 {
593 if( n == 0 )
594 camellia_crypt_ecb( ctx, CAMELLIA_ENCRYPT, iv, iv );
595
596 c = *input++;
597 *output++ = (unsigned char)( c ^ iv[n] );
598 iv[n] = (unsigned char) c;
599
600 n = (n + 1) & 0x0F;
601 }
602 }
603 else
604 {
605 while( length-- )
606 {
607 if( n == 0 )
608 camellia_crypt_ecb( ctx, CAMELLIA_ENCRYPT, iv, iv );
609
610 iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
611
612 n = (n + 1) & 0x0F;
613 }
614 }
615
616 *iv_off = n;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000617
618 return( 0 );
Paul Bakker38119b12009-01-10 23:31:23 +0000619}
620
621#if defined(POLARSSL_SELF_TEST)
622
623#include <stdio.h>
624
625/*
626 * Camellia test vectors from:
627 *
628 * http://info.isl.ntt.co.jp/crypt/eng/camellia/technology.html:
629 * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/intermediate.txt
630 * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/t_camellia.txt
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000631 * (For each bitlength: Key 0, Nr 39)
Paul Bakker38119b12009-01-10 23:31:23 +0000632 */
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000633#define CAMELLIA_TESTS_ECB 2
Paul Bakker38119b12009-01-10 23:31:23 +0000634
635static const unsigned char camellia_test_ecb_key[3][CAMELLIA_TESTS_ECB][32] =
636{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000637 {
638 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
639 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
640 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
641 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
642 },
643 {
644 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
645 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
646 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
647 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
648 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
649 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
650 },
651 {
652 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
653 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
654 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
655 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
656 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
657 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
658 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
659 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
660 },
Paul Bakker38119b12009-01-10 23:31:23 +0000661};
662
663static const unsigned char camellia_test_ecb_plain[CAMELLIA_TESTS_ECB][16] =
664{
665 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
666 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
667 { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
668 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
669};
670
671static const unsigned char camellia_test_ecb_cipher[3][CAMELLIA_TESTS_ECB][16] =
672{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000673 {
674 { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73,
675 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 },
676 { 0x38, 0x3C, 0x6C, 0x2A, 0xAB, 0xEF, 0x7F, 0xDE,
677 0x25, 0xCD, 0x47, 0x0B, 0xF7, 0x74, 0xA3, 0x31 }
678 },
679 {
680 { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8,
681 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 },
682 { 0xD1, 0x76, 0x3F, 0xC0, 0x19, 0xD7, 0x7C, 0xC9,
683 0x30, 0xBF, 0xF2, 0xA5, 0x6F, 0x7C, 0x93, 0x64 }
684 },
685 {
686 { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c,
687 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 },
688 { 0x05, 0x03, 0xFB, 0x10, 0xAB, 0x24, 0x1E, 0x7C,
689 0xF4, 0x5D, 0x8C, 0xDE, 0xEE, 0x47, 0x43, 0x35 }
690 }
Paul Bakker38119b12009-01-10 23:31:23 +0000691};
692
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000693#define CAMELLIA_TESTS_CBC 3
Paul Bakker38119b12009-01-10 23:31:23 +0000694
695static const unsigned char camellia_test_cbc_key[3][32] =
696{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000697 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
698 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }
699 ,
700 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
701 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
702 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }
703 ,
704 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
705 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
706 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
707 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Paul Bakker38119b12009-01-10 23:31:23 +0000708};
709
710static const unsigned char camellia_test_cbc_iv[16] =
711
712 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
713 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }
714;
715
716static const unsigned char camellia_test_cbc_plain[CAMELLIA_TESTS_CBC][16] =
717{
718 { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
719 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A },
720 { 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
721 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51 },
722 { 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
723 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF }
724
725};
726
727static const unsigned char camellia_test_cbc_cipher[3][CAMELLIA_TESTS_CBC][16] =
728{
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000729 {
730 { 0x16, 0x07, 0xCF, 0x49, 0x4B, 0x36, 0xBB, 0xF0,
731 0x0D, 0xAE, 0xB0, 0xB5, 0x03, 0xC8, 0x31, 0xAB },
732 { 0xA2, 0xF2, 0xCF, 0x67, 0x16, 0x29, 0xEF, 0x78,
733 0x40, 0xC5, 0xA5, 0xDF, 0xB5, 0x07, 0x48, 0x87 },
734 { 0x0F, 0x06, 0x16, 0x50, 0x08, 0xCF, 0x8B, 0x8B,
735 0x5A, 0x63, 0x58, 0x63, 0x62, 0x54, 0x3E, 0x54 }
736 },
737 {
738 { 0x2A, 0x48, 0x30, 0xAB, 0x5A, 0xC4, 0xA1, 0xA2,
739 0x40, 0x59, 0x55, 0xFD, 0x21, 0x95, 0xCF, 0x93 },
740 { 0x5D, 0x5A, 0x86, 0x9B, 0xD1, 0x4C, 0xE5, 0x42,
741 0x64, 0xF8, 0x92, 0xA6, 0xDD, 0x2E, 0xC3, 0xD5 },
742 { 0x37, 0xD3, 0x59, 0xC3, 0x34, 0x98, 0x36, 0xD8,
743 0x84, 0xE3, 0x10, 0xAD, 0xDF, 0x68, 0xC4, 0x49 }
744 },
745 {
746 { 0xE6, 0xCF, 0xA3, 0x5F, 0xC0, 0x2B, 0x13, 0x4A,
747 0x4D, 0x2C, 0x0B, 0x67, 0x37, 0xAC, 0x3E, 0xDA },
748 { 0x36, 0xCB, 0xEB, 0x73, 0xBD, 0x50, 0x4B, 0x40,
749 0x70, 0xB1, 0xB7, 0xDE, 0x2B, 0x21, 0xEB, 0x50 },
750 { 0xE3, 0x1A, 0x60, 0x55, 0x29, 0x7D, 0x96, 0xCA,
751 0x33, 0x30, 0xCD, 0xF1, 0xB1, 0x86, 0x0A, 0x83 }
752 }
Paul Bakker38119b12009-01-10 23:31:23 +0000753};
754
755
756/*
757 * Checkup routine
758 */
759int camellia_self_test( int verbose )
760{
Paul Bakker026c03b2009-03-28 17:53:03 +0000761 int i, j, u, v;
Paul Bakker38119b12009-01-10 23:31:23 +0000762 unsigned char key[32];
763 unsigned char buf[64];
Paul Bakker38119b12009-01-10 23:31:23 +0000764 unsigned char src[16];
765 unsigned char dst[16];
766 unsigned char iv[16];
767 camellia_context ctx;
768
769 memset( key, 0, 32 );
770
771 for (j = 0; j < 6; j++) {
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000772 u = j >> 1;
773 v = j & 1;
Paul Bakker38119b12009-01-10 23:31:23 +0000774
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000775 if( verbose != 0 )
776 printf( " CAMELLIA-ECB-%3d (%s): ", 128 + u * 64,
777 (v == CAMELLIA_DECRYPT) ? "dec" : "enc");
Paul Bakker38119b12009-01-10 23:31:23 +0000778
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000779 for (i = 0; i < CAMELLIA_TESTS_ECB; i++ ) {
780 memcpy( key, camellia_test_ecb_key[u][i], 16 + 8 * u);
Paul Bakker38119b12009-01-10 23:31:23 +0000781
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000782 if (v == CAMELLIA_DECRYPT) {
783 camellia_setkey_dec(&ctx, key, 128 + u * 64);
784 memcpy(src, camellia_test_ecb_cipher[u][i], 16);
785 memcpy(dst, camellia_test_ecb_plain[i], 16);
786 } else { /* CAMELLIA_ENCRYPT */
787 camellia_setkey_enc(&ctx, key, 128 + u * 64);
788 memcpy(src, camellia_test_ecb_plain[i], 16);
789 memcpy(dst, camellia_test_ecb_cipher[u][i], 16);
790 }
Paul Bakker38119b12009-01-10 23:31:23 +0000791
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000792 camellia_crypt_ecb(&ctx, v, src, buf);
Paul Bakker38119b12009-01-10 23:31:23 +0000793
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000794 if( memcmp( buf, dst, 16 ) != 0 )
795 {
796 if( verbose != 0 )
797 printf( "failed\n" );
Paul Bakker38119b12009-01-10 23:31:23 +0000798
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000799 return( 1 );
800 }
801 }
Paul Bakker38119b12009-01-10 23:31:23 +0000802
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000803 if( verbose != 0 )
804 printf( "passed\n" );
Paul Bakker38119b12009-01-10 23:31:23 +0000805 }
806
807 if( verbose != 0 )
808 printf( "\n" );
809
810 /*
811 * CBC mode
812 */
813 for( j = 0; j < 6; j++ )
814 {
815 u = j >> 1;
816 v = j & 1;
817
818 if( verbose != 0 )
819 printf( " CAMELLIA-CBC-%3d (%s): ", 128 + u * 64,
820 ( v == CAMELLIA_DECRYPT ) ? "dec" : "enc" );
821
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000822 memcpy( src, camellia_test_cbc_iv, 16);
823 memcpy( dst, camellia_test_cbc_iv, 16);
824 memcpy( key, camellia_test_cbc_key[u], 16 + 8 * u);
Paul Bakker38119b12009-01-10 23:31:23 +0000825
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000826 if (v == CAMELLIA_DECRYPT) {
827 camellia_setkey_dec(&ctx, key, 128 + u * 64);
828 } else {
829 camellia_setkey_enc(&ctx, key, 128 + u * 64);
830 }
Paul Bakker38119b12009-01-10 23:31:23 +0000831
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000832 for (i = 0; i < CAMELLIA_TESTS_CBC; i++ ) {
Paul Bakker38119b12009-01-10 23:31:23 +0000833
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000834 if (v == CAMELLIA_DECRYPT) {
835 memcpy( iv , src, 16 );
836 memcpy(src, camellia_test_cbc_cipher[u][i], 16);
837 memcpy(dst, camellia_test_cbc_plain[i], 16);
838 } else { /* CAMELLIA_ENCRYPT */
839 memcpy( iv , dst, 16 );
840 memcpy(src, camellia_test_cbc_plain[i], 16);
841 memcpy(dst, camellia_test_cbc_cipher[u][i], 16);
842 }
Paul Bakker38119b12009-01-10 23:31:23 +0000843
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000844 camellia_crypt_cbc(&ctx, v, 16, iv, src, buf);
Paul Bakker38119b12009-01-10 23:31:23 +0000845
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000846 if( memcmp( buf, dst, 16 ) != 0 )
847 {
848 if( verbose != 0 )
849 printf( "failed\n" );
Paul Bakker38119b12009-01-10 23:31:23 +0000850
Paul Bakkerc81f6c32009-05-03 13:09:15 +0000851 return( 1 );
852 }
853 }
Paul Bakker38119b12009-01-10 23:31:23 +0000854
855 if( verbose != 0 )
856 printf( "passed\n" );
857 }
858
859 if( verbose != 0 )
860 printf( "\n" );
861
862 return ( 0 );
Paul Bakker38119b12009-01-10 23:31:23 +0000863}
864
865#endif
866
867#endif