Merge pull request #9089 from ronald-cron-arm/add-cve-2024-30166-ref-3.6

[Backport 3.6] ChangeLog: Add missing reference to CVE in security entry
diff --git a/ChangeLog.d/fix-concurrently-loading-non-existent-keys.txt b/ChangeLog.d/fix-concurrently-loading-non-existent-keys.txt
new file mode 100644
index 0000000..8a406a1
--- /dev/null
+++ b/ChangeLog.d/fix-concurrently-loading-non-existent-keys.txt
@@ -0,0 +1,4 @@
+Bugfix
+   * Fix rare concurrent access bug where attempting to operate on a
+     non-existent key while concurrently creating a new key could potentially
+     corrupt the key store.
diff --git a/ChangeLog.d/fix-secure-element-key-creation.txt b/ChangeLog.d/fix-secure-element-key-creation.txt
new file mode 100644
index 0000000..23a46c0
--- /dev/null
+++ b/ChangeLog.d/fix-secure-element-key-creation.txt
@@ -0,0 +1,5 @@
+Bugfix
+   * Fix error handling when creating a key in a dynamic secure element
+     (feature enabled by MBEDTLS_PSA_CRYPTO_SE_C). In a low memory condition,
+     the creation could return PSA_SUCCESS but using or destroying the key
+     would not work. Fixes #8537.
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 0a9011a..02554d1 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -1835,6 +1835,9 @@
 
         status = psa_copy_key_material_into_slot(
             slot, (uint8_t *) (&slot_number), sizeof(slot_number));
+        if (status != PSA_SUCCESS) {
+            return status;
+        }
     }
 
     if (*p_drv == NULL && method == PSA_KEY_CREATION_REGISTER) {
diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c
index b184ed0..9986a44 100644
--- a/library/psa_crypto_slot_management.c
+++ b/library/psa_crypto_slot_management.c
@@ -424,6 +424,8 @@
     if (status != PSA_SUCCESS) {
         psa_wipe_key_slot(*p_slot);
 
+        /* If the key does not exist, we need to return
+         * PSA_ERROR_INVALID_HANDLE. */
         if (status == PSA_ERROR_DOES_NOT_EXIST) {
             status = PSA_ERROR_INVALID_HANDLE;
         }
@@ -440,6 +442,9 @@
     status = PSA_ERROR_INVALID_HANDLE;
 #endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
 
+    if (status != PSA_SUCCESS) {
+        *p_slot = NULL;
+    }
 #if defined(MBEDTLS_THREADING_C)
     PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
                               &mbedtls_threading_key_slot_mutex));
diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h
index bcfc9d8..a84be7d 100644
--- a/library/psa_crypto_slot_management.h
+++ b/library/psa_crypto_slot_management.h
@@ -58,6 +58,9 @@
  * It is the responsibility of the caller to call psa_unregister_read(slot)
  * when they have finished reading the contents of the slot.
  *
+ * On failure, `*p_slot` is set to NULL. This ensures that it is always valid
+ * to call psa_unregister_read on the returned slot.
+ *
  * \param key           Key identifier to query.
  * \param[out] p_slot   On success, `*p_slot` contains a pointer to the
  *                      key slot containing the description of the key
diff --git a/programs/ssl/ssl_mail_client.c b/programs/ssl/ssl_mail_client.c
index febb881..e3ed697 100644
--- a/programs/ssl/ssl_mail_client.c
+++ b/programs/ssl/ssl_mail_client.c
@@ -727,7 +727,11 @@
     mbedtls_printf("  > Write MAIL FROM to server:");
     fflush(stdout);
 
-    len = sprintf((char *) buf, "MAIL FROM:<%s>\r\n", opt.mail_from);
+    len = mbedtls_snprintf((char *) buf, sizeof(buf), "MAIL FROM:<%s>\r\n", opt.mail_from);
+    if (len < 0 || (size_t) len >= sizeof(buf)) {
+        mbedtls_printf(" failed\n  ! mbedtls_snprintf encountered error or truncated output\n\n");
+        goto exit;
+    }
     ret = write_ssl_and_get_response(&ssl, buf, len);
     if (ret < 200 || ret > 299) {
         mbedtls_printf(" failed\n  ! server responded with %d\n\n", ret);
@@ -739,7 +743,11 @@
     mbedtls_printf("  > Write RCPT TO to server:");
     fflush(stdout);
 
-    len = sprintf((char *) buf, "RCPT TO:<%s>\r\n", opt.mail_to);
+    len = mbedtls_snprintf((char *) buf, sizeof(buf), "RCPT TO:<%s>\r\n", opt.mail_to);
+    if (len < 0 || (size_t) len >= sizeof(buf)) {
+        mbedtls_printf(" failed\n  ! mbedtls_snprintf encountered error or truncated output\n\n");
+        goto exit;
+    }
     ret = write_ssl_and_get_response(&ssl, buf, len);
     if (ret < 200 || ret > 299) {
         mbedtls_printf(" failed\n  ! server responded with %d\n\n", ret);
@@ -763,11 +771,16 @@
     mbedtls_printf("  > Write content to server:");
     fflush(stdout);
 
-    len = sprintf((char *) buf, "From: %s\r\nSubject: Mbed TLS Test mail\r\n\r\n"
-                                "This is a simple test mail from the "
-                                "Mbed TLS mail client example.\r\n"
-                                "\r\n"
-                                "Enjoy!", opt.mail_from);
+    len = mbedtls_snprintf((char *) buf, sizeof(buf),
+                           "From: %s\r\nSubject: Mbed TLS Test mail\r\n\r\n"
+                           "This is a simple test mail from the "
+                           "Mbed TLS mail client example.\r\n"
+                           "\r\n"
+                           "Enjoy!", opt.mail_from);
+    if (len < 0 || (size_t) len >= sizeof(buf)) {
+        mbedtls_printf(" failed\n  ! mbedtls_snprintf encountered error or truncated output\n\n");
+        goto exit;
+    }
     ret = write_ssl_data(&ssl, buf, len);
 
     len = sprintf((char *) buf, "\r\n.\r\n");