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 "internal/cryptlib.h"
17 #include "internal/provider_algs.h"
18 #include "ciphers_locl.h"
20 static void PROV_AES_KEY_generic_init(PROV_AES_KEY
*ctx
,
21 const unsigned char *iv
,
25 memcpy(ctx
->iv
, iv
, AES_BLOCK_SIZE
);
29 static int aes_einit(void *vctx
, const unsigned char *key
,
30 const unsigned char *iv
)
32 PROV_AES_KEY
*ctx
= (PROV_AES_KEY
*)vctx
;
34 PROV_AES_KEY_generic_init(ctx
, iv
, 1);
36 return ctx
->ciph
->init(ctx
, key
, ctx
->keylen
);
41 static int aes_dinit(void *vctx
, const unsigned char *key
,
42 const unsigned char *iv
)
44 PROV_AES_KEY
*ctx
= (PROV_AES_KEY
*)vctx
;
46 PROV_AES_KEY_generic_init(ctx
, iv
, 0);
48 return ctx
->ciph
->init(ctx
, key
, ctx
->keylen
);
53 static int aes_update(void *vctx
, unsigned char *out
, size_t *outl
,
54 const unsigned char *in
, size_t inl
)
56 PROV_AES_KEY
*ctx
= (PROV_AES_KEY
*)vctx
;
57 size_t nextblocks
= fillblock(ctx
->buf
, &ctx
->bufsz
, AES_BLOCK_SIZE
, &in
,
62 * If we're decrypting and we end an update on a block boundary we hold
63 * the last block back in case this is the last update call and the last
66 if (ctx
->bufsz
== AES_BLOCK_SIZE
67 && (ctx
->enc
|| inl
> 0 || !ctx
->pad
)) {
68 if (!ctx
->ciph
->cipher(ctx
, out
, ctx
->buf
, AES_BLOCK_SIZE
))
71 outlint
= AES_BLOCK_SIZE
;
72 out
+= AES_BLOCK_SIZE
;
75 if (!ctx
->enc
&& ctx
->pad
&& nextblocks
== inl
) {
76 if (!ossl_assert(inl
>= AES_BLOCK_SIZE
))
78 nextblocks
-= AES_BLOCK_SIZE
;
80 if (!ctx
->ciph
->cipher(ctx
, out
, in
, nextblocks
))
84 outlint
+= nextblocks
;
86 if (!trailingdata(ctx
->buf
, &ctx
->bufsz
, AES_BLOCK_SIZE
, &in
, &inl
))
93 static int aes_final(void *vctx
, unsigned char *out
, size_t *outl
)
95 PROV_AES_KEY
*ctx
= (PROV_AES_KEY
*)vctx
;
99 padblock(ctx
->buf
, &ctx
->bufsz
, AES_BLOCK_SIZE
);
100 } else if (ctx
->bufsz
== 0) {
103 } else if (ctx
->bufsz
!= AES_BLOCK_SIZE
) {
104 /* TODO(3.0): What is the correct error code here? */
108 if (!ctx
->ciph
->cipher(ctx
, out
, ctx
->buf
, AES_BLOCK_SIZE
))
111 *outl
= AES_BLOCK_SIZE
;
116 /* TODO(3.0): What's the correct error here */
117 if (ctx
->bufsz
!= AES_BLOCK_SIZE
) {
118 if (ctx
->bufsz
== 0 && !ctx
->pad
) {
125 if (!ctx
->ciph
->cipher(ctx
, ctx
->buf
, ctx
->buf
, AES_BLOCK_SIZE
))
128 /* TODO(3.0): What is the correct error here */
129 if (ctx
->pad
&& !unpadblock(ctx
->buf
, &ctx
->bufsz
, AES_BLOCK_SIZE
))
132 memcpy(out
, ctx
->buf
, ctx
->bufsz
);
138 static int aes_cipher(void *vctx
, unsigned char *out
, const unsigned char *in
,
141 PROV_AES_KEY
*ctx
= (PROV_AES_KEY
*)vctx
;
143 if (!ctx
->ciph
->cipher(ctx
, out
, in
, inl
))
149 #define IMPLEMENT_new_params(lcmode, UCMODE) \
150 static int aes_##lcmode##_get_params(const OSSL_PARAM params[]) \
152 const OSSL_PARAM *p; \
154 p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE); \
155 if (p != NULL && !OSSL_PARAM_set_int(p, EVP_CIPH_##UCMODE##_MODE)) \
161 #define IMPLEMENT_new_ctx(lcmode, UCMODE, len) \
162 static void *aes_##len##_##lcmode##_newctx(void) \
164 PROV_AES_KEY *ctx = OPENSSL_zalloc(sizeof(*ctx)); \
167 ctx->keylen = (len / 8); \
168 ctx->ciph = PROV_AES_CIPHER_##lcmode(); \
169 ctx->mode = EVP_CIPH_##UCMODE##_MODE; \
174 IMPLEMENT_new_params(ecb
, ECB
)
175 IMPLEMENT_new_ctx(ecb
, ECB
, 256)
176 IMPLEMENT_new_ctx(ecb
, ECB
, 192)
177 IMPLEMENT_new_ctx(ecb
, ECB
, 128)
180 IMPLEMENT_new_params(cbc
, CBC
)
181 IMPLEMENT_new_ctx(cbc
, CBC
, 256)
182 IMPLEMENT_new_ctx(cbc
, CBC
, 192)
183 IMPLEMENT_new_ctx(cbc
, CBC
, 128)
185 static void aes_freectx(void *vctx
)
187 PROV_AES_KEY
*ctx
= (PROV_AES_KEY
*)vctx
;
189 OPENSSL_clear_free(ctx
, sizeof(*ctx
));
192 static void *aes_dupctx(void *ctx
)
194 PROV_AES_KEY
*in
= (PROV_AES_KEY
*)ctx
;
195 PROV_AES_KEY
*ret
= OPENSSL_malloc(sizeof(*ret
));
202 static size_t key_length_256(void)
207 static size_t key_length_192(void)
212 static size_t key_length_128(void)
217 static size_t iv_length_16(void)
222 static size_t iv_length_0(void)
227 static size_t block_size_16(void)
232 static int aes_ctx_get_params(void *vctx
, const OSSL_PARAM params
[])
234 PROV_AES_KEY
*ctx
= (PROV_AES_KEY
*)vctx
;
237 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_PADDING
);
238 if (p
!= NULL
&& !OSSL_PARAM_set_uint(p
, ctx
->pad
))
244 static int aes_ctx_set_params(void *vctx
, const OSSL_PARAM params
[])
246 PROV_AES_KEY
*ctx
= (PROV_AES_KEY
*)vctx
;
249 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_PADDING
);
253 if (!OSSL_PARAM_get_int(p
, &pad
))
255 ctx
->pad
= pad
? 1 : 0;
260 #define IMPLEMENT_funcs(mode, keylen, ivlen, blksz) \
261 const OSSL_DISPATCH aes##keylen##mode##_functions[] = { \
262 { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))aes_##keylen##_##mode##_newctx }, \
263 { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))aes_einit }, \
264 { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))aes_dinit }, \
265 { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))aes_update }, \
266 { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))aes_final }, \
267 { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))aes_cipher }, \
268 { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))aes_freectx }, \
269 { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))aes_dupctx }, \
270 { OSSL_FUNC_CIPHER_KEY_LENGTH, (void (*)(void))key_length_##keylen }, \
271 { OSSL_FUNC_CIPHER_IV_LENGTH, (void (*)(void))iv_length_##ivlen }, \
272 { OSSL_FUNC_CIPHER_BLOCK_SIZE, (void (*)(void))block_size_##blksz }, \
273 { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))aes_##mode##_get_params }, \
274 { OSSL_FUNC_CIPHER_CTX_GET_PARAMS, (void (*)(void))aes_ctx_get_params }, \
275 { OSSL_FUNC_CIPHER_CTX_SET_PARAMS, (void (*)(void))aes_ctx_set_params }, \
281 IMPLEMENT_funcs(ecb
, 256, 0, 16)
282 IMPLEMENT_funcs(ecb
, 192, 0, 16)
283 IMPLEMENT_funcs(ecb
, 128, 0, 16)
287 IMPLEMENT_funcs(cbc
, 256, 16, 16)
288 IMPLEMENT_funcs(cbc
, 192, 16, 16)
289 IMPLEMENT_funcs(cbc
, 128, 16, 16)