aboutsummaryrefslogtreecommitdiff
path: root/crypto/evp/mac_meth.c
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2019-05-07 12:39:58 +0200
committerRichard Levitte <levitte@openssl.org>2019-08-15 22:12:25 +0200
commite74bd29053a543ab4908ae8545b46f2e38c98bab (patch)
treeee0d540bd5f8319549c1ab0d4b356f8b166d021e /crypto/evp/mac_meth.c
parent3ded2288a45d2cc3a27a1b08d29499cbcec52c0e (diff)
downloadopenssl-e74bd29053a543ab4908ae8545b46f2e38c98bab.zip
openssl-e74bd29053a543ab4908ae8545b46f2e38c98bab.tar.gz
openssl-e74bd29053a543ab4908ae8545b46f2e38c98bab.tar.bz2
Prepare EVP_MAC infrastructure for moving all MACs to providers
Quite a few adaptations are needed, most prominently the added code to allow provider based MACs. As part of this, all the old information functions are gone, except for EVP_MAC_name(). Some of them will reappear later, for example EVP_MAC_do_all() in some form. MACs by EVP_PKEY was particularly difficult to deal with, as they need to allocate and deallocate EVP_MAC_CTXs "under the hood", and thereby implicitly fetch the corresponding EVP_MAC. This means that EVP_MACs can't be constant in a EVP_MAC_CTX, as their reference count may need to be incremented and decremented as part of the allocation or deallocation of the EVP_MAC_CTX. It may be that other provider based EVP operation types may need to be handled in a similar manner. Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Shane Lontis <shane.lontis@oracle.com> (Merged from https://github.com/openssl/openssl/pull/8877)
Diffstat (limited to 'crypto/evp/mac_meth.c')
-rw-r--r--crypto/evp/mac_meth.c195
1 files changed, 195 insertions, 0 deletions
diff --git a/crypto/evp/mac_meth.c b/crypto/evp/mac_meth.c
new file mode 100644
index 0000000..983b2db
--- /dev/null
+++ b/crypto/evp/mac_meth.c
@@ -0,0 +1,195 @@
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <openssl/core.h>
+#include <openssl/core_numbers.h>
+#include "internal/evp_int.h"
+#include "internal/provider.h"
+#include "evp_locl.h"
+
+static int evp_mac_up_ref(void *vmac)
+{
+ EVP_MAC *mac = vmac;
+ int ref = 0;
+
+ CRYPTO_UP_REF(&mac->refcnt, &ref, mac->lock);
+ return 1;
+}
+
+static void evp_mac_free(void *vmac)
+{
+ EVP_MAC *mac = vmac;
+ int ref = 0;
+
+ if (mac == NULL)
+ return;
+
+ CRYPTO_DOWN_REF(&mac->refcnt, &ref, mac->lock);
+ if (ref > 0)
+ return;
+ ossl_provider_free(mac->prov);
+ OPENSSL_free(mac->name);
+ CRYPTO_THREAD_lock_free(mac->lock);
+ OPENSSL_free(mac);
+}
+
+static void *evp_mac_new(void)
+{
+ EVP_MAC *mac = NULL;
+
+ if ((mac = OPENSSL_zalloc(sizeof(*mac))) == NULL
+ || (mac->lock = CRYPTO_THREAD_lock_new()) == NULL) {
+ evp_mac_free(mac);
+ return NULL;
+ }
+
+ mac->refcnt = 1;
+
+ return mac;
+}
+
+static void *evp_mac_from_dispatch(const char *name, const OSSL_DISPATCH *fns,
+ OSSL_PROVIDER *prov)
+{
+ EVP_MAC *mac = NULL;
+ int fnmaccnt = 0, fnctxcnt = 0;
+
+ if ((mac = evp_mac_new()) == NULL
+ || (mac->name = OPENSSL_strdup(name)) == NULL) {
+ EVP_MAC_free(mac);
+ EVPerr(0, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ for (; fns->function_id != 0; fns++) {
+ switch (fns->function_id) {
+ case OSSL_FUNC_MAC_NEWCTX:
+ if (mac->newctx != NULL)
+ break;
+ mac->newctx = OSSL_get_OP_mac_newctx(fns);
+ fnctxcnt++;
+ break;
+ case OSSL_FUNC_MAC_DUPCTX:
+ if (mac->dupctx != NULL)
+ break;
+ mac->dupctx = OSSL_get_OP_mac_dupctx(fns);
+ break;
+ case OSSL_FUNC_MAC_FREECTX:
+ if (mac->freectx != NULL)
+ break;
+ mac->freectx = OSSL_get_OP_mac_freectx(fns);
+ fnctxcnt++;
+ break;
+ case OSSL_FUNC_MAC_INIT:
+ if (mac->init != NULL)
+ break;
+ mac->init = OSSL_get_OP_mac_init(fns);
+ fnmaccnt++;
+ break;
+ case OSSL_FUNC_MAC_UPDATE:
+ if (mac->update != NULL)
+ break;
+ mac->update = OSSL_get_OP_mac_update(fns);
+ fnmaccnt++;
+ break;
+ case OSSL_FUNC_MAC_FINAL:
+ if (mac->final != NULL)
+ break;
+ mac->final = OSSL_get_OP_mac_final(fns);
+ fnmaccnt++;
+ break;
+ case OSSL_FUNC_MAC_GETTABLE_PARAMS:
+ if (mac->gettable_params != NULL)
+ break;
+ mac->gettable_params =
+ OSSL_get_OP_mac_gettable_params(fns);
+ break;
+ case OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS:
+ if (mac->gettable_ctx_params != NULL)
+ break;
+ mac->gettable_ctx_params =
+ OSSL_get_OP_mac_gettable_ctx_params(fns);
+ break;
+ case OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS:
+ if (mac->settable_ctx_params != NULL)
+ break;
+ mac->settable_ctx_params =
+ OSSL_get_OP_mac_settable_ctx_params(fns);
+ break;
+ case OSSL_FUNC_MAC_GET_PARAMS:
+ if (mac->get_params != NULL)
+ break;
+ mac->get_params = OSSL_get_OP_mac_get_params(fns);
+ break;
+ case OSSL_FUNC_MAC_CTX_GET_PARAMS:
+ if (mac->ctx_get_params != NULL)
+ break;
+ mac->ctx_get_params = OSSL_get_OP_mac_ctx_get_params(fns);
+ break;
+ case OSSL_FUNC_MAC_CTX_SET_PARAMS:
+ if (mac->ctx_set_params != NULL)
+ break;
+ mac->ctx_set_params = OSSL_get_OP_mac_ctx_set_params(fns);
+ break;
+ }
+ }
+ if (fnmaccnt != 3
+ || fnctxcnt != 2) {
+ /*
+ * In order to be a consistent set of functions we must have at least
+ * a complete set of "mac" functions, and a complete set of context
+ * management functions, as well as the size function.
+ */
+ evp_mac_free(mac);
+ ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
+ return NULL;
+ }
+ mac->prov = prov;
+ if (prov != NULL)
+ ossl_provider_up_ref(prov);
+
+ return mac;
+}
+
+EVP_MAC *EVP_MAC_fetch(OPENSSL_CTX *libctx, const char *algorithm,
+ const char *properties)
+{
+ return evp_generic_fetch(libctx, OSSL_OP_MAC, algorithm, properties,
+ evp_mac_from_dispatch, evp_mac_up_ref,
+ evp_mac_free);
+}
+
+int EVP_MAC_up_ref(EVP_MAC *mac)
+{
+ return evp_mac_up_ref(mac);
+}
+
+void EVP_MAC_free(EVP_MAC *mac)
+{
+ evp_mac_free(mac);
+}
+
+const char *EVP_MAC_name(const EVP_MAC *mac)
+{
+ return mac->name;
+}
+
+const OSSL_PARAM *EVP_MAC_gettable_params(const EVP_MAC *mac)
+{
+ if (mac->gettable_params == NULL)
+ return NULL;
+ return mac->gettable_params();
+}
+
+const OSSL_PARAM *EVP_MAC_CTX_gettable_params(const EVP_MAC *mac)
+{
+ if (mac->gettable_ctx_params == NULL)
+ return NULL;
+ return mac->gettable_ctx_params();
+}
+
+const OSSL_PARAM *EVP_MAC_CTX_settable_params(const EVP_MAC *mac)
+{
+ if (mac->settable_ctx_params == NULL)
+ return NULL;
+ return mac->settable_ctx_params();
+}