Update key share group ranking algorithm

In case no user group ranking is set, all groups are now ranked equally
instead of the order in the `preferredGroup` array. This is the
behavior already indicated in the comment header of the function.

This change is necessary for applications that do not set their own
group ranking (via `wolfSSL_CTX_set_groups()` for example). When such an
application creates a TLS server and receives a ClientHello message with
multiple key shares, now the first key share is selected instead of the
one with the lowest index in the `preferredGroup` array.

Recent browsers with PQC support place two key shares in their
ClientHello message: a hybrid PQC + X25519 one and at least one
classic-only one. The hybrid one is the first one, indicating a
preference. Without this change, however, always the classic-only key
share has been selected, as these algorithms have a lower index in the
`preferredGroup` array compared to the PQC hybrids.

Tested using a patched version of NGINX.

This change also results in a different selection of a key share group
in case of a HelloRetryRequest message. For the tests, where static
ephemeral keys are used (`WOLFSSL_STATIC_EPHEMERAL`), an additional
check is necessary to make sure the correct key is used for the ECDH
calculation.

Signed-off-by: Tobias Frauenschläger <tobias.frauenschlaeger@oth-regensburg.de>
This commit is contained in:
Tobias Frauenschläger
2024-11-11 12:39:09 +01:00
parent 89491c7e36
commit c899f79cfa

View File

@ -8012,7 +8012,7 @@ static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse)
#ifdef WOLFSSL_STATIC_EPHEMERAL
ret = wolfSSL_StaticEphemeralKeyLoad(ssl, WC_PK_TYPE_ECDH, kse->key);
if (ret != 0)
if (ret != 0 || eccKey->dp->id != curveId)
#endif
{
/* set curve info for EccMakeKey "peer" info */
@ -10745,8 +10745,7 @@ static int TLSX_KeyShare_GroupRank(const WOLFSSL* ssl, int group)
byte numGroups;
if (ssl->numGroups == 0) {
groups = preferredGroup;
numGroups = PREFERRED_GROUP_SZ;
return 0;
}
else {
groups = ssl->group;