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