2 * Copyright 2019-2021 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
10 /* Dispatch functions for chacha20 cipher */
12 #include <openssl/proverr.h>
13 #include "cipher_chacha20.h"
14 #include "prov/implementations.h"
15 #include "prov/providercommon.h"
17 #define CHACHA20_KEYLEN (CHACHA_KEY_SIZE)
18 #define CHACHA20_BLKLEN (1)
19 #define CHACHA20_IVLEN (CHACHA_CTR_SIZE)
20 #define CHACHA20_FLAGS (PROV_CIPHER_FLAG_CUSTOM_IV)
22 static OSSL_FUNC_cipher_newctx_fn chacha20_newctx
;
23 static OSSL_FUNC_cipher_freectx_fn chacha20_freectx
;
24 static OSSL_FUNC_cipher_get_params_fn chacha20_get_params
;
25 static OSSL_FUNC_cipher_get_ctx_params_fn chacha20_get_ctx_params
;
26 static OSSL_FUNC_cipher_set_ctx_params_fn chacha20_set_ctx_params
;
27 static OSSL_FUNC_cipher_gettable_ctx_params_fn chacha20_gettable_ctx_params
;
28 static OSSL_FUNC_cipher_settable_ctx_params_fn chacha20_settable_ctx_params
;
29 #define chacha20_cipher ossl_cipher_generic_cipher
30 #define chacha20_update ossl_cipher_generic_stream_update
31 #define chacha20_final ossl_cipher_generic_stream_final
32 #define chacha20_gettable_params ossl_cipher_generic_gettable_params
34 void ossl_chacha20_initctx(PROV_CHACHA20_CTX
*ctx
)
36 ossl_cipher_generic_initkey(ctx
, CHACHA20_KEYLEN
* 8,
40 ossl_prov_cipher_hw_chacha20(CHACHA20_KEYLEN
* 8),
44 static void *chacha20_newctx(void *provctx
)
46 PROV_CHACHA20_CTX
*ctx
;
48 if (!ossl_prov_is_running())
51 ctx
= OPENSSL_zalloc(sizeof(*ctx
));
53 ossl_chacha20_initctx(ctx
);
57 static void chacha20_freectx(void *vctx
)
59 PROV_CHACHA20_CTX
*ctx
= (PROV_CHACHA20_CTX
*)vctx
;
62 ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX
*)vctx
);
63 OPENSSL_clear_free(ctx
, sizeof(*ctx
));
67 static int chacha20_get_params(OSSL_PARAM params
[])
69 return ossl_cipher_generic_get_params(params
, 0, CHACHA20_FLAGS
,
75 static int chacha20_get_ctx_params(void *vctx
, OSSL_PARAM params
[])
79 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_IVLEN
);
80 if (p
!= NULL
&& !OSSL_PARAM_set_size_t(p
, CHACHA20_IVLEN
)) {
81 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_SET_PARAMETER
);
84 p
= OSSL_PARAM_locate(params
, OSSL_CIPHER_PARAM_KEYLEN
);
85 if (p
!= NULL
&& !OSSL_PARAM_set_size_t(p
, CHACHA20_KEYLEN
)) {
86 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_SET_PARAMETER
);
93 static const OSSL_PARAM chacha20_known_gettable_ctx_params
[] = {
94 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN
, NULL
),
95 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN
, NULL
),
98 const OSSL_PARAM
*chacha20_gettable_ctx_params(ossl_unused
void *provctx
)
100 return chacha20_known_gettable_ctx_params
;
103 static int chacha20_set_ctx_params(void *vctx
, const OSSL_PARAM params
[])
108 p
= OSSL_PARAM_locate_const(params
, OSSL_CIPHER_PARAM_KEYLEN
);
110 if (!OSSL_PARAM_get_size_t(p
, &len
)) {
111 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_GET_PARAMETER
);
114 if (len
!= CHACHA20_KEYLEN
) {
115 ERR_raise(ERR_LIB_PROV
, PROV_R_INVALID_KEY_LENGTH
);
119 p
= OSSL_PARAM_locate_const(params
, OSSL_CIPHER_PARAM_IVLEN
);
121 if (!OSSL_PARAM_get_size_t(p
, &len
)) {
122 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_GET_PARAMETER
);
125 if (len
!= CHACHA20_IVLEN
) {
126 ERR_raise(ERR_LIB_PROV
, PROV_R_INVALID_IV_LENGTH
);
133 static const OSSL_PARAM chacha20_known_settable_ctx_params
[] = {
134 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN
, NULL
),
135 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN
, NULL
),
138 const OSSL_PARAM
*chacha20_settable_ctx_params(ossl_unused
void *provctx
)
140 return chacha20_known_settable_ctx_params
;
143 int ossl_chacha20_einit(void *vctx
, const unsigned char *key
, size_t keylen
,
144 const unsigned char *iv
, size_t ivlen
)
148 /* The generic function checks for ossl_prov_is_running() */
149 ret
= ossl_cipher_generic_einit(vctx
, key
, keylen
, iv
, ivlen
);
150 if (ret
&& iv
!= NULL
) {
151 PROV_CIPHER_CTX
*ctx
= (PROV_CIPHER_CTX
*)vctx
;
152 PROV_CIPHER_HW_CHACHA20
*hw
= (PROV_CIPHER_HW_CHACHA20
*)ctx
->hw
;
159 int ossl_chacha20_dinit(void *vctx
, const unsigned char *key
, size_t keylen
,
160 const unsigned char *iv
, size_t ivlen
)
164 /* The generic function checks for ossl_prov_is_running() */
165 ret
= ossl_cipher_generic_dinit(vctx
, key
, keylen
, iv
, ivlen
);
166 if (ret
&& iv
!= NULL
) {
167 PROV_CIPHER_CTX
*ctx
= (PROV_CIPHER_CTX
*)vctx
;
168 PROV_CIPHER_HW_CHACHA20
*hw
= (PROV_CIPHER_HW_CHACHA20
*)ctx
->hw
;
175 /* ossl_chacha20_functions */
176 const OSSL_DISPATCH ossl_chacha20_functions
[] = {
177 { OSSL_FUNC_CIPHER_NEWCTX
, (void (*)(void))chacha20_newctx
},
178 { OSSL_FUNC_CIPHER_FREECTX
, (void (*)(void))chacha20_freectx
},
179 { OSSL_FUNC_CIPHER_ENCRYPT_INIT
, (void (*)(void))ossl_chacha20_einit
},
180 { OSSL_FUNC_CIPHER_DECRYPT_INIT
, (void (*)(void))ossl_chacha20_dinit
},
181 { OSSL_FUNC_CIPHER_UPDATE
, (void (*)(void))chacha20_update
},
182 { OSSL_FUNC_CIPHER_FINAL
, (void (*)(void))chacha20_final
},
183 { OSSL_FUNC_CIPHER_CIPHER
, (void (*)(void))chacha20_cipher
},
184 { OSSL_FUNC_CIPHER_GET_PARAMS
, (void (*)(void))chacha20_get_params
},
185 { OSSL_FUNC_CIPHER_GETTABLE_PARAMS
,(void (*)(void))chacha20_gettable_params
},
186 { OSSL_FUNC_CIPHER_GET_CTX_PARAMS
, (void (*)(void))chacha20_get_ctx_params
},
187 { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS
,
188 (void (*)(void))chacha20_gettable_ctx_params
},
189 { OSSL_FUNC_CIPHER_SET_CTX_PARAMS
, (void (*)(void))chacha20_set_ctx_params
},
190 { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS
,
191 (void (*)(void))chacha20_settable_ctx_params
},