2 * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
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
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 <openssl/rand.h>
17 #include "internal/cryptlib.h"
18 #include "internal/provider_algs.h"
19 #include "ciphers_locl.h"
20 #include "internal/providercommonerr.h"
22 static OSSL_OP_cipher_encrypt_init_fn aes_einit
;
23 static OSSL_OP_cipher_decrypt_init_fn aes_dinit
;
24 static OSSL_OP_cipher_update_fn aes_block_update
;
25 static OSSL_OP_cipher_final_fn aes_block_final
;
26 static OSSL_OP_cipher_update_fn aes_stream_update
;
27 static OSSL_OP_cipher_final_fn aes_stream_final
;
28 static OSSL_OP_cipher_cipher_fn aes_cipher
;
29 static OSSL_OP_cipher_freectx_fn aes_freectx
;
30 static OSSL_OP_cipher_dupctx_fn aes_dupctx
;
31 static OSSL_OP_cipher_ctx_get_params_fn aes_ctx_get_params
;
32 static OSSL_OP_cipher_ctx_set_params_fn aes_ctx_set_params
;
34 static int PROV_AES_KEY_generic_init(PROV_AES_KEY
*ctx
,
35 const unsigned char *iv
,
39 if (iv
!= NULL
&& ctx
->mode
!= EVP_CIPH_ECB_MODE
) {
40 if (ivlen
!= AES_BLOCK_SIZE
) {
41 PROVerr(PROV_F_PROV_AES_KEY_GENERIC_INIT
, ERR_R_INTERNAL_ERROR
);
44 memcpy(ctx
->iv
, iv
, AES_BLOCK_SIZE
);
51 static int aes_einit(void *vctx
, const unsigned char *key
, size_t keylen
,
52 const unsigned char *iv
, size_t ivlen
)
54 PROV_AES_KEY
*ctx
= (PROV_AES_KEY
*)vctx
;
56 if (!PROV_AES_KEY_generic_init(ctx
, iv
, ivlen
, 1)) {
57 /* PROVerr already called */
61 if (keylen
!= ctx
->keylen
) {
62 PROVerr(PROV_F_AES_EINIT
, PROV_R_INVALID_KEYLEN
);
65 return ctx
->ciph
->init(ctx
, key
, ctx
->keylen
);
71 static int aes_dinit(void *vctx
, const unsigned char *key
, size_t keylen
,
72 const unsigned char *iv
, size_t ivlen
)
74 PROV_AES_KEY
*ctx
= (PROV_AES_KEY
*)vctx
;
76 if (!PROV_AES_KEY_generic_init(ctx
, iv
, ivlen
, 0)) {
77 /* PROVerr already called */
81 if (keylen
!= ctx
->keylen
) {
82 PROVerr(PROV_F_AES_DINIT
, PROV_R_INVALID_KEYLEN
);
85 return ctx
->ciph
->init(ctx
, key
, ctx
->keylen
);
91 static int aes_block_update(void *vctx
, unsigned char *out
, size_t *outl
,
92 size_t outsize
, const unsigned char *in
, size_t inl
)
94 PROV_AES_KEY
*ctx
= (PROV_AES_KEY
*)vctx
;
95 size_t nextblocks
= fillblock(ctx
->buf
, &ctx
->bufsz
, AES_BLOCK_SIZE
, &in
,
100 * If we're decrypting and we end an update on a block boundary we hold
101 * the last block back in case this is the last update call and the last
104 if (ctx
->bufsz
== AES_BLOCK_SIZE
105 && (ctx
->enc
|| inl
> 0 || !ctx
->pad
)) {
106 if (outsize
< AES_BLOCK_SIZE
) {
107 PROVerr(PROV_F_AES_BLOCK_UPDATE
, PROV_R_OUTPUT_BUFFER_TOO_SMALL
);
110 if (!ctx
->ciph
->cipher(ctx
, out
, ctx
->buf
, AES_BLOCK_SIZE
)) {
111 PROVerr(PROV_F_AES_BLOCK_UPDATE
, PROV_R_CIPHER_OPERATION_FAILED
);
115 outlint
= AES_BLOCK_SIZE
;
116 out
+= AES_BLOCK_SIZE
;
118 if (nextblocks
> 0) {
119 if (!ctx
->enc
&& ctx
->pad
&& nextblocks
== inl
) {
120 if (!ossl_assert(inl
>= AES_BLOCK_SIZE
)) {
121 PROVerr(PROV_F_AES_BLOCK_UPDATE
, PROV_R_OUTPUT_BUFFER_TOO_SMALL
);
124 nextblocks
-= AES_BLOCK_SIZE
;
126 outlint
+= nextblocks
;
127 if (outsize
< outlint
) {
128 PROVerr(PROV_F_AES_BLOCK_UPDATE
, PROV_R_OUTPUT_BUFFER_TOO_SMALL
);
131 if (!ctx
->ciph
->cipher(ctx
, out
, in
, nextblocks
)) {
132 PROVerr(PROV_F_AES_BLOCK_UPDATE
, PROV_R_CIPHER_OPERATION_FAILED
);
138 if (!trailingdata(ctx
->buf
, &ctx
->bufsz
, AES_BLOCK_SIZE
, &in
, &inl
)) {
139 /* PROVerr already called */
147 static int aes_block_final(void *vctx
, unsigned char *out
, size_t *outl
,
150 PROV_AES_KEY
*ctx
= (PROV_AES_KEY
*)vctx
;
154 padblock(ctx
->buf
, &ctx
->bufsz
, AES_BLOCK_SIZE
);
155 } else if (ctx
->bufsz
== 0) {
158 } else if (ctx
->bufsz
!= AES_BLOCK_SIZE
) {
159 PROVerr(PROV_F_AES_BLOCK_FINAL
, PROV_R_WRONG_FINAL_BLOCK_LENGTH
);
163 if (outsize
< AES_BLOCK_SIZE
) {
164 PROVerr(PROV_F_AES_BLOCK_FINAL
, PROV_R_OUTPUT_BUFFER_TOO_SMALL
);
167 if (!ctx
->ciph
->cipher(ctx
, out
, ctx
->buf
, AES_BLOCK_SIZE
)) {
168 PROVerr(PROV_F_AES_BLOCK_FINAL
, PROV_R_CIPHER_OPERATION_FAILED
);
172 *outl
= AES_BLOCK_SIZE
;
177 if (ctx
->bufsz
!= AES_BLOCK_SIZE
) {
178 if (ctx
->bufsz
== 0 && !ctx
->pad
) {
182 PROVerr(PROV_F_AES_BLOCK_FINAL
, PROV_R_WRONG_FINAL_BLOCK_LENGTH
);
186 if (!ctx
->ciph
->cipher(ctx
, ctx
->buf
, ctx
->buf
, AES_BLOCK_SIZE
)) {
187 PROVerr(PROV_F_AES_BLOCK_FINAL
, PROV_R_CIPHER_OPERATION_FAILED
);
191 if (ctx
->pad
&& !unpadblock(ctx
->buf
, &ctx
->bufsz
, AES_BLOCK_SIZE
)) {
192 /* PROVerr already called */
196 if (outsize
< ctx
->bufsz
) {
197 PROVerr(PROV_F_AES_BLOCK_FINAL
, PROV_R_OUTPUT_BUFFER_TOO_SMALL
);
200 memcpy(out
, ctx
->buf
, ctx
->bufsz
);
206 static int aes_stream_update(void *vctx
, unsigned char *out
, size_t *outl
,
207 size_t outsize
, const unsigned char *in
,
210 PROV_AES_KEY
*ctx
= (PROV_AES_KEY
*)vctx
;
213 PROVerr(PROV_F_AES_STREAM_UPDATE
, PROV_R_OUTPUT_BUFFER_TOO_SMALL
);
217 if (!ctx
->ciph
->cipher(ctx
, out
, in
, inl
)) {
218 PROVerr(PROV_F_AES_STREAM_UPDATE
, PROV_R_CIPHER_OPERATION_FAILED
);
225 static int aes_stream_final(void *vctx
, unsigned char *out
, size_t *outl
,
232 static int aes_cipher(void *vctx
,
233 unsigned char *out
, size_t *outl
, size_t outsize
,
234 const unsigned char *in
, size_t inl
)
236 PROV_AES_KEY
*ctx
= (PROV_AES_KEY
*)vctx
;
239 PROVerr(PROV_F_AES_CIPHER
, PROV_R_OUTPUT_BUFFER_TOO_SMALL
);
243 if (!ctx
->ciph
->cipher(ctx
, out
, in
, inl
)) {
244 PROVerr(PROV_F_AES_CIPHER
, PROV_R_CIPHER_OPERATION_FAILED
);
252 static void *aes_new_ctx(void *provctx
, size_t mode
, size_t kbits
,
253 const PROV_AES_CIPHER
*ciph
)
255 PROV_AES_KEY
*ctx
= OPENSSL_zalloc(sizeof(*ctx
));
258 ctx
->keylen
= kbits
/ 8;
264 int aes_get_params(OSSL_PARAM params
[], int md
, unsigned long flags
,
265 int kbits
, int blkbits
, int ivbits
)
269 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_MODE
);
271 if (!OSSL_PARAM_set_int(p
, md
))
274 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_FLAGS
);
276 if (!OSSL_PARAM_set_ulong(p
, flags
))
279 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_KEYLEN
);
281 if (!OSSL_PARAM_set_int(p
, kbits
/ 8))
284 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_BLOCK_SIZE
);
286 if (!OSSL_PARAM_set_int(p
, blkbits
/ 8))
289 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_IVLEN
);
291 if (!OSSL_PARAM_set_int(p
, ivbits
/ 8))
297 #define IMPLEMENT_cipher(lcmode, UCMODE, flags, kbits, blkbits, ivbits) \
298 static OSSL_OP_cipher_get_params_fn aes_##kbits##_##lcmode##_get_params; \
299 static int aes_##kbits##_##lcmode##_get_params(OSSL_PARAM params[]) \
301 return aes_get_params(params, EVP_CIPH_##UCMODE##_MODE, flags, kbits, \
304 static OSSL_OP_cipher_newctx_fn aes_##kbits##_##lcmode##_newctx; \
305 static void *aes_##kbits##_##lcmode##_newctx(void *provctx) \
307 return aes_new_ctx(provctx, EVP_CIPH_##UCMODE##_MODE, kbits, \
308 PROV_AES_CIPHER_##lcmode(kbits / 8)); \
312 IMPLEMENT_cipher(ecb
, ECB
, 0, 256, 128, 0)
313 IMPLEMENT_cipher(ecb
, ECB
, 0, 192, 128, 0)
314 IMPLEMENT_cipher(ecb
, ECB
, 0, 128, 128, 0)
317 IMPLEMENT_cipher(cbc
, CBC
, 0, 256, 128, 128)
318 IMPLEMENT_cipher(cbc
, CBC
, 0, 192, 128, 128)
319 IMPLEMENT_cipher(cbc
, CBC
, 0, 128, 128, 128)
322 IMPLEMENT_cipher(ofb
, OFB
, 0, 256, 8, 128)
323 IMPLEMENT_cipher(ofb
, OFB
, 0, 192, 8, 128)
324 IMPLEMENT_cipher(ofb
, OFB
, 0, 128, 8, 128)
327 IMPLEMENT_cipher(cfb
, CFB
, 0, 256, 8, 128)
328 IMPLEMENT_cipher(cfb
, CFB
, 0, 192, 8, 128)
329 IMPLEMENT_cipher(cfb
, CFB
, 0, 128, 8, 128)
330 IMPLEMENT_cipher(cfb1
, CFB
, 0, 256, 8, 128)
331 IMPLEMENT_cipher(cfb1
, CFB
, 0, 192, 8, 128)
332 IMPLEMENT_cipher(cfb1
, CFB
, 0, 128, 8, 128)
333 IMPLEMENT_cipher(cfb8
, CFB
, 0, 256, 8, 128)
334 IMPLEMENT_cipher(cfb8
, CFB
, 0, 192, 8, 128)
335 IMPLEMENT_cipher(cfb8
, CFB
, 0, 128, 8, 128)
338 IMPLEMENT_cipher(ctr
, CTR
, 0, 256, 8, 128)
339 IMPLEMENT_cipher(ctr
, CTR
, 0, 192, 8, 128)
340 IMPLEMENT_cipher(ctr
, CTR
, 0, 128, 8, 128)
342 static void aes_freectx(void *vctx
)
344 PROV_AES_KEY
*ctx
= (PROV_AES_KEY
*)vctx
;
346 OPENSSL_clear_free(ctx
, sizeof(*ctx
));
349 static void *aes_dupctx(void *ctx
)
351 PROV_AES_KEY
*in
= (PROV_AES_KEY
*)ctx
;
352 PROV_AES_KEY
*ret
= OPENSSL_malloc(sizeof(*ret
));
355 PROVerr(PROV_F_AES_DUPCTX
, ERR_R_MALLOC_FAILURE
);
363 static int aes_ctx_get_params(void *vctx
, OSSL_PARAM params
[])
365 PROV_AES_KEY
*ctx
= (PROV_AES_KEY
*)vctx
;
368 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_IVLEN
);
370 if (!OSSL_PARAM_set_int(p
, AES_BLOCK_SIZE
))
373 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_PADDING
);
374 if (p
!= NULL
&& !OSSL_PARAM_set_int(p
, ctx
->pad
)) {
375 PROVerr(PROV_F_AES_CTX_GET_PARAMS
, PROV_R_FAILED_TO_SET_PARAMETER
);
378 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_IV
);
380 && !OSSL_PARAM_set_octet_ptr(p
, &ctx
->iv
, AES_BLOCK_SIZE
)
381 && !OSSL_PARAM_set_octet_string(p
, &ctx
->iv
, AES_BLOCK_SIZE
)) {
382 PROVerr(PROV_F_AES_CTX_GET_PARAMS
,
383 PROV_R_FAILED_TO_SET_PARAMETER
);
386 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_NUM
);
387 if (p
!= NULL
&& !OSSL_PARAM_set_size_t(p
, ctx
->num
)) {
388 PROVerr(PROV_F_AES_CTX_GET_PARAMS
,
389 PROV_R_FAILED_TO_SET_PARAMETER
);
392 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_KEYLEN
);
393 if (p
!= NULL
&& !OSSL_PARAM_set_int(p
, ctx
->keylen
)) {
394 PROVerr(PROV_F_AES_CTX_GET_PARAMS
,
395 PROV_R_FAILED_TO_SET_PARAMETER
);
402 static int aes_ctx_set_params(void *vctx
, const OSSL_PARAM params
[])
404 PROV_AES_KEY
*ctx
= (PROV_AES_KEY
*)vctx
;
407 p
= OSSL_PARAM_locate_const(params
, OSSL_CIPHER_PARAM_PADDING
);
411 if (!OSSL_PARAM_get_int(p
, &pad
)) {
412 PROVerr(PROV_F_AES_CTX_SET_PARAMS
,
413 PROV_R_FAILED_TO_GET_PARAMETER
);
416 ctx
->pad
= pad
? 1 : 0;
418 p
= OSSL_PARAM_locate_const(params
, OSSL_CIPHER_PARAM_NUM
);
422 if (!OSSL_PARAM_get_int(p
, &num
)) {
423 PROVerr(PROV_F_AES_CTX_SET_PARAMS
,
424 PROV_R_FAILED_TO_GET_PARAMETER
);
429 p
= OSSL_PARAM_locate_const(params
, OSSL_CIPHER_PARAM_KEYLEN
);
433 if (!OSSL_PARAM_get_int(p
, &keylen
)) {
434 PROVerr(PROV_F_AES_CTX_SET_PARAMS
,
435 PROV_R_FAILED_TO_GET_PARAMETER
);
438 ctx
->keylen
= keylen
;
443 #define IMPLEMENT_block_funcs(mode, kbits) \
444 const OSSL_DISPATCH aes##kbits##mode##_functions[] = { \
445 { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))aes_##kbits##_##mode##_newctx }, \
446 { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))aes_einit }, \
447 { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))aes_dinit }, \
448 { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))aes_block_update }, \
449 { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))aes_block_final }, \
450 { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))aes_cipher }, \
451 { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))aes_freectx }, \
452 { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))aes_dupctx }, \
453 { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))aes_##kbits##_##mode##_get_params }, \
454 { OSSL_FUNC_CIPHER_CTX_GET_PARAMS, (void (*)(void))aes_ctx_get_params }, \
455 { OSSL_FUNC_CIPHER_CTX_SET_PARAMS, (void (*)(void))aes_ctx_set_params }, \
459 #define IMPLEMENT_stream_funcs(mode, kbits) \
460 const OSSL_DISPATCH aes##kbits##mode##_functions[] = { \
461 { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))aes_##kbits##_##mode##_newctx }, \
462 { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))aes_einit }, \
463 { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))aes_dinit }, \
464 { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))aes_stream_update }, \
465 { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))aes_stream_final }, \
466 { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))aes_cipher }, \
467 { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))aes_freectx }, \
468 { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))aes_dupctx }, \
469 { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))aes_##kbits##_##mode##_get_params }, \
470 { OSSL_FUNC_CIPHER_CTX_GET_PARAMS, (void (*)(void))aes_ctx_get_params }, \
471 { OSSL_FUNC_CIPHER_CTX_SET_PARAMS, (void (*)(void))aes_ctx_set_params }, \
476 IMPLEMENT_block_funcs(ecb
, 256)
477 IMPLEMENT_block_funcs(ecb
, 192)
478 IMPLEMENT_block_funcs(ecb
, 128)
481 IMPLEMENT_block_funcs(cbc
, 256)
482 IMPLEMENT_block_funcs(cbc
, 192)
483 IMPLEMENT_block_funcs(cbc
, 128)
486 IMPLEMENT_stream_funcs(ofb
, 256)
487 IMPLEMENT_stream_funcs(ofb
, 192)
488 IMPLEMENT_stream_funcs(ofb
, 128)
491 IMPLEMENT_stream_funcs(cfb
, 256)
492 IMPLEMENT_stream_funcs(cfb
, 192)
493 IMPLEMENT_stream_funcs(cfb
, 128)
494 IMPLEMENT_stream_funcs(cfb1
, 256)
495 IMPLEMENT_stream_funcs(cfb1
, 192)
496 IMPLEMENT_stream_funcs(cfb1
, 128)
497 IMPLEMENT_stream_funcs(cfb8
, 256)
498 IMPLEMENT_stream_funcs(cfb8
, 192)
499 IMPLEMENT_stream_funcs(cfb8
, 128)
502 IMPLEMENT_stream_funcs(ctr
, 256)
503 IMPLEMENT_stream_funcs(ctr
, 192)
504 IMPLEMENT_stream_funcs(ctr
, 128)