2 * Copyright 2022 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_dispatch.h>
14 #include "internal/provider.h"
15 #include "internal/core.h"
16 #include "crypto/evp.h"
17 #include "evp_local.h"
19 static int evp_mac_up_ref(void *vmac
)
24 CRYPTO_UP_REF(&mac
->refcnt
, &ref
, mac
->lock
);
28 static void evp_mac_free(void *vmac
)
36 CRYPTO_DOWN_REF(&mac
->refcnt
, &ref
, mac
->lock
);
39 OPENSSL_free(mac
->type_name
);
40 ossl_provider_free(mac
->prov
);
41 CRYPTO_THREAD_lock_free(mac
->lock
);
45 static void *evp_mac_new(void)
49 if ((mac
= OPENSSL_zalloc(sizeof(*mac
))) == NULL
50 || (mac
->lock
= CRYPTO_THREAD_lock_new()) == NULL
) {
60 static void *evp_mac_from_algorithm(int name_id
,
61 const OSSL_ALGORITHM
*algodef
,
64 const OSSL_DISPATCH
*fns
= algodef
->implementation
;
66 int fnmaccnt
= 0, fnctxcnt
= 0;
68 if ((mac
= evp_mac_new()) == NULL
) {
69 ERR_raise(ERR_LIB_EVP
, ERR_R_MALLOC_FAILURE
);
72 mac
->name_id
= name_id
;
73 if ((mac
->type_name
= ossl_algorithm_get1_first_name(algodef
)) == NULL
) {
77 mac
->description
= algodef
->algorithm_description
;
79 for (; fns
->function_id
!= 0; fns
++) {
80 switch (fns
->function_id
) {
81 case OSSL_FUNC_MAC_NEWCTX
:
82 if (mac
->newctx
!= NULL
)
84 mac
->newctx
= OSSL_FUNC_mac_newctx(fns
);
87 case OSSL_FUNC_MAC_DUPCTX
:
88 if (mac
->dupctx
!= NULL
)
90 mac
->dupctx
= OSSL_FUNC_mac_dupctx(fns
);
92 case OSSL_FUNC_MAC_FREECTX
:
93 if (mac
->freectx
!= NULL
)
95 mac
->freectx
= OSSL_FUNC_mac_freectx(fns
);
98 case OSSL_FUNC_MAC_INIT
:
99 if (mac
->init
!= NULL
)
101 mac
->init
= OSSL_FUNC_mac_init(fns
);
104 case OSSL_FUNC_MAC_UPDATE
:
105 if (mac
->update
!= NULL
)
107 mac
->update
= OSSL_FUNC_mac_update(fns
);
110 case OSSL_FUNC_MAC_FINAL
:
111 if (mac
->final
!= NULL
)
113 mac
->final
= OSSL_FUNC_mac_final(fns
);
116 case OSSL_FUNC_MAC_GETTABLE_PARAMS
:
117 if (mac
->gettable_params
!= NULL
)
119 mac
->gettable_params
=
120 OSSL_FUNC_mac_gettable_params(fns
);
122 case OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS
:
123 if (mac
->gettable_ctx_params
!= NULL
)
125 mac
->gettable_ctx_params
=
126 OSSL_FUNC_mac_gettable_ctx_params(fns
);
128 case OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS
:
129 if (mac
->settable_ctx_params
!= NULL
)
131 mac
->settable_ctx_params
=
132 OSSL_FUNC_mac_settable_ctx_params(fns
);
134 case OSSL_FUNC_MAC_GET_PARAMS
:
135 if (mac
->get_params
!= NULL
)
137 mac
->get_params
= OSSL_FUNC_mac_get_params(fns
);
139 case OSSL_FUNC_MAC_GET_CTX_PARAMS
:
140 if (mac
->get_ctx_params
!= NULL
)
142 mac
->get_ctx_params
= OSSL_FUNC_mac_get_ctx_params(fns
);
144 case OSSL_FUNC_MAC_SET_CTX_PARAMS
:
145 if (mac
->set_ctx_params
!= NULL
)
147 mac
->set_ctx_params
= OSSL_FUNC_mac_set_ctx_params(fns
);
154 * In order to be a consistent set of functions we must have at least
155 * a complete set of "mac" functions, and a complete set of context
156 * management functions, as well as the size function.
159 ERR_raise(ERR_LIB_EVP
, EVP_R_INVALID_PROVIDER_FUNCTIONS
);
164 ossl_provider_up_ref(prov
);
169 EVP_MAC
*EVP_MAC_fetch(OSSL_LIB_CTX
*libctx
, const char *algorithm
,
170 const char *properties
)
172 return evp_generic_fetch(libctx
, OSSL_OP_MAC
, algorithm
, properties
,
173 evp_mac_from_algorithm
, evp_mac_up_ref
,
177 int EVP_MAC_up_ref(EVP_MAC
*mac
)
179 return evp_mac_up_ref(mac
);
182 void EVP_MAC_free(EVP_MAC
*mac
)
187 const OSSL_PROVIDER
*EVP_MAC_get0_provider(const EVP_MAC
*mac
)
192 const OSSL_PARAM
*EVP_MAC_gettable_params(const EVP_MAC
*mac
)
194 if (mac
->gettable_params
== NULL
)
196 return mac
->gettable_params(ossl_provider_ctx(EVP_MAC_get0_provider(mac
)));
199 const OSSL_PARAM
*EVP_MAC_gettable_ctx_params(const EVP_MAC
*mac
)
203 if (mac
->gettable_ctx_params
== NULL
)
205 alg
= ossl_provider_ctx(EVP_MAC_get0_provider(mac
));
206 return mac
->gettable_ctx_params(NULL
, alg
);
209 const OSSL_PARAM
*EVP_MAC_settable_ctx_params(const EVP_MAC
*mac
)
213 if (mac
->settable_ctx_params
== NULL
)
215 alg
= ossl_provider_ctx(EVP_MAC_get0_provider(mac
));
216 return mac
->settable_ctx_params(NULL
, alg
);
219 const OSSL_PARAM
*EVP_MAC_CTX_gettable_params(EVP_MAC_CTX
*ctx
)
223 if (ctx
->meth
->gettable_ctx_params
== NULL
)
225 alg
= ossl_provider_ctx(EVP_MAC_get0_provider(ctx
->meth
));
226 return ctx
->meth
->gettable_ctx_params(ctx
->algctx
, alg
);
229 const OSSL_PARAM
*EVP_MAC_CTX_settable_params(EVP_MAC_CTX
*ctx
)
233 if (ctx
->meth
->settable_ctx_params
== NULL
)
235 alg
= ossl_provider_ctx(EVP_MAC_get0_provider(ctx
->meth
));
236 return ctx
->meth
->settable_ctx_params(ctx
->algctx
, alg
);
239 void EVP_MAC_do_all_provided(OSSL_LIB_CTX
*libctx
,
240 void (*fn
)(EVP_MAC
*mac
, void *arg
),
243 evp_generic_do_all(libctx
, OSSL_OP_MAC
,
244 (void (*)(void *, void *))fn
, arg
,
245 evp_mac_from_algorithm
, evp_mac_up_ref
, evp_mac_free
);