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 : CAMELLIA_KEY ks;
72 : block128_f block;
73 : union {
74 : cbc128_f cbc;
75 : ctr128_f ctr;
76 : } stream;
77 : } EVP_CAMELLIA_KEY;
78 :
79 : # define MAXBITCHUNK ((size_t)1<<(sizeof(size_t)*8-4))
80 :
81 : /* Attribute operation for Camellia */
82 : # define data(ctx) EVP_C_DATA(EVP_CAMELLIA_KEY,ctx)
83 :
84 : # if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
85 : /* ---------^^^ this is not a typo, just a way to detect that
86 : * assembler support was in general requested... */
87 : # include "sparc_arch.h"
88 :
89 : extern unsigned int OPENSSL_sparcv9cap_P[];
90 :
91 : # define SPARC_CMLL_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_CAMELLIA)
92 :
93 : void cmll_t4_set_key(const unsigned char *key, int bits, CAMELLIA_KEY *ks);
94 : void cmll_t4_encrypt(const unsigned char *in, unsigned char *out,
95 : const CAMELLIA_KEY *key);
96 : void cmll_t4_decrypt(const unsigned char *in, unsigned char *out,
97 : const CAMELLIA_KEY *key);
98 :
99 : void cmll128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
100 : size_t len, const CAMELLIA_KEY *key,
101 : unsigned char *ivec);
102 : void cmll128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
103 : size_t len, const CAMELLIA_KEY *key,
104 : unsigned char *ivec);
105 : void cmll256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
106 : size_t len, const CAMELLIA_KEY *key,
107 : unsigned char *ivec);
108 : void cmll256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
109 : size_t len, const CAMELLIA_KEY *key,
110 : unsigned char *ivec);
111 : void cmll128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
112 : size_t blocks, const CAMELLIA_KEY *key,
113 : unsigned char *ivec);
114 : void cmll256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
115 : size_t blocks, const CAMELLIA_KEY *key,
116 : unsigned char *ivec);
117 :
118 : static int cmll_t4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
119 : const unsigned char *iv, int enc)
120 : {
121 : int ret, mode, bits;
122 : EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data;
123 :
124 : mode = ctx->cipher->flags & EVP_CIPH_MODE;
125 : bits = ctx->key_len * 8;
126 :
127 : cmll_t4_set_key(key, bits, &dat->ks);
128 :
129 : if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
130 : && !enc) {
131 : ret = 0;
132 : dat->block = (block128_f) cmll_t4_decrypt;
133 : switch (bits) {
134 : case 128:
135 : dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
136 : (cbc128_f) cmll128_t4_cbc_decrypt : NULL;
137 : break;
138 : case 192:
139 : case 256:
140 : dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
141 : (cbc128_f) cmll256_t4_cbc_decrypt : NULL;
142 : break;
143 : default:
144 : ret = -1;
145 : }
146 : } else {
147 : ret = 0;
148 : dat->block = (block128_f) cmll_t4_encrypt;
149 : switch (bits) {
150 : case 128:
151 : if (mode == EVP_CIPH_CBC_MODE)
152 : dat->stream.cbc = (cbc128_f) cmll128_t4_cbc_encrypt;
153 : else if (mode == EVP_CIPH_CTR_MODE)
154 : dat->stream.ctr = (ctr128_f) cmll128_t4_ctr32_encrypt;
155 : else
156 : dat->stream.cbc = NULL;
157 : break;
158 : case 192:
159 : case 256:
160 : if (mode == EVP_CIPH_CBC_MODE)
161 : dat->stream.cbc = (cbc128_f) cmll256_t4_cbc_encrypt;
162 : else if (mode == EVP_CIPH_CTR_MODE)
163 : dat->stream.ctr = (ctr128_f) cmll256_t4_ctr32_encrypt;
164 : else
165 : dat->stream.cbc = NULL;
166 : break;
167 : default:
168 : ret = -1;
169 : }
170 : }
171 :
172 : if (ret < 0) {
173 : EVPerr(EVP_F_CMLL_T4_INIT_KEY, EVP_R_CAMELLIA_KEY_SETUP_FAILED);
174 : return 0;
175 : }
176 :
177 : return 1;
178 : }
179 :
180 : # define cmll_t4_cbc_cipher camellia_cbc_cipher
181 : static int cmll_t4_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
182 : const unsigned char *in, size_t len);
183 :
184 : # define cmll_t4_ecb_cipher camellia_ecb_cipher
185 : static int cmll_t4_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
186 : const unsigned char *in, size_t len);
187 :
188 : # define cmll_t4_ofb_cipher camellia_ofb_cipher
189 : static int cmll_t4_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
190 : const unsigned char *in, size_t len);
191 :
192 : # define cmll_t4_cfb_cipher camellia_cfb_cipher
193 : static int cmll_t4_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
194 : const unsigned char *in, size_t len);
195 :
196 : # define cmll_t4_cfb8_cipher camellia_cfb8_cipher
197 : static int cmll_t4_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
198 : const unsigned char *in, size_t len);
199 :
200 : # define cmll_t4_cfb1_cipher camellia_cfb1_cipher
201 : static int cmll_t4_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
202 : const unsigned char *in, size_t len);
203 :
204 : # define cmll_t4_ctr_cipher camellia_ctr_cipher
205 : static int cmll_t4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
206 : const unsigned char *in, size_t len);
207 :
208 : # define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
209 : static const EVP_CIPHER cmll_t4_##keylen##_##mode = { \
210 : nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
211 : flags|EVP_CIPH_##MODE##_MODE, \
212 : cmll_t4_init_key, \
213 : cmll_t4_##mode##_cipher, \
214 : NULL, \
215 : sizeof(EVP_CAMELLIA_KEY), \
216 : NULL,NULL,NULL,NULL }; \
217 : static const EVP_CIPHER camellia_##keylen##_##mode = { \
218 : nid##_##keylen##_##nmode,blocksize, \
219 : keylen/8,ivlen, \
220 : flags|EVP_CIPH_##MODE##_MODE, \
221 : camellia_init_key, \
222 : camellia_##mode##_cipher, \
223 : NULL, \
224 : sizeof(EVP_CAMELLIA_KEY), \
225 : NULL,NULL,NULL,NULL }; \
226 : const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
227 : { return SPARC_CMLL_CAPABLE?&cmll_t4_##keylen##_##mode:&camellia_##keylen##_##mode; }
228 :
229 : # else
230 :
231 : # define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
232 : static const EVP_CIPHER camellia_##keylen##_##mode = { \
233 : nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
234 : flags|EVP_CIPH_##MODE##_MODE, \
235 : camellia_init_key, \
236 : camellia_##mode##_cipher, \
237 : NULL, \
238 : sizeof(EVP_CAMELLIA_KEY), \
239 : NULL,NULL,NULL,NULL }; \
240 : const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
241 : { return &camellia_##keylen##_##mode; }
242 :
243 : # endif
244 :
245 : # define BLOCK_CIPHER_generic_pack(nid,keylen,flags) \
246 : BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
247 : BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
248 : BLOCK_CIPHER_generic(nid,keylen,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
249 : BLOCK_CIPHER_generic(nid,keylen,1,16,cfb128,cfb,CFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
250 : BLOCK_CIPHER_generic(nid,keylen,1,16,cfb1,cfb1,CFB,flags) \
251 : BLOCK_CIPHER_generic(nid,keylen,1,16,cfb8,cfb8,CFB,flags)
252 : # if 0 /* not yet, missing NID */
253 : BLOCK_CIPHER_generic(nid, keylen, 1, 16, ctr, ctr, CTR, flags)
254 : # endif
255 : /* The subkey for Camellia is generated. */
256 0 : static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
257 : const unsigned char *iv, int enc)
258 : {
259 : int ret, mode;
260 0 : EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data;
261 :
262 0 : ret = Camellia_set_key(key, ctx->key_len * 8, &dat->ks);
263 0 : if (ret < 0) {
264 0 : EVPerr(EVP_F_CAMELLIA_INIT_KEY, EVP_R_CAMELLIA_KEY_SETUP_FAILED);
265 0 : return 0;
266 : }
267 :
268 0 : mode = ctx->cipher->flags & EVP_CIPH_MODE;
269 0 : if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
270 0 : && !enc) {
271 0 : dat->block = (block128_f) Camellia_decrypt;
272 0 : dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
273 0 : (cbc128_f) Camellia_cbc_encrypt : NULL;
274 : } else {
275 0 : dat->block = (block128_f) Camellia_encrypt;
276 0 : dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
277 0 : (cbc128_f) Camellia_cbc_encrypt : NULL;
278 : }
279 :
280 : return 1;
281 : }
282 :
283 0 : static int camellia_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
284 : const unsigned char *in, size_t len)
285 : {
286 0 : EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data;
287 :
288 0 : if (dat->stream.cbc)
289 0 : (*dat->stream.cbc) (in, out, len, &dat->ks, ctx->iv, ctx->encrypt);
290 0 : else if (ctx->encrypt)
291 0 : CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, ctx->iv, dat->block);
292 : else
293 0 : CRYPTO_cbc128_decrypt(in, out, len, &dat->ks, ctx->iv, dat->block);
294 :
295 0 : return 1;
296 : }
297 :
298 0 : static int camellia_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
299 : const unsigned char *in, size_t len)
300 : {
301 0 : size_t bl = ctx->cipher->block_size;
302 : size_t i;
303 0 : EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data;
304 :
305 0 : if (len < bl)
306 : return 1;
307 :
308 0 : for (i = 0, len -= bl; i <= len; i += bl)
309 0 : (*dat->block) (in + i, out + i, &dat->ks);
310 :
311 : return 1;
312 : }
313 :
314 0 : static int camellia_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
315 : const unsigned char *in, size_t len)
316 : {
317 0 : EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data;
318 :
319 0 : CRYPTO_ofb128_encrypt(in, out, len, &dat->ks,
320 0 : ctx->iv, &ctx->num, dat->block);
321 0 : return 1;
322 : }
323 :
324 0 : static int camellia_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
325 : const unsigned char *in, size_t len)
326 : {
327 0 : EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data;
328 :
329 0 : CRYPTO_cfb128_encrypt(in, out, len, &dat->ks,
330 0 : ctx->iv, &ctx->num, ctx->encrypt, dat->block);
331 0 : return 1;
332 : }
333 :
334 0 : static int camellia_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
335 : const unsigned char *in, size_t len)
336 : {
337 0 : EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data;
338 :
339 0 : CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks,
340 0 : ctx->iv, &ctx->num, ctx->encrypt, dat->block);
341 0 : return 1;
342 : }
343 :
344 0 : static int camellia_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
345 : const unsigned char *in, size_t len)
346 : {
347 0 : EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data;
348 :
349 0 : if (ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) {
350 0 : CRYPTO_cfb128_1_encrypt(in, out, len, &dat->ks,
351 0 : ctx->iv, &ctx->num, ctx->encrypt, dat->block);
352 0 : return 1;
353 : }
354 :
355 0 : while (len >= MAXBITCHUNK) {
356 0 : CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, &dat->ks,
357 0 : ctx->iv, &ctx->num, ctx->encrypt, dat->block);
358 0 : len -= MAXBITCHUNK;
359 : }
360 0 : if (len)
361 0 : CRYPTO_cfb128_1_encrypt(in, out, len * 8, &dat->ks,
362 0 : ctx->iv, &ctx->num, ctx->encrypt, dat->block);
363 :
364 : return 1;
365 : }
366 :
367 : # if 0 /* not yet, missing NID */
368 : static int camellia_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
369 : const unsigned char *in, size_t len)
370 : {
371 : unsigned int num = ctx->num;
372 : EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data;
373 :
374 : if (dat->stream.ctr)
375 : CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks,
376 : ctx->iv, ctx->buf, &num, dat->stream.ctr);
377 : else
378 : CRYPTO_ctr128_encrypt(in, out, len, &dat->ks,
379 : ctx->iv, ctx->buf, &num, dat->block);
380 : ctx->num = (size_t)num;
381 : return 1;
382 : }
383 : # endif
384 :
385 847 : BLOCK_CIPHER_generic_pack(NID_camellia, 128, 0)
386 726 : BLOCK_CIPHER_generic_pack(NID_camellia, 192, 0)
387 847 : BLOCK_CIPHER_generic_pack(NID_camellia, 256, 0)
388 : #else
389 :
390 : # ifdef PEDANTIC
391 : static void *dummy = &dummy;
392 : # endif
393 :
394 : #endif
|