X25519: standard requires masking of top bit

Instead of failing when top bit is set, the standard and current research says to mask it.
WOLFSSL_X25519_NO_MASK_PEER is added to allow the rejection when required.
This commit is contained in:
Sean Parkinson
2026-06-17 12:05:27 +10:00
parent 6ff1f8f2b8
commit e017e6cba7
3 changed files with 34 additions and 4 deletions
+1
View File
@@ -971,6 +971,7 @@ WOLFSSL_VALIDATE_DH_KEYGEN
WOLFSSL_WC_SLHDSA_RECURSIVE
WOLFSSL_WC_XMSS_NO_SHA256
WOLFSSL_WICED_PSEUDO_UNIX_EPOCH_TIME
WOLFSSL_X25519_NO_MASK_PEER
WOLFSSL_X509_STORE_ALLOW_NON_CA_INTERMEDIATE
WOLFSSL_X509_STORE_CERTS
WOLFSSL_X509_TRUSTED_CERTIFICATE_CALLBACK
+19 -1
View File
@@ -307,6 +307,10 @@ int test_wc_curve25519_shared_secret_ex(void)
WC_RNG rng;
byte out[CURVE25519_KEYSIZE];
word32 outLen = sizeof(out);
#ifndef WOLFSSL_X25519_NO_MASK_PEER
byte outHiBit[CURVE25519_KEYSIZE];
word32 outHiBitLen = sizeof(out);
#endif
int endian = EC25519_BIG_ENDIAN;
ExpectIntEQ(wc_curve25519_init(&private_key), 0);
@@ -336,11 +340,25 @@ int test_wc_curve25519_shared_secret_ex(void)
ExpectIntEQ(wc_curve25519_shared_secret_ex(&private_key, &public_key, out,
NULL, endian), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifdef WOLFSSL_X25519_NO_MASK_PEER
/* curve25519.c is checking for public_key size less than or equal to 0x7f,
* increasing to 0x8f checks for error being returned */
public_key.p.point[CURVE25519_KEYSIZE-1] = 0x8F;
if (EXPECT_SUCCESS()) {
public_key.p.point[CURVE25519_KEYSIZE-1] = 0x8F;
}
ExpectIntEQ(wc_curve25519_shared_secret_ex(&private_key, &public_key, out,
&outLen, endian), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
#else
ExpectIntEQ(wc_curve25519_shared_secret_ex(&private_key, &public_key, out,
&outLen, endian), 0);
if (EXPECT_SUCCESS()) {
public_key.p.point[CURVE25519_KEYSIZE-1] |= 0x80;
}
ExpectIntEQ(wc_curve25519_shared_secret_ex(&private_key, &public_key,
outHiBit, &outHiBitLen, endian), 0);
ExpectIntEQ(outLen, outHiBitLen);
ExpectBufEQ(out, outHiBit, outLen);
#endif
outLen = outLen - 2;
ExpectIntEQ(wc_curve25519_shared_secret_ex(&private_key, &public_key, out,
+14 -3
View File
@@ -710,10 +710,12 @@ int wc_curve25519_shared_secret_ex(curve25519_key* private_key,
return ECC_BAD_ARG_E;
}
#ifdef WOLFSSL_X25519_NO_MASK_PEER
/* avoid implementation fingerprinting - make sure signed bit is not set */
if (public_key->p.point[CURVE25519_KEYSIZE-1] & 0x80) {
return ECC_BAD_ARG_E;
}
#endif
#ifdef WOLF_CRYPTO_CB
if (private_key->devId != INVALID_DEVID) {
@@ -768,15 +770,24 @@ int wc_curve25519_shared_secret_ex(curve25519_key* private_key,
else
#endif /* WOLFSSL_SE050 */
{
#ifdef WOLFSSL_X25519_NO_MASK_PEER
byte* pubVal = public_key->p.point;
#else
byte pubVal[CURVE25519_KEYSIZE];
XMEMCPY(pubVal, public_key->p.point, CURVE25519_KEYSIZE);
pubVal[CURVE25519_KEYSIZE-1] &= 0x7f;
#endif
#ifndef WOLFSSL_CURVE25519_BLINDING
SAVE_VECTOR_REGISTERS(return _svr_ret;);
ret = curve25519(o.point, private_key->k, public_key->p.point);
ret = curve25519(o.point, private_key->k, pubVal);
RESTORE_VECTOR_REGISTERS();
#else
ret = curve25519_smul_blind(o.point, private_key->k,
public_key->p.point, private_key->rng);
ret = curve25519_smul_blind(o.point, private_key->k, pubVal,
private_key->rng);
#endif
}
#endif /* FREESCALE_LTC_ECC */