Update
[gnupg.git] / cipher / camellia-glue.c
1 /* camellia-glue.c - Glue for the Camellia cipher
2  * Copyright (C) 2007, 2008 Free Software Foundation, Inc.
3  *
4  * This file is part of GNUPG.
5  *
6  * GNUPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GNUPG 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 General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 /* I put the GnuPG-specific stuff in this file to keep the
21    camellia.c/camellia.h files exactly as provided by NTT.  If they
22    update their code, this should make it easier to bring the changes
23    in. - dshaw */
24
25 #include <config.h>
26 #include <sys/types.h>
27 #include <string.h>
28 #include "types.h"
29 #include "cipher.h"
30 #include "algorithms.h"
31 #include "util.h"
32 #include "errors.h"
33 #include "camellia.h"
34
35 typedef struct
36 {
37   int keybitlength;
38   KEY_TABLE_TYPE keytable;
39 } CAMELLIA_context;
40
41 static const char *selftest(void);
42
43 static void
44 burn_stack(int bytes)
45 {
46   char buf[128];
47
48   wipememory(buf,sizeof buf);
49   bytes -= sizeof buf;
50   if (bytes > 0)
51     burn_stack (bytes);
52 }
53
54 static int
55 camellia_setkey(void *c, const byte *key, unsigned keylen)
56 {
57   CAMELLIA_context *ctx=c;
58   static int initialized=0;
59   static const char *selftest_failed=NULL;
60
61   if(keylen!=16 && keylen!=24 && keylen!=32)
62     return G10ERR_WRONG_KEYLEN;
63
64   if(!initialized)
65     {
66       initialized=1;
67       selftest_failed=selftest();
68       if(selftest_failed)
69         log_error("%s\n",selftest_failed);
70     }
71
72   if(selftest_failed)
73     return G10ERR_SELFTEST_FAILED;
74
75   ctx->keybitlength=keylen*8;
76   Camellia_Ekeygen(ctx->keybitlength,key,ctx->keytable); 
77
78   burn_stack
79     ((19+34+34)*sizeof(u32)+2*sizeof(void*) /* camellia_setup256 */
80      +(4+32)*sizeof(u32)+2*sizeof(void*)    /* camellia_setup192 */
81      +0+sizeof(int)+2*sizeof(void*)         /* Camellia_Ekeygen */
82      +3*2*sizeof(void*)                     /* Function calls.  */
83      );
84
85   return 0;
86 }
87
88 static void
89 camellia_encrypt(void *c, byte *outbuf, const byte *inbuf)
90 {
91   CAMELLIA_context *ctx=c;
92
93   Camellia_EncryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
94   burn_stack
95     (sizeof(int)+2*sizeof(unsigned char *)+sizeof(KEY_TABLE_TYPE)
96      +4*sizeof(u32)
97      +2*sizeof(u32*)+4*sizeof(u32)
98      +2*2*sizeof(void*) /* Function calls.  */
99     );
100 }
101
102 static void
103 camellia_decrypt(void *c, byte *outbuf, const byte *inbuf)
104 {
105   CAMELLIA_context *ctx=c;
106
107   Camellia_DecryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
108   burn_stack
109     (sizeof(int)+2*sizeof(unsigned char *)+sizeof(KEY_TABLE_TYPE)
110      +4*sizeof(u32)
111      +2*sizeof(u32*)+4*sizeof(u32)
112      +2*2*sizeof(void*) /* Function calls.  */
113     );
114 }
115
116 static const char *
117 selftest(void)
118 {
119   CAMELLIA_context ctx;
120   /* These test vectors are from RFC-3713 */
121   const byte plaintext[]=
122     {
123       0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
124       0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
125     };
126   const byte key_128[]=
127     {
128       0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
129       0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
130     };
131   const byte ciphertext_128[]=
132     {
133       0x67,0x67,0x31,0x38,0x54,0x96,0x69,0x73,
134       0x08,0x57,0x06,0x56,0x48,0xea,0xbe,0x43
135     };
136   const byte key_192[]=
137     {
138       0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,
139       0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77
140     };
141   const byte ciphertext_192[]=
142     {
143       0xb4,0x99,0x34,0x01,0xb3,0xe9,0x96,0xf8,
144       0x4e,0xe5,0xce,0xe7,0xd7,0x9b,0x09,0xb9
145     };
146   const byte key_256[]=
147     {
148       0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,
149       0x98,0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,
150       0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff
151     };
152   const byte ciphertext_256[]=
153     {
154       0x9a,0xcc,0x23,0x7d,0xff,0x16,0xd7,0x6c,
155       0x20,0xef,0x7c,0x91,0x9e,0x3a,0x75,0x09
156     };
157   byte scratch[sizeof(plaintext)];
158
159   camellia_setkey(&ctx,key_128,sizeof(key_128));
160   camellia_encrypt(&ctx,scratch,plaintext);
161   if(memcmp(scratch,ciphertext_128,sizeof(scratch))!=0)
162     return "CAMELLIA128 test encryption failed.";
163   camellia_decrypt(&ctx,scratch,scratch);
164   if(memcmp(scratch,plaintext,sizeof(scratch))!=0)
165     return "CAMELLIA128 test decryption failed.";
166
167   camellia_setkey(&ctx,key_192,sizeof(key_192));
168   camellia_encrypt(&ctx,scratch,plaintext);
169   if(memcmp(scratch,ciphertext_192,sizeof(scratch))!=0)
170     return "CAMELLIA192 test encryption failed.";
171   camellia_decrypt(&ctx,scratch,scratch);
172   if(memcmp(scratch,plaintext,sizeof(scratch))!=0)
173     return "CAMELLIA192 test decryption failed.";
174
175   camellia_setkey(&ctx,key_256,sizeof(key_256));
176   camellia_encrypt(&ctx,scratch,plaintext);
177   if(memcmp(scratch,ciphertext_256,sizeof(scratch))!=0)
178     return "CAMELLIA256 test encryption failed.";
179   camellia_decrypt(&ctx,scratch,scratch);
180   if(memcmp(scratch,plaintext,sizeof(scratch))!=0)
181     return "CAMELLIA256 test decryption failed.";
182
183   return NULL;
184 }
185
186 const char *
187 camellia_get_info(int algo, size_t *keylen,
188                   size_t *blocksize, size_t *contextsize,
189                   int (**r_setkey)(void *c, const byte *key, unsigned keylen),
190                   void (**r_encrypt)(void *c, byte *outbuf, const byte *inbuf),
191                   void (**r_decrypt)(void *c, byte *outbuf, const byte *inbuf)
192                   )
193 {
194   *blocksize = CAMELLIA_BLOCK_SIZE;
195   *contextsize = sizeof (CAMELLIA_context);
196
197   *r_setkey = camellia_setkey;
198   *r_encrypt = camellia_encrypt;
199   *r_decrypt = camellia_decrypt;
200
201   if(algo==CIPHER_ALGO_CAMELLIA128)
202     {
203       *keylen = 128;
204       return "CAMELLIA128";
205     }
206   else if(algo==CIPHER_ALGO_CAMELLIA192)
207     {
208       *keylen = 192;
209       return "CAMELLIA192";
210     }
211   else if(algo==CIPHER_ALGO_CAMELLIA256)
212     {
213       *keylen = 256;
214       return "CAMELLIA256";
215     }
216   else
217     return NULL;
218 }