cipher-selftest: make selftest work with any block-size
[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__)
79 #  define USE_AESNI_AVX 1
80 # endif
81 #endif
82
83 typedef struct
84 {
85   int keybitlength;
86   KEY_TABLE_TYPE keytable;
87 #ifdef USE_AESNI_AVX
88   int use_aesni_avx;            /* AES-NI/AVX implementation shall be used.  */
89 #endif /*USE_AESNI_AVX*/
90 } CAMELLIA_context;
91
92 #ifdef USE_AESNI_AVX
93 /* Assembler implementations of Camellia using AES-NI and AVX.  Process data
94    in 16 block same time.
95  */
96 extern void _gcry_camellia_aesni_avx_ctr_enc(CAMELLIA_context *ctx,
97                                              unsigned char *out,
98                                              const unsigned char *in,
99                                              unsigned char *ctr);
100
101 extern void _gcry_camellia_aesni_avx_cbc_dec(CAMELLIA_context *ctx,
102                                              unsigned char *out,
103                                              const unsigned char *in,
104                                              unsigned char *iv);
105
106 extern void _gcry_camellia_aesni_avx_cfb_dec(CAMELLIA_context *ctx,
107                                              unsigned char *out,
108                                              const unsigned char *in,
109                                              unsigned char *iv);
110 #endif
111
112 static const char *selftest(void);
113
114 static gcry_err_code_t
115 camellia_setkey(void *c, const byte *key, unsigned keylen)
116 {
117   CAMELLIA_context *ctx=c;
118   static int initialized=0;
119   static const char *selftest_failed=NULL;
120
121   if(keylen!=16 && keylen!=24 && keylen!=32)
122     return GPG_ERR_INV_KEYLEN;
123
124   if(!initialized)
125     {
126       initialized=1;
127       selftest_failed=selftest();
128       if(selftest_failed)
129         log_error("%s\n",selftest_failed);
130     }
131
132   if(selftest_failed)
133     return GPG_ERR_SELFTEST_FAILED;
134
135   ctx->keybitlength=keylen*8;
136   Camellia_Ekeygen(ctx->keybitlength,key,ctx->keytable);
137   _gcry_burn_stack
138     ((19+34+34)*sizeof(u32)+2*sizeof(void*) /* camellia_setup256 */
139      +(4+32)*sizeof(u32)+2*sizeof(void*)    /* camellia_setup192 */
140      +0+sizeof(int)+2*sizeof(void*)         /* Camellia_Ekeygen */
141      +3*2*sizeof(void*)                     /* Function calls.  */
142      );
143
144 #ifdef USE_AESNI_AVX
145   ctx->use_aesni_avx = 0;
146   if ((_gcry_get_hw_features () & HWF_INTEL_AESNI) &&
147       (_gcry_get_hw_features () & HWF_INTEL_AVX))
148     {
149       ctx->use_aesni_avx = 1;
150     }
151 #endif
152
153   return 0;
154 }
155
156 static void
157 camellia_encrypt(void *c, byte *outbuf, const byte *inbuf)
158 {
159   CAMELLIA_context *ctx=c;
160
161   Camellia_EncryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
162
163 #define CAMELLIA_encrypt_stack_burn_size \
164   (sizeof(int)+2*sizeof(unsigned char *)+sizeof(void*/*KEY_TABLE_TYPE*/) \
165      +4*sizeof(u32)+4*sizeof(u32) \
166      +2*sizeof(u32*)+4*sizeof(u32) \
167      +2*2*sizeof(void*) /* Function calls.  */ \
168     )
169
170   _gcry_burn_stack(CAMELLIA_encrypt_stack_burn_size);
171 }
172
173 static void
174 camellia_decrypt(void *c, byte *outbuf, const byte *inbuf)
175 {
176   CAMELLIA_context *ctx=c;
177
178   Camellia_DecryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
179
180 #define CAMELLIA_decrypt_stack_burn_size \
181     (sizeof(int)+2*sizeof(unsigned char *)+sizeof(void*/*KEY_TABLE_TYPE*/) \
182      +4*sizeof(u32)+4*sizeof(u32) \
183      +2*sizeof(u32*)+4*sizeof(u32) \
184      +2*2*sizeof(void*) /* Function calls.  */ \
185     )
186
187   _gcry_burn_stack(CAMELLIA_decrypt_stack_burn_size);
188 }
189
190 /* Bulk encryption of complete blocks in CTR mode.  This function is only
191    intended for the bulk encryption feature of cipher.c.  CTR is expected to be
192    of size CAMELLIA_BLOCK_SIZE. */
193 void
194 _gcry_camellia_ctr_enc(void *context, unsigned char *ctr,
195                        void *outbuf_arg, const void *inbuf_arg,
196                        unsigned int nblocks)
197 {
198   CAMELLIA_context *ctx = context;
199   unsigned char *outbuf = outbuf_arg;
200   const unsigned char *inbuf = inbuf_arg;
201   unsigned char tmpbuf[CAMELLIA_BLOCK_SIZE];
202   int burn_stack_depth = CAMELLIA_encrypt_stack_burn_size;
203   int i;
204
205 #ifdef USE_AESNI_AVX
206   if (ctx->use_aesni_avx)
207     {
208       int did_use_aesni_avx = 0;
209
210       /* Process data in 16 block chunks. */
211       while (nblocks >= 16)
212         {
213           _gcry_camellia_aesni_avx_ctr_enc(ctx, outbuf, inbuf, ctr);
214
215           nblocks -= 16;
216           outbuf += 16 * CAMELLIA_BLOCK_SIZE;
217           inbuf  += 16 * CAMELLIA_BLOCK_SIZE;
218           did_use_aesni_avx = 1;
219         }
220
221       if (did_use_aesni_avx)
222         {
223           /* clear AVX registers */
224           asm volatile ("vzeroall;\n":::);
225
226           if (burn_stack_depth < 16 * CAMELLIA_BLOCK_SIZE + 2 * sizeof(void *))
227             burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE + 2 * sizeof(void *);
228         }
229
230       /* Use generic code to handle smaller chunks... */
231       /* TODO: use caching instead? */
232     }
233 #endif
234
235   for ( ;nblocks; nblocks-- )
236     {
237       /* Encrypt the counter. */
238       Camellia_EncryptBlock(ctx->keybitlength, ctr, ctx->keytable, tmpbuf);
239       /* XOR the input with the encrypted counter and store in output.  */
240       buf_xor(outbuf, tmpbuf, inbuf, CAMELLIA_BLOCK_SIZE);
241       outbuf += CAMELLIA_BLOCK_SIZE;
242       inbuf  += CAMELLIA_BLOCK_SIZE;
243       /* Increment the counter.  */
244       for (i = CAMELLIA_BLOCK_SIZE; i > 0; i--)
245         {
246           ctr[i-1]++;
247           if (ctr[i-1])
248             break;
249         }
250     }
251
252   wipememory(tmpbuf, sizeof(tmpbuf));
253   _gcry_burn_stack(burn_stack_depth);
254 }
255
256 /* Bulk decryption of complete blocks in CBC mode.  This function is only
257    intended for the bulk encryption feature of cipher.c. */
258 void
259 _gcry_camellia_cbc_dec(void *context, unsigned char *iv,
260                        void *outbuf_arg, const void *inbuf_arg,
261                        unsigned int nblocks)
262 {
263   CAMELLIA_context *ctx = context;
264   unsigned char *outbuf = outbuf_arg;
265   const unsigned char *inbuf = inbuf_arg;
266   unsigned char savebuf[CAMELLIA_BLOCK_SIZE];
267   int burn_stack_depth = CAMELLIA_decrypt_stack_burn_size;
268
269 #ifdef USE_AESNI_AVX
270   if (ctx->use_aesni_avx)
271     {
272       int did_use_aesni_avx = 0;
273
274       /* Process data in 16 block chunks. */
275       while (nblocks >= 16)
276         {
277           _gcry_camellia_aesni_avx_cbc_dec(ctx, outbuf, inbuf, iv);
278
279           nblocks -= 16;
280           outbuf += 16 * CAMELLIA_BLOCK_SIZE;
281           inbuf  += 16 * CAMELLIA_BLOCK_SIZE;
282           did_use_aesni_avx = 1;
283         }
284
285       if (did_use_aesni_avx)
286         {
287           /* clear AVX registers */
288           asm volatile ("vzeroall;\n":::);
289
290           if (burn_stack_depth < 16 * CAMELLIA_BLOCK_SIZE + 2 * sizeof(void *))
291             burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE + 2 * sizeof(void *);
292         }
293
294       /* Use generic code to handle smaller chunks... */
295     }
296 #endif
297
298   for ( ;nblocks; nblocks-- )
299     {
300       /* We need to save INBUF away because it may be identical to
301          OUTBUF.  */
302       memcpy(savebuf, inbuf, CAMELLIA_BLOCK_SIZE);
303
304       Camellia_DecryptBlock(ctx->keybitlength, inbuf, ctx->keytable, outbuf);
305
306       buf_xor(outbuf, outbuf, iv, CAMELLIA_BLOCK_SIZE);
307       memcpy(iv, savebuf, CAMELLIA_BLOCK_SIZE);
308       inbuf += CAMELLIA_BLOCK_SIZE;
309       outbuf += CAMELLIA_BLOCK_SIZE;
310     }
311
312   wipememory(savebuf, sizeof(savebuf));
313   _gcry_burn_stack(burn_stack_depth);
314 }
315
316 /* Bulk decryption of complete blocks in CFB mode.  This function is only
317    intended for the bulk encryption feature of cipher.c. */
318 void
319 _gcry_camellia_cfb_dec(void *context, unsigned char *iv,
320                        void *outbuf_arg, const void *inbuf_arg,
321                        unsigned int nblocks)
322 {
323   CAMELLIA_context *ctx = context;
324   unsigned char *outbuf = outbuf_arg;
325   const unsigned char *inbuf = inbuf_arg;
326   int burn_stack_depth = CAMELLIA_decrypt_stack_burn_size;
327
328 #ifdef USE_AESNI_AVX
329   if (ctx->use_aesni_avx)
330     {
331       int did_use_aesni_avx = 0;
332
333       /* Process data in 16 block chunks. */
334       while (nblocks >= 16)
335         {
336           _gcry_camellia_aesni_avx_cfb_dec(ctx, outbuf, inbuf, iv);
337
338           nblocks -= 16;
339           outbuf += 16 * CAMELLIA_BLOCK_SIZE;
340           inbuf  += 16 * CAMELLIA_BLOCK_SIZE;
341           did_use_aesni_avx = 1;
342         }
343
344       if (did_use_aesni_avx)
345         {
346           /* clear AVX registers */
347           asm volatile ("vzeroall;\n":::);
348
349           if (burn_stack_depth < 16 * CAMELLIA_BLOCK_SIZE + 2 * sizeof(void *))
350             burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE + 2 * sizeof(void *);
351         }
352
353       /* Use generic code to handle smaller chunks... */
354     }
355 #endif
356
357   for ( ;nblocks; nblocks-- )
358     {
359       Camellia_EncryptBlock(ctx->keybitlength, iv, ctx->keytable, iv);
360       buf_xor_n_copy(outbuf, iv, inbuf, CAMELLIA_BLOCK_SIZE);
361       outbuf += CAMELLIA_BLOCK_SIZE;
362       inbuf  += CAMELLIA_BLOCK_SIZE;
363     }
364
365   _gcry_burn_stack(burn_stack_depth);
366 }
367
368 /* Run the self-tests for CAMELLIA-CTR-128, tests IV increment of bulk CTR
369    encryption.  Returns NULL on success. */
370 static const char*
371 selftest_ctr_128 (void)
372 {
373   const int nblocks = 16+1;
374   const int blocksize = CAMELLIA_BLOCK_SIZE;
375   const int context_size = sizeof(CAMELLIA_context);
376
377   return _gcry_selftest_helper_ctr("CAMELLIA", &camellia_setkey,
378            &camellia_encrypt, &_gcry_camellia_ctr_enc, nblocks, blocksize,
379            context_size);
380 }
381
382 /* Run the self-tests for CAMELLIA-CBC-128, tests bulk CBC decryption.
383    Returns NULL on success. */
384 static const char*
385 selftest_cbc_128 (void)
386 {
387   const int nblocks = 16+2;
388   const int blocksize = CAMELLIA_BLOCK_SIZE;
389   const int context_size = sizeof(CAMELLIA_context);
390
391   return _gcry_selftest_helper_cbc("CAMELLIA", &camellia_setkey,
392            &camellia_encrypt, &_gcry_camellia_cbc_dec, nblocks, blocksize,
393            context_size);
394 }
395
396 /* Run the self-tests for CAMELLIA-CFB-128, tests bulk CFB decryption.
397    Returns NULL on success. */
398 static const char*
399 selftest_cfb_128 (void)
400 {
401   const int nblocks = 16+2;
402   const int blocksize = CAMELLIA_BLOCK_SIZE;
403   const int context_size = sizeof(CAMELLIA_context);
404
405   return _gcry_selftest_helper_cfb("CAMELLIA", &camellia_setkey,
406            &camellia_encrypt, &_gcry_camellia_cfb_dec, nblocks, blocksize,
407            context_size);
408 }
409
410 static const char *
411 selftest(void)
412 {
413   CAMELLIA_context ctx;
414   byte scratch[16];
415   const char *r;
416
417   /* These test vectors are from RFC-3713 */
418   const byte plaintext[]=
419     {
420       0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
421       0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
422     };
423   const byte key_128[]=
424     {
425       0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
426       0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
427     };
428   const byte ciphertext_128[]=
429     {
430       0x67,0x67,0x31,0x38,0x54,0x96,0x69,0x73,
431       0x08,0x57,0x06,0x56,0x48,0xea,0xbe,0x43
432     };
433   const byte key_192[]=
434     {
435       0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,
436       0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77
437     };
438   const byte ciphertext_192[]=
439     {
440       0xb4,0x99,0x34,0x01,0xb3,0xe9,0x96,0xf8,
441       0x4e,0xe5,0xce,0xe7,0xd7,0x9b,0x09,0xb9
442     };
443   const byte key_256[]=
444     {
445       0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,
446       0x98,0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,
447       0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff
448     };
449   const byte ciphertext_256[]=
450     {
451       0x9a,0xcc,0x23,0x7d,0xff,0x16,0xd7,0x6c,
452       0x20,0xef,0x7c,0x91,0x9e,0x3a,0x75,0x09
453     };
454
455   camellia_setkey(&ctx,key_128,sizeof(key_128));
456   camellia_encrypt(&ctx,scratch,plaintext);
457   if(memcmp(scratch,ciphertext_128,sizeof(ciphertext_128))!=0)
458     return "CAMELLIA-128 test encryption failed.";
459   camellia_decrypt(&ctx,scratch,scratch);
460   if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
461     return "CAMELLIA-128 test decryption failed.";
462
463   camellia_setkey(&ctx,key_192,sizeof(key_192));
464   camellia_encrypt(&ctx,scratch,plaintext);
465   if(memcmp(scratch,ciphertext_192,sizeof(ciphertext_192))!=0)
466     return "CAMELLIA-192 test encryption failed.";
467   camellia_decrypt(&ctx,scratch,scratch);
468   if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
469     return "CAMELLIA-192 test decryption failed.";
470
471   camellia_setkey(&ctx,key_256,sizeof(key_256));
472   camellia_encrypt(&ctx,scratch,plaintext);
473   if(memcmp(scratch,ciphertext_256,sizeof(ciphertext_256))!=0)
474     return "CAMELLIA-256 test encryption failed.";
475   camellia_decrypt(&ctx,scratch,scratch);
476   if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
477     return "CAMELLIA-256 test decryption failed.";
478
479   if ( (r = selftest_ctr_128 ()) )
480     return r;
481
482   if ( (r = selftest_cbc_128 ()) )
483     return r;
484
485   if ( (r = selftest_cfb_128 ()) )
486     return r;
487
488   return NULL;
489 }
490
491 /* These oids are from
492    <http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications_oid.html>,
493    retrieved May 1, 2007. */
494
495 static gcry_cipher_oid_spec_t camellia128_oids[] =
496   {
497     {"1.2.392.200011.61.1.1.1.2", GCRY_CIPHER_MODE_CBC},
498     {"0.3.4401.5.3.1.9.1", GCRY_CIPHER_MODE_ECB},
499     {"0.3.4401.5.3.1.9.3", GCRY_CIPHER_MODE_OFB},
500     {"0.3.4401.5.3.1.9.4", GCRY_CIPHER_MODE_CFB},
501     { NULL }
502   };
503
504 static gcry_cipher_oid_spec_t camellia192_oids[] =
505   {
506     {"1.2.392.200011.61.1.1.1.3", GCRY_CIPHER_MODE_CBC},
507     {"0.3.4401.5.3.1.9.21", GCRY_CIPHER_MODE_ECB},
508     {"0.3.4401.5.3.1.9.23", GCRY_CIPHER_MODE_OFB},
509     {"0.3.4401.5.3.1.9.24", GCRY_CIPHER_MODE_CFB},
510     { NULL }
511   };
512
513 static gcry_cipher_oid_spec_t camellia256_oids[] =
514   {
515     {"1.2.392.200011.61.1.1.1.4", GCRY_CIPHER_MODE_CBC},
516     {"0.3.4401.5.3.1.9.41", GCRY_CIPHER_MODE_ECB},
517     {"0.3.4401.5.3.1.9.43", GCRY_CIPHER_MODE_OFB},
518     {"0.3.4401.5.3.1.9.44", GCRY_CIPHER_MODE_CFB},
519     { NULL }
520   };
521
522 gcry_cipher_spec_t _gcry_cipher_spec_camellia128 =
523   {
524     "CAMELLIA128",NULL,camellia128_oids,CAMELLIA_BLOCK_SIZE,128,
525     sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
526   };
527
528 gcry_cipher_spec_t _gcry_cipher_spec_camellia192 =
529   {
530     "CAMELLIA192",NULL,camellia192_oids,CAMELLIA_BLOCK_SIZE,192,
531     sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
532   };
533
534 gcry_cipher_spec_t _gcry_cipher_spec_camellia256 =
535   {
536     "CAMELLIA256",NULL,camellia256_oids,CAMELLIA_BLOCK_SIZE,256,
537     sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
538   };