diff --git a/ChangeLog.d/use_heap_rsa_signature.txt b/ChangeLog.d/use_heap_rsa_signature.txt new file mode 100644 index 000000000..e6d7b1255 --- /dev/null +++ b/ChangeLog.d/use_heap_rsa_signature.txt @@ -0,0 +1,4 @@ +Changes + * Use heap memory to allocate DER encoded RSA private key. + This reduces stack usage significantly for RSA signature + operations when MBEDTLS_PSA_CRYPTO_C is defined. diff --git a/library/pk_wrap.c b/library/pk_wrap.c index 4d91f22b2..d83ed5983 100644 --- a/library/pk_wrap.c +++ b/library/pk_wrap.c @@ -308,11 +308,16 @@ int mbedtls_pk_psa_rsa_sign_ext(psa_algorithm_t alg, psa_status_t status; mbedtls_pk_context key; int key_len; - unsigned char buf[MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES]; + unsigned char *buf = NULL; + buf = mbedtls_calloc(1, MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES); + if (buf == NULL) { + return MBEDTLS_ERR_PK_ALLOC_FAILED; + } mbedtls_pk_info_t pk_info = mbedtls_rsa_info; *sig_len = mbedtls_rsa_get_len(rsa_ctx); if (sig_size < *sig_len) { + mbedtls_free(buf); return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL; } @@ -320,8 +325,9 @@ int mbedtls_pk_psa_rsa_sign_ext(psa_algorithm_t alg, * re-construct one to make it happy */ key.pk_info = &pk_info; key.pk_ctx = rsa_ctx; - key_len = mbedtls_pk_write_key_der(&key, buf, sizeof(buf)); + key_len = mbedtls_pk_write_key_der(&key, buf, MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES); if (key_len <= 0) { + mbedtls_free(buf); return MBEDTLS_ERR_PK_BAD_INPUT_DATA; } psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); @@ -329,7 +335,7 @@ int mbedtls_pk_psa_rsa_sign_ext(psa_algorithm_t alg, psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR); status = psa_import_key(&attributes, - buf + sizeof(buf) - key_len, key_len, + buf + MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES - key_len, key_len, &key_id); if (status != PSA_SUCCESS) { ret = PSA_PK_TO_MBEDTLS_ERR(status); @@ -345,6 +351,7 @@ int mbedtls_pk_psa_rsa_sign_ext(psa_algorithm_t alg, ret = 0; cleanup: + mbedtls_free(buf); status = psa_destroy_key(key_id); if (ret == 0 && status != PSA_SUCCESS) { ret = PSA_PK_TO_MBEDTLS_ERR(status);