mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2025-01-11 20:05:37 +00:00
Move export key sanity check from generate to exercise
Move the code to perform sanity checks on the exported key from generate_key to exercise_key. This way the sanity checks can be performed after importing or deriving a key as well. In addition to checking the exported key if its usage allows it, check the exported public key if the key is asymmetric.
This commit is contained in:
parent
1be949b846
commit
d14664a79b
|
@ -393,6 +393,156 @@ exit:
|
|||
return( 0 );
|
||||
}
|
||||
|
||||
int exported_key_sanity_check( psa_key_type_t type, size_t bits,
|
||||
uint8_t *exported, size_t exported_length )
|
||||
{
|
||||
if( key_type_is_raw_bytes( type ) )
|
||||
TEST_ASSERT( exported_length == ( bits + 7 ) / 8 );
|
||||
|
||||
#if defined(MBEDTLS_DES_C)
|
||||
if( type == PSA_KEY_TYPE_DES )
|
||||
{
|
||||
/* Check the parity bits. */
|
||||
unsigned i;
|
||||
for( i = 0; i < bits / 8; i++ )
|
||||
{
|
||||
unsigned bit_count = 0;
|
||||
unsigned m;
|
||||
for( m = 1; m <= 0x100; m <<= 1 )
|
||||
{
|
||||
if( exported[i] & m )
|
||||
++bit_count;
|
||||
}
|
||||
TEST_ASSERT( bit_count % 2 != 0 );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
|
||||
if( type == PSA_KEY_TYPE_RSA_KEYPAIR )
|
||||
{
|
||||
/* Sanity check: does this look like the beginning of a PKCS#8
|
||||
* RSA key pair? Assumes bits is a multiple of 8. */
|
||||
size_t n_bytes = bits / 8 + 1;
|
||||
size_t n_encoded_bytes;
|
||||
unsigned char *n_end;
|
||||
TEST_ASSERT( exported_length >= 7 + ( n_bytes + 3 ) * 9 / 2 );
|
||||
TEST_ASSERT( exported[0] == 0x30 );
|
||||
TEST_ASSERT( exported[1] == 0x82 ); // assumes >=416-bit key
|
||||
TEST_ASSERT( exported[4] == 0x02 );
|
||||
TEST_ASSERT( exported[5] == 0x01 );
|
||||
TEST_ASSERT( exported[6] == 0x00 );
|
||||
TEST_ASSERT( exported[7] == 0x02 );
|
||||
n_encoded_bytes = exported[8];
|
||||
n_end = exported + 9 + n_encoded_bytes;
|
||||
if( n_encoded_bytes & 0x80 )
|
||||
{
|
||||
n_encoded_bytes = ( n_encoded_bytes & 0x7f ) << 7;
|
||||
n_encoded_bytes |= exported[9] & 0x7f;
|
||||
n_end += 1;
|
||||
}
|
||||
/* The encoding of n should start with a 0 byte since it should
|
||||
* have its high bit set. However Mbed TLS is not compliant and
|
||||
* generates an invalid, but widely tolerated, encoding of
|
||||
* positive INTEGERs with a bit size that is a multiple of 8
|
||||
* with no leading 0 byte. Accept this here. */
|
||||
TEST_ASSERT( n_bytes == n_encoded_bytes ||
|
||||
n_bytes == n_encoded_bytes + 1 );
|
||||
if( n_bytes == n_encoded_bytes )
|
||||
TEST_ASSERT( exported[n_encoded_bytes <= 127 ? 9 : 10] == 0x00 );
|
||||
/* Sanity check: e must be 3 */
|
||||
TEST_ASSERT( n_end[0] == 0x02 );
|
||||
TEST_ASSERT( n_end[1] == 0x03 );
|
||||
TEST_ASSERT( n_end[2] == 0x01 );
|
||||
TEST_ASSERT( n_end[3] == 0x00 );
|
||||
TEST_ASSERT( n_end[4] == 0x01 );
|
||||
TEST_ASSERT( n_end[5] == 0x02 );
|
||||
}
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( type ) )
|
||||
{
|
||||
/* Sanity check: does this look like the beginning of a PKCS#8
|
||||
* elliptic curve key pair? */
|
||||
TEST_ASSERT( exported_length >= bits * 3 / 8 + 10 );
|
||||
TEST_ASSERT( exported[0] == 0x30 );
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
|
||||
return( 0 );
|
||||
|
||||
exit:
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
static int exercise_export_key( psa_key_slot_t slot,
|
||||
psa_key_usage_t usage )
|
||||
{
|
||||
psa_key_type_t type;
|
||||
size_t bits;
|
||||
uint8_t *exported = NULL;
|
||||
size_t exported_size = 0;
|
||||
size_t exported_length = 0;
|
||||
int ok = 0;
|
||||
|
||||
if( ( usage & PSA_KEY_USAGE_EXPORT ) == 0 )
|
||||
{
|
||||
TEST_ASSERT( psa_export_key( slot, NULL, 0, &exported_length ) ==
|
||||
PSA_ERROR_NOT_PERMITTED );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
TEST_ASSERT( psa_get_key_information( slot, &type, &bits ) == PSA_SUCCESS );
|
||||
exported_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
|
||||
exported = mbedtls_calloc( 1, exported_size );
|
||||
TEST_ASSERT( exported != NULL );
|
||||
|
||||
TEST_ASSERT( psa_export_key( slot,
|
||||
exported, exported_size,
|
||||
&exported_length ) == PSA_SUCCESS );
|
||||
ok = exported_key_sanity_check( type, bits, exported, exported_length );
|
||||
|
||||
exit:
|
||||
mbedtls_free( exported );
|
||||
return( ok );
|
||||
}
|
||||
|
||||
static int exercise_export_public_key( psa_key_slot_t slot )
|
||||
{
|
||||
psa_key_type_t type;
|
||||
psa_key_type_t public_type;
|
||||
size_t bits;
|
||||
uint8_t *exported = NULL;
|
||||
size_t exported_size = 0;
|
||||
size_t exported_length = 0;
|
||||
int ok = 0;
|
||||
|
||||
TEST_ASSERT( psa_get_key_information( slot, &type, &bits ) == PSA_SUCCESS );
|
||||
if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( type ) )
|
||||
{
|
||||
TEST_ASSERT( psa_export_public_key( slot,
|
||||
NULL, 0, &exported_length ) ==
|
||||
PSA_ERROR_INVALID_ARGUMENT );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( type );
|
||||
exported_size = PSA_KEY_EXPORT_MAX_SIZE( public_type, bits );
|
||||
exported = mbedtls_calloc( 1, exported_size );
|
||||
TEST_ASSERT( exported != NULL );
|
||||
|
||||
TEST_ASSERT( psa_export_public_key( slot,
|
||||
exported, exported_size,
|
||||
&exported_length ) == PSA_SUCCESS );
|
||||
ok = exported_key_sanity_check( public_type, bits,
|
||||
exported, exported_length );
|
||||
|
||||
exit:
|
||||
mbedtls_free( exported );
|
||||
return( ok );
|
||||
}
|
||||
|
||||
static int exercise_key( psa_key_slot_t slot,
|
||||
psa_key_usage_t usage,
|
||||
psa_algorithm_t alg )
|
||||
|
@ -421,6 +571,10 @@ static int exercise_key( psa_key_slot_t slot,
|
|||
test_fail( message, __LINE__, __FILE__ );
|
||||
ok = 0;
|
||||
}
|
||||
|
||||
ok = ok && exercise_export_key( slot, usage );
|
||||
ok = ok && exercise_export_public_key( slot );
|
||||
|
||||
return( ok );
|
||||
}
|
||||
|
||||
|
@ -3056,10 +3210,6 @@ void generate_key( int type_arg,
|
|||
psa_status_t expected_status = expected_status_arg;
|
||||
psa_key_type_t got_type;
|
||||
size_t got_bits;
|
||||
unsigned char exported[616] = {0}; /* enough for a 1024-bit RSA key */
|
||||
size_t exported_length;
|
||||
psa_status_t expected_export_status =
|
||||
usage & PSA_KEY_USAGE_EXPORT ? PSA_SUCCESS : PSA_ERROR_NOT_PERMITTED;
|
||||
psa_status_t expected_info_status =
|
||||
expected_status == PSA_SUCCESS ? PSA_SUCCESS : PSA_ERROR_EMPTY_SLOT;
|
||||
psa_key_policy_t policy;
|
||||
|
@ -3083,84 +3233,6 @@ void generate_key( int type_arg,
|
|||
TEST_ASSERT( got_type == type );
|
||||
TEST_ASSERT( got_bits == bits );
|
||||
|
||||
/* Export the key */
|
||||
TEST_ASSERT( psa_export_key( slot,
|
||||
exported, sizeof( exported ),
|
||||
&exported_length ) == expected_export_status );
|
||||
if( expected_export_status == PSA_SUCCESS )
|
||||
{
|
||||
if( key_type_is_raw_bytes( type ) )
|
||||
TEST_ASSERT( exported_length == ( bits + 7 ) / 8 );
|
||||
#if defined(MBEDTLS_DES_C)
|
||||
if( type == PSA_KEY_TYPE_DES )
|
||||
{
|
||||
/* Check the parity bits. */
|
||||
unsigned i;
|
||||
for( i = 0; i < bits / 8; i++ )
|
||||
{
|
||||
unsigned bit_count = 0;
|
||||
unsigned m;
|
||||
for( m = 1; m <= 0x100; m <<= 1 )
|
||||
{
|
||||
if( exported[i] & m )
|
||||
++bit_count;
|
||||
}
|
||||
TEST_ASSERT( bit_count % 2 != 0 );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
|
||||
if( type == PSA_KEY_TYPE_RSA_KEYPAIR )
|
||||
{
|
||||
/* Sanity check: does this look like the beginning of a PKCS#8
|
||||
* RSA key pair? Assumes bits is a multiple of 8. */
|
||||
size_t n_bytes = bits / 8 + 1;
|
||||
size_t n_encoded_bytes;
|
||||
unsigned char *n_end;
|
||||
TEST_ASSERT( exported_length >= 7 + ( n_bytes + 3 ) * 9 / 2 );
|
||||
TEST_ASSERT( exported[0] == 0x30 );
|
||||
TEST_ASSERT( exported[1] == 0x82 ); // assumes >=416-bit key
|
||||
TEST_ASSERT( exported[4] == 0x02 );
|
||||
TEST_ASSERT( exported[5] == 0x01 );
|
||||
TEST_ASSERT( exported[6] == 0x00 );
|
||||
TEST_ASSERT( exported[7] == 0x02 );
|
||||
n_encoded_bytes = exported[8];
|
||||
n_end = exported + 9 + n_encoded_bytes;
|
||||
if( n_encoded_bytes & 0x80 )
|
||||
{
|
||||
n_encoded_bytes = ( n_encoded_bytes & 0x7f ) << 7;
|
||||
n_encoded_bytes |= exported[9] & 0x7f;
|
||||
n_end += 1;
|
||||
}
|
||||
/* The encoding of n should start with a 0 byte since it should
|
||||
* have its high bit set. However Mbed TLS is not compliant and
|
||||
* generates an invalid, but widely tolerated, encoding of
|
||||
* positive INTEGERs with a bit size that is a multiple of 8
|
||||
* with no leading 0 byte. Accept this here. */
|
||||
TEST_ASSERT( n_bytes == n_encoded_bytes ||
|
||||
n_bytes == n_encoded_bytes + 1 );
|
||||
if( n_bytes == n_encoded_bytes )
|
||||
TEST_ASSERT( exported[n_encoded_bytes <= 127 ? 9 : 10] == 0x00 );
|
||||
/* Sanity check: e must be 3 */
|
||||
TEST_ASSERT( n_end[0] == 0x02 );
|
||||
TEST_ASSERT( n_end[1] == 0x03 );
|
||||
TEST_ASSERT( n_end[2] == 0x01 );
|
||||
TEST_ASSERT( n_end[3] == 0x00 );
|
||||
TEST_ASSERT( n_end[4] == 0x01 );
|
||||
TEST_ASSERT( n_end[5] == 0x02 );
|
||||
}
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
if( PSA_KEY_TYPE_IS_ECC( type ) )
|
||||
{
|
||||
/* Sanity check: does this look like the beginning of a PKCS#8
|
||||
* elliptic curve key pair? */
|
||||
TEST_ASSERT( exported_length >= bits * 3 / 8 + 10 );
|
||||
TEST_ASSERT( exported[0] == 0x30 );
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
}
|
||||
|
||||
/* Do something with the key according to its type and permitted usage. */
|
||||
if( ! exercise_key( slot, usage, alg ) )
|
||||
goto exit;
|
||||
|
|
Loading…
Reference in a new issue