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 66typedef struct 67{ 68 int keybitlength; 69 KEY_TABLE_TYPE keytable; 70} CAMELLIA_context; 71 72static const char *selftest(void); 73 74static gcry_err_code_t 75camellia_setkey(void *c, const byte *key, unsigned keylen) 76{ 77 CAMELLIA_context *ctx=c; 78 static int initialized=0; 79 static const char *selftest_failed=NULL; 80 81 if(keylen!=16 && keylen!=24 && keylen!=32) 82 return GPG_ERR_INV_KEYLEN; 83 84 if(!initialized) 85 { 86 initialized=1; 87 selftest_failed=selftest(); 88 if(selftest_failed) 89 log_error("%s\n",selftest_failed); 90 } 91 92 if(selftest_failed) 93 return GPG_ERR_SELFTEST_FAILED; 94 95 ctx->keybitlength=keylen*8; 96 Camellia_Ekeygen(ctx->keybitlength,key,ctx->keytable); 97 _gcry_burn_stack 98 ((19+34+34)*sizeof(u32)+2*sizeof(void*) /* camellia_setup256 */ 99 +(4+32)*sizeof(u32)+2*sizeof(void*) /* camellia_setup192 */ 100 +0+sizeof(int)+2*sizeof(void*) /* Camellia_Ekeygen */ 101 +3*2*sizeof(void*) /* Function calls. */ 102 ); 103 104 return 0; 105} 106 107static void 108camellia_encrypt(void *c, byte *outbuf, const byte *inbuf) 109{ 110 CAMELLIA_context *ctx=c; 111 112 Camellia_EncryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf); 113 _gcry_burn_stack 114 (sizeof(int)+2*sizeof(unsigned char *)+sizeof(KEY_TABLE_TYPE) 115 +4*sizeof(u32) 116 +2*sizeof(u32*)+4*sizeof(u32) 117 +2*2*sizeof(void*) /* Function calls. */ 118 ); 119} 120 121static void 122camellia_decrypt(void *c, byte *outbuf, const byte *inbuf) 123{ 124 CAMELLIA_context *ctx=c; 125 126 Camellia_DecryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf); 127 _gcry_burn_stack 128 (sizeof(int)+2*sizeof(unsigned char *)+sizeof(KEY_TABLE_TYPE) 129 +4*sizeof(u32) 130 +2*sizeof(u32*)+4*sizeof(u32) 131 +2*2*sizeof(void*) /* Function calls. */ 132 ); 133} 134 135static const char * 136selftest(void) 137{ 138 CAMELLIA_context ctx; 139 byte scratch[16]; 140 141 /* These test vectors are from RFC-3713 */ 142 const byte plaintext[]= 143 { 144 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, 145 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10 146 }; 147 const byte key_128[]= 148 { 149 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, 150 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10 151 }; 152 const byte ciphertext_128[]= 153 { 154 0x67,0x67,0x31,0x38,0x54,0x96,0x69,0x73, 155 0x08,0x57,0x06,0x56,0x48,0xea,0xbe,0x43 156 }; 157 const byte key_192[]= 158 { 159 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98, 160 0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77 161 }; 162 const byte ciphertext_192[]= 163 { 164 0xb4,0x99,0x34,0x01,0xb3,0xe9,0x96,0xf8, 165 0x4e,0xe5,0xce,0xe7,0xd7,0x9b,0x09,0xb9 166 }; 167 const byte key_256[]= 168 { 169 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba, 170 0x98,0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55, 171 0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff 172 }; 173 const byte ciphertext_256[]= 174 { 175 0x9a,0xcc,0x23,0x7d,0xff,0x16,0xd7,0x6c, 176 0x20,0xef,0x7c,0x91,0x9e,0x3a,0x75,0x09 177 }; 178 179 camellia_setkey(&ctx,key_128,sizeof(key_128)); 180 camellia_encrypt(&ctx,scratch,plaintext); 181 if(memcmp(scratch,ciphertext_128,sizeof(ciphertext_128))!=0) 182 return "CAMELLIA-128 test encryption failed."; 183 camellia_decrypt(&ctx,scratch,scratch); 184 if(memcmp(scratch,plaintext,sizeof(plaintext))!=0) 185 return "CAMELLIA-128 test decryption failed."; 186 187 camellia_setkey(&ctx,key_192,sizeof(key_192)); 188 camellia_encrypt(&ctx,scratch,plaintext); 189 if(memcmp(scratch,ciphertext_192,sizeof(ciphertext_192))!=0) 190 return "CAMELLIA-192 test encryption failed."; 191 camellia_decrypt(&ctx,scratch,scratch); 192 if(memcmp(scratch,plaintext,sizeof(plaintext))!=0) 193 return "CAMELLIA-192 test decryption failed."; 194 195 camellia_setkey(&ctx,key_256,sizeof(key_256)); 196 camellia_encrypt(&ctx,scratch,plaintext); 197 if(memcmp(scratch,ciphertext_256,sizeof(ciphertext_256))!=0) 198 return "CAMELLIA-256 test encryption failed."; 199 camellia_decrypt(&ctx,scratch,scratch); 200 if(memcmp(scratch,plaintext,sizeof(plaintext))!=0) 201 return "CAMELLIA-256 test decryption failed."; 202 203 return NULL; 204} 205 206/* These oids are from 207 <http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications_oid.html>, 208 retrieved May 1, 2007. */ 209 210static gcry_cipher_oid_spec_t camellia128_oids[] = 211 { 212 {"1.2.392.200011.61.1.1.1.2", GCRY_CIPHER_MODE_CBC}, 213 {"0.3.4401.5.3.1.9.1", GCRY_CIPHER_MODE_ECB}, 214 {"0.3.4401.5.3.1.9.3", GCRY_CIPHER_MODE_OFB}, 215 {"0.3.4401.5.3.1.9.4", GCRY_CIPHER_MODE_CFB}, 216 { NULL } 217 }; 218 219static gcry_cipher_oid_spec_t camellia192_oids[] = 220 { 221 {"1.2.392.200011.61.1.1.1.3", GCRY_CIPHER_MODE_CBC}, 222 {"0.3.4401.5.3.1.9.21", GCRY_CIPHER_MODE_ECB}, 223 {"0.3.4401.5.3.1.9.23", GCRY_CIPHER_MODE_OFB}, 224 {"0.3.4401.5.3.1.9.24", GCRY_CIPHER_MODE_CFB}, 225 { NULL } 226 }; 227 228static gcry_cipher_oid_spec_t camellia256_oids[] = 229 { 230 {"1.2.392.200011.61.1.1.1.4", GCRY_CIPHER_MODE_CBC}, 231 {"0.3.4401.5.3.1.9.41", GCRY_CIPHER_MODE_ECB}, 232 {"0.3.4401.5.3.1.9.43", GCRY_CIPHER_MODE_OFB}, 233 {"0.3.4401.5.3.1.9.44", GCRY_CIPHER_MODE_CFB}, 234 { NULL } 235 }; 236 237gcry_cipher_spec_t _gcry_cipher_spec_camellia128 = 238 { 239 "CAMELLIA128",NULL,camellia128_oids,CAMELLIA_BLOCK_SIZE,128, 240 sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt 241 }; 242 243gcry_cipher_spec_t _gcry_cipher_spec_camellia192 = 244 { 245 "CAMELLIA192",NULL,camellia192_oids,CAMELLIA_BLOCK_SIZE,192, 246 sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt 247 }; 248 249gcry_cipher_spec_t _gcry_cipher_spec_camellia256 = 250 { 251 "CAMELLIA256",NULL,camellia256_oids,CAMELLIA_BLOCK_SIZE,256, 252 sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt 253 }; 254