Define MBEDTLS_PK_SIGNATURE_MAX_SIZE #315
No reviewers
Labels
No labels
api-spec
bug
CLA requested
CLA valid
compliance
DO NOT MERGE
duplicate
enhancement
feature branch
good first issue
HEADER FORMATTING ISSUE
help wanted
Information
invalid
Jira status: AWAITING REVIEW
Jira status: CLOSED
Jira status: DONE
Jira status: IN PROGRESS
Jira status: IN REVIEW
Jira status: OPEN
Jira status: REOPENED
Jira status: RESOLVED
mirrored
mirror internally
needs: backports
needs: ci
needs: design review
needs: preceding PR
needs: review
needs: work
notabug
open for community contribution
Product Backlog
question
ready for merge
security
stale
type: bug
type: enhancement
type: question
web pages
wontfix
writing
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-ARMmbed/mbed-crypto!315
Loading…
Reference in a new issue
No description provided.
Delete branch "pk_signature_max_size"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Define
MBEDTLS_PK_SIGNATURE_MAX_SIZE, which is (larger than) the maximum size of a signature produced bymbedtls_pk_sign().Fix the sample programs
pk_signandpk_verifyto use this size, instead ofMBEDTLS_MPI_MAX_SIZEwhich is typically too small in builds without RSA.Add unit tests that would catch an incorrect value for
MBEDTLS_PK_SIGNATURE_MAX_SIZE. Non-regression: one of the new test cases fails inconfig-suite-b.hwith ASan enabled ifMBEDTLS_PK_SIGNATURE_MAX_SIZEhas the valueMBEDTLS_MPI_MAX_SIZEwhich was previously used inprograms/pkey/pk_sign.Internal ref: IOTSSL-2857
This was fixed in a different way in Mbed TLS 2.7, 2.16 and development (released in 2.19) (private link: https://github.com/ARMmbed/mbedtls-restricted/pull/573). We lost the fix to development due to a mistake when splitting Mbed Crypto and Mbed TLS (internal ref: IOTCRYPT-969).
Goal this PR: fix IOTSSL-2857 on the crypto side in a way that's better for users and easier to test than the original fix. Note that on the TLS side, the fix made in X.509 via #r573 is sufficient to fix IOTSSL-2857.
Follow-ups:
MBEDTLS_PK_SIGNATURE_MAX_SIZE.@ -104,0 +125,4 @@#define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE#endif#if defined(MBEDTLS_ECDSA_C) && \These lines appear to unset
MBEDTLS_PK_SIGNATURE_MAX_SIZEand then reset it back toMBEDTLS_MPI_MAX_SIZE. Am I missing something here?@ -928,1 +943,4 @@rnd_std_rand, NULL, rs_ctx ) == sign_ret );if( sign_ret == 0 )TEST_ASSERT( sig_len <= MBEDTLS_PK_SIGNATURE_MAX_SIZE );elseIs is even possible for this to be ever triggered? Won't it be a buffer overflow in such case? Can max(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE) be higher than MBEDTLS_PK_SIGNATURE_MAX_SIZE?
@ -775,2 +775,4 @@*sig_len = rsa_alt->key_len_func( rsa_alt->key );if( *sig_len > MBEDTLS_PK_SIGNATURE_MAX_SIZE )return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );Shouldn't we reset the sig_len in such case?
Shouldn't we reset the sig_len in such case?
@ -928,1 +943,4 @@rnd_std_rand, NULL, rs_ctx ) == sign_ret );if( sign_ret == 0 )TEST_ASSERT( sig_len <= MBEDTLS_PK_SIGNATURE_MAX_SIZE );elseThis can be triggered if
mbedtls_pk_signis buggy, which is the point of a test.mbedtls_pk_signwrites less thanMAX_SIZEbytes to its output buffer but setssig_lento this value, the test fails here. This is a possible failure mode, but not a likely one.mbedtls_pk_signwrites more thanMAX_SIZEbytes to its output buffer, there's a buffer overflow. Since we can't be sure how muchmbedtls_pk_signwill write, the potential buffer overflow if the code is buggy is unavoidable. I could add a safety margin and hope that the overflow doesn't go beyond that, but I don't think it's very useful: ASan detects it nicely (try it out with the commit that adds this test withconfig-suite-b.h).max(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE)can be higher thanMBEDTLS_PK_SIGNATURE_MAX_SIZE, but only if ECDSA or RSA is disabled, or if the definition ofMBEDTLS_PK_SIGNATURE_MAX_SIZEis buggy.@ -775,2 +775,4 @@*sig_len = rsa_alt->key_len_func( rsa_alt->key );if( *sig_len > MBEDTLS_PK_SIGNATURE_MAX_SIZE )return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );*sig_lenis unspecified on error. In the mbedtls API, we usually go for minimal code size and leave whatever was there as long as it isn't sensitive.@ -104,0 +125,4 @@#define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE#endif#if defined(MBEDTLS_ECDSA_C) && \It's a coincidence. The undef/define gymnastic is necessary to redefine the value. While you can express max(…) using C operators, it doesn't scale. It's still ok for max(x1,x2) (
x1 > x2 ? x1 : x2) but it quickly grows unmanageable formax(x1, x2, x3, …).I'll add a comment to explain what's going on.
@ -104,0 +125,4 @@#define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE#endif#if defined(MBEDTLS_ECDSA_C) && \Ah, but no, the code isn't working as intended! It's always setting
MBEDTLS_PK_SIGNATURE_MAX_SIZEto be at leastMBEDTLS_MPI_MAX_SIZE, which I wanted to avoid in the fairly common case whereMBEDTLS_MPI_MAX_SIZEis kept to a large value but RSA signature is disabled andMBEDTLS_PK_SIGNATURE_MAX_SIZEencompasses ECDSA only with a much smaller maximum size.@ -104,0 +125,4 @@#define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE#endif#if defined(MBEDTLS_ECDSA_C) && \Uh, actually, this fallback was working as intended, sort of. It's not a fallback in the sense of “if nothing else is defined”, but something that can arise even if nothing is defined.
Except that the RSA_ALT case can't happen if RSA_ALT is not enabled, so that part was wrong.
@ -104,0 +125,4 @@#define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE#endif#if defined(MBEDTLS_ECDSA_C) && \Fixed.
CI looks pretty unhappy about something in the pk test suite
PSA wrapped sign .................................................. FAILEDTurns out that checking the value of a variable before setting it doesn't work. And locally testing a bunch of “exotic” configuration, but not
full, is not such a good predictor of all configurations working. Who'd'a thunk it.CI says it's still not right. I'll analyze another day.
@AndrzejKurek @dgreen-arm CI passed! Please re-review. I tweaked some commits; the original branch is at https://github.com/gilles-peskine-arm/mbed-crypto/tree/pk_signature_max_size-1.
@ -104,0 +138,4 @@/* PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE is the maximum size of a signature made* through the PSA API in the PSA representation. */#undef MBEDTLS_PK_SIGNATURE_MAX_SIZE#define MBEDTLS_PK_SIGNATURE_MAX_SIZE PSA_ASYMMETRIC_SIGNATURE_MAX_SIZEShouldn't there be a +11 here?
@ -774,6 +774,8 @@ static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,#endif /* SIZE_MAX > UINT_MAX */*sig_len = rsa_alt->key_len_func( rsa_alt->key );if( *sig_len > MBEDTLS_PK_SIGNATURE_MAX_SIZE )What if we support a feature that makes
MBEDTLS_PK_SIGNATURE_MAX_SIZEbigger, but is not needed in this case?You've mentioned that
You may use a smaller buffer if it is large enough given the key type.but we have a generic check here.@ -104,0 +138,4 @@/* PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE is the maximum size of a signature made* through the PSA API in the PSA representation. */#undef MBEDTLS_PK_SIGNATURE_MAX_SIZE#define MBEDTLS_PK_SIGNATURE_MAX_SIZE PSA_ASYMMETRIC_SIGNATURE_MAX_SIZEActually, there shouldn't be a
+ 11above. I've amended the corresponding commit.I'm not adding a non-regression test for this because it's currently impossible: this could only trigger if it was possible to enable a PSA signature method without enabling internal RSA or ECDSA.
@ -774,6 +774,8 @@ static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,#endif /* SIZE_MAX > UINT_MAX */*sig_len = rsa_alt->key_len_func( rsa_alt->key );if( *sig_len > MBEDTLS_PK_SIGNATURE_MAX_SIZE )This is a sanity check. Ideally this function would check that the signature size is less than the buffer size, but this is impossible since it doesn't know the buffer size. The proper fix is to change the API to pass the buffer size, and we're doing this through PSA. At least here an application can choose to use
MAX_SIZEas the buffer size and maybe use too much RAM but be sure that there's no risk of a buffer overflow.I don't see any real potential for improvement here. I could add a separate constant
MBEDTLS_PK_RSA_ALT_SIGNATURE_MAX_SIZE, but what would be the point? The main benefit of using the pk module is to use it without caring about the precise key type. A guarantee which is only valid for a specific key type doesn't help much.