More info from GCRYCTL_PRINT_CONFIG.
[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 /* Need to redefine the external symbols to keep the libgcrypt name
31    space clean.  */ 
32 #define Camellia_Ekeygen      _gcry_Camellia_Ekeygen
33 #define Camellia_EncryptBlock _gcry_Camellia_EncryptBlock
34 #define Camellia_DecryptBlock _gcry_Camellia_DecryptBlock
35 #define camellia_decrypt128   _gcry_camellia_decrypt128
36 #define camellia_decrypt256   _gcry_camellia_decrypt256
37 #define camellia_encrypt128   _gcry_camellia_encrypt128
38 #define camellia_encrypt256   _gcry_camellia_encrypt256
39 #define camellia_setup128     _gcry_camellia_setup128  
40 #define camellia_setup192     _gcry_camellia_setup192  
41 #define camellia_setup256     _gcry_camellia_setup256
42 #endif /* Code sample. */
43
44
45 #include <config.h>
46 #include "types.h"
47 #include "g10lib.h"
48 #include "cipher.h"
49 #include "camellia.h"
50
51 typedef struct
52 {
53   int keybitlength;
54   KEY_TABLE_TYPE keytable;
55 } CAMELLIA_context;
56
57 static const char *selftest(void);
58
59 static gcry_err_code_t
60 camellia_setkey(void *c, const byte *key, unsigned keylen)
61 {
62   CAMELLIA_context *ctx=c;
63   static int initialized=0;
64   static const char *selftest_failed=NULL;
65
66   if(keylen!=16 && keylen!=24 && keylen!=32)
67     return GPG_ERR_INV_KEYLEN;
68
69   if(!initialized)
70     {
71       initialized=1;
72       selftest_failed=selftest();
73       if(selftest_failed)
74         log_error("%s\n",selftest_failed);
75     }
76
77   if(selftest_failed)
78     return GPG_ERR_SELFTEST_FAILED;
79
80   ctx->keybitlength=keylen*8;
81   Camellia_Ekeygen(ctx->keybitlength,key,ctx->keytable);
82   _gcry_burn_stack(4+4+6+34+34+sizeof(unsigned char *)+sizeof(u32 *));
83
84   return 0;
85 }
86
87 static void
88 camellia_encrypt(void *c, byte *outbuf, const byte *inbuf)
89 {
90   CAMELLIA_context *ctx=c;
91
92   Camellia_EncryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
93   _gcry_burn_stack(sizeof(int)+sizeof(unsigned char *)+sizeof(KEY_TABLE_TYPE)
94                    +sizeof(unsigned char *)+16+4+4+4+4+sizeof(u32 *)
95                    +sizeof(u32 *));
96 }
97
98 static void
99 camellia_decrypt(void *c, byte *outbuf, const byte *inbuf)
100 {
101   CAMELLIA_context *ctx=c;
102
103   Camellia_DecryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
104   _gcry_burn_stack(sizeof(int)+sizeof(unsigned char *)+sizeof(KEY_TABLE_TYPE)
105                    +sizeof(unsigned char *)+16+4+4+4+4+sizeof(u32 *)
106                    +sizeof(u32 *));
107 }
108
109 static const char *
110 selftest(void)
111 {
112   CAMELLIA_context ctx;
113   byte scratch[16];
114   
115   /* These test vectors are from RFC-3713 */
116   const byte plaintext[]=
117     {
118       0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
119       0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
120     };
121   const byte key_128[]=
122     {
123       0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
124       0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
125     };
126   const byte ciphertext_128[]=
127     {
128       0x67,0x67,0x31,0x38,0x54,0x96,0x69,0x73,
129       0x08,0x57,0x06,0x56,0x48,0xea,0xbe,0x43
130     };
131   const byte key_192[]=
132     {
133       0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,
134       0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77
135     };
136   const byte ciphertext_192[]=
137     {
138       0xb4,0x99,0x34,0x01,0xb3,0xe9,0x96,0xf8,
139       0x4e,0xe5,0xce,0xe7,0xd7,0x9b,0x09,0xb9
140     };
141   const byte key_256[]=
142     {
143       0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,
144       0x98,0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,
145       0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff
146     };
147   const byte ciphertext_256[]=
148     {
149       0x9a,0xcc,0x23,0x7d,0xff,0x16,0xd7,0x6c,
150       0x20,0xef,0x7c,0x91,0x9e,0x3a,0x75,0x09
151     };
152
153   camellia_setkey(&ctx,key_128,sizeof(key_128));
154   camellia_encrypt(&ctx,scratch,plaintext);
155   if(memcmp(scratch,ciphertext_128,sizeof(ciphertext_128))!=0)
156     return "CAMELLIA-128 test encryption failed.";
157   camellia_decrypt(&ctx,scratch,scratch);
158   if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
159     return "CAMELLIA-128 test decryption failed.";
160
161   camellia_setkey(&ctx,key_192,sizeof(key_192));
162   camellia_encrypt(&ctx,scratch,plaintext);
163   if(memcmp(scratch,ciphertext_192,sizeof(ciphertext_192))!=0)
164     return "CAMELLIA-192 test encryption failed.";
165   camellia_decrypt(&ctx,scratch,scratch);
166   if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
167     return "CAMELLIA-192 test decryption failed.";
168
169   camellia_setkey(&ctx,key_256,sizeof(key_256));
170   camellia_encrypt(&ctx,scratch,plaintext);
171   if(memcmp(scratch,ciphertext_256,sizeof(ciphertext_256))!=0)
172     return "CAMELLIA-256 test encryption failed.";
173   camellia_decrypt(&ctx,scratch,scratch);
174   if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
175     return "CAMELLIA-256 test decryption failed.";
176
177   return NULL;
178 }
179
180 /* These oids are from
181    <http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications_oid.html>,
182    retrieved May 1, 2007. */
183
184 static gcry_cipher_oid_spec_t camellia128_oids[] =
185   {
186     {"1.2.392.200011.61.1.1.1.2", GCRY_CIPHER_MODE_CBC},
187     {"0.3.4401.5.3.1.9.1", GCRY_CIPHER_MODE_ECB},
188     {"0.3.4401.5.3.1.9.3", GCRY_CIPHER_MODE_OFB},
189     {"0.3.4401.5.3.1.9.4", GCRY_CIPHER_MODE_CFB},
190     { NULL }
191   };
192
193 static gcry_cipher_oid_spec_t camellia192_oids[] =
194   {
195     {"1.2.392.200011.61.1.1.1.3", GCRY_CIPHER_MODE_CBC},
196     {"0.3.4401.5.3.1.9.21", GCRY_CIPHER_MODE_ECB},
197     {"0.3.4401.5.3.1.9.23", GCRY_CIPHER_MODE_OFB},
198     {"0.3.4401.5.3.1.9.24", GCRY_CIPHER_MODE_CFB},
199     { NULL }
200   };
201
202 static gcry_cipher_oid_spec_t camellia256_oids[] =
203   {
204     {"1.2.392.200011.61.1.1.1.4", GCRY_CIPHER_MODE_CBC},
205     {"0.3.4401.5.3.1.9.41", GCRY_CIPHER_MODE_ECB},
206     {"0.3.4401.5.3.1.9.43", GCRY_CIPHER_MODE_OFB},
207     {"0.3.4401.5.3.1.9.44", GCRY_CIPHER_MODE_CFB},
208     { NULL }
209   };
210
211 gcry_cipher_spec_t _gcry_cipher_spec_camellia128 =
212   {
213     "CAMELLIA128",NULL,camellia128_oids,CAMELLIA_BLOCK_SIZE,128,
214     sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
215   };
216
217 gcry_cipher_spec_t _gcry_cipher_spec_camellia192 =
218   {
219     "CAMELLIA192",NULL,camellia192_oids,CAMELLIA_BLOCK_SIZE,192,
220     sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
221   };
222
223 gcry_cipher_spec_t _gcry_cipher_spec_camellia256 =
224   {
225     "CAMELLIA256",NULL,camellia256_oids,CAMELLIA_BLOCK_SIZE,256,
226     sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
227   };