1 | /*
|
---|
2 | * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
|
---|
3 | *
|
---|
4 | * Licensed under the OpenSSL license (the "License"). You may not use
|
---|
5 | * this file except in compliance with the License. You can obtain a copy
|
---|
6 | * in the file LICENSE in the source distribution or at
|
---|
7 | * https://www.openssl.org/source/license.html
|
---|
8 | */
|
---|
9 |
|
---|
10 | #include <openssl/opensslconf.h>
|
---|
11 | #ifdef OPENSSL_NO_CAMELLIA
|
---|
12 | NON_EMPTY_TRANSLATION_UNIT
|
---|
13 | #else
|
---|
14 |
|
---|
15 | # include <openssl/evp.h>
|
---|
16 | # include <openssl/err.h>
|
---|
17 | # include <string.h>
|
---|
18 | # include <assert.h>
|
---|
19 | # include <openssl/camellia.h>
|
---|
20 | # include "crypto/evp.h"
|
---|
21 | # include "modes_local.h"
|
---|
22 |
|
---|
23 | static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
---|
24 | const unsigned char *iv, int enc);
|
---|
25 |
|
---|
26 | /* Camellia subkey Structure */
|
---|
27 | typedef struct {
|
---|
28 | CAMELLIA_KEY ks;
|
---|
29 | block128_f block;
|
---|
30 | union {
|
---|
31 | cbc128_f cbc;
|
---|
32 | ctr128_f ctr;
|
---|
33 | } stream;
|
---|
34 | } EVP_CAMELLIA_KEY;
|
---|
35 |
|
---|
36 | # define MAXBITCHUNK ((size_t)1<<(sizeof(size_t)*8-4))
|
---|
37 |
|
---|
38 | /* Attribute operation for Camellia */
|
---|
39 | # define data(ctx) EVP_C_DATA(EVP_CAMELLIA_KEY,ctx)
|
---|
40 |
|
---|
41 | # if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
|
---|
42 | /* ---------^^^ this is not a typo, just a way to detect that
|
---|
43 | * assembler support was in general requested... */
|
---|
44 | # include "sparc_arch.h"
|
---|
45 |
|
---|
46 | extern unsigned int OPENSSL_sparcv9cap_P[];
|
---|
47 |
|
---|
48 | # define SPARC_CMLL_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_CAMELLIA)
|
---|
49 |
|
---|
50 | void cmll_t4_set_key(const unsigned char *key, int bits, CAMELLIA_KEY *ks);
|
---|
51 | void cmll_t4_encrypt(const unsigned char *in, unsigned char *out,
|
---|
52 | const CAMELLIA_KEY *key);
|
---|
53 | void cmll_t4_decrypt(const unsigned char *in, unsigned char *out,
|
---|
54 | const CAMELLIA_KEY *key);
|
---|
55 |
|
---|
56 | void cmll128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
---|
57 | size_t len, const CAMELLIA_KEY *key,
|
---|
58 | unsigned char *ivec);
|
---|
59 | void cmll128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
|
---|
60 | size_t len, const CAMELLIA_KEY *key,
|
---|
61 | unsigned char *ivec);
|
---|
62 | void cmll256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
---|
63 | size_t len, const CAMELLIA_KEY *key,
|
---|
64 | unsigned char *ivec);
|
---|
65 | void cmll256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
|
---|
66 | size_t len, const CAMELLIA_KEY *key,
|
---|
67 | unsigned char *ivec);
|
---|
68 | void cmll128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
|
---|
69 | size_t blocks, const CAMELLIA_KEY *key,
|
---|
70 | unsigned char *ivec);
|
---|
71 | void cmll256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
|
---|
72 | size_t blocks, const CAMELLIA_KEY *key,
|
---|
73 | unsigned char *ivec);
|
---|
74 |
|
---|
75 | static int cmll_t4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
---|
76 | const unsigned char *iv, int enc)
|
---|
77 | {
|
---|
78 | int ret, mode, bits;
|
---|
79 | EVP_CAMELLIA_KEY *dat =
|
---|
80 | (EVP_CAMELLIA_KEY *)EVP_CIPHER_CTX_get_cipher_data(ctx);
|
---|
81 |
|
---|
82 | mode = EVP_CIPHER_CTX_mode(ctx);
|
---|
83 | bits = EVP_CIPHER_CTX_key_length(ctx) * 8;
|
---|
84 |
|
---|
85 | cmll_t4_set_key(key, bits, &dat->ks);
|
---|
86 |
|
---|
87 | if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
|
---|
88 | && !enc) {
|
---|
89 | ret = 0;
|
---|
90 | dat->block = (block128_f) cmll_t4_decrypt;
|
---|
91 | switch (bits) {
|
---|
92 | case 128:
|
---|
93 | dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
|
---|
94 | (cbc128_f) cmll128_t4_cbc_decrypt : NULL;
|
---|
95 | break;
|
---|
96 | case 192:
|
---|
97 | case 256:
|
---|
98 | dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
|
---|
99 | (cbc128_f) cmll256_t4_cbc_decrypt : NULL;
|
---|
100 | break;
|
---|
101 | default:
|
---|
102 | ret = -1;
|
---|
103 | }
|
---|
104 | } else {
|
---|
105 | ret = 0;
|
---|
106 | dat->block = (block128_f) cmll_t4_encrypt;
|
---|
107 | switch (bits) {
|
---|
108 | case 128:
|
---|
109 | if (mode == EVP_CIPH_CBC_MODE)
|
---|
110 | dat->stream.cbc = (cbc128_f) cmll128_t4_cbc_encrypt;
|
---|
111 | else if (mode == EVP_CIPH_CTR_MODE)
|
---|
112 | dat->stream.ctr = (ctr128_f) cmll128_t4_ctr32_encrypt;
|
---|
113 | else
|
---|
114 | dat->stream.cbc = NULL;
|
---|
115 | break;
|
---|
116 | case 192:
|
---|
117 | case 256:
|
---|
118 | if (mode == EVP_CIPH_CBC_MODE)
|
---|
119 | dat->stream.cbc = (cbc128_f) cmll256_t4_cbc_encrypt;
|
---|
120 | else if (mode == EVP_CIPH_CTR_MODE)
|
---|
121 | dat->stream.ctr = (ctr128_f) cmll256_t4_ctr32_encrypt;
|
---|
122 | else
|
---|
123 | dat->stream.cbc = NULL;
|
---|
124 | break;
|
---|
125 | default:
|
---|
126 | ret = -1;
|
---|
127 | }
|
---|
128 | }
|
---|
129 |
|
---|
130 | if (ret < 0) {
|
---|
131 | EVPerr(EVP_F_CMLL_T4_INIT_KEY, EVP_R_CAMELLIA_KEY_SETUP_FAILED);
|
---|
132 | return 0;
|
---|
133 | }
|
---|
134 |
|
---|
135 | return 1;
|
---|
136 | }
|
---|
137 |
|
---|
138 | # define cmll_t4_cbc_cipher camellia_cbc_cipher
|
---|
139 | static int cmll_t4_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
---|
140 | const unsigned char *in, size_t len);
|
---|
141 |
|
---|
142 | # define cmll_t4_ecb_cipher camellia_ecb_cipher
|
---|
143 | static int cmll_t4_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
---|
144 | const unsigned char *in, size_t len);
|
---|
145 |
|
---|
146 | # define cmll_t4_ofb_cipher camellia_ofb_cipher
|
---|
147 | static int cmll_t4_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
---|
148 | const unsigned char *in, size_t len);
|
---|
149 |
|
---|
150 | # define cmll_t4_cfb_cipher camellia_cfb_cipher
|
---|
151 | static int cmll_t4_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
---|
152 | const unsigned char *in, size_t len);
|
---|
153 |
|
---|
154 | # define cmll_t4_cfb8_cipher camellia_cfb8_cipher
|
---|
155 | static int cmll_t4_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
---|
156 | const unsigned char *in, size_t len);
|
---|
157 |
|
---|
158 | # define cmll_t4_cfb1_cipher camellia_cfb1_cipher
|
---|
159 | static int cmll_t4_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
---|
160 | const unsigned char *in, size_t len);
|
---|
161 |
|
---|
162 | # define cmll_t4_ctr_cipher camellia_ctr_cipher
|
---|
163 | static int cmll_t4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
---|
164 | const unsigned char *in, size_t len);
|
---|
165 |
|
---|
166 | # define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
|
---|
167 | static const EVP_CIPHER cmll_t4_##keylen##_##mode = { \
|
---|
168 | nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
|
---|
169 | flags|EVP_CIPH_##MODE##_MODE, \
|
---|
170 | cmll_t4_init_key, \
|
---|
171 | cmll_t4_##mode##_cipher, \
|
---|
172 | NULL, \
|
---|
173 | sizeof(EVP_CAMELLIA_KEY), \
|
---|
174 | NULL,NULL,NULL,NULL }; \
|
---|
175 | static const EVP_CIPHER camellia_##keylen##_##mode = { \
|
---|
176 | nid##_##keylen##_##nmode,blocksize, \
|
---|
177 | keylen/8,ivlen, \
|
---|
178 | flags|EVP_CIPH_##MODE##_MODE, \
|
---|
179 | camellia_init_key, \
|
---|
180 | camellia_##mode##_cipher, \
|
---|
181 | NULL, \
|
---|
182 | sizeof(EVP_CAMELLIA_KEY), \
|
---|
183 | NULL,NULL,NULL,NULL }; \
|
---|
184 | const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
|
---|
185 | { return SPARC_CMLL_CAPABLE?&cmll_t4_##keylen##_##mode:&camellia_##keylen##_##mode; }
|
---|
186 |
|
---|
187 | # else
|
---|
188 |
|
---|
189 | # define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
|
---|
190 | static const EVP_CIPHER camellia_##keylen##_##mode = { \
|
---|
191 | nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
|
---|
192 | flags|EVP_CIPH_##MODE##_MODE, \
|
---|
193 | camellia_init_key, \
|
---|
194 | camellia_##mode##_cipher, \
|
---|
195 | NULL, \
|
---|
196 | sizeof(EVP_CAMELLIA_KEY), \
|
---|
197 | NULL,NULL,NULL,NULL }; \
|
---|
198 | const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
|
---|
199 | { return &camellia_##keylen##_##mode; }
|
---|
200 |
|
---|
201 | # endif
|
---|
202 |
|
---|
203 | # define BLOCK_CIPHER_generic_pack(nid,keylen,flags) \
|
---|
204 | BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
|
---|
205 | BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
|
---|
206 | BLOCK_CIPHER_generic(nid,keylen,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
|
---|
207 | BLOCK_CIPHER_generic(nid,keylen,1,16,cfb128,cfb,CFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
|
---|
208 | BLOCK_CIPHER_generic(nid,keylen,1,16,cfb1,cfb1,CFB,flags) \
|
---|
209 | BLOCK_CIPHER_generic(nid,keylen,1,16,cfb8,cfb8,CFB,flags) \
|
---|
210 | BLOCK_CIPHER_generic(nid, keylen, 1, 16, ctr, ctr, CTR, flags)
|
---|
211 |
|
---|
212 | /* The subkey for Camellia is generated. */
|
---|
213 | static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
---|
214 | const unsigned char *iv, int enc)
|
---|
215 | {
|
---|
216 | int ret, mode;
|
---|
217 | EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx);
|
---|
218 |
|
---|
219 | ret = Camellia_set_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, &dat->ks);
|
---|
220 | if (ret < 0) {
|
---|
221 | EVPerr(EVP_F_CAMELLIA_INIT_KEY, EVP_R_CAMELLIA_KEY_SETUP_FAILED);
|
---|
222 | return 0;
|
---|
223 | }
|
---|
224 |
|
---|
225 | mode = EVP_CIPHER_CTX_mode(ctx);
|
---|
226 | if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
|
---|
227 | && !enc) {
|
---|
228 | dat->block = (block128_f) Camellia_decrypt;
|
---|
229 | dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
|
---|
230 | (cbc128_f) Camellia_cbc_encrypt : NULL;
|
---|
231 | } else {
|
---|
232 | dat->block = (block128_f) Camellia_encrypt;
|
---|
233 | dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
|
---|
234 | (cbc128_f) Camellia_cbc_encrypt : NULL;
|
---|
235 | }
|
---|
236 |
|
---|
237 | return 1;
|
---|
238 | }
|
---|
239 |
|
---|
240 | static int camellia_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
---|
241 | const unsigned char *in, size_t len)
|
---|
242 | {
|
---|
243 | EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx);
|
---|
244 |
|
---|
245 | if (dat->stream.cbc)
|
---|
246 | (*dat->stream.cbc) (in, out, len, &dat->ks,
|
---|
247 | EVP_CIPHER_CTX_iv_noconst(ctx),
|
---|
248 | EVP_CIPHER_CTX_encrypting(ctx));
|
---|
249 | else if (EVP_CIPHER_CTX_encrypting(ctx))
|
---|
250 | CRYPTO_cbc128_encrypt(in, out, len, &dat->ks,
|
---|
251 | EVP_CIPHER_CTX_iv_noconst(ctx), dat->block);
|
---|
252 | else
|
---|
253 | CRYPTO_cbc128_decrypt(in, out, len, &dat->ks,
|
---|
254 | EVP_CIPHER_CTX_iv_noconst(ctx), dat->block);
|
---|
255 |
|
---|
256 | return 1;
|
---|
257 | }
|
---|
258 |
|
---|
259 | static int camellia_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
---|
260 | const unsigned char *in, size_t len)
|
---|
261 | {
|
---|
262 | size_t bl = EVP_CIPHER_CTX_block_size(ctx);
|
---|
263 | size_t i;
|
---|
264 | EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx);
|
---|
265 |
|
---|
266 | if (len < bl)
|
---|
267 | return 1;
|
---|
268 |
|
---|
269 | for (i = 0, len -= bl; i <= len; i += bl)
|
---|
270 | (*dat->block) (in + i, out + i, &dat->ks);
|
---|
271 |
|
---|
272 | return 1;
|
---|
273 | }
|
---|
274 |
|
---|
275 | static int camellia_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
---|
276 | const unsigned char *in, size_t len)
|
---|
277 | {
|
---|
278 | EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx);
|
---|
279 |
|
---|
280 | int num = EVP_CIPHER_CTX_num(ctx);
|
---|
281 | CRYPTO_ofb128_encrypt(in, out, len, &dat->ks,
|
---|
282 | EVP_CIPHER_CTX_iv_noconst(ctx), &num, dat->block);
|
---|
283 | EVP_CIPHER_CTX_set_num(ctx, num);
|
---|
284 | return 1;
|
---|
285 | }
|
---|
286 |
|
---|
287 | static int camellia_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
---|
288 | const unsigned char *in, size_t len)
|
---|
289 | {
|
---|
290 | EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx);
|
---|
291 |
|
---|
292 | int num = EVP_CIPHER_CTX_num(ctx);
|
---|
293 | CRYPTO_cfb128_encrypt(in, out, len, &dat->ks,
|
---|
294 | EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block);
|
---|
295 | EVP_CIPHER_CTX_set_num(ctx, num);
|
---|
296 | return 1;
|
---|
297 | }
|
---|
298 |
|
---|
299 | static int camellia_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
---|
300 | const unsigned char *in, size_t len)
|
---|
301 | {
|
---|
302 | EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx);
|
---|
303 |
|
---|
304 | int num = EVP_CIPHER_CTX_num(ctx);
|
---|
305 | CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks,
|
---|
306 | EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block);
|
---|
307 | EVP_CIPHER_CTX_set_num(ctx, num);
|
---|
308 | return 1;
|
---|
309 | }
|
---|
310 |
|
---|
311 | static int camellia_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
---|
312 | const unsigned char *in, size_t len)
|
---|
313 | {
|
---|
314 | EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx);
|
---|
315 |
|
---|
316 | if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS)) {
|
---|
317 | int num = EVP_CIPHER_CTX_num(ctx);
|
---|
318 | CRYPTO_cfb128_1_encrypt(in, out, len, &dat->ks,
|
---|
319 | EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block);
|
---|
320 | EVP_CIPHER_CTX_set_num(ctx, num);
|
---|
321 | return 1;
|
---|
322 | }
|
---|
323 |
|
---|
324 | while (len >= MAXBITCHUNK) {
|
---|
325 | int num = EVP_CIPHER_CTX_num(ctx);
|
---|
326 | CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, &dat->ks,
|
---|
327 | EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block);
|
---|
328 | EVP_CIPHER_CTX_set_num(ctx, num);
|
---|
329 | len -= MAXBITCHUNK;
|
---|
330 | out += MAXBITCHUNK;
|
---|
331 | in += MAXBITCHUNK;
|
---|
332 | }
|
---|
333 | if (len) {
|
---|
334 | int num = EVP_CIPHER_CTX_num(ctx);
|
---|
335 | CRYPTO_cfb128_1_encrypt(in, out, len * 8, &dat->ks,
|
---|
336 | EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block);
|
---|
337 | EVP_CIPHER_CTX_set_num(ctx, num);
|
---|
338 | }
|
---|
339 |
|
---|
340 | return 1;
|
---|
341 | }
|
---|
342 |
|
---|
343 | static int camellia_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
---|
344 | const unsigned char *in, size_t len)
|
---|
345 | {
|
---|
346 | unsigned int num = EVP_CIPHER_CTX_num(ctx);
|
---|
347 | EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx);
|
---|
348 |
|
---|
349 | if (dat->stream.ctr)
|
---|
350 | CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks,
|
---|
351 | EVP_CIPHER_CTX_iv_noconst(ctx),
|
---|
352 | EVP_CIPHER_CTX_buf_noconst(ctx), &num,
|
---|
353 | dat->stream.ctr);
|
---|
354 | else
|
---|
355 | CRYPTO_ctr128_encrypt(in, out, len, &dat->ks,
|
---|
356 | EVP_CIPHER_CTX_iv_noconst(ctx),
|
---|
357 | EVP_CIPHER_CTX_buf_noconst(ctx), &num,
|
---|
358 | dat->block);
|
---|
359 | EVP_CIPHER_CTX_set_num(ctx, num);
|
---|
360 | return 1;
|
---|
361 | }
|
---|
362 |
|
---|
363 | BLOCK_CIPHER_generic_pack(NID_camellia, 128, 0)
|
---|
364 | BLOCK_CIPHER_generic_pack(NID_camellia, 192, 0)
|
---|
365 | BLOCK_CIPHER_generic_pack(NID_camellia, 256, 0)
|
---|
366 | #endif
|
---|