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 "ciphercommon_local.h"
15 #include "prov/provider_ctx.h"
16 #include "prov/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 CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(cipher_generic
)
72 CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(cipher_generic
)
75 * Variable key length cipher functions for OSSL_PARAM settables
78 int cipher_var_keylen_set_ctx_params(void *vctx
, const OSSL_PARAM params
[])
80 PROV_CIPHER_CTX
*ctx
= (PROV_CIPHER_CTX
*)vctx
;
83 if (!cipher_generic_set_ctx_params(vctx
, params
))
85 p
= OSSL_PARAM_locate_const(params
, OSSL_CIPHER_PARAM_KEYLEN
);
89 if (!OSSL_PARAM_get_size_t(p
, &keylen
)) {
90 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_GET_PARAMETER
);
98 CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(cipher_var_keylen
)
99 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN
, NULL
),
100 CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(cipher_var_keylen
)
103 * AEAD cipher functions for OSSL_PARAM gettables and settables
105 static const OSSL_PARAM cipher_aead_known_gettable_ctx_params
[] = {
106 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN
, NULL
),
107 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN
, NULL
),
108 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TAGLEN
, NULL
),
109 OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV
, NULL
, 0),
110 OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG
, NULL
, 0),
111 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD
, NULL
),
114 const OSSL_PARAM
*cipher_aead_gettable_ctx_params(void)
116 return cipher_aead_known_gettable_ctx_params
;
119 static const OSSL_PARAM cipher_aead_known_settable_ctx_params
[] = {
120 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_IVLEN
, NULL
),
121 OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG
, NULL
, 0),
122 OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD
, NULL
, 0),
123 OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED
, NULL
, 0),
126 const OSSL_PARAM
*cipher_aead_settable_ctx_params(void)
128 return cipher_aead_known_settable_ctx_params
;
131 static int cipher_generic_init_internal(PROV_CIPHER_CTX
*ctx
,
132 const unsigned char *key
, size_t keylen
,
133 const unsigned char *iv
, size_t ivlen
,
136 ctx
->enc
= enc
? 1 : 0;
138 if (iv
!= NULL
&& ctx
->mode
!= EVP_CIPH_ECB_MODE
) {
139 if (!cipher_generic_initiv(ctx
, iv
, ivlen
))
143 if ((ctx
->flags
& EVP_CIPH_VARIABLE_LENGTH
) == 0) {
144 if (keylen
!= ctx
->keylen
) {
145 ERR_raise(ERR_LIB_PROV
, PROV_R_INVALID_KEYLEN
);
149 ctx
->keylen
= keylen
;
151 return ctx
->hw
->init(ctx
, key
, ctx
->keylen
);
156 int cipher_generic_einit(void *vctx
, const unsigned char *key
, size_t keylen
,
157 const unsigned char *iv
, size_t ivlen
)
159 return cipher_generic_init_internal((PROV_CIPHER_CTX
*)vctx
, key
, keylen
,
163 int cipher_generic_dinit(void *vctx
, const unsigned char *key
, size_t keylen
,
164 const unsigned char *iv
, size_t ivlen
)
166 return cipher_generic_init_internal((PROV_CIPHER_CTX
*)vctx
, key
, keylen
,
170 int cipher_generic_block_update(void *vctx
, unsigned char *out
, size_t *outl
,
171 size_t outsize
, const unsigned char *in
,
175 PROV_CIPHER_CTX
*ctx
= (PROV_CIPHER_CTX
*)vctx
;
176 size_t blksz
= ctx
->blocksize
;
177 size_t nextblocks
= fillblock(ctx
->buf
, &ctx
->bufsz
, blksz
, &in
, &inl
);
180 * If we're decrypting and we end an update on a block boundary we hold
181 * the last block back in case this is the last update call and the last
184 if (ctx
->bufsz
== blksz
&& (ctx
->enc
|| inl
> 0 || !ctx
->pad
)) {
185 if (outsize
< blksz
) {
186 ERR_raise(ERR_LIB_PROV
, PROV_R_OUTPUT_BUFFER_TOO_SMALL
);
189 if (!ctx
->hw
->cipher(ctx
, out
, ctx
->buf
, blksz
)) {
190 ERR_raise(ERR_LIB_PROV
, PROV_R_CIPHER_OPERATION_FAILED
);
197 if (nextblocks
> 0) {
198 if (!ctx
->enc
&& ctx
->pad
&& nextblocks
== inl
) {
199 if (!ossl_assert(inl
>= blksz
)) {
200 ERR_raise(ERR_LIB_PROV
, PROV_R_OUTPUT_BUFFER_TOO_SMALL
);
205 outlint
+= nextblocks
;
206 if (outsize
< outlint
) {
207 ERR_raise(ERR_LIB_PROV
, PROV_R_OUTPUT_BUFFER_TOO_SMALL
);
211 if (nextblocks
> 0) {
212 if (!ctx
->hw
->cipher(ctx
, out
, in
, nextblocks
)) {
213 ERR_raise(ERR_LIB_PROV
, PROV_R_CIPHER_OPERATION_FAILED
);
219 if (!trailingdata(ctx
->buf
, &ctx
->bufsz
, blksz
, &in
, &inl
)) {
220 /* ERR_raise already called */
228 int cipher_generic_block_final(void *vctx
, unsigned char *out
, size_t *outl
,
231 PROV_CIPHER_CTX
*ctx
= (PROV_CIPHER_CTX
*)vctx
;
232 size_t blksz
= ctx
->blocksize
;
236 padblock(ctx
->buf
, &ctx
->bufsz
, blksz
);
237 } else if (ctx
->bufsz
== 0) {
240 } else if (ctx
->bufsz
!= blksz
) {
241 ERR_raise(ERR_LIB_PROV
, PROV_R_WRONG_FINAL_BLOCK_LENGTH
);
245 if (outsize
< blksz
) {
246 ERR_raise(ERR_LIB_PROV
, PROV_R_OUTPUT_BUFFER_TOO_SMALL
);
249 if (!ctx
->hw
->cipher(ctx
, out
, ctx
->buf
, blksz
)) {
250 ERR_raise(ERR_LIB_PROV
, PROV_R_CIPHER_OPERATION_FAILED
);
259 if (ctx
->bufsz
!= blksz
) {
260 if (ctx
->bufsz
== 0 && !ctx
->pad
) {
264 ERR_raise(ERR_LIB_PROV
, PROV_R_WRONG_FINAL_BLOCK_LENGTH
);
268 if (!ctx
->hw
->cipher(ctx
, ctx
->buf
, ctx
->buf
, blksz
)) {
269 ERR_raise(ERR_LIB_PROV
, PROV_R_CIPHER_OPERATION_FAILED
);
273 if (ctx
->pad
&& !unpadblock(ctx
->buf
, &ctx
->bufsz
, blksz
)) {
274 /* ERR_raise already called */
278 if (outsize
< ctx
->bufsz
) {
279 ERR_raise(ERR_LIB_PROV
, PROV_R_OUTPUT_BUFFER_TOO_SMALL
);
282 memcpy(out
, ctx
->buf
, ctx
->bufsz
);
288 int cipher_generic_stream_update(void *vctx
, unsigned char *out
, size_t *outl
,
289 size_t outsize
, const unsigned char *in
,
292 PROV_CIPHER_CTX
*ctx
= (PROV_CIPHER_CTX
*)vctx
;
300 ERR_raise(ERR_LIB_PROV
, PROV_R_OUTPUT_BUFFER_TOO_SMALL
);
304 if (!ctx
->hw
->cipher(ctx
, out
, in
, inl
)) {
305 ERR_raise(ERR_LIB_PROV
, PROV_R_CIPHER_OPERATION_FAILED
);
312 int cipher_generic_stream_final(void *vctx
, unsigned char *out
, size_t *outl
,
319 int cipher_generic_cipher(void *vctx
,
320 unsigned char *out
, size_t *outl
, size_t outsize
,
321 const unsigned char *in
, size_t inl
)
323 PROV_CIPHER_CTX
*ctx
= (PROV_CIPHER_CTX
*)vctx
;
326 ERR_raise(ERR_LIB_PROV
, PROV_R_OUTPUT_BUFFER_TOO_SMALL
);
330 if (!ctx
->hw
->cipher(ctx
, out
, in
, inl
)) {
331 ERR_raise(ERR_LIB_PROV
, PROV_R_CIPHER_OPERATION_FAILED
);
339 int cipher_generic_get_ctx_params(void *vctx
, OSSL_PARAM params
[])
341 PROV_CIPHER_CTX
*ctx
= (PROV_CIPHER_CTX
*)vctx
;
344 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_IVLEN
);
345 if (p
!= NULL
&& !OSSL_PARAM_set_size_t(p
, ctx
->ivlen
)) {
346 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_SET_PARAMETER
);
349 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_PADDING
);
350 if (p
!= NULL
&& !OSSL_PARAM_set_uint(p
, ctx
->pad
)) {
351 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_SET_PARAMETER
);
354 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_IV
);
356 && !OSSL_PARAM_set_octet_ptr(p
, &ctx
->oiv
, ctx
->ivlen
)
357 && !OSSL_PARAM_set_octet_string(p
, &ctx
->oiv
, ctx
->ivlen
)) {
358 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_SET_PARAMETER
);
361 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_NUM
);
362 if (p
!= NULL
&& !OSSL_PARAM_set_uint(p
, ctx
->num
)) {
363 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_SET_PARAMETER
);
366 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_KEYLEN
);
367 if (p
!= NULL
&& !OSSL_PARAM_set_size_t(p
, ctx
->keylen
)) {
368 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_SET_PARAMETER
);
374 int cipher_generic_set_ctx_params(void *vctx
, const OSSL_PARAM params
[])
376 PROV_CIPHER_CTX
*ctx
= (PROV_CIPHER_CTX
*)vctx
;
379 p
= OSSL_PARAM_locate_const(params
, OSSL_CIPHER_PARAM_PADDING
);
383 if (!OSSL_PARAM_get_uint(p
, &pad
)) {
384 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_GET_PARAMETER
);
387 ctx
->pad
= pad
? 1 : 0;
389 p
= OSSL_PARAM_locate_const(params
, OSSL_CIPHER_PARAM_NUM
);
393 if (!OSSL_PARAM_get_uint(p
, &num
)) {
394 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_GET_PARAMETER
);
402 int cipher_generic_initiv(PROV_CIPHER_CTX
*ctx
, const unsigned char *iv
,
405 if (ivlen
!= ctx
->ivlen
406 || ivlen
> sizeof(ctx
->iv
)) {
407 ERR_raise(ERR_LIB_PROV
, PROV_R_INVALID_IVLEN
);
411 memcpy(ctx
->iv
, iv
, ivlen
);
412 memcpy(ctx
->oiv
, iv
, ivlen
);
416 void cipher_generic_initkey(void *vctx
, size_t kbits
, size_t blkbits
,
417 size_t ivbits
, unsigned int mode
, uint64_t flags
,
418 const PROV_CIPHER_HW
*hw
, void *provctx
)
420 PROV_CIPHER_CTX
*ctx
= (PROV_CIPHER_CTX
*)vctx
;
424 ctx
->keylen
= ((kbits
) / 8);
425 ctx
->ivlen
= ((ivbits
) / 8);
428 ctx
->blocksize
= blkbits
/ 8;
430 ctx
->libctx
= PROV_LIBRARY_CONTEXT_OF(provctx
); /* used for rand */