Merge branch 'iotssl-2596-opaque-csr-creation_CRYPTO' into feature-psa-tls-integration-proposed
diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h
index b6f5adc..7f08857 100644
--- a/include/psa/crypto_extra.h
+++ b/include/psa/crypto_extra.h
@@ -48,7 +48,6 @@
 void mbedtls_psa_crypto_free( void );
 
 
-#if ( defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_PSA_HAS_ITS_IO) )
 /**
  * \brief Inject an initial entropy seed for the random generator into
  *        secure storage.
@@ -89,13 +88,20 @@
  *
  * This is an Mbed TLS extension.
  *
- * \param seed[in]      Buffer containing the seed value to inject.
- * \param seed_size     Size of the \p seed buffer.
- *                      The size of the seed in bytes must be greater
- *                      or equal to both #MBEDTLS_ENTROPY_MIN_PLATFORM
- *                      and #MBEDTLS_ENTROPY_BLOCK_SIZE.
- *                      It must be less or equal to
- *                      #MBEDTLS_ENTROPY_MAX_SEED_SIZE.
+ * \note This function is only available on the following platforms:
+ * * If the compile-time options MBEDTLS_ENTROPY_NV_SEED and
+ *   MBEDTLS_PSA_HAS_ITS_IO are both enabled. Note that you
+ *   must provide compatible implementations of mbedtls_nv_seed_read
+ *   and mbedtls_nv_seed_write.
+ * * In a client-server integration of PSA Cryptography, on the client side,
+ *   if the server supports this feature.
+ * \param[in] seed          Buffer containing the seed value to inject.
+ * \param[in] seed_size     Size of the \p seed buffer.
+ *                          The size of the seed in bytes must be greater
+ *                          or equal to both #MBEDTLS_ENTROPY_MIN_PLATFORM
+ *                          and #MBEDTLS_ENTROPY_BLOCK_SIZE.
+ *                          It must be less or equal to
+ *                          #MBEDTLS_ENTROPY_MAX_SEED_SIZE.
  *
  * \retval #PSA_SUCCESS
  *         The seed value was injected successfully. The random generator
@@ -114,7 +120,6 @@
 psa_status_t mbedtls_psa_inject_entropy(const unsigned char *seed,
                                         size_t seed_size);
 
-#endif
 
 #ifdef __cplusplus
 }
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 291dcdb..d100eb1 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -1869,6 +1869,7 @@
     else
 #endif /* MBEDTLS_MD_C */
     {
+        (void) key_bits;
         status = PSA_ERROR_NOT_SUPPORTED;
     }
 
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 87b9ab1..f3bf495 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -84,6 +84,7 @@
 #define DFL_CA_PATH             ""
 #define DFL_CRT_FILE            ""
 #define DFL_KEY_FILE            ""
+#define DFL_KEY_OPAQUE          0
 #define DFL_PSK                 ""
 #define DFL_PSK_IDENTITY        "Client_identity"
 #define DFL_ECJPAKE_PW          NULL
@@ -134,9 +135,16 @@
 #define USAGE_IO \
     "    No file operations available (MBEDTLS_FS_IO not defined)\n"
 #endif /* MBEDTLS_FS_IO */
-#else
+#else /* MBEDTLS_X509_CRT_PARSE_C */
 #define USAGE_IO ""
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
+#if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_X509_CRT_PARSE_C)
+#define USAGE_KEY_OPAQUE \
+    "    key_opaque=%%d       Handle your private key as if it were opaque\n" \
+    "                        default: 0 (disabled)\n"
+#else
+#define USAGE_KEY_OPAQUE ""
+#endif
 
 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
 #define USAGE_PSK                                                   \
@@ -283,6 +291,7 @@
     "    auth_mode=%%s        default: (library default: none)\n" \
     "                        options: none, optional, required\n" \
     USAGE_IO                                                \
+    USAGE_KEY_OPAQUE                                        \
     "\n"                                                    \
     USAGE_PSK                                               \
     USAGE_ECJPAKE                                           \
@@ -337,6 +346,7 @@
     const char *ca_path;        /* the path with the CA certificate(s) reside */
     const char *crt_file;       /* the file with the client certificate     */
     const char *key_file;       /* the file with the client key             */
+    int key_opaque;             /* handle private key as if it were opaque  */
     const char *psk;            /* the pre-shared key                       */
     const char *psk_identity;   /* the pre-shared key identity              */
     const char *ecjpake_pw;     /* the EC J-PAKE password                   */
@@ -556,6 +566,9 @@
     mbedtls_x509_crt cacert;
     mbedtls_x509_crt clicert;
     mbedtls_pk_context pkey;
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+    psa_key_slot_t key_slot = 0; /* invalid key slot */
+#endif
 #endif
     char *p, *q;
     const int *list;
@@ -627,6 +640,7 @@
     opt.ca_path             = DFL_CA_PATH;
     opt.crt_file            = DFL_CRT_FILE;
     opt.key_file            = DFL_KEY_FILE;
+    opt.key_opaque          = DFL_KEY_OPAQUE;
     opt.psk                 = DFL_PSK;
     opt.psk_identity        = DFL_PSK_IDENTITY;
     opt.ecjpake_pw          = DFL_ECJPAKE_PW;
@@ -726,6 +740,10 @@
             opt.crt_file = q;
         else if( strcmp( p, "key_file" ) == 0 )
             opt.key_file = q;
+#if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_X509_CRT_PARSE_C)
+        else if( strcmp( p, "key_opaque" ) == 0 )
+            opt.key_opaque = atoi( q );
+#endif
         else if( strcmp( p, "psk" ) == 0 )
             opt.psk = q;
         else if( strcmp( p, "psk_identity" ) == 0 )
@@ -1309,7 +1327,20 @@
         goto exit;
     }
 
-    mbedtls_printf( " ok\n" );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+    if( opt.key_opaque != 0 )
+    {
+        if( ( ret = mbedtls_pk_wrap_as_opaque( &pkey, &key_slot,
+                                               PSA_ALG_SHA_256 ) ) != 0 )
+        {
+            mbedtls_printf( " failed\n  !  "
+                            "mbedtls_pk_wrap_as_opaque returned -0x%x\n\n", -ret );
+            goto exit;
+        }
+    }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+    mbedtls_printf( " ok (key type: %s)\n", mbedtls_pk_get_name( &pkey ) );
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 
     /*
@@ -2116,6 +2147,9 @@
     mbedtls_x509_crt_free( &clicert );
     mbedtls_x509_crt_free( &cacert );
     mbedtls_pk_free( &pkey );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+    psa_destroy_key( key_slot );
+#endif
 #endif
     mbedtls_ssl_session_free( &saved_session );
     mbedtls_ssl_free( &ssl );
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index ce9aee2..5cded21 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -865,6 +865,21 @@
             -s "Protocol is DTLSv1.2" \
             -s "Ciphersuite is TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256"
 
+# Test using an opaque private key for client authentication
+requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+requires_config_enabled MBEDTLS_X509_CRT_PARSE_C
+requires_config_enabled MBEDTLS_ECDSA_C
+requires_config_enabled MBEDTLS_SHA256_C
+run_test    "Opaque key for client authentication" \
+            "$P_SRV auth_mode=required" \
+            "$P_CLI key_opaque=1 crt_file=data_files/server5.crt \
+             key_file=data_files/server5.key" \
+            0 \
+            -c "key type: Opaque" \
+            -s "Verifying peer X.509 certificate... ok" \
+            -S "error" \
+            -C "error"
+
 # Test current time in ServerHello
 requires_config_enabled MBEDTLS_HAVE_TIME
 run_test    "ServerHello contains gmt_unix_time" \