*/
#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 */
#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 */
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);
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;
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;
}
}
{
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;
+}