summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2019-09-19 11:47:46 +0200
committerRichard Levitte <levitte@openssl.org>2019-09-20 08:28:47 +0200
commit4e8b8e47c85a45d1bda3241d7b2852d82db2a255 (patch)
tree6141920db7bb6b798bf44eb14dc343d9634bc8c9
parentca392b294359a8e9ca55e685b344b485d02bc93b (diff)
Refactor TLS-PRF's kdf_tls1_prf_mkmacctx() to a provider utility
ossl_prov_macctx_load_from_params() creates a EVP_MAC_CTX *, or sets new common parameters for an existing one. Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from https://github.com/openssl/openssl/pull/9946)
-rw-r--r--include/openssl/core_names.h5
-rw-r--r--providers/common/include/internal/provider_util.h24
-rw-r--r--providers/common/kdfs/tls1_prf.c62
-rw-r--r--providers/common/provider_util.c88
4 files changed, 127 insertions, 52 deletions
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
index e1bc43d8db..ad4cf50bb5 100644
--- a/include/openssl/core_names.h
+++ b/include/openssl/core_names.h
@@ -47,6 +47,7 @@ extern "C" {
*/
#define OSSL_ALG_PARAM_DIGEST "digest" /* utf8_string */
#define OSSL_ALG_PARAM_CIPHER "cipher" /* utf8_string */
+#define OSSL_ALG_PARAM_MAC "mac" /* utf8_string */
#define OSSL_ALG_PARAM_ENGINE "engine" /* utf8_string */
#define OSSL_ALG_PARAM_PROPERTIES "properties"/* utf8_string */
@@ -108,8 +109,8 @@ extern "C" {
#define OSSL_KDF_PARAM_KEY "key" /* octet string */
#define OSSL_KDF_PARAM_SALT "salt" /* octet string */
#define OSSL_KDF_PARAM_PASSWORD "pass" /* octet string */
-#define OSSL_KDF_PARAM_DIGEST OSSL_ALG_PARAM_DIGEST /* utf8 string */
-#define OSSL_KDF_PARAM_MAC "mac" /* utf8 string */
+#define OSSL_KDF_PARAM_DIGEST OSSL_ALG_PARAM_DIGEST /* utf8 string */
+#define OSSL_KDF_PARAM_MAC OSSL_ALG_PARAM_MAC /* utf8 string */
#define OSSL_KDF_PARAM_MAC_SIZE "maclen" /* size_t */
#define OSSL_KDF_PARAM_ENGINE OSSL_ALG_PARAM_ENGINE /* utf8 string */
#define OSSL_KDF_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES /* utf8 string */
diff --git a/providers/common/include/internal/provider_util.h b/providers/common/include/internal/provider_util.h
index 9fe21c5ef6..ad7e72293b 100644
--- a/providers/common/include/internal/provider_util.h
+++ b/providers/common/include/internal/provider_util.h
@@ -85,3 +85,27 @@ int ossl_prov_digest_copy(PROV_DIGEST *dst, const PROV_DIGEST *src);
const EVP_MD *ossl_prov_digest_md(const PROV_DIGEST *pd);
ENGINE *ossl_prov_digest_engine(const PROV_DIGEST *pd);
const char *ossl_prov_digest_name(const PROV_DIGEST *pd);
+
+/* MAC functions */
+/*
+ * Load an EVP_MAC_CTX* from the specified parameters with the specified
+ * library context.
+ * The params "mac" and "properties" are used to determine the implementation
+ * used, and the parameters "digest", "cipher", "engine" and "properties" are
+ * passed to the MAC via the created MAC context if they are given.
+ * If there is already a created MAC context, it will be replaced if the "mac"
+ * parameter is found, otherwise it will simply be used as is, and passed the
+ * parameters to pilfer as it sees fit.
+ *
+ * As an option, a MAC name may be explicitly given, and if it is, the "mac"
+ * parameter will be ignored.
+ * Similarly, as an option, a cipher name or a digest name may be explicitly
+ * given, and if any of them is, the "digest" and "cipher" parameters are
+ * ignored.
+ */
+int ossl_prov_macctx_load_from_params(EVP_MAC_CTX **macctx,
+ const OSSL_PARAM params[],
+ const char *macname,
+ const char *ciphername,
+ const char *mdname,
+ OPENSSL_CTX *ctx);
diff --git a/providers/common/kdfs/tls1_prf.c b/providers/common/kdfs/tls1_prf.c
index 0acdcdf3b8..3053b756dc 100644
--- a/providers/common/kdfs/tls1_prf.c
+++ b/providers/common/kdfs/tls1_prf.c
@@ -145,51 +145,6 @@ static int kdf_tls1_prf_derive(void *vctx, unsigned char *key,
key, keylen);
}
-static EVP_MAC_CTX *kdf_tls1_prf_mkmacctx(OPENSSL_CTX *libctx,
- const char *mdname,
- const OSSL_PARAM params[])
-{
- const OSSL_PARAM *p;
- OSSL_PARAM mac_params[5], *mp = mac_params;
- const char *properties = NULL;
- /* TODO(3.0) rethink "flags", also see hmac.c in providers */
- int mac_flags = EVP_MD_CTX_FLAG_NON_FIPS_ALLOW;
- EVP_MAC_CTX *macctx = NULL;
-
- *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
- (char *)mdname, 0);
-#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE)
- if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_ENGINE)) != NULL)
- *mp++ = *p;
-#endif
- if ((p = OSSL_PARAM_locate_const(params,
- OSSL_KDF_PARAM_PROPERTIES)) != NULL) {
- properties = p->data;
- *mp++ = *p;
- }
- *mp++ = OSSL_PARAM_construct_int(OSSL_MAC_PARAM_FLAGS, &mac_flags);
- *mp = OSSL_PARAM_construct_end();
-
- /* Implicit fetch */
- {
- EVP_MAC *mac = EVP_MAC_fetch(libctx, OSSL_MAC_NAME_HMAC, properties);
-
- macctx = EVP_MAC_CTX_new(mac);
- /* The context holds on to the MAC */
- EVP_MAC_free(mac);
- if (macctx == NULL)
- goto err;
- }
-
- if (EVP_MAC_CTX_set_params(macctx, mac_params))
- goto done;
- err:
- EVP_MAC_CTX_free(macctx);
- macctx = NULL;
- done:
- return macctx;
-}
-
static int kdf_tls1_prf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
{
const OSSL_PARAM *p;
@@ -197,13 +152,20 @@ static int kdf_tls1_prf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx);
if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_DIGEST)) != NULL) {
- EVP_MAC_CTX_free(ctx->P_hash);
- EVP_MAC_CTX_free(ctx->P_sha1);
if (strcasecmp(p->data, SN_md5_sha1) == 0) {
- ctx->P_hash = kdf_tls1_prf_mkmacctx(libctx, SN_md5, params);
- ctx->P_sha1 = kdf_tls1_prf_mkmacctx(libctx, SN_sha1, params);
+ if (!ossl_prov_macctx_load_from_params(&ctx->P_hash, params,
+ OSSL_MAC_NAME_HMAC,
+ NULL, SN_md5, libctx)
+ || !ossl_prov_macctx_load_from_params(&ctx->P_sha1, params,
+ OSSL_MAC_NAME_HMAC,
+ NULL, SN_sha1, libctx))
+ return 0;
} else {
- ctx->P_hash = kdf_tls1_prf_mkmacctx(libctx, p->data, params);
+ EVP_MAC_CTX_free(ctx->P_sha1);
+ if (!ossl_prov_macctx_load_from_params(&ctx->P_hash, params,
+ OSSL_MAC_NAME_HMAC,
+ NULL, NULL, libctx))
+ return 0;
}
}
diff --git a/providers/common/provider_util.c b/providers/common/provider_util.c
index 199544730a..4056878498 100644
--- a/providers/common/provider_util.c
+++ b/providers/common/provider_util.c
@@ -165,3 +165,91 @@ const char *ossl_prov_digest_name(const PROV_DIGEST *pd)
{
return pd->name;
}
+
+int ossl_prov_macctx_load_from_params(EVP_MAC_CTX **macctx,
+ const OSSL_PARAM params[],
+ const char *macname,
+ const char *ciphername,
+ const char *mdname,
+ OPENSSL_CTX *libctx)
+{
+ const OSSL_PARAM *p;
+ OSSL_PARAM mac_params[5], *mp = mac_params;
+ const char *properties = NULL;
+
+ if (macname == NULL
+ && (p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_MAC)) != NULL) {
+ if (p->data_type != OSSL_PARAM_UTF8_STRING)
+ return 0;
+ macname = p->data;
+ }
+ if ((p = OSSL_PARAM_locate_const(params,
+ OSSL_ALG_PARAM_PROPERTIES)) != NULL) {
+ if (p->data_type != OSSL_PARAM_UTF8_STRING)
+ return 0;
+ properties = p->data;
+ }
+
+ /* If we got a new mac name, we make a new EVP_MAC_CTX */
+ if (macname != NULL) {
+ EVP_MAC *mac = EVP_MAC_fetch(libctx, macname, properties);
+
+ EVP_MAC_CTX_free(*macctx);
+ *macctx = mac == NULL ? NULL : EVP_MAC_CTX_new(mac);
+ /* The context holds on to the MAC */
+ EVP_MAC_free(mac);
+ if (*macctx == NULL)
+ return 0;
+ }
+
+ /*
+ * If there is no MAC yet (and therefore, no MAC context), we ignore
+ * all other parameters.
+ */
+ if (*macctx == NULL)
+ return 1;
+
+ if (mdname == NULL) {
+ if ((p = OSSL_PARAM_locate_const(params,
+ OSSL_ALG_PARAM_DIGEST)) != NULL) {
+ if (p->data_type != OSSL_PARAM_UTF8_STRING)
+ return 0;
+ mdname = p->data;
+ }
+ }
+ if (ciphername == NULL) {
+ if ((p = OSSL_PARAM_locate_const(params,
+ OSSL_ALG_PARAM_CIPHER)) != NULL) {
+ if (p->data_type != OSSL_PARAM_UTF8_STRING)
+ return 0;
+ ciphername = p->data;
+ }
+ }
+
+ if (mdname != NULL)
+ *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
+ (char *)mdname, 0);
+ if (ciphername != NULL)
+ *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
+ (char *)ciphername, 0);
+ if (properties != NULL)
+ *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_PROPERTIES,
+ (char *)properties, 0);
+
+#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE)
+ if ((p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_ENGINE)) != NULL) {
+ if (p->data_type != OSSL_PARAM_UTF8_STRING)
+ return 0;
+ *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ENGINE,
+ p->data, p->data_size);
+ }
+#endif
+ *mp = OSSL_PARAM_construct_end();
+
+ if (EVP_MAC_CTX_set_params(*macctx, mac_params))
+ return 1;
+
+ EVP_MAC_CTX_free(*macctx);
+ *macctx = NULL;
+ return 0;
+}