]>
Commit | Line | Data |
---|---|---|
aab26e6f MC |
1 | /* |
2 | * Copyright 2019 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 <string.h> | |
11 | #include <openssl/crypto.h> | |
12 | #include <openssl/core_numbers.h> | |
13 | #include <openssl/core_names.h> | |
14 | #include <openssl/evp.h> | |
15 | #include <openssl/params.h> | |
16 | #include "internal/cryptlib.h" | |
861b8f87 | 17 | #include "internal/provider_algs.h" |
aab26e6f MC |
18 | #include "ciphers_locl.h" |
19 | ||
344cfa34 | 20 | static int PROV_AES_KEY_generic_init(PROV_AES_KEY *ctx, |
aab26e6f | 21 | const unsigned char *iv, |
344cfa34 | 22 | size_t ivlen, |
aab26e6f MC |
23 | int enc) |
24 | { | |
344cfa34 MC |
25 | if (iv != NULL && ctx->mode != EVP_CIPH_ECB_MODE) { |
26 | if (ivlen != AES_BLOCK_SIZE) | |
27 | return 0; | |
aab26e6f | 28 | memcpy(ctx->iv, iv, AES_BLOCK_SIZE); |
344cfa34 | 29 | } |
aab26e6f | 30 | ctx->enc = enc; |
344cfa34 MC |
31 | |
32 | return 1; | |
aab26e6f MC |
33 | } |
34 | ||
344cfa34 MC |
35 | static int aes_einit(void *vctx, const unsigned char *key, size_t keylen, |
36 | const unsigned char *iv, size_t ivlen) | |
aab26e6f MC |
37 | { |
38 | PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; | |
39 | ||
344cfa34 MC |
40 | if (!PROV_AES_KEY_generic_init(ctx, iv, ivlen, 1)) |
41 | return 0; | |
42 | if (key != NULL) { | |
43 | if (keylen != ctx->keylen) | |
44 | return 0; | |
aab26e6f | 45 | return ctx->ciph->init(ctx, key, ctx->keylen); |
344cfa34 | 46 | } |
aab26e6f MC |
47 | |
48 | return 1; | |
49 | } | |
50 | ||
344cfa34 MC |
51 | static int aes_dinit(void *vctx, const unsigned char *key, size_t keylen, |
52 | const unsigned char *iv, size_t ivlen) | |
aab26e6f MC |
53 | { |
54 | PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; | |
55 | ||
344cfa34 MC |
56 | if (!PROV_AES_KEY_generic_init(ctx, iv, ivlen, 0)) |
57 | return 0; | |
58 | if (key != NULL) { | |
59 | if (keylen != ctx->keylen) | |
60 | return 0; | |
aab26e6f | 61 | return ctx->ciph->init(ctx, key, ctx->keylen); |
344cfa34 | 62 | } |
aab26e6f MC |
63 | |
64 | return 1; | |
65 | } | |
66 | ||
ed98df51 MC |
67 | static int aes_block_update(void *vctx, unsigned char *out, size_t *outl, |
68 | const unsigned char *in, size_t inl) | |
aab26e6f MC |
69 | { |
70 | PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; | |
71 | size_t nextblocks = fillblock(ctx->buf, &ctx->bufsz, AES_BLOCK_SIZE, &in, | |
72 | &inl); | |
73 | size_t outlint = 0; | |
74 | ||
75 | /* | |
76 | * If we're decrypting and we end an update on a block boundary we hold | |
77 | * the last block back in case this is the last update call and the last | |
78 | * block is padded. | |
79 | */ | |
80 | if (ctx->bufsz == AES_BLOCK_SIZE | |
81 | && (ctx->enc || inl > 0 || !ctx->pad)) { | |
82 | if (!ctx->ciph->cipher(ctx, out, ctx->buf, AES_BLOCK_SIZE)) | |
83 | return 0; | |
84 | ctx->bufsz = 0; | |
85 | outlint = AES_BLOCK_SIZE; | |
86 | out += AES_BLOCK_SIZE; | |
87 | } | |
88 | if (nextblocks > 0) { | |
89 | if (!ctx->enc && ctx->pad && nextblocks == inl) { | |
90 | if (!ossl_assert(inl >= AES_BLOCK_SIZE)) | |
91 | return 0; | |
92 | nextblocks -= AES_BLOCK_SIZE; | |
93 | } | |
94 | if (!ctx->ciph->cipher(ctx, out, in, nextblocks)) | |
95 | return 0; | |
96 | in += nextblocks; | |
97 | inl -= nextblocks; | |
98 | outlint += nextblocks; | |
99 | } | |
100 | if (!trailingdata(ctx->buf, &ctx->bufsz, AES_BLOCK_SIZE, &in, &inl)) | |
101 | return 0; | |
102 | ||
103 | *outl = outlint; | |
104 | return inl == 0; | |
105 | } | |
106 | ||
ed98df51 | 107 | static int aes_block_final(void *vctx, unsigned char *out, size_t *outl) |
aab26e6f MC |
108 | { |
109 | PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; | |
110 | ||
111 | if (ctx->enc) { | |
112 | if (ctx->pad) { | |
113 | padblock(ctx->buf, &ctx->bufsz, AES_BLOCK_SIZE); | |
114 | } else if (ctx->bufsz == 0) { | |
115 | *outl = 0; | |
116 | return 1; | |
117 | } else if (ctx->bufsz != AES_BLOCK_SIZE) { | |
118 | /* TODO(3.0): What is the correct error code here? */ | |
119 | return 0; | |
120 | } | |
121 | ||
122 | if (!ctx->ciph->cipher(ctx, out, ctx->buf, AES_BLOCK_SIZE)) | |
123 | return 0; | |
124 | ctx->bufsz = 0; | |
125 | *outl = AES_BLOCK_SIZE; | |
126 | return 1; | |
127 | } | |
128 | ||
129 | /* Decrypting */ | |
130 | /* TODO(3.0): What's the correct error here */ | |
131 | if (ctx->bufsz != AES_BLOCK_SIZE) { | |
132 | if (ctx->bufsz == 0 && !ctx->pad) { | |
133 | *outl = 0; | |
134 | return 1; | |
135 | } | |
136 | return 0; | |
137 | } | |
138 | ||
139 | if (!ctx->ciph->cipher(ctx, ctx->buf, ctx->buf, AES_BLOCK_SIZE)) | |
140 | return 0; | |
141 | ||
142 | /* TODO(3.0): What is the correct error here */ | |
143 | if (ctx->pad && !unpadblock(ctx->buf, &ctx->bufsz, AES_BLOCK_SIZE)) | |
144 | return 0; | |
145 | ||
146 | memcpy(out, ctx->buf, ctx->bufsz); | |
147 | *outl = ctx->bufsz; | |
148 | ctx->bufsz = 0; | |
149 | return 1; | |
150 | } | |
151 | ||
ed98df51 MC |
152 | static int aes_stream_update(void *vctx, unsigned char *out, size_t *outl, |
153 | const unsigned char *in, size_t inl) | |
154 | { | |
155 | PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; | |
156 | ||
157 | if (!ctx->ciph->cipher(ctx, out, in, inl)) | |
158 | return 0; | |
159 | ||
160 | *outl = inl; | |
161 | return 1; | |
162 | } | |
163 | static int aes_stream_final(void *vctx, unsigned char *out, size_t *outl) | |
164 | { | |
165 | *outl = 0; | |
166 | return 1; | |
167 | } | |
168 | ||
718b133a MC |
169 | static int aes_cipher(void *vctx, unsigned char *out, const unsigned char *in, |
170 | size_t inl) | |
aab26e6f | 171 | { |
718b133a MC |
172 | PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; |
173 | ||
174 | if (!ctx->ciph->cipher(ctx, out, in, inl)) | |
175 | return 0; | |
aab26e6f | 176 | |
718b133a | 177 | return 1; |
aab26e6f MC |
178 | } |
179 | ||
718b133a MC |
180 | #define IMPLEMENT_new_params(lcmode, UCMODE) \ |
181 | static int aes_##lcmode##_get_params(const OSSL_PARAM params[]) \ | |
182 | { \ | |
183 | const OSSL_PARAM *p; \ | |
184 | \ | |
185 | p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE); \ | |
186 | if (p != NULL && !OSSL_PARAM_set_int(p, EVP_CIPH_##UCMODE##_MODE)) \ | |
187 | return 0; \ | |
188 | \ | |
189 | return 1; \ | |
190 | } | |
f4a129bb | 191 | |
718b133a MC |
192 | #define IMPLEMENT_new_ctx(lcmode, UCMODE, len) \ |
193 | static void *aes_##len##_##lcmode##_newctx(void) \ | |
194 | { \ | |
195 | PROV_AES_KEY *ctx = OPENSSL_zalloc(sizeof(*ctx)); \ | |
196 | \ | |
197 | ctx->pad = 1; \ | |
198 | ctx->keylen = (len / 8); \ | |
199 | ctx->ciph = PROV_AES_CIPHER_##lcmode(); \ | |
200 | ctx->mode = EVP_CIPH_##UCMODE##_MODE; \ | |
201 | return ctx; \ | |
202 | } | |
f4a129bb | 203 | |
718b133a MC |
204 | /* ECB */ |
205 | IMPLEMENT_new_params(ecb, ECB) | |
206 | IMPLEMENT_new_ctx(ecb, ECB, 256) | |
207 | IMPLEMENT_new_ctx(ecb, ECB, 192) | |
208 | IMPLEMENT_new_ctx(ecb, ECB, 128) | |
f4a129bb | 209 | |
718b133a MC |
210 | /* CBC */ |
211 | IMPLEMENT_new_params(cbc, CBC) | |
212 | IMPLEMENT_new_ctx(cbc, CBC, 256) | |
213 | IMPLEMENT_new_ctx(cbc, CBC, 192) | |
214 | IMPLEMENT_new_ctx(cbc, CBC, 128) | |
f4a129bb | 215 | |
ed98df51 MC |
216 | /* OFB */ |
217 | IMPLEMENT_new_params(ofb, OFB) | |
218 | IMPLEMENT_new_ctx(ofb, OFB, 256) | |
219 | IMPLEMENT_new_ctx(ofb, OFB, 192) | |
220 | IMPLEMENT_new_ctx(ofb, OFB, 128) | |
221 | ||
75dd6d64 MC |
222 | /* CFB */ |
223 | IMPLEMENT_new_params(cfb, CFB) | |
224 | IMPLEMENT_new_params(cfb1, CFB) | |
225 | IMPLEMENT_new_params(cfb8, CFB) | |
226 | IMPLEMENT_new_ctx(cfb, CFB, 256) | |
227 | IMPLEMENT_new_ctx(cfb, CFB, 192) | |
228 | IMPLEMENT_new_ctx(cfb, CFB, 128) | |
229 | IMPLEMENT_new_ctx(cfb1, CFB, 256) | |
230 | IMPLEMENT_new_ctx(cfb1, CFB, 192) | |
231 | IMPLEMENT_new_ctx(cfb1, CFB, 128) | |
232 | IMPLEMENT_new_ctx(cfb8, CFB, 256) | |
233 | IMPLEMENT_new_ctx(cfb8, CFB, 192) | |
234 | IMPLEMENT_new_ctx(cfb8, CFB, 128) | |
ed98df51 | 235 | |
819a7ae9 MC |
236 | /* CTR */ |
237 | IMPLEMENT_new_params(ctr, CTR) | |
238 | IMPLEMENT_new_ctx(ctr, CTR, 256) | |
239 | IMPLEMENT_new_ctx(ctr, CTR, 192) | |
240 | IMPLEMENT_new_ctx(ctr, CTR, 128) | |
241 | ||
aab26e6f MC |
242 | static void aes_freectx(void *vctx) |
243 | { | |
244 | PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; | |
245 | ||
246 | OPENSSL_clear_free(ctx, sizeof(*ctx)); | |
247 | } | |
248 | ||
249 | static void *aes_dupctx(void *ctx) | |
250 | { | |
251 | PROV_AES_KEY *in = (PROV_AES_KEY *)ctx; | |
252 | PROV_AES_KEY *ret = OPENSSL_malloc(sizeof(*ret)); | |
253 | ||
254 | *ret = *in; | |
255 | ||
256 | return ret; | |
257 | } | |
258 | ||
259 | static size_t key_length_256(void) | |
260 | { | |
261 | return 256 / 8; | |
262 | } | |
263 | ||
f4a129bb MC |
264 | static size_t key_length_192(void) |
265 | { | |
266 | return 192 / 8; | |
267 | } | |
268 | ||
269 | static size_t key_length_128(void) | |
270 | { | |
271 | return 128 / 8; | |
272 | } | |
273 | ||
718b133a MC |
274 | static size_t iv_length_16(void) |
275 | { | |
276 | return 16; | |
277 | } | |
278 | ||
279 | static size_t iv_length_0(void) | |
280 | { | |
281 | return 0; | |
282 | } | |
283 | ||
284 | static size_t block_size_16(void) | |
285 | { | |
286 | return 16; | |
287 | } | |
288 | ||
ed98df51 MC |
289 | static size_t block_size_1(void) |
290 | { | |
291 | return 1; | |
292 | } | |
293 | ||
718b133a | 294 | static int aes_ctx_get_params(void *vctx, const OSSL_PARAM params[]) |
aab26e6f MC |
295 | { |
296 | PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; | |
297 | const OSSL_PARAM *p; | |
298 | ||
299 | p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_PADDING); | |
300 | if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->pad)) | |
301 | return 0; | |
302 | ||
303 | return 1; | |
304 | } | |
305 | ||
718b133a | 306 | static int aes_ctx_set_params(void *vctx, const OSSL_PARAM params[]) |
aab26e6f MC |
307 | { |
308 | PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx; | |
309 | const OSSL_PARAM *p; | |
310 | ||
311 | p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_PADDING); | |
312 | if (p != NULL) { | |
313 | int pad; | |
314 | ||
315 | if (!OSSL_PARAM_get_int(p, &pad)) | |
316 | return 0; | |
317 | ctx->pad = pad ? 1 : 0; | |
318 | } | |
319 | return 1; | |
320 | } | |
321 | ||
ed98df51 | 322 | #define IMPLEMENT_block_funcs(mode, keylen, ivlen) \ |
718b133a MC |
323 | const OSSL_DISPATCH aes##keylen##mode##_functions[] = { \ |
324 | { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))aes_##keylen##_##mode##_newctx }, \ | |
325 | { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))aes_einit }, \ | |
326 | { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))aes_dinit }, \ | |
ed98df51 MC |
327 | { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))aes_block_update }, \ |
328 | { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))aes_block_final }, \ | |
718b133a MC |
329 | { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))aes_cipher }, \ |
330 | { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))aes_freectx }, \ | |
331 | { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))aes_dupctx }, \ | |
332 | { OSSL_FUNC_CIPHER_KEY_LENGTH, (void (*)(void))key_length_##keylen }, \ | |
333 | { OSSL_FUNC_CIPHER_IV_LENGTH, (void (*)(void))iv_length_##ivlen }, \ | |
ed98df51 | 334 | { OSSL_FUNC_CIPHER_BLOCK_SIZE, (void (*)(void))block_size_16 }, \ |
718b133a MC |
335 | { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))aes_##mode##_get_params }, \ |
336 | { OSSL_FUNC_CIPHER_CTX_GET_PARAMS, (void (*)(void))aes_ctx_get_params }, \ | |
337 | { OSSL_FUNC_CIPHER_CTX_SET_PARAMS, (void (*)(void))aes_ctx_set_params }, \ | |
338 | { 0, NULL } \ | |
339 | }; | |
340 | ||
ed98df51 MC |
341 | #define IMPLEMENT_stream_funcs(mode, keylen, ivlen) \ |
342 | const OSSL_DISPATCH aes##keylen##mode##_functions[] = { \ | |
343 | { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))aes_##keylen##_##mode##_newctx }, \ | |
344 | { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))aes_einit }, \ | |
345 | { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))aes_dinit }, \ | |
346 | { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))aes_stream_update }, \ | |
347 | { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))aes_stream_final }, \ | |
348 | { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))aes_cipher }, \ | |
349 | { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))aes_freectx }, \ | |
350 | { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))aes_dupctx }, \ | |
351 | { OSSL_FUNC_CIPHER_KEY_LENGTH, (void (*)(void))key_length_##keylen }, \ | |
352 | { OSSL_FUNC_CIPHER_IV_LENGTH, (void (*)(void))iv_length_##ivlen }, \ | |
353 | { OSSL_FUNC_CIPHER_BLOCK_SIZE, (void (*)(void))block_size_1 }, \ | |
354 | { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))aes_##mode##_get_params }, \ | |
355 | { OSSL_FUNC_CIPHER_CTX_GET_PARAMS, (void (*)(void))aes_ctx_get_params }, \ | |
356 | { OSSL_FUNC_CIPHER_CTX_SET_PARAMS, (void (*)(void))aes_ctx_set_params }, \ | |
357 | { 0, NULL } \ | |
358 | }; | |
718b133a | 359 | |
ed98df51 MC |
360 | /* ECB */ |
361 | IMPLEMENT_block_funcs(ecb, 256, 0) | |
362 | IMPLEMENT_block_funcs(ecb, 192, 0) | |
363 | IMPLEMENT_block_funcs(ecb, 128, 0) | |
718b133a MC |
364 | |
365 | /* CBC */ | |
ed98df51 MC |
366 | IMPLEMENT_block_funcs(cbc, 256, 16) |
367 | IMPLEMENT_block_funcs(cbc, 192, 16) | |
368 | IMPLEMENT_block_funcs(cbc, 128, 16) | |
369 | ||
370 | /* OFB */ | |
371 | IMPLEMENT_stream_funcs(ofb, 256, 16) | |
372 | IMPLEMENT_stream_funcs(ofb, 192, 16) | |
373 | IMPLEMENT_stream_funcs(ofb, 128, 16) | |
75dd6d64 MC |
374 | |
375 | /* CFB */ | |
376 | IMPLEMENT_stream_funcs(cfb, 256, 16) | |
377 | IMPLEMENT_stream_funcs(cfb, 192, 16) | |
378 | IMPLEMENT_stream_funcs(cfb, 128, 16) | |
379 | IMPLEMENT_stream_funcs(cfb1, 256, 16) | |
380 | IMPLEMENT_stream_funcs(cfb1, 192, 16) | |
381 | IMPLEMENT_stream_funcs(cfb1, 128, 16) | |
382 | IMPLEMENT_stream_funcs(cfb8, 256, 16) | |
383 | IMPLEMENT_stream_funcs(cfb8, 192, 16) | |
384 | IMPLEMENT_stream_funcs(cfb8, 128, 16) | |
819a7ae9 MC |
385 | |
386 | /* CTR */ | |
387 | IMPLEMENT_stream_funcs(ctr, 256, 16) | |
388 | IMPLEMENT_stream_funcs(ctr, 192, 16) | |
389 | IMPLEMENT_stream_funcs(ctr, 128, 16) |