Switch psa_{get,set}_domain_parameters to attributes
Change psa_get_domain_parameters() and psa_set_domain_parameters() to
access a psa_key_attributes_t structure rather than a key handle.
In psa_get_key_attributes(), treat the RSA public exponent as a domain
parameter and read it out. This is in preparation for removing the
`extra` parameter of psa_generate_key() and setting the RSA public
exponent for key generation via domain parameters.
In this commit, the default public exponent 65537 is not treated
specially, which allows us to verify that test code that should be
calling psa_reset_key_attributes() after retrieving the attributes of
an RSA key is doing so properly (if it wasn't, there would be a memory
leak), even if the test data happens to use an RSA key with the
default public exponent.
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index c1e3a3f..fba1936 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -983,9 +983,89 @@
void psa_reset_key_attributes( psa_key_attributes_t *attributes )
{
+ mbedtls_free( attributes->domain_parameters );
memset( attributes, 0, sizeof( *attributes ) );
}
+psa_status_t psa_set_key_domain_parameters( psa_key_attributes_t *attributes,
+ psa_key_type_t type,
+ const uint8_t *data,
+ size_t data_length )
+{
+ uint8_t *copy = NULL;
+
+ if( data_length != 0 )
+ {
+ copy = mbedtls_calloc( 1, data_length );
+ if( copy == NULL )
+ return( PSA_ERROR_INSUFFICIENT_MEMORY );
+ memcpy( copy, data, data_length );
+ }
+ /* After this point, this function is guaranteed to succeed, so it
+ * can start modifying `*attributes`. */
+
+ if( attributes->domain_parameters != NULL )
+ {
+ mbedtls_free( attributes->domain_parameters );
+ attributes->domain_parameters = NULL;
+ attributes->domain_parameters_size = 0;
+ }
+
+ attributes->domain_parameters = copy;
+ attributes->domain_parameters_size = data_length;
+ attributes->type = type;
+ return( PSA_SUCCESS );
+}
+
+psa_status_t psa_get_key_domain_parameters(
+ const psa_key_attributes_t *attributes,
+ uint8_t *data, size_t data_size, size_t *data_length )
+{
+ if( attributes->domain_parameters_size > data_size )
+ return( PSA_ERROR_BUFFER_TOO_SMALL );
+ *data_length = attributes->domain_parameters_size;
+ if( attributes->domain_parameters_size != 0 )
+ memcpy( data, attributes->domain_parameters,
+ attributes->domain_parameters_size );
+ return( PSA_SUCCESS );
+}
+
+#if defined(MBEDTLS_RSA_C)
+static psa_status_t psa_get_rsa_public_exponent(
+ const mbedtls_rsa_context *rsa,
+ psa_key_attributes_t *attributes )
+{
+ mbedtls_mpi mpi;
+ int ret;
+ uint8_t *buffer = NULL;
+ size_t buflen;
+ mbedtls_mpi_init( &mpi );
+
+ ret = mbedtls_rsa_export( rsa, NULL, NULL, NULL, NULL, &mpi );
+ if( ret != 0 )
+ goto exit;
+
+ buflen = mbedtls_mpi_size( &mpi );
+ buffer = mbedtls_calloc( 1, buflen );
+ if( buffer == NULL )
+ {
+ ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;
+ goto exit;
+ }
+ ret = mbedtls_mpi_write_binary( &mpi, buffer, buflen );
+ if( ret != 0 )
+ goto exit;
+ attributes->domain_parameters = buffer;
+ attributes->domain_parameters_size = buflen;
+
+exit:
+ mbedtls_mpi_free( &mpi );
+ if( ret != 0 )
+ mbedtls_free( buffer );
+ return( mbedtls_to_psa_error( ret ) );
+}
+#endif /* MBEDTLS_RSA_C */
+
psa_status_t psa_get_key_attributes( psa_key_handle_t handle,
psa_key_attributes_t *attributes )
{
@@ -1003,7 +1083,23 @@
attributes->policy = slot->policy;
attributes->type = slot->type;
attributes->bits = psa_get_key_slot_bits( slot );
- return( PSA_SUCCESS );
+
+ switch( slot->type )
+ {
+#if defined(MBEDTLS_RSA_C)
+ case PSA_KEY_TYPE_RSA_KEYPAIR:
+ case PSA_KEY_TYPE_RSA_PUBLIC_KEY:
+ status = psa_get_rsa_public_exponent( slot->data.rsa, attributes );
+ break;
+#endif
+ default:
+ /* Nothing else to do. */
+ break;
+ }
+
+ if( status != PSA_SUCCESS )
+ psa_reset_key_attributes( attributes );
+ return( status );
}
psa_status_t psa_get_key_information( psa_key_handle_t handle,