Merge pull request #9781 from yanesca/remove_USE_PSA_from_API_doc_9632

Remove discussions of MBEDTLS_USE_PSA_CRYPTO in API documentation
diff --git a/ChangeLog.d/add-psa-iop-generate-key.txt b/ChangeLog.d/add-psa-iop-generate-key.txt
new file mode 100644
index 0000000..0f586ee
--- /dev/null
+++ b/ChangeLog.d/add-psa-iop-generate-key.txt
@@ -0,0 +1,3 @@
+Features
+   * Add an interruptible version of generate key to the PSA interface.
+     See psa_generate_key_iop_setup() and related functions.
diff --git a/ChangeLog.d/fix-compilation-with-djgpp.txt b/ChangeLog.d/fix-compilation-with-djgpp.txt
new file mode 100644
index 0000000..5b79fb6
--- /dev/null
+++ b/ChangeLog.d/fix-compilation-with-djgpp.txt
@@ -0,0 +1,2 @@
+Bugfix
+   * Fix compilation on MS-DOS DJGPP. Fixes #9813.
diff --git a/library/net_sockets.c b/library/net_sockets.c
index f752d13..ca70f37 100644
--- a/library/net_sockets.c
+++ b/library/net_sockets.c
@@ -524,8 +524,8 @@
 #else
     struct timeval tv;
     tv.tv_sec  = usec / 1000000;
-#if defined(__unix__) || defined(__unix) || \
-    (defined(__APPLE__) && defined(__MACH__))
+#if (defined(__unix__) || defined(__unix) || \
+    (defined(__APPLE__) && defined(__MACH__))) && !defined(__DJGPP__)
     tv.tv_usec = (suseconds_t) usec % 1000000;
 #else
     tv.tv_usec = usec % 1000000;
diff --git a/tf-psa-crypto/core/psa_crypto.c b/tf-psa-crypto/core/psa_crypto.c
index beb17d5..359d622 100644
--- a/tf-psa-crypto/core/psa_crypto.c
+++ b/tf-psa-crypto/core/psa_crypto.c
@@ -8409,8 +8409,7 @@
 uint32_t psa_generate_key_iop_get_num_ops(
     psa_generate_key_iop_t *operation)
 {
-    (void) operation;
-    return 0;
+    return operation->num_ops;
 }
 
 psa_status_t psa_generate_key_iop_setup(
@@ -8485,6 +8484,8 @@
         goto exit;
     }
 
+    operation->num_ops = mbedtls_psa_generate_key_iop_get_num_ops(&operation->ctx);
+
     status = psa_import_key(&operation->attributes,
                             key_data + (sizeof(key_data) - key_len),
                             key_len,
diff --git a/tf-psa-crypto/drivers/builtin/src/psa_crypto_ecp.c b/tf-psa-crypto/drivers/builtin/src/psa_crypto_ecp.c
index b58587f..f90274e 100644
--- a/tf-psa-crypto/drivers/builtin/src/psa_crypto_ecp.c
+++ b/tf-psa-crypto/drivers/builtin/src/psa_crypto_ecp.c
@@ -596,6 +596,12 @@
 
 #if defined(MBEDTLS_ECP_RESTARTABLE)
 
+uint32_t mbedtls_psa_generate_key_iop_get_num_ops(
+    mbedtls_psa_generate_key_iop_t *operation)
+{
+    return operation->num_ops;
+}
+
 psa_status_t mbedtls_psa_ecp_generate_key_iop_setup(
     mbedtls_psa_generate_key_iop_t *operation,
     const psa_key_attributes_t *attributes)
@@ -639,6 +645,10 @@
         return mbedtls_to_psa_error(status);
     }
 
+    /* Our implementation of key generation only generates the private key
+       which doesn't invlolve any ECC arithmetic operations so number of ops
+       is less than 1 but we round up to 1 to differentiate between num ops of
+       0 which means no work has been done this facilitates testing. */
     operation->num_ops = 1;
 
     status = mbedtls_mpi_write_binary(&operation->ecp.d, key_output, key_output_size);
diff --git a/tf-psa-crypto/drivers/builtin/src/psa_crypto_ecp.h b/tf-psa-crypto/drivers/builtin/src/psa_crypto_ecp.h
index 506516d..261b873 100644
--- a/tf-psa-crypto/drivers/builtin/src/psa_crypto_ecp.h
+++ b/tf-psa-crypto/drivers/builtin/src/psa_crypto_ecp.h
@@ -182,6 +182,17 @@
     uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length);
 
 /**
+ * \brief Get the total number of ops that a key generation operation has taken
+ *        Since it's start.
+ *
+ * \param[in] operation                 The \c mbedtls_psa_generate_key_iop_t to use.
+ *                                      This must be initialized first.
+ * \return Total number of operations.
+ */
+uint32_t mbedtls_psa_generate_key_iop_get_num_ops(
+    mbedtls_psa_generate_key_iop_t *operation);
+
+/**
  * \brief Setup a new interruptible key generation operation.
  *
  *  \param[in] operation                 The \c mbedtls_psa_generate_key_iop_t to use.
diff --git a/tf-psa-crypto/tests/suites/test_suite_psa_crypto.function b/tf-psa-crypto/tests/suites/test_suite_psa_crypto.function
index c555093..00b935b 100644
--- a/tf-psa-crypto/tests/suites/test_suite_psa_crypto.function
+++ b/tf-psa-crypto/tests/suites/test_suite_psa_crypto.function
@@ -10240,6 +10240,9 @@
     psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_key_attributes_t iop_attributes = PSA_KEY_ATTRIBUTES_INIT;
     psa_generate_key_iop_t operation = PSA_GENERATE_KEY_IOP_INIT;
+    size_t num_ops_prior = 0;
+    size_t num_ops = 0;
+
 
     PSA_ASSERT(psa_crypto_init());
 
@@ -10303,8 +10306,26 @@
         goto exit;
     }
 
+    num_ops_prior = psa_generate_key_iop_get_num_ops(&operation);
+    TEST_EQUAL(num_ops_prior, 0);
+
     do {
         status = psa_generate_key_iop_complete(&operation, &iop_key);
+
+        if (status == PSA_SUCCESS || status == PSA_OPERATION_INCOMPLETE) {
+            num_ops = psa_generate_key_iop_get_num_ops(&operation);
+
+            /* Our implementation of key generation only generates the private key
+               which doesn't invlolve any ECC arithmetic operations so number of ops
+               is less than 1 but we round up to 1 to differentiate between num ops of
+               0 which means no work has been done this facilitates testing.
+               It is acceptable however for other implementations to set the number of
+               ops to zero. */
+            TEST_LE_U(num_ops_prior + 1, num_ops);
+
+            num_ops_prior = num_ops;
+        }
+
     } while (status == PSA_OPERATION_INCOMPLETE);
 
     TEST_EQUAL(status, PSA_SUCCESS);
@@ -10319,6 +10340,10 @@
     status = psa_generate_key_iop_complete(&operation, &iop_key);
     TEST_EQUAL(status, PSA_ERROR_BAD_STATE);
 
+    TEST_EQUAL(psa_generate_key_iop_abort(&operation), PSA_SUCCESS);
+    num_ops = psa_generate_key_iop_get_num_ops(&operation);
+    TEST_EQUAL(num_ops, 0);
+
 exit:
     psa_generate_key_iop_abort(&operation);
     /*