Implement can_do for opaque ECC keypairs

Unfortunately the can_do wrapper does not receive the key context as an
argument, so it cannot check psa_get_key_information(). Later we might want to
change our internal structures to fix this, but for now we'll just restrict
opaque PSA keys to be ECDSA keypairs, as this is the only thing we need for
now. It also simplifies testing a bit (no need to test each key type).
This commit is contained in:
Manuel Pégourié-Gonnard 2018-10-31 10:57:29 +01:00 committed by Hanno Becker
parent 683632b78e
commit 07b103fe07
4 changed files with 38 additions and 5 deletions

View file

@ -249,7 +249,7 @@ int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info );
* \brief Initialize a PK context to wrap a PSA key slot.
*
* \param ctx Context to initialize. Must be empty (type NONE).
* \param key PSA key slot to wrap.
* \param key PSA key slot to wrap - must hold an ECC keypair.
*
* \note The wrapped key slot must remain valid as long as the
* wrapping PK context is in use, that is at least between
@ -257,13 +257,19 @@ int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info );
* mbedtls_pk_free() is called on this context. The wrapped
* key slot might then be independently used or destroyed.
*
* \return 0 on success,
* MBEDTLS_ERR_PK_BAD_INPUT_DATA on invalid input,
* MBEDTLS_ERR_PK_ALLOC_FAILED on allocation failure.
* \return \c 0 on success,
* \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA on invalid input
* (context already used, invalid key slot)
* \return #MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE if the key is not an
* ECC keypair,
* \return #MBEDTLS_ERR_PK_ALLOC_FAILED on allocation failure.
*
* \note This function replaces mbedtls_pk_setup() for contexts
* that wrap a (possibly opaque) PSA key slot instead of
* storing and manipulating the key material directly.
*
* \note This function is currently only available for ECC keypair.
* Support for other key types will be added later.
*/
int mbedtls_pk_setup_psa( mbedtls_pk_context *ctx, const psa_key_slot_t key );
#endif /* MBEDTLS_USE_PSA_CRYPTO */

View file

@ -147,10 +147,18 @@ int mbedtls_pk_setup_psa( mbedtls_pk_context *ctx, const psa_key_slot_t key )
{
const mbedtls_pk_info_t * const info = &mbedtls_pk_opaque_psa_info;
psa_key_slot_t *pk_ctx;
psa_key_type_t type;
if( ctx == NULL || ctx->pk_info != NULL )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
if( PSA_SUCCESS != psa_get_key_information( key, &type, NULL ) )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
/* Current implementation of can_do() relies on this. */
if( ! PSA_KEY_TYPE_IS_ECC_KEYPAIR( type ) )
return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE) ;
if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
return( MBEDTLS_ERR_PK_ALLOC_FAILED );

View file

@ -744,11 +744,20 @@ static size_t pk_psa_get_bitlen( const void *ctx )
return( bits );
}
static int pk_psa_can_do( mbedtls_pk_type_t type )
{
/* For now opaque PSA keys can only wrap ECC keypairs,
* as checked by setup_psa().
* Also, ECKEY_DH does not really make sense with the current API. */
return( type == MBEDTLS_PK_ECKEY ||
type == MBEDTLS_PK_ECDSA );
}
const mbedtls_pk_info_t mbedtls_pk_opaque_psa_info = {
MBEDTLS_PK_OPAQUE_PSA,
"Opaque (PSA)",
pk_psa_get_bitlen,
NULL, /* coming soon: can_do */
pk_psa_can_do,
NULL, /* verify - will be done later */
NULL, /* coming soon: sign */
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)

View file

@ -108,6 +108,12 @@ void pk_psa_utils( )
mbedtls_pk_init( &pk );
TEST_ASSERT( mbedtls_pk_setup_psa( &pk, 0 ) ==
MBEDTLS_ERR_PK_BAD_INPUT_DATA );
mbedtls_pk_free( &pk );
mbedtls_pk_init( &pk );
key = pk_psa_genkey();
TEST_ASSERT( key != 0 );
@ -119,6 +125,10 @@ void pk_psa_utils( )
TEST_ASSERT( mbedtls_pk_get_bitlen( &pk ) == bitlen );
TEST_ASSERT( mbedtls_pk_get_len( &pk ) == bitlen / 8 );
TEST_ASSERT( mbedtls_pk_can_do( &pk, MBEDTLS_PK_ECKEY ) == 1 );
TEST_ASSERT( mbedtls_pk_can_do( &pk, MBEDTLS_PK_ECDSA ) == 1 );
TEST_ASSERT( mbedtls_pk_can_do( &pk, MBEDTLS_PK_RSA ) == 0 );
/* test that freeing the context does not destroy the key */
mbedtls_pk_free( &pk );
TEST_ASSERT( PSA_SUCCESS == psa_destroy_key( key ) );