da9dca35e4f48af83fd7c2576e651e21d6b150e7
[openssl.git] / crypto / evp / e_camellia.c
1 /* crypto/evp/e_camellia.c -*- mode:C; c-file-style: "eay" -*- */
2 /* ====================================================================
3  * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer. 
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in
14  *    the documentation and/or other materials provided with the
15  *    distribution.
16  *
17  * 3. All advertising materials mentioning features or use of this
18  *    software must display the following acknowledgment:
19  *    "This product includes software developed by the OpenSSL Project
20  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
21  *
22  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23  *    endorse or promote products derived from this software without
24  *    prior written permission. For written permission, please contact
25  *    openssl-core@openssl.org.
26  *
27  * 5. Products derived from this software may not be called "OpenSSL"
28  *    nor may "OpenSSL" appear in their names without prior written
29  *    permission of the OpenSSL Project.
30  *
31  * 6. Redistributions of any form whatsoever must retain the following
32  *    acknowledgment:
33  *    "This product includes software developed by the OpenSSL Project
34  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
35  *
36  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47  * OF THE POSSIBILITY OF SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This product includes cryptographic software written by Eric Young
51  * (eay@cryptsoft.com).  This product includes software written by Tim
52  * Hudson (tjh@cryptsoft.com).
53  *
54  */
55
56 #include <openssl/opensslconf.h>
57 #ifndef OPENSSL_NO_CAMELLIA
58 #include <openssl/evp.h>
59 #include <openssl/err.h>
60 #include <string.h>
61 #include <assert.h>
62 #include <openssl/camellia.h>
63 #include "evp_locl.h"
64 #include "modes_lcl.h"
65
66 static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
67         const unsigned char *iv, int enc);
68
69 /* Camellia subkey Structure */
70 typedef struct
71         {
72         CAMELLIA_KEY ks;
73         block128_f block;
74         union {
75                 cbc128_f cbc;
76                 ctr128_f ctr;
77         } stream;
78         } EVP_CAMELLIA_KEY;
79
80 #define MAXBITCHUNK     ((size_t)1<<(sizeof(size_t)*8-4))
81
82 /* Attribute operation for Camellia */
83 #define data(ctx)       EVP_C_DATA(EVP_CAMELLIA_KEY,ctx)
84
85 #if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
86 /* ---------^^^ this is not a typo, just a way to detect that
87  * assembler support was in general requested... */
88 #include "sparc_arch.h"
89
90 extern unsigned int OPENSSL_sparcv9cap_P[];
91
92 #define SPARC_CMLL_CAPABLE      (OPENSSL_sparcv9cap_P[1] & CFR_CAMELLIA)
93
94 void    cmll_t4_set_key (const unsigned char *key, int bits,
95                                 CAMELLIA_KEY *ks);
96 void    cmll_t4_encrypt (const unsigned char *in, unsigned char *out,
97                                 const CAMELLIA_KEY *key);
98 void    cmll_t4_decrypt (const unsigned char *in, unsigned char *out,
99                                 const CAMELLIA_KEY *key);
100
101 void    cmll128_t4_cbc_encrypt (const unsigned char *in, unsigned char *out,
102                                 size_t len, const CAMELLIA_KEY *key,
103                                 unsigned char *ivec);
104 void    cmll128_t4_cbc_decrypt (const unsigned char *in, unsigned char *out,
105                                 size_t len, const CAMELLIA_KEY *key,
106                                 unsigned char *ivec);
107 void    cmll256_t4_cbc_encrypt (const unsigned char *in, unsigned char *out,
108                                 size_t len, const CAMELLIA_KEY *key,
109                                 unsigned char *ivec);
110 void    cmll256_t4_cbc_decrypt (const unsigned char *in, unsigned char *out,
111                                 size_t len, const CAMELLIA_KEY *key,
112                                 unsigned char *ivec);
113 void    cmll128_t4_ctr32_encrypt (const unsigned char *in, unsigned char *out,
114                                 size_t blocks, const CAMELLIA_KEY *key,
115                                 unsigned char *ivec);
116 void    cmll256_t4_ctr32_encrypt (const unsigned char *in, unsigned char *out,
117                                 size_t blocks, const CAMELLIA_KEY *key,
118                                 unsigned char *ivec);
119
120 static int cmll_t4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
121                    const unsigned char *iv, int enc)
122         {
123         int ret, mode, bits;
124         EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *)ctx->cipher_data;
125
126         mode = ctx->cipher->flags & EVP_CIPH_MODE;
127         bits = ctx->key_len*8;
128
129         cmll_t4_set_key(key, bits, &dat->ks);
130
131         if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
132             && !enc)
133                 {
134                     ret = 0;
135                     dat->block  = (block128_f)cmll_t4_decrypt;
136                     switch (bits) {
137                     case 128:
138                         dat->stream.cbc = mode==EVP_CIPH_CBC_MODE ?
139                                                 (cbc128_f)cmll128_t4_cbc_decrypt :
140                                                 NULL;
141                         break;
142                     case 192:
143                     case 256:
144                         dat->stream.cbc = mode==EVP_CIPH_CBC_MODE ?
145                                                 (cbc128_f)cmll256_t4_cbc_decrypt :
146                                                 NULL;
147                         break;
148                     default:
149                         ret = -1;
150                     }
151                 }
152         else    {
153                     ret = 0;
154                     dat->block  = (block128_f)cmll_t4_encrypt;
155                     switch (bits) {
156                     case 128:
157                         if (mode==EVP_CIPH_CBC_MODE)
158                                 dat->stream.cbc = (cbc128_f)cmll128_t4_cbc_encrypt;
159                         else if (mode==EVP_CIPH_CTR_MODE)
160                                 dat->stream.ctr = (ctr128_f)cmll128_t4_ctr32_encrypt;
161                         else
162                                 dat->stream.cbc = NULL;
163                         break;
164                     case 192:
165                     case 256:
166                         if (mode==EVP_CIPH_CBC_MODE)
167                                 dat->stream.cbc = (cbc128_f)cmll256_t4_cbc_encrypt;
168                         else if (mode==EVP_CIPH_CTR_MODE)
169                                 dat->stream.ctr = (ctr128_f)cmll256_t4_ctr32_encrypt;
170                         else
171                                 dat->stream.cbc = NULL;
172                         break;
173                     default:
174                         ret = -1;
175                     }
176                 }
177
178         if(ret < 0)
179                 {
180                 EVPerr(EVP_F_CAMELLIA_INIT_KEY,EVP_R_CAMELLIA_KEY_SETUP_FAILED);
181                 return 0;
182                 }
183
184         return 1;
185         }
186
187 #define cmll_t4_cbc_cipher camellia_cbc_cipher
188 static int cmll_t4_cbc_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
189         const unsigned char *in, size_t len);
190
191 #define cmll_t4_ecb_cipher camellia_ecb_cipher 
192 static int cmll_t4_ecb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
193         const unsigned char *in, size_t len);
194
195 #define cmll_t4_ofb_cipher camellia_ofb_cipher
196 static int cmll_t4_ofb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
197         const unsigned char *in,size_t len);
198
199 #define cmll_t4_cfb_cipher camellia_cfb_cipher
200 static int cmll_t4_cfb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
201         const unsigned char *in,size_t len);
202
203 #define cmll_t4_cfb8_cipher camellia_cfb8_cipher
204 static int cmll_t4_cfb8_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
205         const unsigned char *in,size_t len);
206
207 #define cmll_t4_cfb1_cipher camellia_cfb1_cipher
208 static int cmll_t4_cfb1_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
209         const unsigned char *in,size_t len);
210
211 #define cmll_t4_ctr_cipher camellia_ctr_cipher
212 static int cmll_t4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
213                 const unsigned char *in, size_t len);
214
215 #define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
216 static const EVP_CIPHER cmll_t4_##keylen##_##mode = { \
217         nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
218         flags|EVP_CIPH_##MODE##_MODE,   \
219         cmll_t4_init_key,               \
220         cmll_t4_##mode##_cipher,        \
221         NULL,                           \
222         sizeof(EVP_CAMELLIA_KEY),       \
223         NULL,NULL,NULL,NULL }; \
224 static const EVP_CIPHER camellia_##keylen##_##mode = { \
225         nid##_##keylen##_##nmode,blocksize,     \
226         keylen/8,ivlen, \
227         flags|EVP_CIPH_##MODE##_MODE,   \
228         camellia_init_key,              \
229         camellia_##mode##_cipher,       \
230         NULL,                           \
231         sizeof(EVP_CAMELLIA_KEY),       \
232         NULL,NULL,NULL,NULL }; \
233 const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
234 { return SPARC_CMLL_CAPABLE?&cmll_t4_##keylen##_##mode:&camellia_##keylen##_##mode; }
235
236 #else
237
238 #define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
239 static const EVP_CIPHER camellia_##keylen##_##mode = { \
240         nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
241         flags|EVP_CIPH_##MODE##_MODE,   \
242         camellia_init_key,              \
243         camellia_##mode##_cipher,       \
244         NULL,                           \
245         sizeof(EVP_CAMELLIA_KEY),       \
246         NULL,NULL,NULL,NULL }; \
247 const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
248 { return &camellia_##keylen##_##mode; }
249
250 #endif
251
252 #define BLOCK_CIPHER_generic_pack(nid,keylen,flags)             \
253         BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)     \
254         BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)      \
255         BLOCK_CIPHER_generic(nid,keylen,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)   \
256         BLOCK_CIPHER_generic(nid,keylen,1,16,cfb128,cfb,CFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)   \
257         BLOCK_CIPHER_generic(nid,keylen,1,16,cfb1,cfb1,CFB,flags)       \
258         BLOCK_CIPHER_generic(nid,keylen,1,16,cfb8,cfb8,CFB,flags)
259 #if 0
260         BLOCK_CIPHER_generic(nid,keylen,1,16,ctr,ctr,CTR,flags)
261 #endif
262
263 /* The subkey for Camellia is generated. */ 
264 static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
265         const unsigned char *iv, int enc)
266         {
267         int ret, mode;
268         EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *)ctx->cipher_data;
269
270         ret=Camellia_set_key(key, ctx->key_len * 8, &dat->ks);
271         if(ret < 0)
272                 {
273                 EVPerr(EVP_F_CAMELLIA_INIT_KEY,EVP_R_CAMELLIA_KEY_SETUP_FAILED);
274                 return 0;
275                 }
276
277         mode = ctx->cipher->flags & EVP_CIPH_MODE;
278         if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
279             && !enc)
280                 {
281                 dat->block      = (block128_f)Camellia_decrypt;
282                 dat->stream.cbc = mode==EVP_CIPH_CBC_MODE ?
283                                         (cbc128_f)Camellia_cbc_encrypt :
284                                         NULL;
285                 }
286         else
287                 {
288                 dat->block      = (block128_f)Camellia_encrypt;
289                 dat->stream.cbc = mode==EVP_CIPH_CBC_MODE ?
290                                         (cbc128_f)Camellia_cbc_encrypt :
291                                         NULL;
292                 }
293
294
295         return 1;
296         }
297
298 static int camellia_cbc_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
299         const unsigned char *in, size_t len)
300 {
301         EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *)ctx->cipher_data;
302
303         if (dat->stream.cbc)
304                 (*dat->stream.cbc)(in,out,len,&dat->ks,ctx->iv,ctx->encrypt);
305         else if (ctx->encrypt)
306                 CRYPTO_cbc128_encrypt(in,out,len,&dat->ks,ctx->iv,dat->block);
307         else
308                 CRYPTO_cbc128_encrypt(in,out,len,&dat->ks,ctx->iv,dat->block);
309
310         return 1;
311 }
312
313 static int camellia_ecb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
314         const unsigned char *in, size_t len)
315 {
316         size_t  bl = ctx->cipher->block_size;
317         size_t  i;
318         EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *)ctx->cipher_data;
319
320         if (len<bl)     return 1;
321
322         for (i=0,len-=bl;i<=len;i+=bl)
323                 (*dat->block)(in+i,out+i,&dat->ks);
324
325         return 1;
326 }
327
328 static int camellia_ofb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
329         const unsigned char *in,size_t len)
330 {
331         EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *)ctx->cipher_data;
332
333         CRYPTO_ofb128_encrypt(in,out,len,&dat->ks,
334                         ctx->iv,&ctx->num,dat->block);
335         return 1;
336 }
337
338 static int camellia_cfb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
339         const unsigned char *in,size_t len)
340 {
341         EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *)ctx->cipher_data;
342
343         CRYPTO_cfb128_encrypt(in,out,len,&dat->ks,
344                         ctx->iv,&ctx->num,ctx->encrypt,dat->block);
345         return 1;
346 }
347
348 static int camellia_cfb8_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
349         const unsigned char *in,size_t len)
350 {
351         EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *)ctx->cipher_data;
352
353         CRYPTO_cfb128_8_encrypt(in,out,len,&dat->ks,
354                         ctx->iv,&ctx->num,ctx->encrypt,dat->block);
355         return 1;
356 }
357
358 static int camellia_cfb1_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
359         const unsigned char *in,size_t len)
360 {
361         EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *)ctx->cipher_data;
362
363         if (ctx->flags&EVP_CIPH_FLAG_LENGTH_BITS) {
364                 CRYPTO_cfb128_1_encrypt(in,out,len,&dat->ks,
365                         ctx->iv,&ctx->num,ctx->encrypt,dat->block);
366                 return 1;
367         }
368
369         while (len>=MAXBITCHUNK) {
370                 CRYPTO_cfb128_1_encrypt(in,out,MAXBITCHUNK*8,&dat->ks,
371                         ctx->iv,&ctx->num,ctx->encrypt,dat->block);
372                 len-=MAXBITCHUNK;
373         }
374         if (len)
375                 CRYPTO_cfb128_1_encrypt(in,out,len*8,&dat->ks,
376                         ctx->iv,&ctx->num,ctx->encrypt,dat->block);
377         
378         return 1;
379 }
380
381 static int camellia_ctr_cipher (EVP_CIPHER_CTX *ctx, unsigned char *out,
382                 const unsigned char *in, size_t len)
383 {
384         unsigned int num = ctx->num;
385         EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *)ctx->cipher_data;
386
387         if (dat->stream.ctr)
388                 CRYPTO_ctr128_encrypt_ctr32(in,out,len,&dat->ks,
389                         ctx->iv,ctx->buf,&num,dat->stream.ctr);
390         else
391                 CRYPTO_ctr128_encrypt(in,out,len,&dat->ks,
392                         ctx->iv,ctx->buf,&num,dat->block);
393         ctx->num = (size_t)num;
394         return 1;
395 }
396
397 BLOCK_CIPHER_generic_pack(NID_camellia,128,EVP_CIPH_FLAG_FIPS)
398 BLOCK_CIPHER_generic_pack(NID_camellia,192,EVP_CIPH_FLAG_FIPS)
399 BLOCK_CIPHER_generic_pack(NID_camellia,256,EVP_CIPH_FLAG_FIPS)
400
401 #else
402
403 # ifdef PEDANTIC
404 static void *dummy=&dummy;
405 # endif
406
407 #endif