Commit 45c8f381b5 for openssl.org
commit 45c8f381b5513feaead63e294e901a5a58566bcb
Author: mzfr <github@mzfr.in>
Date: Wed Sep 23 23:14:19 2026 +0800
Preserve SNMPKDF password after rejected updates
Validate password length before modifying the context and raise an error for invalid lengths. Add regression coverage for rejected updates.
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Merge-date: Fri Nov 13 15:15:28 2026
Merged-from: https://github.com/openssl/openssl/pull/32960
diff --git a/providers/implementations/kdfs/snmpkdf.c b/providers/implementations/kdfs/snmpkdf.c
index e857abc1e8..11dff38653 100644
--- a/providers/implementations/kdfs/snmpkdf.c
+++ b/providers/implementations/kdfs/snmpkdf.c
@@ -163,6 +163,13 @@ static int kdf_snmpkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
if (ctx == NULL || !snmp_set_ctx_params_decoder(params, &p))
return 0;
+ if (p.pw != NULL
+ && (p.pw->data_size < KDF_SNMP_MIN_PASSWORD_LEN
+ || p.pw->data_size > KDF_SNMP_PASSWORD_HASH_AMOUNT)) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_INPUT_LENGTH);
+ return 0;
+ }
+
libctx = PROV_LIBCTX_OF(ctx->provctx);
if (p.digest != NULL) {
if (!ossl_prov_digest_load(&ctx->digest, p.digest, p.propq, libctx))
@@ -181,8 +188,6 @@ static int kdf_snmpkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
if (p.pw != NULL) {
if (!snmpkdf_set_membuf(&ctx->password, &ctx->password_len, p.pw))
return 0;
- if ((ctx->password_len > KDF_SNMP_PASSWORD_HASH_AMOUNT) || (ctx->password_len < KDF_SNMP_MIN_PASSWORD_LEN))
- return 0;
}
if (p.eid != NULL && !snmpkdf_set_membuf(&ctx->eid, &ctx->eid_len, p.eid))
diff --git a/test/evp_kdf_test.c b/test/evp_kdf_test.c
index ec77564699..155f093d95 100644
--- a/test/evp_kdf_test.c
+++ b/test/evp_kdf_test.c
@@ -2099,6 +2099,39 @@ err:
}
#endif /* OPENSSL_NO_SRTPKDF */
+#ifndef OPENSSL_NO_SNMPKDF
+static int test_kdf_snmpkdf_rejected_password(void)
+{
+ int ret;
+ EVP_KDF_CTX *kctx = NULL;
+ OSSL_PARAM params[4], rejected[2];
+ unsigned char password[] = "password";
+ unsigned char eid[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
+ unsigned char dummy = 0;
+ unsigned char expected[32], out[sizeof(expected)];
+
+ params[0] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
+ "SHA256", 0);
+ params[1] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD,
+ password, sizeof(password) - 1);
+ params[2] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SNMPKDF_EID,
+ eid, sizeof(eid));
+ params[3] = OSSL_PARAM_construct_end();
+ rejected[0] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD,
+ &dummy, 0);
+ rejected[1] = OSSL_PARAM_construct_end();
+
+ ret = TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_SNMPKDF))
+ && TEST_true(EVP_KDF_derive(kctx, expected, sizeof(expected), params))
+ && TEST_false(EVP_KDF_CTX_set_params(kctx, rejected))
+ && TEST_true(EVP_KDF_derive(kctx, out, sizeof(out), NULL))
+ && TEST_mem_eq(out, sizeof(out), expected, sizeof(expected));
+
+ EVP_KDF_CTX_free(kctx);
+ return ret;
+}
+#endif /* OPENSSL_NO_SNMPKDF */
+
#ifndef OPENSSL_NO_SSHKDF
static int test_kdf_sshkdf(void)
{
@@ -2591,6 +2624,9 @@ int setup_tests(void)
#ifndef OPENSSL_NO_SRTPKDF
ADD_TEST(test_kdf_srtpkdf_size);
#endif
+#ifndef OPENSSL_NO_SNMPKDF
+ ADD_TEST(test_kdf_snmpkdf_rejected_password);
+#endif
#ifndef OPENSSL_NO_SSHKDF
ADD_TEST(test_kdf_sshkdf);
#endif