--- fips.c | 5 +++++ kex.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 1 deletion(-) --- a/fips.c +++ b/fips.c @@ -48,6 +48,11 @@ static int fips_state = -1; +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) +# define FIPS_mode() EVP_default_properties_is_fips_enabled(NULL) +# define FIPS_mode_set(x) EVP_default_properties_enable_fips(NULL,x) +#endif + /* calculates HMAC of contents of a file given by filename using the hash * algorithm specified by FIPS_HMAC_EVP in fips.h and placing the result into * newly allacated memory - remember to free it when not needed anymore */ --- a/kex.c +++ b/kex.c @@ -41,6 +41,9 @@ #include #include #include +# if (OPENSSL_VERSION_NUMBER >= 0x30000000L) +# include +# endif #endif #include "ssh.h" @@ -1191,14 +1194,61 @@ derive_key_via_openssl(struct ssh *ssh, { struct kex *kex = ssh->kex; EVP_KDF_CTX *hashctx = NULL; - const EVP_MD *md = NULL; u_char *digest = NULL; int r = SSH_ERR_LIBCRYPTO_ERROR; +# if (OPENSSL_VERSION_NUMBER >= 0x30000000L) + OSSL_PARAM params[6], *p = params; + char type = (char) id; + EVP_KDF *kdf = EVP_KDF_fetch (NULL, "SSHKDF", NULL); + if (!kdf) + goto out; + hashctx = EVP_KDF_CTX_new (kdf); +# else + const EVP_MD *md = NULL; hashctx = EVP_KDF_CTX_new_id (EVP_KDF_SSHKDF); +# endif if (!hashctx) goto out; +# if (OPENSSL_VERSION_NUMBER >= 0x30000000L) + switch (kex->hash_alg) + { + case SSH_DIGEST_MD5: + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + SN_md5, strlen(SN_md5)); + break; + case SSH_DIGEST_SHA1: + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + SN_sha1, strlen(SN_sha1)); + break; + case SSH_DIGEST_SHA256: + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + SN_sha256, strlen(SN_sha256)); + break; + case SSH_DIGEST_SHA384: + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + SN_sha384, strlen(SN_sha384)); + break; + case SSH_DIGEST_SHA512: + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + SN_sha512, strlen(SN_sha512)); + break; + default: + goto out; + } + + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, + sshbuf_ptr(shared_secret), sshbuf_len(shared_secret)); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SSHKDF_XCGHASH, + hash, (size_t) hashlen); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SSHKDF_SESSION_ID, + sshbuf_ptr(kex->session_id), (size_t) sshbuf_len(kex->session_id)); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_SSHKDF_TYPE, + &type, sizeof(type)); + *p = OSSL_PARAM_construct_end(); + +# else md = get_openssl_md_for_hash_alg (kex->hash_alg); if (!md) goto out; @@ -1215,6 +1265,7 @@ derive_key_via_openssl(struct ssh *ssh, sshbuf_ptr(kex->session_id), (size_t) sshbuf_len(kex->session_id)) != 1) goto out; +# endif digest = calloc (1, need); if (!digest) { @@ -1222,7 +1273,11 @@ derive_key_via_openssl(struct ssh *ssh, goto out; } +# if (OPENSSL_VERSION_NUMBER >= 0x30000000L) + if (EVP_KDF_derive (hashctx, digest, need, params) != 1) +# else if (EVP_KDF_derive (hashctx, digest, need) != 1) +# endif goto out; *keyp = digest; @@ -1233,6 +1288,10 @@ derive_key_via_openssl(struct ssh *ssh, if (hashctx) EVP_KDF_CTX_free(hashctx); +# if (OPENSSL_VERSION_NUMBER >= 0x30000000L) + EVP_KDF_free(kdf); +# endif + if (digest) free(digest);