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
10 #include <openssl/evp.h>
11 #include <openssl/err.h>
12 #include <openssl/core.h>
13 #include <openssl/core_numbers.h>
14 #include <openssl/kdf.h>
15 #include "crypto/evp.h"
16 #include "internal/provider.h"
17 #include "evp_local.h"
19 static int evp_kdf_up_ref(void *vkdf
)
21 EVP_KDF
*kdf
= (EVP_KDF
*)vkdf
;
24 CRYPTO_UP_REF(&kdf
->refcnt
, &ref
, kdf
->lock
);
28 static void evp_kdf_free(void *vkdf
){
29 EVP_KDF
*kdf
= (EVP_KDF
*)vkdf
;
33 CRYPTO_DOWN_REF(&kdf
->refcnt
, &ref
, kdf
->lock
);
35 ossl_provider_free(kdf
->prov
);
36 CRYPTO_THREAD_lock_free(kdf
->lock
);
42 static void *evp_kdf_new(void)
46 if ((kdf
= OPENSSL_zalloc(sizeof(*kdf
))) == NULL
47 || (kdf
->lock
= CRYPTO_THREAD_lock_new()) == NULL
) {
55 static void *evp_kdf_from_dispatch(int name_id
,
56 const OSSL_DISPATCH
*fns
,
61 int fnkdfcnt
= 0, fnctxcnt
= 0;
63 if ((kdf
= evp_kdf_new()) == NULL
) {
64 EVPerr(0, ERR_R_MALLOC_FAILURE
);
67 kdf
->name_id
= name_id
;
69 for (; fns
->function_id
!= 0; fns
++) {
70 switch (fns
->function_id
) {
71 case OSSL_FUNC_KDF_NEWCTX
:
72 if (kdf
->newctx
!= NULL
)
74 kdf
->newctx
= OSSL_get_OP_kdf_newctx(fns
);
77 case OSSL_FUNC_KDF_DUPCTX
:
78 if (kdf
->dupctx
!= NULL
)
80 kdf
->dupctx
= OSSL_get_OP_kdf_dupctx(fns
);
82 case OSSL_FUNC_KDF_FREECTX
:
83 if (kdf
->freectx
!= NULL
)
85 kdf
->freectx
= OSSL_get_OP_kdf_freectx(fns
);
88 case OSSL_FUNC_KDF_RESET
:
89 if (kdf
->reset
!= NULL
)
91 kdf
->reset
= OSSL_get_OP_kdf_reset(fns
);
93 case OSSL_FUNC_KDF_DERIVE
:
94 if (kdf
->derive
!= NULL
)
96 kdf
->derive
= OSSL_get_OP_kdf_derive(fns
);
99 case OSSL_FUNC_KDF_GETTABLE_PARAMS
:
100 if (kdf
->gettable_params
!= NULL
)
102 kdf
->gettable_params
=
103 OSSL_get_OP_kdf_gettable_params(fns
);
105 case OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS
:
106 if (kdf
->gettable_ctx_params
!= NULL
)
108 kdf
->gettable_ctx_params
=
109 OSSL_get_OP_kdf_gettable_ctx_params(fns
);
111 case OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS
:
112 if (kdf
->settable_ctx_params
!= NULL
)
114 kdf
->settable_ctx_params
=
115 OSSL_get_OP_kdf_settable_ctx_params(fns
);
117 case OSSL_FUNC_KDF_GET_PARAMS
:
118 if (kdf
->get_params
!= NULL
)
120 kdf
->get_params
= OSSL_get_OP_kdf_get_params(fns
);
122 case OSSL_FUNC_KDF_GET_CTX_PARAMS
:
123 if (kdf
->get_ctx_params
!= NULL
)
125 kdf
->get_ctx_params
= OSSL_get_OP_kdf_get_ctx_params(fns
);
127 case OSSL_FUNC_KDF_SET_CTX_PARAMS
:
128 if (kdf
->set_ctx_params
!= NULL
)
130 kdf
->set_ctx_params
= OSSL_get_OP_kdf_set_ctx_params(fns
);
134 if (fnkdfcnt
!= 1 || fnctxcnt
!= 2) {
136 * In order to be a consistent set of functions we must have at least
137 * a derive function, and a complete set of context management
141 ERR_raise(ERR_LIB_EVP
, EVP_R_INVALID_PROVIDER_FUNCTIONS
);
146 ossl_provider_up_ref(prov
);
151 EVP_KDF
*EVP_KDF_fetch(OPENSSL_CTX
*libctx
, const char *algorithm
,
152 const char *properties
)
154 return evp_generic_fetch(libctx
, OSSL_OP_KDF
, algorithm
, properties
,
155 evp_kdf_from_dispatch
, NULL
, evp_kdf_up_ref
,
159 int EVP_KDF_up_ref(EVP_KDF
*kdf
)
161 return evp_kdf_up_ref(kdf
);
164 void EVP_KDF_free(EVP_KDF
*kdf
)
169 const OSSL_PARAM
*EVP_KDF_gettable_params(const EVP_KDF
*kdf
)
171 if (kdf
->gettable_params
== NULL
)
173 return kdf
->gettable_params();
176 const OSSL_PARAM
*EVP_KDF_CTX_gettable_params(const EVP_KDF
*kdf
)
178 if (kdf
->gettable_ctx_params
== NULL
)
180 return kdf
->gettable_ctx_params();
183 const OSSL_PARAM
*EVP_KDF_CTX_settable_params(const EVP_KDF
*kdf
)
185 if (kdf
->settable_ctx_params
== NULL
)
187 return kdf
->settable_ctx_params();
190 void EVP_KDF_do_all_ex(OPENSSL_CTX
*libctx
,
191 void (*fn
)(EVP_KDF
*kdf
, void *arg
),
194 evp_generic_do_all(libctx
, OSSL_OP_KDF
,
195 (void (*)(void *, void *))fn
, arg
,
196 evp_kdf_from_dispatch
, NULL
, evp_kdf_free
);