rsa_signature: Use heap memory to allocate DER encoded RSA private key
'mbedtls_pk_psa_rsa_sign_ext' function allocates a buffer of maximum
size 5679 bytes (MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES) on the stack to store
DER encoded private key. This increased stack usage significantly for
RSA signature operations when MBEDTLS_PSA_CRYPTO_C is defined.
This issue was discovered when adding support for EAP-TLS 1.3 (rfc9190).
Signed-off-by: Sarvesh Bodakhe <sarvesh.bodakhe@espressif.com>
diff --git a/ChangeLog.d/use_heap_rsa_signature.txt b/ChangeLog.d/use_heap_rsa_signature.txt
new file mode 100644
index 0000000..e6d7b12
--- /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 4781151..a92c754 100644
--- a/library/pk_wrap.c
+++ b/library/pk_wrap.c
@@ -302,11 +302,16 @@
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;
}
@@ -314,8 +319,9 @@
* 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);
@@ -323,7 +329,7 @@
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);
@@ -339,6 +345,7 @@
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);