mirror of
https://github.com/openssl/openssl.git
synced 2024-11-21 01:15:20 +08:00
Adapt diverse code to provider based MACs.
CRMF, SSKDF, TLS1_PRF and SIV are affected by this. This also forces the need to check MAC names, which leads to storing the names in the created methods, which affects all EVP APIs, not just EVP_MAC. We will want that kind of information anyway (for example for 'openssl list')... Consequently, EVP_MAC_name() is re-implemented. Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Shane Lontis <shane.lontis@oracle.com> (Merged from https://github.com/openssl/openssl/pull/8877)
This commit is contained in:
parent
d747fb2ec5
commit
776796e818
@ -12,6 +12,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
|
|
||||||
@ -22,6 +24,8 @@
|
|||||||
#include <openssl/crmf.h>
|
#include <openssl/crmf.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/params.h>
|
||||||
|
#include <openssl/core_names.h>
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* creates and initializes OSSL_CRMF_PBMPARAMETER (section 4.4)
|
* creates and initializes OSSL_CRMF_PBMPARAMETER (section 4.4)
|
||||||
@ -120,9 +124,10 @@ OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(size_t slen, int owfnid,
|
|||||||
int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
|
int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
|
||||||
const unsigned char *msg, size_t msglen,
|
const unsigned char *msg, size_t msglen,
|
||||||
const unsigned char *sec, size_t seclen,
|
const unsigned char *sec, size_t seclen,
|
||||||
unsigned char **mac, size_t *maclen)
|
unsigned char **out, size_t *outlen)
|
||||||
{
|
{
|
||||||
int mac_nid, hmac_md_nid = NID_undef;
|
int mac_nid, hmac_md_nid = NID_undef;
|
||||||
|
const char *mdname = NULL;
|
||||||
const EVP_MD *m = NULL;
|
const EVP_MD *m = NULL;
|
||||||
EVP_MD_CTX *ctx = NULL;
|
EVP_MD_CTX *ctx = NULL;
|
||||||
unsigned char basekey[EVP_MAX_MD_SIZE];
|
unsigned char basekey[EVP_MAX_MD_SIZE];
|
||||||
@ -130,9 +135,12 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
|
|||||||
int64_t iterations;
|
int64_t iterations;
|
||||||
unsigned char *mac_res = 0;
|
unsigned char *mac_res = 0;
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
|
EVP_MAC *mac = NULL;
|
||||||
EVP_MAC_CTX *mctx = NULL;
|
EVP_MAC_CTX *mctx = NULL;
|
||||||
|
OSSL_PARAM macparams[3] =
|
||||||
|
{ OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END };
|
||||||
|
|
||||||
if (mac == NULL || pbmp == NULL || pbmp->mac == NULL
|
if (out == NULL || pbmp == NULL || pbmp->mac == NULL
|
||||||
|| pbmp->mac->algorithm == NULL || msg == NULL || sec == NULL) {
|
|| pbmp->mac->algorithm == NULL || msg == NULL || sec == NULL) {
|
||||||
CRMFerr(CRMF_F_OSSL_CRMF_PBM_NEW, CRMF_R_NULL_ARGUMENT);
|
CRMFerr(CRMF_F_OSSL_CRMF_PBM_NEW, CRMF_R_NULL_ARGUMENT);
|
||||||
goto err;
|
goto err;
|
||||||
@ -193,17 +201,22 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
|
|||||||
mac_nid = OBJ_obj2nid(pbmp->mac->algorithm);
|
mac_nid = OBJ_obj2nid(pbmp->mac->algorithm);
|
||||||
|
|
||||||
if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, mac_nid, NULL, &hmac_md_nid, NULL)
|
if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, mac_nid, NULL, &hmac_md_nid, NULL)
|
||||||
|| ((m = EVP_get_digestbynid(hmac_md_nid)) == NULL)) {
|
|| ((mdname = OBJ_nid2sn(hmac_md_nid)) == NULL)) {
|
||||||
CRMFerr(CRMF_F_OSSL_CRMF_PBM_NEW, CRMF_R_UNSUPPORTED_ALGORITHM);
|
CRMFerr(CRMF_F_OSSL_CRMF_PBM_NEW, CRMF_R_UNSUPPORTED_ALGORITHM);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mctx = EVP_MAC_CTX_new(EVP_get_macbyname("HMAC"))) == NULL
|
macparams[0] =
|
||||||
|| EVP_MAC_ctrl(mctx, EVP_MAC_CTRL_SET_MD, m) <= 0
|
OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ALGORITHM,
|
||||||
|| EVP_MAC_ctrl(mctx, EVP_MAC_CTRL_SET_KEY, basekey, bklen) <= 0
|
(char *)mdname, strlen(mdname) + 1);
|
||||||
|
macparams[1] =
|
||||||
|
OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, basekey, bklen);
|
||||||
|
if ((mac = EVP_MAC_fetch(NULL, "HMAC", NULL)) == NULL
|
||||||
|
|| (mctx = EVP_MAC_CTX_new(mac)) == NULL
|
||||||
|
|| !EVP_MAC_CTX_set_params(mctx, macparams)
|
||||||
|| !EVP_MAC_init(mctx)
|
|| !EVP_MAC_init(mctx)
|
||||||
|| !EVP_MAC_update(mctx, msg, msglen)
|
|| !EVP_MAC_update(mctx, msg, msglen)
|
||||||
|| !EVP_MAC_final(mctx, mac_res, maclen))
|
|| !EVP_MAC_final(mctx, mac_res, outlen, EVP_MAX_MD_SIZE))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
ok = 1;
|
ok = 1;
|
||||||
@ -212,10 +225,11 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
|
|||||||
/* cleanup */
|
/* cleanup */
|
||||||
OPENSSL_cleanse(basekey, bklen);
|
OPENSSL_cleanse(basekey, bklen);
|
||||||
EVP_MAC_CTX_free(mctx);
|
EVP_MAC_CTX_free(mctx);
|
||||||
|
EVP_MAC_free(mac);
|
||||||
EVP_MD_CTX_free(ctx);
|
EVP_MD_CTX_free(ctx);
|
||||||
|
|
||||||
if (ok == 1) {
|
if (ok == 1) {
|
||||||
*mac = mac_res;
|
*out = mac_res;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,6 +211,7 @@ struct siv128_context {
|
|||||||
SIV_BLOCK d;
|
SIV_BLOCK d;
|
||||||
SIV_BLOCK tag;
|
SIV_BLOCK tag;
|
||||||
EVP_CIPHER_CTX *cipher_ctx;
|
EVP_CIPHER_CTX *cipher_ctx;
|
||||||
|
EVP_MAC *mac;
|
||||||
EVP_MAC_CTX *mac_ctx_init;
|
EVP_MAC_CTX *mac_ctx_init;
|
||||||
int final_ret;
|
int final_ret;
|
||||||
int crypto_ok;
|
int crypto_ok;
|
||||||
|
@ -40,12 +40,14 @@
|
|||||||
#include <openssl/hmac.h>
|
#include <openssl/hmac.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/kdf.h>
|
#include <openssl/kdf.h>
|
||||||
|
#include <openssl/core_names.h>
|
||||||
|
#include <openssl/params.h>
|
||||||
#include "internal/cryptlib.h"
|
#include "internal/cryptlib.h"
|
||||||
#include "internal/evp_int.h"
|
#include "internal/evp_int.h"
|
||||||
#include "kdf_local.h"
|
#include "kdf_local.h"
|
||||||
|
|
||||||
struct evp_kdf_impl_st {
|
struct evp_kdf_impl_st {
|
||||||
const EVP_MAC *mac; /* H(x) = HMAC_hash OR H(x) = KMAC */
|
EVP_MAC *mac; /* H(x) = HMAC_hash OR H(x) = KMAC */
|
||||||
const EVP_MD *md; /* H(x) = hash OR when H(x) = HMAC_hash */
|
const EVP_MD *md; /* H(x) = hash OR when H(x) = HMAC_hash */
|
||||||
unsigned char *secret;
|
unsigned char *secret;
|
||||||
size_t secret_len;
|
size_t secret_len;
|
||||||
@ -141,11 +143,17 @@ static int kmac_init(EVP_MAC_CTX *ctx, const unsigned char *custom,
|
|||||||
size_t custom_len, size_t kmac_out_len,
|
size_t custom_len, size_t kmac_out_len,
|
||||||
size_t derived_key_len, unsigned char **out)
|
size_t derived_key_len, unsigned char **out)
|
||||||
{
|
{
|
||||||
|
OSSL_PARAM params[2];
|
||||||
|
|
||||||
/* Only KMAC has custom data - so return if not KMAC */
|
/* Only KMAC has custom data - so return if not KMAC */
|
||||||
if (custom == NULL)
|
if (custom == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (EVP_MAC_ctrl(ctx, EVP_MAC_CTRL_SET_CUSTOM, custom, custom_len) <= 0)
|
params[0] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_CUSTOM,
|
||||||
|
(void *)custom, custom_len);
|
||||||
|
params[1] = OSSL_PARAM_construct_end();
|
||||||
|
|
||||||
|
if (!EVP_MAC_CTX_set_params(ctx, params))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* By default only do one iteration if kmac_out_len is not specified */
|
/* By default only do one iteration if kmac_out_len is not specified */
|
||||||
@ -160,7 +168,10 @@ static int kmac_init(EVP_MAC_CTX *ctx, const unsigned char *custom,
|
|||||||
|| kmac_out_len == 64))
|
|| kmac_out_len == 64))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (EVP_MAC_ctrl(ctx, EVP_MAC_CTRL_SET_SIZE, kmac_out_len) <= 0)
|
params[0] = OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_OUTLEN,
|
||||||
|
&kmac_out_len);
|
||||||
|
|
||||||
|
if (EVP_MAC_CTX_set_params(ctx, params) <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -181,7 +192,7 @@ static int kmac_init(EVP_MAC_CTX *ctx, const unsigned char *custom,
|
|||||||
* H(x) = HMAC-hash(salt, x) OR
|
* H(x) = HMAC-hash(salt, x) OR
|
||||||
* H(x) = KMAC#(salt, x, outbits, CustomString='KDF')
|
* H(x) = KMAC#(salt, x, outbits, CustomString='KDF')
|
||||||
*/
|
*/
|
||||||
static int SSKDF_mac_kdm(const EVP_MAC *kdf_mac, const EVP_MD *hmac_md,
|
static int SSKDF_mac_kdm(EVP_MAC *kdf_mac, const EVP_MD *hmac_md,
|
||||||
const unsigned char *kmac_custom,
|
const unsigned char *kmac_custom,
|
||||||
size_t kmac_custom_len, size_t kmac_out_len,
|
size_t kmac_custom_len, size_t kmac_out_len,
|
||||||
const unsigned char *salt, size_t salt_len,
|
const unsigned char *salt, size_t salt_len,
|
||||||
@ -196,6 +207,8 @@ static int SSKDF_mac_kdm(const EVP_MAC *kdf_mac, const EVP_MD *hmac_md,
|
|||||||
unsigned char *out = derived_key;
|
unsigned char *out = derived_key;
|
||||||
EVP_MAC_CTX *ctx = NULL, *ctx_init = NULL;
|
EVP_MAC_CTX *ctx = NULL, *ctx_init = NULL;
|
||||||
unsigned char *mac = mac_buf, *kmac_buffer = NULL;
|
unsigned char *mac = mac_buf, *kmac_buffer = NULL;
|
||||||
|
OSSL_PARAM params[3];
|
||||||
|
size_t params_n = 0;
|
||||||
|
|
||||||
if (z_len > SSKDF_MAX_INLEN || info_len > SSKDF_MAX_INLEN
|
if (z_len > SSKDF_MAX_INLEN || info_len > SSKDF_MAX_INLEN
|
||||||
|| derived_key_len > SSKDF_MAX_INLEN
|
|| derived_key_len > SSKDF_MAX_INLEN
|
||||||
@ -205,11 +218,20 @@ static int SSKDF_mac_kdm(const EVP_MAC *kdf_mac, const EVP_MD *hmac_md,
|
|||||||
ctx_init = EVP_MAC_CTX_new(kdf_mac);
|
ctx_init = EVP_MAC_CTX_new(kdf_mac);
|
||||||
if (ctx_init == NULL)
|
if (ctx_init == NULL)
|
||||||
goto end;
|
goto end;
|
||||||
if (hmac_md != NULL &&
|
|
||||||
EVP_MAC_ctrl(ctx_init, EVP_MAC_CTRL_SET_MD, hmac_md) <= 0)
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
if (EVP_MAC_ctrl(ctx_init, EVP_MAC_CTRL_SET_KEY, salt, salt_len) <= 0)
|
if (hmac_md != NULL) {
|
||||||
|
const char *mdname = EVP_MD_name(hmac_md);
|
||||||
|
params[params_n++] =
|
||||||
|
OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ALGORITHM,
|
||||||
|
(char *)mdname,
|
||||||
|
strlen(mdname) + 1);
|
||||||
|
}
|
||||||
|
params[params_n++] =
|
||||||
|
OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, (void *)salt,
|
||||||
|
salt_len);
|
||||||
|
params[params_n] = OSSL_PARAM_construct_end();
|
||||||
|
|
||||||
|
if (!EVP_MAC_CTX_set_params(ctx_init, params))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
if (!kmac_init(ctx_init, kmac_custom, kmac_custom_len, kmac_out_len,
|
if (!kmac_init(ctx_init, kmac_custom, kmac_custom_len, kmac_out_len,
|
||||||
@ -239,14 +261,14 @@ static int SSKDF_mac_kdm(const EVP_MAC *kdf_mac, const EVP_MD *hmac_md,
|
|||||||
&& EVP_MAC_update(ctx, info, info_len)))
|
&& EVP_MAC_update(ctx, info, info_len)))
|
||||||
goto end;
|
goto end;
|
||||||
if (len >= out_len) {
|
if (len >= out_len) {
|
||||||
if (!EVP_MAC_final(ctx, out, NULL))
|
if (!EVP_MAC_final(ctx, out, NULL, len))
|
||||||
goto end;
|
goto end;
|
||||||
out += out_len;
|
out += out_len;
|
||||||
len -= out_len;
|
len -= out_len;
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
if (!EVP_MAC_final(ctx, mac, NULL))
|
if (!EVP_MAC_final(ctx, mac, NULL, len))
|
||||||
goto end;
|
goto end;
|
||||||
memcpy(out, mac, len);
|
memcpy(out, mac, len);
|
||||||
break;
|
break;
|
||||||
@ -280,6 +302,10 @@ static void sskdf_reset(EVP_KDF_IMPL *impl)
|
|||||||
OPENSSL_clear_free(impl->secret, impl->secret_len);
|
OPENSSL_clear_free(impl->secret, impl->secret_len);
|
||||||
OPENSSL_clear_free(impl->info, impl->info_len);
|
OPENSSL_clear_free(impl->info, impl->info_len);
|
||||||
OPENSSL_clear_free(impl->salt, impl->salt_len);
|
OPENSSL_clear_free(impl->salt, impl->salt_len);
|
||||||
|
EVP_MAC_free(impl->mac);
|
||||||
|
#if 0 /* TODO(3.0) When we switch to fetched MDs */
|
||||||
|
EVP_MD_meth_free(impl->md);
|
||||||
|
#endif
|
||||||
memset(impl, 0, sizeof(*impl));
|
memset(impl, 0, sizeof(*impl));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,7 +337,6 @@ static int sskdf_set_buffer(va_list args, unsigned char **out, size_t *out_len)
|
|||||||
static int sskdf_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args)
|
static int sskdf_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args)
|
||||||
{
|
{
|
||||||
const EVP_MD *md;
|
const EVP_MD *md;
|
||||||
const EVP_MAC *mac;
|
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case EVP_KDF_CTRL_SET_KEY:
|
case EVP_KDF_CTRL_SET_KEY:
|
||||||
@ -325,17 +350,34 @@ static int sskdf_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args)
|
|||||||
if (md == NULL)
|
if (md == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
#if 0 /* TODO(3.0) When we switch to fetched MDs */
|
||||||
|
EVP_MD_meth_free(impl->md);
|
||||||
|
#endif
|
||||||
impl->md = md;
|
impl->md = md;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case EVP_KDF_CTRL_SET_MAC:
|
case EVP_KDF_CTRL_SET_MAC:
|
||||||
mac = va_arg(args, const EVP_MAC *);
|
{
|
||||||
if (mac == NULL)
|
const char *name;
|
||||||
return 0;
|
EVP_MAC *mac;
|
||||||
|
|
||||||
impl->mac = mac;
|
name = va_arg(args, const char *);
|
||||||
return 1;
|
if (name == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
EVP_MAC_free(impl->mac);
|
||||||
|
impl->mac = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO(3.0) add support for OPENSSL_CTX and properties in KDFs
|
||||||
|
*/
|
||||||
|
mac = EVP_MAC_fetch(NULL, name, NULL);
|
||||||
|
if (mac == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
impl->mac = mac;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
case EVP_KDF_CTRL_SET_SALT:
|
case EVP_KDF_CTRL_SET_SALT:
|
||||||
return sskdf_set_buffer(args, &impl->salt, &impl->salt_len);
|
return sskdf_set_buffer(args, &impl->salt, &impl->salt_len);
|
||||||
|
|
||||||
@ -348,20 +390,6 @@ static int sskdf_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pass a mac to a ctrl */
|
|
||||||
static int sskdf_mac2ctrl(EVP_KDF_IMPL *impl,
|
|
||||||
int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args),
|
|
||||||
int cmd, const char *mac_name)
|
|
||||||
{
|
|
||||||
const EVP_MAC *mac;
|
|
||||||
|
|
||||||
if (mac_name == NULL || (mac = EVP_get_macbyname(mac_name)) == NULL) {
|
|
||||||
KDFerr(KDF_F_SSKDF_MAC2CTRL, KDF_R_INVALID_MAC_TYPE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return call_ctrl(ctrl, impl, cmd, mac);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sskdf_ctrl_str(EVP_KDF_IMPL *impl, const char *type,
|
static int sskdf_ctrl_str(EVP_KDF_IMPL *impl, const char *type,
|
||||||
const char *value)
|
const char *value)
|
||||||
{
|
{
|
||||||
@ -385,7 +413,7 @@ static int sskdf_ctrl_str(EVP_KDF_IMPL *impl, const char *type,
|
|||||||
return kdf_md2ctrl(impl, sskdf_ctrl, EVP_KDF_CTRL_SET_MD, value);
|
return kdf_md2ctrl(impl, sskdf_ctrl, EVP_KDF_CTRL_SET_MD, value);
|
||||||
|
|
||||||
if (strcmp(type, "mac") == 0)
|
if (strcmp(type, "mac") == 0)
|
||||||
return sskdf_mac2ctrl(impl, sskdf_ctrl, EVP_KDF_CTRL_SET_MAC, value);
|
return kdf_str2ctrl(impl, sskdf_ctrl, EVP_KDF_CTRL_SET_MAC, value);
|
||||||
|
|
||||||
if (strcmp(type, "salt") == 0)
|
if (strcmp(type, "salt") == 0)
|
||||||
return kdf_str2ctrl(impl, sskdf_ctrl, EVP_KDF_CTRL_SET_SALT, value);
|
return kdf_str2ctrl(impl, sskdf_ctrl, EVP_KDF_CTRL_SET_SALT, value);
|
||||||
@ -430,11 +458,16 @@ static int sskdf_derive(EVP_KDF_IMPL *impl, unsigned char *key, size_t keylen)
|
|||||||
int ret;
|
int ret;
|
||||||
const unsigned char *custom = NULL;
|
const unsigned char *custom = NULL;
|
||||||
size_t custom_len = 0;
|
size_t custom_len = 0;
|
||||||
int nid;
|
const char *macname;
|
||||||
int default_salt_len;
|
int default_salt_len;
|
||||||
|
|
||||||
nid = EVP_MAC_nid(impl->mac);
|
/*
|
||||||
if (nid == EVP_MAC_HMAC) {
|
* TODO(3.0) investigate the necessity to have all these controls.
|
||||||
|
* Why does KMAC require a salt length that's shorter than the MD
|
||||||
|
* block size?
|
||||||
|
*/
|
||||||
|
macname = EVP_MAC_name(impl->mac);
|
||||||
|
if (strcmp(macname, "HMAC") == 0) {
|
||||||
/* H(x) = HMAC(x, salt, hash) */
|
/* H(x) = HMAC(x, salt, hash) */
|
||||||
if (impl->md == NULL) {
|
if (impl->md == NULL) {
|
||||||
KDFerr(KDF_F_SSKDF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST);
|
KDFerr(KDF_F_SSKDF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST);
|
||||||
@ -443,11 +476,12 @@ static int sskdf_derive(EVP_KDF_IMPL *impl, unsigned char *key, size_t keylen)
|
|||||||
default_salt_len = EVP_MD_block_size(impl->md);
|
default_salt_len = EVP_MD_block_size(impl->md);
|
||||||
if (default_salt_len <= 0)
|
if (default_salt_len <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
} else if (nid == EVP_MAC_KMAC128 || nid == EVP_MAC_KMAC256) {
|
} else if (strcmp(macname, "KMAC128") == 0
|
||||||
|
|| strcmp(macname, "KMAC256") == 0) {
|
||||||
/* H(x) = KMACzzz(x, salt, custom) */
|
/* H(x) = KMACzzz(x, salt, custom) */
|
||||||
custom = kmac_custom_str;
|
custom = kmac_custom_str;
|
||||||
custom_len = sizeof(kmac_custom_str);
|
custom_len = sizeof(kmac_custom_str);
|
||||||
if (nid == EVP_MAC_KMAC128)
|
if (strcmp(macname, "KMAC128") == 0)
|
||||||
default_salt_len = SSKDF_KMAC128_DEFAULT_SALT_SIZE;
|
default_salt_len = SSKDF_KMAC128_DEFAULT_SALT_SIZE;
|
||||||
else
|
else
|
||||||
default_salt_len = SSKDF_KMAC256_DEFAULT_SALT_SIZE;
|
default_salt_len = SSKDF_KMAC256_DEFAULT_SALT_SIZE;
|
||||||
|
@ -51,6 +51,8 @@
|
|||||||
#include "internal/cryptlib.h"
|
#include "internal/cryptlib.h"
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/kdf.h>
|
#include <openssl/kdf.h>
|
||||||
|
#include <openssl/core_names.h>
|
||||||
|
#include <openssl/params.h>
|
||||||
#include "internal/evp_int.h"
|
#include "internal/evp_int.h"
|
||||||
#include "kdf_local.h"
|
#include "kdf_local.h"
|
||||||
|
|
||||||
@ -232,19 +234,30 @@ static int tls1_prf_P_hash(const EVP_MD *md,
|
|||||||
unsigned char *out, size_t olen)
|
unsigned char *out, size_t olen)
|
||||||
{
|
{
|
||||||
size_t chunk;
|
size_t chunk;
|
||||||
|
EVP_MAC *mac = NULL;
|
||||||
EVP_MAC_CTX *ctx = NULL, *ctx_Ai = NULL, *ctx_init = NULL;
|
EVP_MAC_CTX *ctx = NULL, *ctx_Ai = NULL, *ctx_init = NULL;
|
||||||
unsigned char Ai[EVP_MAX_MD_SIZE];
|
unsigned char Ai[EVP_MAX_MD_SIZE];
|
||||||
size_t Ai_len;
|
size_t Ai_len;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
OSSL_PARAM params[4];
|
||||||
|
int mac_flags;
|
||||||
|
const char *mdname = EVP_MD_name(md);
|
||||||
|
|
||||||
ctx_init = EVP_MAC_CTX_new_id(EVP_MAC_HMAC);
|
mac = EVP_MAC_fetch(NULL, "HMAC", NULL); /* Implicit fetch */
|
||||||
|
ctx_init = EVP_MAC_CTX_new(mac);
|
||||||
if (ctx_init == NULL)
|
if (ctx_init == NULL)
|
||||||
goto err;
|
goto err;
|
||||||
if (EVP_MAC_ctrl(ctx_init, EVP_MAC_CTRL_SET_FLAGS, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW) != 1)
|
|
||||||
goto err;
|
/* TODO(3.0) rethink "flags", also see hmac.c in providers */
|
||||||
if (EVP_MAC_ctrl(ctx_init, EVP_MAC_CTRL_SET_MD, md) != 1)
|
mac_flags = EVP_MD_CTX_FLAG_NON_FIPS_ALLOW;
|
||||||
goto err;
|
params[0] = OSSL_PARAM_construct_int(OSSL_MAC_PARAM_FLAGS, &mac_flags);
|
||||||
if (EVP_MAC_ctrl(ctx_init, EVP_MAC_CTRL_SET_KEY, sec, sec_len) != 1)
|
params[1] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ALGORITHM,
|
||||||
|
(char *)mdname,
|
||||||
|
strlen(mdname) + 1);
|
||||||
|
params[2] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
|
||||||
|
(void *)sec, sec_len);
|
||||||
|
params[3] = OSSL_PARAM_construct_end();
|
||||||
|
if (!EVP_MAC_CTX_set_params(ctx_init, params))
|
||||||
goto err;
|
goto err;
|
||||||
if (!EVP_MAC_init(ctx_init))
|
if (!EVP_MAC_init(ctx_init))
|
||||||
goto err;
|
goto err;
|
||||||
@ -260,7 +273,7 @@ static int tls1_prf_P_hash(const EVP_MD *md,
|
|||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* calc: A(i) = HMAC_<hash>(secret, A(i-1)) */
|
/* calc: A(i) = HMAC_<hash>(secret, A(i-1)) */
|
||||||
if (!EVP_MAC_final(ctx_Ai, Ai, &Ai_len))
|
if (!EVP_MAC_final(ctx_Ai, Ai, &Ai_len, sizeof(Ai)))
|
||||||
goto err;
|
goto err;
|
||||||
EVP_MAC_CTX_free(ctx_Ai);
|
EVP_MAC_CTX_free(ctx_Ai);
|
||||||
ctx_Ai = NULL;
|
ctx_Ai = NULL;
|
||||||
@ -281,12 +294,12 @@ static int tls1_prf_P_hash(const EVP_MD *md,
|
|||||||
goto err;
|
goto err;
|
||||||
if (olen <= chunk) {
|
if (olen <= chunk) {
|
||||||
/* last chunk - use Ai as temp bounce buffer */
|
/* last chunk - use Ai as temp bounce buffer */
|
||||||
if (!EVP_MAC_final(ctx, Ai, &Ai_len))
|
if (!EVP_MAC_final(ctx, Ai, &Ai_len, sizeof(Ai)))
|
||||||
goto err;
|
goto err;
|
||||||
memcpy(out, Ai, olen);
|
memcpy(out, Ai, olen);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!EVP_MAC_final(ctx, out, NULL))
|
if (!EVP_MAC_final(ctx, out, NULL, olen))
|
||||||
goto err;
|
goto err;
|
||||||
EVP_MAC_CTX_free(ctx);
|
EVP_MAC_CTX_free(ctx);
|
||||||
ctx = NULL;
|
ctx = NULL;
|
||||||
@ -298,6 +311,7 @@ static int tls1_prf_P_hash(const EVP_MD *md,
|
|||||||
EVP_MAC_CTX_free(ctx);
|
EVP_MAC_CTX_free(ctx);
|
||||||
EVP_MAC_CTX_free(ctx_Ai);
|
EVP_MAC_CTX_free(ctx_Ai);
|
||||||
EVP_MAC_CTX_free(ctx_init);
|
EVP_MAC_CTX_free(ctx_init);
|
||||||
|
EVP_MAC_free(mac);
|
||||||
OPENSSL_cleanse(Ai, sizeof(Ai));
|
OPENSSL_cleanse(Ai, sizeof(Ai));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <openssl/crypto.h>
|
#include <openssl/crypto.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/core_names.h>
|
||||||
|
#include <openssl/params.h>
|
||||||
#include "internal/modes_int.h"
|
#include "internal/modes_int.h"
|
||||||
#include "internal/siv_int.h"
|
#include "internal/siv_int.h"
|
||||||
|
|
||||||
@ -117,7 +119,7 @@ __owur static ossl_inline int siv128_do_s2v_p(SIV128_CONTEXT *ctx, SIV_BLOCK *ou
|
|||||||
if (!EVP_MAC_update(mac_ctx, t.byte, SIV_LEN))
|
if (!EVP_MAC_update(mac_ctx, t.byte, SIV_LEN))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (!EVP_MAC_final(mac_ctx, out->byte, &out_len)
|
if (!EVP_MAC_final(mac_ctx, out->byte, &out_len, sizeof(out->byte))
|
||||||
|| out_len != SIV_LEN)
|
|| out_len != SIV_LEN)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
@ -167,6 +169,15 @@ int CRYPTO_siv128_init(SIV128_CONTEXT *ctx, const unsigned char *key, int klen,
|
|||||||
static const unsigned char zero[SIV_LEN] = { 0 };
|
static const unsigned char zero[SIV_LEN] = { 0 };
|
||||||
size_t out_len = SIV_LEN;
|
size_t out_len = SIV_LEN;
|
||||||
EVP_MAC_CTX *mac_ctx = NULL;
|
EVP_MAC_CTX *mac_ctx = NULL;
|
||||||
|
OSSL_PARAM params[3];
|
||||||
|
const char *cbc_name = EVP_CIPHER_name(cbc);
|
||||||
|
|
||||||
|
params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ALGORITHM,
|
||||||
|
(char *)cbc_name,
|
||||||
|
strlen(cbc_name) + 1);
|
||||||
|
params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
|
||||||
|
(void *)key, klen);
|
||||||
|
params[2] = OSSL_PARAM_construct_end();
|
||||||
|
|
||||||
memset(&ctx->d, 0, sizeof(ctx->d));
|
memset(&ctx->d, 0, sizeof(ctx->d));
|
||||||
ctx->cipher_ctx = NULL;
|
ctx->cipher_ctx = NULL;
|
||||||
@ -174,16 +185,19 @@ int CRYPTO_siv128_init(SIV128_CONTEXT *ctx, const unsigned char *key, int klen,
|
|||||||
|
|
||||||
if (key == NULL || cbc == NULL || ctr == NULL
|
if (key == NULL || cbc == NULL || ctr == NULL
|
||||||
|| (ctx->cipher_ctx = EVP_CIPHER_CTX_new()) == NULL
|
|| (ctx->cipher_ctx = EVP_CIPHER_CTX_new()) == NULL
|
||||||
|| (ctx->mac_ctx_init = EVP_MAC_CTX_new_id(EVP_MAC_CMAC)) == NULL
|
/* TODO(3.0) library context */
|
||||||
|| EVP_MAC_ctrl(ctx->mac_ctx_init, EVP_MAC_CTRL_SET_CIPHER, cbc) <= 0
|
|| (ctx->mac = EVP_MAC_fetch(NULL, "CMAC", NULL)) == NULL
|
||||||
|| EVP_MAC_ctrl(ctx->mac_ctx_init, EVP_MAC_CTRL_SET_KEY, key, klen) <= 0
|
|| (ctx->mac_ctx_init = EVP_MAC_CTX_new(ctx->mac)) == NULL
|
||||||
|
|| !EVP_MAC_CTX_set_params(ctx->mac_ctx_init, params)
|
||||||
|| !EVP_EncryptInit_ex(ctx->cipher_ctx, ctr, NULL, key + klen, NULL)
|
|| !EVP_EncryptInit_ex(ctx->cipher_ctx, ctr, NULL, key + klen, NULL)
|
||||||
|| (mac_ctx = EVP_MAC_CTX_dup(ctx->mac_ctx_init)) == NULL
|
|| (mac_ctx = EVP_MAC_CTX_dup(ctx->mac_ctx_init)) == NULL
|
||||||
|| !EVP_MAC_update(mac_ctx, zero, sizeof(zero))
|
|| !EVP_MAC_update(mac_ctx, zero, sizeof(zero))
|
||||||
|| !EVP_MAC_final(mac_ctx, ctx->d.byte, &out_len)) {
|
|| !EVP_MAC_final(mac_ctx, ctx->d.byte, &out_len,
|
||||||
|
sizeof(ctx->d.byte))) {
|
||||||
EVP_CIPHER_CTX_free(ctx->cipher_ctx);
|
EVP_CIPHER_CTX_free(ctx->cipher_ctx);
|
||||||
EVP_MAC_CTX_free(ctx->mac_ctx_init);
|
EVP_MAC_CTX_free(ctx->mac_ctx_init);
|
||||||
EVP_MAC_CTX_free(mac_ctx);
|
EVP_MAC_CTX_free(mac_ctx);
|
||||||
|
EVP_MAC_free(ctx->mac);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EVP_MAC_CTX_free(mac_ctx);
|
EVP_MAC_CTX_free(mac_ctx);
|
||||||
@ -223,10 +237,10 @@ int CRYPTO_siv128_aad(SIV128_CONTEXT *ctx, const unsigned char *aad,
|
|||||||
|
|
||||||
siv128_dbl(&ctx->d);
|
siv128_dbl(&ctx->d);
|
||||||
|
|
||||||
mac_ctx = EVP_MAC_CTX_dup(ctx->mac_ctx_init);
|
if ((mac_ctx = EVP_MAC_CTX_dup(ctx->mac_ctx_init)) == NULL
|
||||||
if (mac_ctx == NULL
|
|
||||||
|| !EVP_MAC_update(mac_ctx, aad, len)
|
|| !EVP_MAC_update(mac_ctx, aad, len)
|
||||||
|| !EVP_MAC_final(mac_ctx, mac_out.byte, &out_len)
|
|| !EVP_MAC_final(mac_ctx, mac_out.byte, &out_len,
|
||||||
|
sizeof(mac_out.byte))
|
||||||
|| out_len != SIV_LEN) {
|
|| out_len != SIV_LEN) {
|
||||||
EVP_MAC_CTX_free(mac_ctx);
|
EVP_MAC_CTX_free(mac_ctx);
|
||||||
return 0;
|
return 0;
|
||||||
@ -345,6 +359,8 @@ int CRYPTO_siv128_cleanup(SIV128_CONTEXT *ctx)
|
|||||||
ctx->cipher_ctx = NULL;
|
ctx->cipher_ctx = NULL;
|
||||||
EVP_MAC_CTX_free(ctx->mac_ctx_init);
|
EVP_MAC_CTX_free(ctx->mac_ctx_init);
|
||||||
ctx->mac_ctx_init = NULL;
|
ctx->mac_ctx_init = NULL;
|
||||||
|
EVP_MAC_free(ctx->mac);
|
||||||
|
ctx->mac = NULL;
|
||||||
OPENSSL_cleanse(&ctx->d, sizeof(ctx->d));
|
OPENSSL_cleanse(&ctx->d, sizeof(ctx->d));
|
||||||
OPENSSL_cleanse(&ctx->tag, sizeof(ctx->tag));
|
OPENSSL_cleanse(&ctx->tag, sizeof(ctx->tag));
|
||||||
ctx->final_ret = -1;
|
ctx->final_ret = -1;
|
||||||
|
Loading…
Reference in New Issue
Block a user