From 581451ffca74d4080e6480118a2752b6841ff73e Mon Sep 17 00:00:00 2001 From: tb Date: Mon, 29 Mar 2021 15:57:23 +0000 Subject: Prepare to provide EVP_PKEY_new_CMAC_key() sebastia ran into this when attempting to update security/hcxtools. This will be tested via wycheproof.go once the symbol is public. ok jsing, tested by sebastia --- lib/libcrypto/evp/evp.h | 9 +++++++- lib/libcrypto/evp/evp_err.c | 3 ++- lib/libcrypto/evp/m_sigver.c | 41 ++++++++++++++++++++++++++--------- lib/libcrypto/evp/p_lib.c | 51 +++++++++++++++++++++++++++++++++++++------- 4 files changed, 84 insertions(+), 20 deletions(-) (limited to 'lib') diff --git a/lib/libcrypto/evp/evp.h b/lib/libcrypto/evp/evp.h index f1fe8a1e34b..ca51429fa0c 100644 --- a/lib/libcrypto/evp/evp.h +++ b/lib/libcrypto/evp/evp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: evp.h,v 1.79 2020/04/27 19:31:02 tb Exp $ */ +/* $OpenBSD: evp.h,v 1.80 2021/03/29 15:57:23 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1149,6 +1149,10 @@ void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen); EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, const unsigned char *key, int keylen); +#if defined(LIBRESSL_INTERNAL) +EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, + size_t len, const EVP_CIPHER *cipher); +#endif void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data); void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx); @@ -1512,6 +1516,9 @@ void ERR_load_EVP_strings(void); #define EVP_R_INVALID_OPERATION 148 #define EVP_R_IV_TOO_LARGE 102 #define EVP_R_KEYGEN_FAILURE 120 +#if defined(LIBRESSL_INTERNAL) +#define EVP_R_KEY_SETUP_FAILED 180 +#endif #define EVP_R_MESSAGE_DIGEST_IS_NULL 159 #define EVP_R_METHOD_NOT_SUPPORTED 144 #define EVP_R_MISSING_PARAMETERS 103 diff --git a/lib/libcrypto/evp/evp_err.c b/lib/libcrypto/evp/evp_err.c index 2494cf57905..07ece82c3ad 100644 --- a/lib/libcrypto/evp/evp_err.c +++ b/lib/libcrypto/evp/evp_err.c @@ -1,4 +1,4 @@ -/* $OpenBSD: evp_err.c,v 1.26 2020/04/27 19:31:02 tb Exp $ */ +/* $OpenBSD: evp_err.c,v 1.27 2021/03/29 15:57:23 tb Exp $ */ /* ==================================================================== * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. * @@ -116,6 +116,7 @@ static ERR_STRING_DATA EVP_str_reasons[] = { {ERR_REASON(EVP_R_INVALID_OPERATION) , "invalid operation"}, {ERR_REASON(EVP_R_IV_TOO_LARGE) , "iv too large"}, {ERR_REASON(EVP_R_KEYGEN_FAILURE) , "keygen failure"}, + {ERR_REASON(EVP_R_KEY_SETUP_FAILED) , "key setup failed"}, {ERR_REASON(EVP_R_MESSAGE_DIGEST_IS_NULL), "message digest is null"}, {ERR_REASON(EVP_R_METHOD_NOT_SUPPORTED) , "method not supported"}, {ERR_REASON(EVP_R_MISSING_PARAMETERS) , "missing parameters"}, diff --git a/lib/libcrypto/evp/m_sigver.c b/lib/libcrypto/evp/m_sigver.c index 9e313c36308..f7dcaff418e 100644 --- a/lib/libcrypto/evp/m_sigver.c +++ b/lib/libcrypto/evp/m_sigver.c @@ -1,4 +1,4 @@ -/* $OpenBSD: m_sigver.c,v 1.7 2018/05/13 06:35:10 tb Exp $ */ +/* $OpenBSD: m_sigver.c,v 1.8 2021/03/29 15:57:23 tb Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2006. */ @@ -74,15 +74,17 @@ do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, if (ctx->pctx == NULL) return 0; - if (type == NULL) { - int def_nid; - if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0) - type = EVP_get_digestbynid(def_nid); - } + if (!(ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)) { + if (type == NULL) { + int def_nid; + if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0) + type = EVP_get_digestbynid(def_nid); + } - if (type == NULL) { - EVPerror(EVP_R_NO_DEFAULT_DIGEST); - return 0; + if (type == NULL) { + EVPerror(EVP_R_NO_DEFAULT_DIGEST); + return 0; + } } if (ver) { @@ -105,6 +107,8 @@ do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, return 0; if (pctx) *pctx = ctx->pctx; + if (ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) + return 1; if (!EVP_DigestInit_ex(ctx, type, e)) return 0; return 1; @@ -127,7 +131,24 @@ EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen) { - int sctx, r = 0; + EVP_PKEY_CTX *pctx = ctx->pctx; + int sctx; + int r = 0; + + if (pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) { + EVP_PKEY_CTX *dctx; + + if (sigret == NULL) + return pctx->pmeth->signctx(pctx, sigret, siglen, ctx); + + /* XXX - support EVP_MD_CTX_FLAG_FINALISE? */ + if ((dctx = EVP_PKEY_CTX_dup(ctx->pctx)) == NULL) + return 0; + r = dctx->pmeth->signctx(dctx, sigret, siglen, ctx); + EVP_PKEY_CTX_free(dctx); + + return r; + } if (ctx->pctx->pmeth->signctx) sctx = 1; diff --git a/lib/libcrypto/evp/p_lib.c b/lib/libcrypto/evp/p_lib.c index 13a9d65f28b..9577b10ea1b 100644 --- a/lib/libcrypto/evp/p_lib.c +++ b/lib/libcrypto/evp/p_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: p_lib.c,v 1.25 2019/03/17 18:17:45 tb Exp $ */ +/* $OpenBSD: p_lib.c,v 1.26 2021/03/29 15:57:23 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -61,6 +61,7 @@ #include #include +#include #include #include #include @@ -216,10 +217,14 @@ EVP_PKEY_up_ref(EVP_PKEY *pkey) */ static int -pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len) +pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str, int len) { const EVP_PKEY_ASN1_METHOD *ameth; - ENGINE *e = NULL; + ENGINE **eptr = NULL; + + if (e == NULL) + eptr = &e; + if (pkey) { if (pkey->pkey.ptr) EVP_PKEY_free_it(pkey); @@ -234,11 +239,11 @@ pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len) #endif } if (str) - ameth = EVP_PKEY_asn1_find_str(&e, str, len); + ameth = EVP_PKEY_asn1_find_str(eptr, str, len); else - ameth = EVP_PKEY_asn1_find(&e, type); + ameth = EVP_PKEY_asn1_find(eptr, type); #ifndef OPENSSL_NO_ENGINE - if (pkey == NULL) + if (pkey == NULL && eptr != NULL) ENGINE_finish(e); #endif if (!ameth) { @@ -258,13 +263,43 @@ pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len) int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) { - return pkey_set_type(pkey, type, NULL, -1); + return pkey_set_type(pkey, NULL, type, NULL, -1); +} + +EVP_PKEY * +EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, size_t len, + const EVP_CIPHER *cipher) +{ + EVP_PKEY *ret = NULL; + CMAC_CTX *cmctx = NULL; + + if ((ret = EVP_PKEY_new()) == NULL) + goto err; + if ((cmctx = CMAC_CTX_new()) == NULL) + goto err; + + if (!pkey_set_type(ret, e, EVP_PKEY_CMAC, NULL, -1)) + goto err; + + if (!CMAC_Init(cmctx, priv, len, cipher, e)) { + EVPerror(EVP_R_KEY_SETUP_FAILED); + goto err; + } + + ret->pkey.ptr = (char *)cmctx; + + return ret; + + err: + EVP_PKEY_free(ret); + CMAC_CTX_free(cmctx); + return NULL; } int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len) { - return pkey_set_type(pkey, EVP_PKEY_NONE, str, len); + return pkey_set_type(pkey, NULL, EVP_PKEY_NONE, str, len); } int -- cgit v1.2.3-59-g8ed1b