Branch data Line data Source code
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_CMLL_T4_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 /* not yet, missing NID */
260 : : BLOCK_CIPHER_generic(nid,keylen,1,16,ctr,ctr,CTR,flags)
261 : : #endif
262 : :
263 : : /* The subkey for Camellia is generated. */
264 : 305 : 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 : 305 : EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *)ctx->cipher_data;
269 : :
270 : 305 : ret=Camellia_set_key(key, ctx->key_len * 8, &dat->ks);
271 [ - + ]: 305 : if(ret < 0)
272 : : {
273 : 0 : EVPerr(EVP_F_CAMELLIA_INIT_KEY,EVP_R_CAMELLIA_KEY_SETUP_FAILED);
274 : 0 : return 0;
275 : : }
276 : :
277 : 305 : mode = ctx->cipher->flags & EVP_CIPH_MODE;
278 [ + + ]: 305 : if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
279 [ + + ]: 257 : && !enc)
280 : : {
281 : 127 : dat->block = (block128_f)Camellia_decrypt;
282 : 127 : dat->stream.cbc = mode==EVP_CIPH_CBC_MODE ?
283 [ + + ]: 127 : (cbc128_f)Camellia_cbc_encrypt :
284 : : NULL;
285 : : }
286 : : else
287 : : {
288 : 178 : dat->block = (block128_f)Camellia_encrypt;
289 : 178 : dat->stream.cbc = mode==EVP_CIPH_CBC_MODE ?
290 [ + + ]: 178 : (cbc128_f)Camellia_cbc_encrypt :
291 : : NULL;
292 : : }
293 : :
294 : :
295 : : return 1;
296 : : }
297 : :
298 : 738 : static int camellia_cbc_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
299 : : const unsigned char *in, size_t len)
300 : : {
301 : 738 : EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *)ctx->cipher_data;
302 : :
303 [ + - ]: 738 : if (dat->stream.cbc)
304 : 738 : (*dat->stream.cbc)(in,out,len,&dat->ks,ctx->iv,ctx->encrypt);
305 [ # # ]: 0 : else if (ctx->encrypt)
306 : 0 : CRYPTO_cbc128_encrypt(in,out,len,&dat->ks,ctx->iv,dat->block);
307 : : else
308 : 0 : CRYPTO_cbc128_decrypt(in,out,len,&dat->ks,ctx->iv,dat->block);
309 : :
310 : 738 : return 1;
311 : : }
312 : :
313 : 219 : static int camellia_ecb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
314 : : const unsigned char *in, size_t len)
315 : : {
316 : 219 : size_t bl = ctx->cipher->block_size;
317 : : size_t i;
318 : 219 : EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *)ctx->cipher_data;
319 : :
320 [ + - ]: 219 : if (len<bl) return 1;
321 : :
322 [ + + ]: 1020 : for (i=0,len-=bl;i<=len;i+=bl)
323 : 801 : (*dat->block)(in+i,out+i,&dat->ks);
324 : :
325 : : return 1;
326 : : }
327 : :
328 : 24 : static int camellia_ofb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
329 : : const unsigned char *in,size_t len)
330 : : {
331 : 24 : EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *)ctx->cipher_data;
332 : :
333 : 24 : CRYPTO_ofb128_encrypt(in,out,len,&dat->ks,
334 : 24 : ctx->iv,&ctx->num,dat->block);
335 : 24 : return 1;
336 : : }
337 : :
338 : 24 : static int camellia_cfb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
339 : : const unsigned char *in,size_t len)
340 : : {
341 : 24 : EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *)ctx->cipher_data;
342 : :
343 : 24 : CRYPTO_cfb128_encrypt(in,out,len,&dat->ks,
344 : 24 : ctx->iv,&ctx->num,ctx->encrypt,dat->block);
345 : 24 : return 1;
346 : : }
347 : :
348 : 0 : static int camellia_cfb8_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
349 : : const unsigned char *in,size_t len)
350 : : {
351 : 0 : EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *)ctx->cipher_data;
352 : :
353 : 0 : CRYPTO_cfb128_8_encrypt(in,out,len,&dat->ks,
354 : 0 : ctx->iv,&ctx->num,ctx->encrypt,dat->block);
355 : 0 : return 1;
356 : : }
357 : :
358 : 0 : static int camellia_cfb1_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
359 : : const unsigned char *in,size_t len)
360 : : {
361 : 0 : EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *)ctx->cipher_data;
362 : :
363 [ # # ]: 0 : if (ctx->flags&EVP_CIPH_FLAG_LENGTH_BITS) {
364 : 0 : CRYPTO_cfb128_1_encrypt(in,out,len,&dat->ks,
365 : 0 : ctx->iv,&ctx->num,ctx->encrypt,dat->block);
366 : 0 : return 1;
367 : : }
368 : :
369 [ # # ]: 0 : while (len>=MAXBITCHUNK) {
370 : 0 : CRYPTO_cfb128_1_encrypt(in,out,MAXBITCHUNK*8,&dat->ks,
371 : 0 : ctx->iv,&ctx->num,ctx->encrypt,dat->block);
372 : 0 : len-=MAXBITCHUNK;
373 : : }
374 [ # # ]: 0 : if (len)
375 : 0 : CRYPTO_cfb128_1_encrypt(in,out,len*8,&dat->ks,
376 : 0 : ctx->iv,&ctx->num,ctx->encrypt,dat->block);
377 : :
378 : : return 1;
379 : : }
380 : :
381 : : #if 0 /* not yet, missing NID */
382 : : static int camellia_ctr_cipher (EVP_CIPHER_CTX *ctx, unsigned char *out,
383 : : const unsigned char *in, size_t len)
384 : : {
385 : : unsigned int num = ctx->num;
386 : : EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *)ctx->cipher_data;
387 : :
388 : : if (dat->stream.ctr)
389 : : CRYPTO_ctr128_encrypt_ctr32(in,out,len,&dat->ks,
390 : : ctx->iv,ctx->buf,&num,dat->stream.ctr);
391 : : else
392 : : CRYPTO_ctr128_encrypt(in,out,len,&dat->ks,
393 : : ctx->iv,ctx->buf,&num,dat->block);
394 : : ctx->num = (size_t)num;
395 : : return 1;
396 : : }
397 : : #endif
398 : :
399 : 5325 : BLOCK_CIPHER_generic_pack(NID_camellia,128,0)
400 : 4356 : BLOCK_CIPHER_generic_pack(NID_camellia,192,0)
401 : 5325 : BLOCK_CIPHER_generic_pack(NID_camellia,256,0)
402 : :
403 : : #else
404 : :
405 : : # ifdef PEDANTIC
406 : : static void *dummy=&dummy;
407 : : # endif
408 : :
409 : : #endif
|