LCOV - code coverage report
Current view: top level - cipher - camellia-glue.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 323 0.0 %
Date: 2016-12-15 12:59:22 Functions: 0 12 0.0 %

          Line data    Source code
       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-internal.h"
      67             : #include "cipher-selftest.h"
      68             : 
      69             : /* Helper macro to force alignment to 16 bytes.  */
      70             : #ifdef HAVE_GCC_ATTRIBUTE_ALIGNED
      71             : # define ATTR_ALIGNED_16  __attribute__ ((aligned (16)))
      72             : #else
      73             : # define ATTR_ALIGNED_16
      74             : #endif
      75             : 
      76             : /* USE_AESNI inidicates whether to compile with Intel AES-NI/AVX code. */
      77             : #undef USE_AESNI_AVX
      78             : #if defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX_SUPPORT)
      79             : # if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
      80             :      defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
      81             : #  define USE_AESNI_AVX 1
      82             : # endif
      83             : #endif
      84             : 
      85             : /* USE_AESNI_AVX2 inidicates whether to compile with Intel AES-NI/AVX2 code. */
      86             : #undef USE_AESNI_AVX2
      87             : #if defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX2_SUPPORT)
      88             : # if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
      89             :      defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
      90             : #  define USE_AESNI_AVX2 1
      91             : # endif
      92             : #endif
      93             : 
      94             : typedef struct
      95             : {
      96             :   KEY_TABLE_TYPE keytable;
      97             :   int keybitlength;
      98             : #ifdef USE_AESNI_AVX
      99             :   unsigned int use_aesni_avx:1; /* AES-NI/AVX implementation shall be used.  */
     100             : #endif /*USE_AESNI_AVX*/
     101             : #ifdef USE_AESNI_AVX2
     102             :   unsigned int use_aesni_avx2:1;/* AES-NI/AVX2 implementation shall be used.  */
     103             : #endif /*USE_AESNI_AVX2*/
     104             : } CAMELLIA_context;
     105             : 
     106             : /* Assembly implementations use SystemV ABI, ABI conversion and additional
     107             :  * stack to store XMM6-XMM15 needed on Win64. */
     108             : #undef ASM_FUNC_ABI
     109             : #undef ASM_EXTRA_STACK
     110             : #if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2)
     111             : # ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
     112             : #  define ASM_FUNC_ABI __attribute__((sysv_abi))
     113             : #  define ASM_EXTRA_STACK (10 * 16)
     114             : # else
     115             : #  define ASM_FUNC_ABI
     116             : #  define ASM_EXTRA_STACK 0
     117             : # endif
     118             : #endif
     119             : 
     120             : #ifdef USE_AESNI_AVX
     121             : /* Assembler implementations of Camellia using AES-NI and AVX.  Process data
     122             :    in 16 block same time.
     123             :  */
     124             : extern void _gcry_camellia_aesni_avx_ctr_enc(CAMELLIA_context *ctx,
     125             :                                              unsigned char *out,
     126             :                                              const unsigned char *in,
     127             :                                              unsigned char *ctr) ASM_FUNC_ABI;
     128             : 
     129             : extern void _gcry_camellia_aesni_avx_cbc_dec(CAMELLIA_context *ctx,
     130             :                                              unsigned char *out,
     131             :                                              const unsigned char *in,
     132             :                                              unsigned char *iv) ASM_FUNC_ABI;
     133             : 
     134             : extern void _gcry_camellia_aesni_avx_cfb_dec(CAMELLIA_context *ctx,
     135             :                                              unsigned char *out,
     136             :                                              const unsigned char *in,
     137             :                                              unsigned char *iv) ASM_FUNC_ABI;
     138             : 
     139             : extern void _gcry_camellia_aesni_avx_ocb_enc(CAMELLIA_context *ctx,
     140             :                                              unsigned char *out,
     141             :                                              const unsigned char *in,
     142             :                                              unsigned char *offset,
     143             :                                              unsigned char *checksum,
     144             :                                              const u64 Ls[16]) ASM_FUNC_ABI;
     145             : 
     146             : extern void _gcry_camellia_aesni_avx_ocb_dec(CAMELLIA_context *ctx,
     147             :                                              unsigned char *out,
     148             :                                              const unsigned char *in,
     149             :                                              unsigned char *offset,
     150             :                                              unsigned char *checksum,
     151             :                                              const u64 Ls[16]) ASM_FUNC_ABI;
     152             : 
     153             : extern void _gcry_camellia_aesni_avx_ocb_auth(CAMELLIA_context *ctx,
     154             :                                              const unsigned char *abuf,
     155             :                                              unsigned char *offset,
     156             :                                              unsigned char *checksum,
     157             :                                              const u64 Ls[16]) ASM_FUNC_ABI;
     158             : 
     159             : extern void _gcry_camellia_aesni_avx_keygen(CAMELLIA_context *ctx,
     160             :                                             const unsigned char *key,
     161             :                                             unsigned int keylen) ASM_FUNC_ABI;
     162             : #endif
     163             : 
     164             : #ifdef USE_AESNI_AVX2
     165             : /* Assembler implementations of Camellia using AES-NI and AVX2.  Process data
     166             :    in 32 block same time.
     167             :  */
     168             : extern void _gcry_camellia_aesni_avx2_ctr_enc(CAMELLIA_context *ctx,
     169             :                                               unsigned char *out,
     170             :                                               const unsigned char *in,
     171             :                                               unsigned char *ctr) ASM_FUNC_ABI;
     172             : 
     173             : extern void _gcry_camellia_aesni_avx2_cbc_dec(CAMELLIA_context *ctx,
     174             :                                               unsigned char *out,
     175             :                                               const unsigned char *in,
     176             :                                               unsigned char *iv) ASM_FUNC_ABI;
     177             : 
     178             : extern void _gcry_camellia_aesni_avx2_cfb_dec(CAMELLIA_context *ctx,
     179             :                                               unsigned char *out,
     180             :                                               const unsigned char *in,
     181             :                                               unsigned char *iv) ASM_FUNC_ABI;
     182             : 
     183             : extern void _gcry_camellia_aesni_avx2_ocb_enc(CAMELLIA_context *ctx,
     184             :                                               unsigned char *out,
     185             :                                               const unsigned char *in,
     186             :                                               unsigned char *offset,
     187             :                                               unsigned char *checksum,
     188             :                                               const u64 Ls[32]) ASM_FUNC_ABI;
     189             : 
     190             : extern void _gcry_camellia_aesni_avx2_ocb_dec(CAMELLIA_context *ctx,
     191             :                                               unsigned char *out,
     192             :                                               const unsigned char *in,
     193             :                                               unsigned char *offset,
     194             :                                               unsigned char *checksum,
     195             :                                               const u64 Ls[32]) ASM_FUNC_ABI;
     196             : 
     197             : extern void _gcry_camellia_aesni_avx2_ocb_auth(CAMELLIA_context *ctx,
     198             :                                                const unsigned char *abuf,
     199             :                                                unsigned char *offset,
     200             :                                                unsigned char *checksum,
     201             :                                                const u64 Ls[32]) ASM_FUNC_ABI;
     202             : #endif
     203             : 
     204             : static const char *selftest(void);
     205             : 
     206             : static gcry_err_code_t
     207           0 : camellia_setkey(void *c, const byte *key, unsigned keylen)
     208             : {
     209           0 :   CAMELLIA_context *ctx=c;
     210             :   static int initialized=0;
     211             :   static const char *selftest_failed=NULL;
     212             : #if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2)
     213           0 :   unsigned int hwf = _gcry_get_hw_features ();
     214             : #endif
     215             : 
     216           0 :   if(keylen!=16 && keylen!=24 && keylen!=32)
     217           0 :     return GPG_ERR_INV_KEYLEN;
     218             : 
     219           0 :   if(!initialized)
     220             :     {
     221           0 :       initialized=1;
     222           0 :       selftest_failed=selftest();
     223           0 :       if(selftest_failed)
     224           0 :         log_error("%s\n",selftest_failed);
     225             :     }
     226             : 
     227           0 :   if(selftest_failed)
     228           0 :     return GPG_ERR_SELFTEST_FAILED;
     229             : 
     230             : #ifdef USE_AESNI_AVX
     231           0 :   ctx->use_aesni_avx = (hwf & HWF_INTEL_AESNI) && (hwf & HWF_INTEL_AVX);
     232             : #endif
     233             : #ifdef USE_AESNI_AVX2
     234           0 :   ctx->use_aesni_avx2 = (hwf & HWF_INTEL_AESNI) && (hwf & HWF_INTEL_AVX2);
     235             : #endif
     236             : 
     237           0 :   ctx->keybitlength=keylen*8;
     238             : 
     239             :   if (0)
     240             :     { }
     241             : #ifdef USE_AESNI_AVX
     242           0 :   else if (ctx->use_aesni_avx)
     243           0 :     _gcry_camellia_aesni_avx_keygen(ctx, key, keylen);
     244             :   else
     245             : #endif
     246             :     {
     247           0 :       Camellia_Ekeygen(ctx->keybitlength,key,ctx->keytable);
     248           0 :       _gcry_burn_stack
     249             :         ((19+34+34)*sizeof(u32)+2*sizeof(void*) /* camellia_setup256 */
     250             :          +(4+32)*sizeof(u32)+2*sizeof(void*)    /* camellia_setup192 */
     251             :          +0+sizeof(int)+2*sizeof(void*)         /* Camellia_Ekeygen */
     252             :          +3*2*sizeof(void*)                     /* Function calls.  */
     253             :          );
     254             :     }
     255             : 
     256           0 :   return 0;
     257             : }
     258             : 
     259             : #ifdef USE_ARM_ASM
     260             : 
     261             : /* Assembly implementations of Camellia. */
     262             : extern void _gcry_camellia_arm_encrypt_block(const KEY_TABLE_TYPE keyTable,
     263             :                                                byte *outbuf, const byte *inbuf,
     264             :                                                const int keybits);
     265             : 
     266             : extern void _gcry_camellia_arm_decrypt_block(const KEY_TABLE_TYPE keyTable,
     267             :                                                byte *outbuf, const byte *inbuf,
     268             :                                                const int keybits);
     269             : 
     270             : static void Camellia_EncryptBlock(const int keyBitLength,
     271             :                                   const unsigned char *plaintext,
     272             :                                   const KEY_TABLE_TYPE keyTable,
     273             :                                   unsigned char *cipherText)
     274             : {
     275             :   _gcry_camellia_arm_encrypt_block(keyTable, cipherText, plaintext,
     276             :                                      keyBitLength);
     277             : }
     278             : 
     279             : static void Camellia_DecryptBlock(const int keyBitLength,
     280             :                                   const unsigned char *cipherText,
     281             :                                   const KEY_TABLE_TYPE keyTable,
     282             :                                   unsigned char *plaintext)
     283             : {
     284             :   _gcry_camellia_arm_decrypt_block(keyTable, plaintext, cipherText,
     285             :                                      keyBitLength);
     286             : }
     287             : 
     288             : #ifdef __aarch64__
     289             : #  define CAMELLIA_encrypt_stack_burn_size (0)
     290             : #  define CAMELLIA_decrypt_stack_burn_size (0)
     291             : #else
     292             : #  define CAMELLIA_encrypt_stack_burn_size (15*4)
     293             : #  define CAMELLIA_decrypt_stack_burn_size (15*4)
     294             : #endif
     295             : 
     296             : static unsigned int
     297             : camellia_encrypt(void *c, byte *outbuf, const byte *inbuf)
     298             : {
     299             :   CAMELLIA_context *ctx = c;
     300             :   Camellia_EncryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
     301             :   return /*burn_stack*/ (CAMELLIA_encrypt_stack_burn_size);
     302             : }
     303             : 
     304             : static unsigned int
     305             : camellia_decrypt(void *c, byte *outbuf, const byte *inbuf)
     306             : {
     307             :   CAMELLIA_context *ctx=c;
     308             :   Camellia_DecryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
     309             :   return /*burn_stack*/ (CAMELLIA_decrypt_stack_burn_size);
     310             : }
     311             : 
     312             : #else /*USE_ARM_ASM*/
     313             : 
     314             : static unsigned int
     315           0 : camellia_encrypt(void *c, byte *outbuf, const byte *inbuf)
     316             : {
     317           0 :   CAMELLIA_context *ctx=c;
     318             : 
     319           0 :   Camellia_EncryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
     320             : 
     321             : #define CAMELLIA_encrypt_stack_burn_size \
     322             :   (sizeof(int)+2*sizeof(unsigned char *)+sizeof(void*/*KEY_TABLE_TYPE*/) \
     323             :      +4*sizeof(u32)+4*sizeof(u32) \
     324             :      +2*sizeof(u32*)+4*sizeof(u32) \
     325             :      +2*2*sizeof(void*) /* Function calls.  */ \
     326             :     )
     327             : 
     328           0 :   return /*burn_stack*/ (CAMELLIA_encrypt_stack_burn_size);
     329             : }
     330             : 
     331             : static unsigned int
     332           0 : camellia_decrypt(void *c, byte *outbuf, const byte *inbuf)
     333             : {
     334           0 :   CAMELLIA_context *ctx=c;
     335             : 
     336           0 :   Camellia_DecryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
     337             : 
     338             : #define CAMELLIA_decrypt_stack_burn_size \
     339             :     (sizeof(int)+2*sizeof(unsigned char *)+sizeof(void*/*KEY_TABLE_TYPE*/) \
     340             :      +4*sizeof(u32)+4*sizeof(u32) \
     341             :      +2*sizeof(u32*)+4*sizeof(u32) \
     342             :      +2*2*sizeof(void*) /* Function calls.  */ \
     343             :     )
     344             : 
     345           0 :   return /*burn_stack*/ (CAMELLIA_decrypt_stack_burn_size);
     346             : }
     347             : 
     348             : #endif /*!USE_ARM_ASM*/
     349             : 
     350             : /* Bulk encryption of complete blocks in CTR mode.  This function is only
     351             :    intended for the bulk encryption feature of cipher.c.  CTR is expected to be
     352             :    of size CAMELLIA_BLOCK_SIZE. */
     353             : void
     354           0 : _gcry_camellia_ctr_enc(void *context, unsigned char *ctr,
     355             :                        void *outbuf_arg, const void *inbuf_arg,
     356             :                        size_t nblocks)
     357             : {
     358           0 :   CAMELLIA_context *ctx = context;
     359           0 :   unsigned char *outbuf = outbuf_arg;
     360           0 :   const unsigned char *inbuf = inbuf_arg;
     361             :   unsigned char tmpbuf[CAMELLIA_BLOCK_SIZE];
     362           0 :   int burn_stack_depth = CAMELLIA_encrypt_stack_burn_size;
     363             :   int i;
     364             : 
     365             : #ifdef USE_AESNI_AVX2
     366           0 :   if (ctx->use_aesni_avx2)
     367             :     {
     368           0 :       int did_use_aesni_avx2 = 0;
     369             : 
     370             :       /* Process data in 32 block chunks. */
     371           0 :       while (nblocks >= 32)
     372             :         {
     373           0 :           _gcry_camellia_aesni_avx2_ctr_enc(ctx, outbuf, inbuf, ctr);
     374             : 
     375           0 :           nblocks -= 32;
     376           0 :           outbuf += 32 * CAMELLIA_BLOCK_SIZE;
     377           0 :           inbuf  += 32 * CAMELLIA_BLOCK_SIZE;
     378           0 :           did_use_aesni_avx2 = 1;
     379             :         }
     380             : 
     381           0 :       if (did_use_aesni_avx2)
     382             :         {
     383           0 :           int avx2_burn_stack_depth = 32 * CAMELLIA_BLOCK_SIZE + 16 +
     384             :                                         2 * sizeof(void *) + ASM_EXTRA_STACK;
     385             : 
     386           0 :           if (burn_stack_depth < avx2_burn_stack_depth)
     387           0 :             burn_stack_depth = avx2_burn_stack_depth;
     388             :         }
     389             : 
     390             :       /* Use generic code to handle smaller chunks... */
     391             :       /* TODO: use caching instead? */
     392             :     }
     393             : #endif
     394             : 
     395             : #ifdef USE_AESNI_AVX
     396           0 :   if (ctx->use_aesni_avx)
     397             :     {
     398           0 :       int did_use_aesni_avx = 0;
     399             : 
     400             :       /* Process data in 16 block chunks. */
     401           0 :       while (nblocks >= 16)
     402             :         {
     403           0 :           _gcry_camellia_aesni_avx_ctr_enc(ctx, outbuf, inbuf, ctr);
     404             : 
     405           0 :           nblocks -= 16;
     406           0 :           outbuf += 16 * CAMELLIA_BLOCK_SIZE;
     407           0 :           inbuf  += 16 * CAMELLIA_BLOCK_SIZE;
     408           0 :           did_use_aesni_avx = 1;
     409             :         }
     410             : 
     411           0 :       if (did_use_aesni_avx)
     412             :         {
     413           0 :           int avx_burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE +
     414             :                                        2 * sizeof(void *) + ASM_EXTRA_STACK;
     415             : 
     416           0 :           if (burn_stack_depth < avx_burn_stack_depth)
     417           0 :             burn_stack_depth = avx_burn_stack_depth;
     418             :         }
     419             : 
     420             :       /* Use generic code to handle smaller chunks... */
     421             :       /* TODO: use caching instead? */
     422             :     }
     423             : #endif
     424             : 
     425           0 :   for ( ;nblocks; nblocks-- )
     426             :     {
     427             :       /* Encrypt the counter. */
     428           0 :       Camellia_EncryptBlock(ctx->keybitlength, ctr, ctx->keytable, tmpbuf);
     429             :       /* XOR the input with the encrypted counter and store in output.  */
     430           0 :       buf_xor(outbuf, tmpbuf, inbuf, CAMELLIA_BLOCK_SIZE);
     431           0 :       outbuf += CAMELLIA_BLOCK_SIZE;
     432           0 :       inbuf  += CAMELLIA_BLOCK_SIZE;
     433             :       /* Increment the counter.  */
     434           0 :       for (i = CAMELLIA_BLOCK_SIZE; i > 0; i--)
     435             :         {
     436           0 :           ctr[i-1]++;
     437           0 :           if (ctr[i-1])
     438           0 :             break;
     439             :         }
     440             :     }
     441             : 
     442           0 :   wipememory(tmpbuf, sizeof(tmpbuf));
     443           0 :   _gcry_burn_stack(burn_stack_depth);
     444           0 : }
     445             : 
     446             : /* Bulk decryption of complete blocks in CBC mode.  This function is only
     447             :    intended for the bulk encryption feature of cipher.c. */
     448             : void
     449           0 : _gcry_camellia_cbc_dec(void *context, unsigned char *iv,
     450             :                        void *outbuf_arg, const void *inbuf_arg,
     451             :                        size_t nblocks)
     452             : {
     453           0 :   CAMELLIA_context *ctx = context;
     454           0 :   unsigned char *outbuf = outbuf_arg;
     455           0 :   const unsigned char *inbuf = inbuf_arg;
     456             :   unsigned char savebuf[CAMELLIA_BLOCK_SIZE];
     457           0 :   int burn_stack_depth = CAMELLIA_decrypt_stack_burn_size;
     458             : 
     459             : #ifdef USE_AESNI_AVX2
     460           0 :   if (ctx->use_aesni_avx2)
     461             :     {
     462           0 :       int did_use_aesni_avx2 = 0;
     463             : 
     464             :       /* Process data in 32 block chunks. */
     465           0 :       while (nblocks >= 32)
     466             :         {
     467           0 :           _gcry_camellia_aesni_avx2_cbc_dec(ctx, outbuf, inbuf, iv);
     468             : 
     469           0 :           nblocks -= 32;
     470           0 :           outbuf += 32 * CAMELLIA_BLOCK_SIZE;
     471           0 :           inbuf  += 32 * CAMELLIA_BLOCK_SIZE;
     472           0 :           did_use_aesni_avx2 = 1;
     473             :         }
     474             : 
     475           0 :       if (did_use_aesni_avx2)
     476             :         {
     477           0 :           int avx2_burn_stack_depth = 32 * CAMELLIA_BLOCK_SIZE + 16 +
     478             :                                         2 * sizeof(void *) + ASM_EXTRA_STACK;;
     479             : 
     480           0 :           if (burn_stack_depth < avx2_burn_stack_depth)
     481           0 :             burn_stack_depth = avx2_burn_stack_depth;
     482             :         }
     483             : 
     484             :       /* Use generic code to handle smaller chunks... */
     485             :     }
     486             : #endif
     487             : 
     488             : #ifdef USE_AESNI_AVX
     489           0 :   if (ctx->use_aesni_avx)
     490             :     {
     491           0 :       int did_use_aesni_avx = 0;
     492             : 
     493             :       /* Process data in 16 block chunks. */
     494           0 :       while (nblocks >= 16)
     495             :         {
     496           0 :           _gcry_camellia_aesni_avx_cbc_dec(ctx, outbuf, inbuf, iv);
     497             : 
     498           0 :           nblocks -= 16;
     499           0 :           outbuf += 16 * CAMELLIA_BLOCK_SIZE;
     500           0 :           inbuf  += 16 * CAMELLIA_BLOCK_SIZE;
     501           0 :           did_use_aesni_avx = 1;
     502             :         }
     503             : 
     504           0 :       if (did_use_aesni_avx)
     505             :         {
     506           0 :           int avx_burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE +
     507             :                                        2 * sizeof(void *) + ASM_EXTRA_STACK;
     508             : 
     509           0 :           if (burn_stack_depth < avx_burn_stack_depth)
     510           0 :             burn_stack_depth = avx_burn_stack_depth;
     511             :         }
     512             : 
     513             :       /* Use generic code to handle smaller chunks... */
     514             :     }
     515             : #endif
     516             : 
     517           0 :   for ( ;nblocks; nblocks-- )
     518             :     {
     519             :       /* INBUF is needed later and it may be identical to OUTBUF, so store
     520             :          the intermediate result to SAVEBUF.  */
     521           0 :       Camellia_DecryptBlock(ctx->keybitlength, inbuf, ctx->keytable, savebuf);
     522             : 
     523           0 :       buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, CAMELLIA_BLOCK_SIZE);
     524           0 :       inbuf += CAMELLIA_BLOCK_SIZE;
     525           0 :       outbuf += CAMELLIA_BLOCK_SIZE;
     526             :     }
     527             : 
     528           0 :   wipememory(savebuf, sizeof(savebuf));
     529           0 :   _gcry_burn_stack(burn_stack_depth);
     530           0 : }
     531             : 
     532             : /* Bulk decryption of complete blocks in CFB mode.  This function is only
     533             :    intended for the bulk encryption feature of cipher.c. */
     534             : void
     535           0 : _gcry_camellia_cfb_dec(void *context, unsigned char *iv,
     536             :                        void *outbuf_arg, const void *inbuf_arg,
     537             :                        size_t nblocks)
     538             : {
     539           0 :   CAMELLIA_context *ctx = context;
     540           0 :   unsigned char *outbuf = outbuf_arg;
     541           0 :   const unsigned char *inbuf = inbuf_arg;
     542           0 :   int burn_stack_depth = CAMELLIA_decrypt_stack_burn_size;
     543             : 
     544             : #ifdef USE_AESNI_AVX2
     545           0 :   if (ctx->use_aesni_avx2)
     546             :     {
     547           0 :       int did_use_aesni_avx2 = 0;
     548             : 
     549             :       /* Process data in 32 block chunks. */
     550           0 :       while (nblocks >= 32)
     551             :         {
     552           0 :           _gcry_camellia_aesni_avx2_cfb_dec(ctx, outbuf, inbuf, iv);
     553             : 
     554           0 :           nblocks -= 32;
     555           0 :           outbuf += 32 * CAMELLIA_BLOCK_SIZE;
     556           0 :           inbuf  += 32 * CAMELLIA_BLOCK_SIZE;
     557           0 :           did_use_aesni_avx2 = 1;
     558             :         }
     559             : 
     560           0 :       if (did_use_aesni_avx2)
     561             :         {
     562           0 :           int avx2_burn_stack_depth = 32 * CAMELLIA_BLOCK_SIZE + 16 +
     563             :                                         2 * sizeof(void *) + ASM_EXTRA_STACK;
     564             : 
     565           0 :           if (burn_stack_depth < avx2_burn_stack_depth)
     566           0 :             burn_stack_depth = avx2_burn_stack_depth;
     567             :         }
     568             : 
     569             :       /* Use generic code to handle smaller chunks... */
     570             :     }
     571             : #endif
     572             : 
     573             : #ifdef USE_AESNI_AVX
     574           0 :   if (ctx->use_aesni_avx)
     575             :     {
     576           0 :       int did_use_aesni_avx = 0;
     577             : 
     578             :       /* Process data in 16 block chunks. */
     579           0 :       while (nblocks >= 16)
     580             :         {
     581           0 :           _gcry_camellia_aesni_avx_cfb_dec(ctx, outbuf, inbuf, iv);
     582             : 
     583           0 :           nblocks -= 16;
     584           0 :           outbuf += 16 * CAMELLIA_BLOCK_SIZE;
     585           0 :           inbuf  += 16 * CAMELLIA_BLOCK_SIZE;
     586           0 :           did_use_aesni_avx = 1;
     587             :         }
     588             : 
     589           0 :       if (did_use_aesni_avx)
     590             :         {
     591           0 :           int avx_burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE +
     592             :                                        2 * sizeof(void *) + ASM_EXTRA_STACK;
     593             : 
     594           0 :           if (burn_stack_depth < avx_burn_stack_depth)
     595           0 :             burn_stack_depth = avx_burn_stack_depth;
     596             :         }
     597             : 
     598             :       /* Use generic code to handle smaller chunks... */
     599             :     }
     600             : #endif
     601             : 
     602           0 :   for ( ;nblocks; nblocks-- )
     603             :     {
     604           0 :       Camellia_EncryptBlock(ctx->keybitlength, iv, ctx->keytable, iv);
     605           0 :       buf_xor_n_copy(outbuf, iv, inbuf, CAMELLIA_BLOCK_SIZE);
     606           0 :       outbuf += CAMELLIA_BLOCK_SIZE;
     607           0 :       inbuf  += CAMELLIA_BLOCK_SIZE;
     608             :     }
     609             : 
     610           0 :   _gcry_burn_stack(burn_stack_depth);
     611           0 : }
     612             : 
     613             : /* Bulk encryption/decryption of complete blocks in OCB mode. */
     614             : size_t
     615           0 : _gcry_camellia_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
     616             :                           const void *inbuf_arg, size_t nblocks, int encrypt)
     617             : {
     618             : #if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2)
     619           0 :   CAMELLIA_context *ctx = (void *)&c->context.c;
     620           0 :   unsigned char *outbuf = outbuf_arg;
     621           0 :   const unsigned char *inbuf = inbuf_arg;
     622             :   int burn_stack_depth;
     623           0 :   u64 blkn = c->u_mode.ocb.data_nblocks;
     624             : 
     625           0 :   burn_stack_depth = encrypt ? CAMELLIA_encrypt_stack_burn_size :
     626             :                               CAMELLIA_decrypt_stack_burn_size;
     627             : #else
     628             :   (void)c;
     629             :   (void)outbuf_arg;
     630             :   (void)inbuf_arg;
     631             :   (void)encrypt;
     632             : #endif
     633             : 
     634             : #ifdef USE_AESNI_AVX2
     635           0 :   if (ctx->use_aesni_avx2)
     636             :     {
     637           0 :       int did_use_aesni_avx2 = 0;
     638             :       u64 Ls[32];
     639           0 :       unsigned int n = 32 - (blkn % 32);
     640             :       u64 *l;
     641             :       int i;
     642             : 
     643           0 :       if (nblocks >= 32)
     644             :         {
     645           0 :           for (i = 0; i < 32; i += 8)
     646             :             {
     647             :               /* Use u64 to store pointers for x32 support (assembly function
     648             :                * assumes 64-bit pointers). */
     649           0 :               Ls[(i + 0 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
     650           0 :               Ls[(i + 1 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
     651           0 :               Ls[(i + 2 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
     652           0 :               Ls[(i + 3 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
     653           0 :               Ls[(i + 4 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
     654           0 :               Ls[(i + 5 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
     655           0 :               Ls[(i + 6 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
     656             :             }
     657             : 
     658           0 :           Ls[(7 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
     659           0 :           Ls[(15 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[4];
     660           0 :           Ls[(23 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
     661           0 :           l = &Ls[(31 + n) % 32];
     662             : 
     663             :           /* Process data in 32 block chunks. */
     664           0 :           while (nblocks >= 32)
     665             :             {
     666           0 :               blkn += 32;
     667           0 :               *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 32);
     668             : 
     669           0 :               if (encrypt)
     670           0 :                 _gcry_camellia_aesni_avx2_ocb_enc(ctx, outbuf, inbuf, c->u_iv.iv,
     671           0 :                                                   c->u_ctr.ctr, Ls);
     672             :               else
     673           0 :                 _gcry_camellia_aesni_avx2_ocb_dec(ctx, outbuf, inbuf, c->u_iv.iv,
     674           0 :                                                   c->u_ctr.ctr, Ls);
     675             : 
     676           0 :               nblocks -= 32;
     677           0 :               outbuf += 32 * CAMELLIA_BLOCK_SIZE;
     678           0 :               inbuf  += 32 * CAMELLIA_BLOCK_SIZE;
     679           0 :               did_use_aesni_avx2 = 1;
     680             :             }
     681             :         }
     682             : 
     683           0 :       if (did_use_aesni_avx2)
     684             :         {
     685           0 :           int avx2_burn_stack_depth = 32 * CAMELLIA_BLOCK_SIZE +
     686             :                                       2 * sizeof(void *) + ASM_EXTRA_STACK;
     687             : 
     688           0 :           if (burn_stack_depth < avx2_burn_stack_depth)
     689           0 :             burn_stack_depth = avx2_burn_stack_depth;
     690             :         }
     691             : 
     692             :       /* Use generic code to handle smaller chunks... */
     693             :     }
     694             : #endif
     695             : 
     696             : #ifdef USE_AESNI_AVX
     697           0 :   if (ctx->use_aesni_avx)
     698             :     {
     699           0 :       int did_use_aesni_avx = 0;
     700             :       u64 Ls[16];
     701           0 :       unsigned int n = 16 - (blkn % 16);
     702             :       u64 *l;
     703             :       int i;
     704             : 
     705           0 :       if (nblocks >= 16)
     706             :         {
     707           0 :           for (i = 0; i < 16; i += 8)
     708             :             {
     709             :               /* Use u64 to store pointers for x32 support (assembly function
     710             :                * assumes 64-bit pointers). */
     711           0 :               Ls[(i + 0 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
     712           0 :               Ls[(i + 1 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
     713           0 :               Ls[(i + 2 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
     714           0 :               Ls[(i + 3 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
     715           0 :               Ls[(i + 4 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
     716           0 :               Ls[(i + 5 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
     717           0 :               Ls[(i + 6 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
     718             :             }
     719             : 
     720           0 :           Ls[(7 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
     721           0 :           l = &Ls[(15 + n) % 16];
     722             : 
     723             :           /* Process data in 16 block chunks. */
     724           0 :           while (nblocks >= 16)
     725             :             {
     726           0 :               blkn += 16;
     727           0 :               *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 16);
     728             : 
     729           0 :               if (encrypt)
     730           0 :                 _gcry_camellia_aesni_avx_ocb_enc(ctx, outbuf, inbuf, c->u_iv.iv,
     731           0 :                                                 c->u_ctr.ctr, Ls);
     732             :               else
     733           0 :                 _gcry_camellia_aesni_avx_ocb_dec(ctx, outbuf, inbuf, c->u_iv.iv,
     734           0 :                                                 c->u_ctr.ctr, Ls);
     735             : 
     736           0 :               nblocks -= 16;
     737           0 :               outbuf += 16 * CAMELLIA_BLOCK_SIZE;
     738           0 :               inbuf  += 16 * CAMELLIA_BLOCK_SIZE;
     739           0 :               did_use_aesni_avx = 1;
     740             :             }
     741             :         }
     742             : 
     743           0 :       if (did_use_aesni_avx)
     744             :         {
     745           0 :           int avx_burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE +
     746             :                                       2 * sizeof(void *) + ASM_EXTRA_STACK;
     747             : 
     748           0 :           if (burn_stack_depth < avx_burn_stack_depth)
     749           0 :             burn_stack_depth = avx_burn_stack_depth;
     750             :         }
     751             : 
     752             :       /* Use generic code to handle smaller chunks... */
     753             :     }
     754             : #endif
     755             : 
     756             : #if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2)
     757           0 :   c->u_mode.ocb.data_nblocks = blkn;
     758             : 
     759           0 :   if (burn_stack_depth)
     760           0 :     _gcry_burn_stack (burn_stack_depth + 4 * sizeof(void *));
     761             : #endif
     762             : 
     763           0 :   return nblocks;
     764             : }
     765             : 
     766             : /* Bulk authentication of complete blocks in OCB mode. */
     767             : size_t
     768           0 : _gcry_camellia_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
     769             :                          size_t nblocks)
     770             : {
     771             : #if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2)
     772           0 :   CAMELLIA_context *ctx = (void *)&c->context.c;
     773           0 :   const unsigned char *abuf = abuf_arg;
     774             :   int burn_stack_depth;
     775           0 :   u64 blkn = c->u_mode.ocb.aad_nblocks;
     776             : 
     777           0 :   burn_stack_depth = CAMELLIA_encrypt_stack_burn_size;
     778             : #else
     779             :   (void)c;
     780             :   (void)abuf_arg;
     781             : #endif
     782             : 
     783             : #ifdef USE_AESNI_AVX2
     784           0 :   if (ctx->use_aesni_avx2)
     785             :     {
     786           0 :       int did_use_aesni_avx2 = 0;
     787             :       u64 Ls[32];
     788           0 :       unsigned int n = 32 - (blkn % 32);
     789             :       u64 *l;
     790             :       int i;
     791             : 
     792           0 :       if (nblocks >= 32)
     793             :         {
     794           0 :           for (i = 0; i < 32; i += 8)
     795             :             {
     796             :               /* Use u64 to store pointers for x32 support (assembly function
     797             :                * assumes 64-bit pointers). */
     798           0 :               Ls[(i + 0 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
     799           0 :               Ls[(i + 1 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
     800           0 :               Ls[(i + 2 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
     801           0 :               Ls[(i + 3 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
     802           0 :               Ls[(i + 4 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
     803           0 :               Ls[(i + 5 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
     804           0 :               Ls[(i + 6 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
     805             :             }
     806             : 
     807           0 :           Ls[(7 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
     808           0 :           Ls[(15 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[4];
     809           0 :           Ls[(23 + n) % 32] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
     810           0 :           l = &Ls[(31 + n) % 32];
     811             : 
     812             :           /* Process data in 32 block chunks. */
     813           0 :           while (nblocks >= 32)
     814             :             {
     815           0 :               blkn += 32;
     816           0 :               *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 32);
     817             : 
     818           0 :               _gcry_camellia_aesni_avx2_ocb_auth(ctx, abuf,
     819           0 :                                                  c->u_mode.ocb.aad_offset,
     820           0 :                                                  c->u_mode.ocb.aad_sum, Ls);
     821             : 
     822           0 :               nblocks -= 32;
     823           0 :               abuf += 32 * CAMELLIA_BLOCK_SIZE;
     824           0 :               did_use_aesni_avx2 = 1;
     825             :             }
     826             :         }
     827             : 
     828           0 :       if (did_use_aesni_avx2)
     829             :         {
     830           0 :           int avx2_burn_stack_depth = 32 * CAMELLIA_BLOCK_SIZE +
     831             :                                       2 * sizeof(void *) + ASM_EXTRA_STACK;
     832             : 
     833           0 :           if (burn_stack_depth < avx2_burn_stack_depth)
     834           0 :             burn_stack_depth = avx2_burn_stack_depth;
     835             :         }
     836             : 
     837             :       /* Use generic code to handle smaller chunks... */
     838             :     }
     839             : #endif
     840             : 
     841             : #ifdef USE_AESNI_AVX
     842           0 :   if (ctx->use_aesni_avx)
     843             :     {
     844           0 :       int did_use_aesni_avx = 0;
     845             :       u64 Ls[16];
     846           0 :       unsigned int n = 16 - (blkn % 16);
     847             :       u64 *l;
     848             :       int i;
     849             : 
     850           0 :       if (nblocks >= 16)
     851             :         {
     852           0 :           for (i = 0; i < 16; i += 8)
     853             :             {
     854             :               /* Use u64 to store pointers for x32 support (assembly function
     855             :                * assumes 64-bit pointers). */
     856           0 :               Ls[(i + 0 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
     857           0 :               Ls[(i + 1 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
     858           0 :               Ls[(i + 2 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
     859           0 :               Ls[(i + 3 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[2];
     860           0 :               Ls[(i + 4 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
     861           0 :               Ls[(i + 5 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[1];
     862           0 :               Ls[(i + 6 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[0];
     863             :             }
     864             : 
     865           0 :           Ls[(7 + n) % 16] = (uintptr_t)(void *)c->u_mode.ocb.L[3];
     866           0 :           l = &Ls[(15 + n) % 16];
     867             : 
     868             :           /* Process data in 16 block chunks. */
     869           0 :           while (nblocks >= 16)
     870             :             {
     871           0 :               blkn += 16;
     872           0 :               *l = (uintptr_t)(void *)ocb_get_l(c, blkn - blkn % 16);
     873             : 
     874           0 :               _gcry_camellia_aesni_avx_ocb_auth(ctx, abuf,
     875           0 :                                                 c->u_mode.ocb.aad_offset,
     876           0 :                                                 c->u_mode.ocb.aad_sum, Ls);
     877             : 
     878           0 :               nblocks -= 16;
     879           0 :               abuf += 16 * CAMELLIA_BLOCK_SIZE;
     880           0 :               did_use_aesni_avx = 1;
     881             :             }
     882             :         }
     883             : 
     884           0 :       if (did_use_aesni_avx)
     885             :         {
     886           0 :           int avx_burn_stack_depth = 16 * CAMELLIA_BLOCK_SIZE +
     887             :                                       2 * sizeof(void *) + ASM_EXTRA_STACK;
     888             : 
     889           0 :           if (burn_stack_depth < avx_burn_stack_depth)
     890           0 :             burn_stack_depth = avx_burn_stack_depth;
     891             :         }
     892             : 
     893             :       /* Use generic code to handle smaller chunks... */
     894             :     }
     895             : #endif
     896             : 
     897             : #if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2)
     898           0 :   c->u_mode.ocb.aad_nblocks = blkn;
     899             : 
     900           0 :   if (burn_stack_depth)
     901           0 :     _gcry_burn_stack (burn_stack_depth + 4 * sizeof(void *));
     902             : #endif
     903             : 
     904           0 :   return nblocks;
     905             : }
     906             : 
     907             : /* Run the self-tests for CAMELLIA-CTR-128, tests IV increment of bulk CTR
     908             :    encryption.  Returns NULL on success. */
     909             : static const char*
     910           0 : selftest_ctr_128 (void)
     911             : {
     912           0 :   const int nblocks = 32+16+1;
     913           0 :   const int blocksize = CAMELLIA_BLOCK_SIZE;
     914           0 :   const int context_size = sizeof(CAMELLIA_context);
     915             : 
     916           0 :   return _gcry_selftest_helper_ctr("CAMELLIA", &camellia_setkey,
     917             :            &camellia_encrypt, &_gcry_camellia_ctr_enc, nblocks, blocksize,
     918             :            context_size);
     919             : }
     920             : 
     921             : /* Run the self-tests for CAMELLIA-CBC-128, tests bulk CBC decryption.
     922             :    Returns NULL on success. */
     923             : static const char*
     924           0 : selftest_cbc_128 (void)
     925             : {
     926           0 :   const int nblocks = 32+16+2;
     927           0 :   const int blocksize = CAMELLIA_BLOCK_SIZE;
     928           0 :   const int context_size = sizeof(CAMELLIA_context);
     929             : 
     930           0 :   return _gcry_selftest_helper_cbc("CAMELLIA", &camellia_setkey,
     931             :            &camellia_encrypt, &_gcry_camellia_cbc_dec, nblocks, blocksize,
     932             :            context_size);
     933             : }
     934             : 
     935             : /* Run the self-tests for CAMELLIA-CFB-128, tests bulk CFB decryption.
     936             :    Returns NULL on success. */
     937             : static const char*
     938           0 : selftest_cfb_128 (void)
     939             : {
     940           0 :   const int nblocks = 32+16+2;
     941           0 :   const int blocksize = CAMELLIA_BLOCK_SIZE;
     942           0 :   const int context_size = sizeof(CAMELLIA_context);
     943             : 
     944           0 :   return _gcry_selftest_helper_cfb("CAMELLIA", &camellia_setkey,
     945             :            &camellia_encrypt, &_gcry_camellia_cfb_dec, nblocks, blocksize,
     946             :            context_size);
     947             : }
     948             : 
     949             : static const char *
     950           0 : selftest(void)
     951             : {
     952             :   CAMELLIA_context ctx;
     953             :   byte scratch[16];
     954             :   const char *r;
     955             : 
     956             :   /* These test vectors are from RFC-3713 */
     957             :   static const byte plaintext[]=
     958             :     {
     959             :       0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
     960             :       0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
     961             :     };
     962             :   static const byte key_128[]=
     963             :     {
     964             :       0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
     965             :       0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
     966             :     };
     967             :   static const byte ciphertext_128[]=
     968             :     {
     969             :       0x67,0x67,0x31,0x38,0x54,0x96,0x69,0x73,
     970             :       0x08,0x57,0x06,0x56,0x48,0xea,0xbe,0x43
     971             :     };
     972             :   static const byte key_192[]=
     973             :     {
     974             :       0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,
     975             :       0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77
     976             :     };
     977             :   static const byte ciphertext_192[]=
     978             :     {
     979             :       0xb4,0x99,0x34,0x01,0xb3,0xe9,0x96,0xf8,
     980             :       0x4e,0xe5,0xce,0xe7,0xd7,0x9b,0x09,0xb9
     981             :     };
     982             :   static const byte key_256[]=
     983             :     {
     984             :       0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,
     985             :       0x98,0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,
     986             :       0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff
     987             :     };
     988             :   static const byte ciphertext_256[]=
     989             :     {
     990             :       0x9a,0xcc,0x23,0x7d,0xff,0x16,0xd7,0x6c,
     991             :       0x20,0xef,0x7c,0x91,0x9e,0x3a,0x75,0x09
     992             :     };
     993             : 
     994           0 :   camellia_setkey(&ctx,key_128,sizeof(key_128));
     995           0 :   camellia_encrypt(&ctx,scratch,plaintext);
     996           0 :   if(memcmp(scratch,ciphertext_128,sizeof(ciphertext_128))!=0)
     997           0 :     return "CAMELLIA-128 test encryption failed.";
     998           0 :   camellia_decrypt(&ctx,scratch,scratch);
     999           0 :   if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
    1000           0 :     return "CAMELLIA-128 test decryption failed.";
    1001             : 
    1002           0 :   camellia_setkey(&ctx,key_192,sizeof(key_192));
    1003           0 :   camellia_encrypt(&ctx,scratch,plaintext);
    1004           0 :   if(memcmp(scratch,ciphertext_192,sizeof(ciphertext_192))!=0)
    1005           0 :     return "CAMELLIA-192 test encryption failed.";
    1006           0 :   camellia_decrypt(&ctx,scratch,scratch);
    1007           0 :   if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
    1008           0 :     return "CAMELLIA-192 test decryption failed.";
    1009             : 
    1010           0 :   camellia_setkey(&ctx,key_256,sizeof(key_256));
    1011           0 :   camellia_encrypt(&ctx,scratch,plaintext);
    1012           0 :   if(memcmp(scratch,ciphertext_256,sizeof(ciphertext_256))!=0)
    1013           0 :     return "CAMELLIA-256 test encryption failed.";
    1014           0 :   camellia_decrypt(&ctx,scratch,scratch);
    1015           0 :   if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
    1016           0 :     return "CAMELLIA-256 test decryption failed.";
    1017             : 
    1018           0 :   if ( (r = selftest_ctr_128 ()) )
    1019           0 :     return r;
    1020             : 
    1021           0 :   if ( (r = selftest_cbc_128 ()) )
    1022           0 :     return r;
    1023             : 
    1024           0 :   if ( (r = selftest_cfb_128 ()) )
    1025           0 :     return r;
    1026             : 
    1027           0 :   return NULL;
    1028             : }
    1029             : 
    1030             : /* These oids are from
    1031             :    <http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications_oid.html>,
    1032             :    retrieved May 1, 2007. */
    1033             : 
    1034             : static gcry_cipher_oid_spec_t camellia128_oids[] =
    1035             :   {
    1036             :     {"1.2.392.200011.61.1.1.1.2", GCRY_CIPHER_MODE_CBC},
    1037             :     {"0.3.4401.5.3.1.9.1", GCRY_CIPHER_MODE_ECB},
    1038             :     {"0.3.4401.5.3.1.9.3", GCRY_CIPHER_MODE_OFB},
    1039             :     {"0.3.4401.5.3.1.9.4", GCRY_CIPHER_MODE_CFB},
    1040             :     { NULL }
    1041             :   };
    1042             : 
    1043             : static gcry_cipher_oid_spec_t camellia192_oids[] =
    1044             :   {
    1045             :     {"1.2.392.200011.61.1.1.1.3", GCRY_CIPHER_MODE_CBC},
    1046             :     {"0.3.4401.5.3.1.9.21", GCRY_CIPHER_MODE_ECB},
    1047             :     {"0.3.4401.5.3.1.9.23", GCRY_CIPHER_MODE_OFB},
    1048             :     {"0.3.4401.5.3.1.9.24", GCRY_CIPHER_MODE_CFB},
    1049             :     { NULL }
    1050             :   };
    1051             : 
    1052             : static gcry_cipher_oid_spec_t camellia256_oids[] =
    1053             :   {
    1054             :     {"1.2.392.200011.61.1.1.1.4", GCRY_CIPHER_MODE_CBC},
    1055             :     {"0.3.4401.5.3.1.9.41", GCRY_CIPHER_MODE_ECB},
    1056             :     {"0.3.4401.5.3.1.9.43", GCRY_CIPHER_MODE_OFB},
    1057             :     {"0.3.4401.5.3.1.9.44", GCRY_CIPHER_MODE_CFB},
    1058             :     { NULL }
    1059             :   };
    1060             : 
    1061             : gcry_cipher_spec_t _gcry_cipher_spec_camellia128 =
    1062             :   {
    1063             :     GCRY_CIPHER_CAMELLIA128, {0, 0},
    1064             :     "CAMELLIA128",NULL,camellia128_oids,CAMELLIA_BLOCK_SIZE,128,
    1065             :     sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
    1066             :   };
    1067             : 
    1068             : gcry_cipher_spec_t _gcry_cipher_spec_camellia192 =
    1069             :   {
    1070             :     GCRY_CIPHER_CAMELLIA192, {0, 0},
    1071             :     "CAMELLIA192",NULL,camellia192_oids,CAMELLIA_BLOCK_SIZE,192,
    1072             :     sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
    1073             :   };
    1074             : 
    1075             : gcry_cipher_spec_t _gcry_cipher_spec_camellia256 =
    1076             :   {
    1077             :     GCRY_CIPHER_CAMELLIA256, {0, 0},
    1078             :     "CAMELLIA256",NULL,camellia256_oids,CAMELLIA_BLOCK_SIZE,256,
    1079             :     sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
    1080             :   };

Generated by: LCOV version 1.12