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