1 /*
2 * Copyright (c) 2009
3 * NTT (Nippon Telegraph and Telephone Corporation) . All rights reserved.
4 */
5 #include <stdio.h>
6 #include <string.h>
7 #include <stdlib.h>
8 #include <unistd.h>
9 #include "camellia.h"
10
11 #define B 16U
12 unsigned char key[16];
13 unsigned char test_case_len[] = { B+1, 2*B-1, 2*B, 2*B+1, 3*B-1, 3*B, 4*B, };
14 #define NTESTS (sizeof(test_case_len))
15 struct {
16 unsigned char ivec[16];
17 unsigned char input[4*16];
18 unsigned char output[4*16];
19 } test_case[NTESTS];
20 camellia_ctx ctx, dctx;
21
22 static void
init(void)23 init (void)
24 {
25 size_t i, j;
26 cam_rval r;
27
28 srand(42);
29 for (i = 0; i < 16; i++)
30 key[i] = 0xff & rand();
31 memset(test_case, 0, sizeof(test_case));
32 for (i = 0; i < NTESTS; i++)
33 for (j = 0; j < test_case_len[i]; j++) {
34 test_case[i].input[j] = 0xff & rand();
35 }
36
37 r = camellia_enc_key (key, sizeof(key), &ctx);
38 if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
39 r = camellia_dec_key (key, sizeof(key), &dctx);
40 if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
41 }
42
hexdump(const unsigned char * ptr,size_t len)43 static void hexdump(const unsigned char *ptr, size_t len)
44 {
45 size_t i;
46 for (i = 0; i < len; i++)
47 printf ("%s%02X", (i % 16 == 0) ? "\n " : " ", ptr[i]);
48 }
49
50 static void
fips_test(void)51 fips_test (void)
52 {
53 static const unsigned char fipskey[16] = {
54 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
55 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
56 };
57 static const unsigned char input[16] = {
58 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
59 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
60 };
61 static const unsigned char expected[16] = {
62 0x67,0x67,0x31,0x38,0x54,0x96,0x69,0x73,
63 0x08,0x57,0x06,0x56,0x48,0xea,0xbe,0x43
64 };
65 unsigned char output[16];
66 unsigned char tmp[16];
67 camellia_ctx fipsctx;
68 int r;
69
70 printf ("FIPS test:\nkey:");
71 hexdump (fipskey, 16);
72 printf ("\ninput:");
73 hexdump (input, 16);
74 r = camellia_enc_key (fipskey, sizeof(fipskey), &fipsctx);
75 if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
76 r = camellia_enc_blk (input, output, &fipsctx);
77 if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
78 printf ("\noutput:");
79 hexdump (output, 16);
80 printf ("\n");
81 if (memcmp(expected, output, 16))
82 fprintf(stderr, "wrong results!!!\n"), exit (1);
83 r = camellia_dec_key (fipskey, sizeof(fipskey), &fipsctx);
84 if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
85 r = camellia_dec_blk (output, tmp, &fipsctx);
86 if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
87 if (memcmp(input, tmp, 16))
88 fprintf(stderr, "decryption failed!!\n"), exit(1);
89 printf ("ok.\n\n");
90 }
91
92 static void
xor(unsigned char * out,const unsigned char * a,const unsigned char * b)93 xor (unsigned char *out, const unsigned char *a, const unsigned char *b)
94 {
95 size_t i;
96 for (i = 0; i < B; i++)
97 out[i] = a[i] ^ b[i];
98 }
99
100 static void
ecb_enc(unsigned char * out,unsigned char * in,unsigned int len)101 ecb_enc (unsigned char *out, unsigned char *in, unsigned int len)
102 {
103 size_t i;
104 cam_rval r;
105 for (i = 0; i < len; i += 16) {
106 r = camellia_enc_blk (in + i, out + i, &ctx);
107 if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
108 }
109 if (i != len) abort ();
110 }
111
112 static void
ecb_dec(unsigned char * out,unsigned char * in,unsigned int len)113 ecb_dec (unsigned char *out, unsigned char *in, unsigned int len)
114 {
115 size_t i;
116 cam_rval r;
117 for (i = 0; i < len; i += 16) {
118 r = camellia_dec_blk (in + i, out + i, &dctx);
119 if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
120 }
121 if (i != len) abort ();
122 }
123
124 #define D(X) (printf("%s %d: %s=",__FUNCTION__,__LINE__, #X),hexdump(X,B),printf("\n"))
125
126 #undef D
127 #define D(X)
128
129 static void
cbc_enc(unsigned char * out,unsigned char * in,unsigned char * iv,unsigned int len)130 cbc_enc (unsigned char *out, unsigned char *in, unsigned char *iv,
131 unsigned int len)
132 {
133 size_t i;
134 cam_rval r;
135 unsigned char tmp[B];
136 D(iv);
137 memcpy (tmp, iv, B);
138 for (i = 0; i < len; i += B) {
139 D(in+i);
140 xor (tmp, tmp, in + i);
141 D(tmp);
142 r = camellia_enc_blk (tmp, out + i, &ctx);
143 if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
144 memcpy (tmp, out + i, B);
145 D(out+i);
146 }
147 if (i != len) abort ();
148 }
149
150 static void
cbc_dec(unsigned char * out,unsigned char * in,unsigned char * iv,unsigned int len)151 cbc_dec (unsigned char *out, unsigned char *in, unsigned char *iv,
152 unsigned int len)
153 {
154 size_t i;
155 cam_rval r;
156 unsigned char tmp[B];
157 memcpy (tmp, iv, B);
158 for (i = 0; i < len; i += B) {
159 r = camellia_dec_blk (in + i, tmp, &dctx);
160 if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
161 xor (tmp, tmp, iv);
162 iv = in + i;
163 memcpy (out + i, tmp, B);
164 }
165 if (i != len) abort ();
166 }
167
168 static void
cts_enc(unsigned char * out,unsigned char * in,unsigned char * iv,unsigned int len)169 cts_enc (unsigned char *out, unsigned char *in, unsigned char *iv,
170 unsigned int len)
171 {
172 int r;
173 unsigned int len2;
174 unsigned char pn1[B], pn[B], cn[B], cn1[B];
175
176 if (len < B + 1) abort ();
177 len2 = (len - B - 1) & ~(B-1);
178 cbc_enc (out, in, iv, len2);
179 out += len2;
180 in += len2;
181 len -= len2;
182 if (len2)
183 iv = out - B;
184 if (len <= B || len > 2 * B)
185 abort ();
186 printf ("(did CBC mode for %d)\n", len2);
187
188 D(in);
189 xor (pn1, in, iv);
190 D(pn1);
191 r = camellia_enc_blk (pn1, cn, &ctx);
192 if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
193 D(cn);
194 memset (pn, 0, sizeof(pn));
195 memcpy (pn, in+B, len-B);
196 D(pn);
197 xor (pn, pn, cn);
198 D(pn);
199 r = camellia_enc_blk (pn, cn1, &ctx);
200 if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
201 D(cn1);
202 memcpy(out, cn1, B);
203 memcpy(out+B, cn, len-B);
204 }
205
206 static void
cts_dec(unsigned char * out,unsigned char * in,unsigned char * iv,unsigned int len)207 cts_dec (unsigned char *out, unsigned char *in, unsigned char *iv,
208 unsigned int len)
209 {
210 int r;
211 unsigned int len2;
212 unsigned char pn1[B], pn[B], cn[B], cn1[B];
213
214 if (len < B + 1) abort ();
215 len2 = (len - B - 1) & ~(B-1);
216 cbc_dec (out, in, iv, len2);
217 out += len2;
218 in += len2;
219 len -= len2;
220 if (len2)
221 iv = in - B;
222 if (len <= B || len > 2 * B)
223 abort ();
224
225 memcpy (cn1, in, B);
226 r = camellia_dec_blk (cn1, pn, &dctx);
227 if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
228 memset (cn, 0, sizeof(cn));
229 memcpy (cn, in+B, len-B);
230 xor (pn, pn, cn);
231 memcpy (cn+len-B, pn+len-B, 2*B-len);
232 r = camellia_dec_blk (cn, pn1, &dctx);
233 if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
234 xor (pn1, pn1, iv);
235 memcpy(out, pn1, B);
236 memcpy(out+B, pn, len-B);
237 }
238
239 static void
ecb_test(void)240 ecb_test (void)
241 {
242 size_t testno;
243 unsigned char tmp[4*B];
244
245 printf ("ECB tests:\n");
246 printf ("key:");
247 hexdump (key, sizeof(key));
248 for (testno = 0; testno < NTESTS; testno++) {
249 unsigned len = (test_case_len[testno] + 15) & ~15;
250 printf ("\ntest %d - %d bytes\n", (int)testno, len);
251 printf ("input:");
252 hexdump (test_case[testno].input, len);
253 printf ("\n");
254 ecb_enc (test_case[testno].output, test_case[testno].input, len);
255 printf ("output:");
256 hexdump (test_case[testno].output, len);
257 printf ("\n");
258 ecb_dec (tmp, test_case[testno].output, len);
259 if (memcmp (tmp, test_case[testno].input, len)) {
260 printf ("ecb decrypt failed!!");
261 hexdump (tmp, len);
262 printf ("\n");
263 exit (1);
264 }
265 }
266 printf ("\n");
267 }
268
269 unsigned char ivec[16] = { 0 };
270
271 static void
cbc_test(void)272 cbc_test (void)
273 {
274 size_t testno;
275 unsigned char tmp[4*B];
276
277 printf ("CBC tests:\n");
278 printf ("initial vector:");
279 hexdump (ivec, sizeof(ivec));
280 for (testno = 0; testno < NTESTS; testno++) {
281 unsigned len = (test_case_len[testno] + 15) & ~15;
282 printf ("\ntest %d - %d bytes\n", (int)testno, len);
283 printf ("input:");
284 hexdump (test_case[testno].input, len);
285 printf ("\n");
286 cbc_enc (test_case[testno].output, test_case[testno].input, ivec, len);
287 printf ("output:");
288 hexdump (test_case[testno].output, len);
289 printf ("\n");
290 cbc_dec (tmp, test_case[testno].output, ivec, len);
291 if (memcmp (tmp, test_case[testno].input, len)) {
292 printf("cbc decrypt failed!!");
293 hexdump (tmp, len);
294 printf ("\n");
295 exit(1);
296 }
297 }
298 printf ("\n");
299 }
300
301 static void
cts_test(void)302 cts_test (void)
303 {
304 size_t testno;
305 unsigned char tmp[4*B];
306
307 printf ("CTS tests:\n");
308 printf ("initial vector:");
309 hexdump (ivec, sizeof(ivec));
310 for (testno = 0; testno < NTESTS; testno++) {
311 unsigned int len = test_case_len[testno];
312 printf ("\ntest %d - %d bytes\n", (int)testno, len);
313 printf ("input:");
314 hexdump (test_case[testno].input, len);
315 printf ("\n");
316 cts_enc (test_case[testno].output, test_case[testno].input, ivec, len);
317 printf ("output:");
318 hexdump (test_case[testno].output, len);
319 printf ("\n");
320 cts_dec (tmp, test_case[testno].output, ivec, len);
321 if (memcmp (tmp, test_case[testno].input, len))
322 fprintf (stderr, "cts decrypt failed!!\n"), exit(1);
323 }
324 printf ("\n");
325 }
326
327 int
main(void)328 main (void)
329 {
330 init ();
331 fips_test ();
332
333 ecb_test();
334 cbc_test();
335 cts_test();
336
337 return 0;
338 }
339
340