Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should ecdh_param_size allow X25519 as 253 instead of 256? #298

Open
janbrasna opened this issue Nov 18, 2024 · 2 comments
Open

Should ecdh_param_size allow X25519 as 253 instead of 256? #298

janbrasna opened this issue Nov 18, 2024 · 2 comments

Comments

@janbrasna
Copy link

While the math behind "Server Temp Key: X25519, 253 bits" is not exactly clear to me (being 256 bits, among which 251 are variable, and 5 are set to predefined values: the 3 low-order bits and 2 high-order bits being zero, except the second-highest order bit — would understand 251 instead of 256, but don't see why exactly 253), however that's the EC exchange constant for the curve:

@openssl/openssl:include/crypto/ecx.h#L33

This is not mentioned in the actual wiki recommendations, but the value is explicitly set in the guideline json data and is being consumed downstream for comparison/validation.

Question is whether the next release should make this value compatible with OpenSSL outputs, and lower the 256bit threshold to the 253bit reported in s_client handshake.

TLSv1.3 TLS_AES_256_GCM_SHA384, 253 bit ECDH (X25519)
TLSv1.2 ECDHE-RSA-CHACHA20-POLY1305, 256 bit ECDH (P-256)
TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
TLSv1.3 TLS_AES_256_GCM_SHA384, 253 bit ECDH (X25519)
@gstrauss
Copy link

I think you meant "report X25519 as 253" rather than "allow X25519 as 253". Please confirm.

https://x25519.xargs.org/

The key size of X25519 is 256 bits (32 bytes), but five of those bits are "clamped" to fixed values to address various security concerns [...] This makes a key with strength 251 bits.

The parameter size is still 32 bytes (256 bits).

What are your trying to report for ecdh_param_size?


So where might the 253 come from? In mbedTLS, for Curve25519, the number of bits in the private key is 253, and the number of bits in the prime modulus of the base field is 255.
https://github.com/Mbed-TLS/mbedtls/blob/development/docs/psa-transition.md#information-about-a-curve
The definition of struct mbedtls_ecp_group from mbedtls 2.28 explains nbits and pbits members
https://github.com/Mbed-TLS/mbedtls/blob/mbedtls-2.28/include/mbedtls/ecp.h#L270

@janbrasna
Copy link
Author

I'm not aware of any place the guideline would "report" anything, but restricts:

"ecdh_param_size": 256,

that implementations in turn use to scan for key exchange strength (and OpenSSL reports X25519 temp key as 253 bit, failing this check) — I'm not sure the json value was meant to represent the size of the actual key (that is otherwise defined with the allowed curves), or the minimum effective key exchange bits (that scanners seem to refer to), as it's not exactly documented — and most likely comes from times when the param size would be equal to the reported temp key length (read: before adding X25519), and not updated since.

I'm asking this question to a) understand the value and its intent better, b) document it so it can be used downstream without ambiguity, c) decide whether it's still useful, maintained, and matching the other data.

(And if this is still correct as-is, change the downstream consumers to not rely on the reported kx temp info, but check the actual curves used instead, as this size is not useful for any grading/comparison.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants