Switched to GPLv3.
[gnupg.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 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!=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   byte scratch[16];
121
122   /* These test vectors are from RFC-3713 */
123   const byte plaintext[]=
124     {
125       0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
126       0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
127     };
128   const byte key_256[]=
129     {
130       0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,
131       0x98,0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,
132       0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff
133     };
134   const byte ciphertext_256[]=
135     {
136       0x9a,0xcc,0x23,0x7d,0xff,0x16,0xd7,0x6c,
137       0x20,0xef,0x7c,0x91,0x9e,0x3a,0x75,0x09
138     };
139
140   camellia_setkey(&ctx,key_256,sizeof(key_256));
141   camellia_encrypt(&ctx,scratch,plaintext);
142   if(memcmp(scratch,ciphertext_256,sizeof(ciphertext_256))!=0)
143     return "CAMELLIA-256 test encryption failed.";
144   camellia_decrypt(&ctx,scratch,scratch);
145   if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
146     return "CAMELLIA-256 test decryption failed.";
147
148   return NULL;
149 }
150
151 const char *
152 camellia_get_info(int algo, size_t *keylen,
153                   size_t *blocksize, size_t *contextsize,
154                   int (**r_setkey)(void *c, const byte *key, unsigned keylen),
155                   void (**r_encrypt)(void *c, byte *outbuf, const byte *inbuf),
156                   void (**r_decrypt)(void *c, byte *outbuf, const byte *inbuf)
157                   )
158 {
159   *keylen = 256;
160   *blocksize = CAMELLIA_BLOCK_SIZE;
161   *contextsize = sizeof (CAMELLIA_context);
162
163   *r_setkey = camellia_setkey;
164   *r_encrypt = camellia_encrypt;
165   *r_decrypt = camellia_decrypt;
166
167   if(algo==CIPHER_ALGO_CAMELLIA)
168     return "CAMELLIA";
169
170   return NULL;
171 }