diff --git a/doc/man7/EVP_KDF-SSHKDF.pod b/doc/man7/EVP_KDF-SSHKDF.pod index 454bb6b699..2b2f0cc227 100644 --- a/doc/man7/EVP_KDF-SSHKDF.pod +++ b/doc/man7/EVP_KDF-SSHKDF.pod @@ -41,9 +41,9 @@ These parameters work as described in L. These parameters set the respective values for the KDF. If a value is already set, the contents are replaced. -=item "type" (B) +=item "type" (B) -This parameter sets the type for the SSHHKDF operation. +This parameter sets the type for the SSHKDF operation. There are six supported types: =over 4 @@ -51,32 +51,32 @@ There are six supported types: =item EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV The Initial IV from client to server. -A single char of value 65 (ASCII char 'A'). +Char array initializer of value {65, 0}, i.e., ASCII string "A". =item EVP_KDF_SSHKDF_TYPE_INITIAL_IV_SRV_TO_CLI The Initial IV from server to client -A single char of value 66 (ASCII char 'B'). +Char array initializer of value {66, 0}, i.e., ASCII string "B". =item EVP_KDF_SSHKDF_TYPE_ENCRYPTION_KEY_CLI_TO_SRV The Encryption Key from client to server -A single char of value 67 (ASCII char 'C'). +Char array initializer of value {67, 0}, i.e., ASCII string "C". =item EVP_KDF_SSHKDF_TYPE_ENCRYPTION_KEY_SRV_TO_CLI The Encryption Key from server to client -A single char of value 68 (ASCII char 'D'). +Char array initializer of value {68, 0}, i.e., ASCII string "D". =item EVP_KDF_SSHKDF_TYPE_INTEGRITY_KEY_CLI_TO_SRV The Integrity Key from client to server -A single char of value 69 (ASCII char 'E'). +Char array initializer of value {69, 0}, i.e., ASCII string "E". =item EVP_KDF_SSHKDF_TYPE_INTEGRITY_KEY_SRV_TO_CLI The Integrity Key from client to server -A single char of value 70 (ASCII char 'F'). +Char array initializer of value {70, 0}, i.e., ASCII string "F". =back @@ -103,6 +103,7 @@ This example derives an 8 byte IV using SHA-256 with a 1K "key" and appropriate EVP_KDF *kdf; EVP_KDF_CTX *kctx; + const char type[] = EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV; unsigned char key[1024] = "01234..."; unsigned char xcghash[32] = "012345..."; unsigned char session_id[32] = "012345..."; @@ -122,8 +123,8 @@ This example derives an 8 byte IV using SHA-256 with a 1K "key" and appropriate xcghash, (size_t)32); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, session_id, (size_t)32); - *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_SSHKDF_TYPE, - EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_SSHKDF_TYPE, + type, sizeof(type)); *p = OSSL_PARAM_construct_end(); if (EVP_KDF_CTX_set_params(kctx, params) <= 0) /* Error */ diff --git a/doc/man7/provider-kdf.pod b/doc/man7/provider-kdf.pod index 07aaf373c6..be0bc7b51b 100644 --- a/doc/man7/provider-kdf.pod +++ b/doc/man7/provider-kdf.pod @@ -246,7 +246,7 @@ Sets the xcghash in the associated KDF ctx. Sets the session ID in the associated KDF ctx. -=item "type" (B) +=item "type" (B) Sets the SSH KDF type parameter in the associated KDF ctx. There are six supported types: diff --git a/include/openssl/kdf.h b/include/openssl/kdf.h index 7f89f75270..dd485bcb01 100644 --- a/include/openssl/kdf.h +++ b/include/openssl/kdf.h @@ -85,12 +85,14 @@ void EVP_KDF_names_do_all(const EVP_KDF *kdf, # define EVP_KDF_HKDF_MODE_EXTRACT_ONLY 1 # define EVP_KDF_HKDF_MODE_EXPAND_ONLY 2 -#define EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV 65 -#define EVP_KDF_SSHKDF_TYPE_INITIAL_IV_SRV_TO_CLI 66 -#define EVP_KDF_SSHKDF_TYPE_ENCRYPTION_KEY_CLI_TO_SRV 67 -#define EVP_KDF_SSHKDF_TYPE_ENCRYPTION_KEY_SRV_TO_CLI 68 -#define EVP_KDF_SSHKDF_TYPE_INTEGRITY_KEY_CLI_TO_SRV 69 -#define EVP_KDF_SSHKDF_TYPE_INTEGRITY_KEY_SRV_TO_CLI 70 +/* SSHKDF key exchange stages.*/ +/* See https://tools.ietf.org/html/rfc4253#section-7.2 */ +#define EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV {65, 0} +#define EVP_KDF_SSHKDF_TYPE_INITIAL_IV_SRV_TO_CLI {66, 0} +#define EVP_KDF_SSHKDF_TYPE_ENCRYPTION_KEY_CLI_TO_SRV {67, 0} +#define EVP_KDF_SSHKDF_TYPE_ENCRYPTION_KEY_SRV_TO_CLI {68, 0} +#define EVP_KDF_SSHKDF_TYPE_INTEGRITY_KEY_CLI_TO_SRV {69, 0} +#define EVP_KDF_SSHKDF_TYPE_INTEGRITY_KEY_SRV_TO_CLI {70, 0} /**** The legacy PKEY-based KDF API follows. ****/ diff --git a/providers/fips/self_test_data.inc b/providers/fips/self_test_data.inc index 4a9bcf450e..7631d682e5 100644 --- a/providers/fips/self_test_data.inc +++ b/providers/fips/self_test_data.inc @@ -351,7 +351,7 @@ static const ST_KAT_PARAM pbkdf2_params[] = { }; static const char sshkdf_digest[] = "SHA1"; -static int sshkdf_type = EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV; +static const char sshkdf_type[] = EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV; static const unsigned char sshkdf_key[] = { 0x00, 0x00, 0x00, 0x80, 0x55, 0xba, 0xe9, 0x31, 0xc0, 0x7f, 0xd8, 0x24, 0xbf, 0x10, 0xad, 0xd1, @@ -386,7 +386,7 @@ static const unsigned char sshkdf_expected[] = { }; static const ST_KAT_PARAM sshkdf_params[] = { ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_DIGEST, sshkdf_digest), - ST_KAT_PARAM_INT(OSSL_KDF_PARAM_SSHKDF_TYPE, sshkdf_type), + ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_SSHKDF_TYPE, sshkdf_type), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_KEY, sshkdf_key), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_SSHKDF_XCGHASH, sshkdf_xcghash), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_SSHKDF_SESSION_ID, sshkdf_session_id), diff --git a/providers/implementations/kdfs/sshkdf.c b/providers/implementations/kdfs/sshkdf.c index daf0dd2e87..e86c502184 100644 --- a/providers/implementations/kdfs/sshkdf.c +++ b/providers/implementations/kdfs/sshkdf.c @@ -135,7 +135,6 @@ static int kdf_sshkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) const OSSL_PARAM *p; KDF_SSHKDF *ctx = vctx; OSSL_LIB_CTX *provctx = PROV_LIBCTX_OF(ctx->provctx); - int t; if (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx)) return 0; @@ -156,14 +155,17 @@ static int kdf_sshkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SSHKDF_TYPE)) != NULL) { - if (p->data == NULL || p->data_size == 0) + const char *kdftype; + + if (!OSSL_PARAM_get_utf8_string_ptr(p, &kdftype)) return 0; - t = *(unsigned char *)p->data; - if (t < 65 || t > 70) { + if (kdftype == NULL || kdftype[0] == '\0' || kdftype[1] != '\0') + return 0; + if (kdftype[0] < 65 || kdftype[0] > 70) { ERR_raise(ERR_LIB_PROV, PROV_R_VALUE_ERROR); return 0; } - ctx->type = (char)t; + ctx->type = kdftype[0]; } return 1; } diff --git a/test/evp_kdf_test.c b/test/evp_kdf_test.c index d56e14cdb0..b0e8d2b5fb 100644 --- a/test/evp_kdf_test.c +++ b/test/evp_kdf_test.c @@ -1207,7 +1207,7 @@ static int test_kdf_sshkdf(void) int ret; EVP_KDF_CTX *kctx; OSSL_PARAM params[6], *p = params; - char kdftype = EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV; + char kdftype[] = EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV; unsigned char out[8]; /* Test data from NIST CAVS 14.1 test vectors */ static unsigned char key[] = { @@ -1247,7 +1247,7 @@ static int test_kdf_sshkdf(void) *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SSHKDF_SESSION_ID, sessid, sizeof(sessid)); *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_SSHKDF_TYPE, - &kdftype, sizeof(kdftype)); + kdftype, sizeof(kdftype)); *p = OSSL_PARAM_construct_end(); ret =