Skip to content

The logic for comparing two ML-KEM public keys for equality is implemented incorrectly #28563

@roadicing

Description

@roadicing

Since this does not appear to cause any security-related issues, it is being resubmitted as a bug for easier reference during the fix.

The function ossl_ml_kem_pubkey_cmp in OpenSSL, which is used to compare two ML-KEM public keys for equality, contains a logical flaw in its implementation.

openssl/crypto/ml_kem/ml_kem.c

Lines 2069 to 2084 in d498f56

int ossl_ml_kem_pubkey_cmp(const ML_KEM_KEY *key1, const ML_KEM_KEY *key2)
{
/*
* This handles any unexpected differences in the ML-KEM variant rank,
* giving different key component structures, barring SHA3-256 hash
* collisions, the keys are the same size.
*/
if (ossl_ml_kem_have_pubkey(key1) && ossl_ml_kem_have_pubkey(key2))
return memcmp(key1->pkhash, key2->pkhash, ML_KEM_PKHASH_BYTES) == 0;
/*
* No match if just one of the public keys is not available, otherwise both
* are unavailable, and for now such keys are considered equal.
*/
return (ossl_ml_kem_have_pubkey(key1) ^ ossl_ml_kem_have_pubkey(key2));
}

From the function's first return statement, it appears that the intended behavior is to return 1 when the two keys are equal. However, when key1->t is NULL while key2->t is non-NULL, the function's second return also produces 1, indicating equality—although in this case key1 and key2 are clearly not equal.

Conversely, when both key1->t and key2->t are NULL, the function returns 0, indicating inequality—even though in this case the two keys should actually be considered equal.

The comments in the function further suggest that the actual effect is the opposite of the intended design.

This function can be triggered through the higher-level function EVP_PKEY_eq when comparing two ML-KEM public keys.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions