2N/A/* camellia-glue.c - Glue for the Camellia cipher
2N/A * Copyright (C) 2007 Free Software Foundation, Inc.
2N/A *
2N/A * This file is part of Libgcrypt.
2N/A *
2N/A * Libgcrypt is free software; you can redistribute it and/or modify
2N/A * it under the terms of the GNU Lesser General Public License as
2N/A * published by the Free Software Foundation; either version 2.1 of
2N/A * the License, or (at your option) any later version.
2N/A *
2N/A * Libgcrypt is distributed in the hope that it will be useful,
2N/A * but WITHOUT ANY WARRANTY; without even the implied warranty of
2N/A * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2N/A * GNU General Public License for more details.
2N/A *
2N/A * You should have received a copy of the GNU Lesser General Public
2N/A * License along with this program; if not, write to the Free Software
2N/A * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
2N/A * 02110-1301, USA.
2N/A */
2N/A
2N/A/* I put all the libgcrypt-specific stuff in this file to keep the
2N/A camellia.c/camellia.h files exactly as provided by NTT. If they
2N/A update their code, this should make it easier to bring the changes
2N/A in. - dshaw
2N/A
2N/A There is one small change which needs to be done: Include the
2N/A following code at the top of camellia.h: */
2N/A#if 0
2N/A
2N/A/* To use Camellia with libraries it is often useful to keep the name
2N/A * space of the library clean. The following macro is thus useful:
2N/A *
2N/A * #define CAMELLIA_EXT_SYM_PREFIX foo_
2N/A *
2N/A * This prefixes all external symbols with "foo_".
2N/A */
2N/A#ifdef HAVE_CONFIG_H
2N/A#include <config.h>
2N/A#endif
2N/A#ifdef CAMELLIA_EXT_SYM_PREFIX
2N/A#define CAMELLIA_PREFIX1(x,y) x ## y
2N/A#define CAMELLIA_PREFIX2(x,y) CAMELLIA_PREFIX1(x,y)
2N/A#define CAMELLIA_PREFIX(x) CAMELLIA_PREFIX2(CAMELLIA_EXT_SYM_PREFIX,x)
2N/A#define Camellia_Ekeygen CAMELLIA_PREFIX(Camellia_Ekeygen)
2N/A#define Camellia_EncryptBlock CAMELLIA_PREFIX(Camellia_EncryptBlock)
2N/A#define Camellia_DecryptBlock CAMELLIA_PREFIX(Camellia_DecryptBlock)
2N/A#define camellia_decrypt128 CAMELLIA_PREFIX(camellia_decrypt128)
2N/A#define camellia_decrypt256 CAMELLIA_PREFIX(camellia_decrypt256)
2N/A#define camellia_encrypt128 CAMELLIA_PREFIX(camellia_encrypt128)
2N/A#define camellia_encrypt256 CAMELLIA_PREFIX(camellia_encrypt256)
2N/A#define camellia_setup128 CAMELLIA_PREFIX(camellia_setup128)
2N/A#define camellia_setup192 CAMELLIA_PREFIX(camellia_setup192)
2N/A#define camellia_setup256 CAMELLIA_PREFIX(camellia_setup256)
2N/A#endif /*CAMELLIA_EXT_SYM_PREFIX*/
2N/A
2N/A#endif /* Code sample. */
2N/A
2N/A
2N/A#include <config.h>
2N/A#include "types.h"
2N/A#include "g10lib.h"
2N/A#include "cipher.h"
2N/A#include "camellia.h"
2N/A
2N/Atypedef struct
2N/A{
2N/A int keybitlength;
2N/A KEY_TABLE_TYPE keytable;
2N/A} CAMELLIA_context;
2N/A
2N/Astatic const char *selftest(void);
2N/A
2N/Astatic gcry_err_code_t
2N/Acamellia_setkey(void *c, const byte *key, unsigned keylen)
2N/A{
2N/A CAMELLIA_context *ctx=c;
2N/A static int initialized=0;
2N/A static const char *selftest_failed=NULL;
2N/A
2N/A if(keylen!=16 && keylen!=24 && keylen!=32)
2N/A return GPG_ERR_INV_KEYLEN;
2N/A
2N/A if(!initialized)
2N/A {
2N/A initialized=1;
2N/A selftest_failed=selftest();
2N/A if(selftest_failed)
2N/A log_error("%s\n",selftest_failed);
2N/A }
2N/A
2N/A if(selftest_failed)
2N/A return GPG_ERR_SELFTEST_FAILED;
2N/A
2N/A ctx->keybitlength=keylen*8;
2N/A Camellia_Ekeygen(ctx->keybitlength,key,ctx->keytable);
2N/A _gcry_burn_stack
2N/A ((19+34+34)*sizeof(u32)+2*sizeof(void*) /* camellia_setup256 */
2N/A +(4+32)*sizeof(u32)+2*sizeof(void*) /* camellia_setup192 */
2N/A +0+sizeof(int)+2*sizeof(void*) /* Camellia_Ekeygen */
2N/A +3*2*sizeof(void*) /* Function calls. */
2N/A );
2N/A
2N/A return 0;
2N/A}
2N/A
2N/Astatic void
2N/Acamellia_encrypt(void *c, byte *outbuf, const byte *inbuf)
2N/A{
2N/A CAMELLIA_context *ctx=c;
2N/A
2N/A Camellia_EncryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
2N/A _gcry_burn_stack
2N/A (sizeof(int)+2*sizeof(unsigned char *)+sizeof(KEY_TABLE_TYPE)
2N/A +4*sizeof(u32)
2N/A +2*sizeof(u32*)+4*sizeof(u32)
2N/A +2*2*sizeof(void*) /* Function calls. */
2N/A );
2N/A}
2N/A
2N/Astatic void
2N/Acamellia_decrypt(void *c, byte *outbuf, const byte *inbuf)
2N/A{
2N/A CAMELLIA_context *ctx=c;
2N/A
2N/A Camellia_DecryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
2N/A _gcry_burn_stack
2N/A (sizeof(int)+2*sizeof(unsigned char *)+sizeof(KEY_TABLE_TYPE)
2N/A +4*sizeof(u32)
2N/A +2*sizeof(u32*)+4*sizeof(u32)
2N/A +2*2*sizeof(void*) /* Function calls. */
2N/A );
2N/A}
2N/A
2N/Astatic const char *
2N/Aselftest(void)
2N/A{
2N/A CAMELLIA_context ctx;
2N/A byte scratch[16];
2N/A
2N/A /* These test vectors are from RFC-3713 */
2N/A const byte plaintext[]=
2N/A {
2N/A 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
2N/A 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
2N/A };
2N/A const byte key_128[]=
2N/A {
2N/A 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
2N/A 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
2N/A };
2N/A const byte ciphertext_128[]=
2N/A {
2N/A 0x67,0x67,0x31,0x38,0x54,0x96,0x69,0x73,
2N/A 0x08,0x57,0x06,0x56,0x48,0xea,0xbe,0x43
2N/A };
2N/A const byte key_192[]=
2N/A {
2N/A 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,
2N/A 0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77
2N/A };
2N/A const byte ciphertext_192[]=
2N/A {
2N/A 0xb4,0x99,0x34,0x01,0xb3,0xe9,0x96,0xf8,
2N/A 0x4e,0xe5,0xce,0xe7,0xd7,0x9b,0x09,0xb9
2N/A };
2N/A const byte key_256[]=
2N/A {
2N/A 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,
2N/A 0x98,0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,
2N/A 0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff
2N/A };
2N/A const byte ciphertext_256[]=
2N/A {
2N/A 0x9a,0xcc,0x23,0x7d,0xff,0x16,0xd7,0x6c,
2N/A 0x20,0xef,0x7c,0x91,0x9e,0x3a,0x75,0x09
2N/A };
2N/A
2N/A camellia_setkey(&ctx,key_128,sizeof(key_128));
2N/A camellia_encrypt(&ctx,scratch,plaintext);
2N/A if(memcmp(scratch,ciphertext_128,sizeof(ciphertext_128))!=0)
2N/A return "CAMELLIA-128 test encryption failed.";
2N/A camellia_decrypt(&ctx,scratch,scratch);
2N/A if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
2N/A return "CAMELLIA-128 test decryption failed.";
2N/A
2N/A camellia_setkey(&ctx,key_192,sizeof(key_192));
2N/A camellia_encrypt(&ctx,scratch,plaintext);
2N/A if(memcmp(scratch,ciphertext_192,sizeof(ciphertext_192))!=0)
2N/A return "CAMELLIA-192 test encryption failed.";
2N/A camellia_decrypt(&ctx,scratch,scratch);
2N/A if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
2N/A return "CAMELLIA-192 test decryption failed.";
2N/A
2N/A camellia_setkey(&ctx,key_256,sizeof(key_256));
2N/A camellia_encrypt(&ctx,scratch,plaintext);
2N/A if(memcmp(scratch,ciphertext_256,sizeof(ciphertext_256))!=0)
2N/A return "CAMELLIA-256 test encryption failed.";
2N/A camellia_decrypt(&ctx,scratch,scratch);
2N/A if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
2N/A return "CAMELLIA-256 test decryption failed.";
2N/A
2N/A return NULL;
2N/A}
2N/A
2N/A/* These oids are from
2N/A <http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications_oid.html>,
2N/A retrieved May 1, 2007. */
2N/A
2N/Astatic gcry_cipher_oid_spec_t camellia128_oids[] =
2N/A {
2N/A {"1.2.392.200011.61.1.1.1.2", GCRY_CIPHER_MODE_CBC},
2N/A {"0.3.4401.5.3.1.9.1", GCRY_CIPHER_MODE_ECB},
2N/A {"0.3.4401.5.3.1.9.3", GCRY_CIPHER_MODE_OFB},
2N/A {"0.3.4401.5.3.1.9.4", GCRY_CIPHER_MODE_CFB},
2N/A { NULL }
2N/A };
2N/A
2N/Astatic gcry_cipher_oid_spec_t camellia192_oids[] =
2N/A {
2N/A {"1.2.392.200011.61.1.1.1.3", GCRY_CIPHER_MODE_CBC},
2N/A {"0.3.4401.5.3.1.9.21", GCRY_CIPHER_MODE_ECB},
2N/A {"0.3.4401.5.3.1.9.23", GCRY_CIPHER_MODE_OFB},
2N/A {"0.3.4401.5.3.1.9.24", GCRY_CIPHER_MODE_CFB},
2N/A { NULL }
2N/A };
2N/A
2N/Astatic gcry_cipher_oid_spec_t camellia256_oids[] =
2N/A {
2N/A {"1.2.392.200011.61.1.1.1.4", GCRY_CIPHER_MODE_CBC},
2N/A {"0.3.4401.5.3.1.9.41", GCRY_CIPHER_MODE_ECB},
2N/A {"0.3.4401.5.3.1.9.43", GCRY_CIPHER_MODE_OFB},
2N/A {"0.3.4401.5.3.1.9.44", GCRY_CIPHER_MODE_CFB},
2N/A { NULL }
2N/A };
2N/A
2N/Agcry_cipher_spec_t _gcry_cipher_spec_camellia128 =
2N/A {
2N/A "CAMELLIA128",NULL,camellia128_oids,CAMELLIA_BLOCK_SIZE,128,
2N/A sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
2N/A };
2N/A
2N/Agcry_cipher_spec_t _gcry_cipher_spec_camellia192 =
2N/A {
2N/A "CAMELLIA192",NULL,camellia192_oids,CAMELLIA_BLOCK_SIZE,192,
2N/A sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
2N/A };
2N/A
2N/Agcry_cipher_spec_t _gcry_cipher_spec_camellia256 =
2N/A {
2N/A "CAMELLIA256",NULL,camellia256_oids,CAMELLIA_BLOCK_SIZE,256,
2N/A sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
2N/A };