Enable AMD64 Camellia implementations on WIN64
[libgcrypt.git] / cipher / camellia-glue.c
1 /* camellia-glue.c - Glue for the Camellia cipher
2  * Copyright (C) 2007 Free Software Foundation, Inc.
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  * 02110-1301, USA.
20  */
21
22 /* I put all the libgcrypt-specific stuff in this file to keep the
23    camellia.c/camellia.h files exactly as provided by NTT.  If they
24    update their code, this should make it easier to bring the changes
25    in. - dshaw
26
27    There is one small change which needs to be done: Include the
28    following code at the top of camellia.h: */
29 #if 0
30
31 /* To use Camellia with libraries it is often useful to keep the name
32  * space of the library clean.  The following macro is thus useful:
33  *
34  *     #define CAMELLIA_EXT_SYM_PREFIX foo_
35  *
36  * This prefixes all external symbols with "foo_".
37  */
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
41 #ifdef CAMELLIA_EXT_SYM_PREFIX
42 #define CAMELLIA_PREFIX1(x,y) x ## y
43 #define CAMELLIA_PREFIX2(x,y) CAMELLIA_PREFIX1(x,y)
44 #define CAMELLIA_PREFIX(x)    CAMELLIA_PREFIX2(CAMELLIA_EXT_SYM_PREFIX,x)
45 #define Camellia_Ekeygen      CAMELLIA_PREFIX(Camellia_Ekeygen)
46 #define Camellia_EncryptBlock CAMELLIA_PREFIX(Camellia_EncryptBlock)
47 #define Camellia_DecryptBlock CAMELLIA_PREFIX(Camellia_DecryptBlock)
48 #define camellia_decrypt128   CAMELLIA_PREFIX(camellia_decrypt128)
49 #define camellia_decrypt256   CAMELLIA_PREFIX(camellia_decrypt256)
50 #define camellia_encrypt128   CAMELLIA_PREFIX(camellia_encrypt128)
51 #define camellia_encrypt256   CAMELLIA_PREFIX(camellia_encrypt256)
52 #define camellia_setup128     CAMELLIA_PREFIX(camellia_setup128)
53 #define camellia_setup192     CAMELLIA_PREFIX(camellia_setup192)
54 #define camellia_setup256     CAMELLIA_PREFIX(camellia_setup256)
55 #endif /*CAMELLIA_EXT_SYM_PREFIX*/
56
57 #endif /* Code sample. */
58
59
60 #include <config.h>
61 #include "types.h"
62 #include "g10lib.h"
63 #include "cipher.h"
64 #include "camellia.h"
65 #include "bufhelp.h"
66 #include "cipher-selftest.h"
67
68 /* Helper macro to force alignment to 16 bytes.  */
69 #ifdef HAVE_GCC_ATTRIBUTE_ALIGNED
70 # define ATTR_ALIGNED_16  __attribute__ ((aligned (16)))
71 #else
72 # define ATTR_ALIGNED_16
73 #endif
74
75 /* USE_AESNI inidicates whether to compile with Intel AES-NI/AVX code. */
76 #undef USE_AESNI_AVX
77 #if defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX_SUPPORT)
78 # if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
79      defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
80 #  define USE_AESNI_AVX 1
81 # endif
82 #endif
83
84 /* USE_AESNI_AVX2 inidicates whether to compile with Intel AES-NI/AVX2 code. */
85 #undef USE_AESNI_AVX2
86 #if defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX2_SUPPORT)
87 # if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
88      defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
89 #  define USE_AESNI_AVX2 1
90 # endif
91 #endif
92
93 typedef struct
94 {
95   KEY_TABLE_TYPE keytable;
96   int keybitlength;
97 #ifdef USE_AESNI_AVX
98   unsigned int use_aesni_avx:1; /* AES-NI/AVX implementation shall be used.  */
99 #endif /*USE_AESNI_AVX*/
100 #ifdef USE_AESNI_AVX2
101   unsigned int use_aesni_avx2:1;/* AES-NI/AVX2 implementation shall be used.  */
102 #endif /*USE_AESNI_AVX2*/
103 } CAMELLIA_context;
104
105 /* Assembly implementations use SystemV ABI, ABI conversion and additional
106  * stack to store XMM6-XMM15 needed on Win64. */
107 #undef ASM_FUNC_ABI
108 #undef ASM_EXTRA_STACK
109 #if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2)
110 # ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
111 #  define ASM_FUNC_ABI __attribute__((sysv_abi))
112 #  define ASM_EXTRA_STACK (10 * 16)
113 # else
114 #  define ASM_FUNC_ABI
115 #  define ASM_EXTRA_STACK 0
116 # endif
117 #endif
118
119 #ifdef USE_AESNI_AVX
120 /* Assembler implementations of Camellia using AES-NI and AVX.  Process data
121    in 16 block same time.
122  */
123 extern void _gcry_camellia_aesni_avx_ctr_enc(CAMELLIA_context *ctx,
124                                              unsigned char *out,
125                                              const unsigned char *in,
126                                              unsigned char *ctr) ASM_FUNC_ABI;
127
128 extern void _gcry_camellia_aesni_avx_cbc_dec(CAMELLIA_context *ctx,
129                                              unsigned char *out,
130                                              const unsigned char *in,
131                                              unsigned char *iv) ASM_FUNC_ABI;
132
133 extern void _gcry_camellia_aesni_avx_cfb_dec(CAMELLIA_context *ctx,
134                                              unsigned char *out,
135                                              const unsigned char *in,
136                                              unsigned char *iv) ASM_FUNC_ABI;
137
138 extern void _gcry_camellia_aesni_avx_keygen(CAMELLIA_context *ctx,
139                                             const unsigned char *key,
140                                             unsigned int keylen) ASM_FUNC_ABI;
141 #endif
142
143 #ifdef USE_AESNI_AVX2
144 /* Assembler implementations of Camellia using AES-NI and AVX2.  Process data
145    in 32 block same time.
146  */
147 extern void _gcry_camellia_aesni_avx2_ctr_enc(CAMELLIA_context *ctx,
148                                               unsigned char *out,
149                                               const unsigned char *in,
150                                               unsigned char *ctr) ASM_FUNC_ABI;
151
152 extern void _gcry_camellia_aesni_avx2_cbc_dec(CAMELLIA_context *ctx,
153                                               unsigned char *out,
154                                               const unsigned char *in,
155                                               unsigned char *iv) ASM_FUNC_ABI;
156
157 extern void _gcry_camellia_aesni_avx2_cfb_dec(CAMELLIA_context *ctx,
158                                               unsigned char *out,
159                                               const unsigned char *in,
160                                               unsigned char *iv) ASM_FUNC_ABI;
161 #endif
162
163 static const char *selftest(void);
164
165 static gcry_err_code_t
166 camellia_setkey(void *c, const byte *key, unsigned keylen)
167 {
168   CAMELLIA_context *ctx=c;
169   static int initialized=0;
170   static const char *selftest_failed=NULL;
171 #if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2)
172   unsigned int hwf = _gcry_get_hw_features ();
173 #endif
174
175   if(keylen!=16 && keylen!=24 && keylen!=32)
176     return GPG_ERR_INV_KEYLEN;
177
178   if(!initialized)
179     {
180       initialized=1;
181       selftest_failed=selftest();
182       if(selftest_failed)
183         log_error("%s\n",selftest_failed);
184     }
185
186   if(selftest_failed)
187     return GPG_ERR_SELFTEST_FAILED;
188
189 #ifdef USE_AESNI_AVX
190   ctx->use_aesni_avx = (hwf & HWF_INTEL_AESNI) && (hwf & HWF_INTEL_AVX);
191 #endif
192 #ifdef USE_AESNI_AVX2
193   ctx->use_aesni_avx2 = (hwf & HWF_INTEL_AESNI) && (hwf & HWF_INTEL_AVX2);
194 #endif
195
196   ctx->keybitlength=keylen*8;
197
198   if (0)
199     { }
200 #ifdef USE_AESNI_AVX
201   else if (ctx->use_aesni_avx)
202     _gcry_camellia_aesni_avx_keygen(ctx, key, keylen);
203   else
204 #endif
205     {
206       Camellia_Ekeygen(ctx->keybitlength,key,ctx->keytable);
207       _gcry_burn_stack
208         ((19+34+34)*sizeof(u32)+2*sizeof(void*) /* camellia_setup256 */
209          +(4+32)*sizeof(u32)+2*sizeof(void*)    /* camellia_setup192 */
210          +0+sizeof(int)+2*sizeof(void*)         /* Camellia_Ekeygen */
211          +3*2*sizeof(void*)                     /* Function calls.  */
212          );
213     }
214
215   return 0;
216 }
217
218 #ifdef USE_ARM_ASM
219
220 /* Assembly implementations of Camellia. */
221 extern void _gcry_camellia_arm_encrypt_block(const KEY_TABLE_TYPE keyTable,
222                                                byte *outbuf, const byte *inbuf,
223                                                const int keybits);
224
225 extern void _gcry_camellia_arm_decrypt_block(const KEY_TABLE_TYPE keyTable,
226                                                byte *outbuf, const byte *inbuf,
227                                                const int keybits);
228
229 static void Camellia_EncryptBlock(const int keyBitLength,
230                                   const unsigned char *plaintext,
231                                   const KEY_TABLE_TYPE keyTable,
232                                   unsigned char *cipherText)
233 {
234   _gcry_camellia_arm_encrypt_block(keyTable, cipherText, plaintext,
235                                      keyBitLength);
236 }
237
238 static void Camellia_DecryptBlock(const int keyBitLength,
239                                   const unsigned char *cipherText,
240                                   const KEY_TABLE_TYPE keyTable,
241                                   unsigned char *plaintext)
242 {
243   _gcry_camellia_arm_decrypt_block(keyTable, plaintext, cipherText,
244                                      keyBitLength);
245 }
246
247 static unsigned int
248 camellia_encrypt(void *c, byte *outbuf, const byte *inbuf)
249 {
250   CAMELLIA_context *ctx = c;
251   Camellia_EncryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
252 #define CAMELLIA_encrypt_stack_burn_size (15*4)
253   return /*burn_stack*/ (CAMELLIA_encrypt_stack_burn_size);
254 }
255
256 static unsigned int
257 camellia_decrypt(void *c, byte *outbuf, const byte *inbuf)
258 {
259   CAMELLIA_context *ctx=c;
260   Camellia_DecryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
261 #define CAMELLIA_decrypt_stack_burn_size (15*4)
262   return /*burn_stack*/ (CAMELLIA_decrypt_stack_burn_size);
263 }
264
265 #else /*USE_ARM_ASM*/
266
267 static unsigned int
268 camellia_encrypt(void *c, byte *outbuf, const byte *inbuf)
269 {
270   CAMELLIA_context *ctx=c;
271
272   Camellia_EncryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
273
274 #define CAMELLIA_encrypt_stack_burn_size \
275   (sizeof(int)+2*sizeof(unsigned char *)+sizeof(void*/*KEY_TABLE_TYPE*/) \
276      +4*sizeof(u32)+4*sizeof(u32) \
277      +2*sizeof(u32*)+4*sizeof(u32) \
278      +2*2*sizeof(void*) /* Function calls.  */ \
279     )
280
281   return /*burn_stack*/ (CAMELLIA_encrypt_stack_burn_size);
282 }
283
284 static unsigned int
285 camellia_decrypt(void *c, byte *outbuf, const byte *inbuf)
286 {
287   CAMELLIA_context *ctx=c;
288
289   Camellia_DecryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
290
291 #define CAMELLIA_decrypt_stack_burn_size \
292     (sizeof(int)+2*sizeof(unsigned char *)+sizeof(void*/*KEY_TABLE_TYPE*/) \
293      +4*sizeof(u32)+4*sizeof(u32) \
294      +2*sizeof(u32*)+4*sizeof(u32) \
295      +2*2*sizeof(void*) /* Function calls.  */ \
296     )
297
298   return /*burn_stack*/ (CAMELLIA_decrypt_stack_burn_size);
299 }
300
301 #endif /*!USE_ARM_ASM*/
302
303 /* Bulk encryption of complete blocks in CTR mode.  This function is only
304    intended for the bulk encryption feature of cipher.c.  CTR is expected to be
305    of size CAMELLIA_BLOCK_SIZE. */
306 void
307 _gcry_camellia_ctr_enc(void *context, unsigned char *ctr,
308                        void *outbuf_arg, const void *inbuf_arg,
309                        size_t nblocks)
310 {
311   CAMELLIA_context *ctx = context;
312   unsigned char *outbuf = outbuf_arg;
313   const unsigned char *inbuf = inbuf_arg;
314   unsigned char tmpbuf[CAMELLIA_BLOCK_SIZE];
315   int burn_stack_depth = CAMELLIA_encrypt_stack_burn_size;
316   int i;
317
318 #ifdef USE_AESNI_AVX2
319   if (ctx->use_aesni_avx2)
320     {
321       int did_use_aesni_avx2 = 0;
322
323       /* Process data in 32 block chunks. */
324       while (nblocks >= 32)
325         {
326           _gcry_camellia_aesni_avx2_ctr_enc(ctx, outbuf, inbuf, ctr);
327
328           nblocks -= 32;
329           outbuf += 32 * CAMELLIA_BLOCK_SIZE;
330           inbuf  += 32 * CAMELLIA_BLOCK_SIZE;
331           did_use_aesni_avx2 = 1;
332         }
333
334       if (did_use_aesni_avx2)
335         {
336           int avx2_burn_stack_depth = 32 * CAMELLIA_BLOCK_SIZE + 16 +
337                                         2 * sizeof(void *) + ASM_EXTRA_STACK;
338
339           if (burn_stack_depth < avx2_burn_stack_depth)
340             burn_stack_depth = avx2_burn_stack_depth;
341         }
342
343       /* Use generic code to handle smaller chunks... */
344       /* TODO: use caching instead? */
345     }
346 #endif
347
348 #ifdef USE_AESNI_AVX
349   if (ctx->use_aesni_avx)
350     {
351       int did_use_aesni_avx = 0;
352
353       /* Process data in 16 block chunks. */
354       while (nblocks >= 16)
355         {
356           _gcry_camellia_aesni_avx_ctr_enc(ctx, outbuf, inbuf, ctr);
357
358           nblocks -= 16;
359           outbuf += 16 * CAMELLIA_BLOCK_SIZE;
360           inbuf  += 16 * CAMELLIA_BLOCK_SIZE;
361           did_use_aesni_avx = 1;
362         }
363
364       if (did_use_aesni_avx)
365         {
366           int avx_burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE +
367                                        2 * sizeof(void *) + ASM_EXTRA_STACK;
368
369           if (burn_stack_depth < avx_burn_stack_depth)
370             burn_stack_depth = avx_burn_stack_depth;
371         }
372
373       /* Use generic code to handle smaller chunks... */
374       /* TODO: use caching instead? */
375     }
376 #endif
377
378   for ( ;nblocks; nblocks-- )
379     {
380       /* Encrypt the counter. */
381       Camellia_EncryptBlock(ctx->keybitlength, ctr, ctx->keytable, tmpbuf);
382       /* XOR the input with the encrypted counter and store in output.  */
383       buf_xor(outbuf, tmpbuf, inbuf, CAMELLIA_BLOCK_SIZE);
384       outbuf += CAMELLIA_BLOCK_SIZE;
385       inbuf  += CAMELLIA_BLOCK_SIZE;
386       /* Increment the counter.  */
387       for (i = CAMELLIA_BLOCK_SIZE; i > 0; i--)
388         {
389           ctr[i-1]++;
390           if (ctr[i-1])
391             break;
392         }
393     }
394
395   wipememory(tmpbuf, sizeof(tmpbuf));
396   _gcry_burn_stack(burn_stack_depth);
397 }
398
399 /* Bulk decryption of complete blocks in CBC mode.  This function is only
400    intended for the bulk encryption feature of cipher.c. */
401 void
402 _gcry_camellia_cbc_dec(void *context, unsigned char *iv,
403                        void *outbuf_arg, const void *inbuf_arg,
404                        size_t nblocks)
405 {
406   CAMELLIA_context *ctx = context;
407   unsigned char *outbuf = outbuf_arg;
408   const unsigned char *inbuf = inbuf_arg;
409   unsigned char savebuf[CAMELLIA_BLOCK_SIZE];
410   int burn_stack_depth = CAMELLIA_decrypt_stack_burn_size;
411
412 #ifdef USE_AESNI_AVX2
413   if (ctx->use_aesni_avx2)
414     {
415       int did_use_aesni_avx2 = 0;
416
417       /* Process data in 32 block chunks. */
418       while (nblocks >= 32)
419         {
420           _gcry_camellia_aesni_avx2_cbc_dec(ctx, outbuf, inbuf, iv);
421
422           nblocks -= 32;
423           outbuf += 32 * CAMELLIA_BLOCK_SIZE;
424           inbuf  += 32 * CAMELLIA_BLOCK_SIZE;
425           did_use_aesni_avx2 = 1;
426         }
427
428       if (did_use_aesni_avx2)
429         {
430           int avx2_burn_stack_depth = 32 * CAMELLIA_BLOCK_SIZE + 16 +
431                                         2 * sizeof(void *) + ASM_EXTRA_STACK;;
432
433           if (burn_stack_depth < avx2_burn_stack_depth)
434             burn_stack_depth = avx2_burn_stack_depth;
435         }
436
437       /* Use generic code to handle smaller chunks... */
438     }
439 #endif
440
441 #ifdef USE_AESNI_AVX
442   if (ctx->use_aesni_avx)
443     {
444       int did_use_aesni_avx = 0;
445
446       /* Process data in 16 block chunks. */
447       while (nblocks >= 16)
448         {
449           _gcry_camellia_aesni_avx_cbc_dec(ctx, outbuf, inbuf, iv);
450
451           nblocks -= 16;
452           outbuf += 16 * CAMELLIA_BLOCK_SIZE;
453           inbuf  += 16 * CAMELLIA_BLOCK_SIZE;
454           did_use_aesni_avx = 1;
455         }
456
457       if (did_use_aesni_avx)
458         {
459           int avx_burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE +
460                                        2 * sizeof(void *) + ASM_EXTRA_STACK;
461
462           if (burn_stack_depth < avx_burn_stack_depth)
463             burn_stack_depth = avx_burn_stack_depth;
464         }
465
466       /* Use generic code to handle smaller chunks... */
467     }
468 #endif
469
470   for ( ;nblocks; nblocks-- )
471     {
472       /* INBUF is needed later and it may be identical to OUTBUF, so store
473          the intermediate result to SAVEBUF.  */
474       Camellia_DecryptBlock(ctx->keybitlength, inbuf, ctx->keytable, savebuf);
475
476       buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, CAMELLIA_BLOCK_SIZE);
477       inbuf += CAMELLIA_BLOCK_SIZE;
478       outbuf += CAMELLIA_BLOCK_SIZE;
479     }
480
481   wipememory(savebuf, sizeof(savebuf));
482   _gcry_burn_stack(burn_stack_depth);
483 }
484
485 /* Bulk decryption of complete blocks in CFB mode.  This function is only
486    intended for the bulk encryption feature of cipher.c. */
487 void
488 _gcry_camellia_cfb_dec(void *context, unsigned char *iv,
489                        void *outbuf_arg, const void *inbuf_arg,
490                        size_t nblocks)
491 {
492   CAMELLIA_context *ctx = context;
493   unsigned char *outbuf = outbuf_arg;
494   const unsigned char *inbuf = inbuf_arg;
495   int burn_stack_depth = CAMELLIA_decrypt_stack_burn_size;
496
497 #ifdef USE_AESNI_AVX2
498   if (ctx->use_aesni_avx2)
499     {
500       int did_use_aesni_avx2 = 0;
501
502       /* Process data in 32 block chunks. */
503       while (nblocks >= 32)
504         {
505           _gcry_camellia_aesni_avx2_cfb_dec(ctx, outbuf, inbuf, iv);
506
507           nblocks -= 32;
508           outbuf += 32 * CAMELLIA_BLOCK_SIZE;
509           inbuf  += 32 * CAMELLIA_BLOCK_SIZE;
510           did_use_aesni_avx2 = 1;
511         }
512
513       if (did_use_aesni_avx2)
514         {
515           int avx2_burn_stack_depth = 32 * CAMELLIA_BLOCK_SIZE + 16 +
516                                         2 * sizeof(void *) + ASM_EXTRA_STACK;
517
518           if (burn_stack_depth < avx2_burn_stack_depth)
519             burn_stack_depth = avx2_burn_stack_depth;
520         }
521
522       /* Use generic code to handle smaller chunks... */
523     }
524 #endif
525
526 #ifdef USE_AESNI_AVX
527   if (ctx->use_aesni_avx)
528     {
529       int did_use_aesni_avx = 0;
530
531       /* Process data in 16 block chunks. */
532       while (nblocks >= 16)
533         {
534           _gcry_camellia_aesni_avx_cfb_dec(ctx, outbuf, inbuf, iv);
535
536           nblocks -= 16;
537           outbuf += 16 * CAMELLIA_BLOCK_SIZE;
538           inbuf  += 16 * CAMELLIA_BLOCK_SIZE;
539           did_use_aesni_avx = 1;
540         }
541
542       if (did_use_aesni_avx)
543         {
544           int avx_burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE +
545                                        2 * sizeof(void *) + ASM_EXTRA_STACK;
546
547           if (burn_stack_depth < avx_burn_stack_depth)
548             burn_stack_depth = avx_burn_stack_depth;
549         }
550
551       /* Use generic code to handle smaller chunks... */
552     }
553 #endif
554
555   for ( ;nblocks; nblocks-- )
556     {
557       Camellia_EncryptBlock(ctx->keybitlength, iv, ctx->keytable, iv);
558       buf_xor_n_copy(outbuf, iv, inbuf, CAMELLIA_BLOCK_SIZE);
559       outbuf += CAMELLIA_BLOCK_SIZE;
560       inbuf  += CAMELLIA_BLOCK_SIZE;
561     }
562
563   _gcry_burn_stack(burn_stack_depth);
564 }
565
566 /* Run the self-tests for CAMELLIA-CTR-128, tests IV increment of bulk CTR
567    encryption.  Returns NULL on success. */
568 static const char*
569 selftest_ctr_128 (void)
570 {
571   const int nblocks = 32+16+1;
572   const int blocksize = CAMELLIA_BLOCK_SIZE;
573   const int context_size = sizeof(CAMELLIA_context);
574
575   return _gcry_selftest_helper_ctr("CAMELLIA", &camellia_setkey,
576            &camellia_encrypt, &_gcry_camellia_ctr_enc, nblocks, blocksize,
577            context_size);
578 }
579
580 /* Run the self-tests for CAMELLIA-CBC-128, tests bulk CBC decryption.
581    Returns NULL on success. */
582 static const char*
583 selftest_cbc_128 (void)
584 {
585   const int nblocks = 32+16+2;
586   const int blocksize = CAMELLIA_BLOCK_SIZE;
587   const int context_size = sizeof(CAMELLIA_context);
588
589   return _gcry_selftest_helper_cbc("CAMELLIA", &camellia_setkey,
590            &camellia_encrypt, &_gcry_camellia_cbc_dec, nblocks, blocksize,
591            context_size);
592 }
593
594 /* Run the self-tests for CAMELLIA-CFB-128, tests bulk CFB decryption.
595    Returns NULL on success. */
596 static const char*
597 selftest_cfb_128 (void)
598 {
599   const int nblocks = 32+16+2;
600   const int blocksize = CAMELLIA_BLOCK_SIZE;
601   const int context_size = sizeof(CAMELLIA_context);
602
603   return _gcry_selftest_helper_cfb("CAMELLIA", &camellia_setkey,
604            &camellia_encrypt, &_gcry_camellia_cfb_dec, nblocks, blocksize,
605            context_size);
606 }
607
608 static const char *
609 selftest(void)
610 {
611   CAMELLIA_context ctx;
612   byte scratch[16];
613   const char *r;
614
615   /* These test vectors are from RFC-3713 */
616   static const byte plaintext[]=
617     {
618       0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
619       0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
620     };
621   static const byte key_128[]=
622     {
623       0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
624       0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
625     };
626   static const byte ciphertext_128[]=
627     {
628       0x67,0x67,0x31,0x38,0x54,0x96,0x69,0x73,
629       0x08,0x57,0x06,0x56,0x48,0xea,0xbe,0x43
630     };
631   static const byte key_192[]=
632     {
633       0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,
634       0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77
635     };
636   static const byte ciphertext_192[]=
637     {
638       0xb4,0x99,0x34,0x01,0xb3,0xe9,0x96,0xf8,
639       0x4e,0xe5,0xce,0xe7,0xd7,0x9b,0x09,0xb9
640     };
641   static const byte key_256[]=
642     {
643       0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,
644       0x98,0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,
645       0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff
646     };
647   static const byte ciphertext_256[]=
648     {
649       0x9a,0xcc,0x23,0x7d,0xff,0x16,0xd7,0x6c,
650       0x20,0xef,0x7c,0x91,0x9e,0x3a,0x75,0x09
651     };
652
653   camellia_setkey(&ctx,key_128,sizeof(key_128));
654   camellia_encrypt(&ctx,scratch,plaintext);
655   if(memcmp(scratch,ciphertext_128,sizeof(ciphertext_128))!=0)
656     return "CAMELLIA-128 test encryption failed.";
657   camellia_decrypt(&ctx,scratch,scratch);
658   if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
659     return "CAMELLIA-128 test decryption failed.";
660
661   camellia_setkey(&ctx,key_192,sizeof(key_192));
662   camellia_encrypt(&ctx,scratch,plaintext);
663   if(memcmp(scratch,ciphertext_192,sizeof(ciphertext_192))!=0)
664     return "CAMELLIA-192 test encryption failed.";
665   camellia_decrypt(&ctx,scratch,scratch);
666   if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
667     return "CAMELLIA-192 test decryption failed.";
668
669   camellia_setkey(&ctx,key_256,sizeof(key_256));
670   camellia_encrypt(&ctx,scratch,plaintext);
671   if(memcmp(scratch,ciphertext_256,sizeof(ciphertext_256))!=0)
672     return "CAMELLIA-256 test encryption failed.";
673   camellia_decrypt(&ctx,scratch,scratch);
674   if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
675     return "CAMELLIA-256 test decryption failed.";
676
677   if ( (r = selftest_ctr_128 ()) )
678     return r;
679
680   if ( (r = selftest_cbc_128 ()) )
681     return r;
682
683   if ( (r = selftest_cfb_128 ()) )
684     return r;
685
686   return NULL;
687 }
688
689 /* These oids are from
690    <http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications_oid.html>,
691    retrieved May 1, 2007. */
692
693 static gcry_cipher_oid_spec_t camellia128_oids[] =
694   {
695     {"1.2.392.200011.61.1.1.1.2", GCRY_CIPHER_MODE_CBC},
696     {"0.3.4401.5.3.1.9.1", GCRY_CIPHER_MODE_ECB},
697     {"0.3.4401.5.3.1.9.3", GCRY_CIPHER_MODE_OFB},
698     {"0.3.4401.5.3.1.9.4", GCRY_CIPHER_MODE_CFB},
699     { NULL }
700   };
701
702 static gcry_cipher_oid_spec_t camellia192_oids[] =
703   {
704     {"1.2.392.200011.61.1.1.1.3", GCRY_CIPHER_MODE_CBC},
705     {"0.3.4401.5.3.1.9.21", GCRY_CIPHER_MODE_ECB},
706     {"0.3.4401.5.3.1.9.23", GCRY_CIPHER_MODE_OFB},
707     {"0.3.4401.5.3.1.9.24", GCRY_CIPHER_MODE_CFB},
708     { NULL }
709   };
710
711 static gcry_cipher_oid_spec_t camellia256_oids[] =
712   {
713     {"1.2.392.200011.61.1.1.1.4", GCRY_CIPHER_MODE_CBC},
714     {"0.3.4401.5.3.1.9.41", GCRY_CIPHER_MODE_ECB},
715     {"0.3.4401.5.3.1.9.43", GCRY_CIPHER_MODE_OFB},
716     {"0.3.4401.5.3.1.9.44", GCRY_CIPHER_MODE_CFB},
717     { NULL }
718   };
719
720 gcry_cipher_spec_t _gcry_cipher_spec_camellia128 =
721   {
722     GCRY_CIPHER_CAMELLIA128, {0, 0},
723     "CAMELLIA128",NULL,camellia128_oids,CAMELLIA_BLOCK_SIZE,128,
724     sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
725   };
726
727 gcry_cipher_spec_t _gcry_cipher_spec_camellia192 =
728   {
729     GCRY_CIPHER_CAMELLIA192, {0, 0},
730     "CAMELLIA192",NULL,camellia192_oids,CAMELLIA_BLOCK_SIZE,192,
731     sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
732   };
733
734 gcry_cipher_spec_t _gcry_cipher_spec_camellia256 =
735   {
736     GCRY_CIPHER_CAMELLIA256, {0, 0},
737     "CAMELLIA256",NULL,camellia256_oids,CAMELLIA_BLOCK_SIZE,256,
738     sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
739   };