/*
- * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
#include <openssl/engine.h>
#include <openssl/params.h>
#include <openssl/core_names.h>
-#include "internal/evp_int.h"
-#include "evp_locl.h"
+#include "crypto/evp.h"
+#include "evp_local.h"
/* MAC PKEY context structure */
MAC_PKEY_CTX *hctx;
/* We're being smart and using the same base NIDs for PKEY and for MAC */
int nid = ctx->pmeth->pkey_id;
- EVP_MAC *mac = EVP_MAC_fetch(NULL, OBJ_nid2sn(nid), NULL);
+ EVP_MAC *mac;
+
+ ERR_set_mark();
+ mac = EVP_MAC_fetch(ctx->libctx, OBJ_nid2sn(nid), ctx->propquery);
+ ERR_pop_to_mark();
+
+ /*
+ * mac == NULL may actually be ok in some situations. In an
+ * EVP_PKEY_new_mac_key() call a temporary EVP_PKEY_CTX is created with
+ * default libctx. We don't actually need the underlying MAC to be present
+ * to successfully set the key in that case. The resulting EVP_PKEY could
+ * then be used in some other libctx where the MAC *is* present
+ */
if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) {
EVPerr(EVP_F_PKEY_MAC_INIT, ERR_R_MALLOC_FAILURE);
return 0;
}
- hctx->ctx = EVP_MAC_CTX_new(mac);
- if (hctx->ctx == NULL) {
- OPENSSL_free(hctx);
- return 0;
+ if (mac != NULL) {
+ hctx->ctx = EVP_MAC_CTX_new(mac);
+ if (hctx->ctx == NULL) {
+ OPENSSL_free(hctx);
+ return 0;
+ }
}
if (nid == EVP_PKEY_CMAC) {
MAC_PKEY_CTX *sctx, *dctx;
sctx = EVP_PKEY_CTX_get_data(src);
+
+ if (sctx->ctx == NULL) {
+ /* This actually means the fetch failed during the init call */
+ EVPerr(0, EVP_R_FETCH_FAILED);
+ return 0;
+ }
+
if (sctx->ctx->data == NULL)
return 0;
MAC_PKEY_CTX *hctx = ctx == NULL ? NULL : EVP_PKEY_CTX_get_data(ctx);
if (hctx != NULL) {
- EVP_MAC *mac = EVP_MAC_CTX_mac(hctx->ctx);
+ EVP_MAC *mac = hctx->ctx != NULL ? EVP_MAC_CTX_mac(hctx->ctx) : NULL;
switch (hctx->type) {
case MAC_TYPE_RAW:
break;
case MAC_TYPE_MAC:
{
- EVP_MAC_CTX *cmkey = EVP_MAC_CTX_dup(hctx->ctx);
+ EVP_MAC_CTX *cmkey;
+ if (hctx->ctx == NULL) {
+ /* This actually means the fetch failed during the init call */
+ EVPerr(0, EVP_R_FETCH_FAILED);
+ return 0;
+ }
+
+ cmkey = EVP_MAC_CTX_dup(hctx->ctx);
if (cmkey == NULL)
return 0;
if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(hctx->ctx)))
hctx->type == MAC_TYPE_RAW
&& (ctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) != 0;
+ if (hctx->ctx == NULL) {
+ /* This actually means the fetch failed during the init call */
+ EVPerr(0, EVP_R_FETCH_FAILED);
+ return 0;
+ }
+
if (set_key) {
if (!EVP_MAC_is_a(EVP_MAC_CTX_mac(hctx->ctx),
OBJ_nid2sn(EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx)))))
char *engineid = (char *)ENGINE_get_id(ctx->engine);
params[params_n++] =
- OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ENGINE,
- engineid, 0);
+ OSSL_PARAM_construct_utf8_string("engine", engineid, 0);
#endif
params[params_n++] =
OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
ciphname, 0);
params[params_n] = OSSL_PARAM_construct_end();
+ if (hctx->ctx == NULL) {
+ /*
+ * This actually means the fetch failed during the init call
+ */
+ EVPerr(0, EVP_R_FETCH_FAILED);
+ return 0;
+ }
+
if (!EVP_MAC_CTX_set_params(hctx->ctx, params)
|| !EVP_MAC_init(hctx->ctx))
return 0;
if (ctx->pkey == NULL)
return 0;
- new_mac_ctx = EVP_MAC_CTX_dup((EVP_MAC_CTX *)ctx->pkey
- ->pkey.ptr);
+ new_mac_ctx = EVP_MAC_CTX_dup(ctx->pkey->pkey.ptr);
if (new_mac_ctx == NULL)
return 0;
EVP_MAC_CTX_free(hctx->ctx);
params[0] =
OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &size);
+ if (hctx->ctx == NULL) {
+ /*
+ * This actually means the fetch failed during the init call
+ */
+ EVPerr(0, EVP_R_FETCH_FAILED);
+ return 0;
+ }
+
if (!EVP_MAC_CTX_set_params(hctx->ctx, params))
return 0;
p2, p1);
params[params_n] = OSSL_PARAM_construct_end();
+ if (hctx->ctx == NULL) {
+ /*
+ * This actually means the fetch failed during the init call
+ */
+ EVPerr(0, EVP_R_FETCH_FAILED);
+ return 0;
+ }
+
return EVP_MAC_CTX_set_params(hctx->ctx, params);
}
break;
case EVP_PKEY_CTRL_DIGESTINIT:
switch (hctx->type) {
case MAC_TYPE_RAW:
+ if (hctx->ctx == NULL) {
+ /* This actually means the fetch failed during the init call */
+ EVPerr(0, EVP_R_FETCH_FAILED);
+ return 0;
+ }
+
/* Ensure that we have attached the implementation */
if (!EVP_MAC_init(hctx->ctx))
return 0;
char *engineid = ctx->engine == NULL
? NULL : (char *)ENGINE_get_id(ctx->engine);
- if (engineid != NULL) {
+ if (engineid != NULL)
params[params_n++] =
- OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ENGINE,
- engineid, 0);
- }
+ OSSL_PARAM_construct_utf8_string("engine", engineid, 0);
#endif
params[params_n++] =
OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
}
static int pkey_mac_ctrl_str(EVP_PKEY_CTX *ctx,
- const char *type, const char *value)
+ const char *type, const char *value)
{
MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
- const EVP_MAC *mac = EVP_MAC_CTX_mac(hctx->ctx);
+ const EVP_MAC *mac;
OSSL_PARAM params[2];
int ok = 0;
+ if (hctx == NULL) {
+ EVPerr(0, EVP_R_NULL_MAC_PKEY_CTX);
+ return 0;
+ }
+ if (hctx->ctx == NULL) {
+ /* This actually means the fetch failed during the init call */
+ EVPerr(0, EVP_R_FETCH_FAILED);
+ return 0;
+ }
+ mac = EVP_MAC_CTX_mac(hctx->ctx);
+
/*
* Translation of some control names that are equivalent to a single
* parameter name.
type = OSSL_MAC_PARAM_SIZE;
if (!OSSL_PARAM_allocate_from_text(¶ms[0],
- EVP_MAC_CTX_settable_params(mac),
- type, value, strlen(value) + 1))
+ EVP_MAC_settable_ctx_params(mac),
+ type, value, strlen(value) + 1, NULL))
return 0;
params[1] = OSSL_PARAM_construct_end();
+
ok = EVP_MAC_CTX_set_params(hctx->ctx, params);
OPENSSL_free(params[0].data);
return ok;
}
-const EVP_PKEY_METHOD cmac_pkey_meth = {
+static const EVP_PKEY_METHOD cmac_pkey_meth = {
EVP_PKEY_CMAC,
EVP_PKEY_FLAG_SIGCTX_CUSTOM,
pkey_mac_init,
pkey_mac_ctrl_str
};
-const EVP_PKEY_METHOD hmac_pkey_meth = {
+const EVP_PKEY_METHOD *cmac_pkey_method(void)
+{
+ return &cmac_pkey_meth;
+}
+
+static const EVP_PKEY_METHOD hmac_pkey_meth = {
EVP_PKEY_HMAC,
0,
pkey_mac_init,
pkey_mac_ctrl_str
};
-const EVP_PKEY_METHOD siphash_pkey_meth = {
+const EVP_PKEY_METHOD *hmac_pkey_method(void)
+{
+ return &hmac_pkey_meth;
+}
+
+static const EVP_PKEY_METHOD siphash_pkey_meth = {
EVP_PKEY_SIPHASH,
EVP_PKEY_FLAG_SIGCTX_CUSTOM,
pkey_mac_init,
pkey_mac_ctrl_str
};
-const EVP_PKEY_METHOD poly1305_pkey_meth = {
+const EVP_PKEY_METHOD *siphash_pkey_method(void)
+{
+ return &siphash_pkey_meth;
+}
+
+static const EVP_PKEY_METHOD poly1305_pkey_meth = {
EVP_PKEY_POLY1305,
EVP_PKEY_FLAG_SIGCTX_CUSTOM,
pkey_mac_init,
pkey_mac_ctrl,
pkey_mac_ctrl_str
};
+
+const EVP_PKEY_METHOD *poly1305_pkey_method(void)
+{
+ return &poly1305_pkey_meth;
+}