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