-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
extmod: factor mbedtls config to common location, and enable elliptic curves #9506
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
extmod: factor mbedtls config to common location, and enable elliptic curves #9506
Conversation
This is obviously a large increase in code size (for the builds that can afford it). But I don't see any other option. Without elliptic curve cryptography, MicroPython devices are partially cut off from the internet. For users that need to reduce code size they'll need to build custom firmware with a custom mbedtls config. |
#define MBEDTLS_ECDH_C | ||
#define MBEDTLS_ECP_C | ||
#define MBEDTLS_ENTROPY_C | ||
#define MBEDTLS_ERROR_C | ||
#define MBEDTLS_GCM_C |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we remove this exception from the rp2 config and enable for all?
ucryptolib doesn't enable GCM, so the only reason for enabling it would be for SSL. If we think that sites use it (it is a valid TLS configuration), then we should enable it for all ports?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would have to check exactly what it does (and also code size increase).
#define MBEDTLS_ECP_DP_BP256R1_ENABLED | ||
#define MBEDTLS_ECP_DP_BP384R1_ENABLED | ||
#define MBEDTLS_ECP_DP_BP512R1_ENABLED | ||
#define MBEDTLS_ECP_DP_CURVE25519_ENABLED | ||
#define MBEDTLS_ECP_NIST_OPTIM |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Depending on the prime and architecture, makes operations 4 to 8 times faster on the corresponding curve."
Should we enable this for everything?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It costs quite a bit of flash, maybe 6k. On unix it's not needed because it's already fast there. On rp2 it's probably worth it because the rp2 CPU is not fast. I was going to do some perf tests on stm32 with this option enabled/disabled to see if it made a difference, but that takes time.
Definitely, for reference Server_Side_TLS recommendations from Mozilla.
In case anyone needs this: Reducing Mbed TLS memory and storage footprint |
Thanks @Carglglz , both of those links are helpful! |
The So this PR is on hold until we resolve that issue. |
I can reproduce this, |
But deprecating it will be a breaking change for users who have built a web server using older encryption standards. Would be best to not break |
The problem here is that it's negotiating the highest supported cipher by both ends (now ECDHE), but then the server is presenting an RSA cert. I think what we need to do is support the Could use mbedtls_ssl_ciphersuite_from_string etc... We'll have to make the default something that maintains backwards compatibility (as Damien just commented above). |
I agree with not making breaking changes, I meant to change key/cert in
I did enabled
And failure happens here
Running
The only difference is in key/cert
And it does pass the test. So it looks to me like this cipher suite If
allows this key size and the test runs without failures. [EDIT]
int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx,
388 │ mbedtls_md_type_t md_alg,
389 │ const unsigned char *hash, size_t hash_len,
390 │ unsigned char *sig, size_t *sig_len,
391 │ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
392 │ mbedtls_pk_restart_ctx *rs_ctx )
393 │ {
394 │ PK_VALIDATE_RET( ctx != NULL );
395 │ PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
396 │ hash != NULL );
397 │ PK_VALIDATE_RET( sig != NULL );
398 │
399 │ if( ctx->pk_info == NULL ||
400 │ pk_hashlen_helper( md_alg, &hash_len ) != 0 )
401 │ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); <-- So it may be that this ciphersuite doesn't allow hashing algo * Helper for mbedtls_pk_sign and mbedtls_pk_verify
223 │ */
224 │ static inline int pk_hashlen_helper( mbedtls_md_type_t md_alg, size_t *hash_len )
225 │ {
226 │ const mbedtls_md_info_t *md_info;
227 │
228 │ if( *hash_len != 0 )
229 │ return( 0 );
230 │
231 │ if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL )
232 │ return( -1 );
233 │
234 │ *hash_len = mbedtls_md_get_size( md_info );
235 │ return( 0 );
236 │ } Hard to tell tbh 🤷🏼♂️ which one it is (key or md algo) , also from 990 │ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
991 │ int (*f_rng)(void *, unsigned char *, size_t),
992 │ void *p_rng,
993 │ int mode,
994 │ mbedtls_md_type_t md_alg,
995 │ unsigned int hashlen,
996 │ const unsigned char *hash,
997 │ unsigned char *sig ); ... * \note This function always uses the maximum possible salt size,
* up to the length of the payload hash. This choice of salt
* size complies with FIPS 186-4 §5.5 (e) and RFC 8017 (PKCS#1
* v2.2) §9.1.1 step 3. Furthermore this function enforces a
* minimum salt size which is the hash size minus 2 bytes. If
* this minimum size is too large given the key size (the salt
* size, plus the hash size, plus 2 bytes must be no more than
* the key size in bytes), this function returns
* #MBEDTLS_ERR_RSA_BAD_INPUT_DATA. |
I've already done this I've added |
@dpgeorge Also to avoid confusion |
I would like to keep this test as-is. It provides a good baseline test with a simple (albeit old/weak) key/cert pair.
Yes, that could be a solution to get this PR merged. The rp2 port has that enabled already, and it can just stay enabled in that port only, no other ports will enable it (yet).
OK. |
b41c0ca
to
6e4e378
Compare
@Carglglz can you provide more info about this? It looks like there's code in mbedtls to implement this curve, and disabling it reduces code size on the unix port by around 4.5k. So it must do something...? |
Yes, full info here curve25519 support The key part:
Yes, there is a sample Also based on performance
I would disable Brainpool curves, and even maybe a subset of NIST could be good enough e.g. only these three.
I'm pretty sure these ones are widely supported. |
Thanks @Carglglz for the info. Based on that I have disabled curve 25519 and the brainpool curves. Hopefully that doesn't break any existing use cases! I think this PR is now ready to merge. |
This is a no-op change. Signed-off-by: Damien George <damien@micropython.org>
This was already enabled on all ports except mimxrt. Now it's enabled on all of them. Signed-off-by: Damien George <damien@micropython.org>
This is necessary to access sites that only support these protocols. The rp2 port already has ECDH enabled, so this just adds ECDSA there. The other ports now gain both ECDH and ECDSA. The code size increase is: - rp2 (PICO_W): +2916 bytes flash, +24 bytes BSS - stm32 (PYBD_SF6): +20480 bytes flash, +32 bytes data, +48 bytes BSS - mimxrt (TEENSY41): +20708 bytes flash, +32 bytes data, +48 bytes BSS - unix (standard x86-64): +39344 executable, +1744 bytes data, +96 BSS This is obviously a large increase in code size. But there doesn't seem to be any other option because without elliptic curve cryptography devices are partially cut off from the internet. For use cases that require small firmware size, they'll need to build custom firmware with a custom mbedtls config. Signed-off-by: Damien George <damien@micropython.org>
Curve25519 arithmetic is supported in mbedtls, but it's not used for TLS. So there's no need to have this option enabled. Reduces rp2 PICO_W firmware by 2440 bytes. Thanks to @Carglglz for the information. Signed-off-by: Damien George <damien@micropython.org>
They are much slower than NIST (SECP) curves and shouldn't be needed. Reduces rp2 PICO_W firmware by 1328 bytes. Thanks to @Carglglz for the information. Signed-off-by: Damien George <damien@micropython.org>
f749c8b
to
68f166d
Compare
This PR factors all mbedtls config to
extmod/mbedtls/mbedtls_config_common.h
, and then enables EC-DH and EC-DSA on all ports that use it (which is rp2, mimxrt, stm32, unix).ECHS/ECDSA is necessary to access sites that only support these protocols (eg
calendarific.com
).The rp2 port already has ECDH enabled, so this just adds ECDSA. The other ports now gain both ECDH and ECDSA. The code size increase is: