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