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 * Generic dispatch table functions for ciphers.
14 #include "cipher_locl.h"
15 #include "internal/provider_ctx.h"
16 #include "internal/providercommonerr.h"
19 * Generic cipher functions for OSSL_PARAM gettables and settables
21 static const OSSL_PARAM cipher_known_gettable_params
[] = {
22 OSSL_PARAM_uint(OSSL_CIPHER_PARAM_MODE
, NULL
),
23 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN
, NULL
),
24 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN
, NULL
),
25 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_BLOCK_SIZE
, NULL
),
26 OSSL_PARAM_ulong(OSSL_CIPHER_PARAM_FLAGS
, NULL
),
29 const OSSL_PARAM
*cipher_generic_gettable_params(void)
31 return cipher_known_gettable_params
;
34 int cipher_generic_get_params(OSSL_PARAM params
[], unsigned int md
,
36 size_t kbits
, size_t blkbits
, size_t ivbits
)
40 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_MODE
);
41 if (p
!= NULL
&& !OSSL_PARAM_set_uint(p
, md
)) {
42 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_SET_PARAMETER
);
45 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_FLAGS
);
46 if (p
!= NULL
&& !OSSL_PARAM_set_ulong(p
, flags
)) {
47 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_SET_PARAMETER
);
50 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_KEYLEN
);
51 if (p
!= NULL
&& !OSSL_PARAM_set_size_t(p
, kbits
/ 8)) {
52 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_SET_PARAMETER
);
55 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_BLOCK_SIZE
);
56 if (p
!= NULL
&& !OSSL_PARAM_set_size_t(p
, blkbits
/ 8)) {
57 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_SET_PARAMETER
);
60 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_IVLEN
);
61 if (p
!= NULL
&& !OSSL_PARAM_set_size_t(p
, ivbits
/ 8)) {
62 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_SET_PARAMETER
);
68 CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(cipher_generic
)
69 CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(cipher_generic
)
71 static const OSSL_PARAM cipher_known_settable_ctx_params
[] = {
72 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN
, NULL
),
73 OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING
, NULL
),
74 OSSL_PARAM_uint(OSSL_CIPHER_PARAM_NUM
, NULL
),
77 const OSSL_PARAM
*cipher_generic_settable_ctx_params(void)
79 return cipher_known_settable_ctx_params
;
83 * AEAD cipher functions for OSSL_PARAM gettables and settables
85 static const OSSL_PARAM cipher_aead_known_gettable_ctx_params
[] = {
86 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN
, NULL
),
87 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN
, NULL
),
88 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TAGLEN
, NULL
),
89 OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV
, NULL
, 0),
90 OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG
, NULL
, 0),
91 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD
, NULL
),
94 const OSSL_PARAM
*cipher_aead_gettable_ctx_params(void)
96 return cipher_aead_known_gettable_ctx_params
;
99 static const OSSL_PARAM cipher_aead_known_settable_ctx_params
[] = {
100 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN
, NULL
),
101 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_IVLEN
, NULL
),
102 OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG
, NULL
, 0),
103 OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD
, NULL
, 0),
104 OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED
, NULL
, 0),
107 const OSSL_PARAM
*cipher_aead_settable_ctx_params(void)
109 return cipher_aead_known_settable_ctx_params
;
112 static int cipher_generic_init_internal(PROV_CIPHER_CTX
*ctx
,
113 const unsigned char *key
, size_t keylen
,
114 const unsigned char *iv
, size_t ivlen
,
117 ctx
->enc
= enc
? 1 : 0;
119 if (iv
!= NULL
&& ctx
->mode
!= EVP_CIPH_ECB_MODE
) {
120 if (ivlen
!= ctx
->ivlen
) {
121 ERR_raise(ERR_LIB_PROV
, ERR_R_INTERNAL_ERROR
);
124 memcpy(ctx
->iv
, iv
, ctx
->ivlen
);
127 if ((ctx
->flags
& EVP_CIPH_VARIABLE_LENGTH
) == 0) {
128 if (keylen
!= ctx
->keylen
) {
129 ERR_raise(ERR_LIB_PROV
, PROV_R_INVALID_KEYLEN
);
133 ctx
->keylen
= keylen
;
135 return ctx
->hw
->init(ctx
, key
, ctx
->keylen
);
140 int cipher_generic_einit(void *vctx
, const unsigned char *key
, size_t keylen
,
141 const unsigned char *iv
, size_t ivlen
)
143 return cipher_generic_init_internal((PROV_CIPHER_CTX
*)vctx
, key
, keylen
,
147 int cipher_generic_dinit(void *vctx
, const unsigned char *key
, size_t keylen
,
148 const unsigned char *iv
, size_t ivlen
)
150 return cipher_generic_init_internal((PROV_CIPHER_CTX
*)vctx
, key
, keylen
,
154 int cipher_generic_block_update(void *vctx
, unsigned char *out
, size_t *outl
,
155 size_t outsize
, const unsigned char *in
,
159 PROV_CIPHER_CTX
*ctx
= (PROV_CIPHER_CTX
*)vctx
;
160 size_t blksz
= ctx
->blocksize
;
161 size_t nextblocks
= fillblock(ctx
->buf
, &ctx
->bufsz
, blksz
, &in
, &inl
);
164 * If we're decrypting and we end an update on a block boundary we hold
165 * the last block back in case this is the last update call and the last
168 if (ctx
->bufsz
== blksz
&& (ctx
->enc
|| inl
> 0 || !ctx
->pad
)) {
169 if (outsize
< blksz
) {
170 ERR_raise(ERR_LIB_PROV
, PROV_R_OUTPUT_BUFFER_TOO_SMALL
);
173 if (!ctx
->hw
->cipher(ctx
, out
, ctx
->buf
, blksz
)) {
174 ERR_raise(ERR_LIB_PROV
, PROV_R_CIPHER_OPERATION_FAILED
);
181 if (nextblocks
> 0) {
182 if (!ctx
->enc
&& ctx
->pad
&& nextblocks
== inl
) {
183 if (!ossl_assert(inl
>= blksz
)) {
184 ERR_raise(ERR_LIB_PROV
, PROV_R_OUTPUT_BUFFER_TOO_SMALL
);
189 outlint
+= nextblocks
;
190 if (outsize
< outlint
) {
191 ERR_raise(ERR_LIB_PROV
, PROV_R_OUTPUT_BUFFER_TOO_SMALL
);
194 if (!ctx
->hw
->cipher(ctx
, out
, in
, nextblocks
)) {
195 ERR_raise(ERR_LIB_PROV
, PROV_R_CIPHER_OPERATION_FAILED
);
201 if (!trailingdata(ctx
->buf
, &ctx
->bufsz
, blksz
, &in
, &inl
)) {
202 /* ERR_raise already called */
210 int cipher_generic_block_final(void *vctx
, unsigned char *out
, size_t *outl
,
213 PROV_CIPHER_CTX
*ctx
= (PROV_CIPHER_CTX
*)vctx
;
214 size_t blksz
= ctx
->blocksize
;
218 padblock(ctx
->buf
, &ctx
->bufsz
, blksz
);
219 } else if (ctx
->bufsz
== 0) {
222 } else if (ctx
->bufsz
!= blksz
) {
223 ERR_raise(ERR_LIB_PROV
, PROV_R_WRONG_FINAL_BLOCK_LENGTH
);
227 if (outsize
< blksz
) {
228 ERR_raise(ERR_LIB_PROV
, PROV_R_OUTPUT_BUFFER_TOO_SMALL
);
231 if (!ctx
->hw
->cipher(ctx
, out
, ctx
->buf
, blksz
)) {
232 ERR_raise(ERR_LIB_PROV
, PROV_R_CIPHER_OPERATION_FAILED
);
241 if (ctx
->bufsz
!= blksz
) {
242 if (ctx
->bufsz
== 0 && !ctx
->pad
) {
246 ERR_raise(ERR_LIB_PROV
, PROV_R_WRONG_FINAL_BLOCK_LENGTH
);
250 if (!ctx
->hw
->cipher(ctx
, ctx
->buf
, ctx
->buf
, blksz
)) {
251 ERR_raise(ERR_LIB_PROV
, PROV_R_CIPHER_OPERATION_FAILED
);
255 if (ctx
->pad
&& !unpadblock(ctx
->buf
, &ctx
->bufsz
, blksz
)) {
256 /* ERR_raise already called */
260 if (outsize
< ctx
->bufsz
) {
261 ERR_raise(ERR_LIB_PROV
, PROV_R_OUTPUT_BUFFER_TOO_SMALL
);
264 memcpy(out
, ctx
->buf
, ctx
->bufsz
);
270 int cipher_generic_stream_update(void *vctx
, unsigned char *out
, size_t *outl
,
271 size_t outsize
, const unsigned char *in
,
274 PROV_CIPHER_CTX
*ctx
= (PROV_CIPHER_CTX
*)vctx
;
277 ERR_raise(ERR_LIB_PROV
, PROV_R_OUTPUT_BUFFER_TOO_SMALL
);
281 if (!ctx
->hw
->cipher(ctx
, out
, in
, inl
)) {
282 ERR_raise(ERR_LIB_PROV
, PROV_R_CIPHER_OPERATION_FAILED
);
289 int cipher_generic_stream_final(void *vctx
, unsigned char *out
, size_t *outl
,
296 int cipher_generic_cipher(void *vctx
,
297 unsigned char *out
, size_t *outl
, size_t outsize
,
298 const unsigned char *in
, size_t inl
)
300 PROV_CIPHER_CTX
*ctx
= (PROV_CIPHER_CTX
*)vctx
;
303 ERR_raise(ERR_LIB_PROV
, PROV_R_OUTPUT_BUFFER_TOO_SMALL
);
307 if (!ctx
->hw
->cipher(ctx
, out
, in
, inl
)) {
308 ERR_raise(ERR_LIB_PROV
, PROV_R_CIPHER_OPERATION_FAILED
);
316 int cipher_generic_get_ctx_params(void *vctx
, OSSL_PARAM params
[])
318 PROV_CIPHER_CTX
*ctx
= (PROV_CIPHER_CTX
*)vctx
;
321 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_IVLEN
);
322 if (p
!= NULL
&& !OSSL_PARAM_set_size_t(p
, ctx
->ivlen
)) {
323 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_SET_PARAMETER
);
326 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_PADDING
);
327 if (p
!= NULL
&& !OSSL_PARAM_set_uint(p
, ctx
->pad
)) {
328 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_SET_PARAMETER
);
331 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_IV
);
333 && !OSSL_PARAM_set_octet_ptr(p
, &ctx
->iv
, ctx
->ivlen
)
334 && !OSSL_PARAM_set_octet_string(p
, &ctx
->iv
, ctx
->ivlen
)) {
335 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_SET_PARAMETER
);
338 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_NUM
);
339 if (p
!= NULL
&& !OSSL_PARAM_set_uint(p
, ctx
->num
)) {
340 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_SET_PARAMETER
);
343 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_KEYLEN
);
344 if (p
!= NULL
&& !OSSL_PARAM_set_size_t(p
, ctx
->keylen
)) {
345 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_SET_PARAMETER
);
352 int cipher_generic_set_ctx_params(void *vctx
, const OSSL_PARAM params
[])
354 PROV_CIPHER_CTX
*ctx
= (PROV_CIPHER_CTX
*)vctx
;
357 p
= OSSL_PARAM_locate_const(params
, OSSL_CIPHER_PARAM_PADDING
);
361 if (!OSSL_PARAM_get_uint(p
, &pad
)) {
362 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_GET_PARAMETER
);
365 ctx
->pad
= pad
? 1 : 0;
367 p
= OSSL_PARAM_locate_const(params
, OSSL_CIPHER_PARAM_NUM
);
371 if (!OSSL_PARAM_get_uint(p
, &num
)) {
372 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_GET_PARAMETER
);
377 p
= OSSL_PARAM_locate_const(params
, OSSL_CIPHER_PARAM_KEYLEN
);
381 if (!OSSL_PARAM_get_size_t(p
, &keylen
)) {
382 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_GET_PARAMETER
);
385 ctx
->keylen
= keylen
;
390 void cipher_generic_initkey(void *vctx
, size_t kbits
, size_t blkbits
,
391 size_t ivbits
, unsigned int mode
, uint64_t flags
,
392 const PROV_CIPHER_HW
*hw
, void *provctx
)
394 PROV_CIPHER_CTX
*ctx
= (PROV_CIPHER_CTX
*)vctx
;
398 ctx
->keylen
= ((kbits
) / 8);
399 ctx
->ivlen
= ((ivbits
) / 8);
402 ctx
->blocksize
= blkbits
/ 8;
404 ctx
->libctx
= PROV_LIBRARY_CONTEXT_OF(provctx
); /* used for rand */