From a24a5b8cc4103ddd69f21c91c7d7372abc270157 Mon Sep 17 00:00:00 2001 From: Johannes Bauer Date: Sat, 22 Jul 2017 17:43:05 +0200 Subject: [PATCH] More error handling to HKDF and one more case in TLS1-PRF HKDF now handles an invalid digest like TLS1-PRF does (i.e., returns KDF_R_INVALID_DIGEST if the passed digest is not known). Both KDFs now set the error code KDF_R_UNKNOWN_PARAMETER_TYPE if a type was passed that is not recognized. This will have the effect of improving debugging output in case a user uses "openssl pkeyutl -kdf ..." in a wrong way and result in an actual error code (instead of just "failure" and an empty error stack). Reviewed-by: Paul Dale Reviewed-by: Stephen Henson (Merged from https://github.com/openssl/openssl/pull/3989) --- crypto/err/openssl.txt | 2 ++ crypto/kdf/hkdf.c | 11 +++++++++-- crypto/kdf/kdf_err.c | 3 +++ crypto/kdf/tls1_prf.c | 2 ++ include/openssl/kdferr.h | 2 ++ 5 files changed, 18 insertions(+), 2 deletions(-) diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index af3bf775bf..1b677d6924 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -700,6 +700,7 @@ EVP_F_PKEY_SET_TYPE:158:pkey_set_type EVP_F_RC2_MAGIC_TO_METH:109:rc2_magic_to_meth EVP_F_RC5_CTRL:125:rc5_ctrl EVP_F_UPDATE:173:update +KDF_F_PKEY_HKDF_CTRL_STR:103:pkey_hkdf_ctrl_str KDF_F_PKEY_HKDF_DERIVE:102:pkey_hkdf_derive KDF_F_PKEY_TLS1_PRF_CTRL_STR:100:pkey_tls1_prf_ctrl_str KDF_F_PKEY_TLS1_PRF_DERIVE:101:pkey_tls1_prf_derive @@ -1965,6 +1966,7 @@ EVP_R_WRAP_MODE_NOT_ALLOWED:170:wrap mode not allowed EVP_R_WRONG_FINAL_BLOCK_LENGTH:109:wrong final block length KDF_R_INVALID_DIGEST:100:invalid digest KDF_R_MISSING_PARAMETER:101:missing parameter +KDF_R_UNKNOWN_PARAMETER_TYPE:103:unknown parameter type KDF_R_VALUE_MISSING:102:value missing OBJ_R_OID_EXISTS:102:oid exists OBJ_R_UNKNOWN_NID:101:unknown nid diff --git a/crypto/kdf/hkdf.c b/crypto/kdf/hkdf.c index d83283fa14..8ffc8a3899 100644 --- a/crypto/kdf/hkdf.c +++ b/crypto/kdf/hkdf.c @@ -148,8 +148,14 @@ static int pkey_hkdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, return EVP_PKEY_CTX_hkdf_mode(ctx, mode); } - if (strcmp(type, "md") == 0) - return EVP_PKEY_CTX_set_hkdf_md(ctx, EVP_get_digestbyname(value)); + if (strcmp(type, "md") == 0) { + const EVP_MD *md = EVP_get_digestbyname(value); + if (!md) { + KDFerr(KDF_F_PKEY_HKDF_CTRL_STR, KDF_R_INVALID_DIGEST); + return 0; + } + return EVP_PKEY_CTX_set_hkdf_md(ctx, md); + } if (strcmp(type, "salt") == 0) return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_SALT, value); @@ -169,6 +175,7 @@ static int pkey_hkdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, if (strcmp(type, "hexinfo") == 0) return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_INFO, value); + KDFerr(KDF_F_PKEY_HKDF_CTRL_STR, KDF_R_UNKNOWN_PARAMETER_TYPE); return -2; } diff --git a/crypto/kdf/kdf_err.c b/crypto/kdf/kdf_err.c index f6193b2458..f5d0f7eaf6 100644 --- a/crypto/kdf/kdf_err.c +++ b/crypto/kdf/kdf_err.c @@ -14,6 +14,7 @@ #ifndef OPENSSL_NO_ERR static const ERR_STRING_DATA KDF_str_functs[] = { + {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_HKDF_CTRL_STR, 0), "pkey_hkdf_ctrl_str"}, {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_HKDF_DERIVE, 0), "pkey_hkdf_derive"}, {ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_TLS1_PRF_CTRL_STR, 0), "pkey_tls1_prf_ctrl_str"}, @@ -25,6 +26,8 @@ static const ERR_STRING_DATA KDF_str_functs[] = { static const ERR_STRING_DATA KDF_str_reasons[] = { {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_INVALID_DIGEST), "invalid digest"}, {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_PARAMETER), "missing parameter"}, + {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_UNKNOWN_PARAMETER_TYPE), + "unknown parameter type"}, {ERR_PACK(ERR_LIB_KDF, 0, KDF_R_VALUE_MISSING), "value missing"}, {0, NULL} }; diff --git a/crypto/kdf/tls1_prf.c b/crypto/kdf/tls1_prf.c index fa13732bbf..1673b577ad 100644 --- a/crypto/kdf/tls1_prf.c +++ b/crypto/kdf/tls1_prf.c @@ -115,6 +115,8 @@ static int pkey_tls1_prf_ctrl_str(EVP_PKEY_CTX *ctx, return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_TLS_SEED, value); if (strcmp(type, "hexseed") == 0) return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_TLS_SEED, value); + + KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_UNKNOWN_PARAMETER_TYPE); return -2; } diff --git a/include/openssl/kdferr.h b/include/openssl/kdferr.h index aefdbff105..9c09991bfd 100644 --- a/include/openssl/kdferr.h +++ b/include/openssl/kdferr.h @@ -22,6 +22,7 @@ int ERR_load_KDF_strings(void); /* * KDF function codes. */ +# define KDF_F_PKEY_HKDF_CTRL_STR 103 # define KDF_F_PKEY_HKDF_DERIVE 102 # define KDF_F_PKEY_TLS1_PRF_CTRL_STR 100 # define KDF_F_PKEY_TLS1_PRF_DERIVE 101 @@ -31,6 +32,7 @@ int ERR_load_KDF_strings(void); */ # define KDF_R_INVALID_DIGEST 100 # define KDF_R_MISSING_PARAMETER 101 +# define KDF_R_UNKNOWN_PARAMETER_TYPE 103 # define KDF_R_VALUE_MISSING 102 #endif -- 2.34.1