New API function: psa_key_agreement
Set up a generator from a key agreement.
This commit is contained in:
parent
8feb3a886d
commit
01d718cee8
@ -3191,6 +3191,46 @@ psa_status_t psa_key_derivation(psa_crypto_generator_t *generator,
|
||||
size_t label_length,
|
||||
size_t capacity);
|
||||
|
||||
/** Set up a key agreement operation.
|
||||
*
|
||||
* A key agreement algorithm takes two inputs: a private key \p private_key
|
||||
* a public key \p peer_key.
|
||||
* The result of this function is a byte generator which can
|
||||
* be used to produce keys and other cryptographic material.
|
||||
*
|
||||
* \param[in,out] generator The generator object to set up. It must
|
||||
* have been initialized to all-bits-zero,
|
||||
* a logical zero (`{0}`),
|
||||
* \c PSA_CRYPTO_GENERATOR_INIT or
|
||||
* psa_crypto_generator_init().
|
||||
* \param private_key Slot containing the private key to use.
|
||||
* \param[in] peer_key Public key of the peer.
|
||||
* \param peer_key_length Size of \p peer_key in bytes.
|
||||
* \param alg The key agreement algorithm to compute
|
||||
* (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_KEY_AGREEMENT(\p alg) is true).
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_EMPTY_SLOT
|
||||
* \retval #PSA_ERROR_NOT_PERMITTED
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* \c private_key is not compatible with \c alg,
|
||||
* or \p peer_key is not valid for \c alg or not compatible with
|
||||
* \c private_key.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* \c alg is not supported or is not a key derivation algorithm.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
|
||||
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
|
||||
* \retval #PSA_ERROR_HARDWARE_FAILURE
|
||||
* \retval #PSA_ERROR_TAMPERING_DETECTED
|
||||
*/
|
||||
psa_status_t psa_key_agreement(psa_crypto_generator_t *generator,
|
||||
psa_key_slot_t private_key,
|
||||
const uint8_t *peer_key,
|
||||
size_t peer_key_length,
|
||||
psa_algorithm_t alg);
|
||||
|
||||
/**@}*/
|
||||
|
||||
/** \defgroup random Random generation
|
||||
|
@ -3589,6 +3589,66 @@ psa_status_t psa_key_derivation( psa_crypto_generator_t *generator,
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Key agreement */
|
||||
/****************************************************************/
|
||||
|
||||
#define PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE MBEDTLS_ECP_MAX_BYTES
|
||||
|
||||
static psa_status_t psa_key_agreement_internal( psa_crypto_generator_t *generator,
|
||||
key_slot_t *private_key,
|
||||
const uint8_t *peer_key,
|
||||
size_t peer_key_length,
|
||||
psa_algorithm_t alg )
|
||||
{
|
||||
psa_status_t status;
|
||||
uint8_t shared_secret[PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE];
|
||||
size_t shared_secret_length = 0;
|
||||
|
||||
/* Step 1: run the secret agreement algorithm to generate the shared
|
||||
* secret. */
|
||||
switch( PSA_ALG_KEY_AGREEMENT_GET_BASE( alg ) )
|
||||
{
|
||||
default:
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
}
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
/* Step 2: set up the key derivation to generate key material from
|
||||
* the shared secret. */
|
||||
status = psa_key_derivation_internal( generator,
|
||||
shared_secret, shared_secret_length,
|
||||
PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ),
|
||||
NULL, 0, NULL, 0,
|
||||
PSA_GENERATOR_UNBRIDLED_CAPACITY );
|
||||
exit:
|
||||
mbedtls_zeroize( shared_secret, shared_secret_length );
|
||||
return( status );
|
||||
}
|
||||
|
||||
psa_status_t psa_key_agreement( psa_crypto_generator_t *generator,
|
||||
psa_key_slot_t private_key,
|
||||
const uint8_t *peer_key,
|
||||
size_t peer_key_length,
|
||||
psa_algorithm_t alg )
|
||||
{
|
||||
key_slot_t *slot;
|
||||
psa_status_t status;
|
||||
if( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
status = psa_get_key_from_slot( private_key, &slot,
|
||||
PSA_KEY_USAGE_DERIVE, alg );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
return( psa_key_agreement_internal( generator,
|
||||
slot,
|
||||
peer_key, peer_key_length,
|
||||
alg ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Random generation */
|
||||
/****************************************************************/
|
||||
|
@ -435,6 +435,18 @@ PSA key policy: derive, wrong algorithm
|
||||
depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
|
||||
derive_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_TYPE_DERIVE:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HKDF(PSA_ALG_SHA_224)
|
||||
|
||||
PSA key policy: agreement, permitted
|
||||
depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C
|
||||
agreement_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH(PSA_ALG_SELECT_RAW):PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):"3077020101042049c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eeea00a06082a8648ce3d030107a144034200047772656f814b399279d5e1f1781fac6f099a3c5ca1b0e35351834b08b65e0b572590cdaf8f769361bcf34acfc11e5e074e8426bdde04be6e653945449617de45":PSA_ALG_ECDH(PSA_ALG_SELECT_RAW)
|
||||
|
||||
PSA key policy: agreement, not permitted
|
||||
depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C
|
||||
agreement_key_policy:0:PSA_ALG_ECDH(PSA_ALG_SELECT_RAW):PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):"3077020101042049c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eeea00a06082a8648ce3d030107a144034200047772656f814b399279d5e1f1781fac6f099a3c5ca1b0e35351834b08b65e0b572590cdaf8f769361bcf34acfc11e5e074e8426bdde04be6e653945449617de45":PSA_ALG_ECDH(PSA_ALG_SELECT_RAW)
|
||||
|
||||
PSA key policy: agreement, wrong algorithm
|
||||
depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C
|
||||
agreement_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH(PSA_ALG_SELECT_RAW):PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):"3077020101042049c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eeea00a06082a8648ce3d030107a144034200047772656f814b399279d5e1f1781fac6f099a3c5ca1b0e35351834b08b65e0b572590cdaf8f769361bcf34acfc11e5e074e8426bdde04be6e653945449617de45":PSA_ALG_FFDH(PSA_ALG_SELECT_RAW)
|
||||
|
||||
PSA key lifetime: set and get volatile
|
||||
key_lifetime:PSA_KEY_LIFETIME_VOLATILE
|
||||
|
||||
@ -1525,6 +1537,14 @@ PSA key derivation: HKDF SHA-256, derive key, 1+41
|
||||
depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
|
||||
derive_key_export:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":1:41
|
||||
|
||||
PSA key agreement setup: ECDH, unknown KDF
|
||||
depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C
|
||||
key_agreement_setup:PSA_ALG_ECDH(0):PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):"3078020101042100c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433a00a06082a8648ce3d030107a14403420004dad0b65394221cf9b051e1feca5787d098dfe637fc90b9ef945d0c37725811805271a0461cdb8252d61f1c456fa3e59ab1f45b33accf5f58389e0577b8990bb3":"3059301306072a8648ce3d020106082a8648ce3d03010703420004d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ab":PSA_ERROR_NOT_SUPPORTED
|
||||
|
||||
PSA key agreement setup: not a key agreement algorithm
|
||||
depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C
|
||||
key_agreement_setup:PSA_ALG_HKDF( PSA_ALG_SHA_256 ):PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):"3078020101042100c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433a00a06082a8648ce3d030107a14403420004dad0b65394221cf9b051e1feca5787d098dfe637fc90b9ef945d0c37725811805271a0461cdb8252d61f1c456fa3e59ab1f45b33accf5f58389e0577b8990bb3":"3059301306072a8648ce3d020106082a8648ce3d03010703420004d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ab":PSA_ERROR_INVALID_ARGUMENT
|
||||
|
||||
PSA generate random: 0 bytes
|
||||
generate_random:0
|
||||
|
||||
|
@ -392,6 +392,51 @@ exit:
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int exercise_key_agreement_key( psa_key_slot_t key,
|
||||
psa_key_usage_t usage,
|
||||
psa_algorithm_t alg )
|
||||
{
|
||||
psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
|
||||
psa_key_type_t key_type;
|
||||
psa_key_type_t public_key_type;
|
||||
size_t key_bits;
|
||||
uint8_t *public_key = NULL;
|
||||
size_t public_key_length;
|
||||
unsigned char output[1];
|
||||
int ok = 0;
|
||||
|
||||
if( usage & PSA_KEY_USAGE_DERIVE )
|
||||
{
|
||||
/* We need two keys to exercise key agreement. Exercise the
|
||||
* private key against its own public key. */
|
||||
TEST_ASSERT( psa_get_key_information( key,
|
||||
&key_type,
|
||||
&key_bits ) == PSA_SUCCESS );
|
||||
public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( key_type );
|
||||
public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type,
|
||||
key_bits );
|
||||
public_key = mbedtls_calloc( 1, public_key_length );
|
||||
TEST_ASSERT( public_key != NULL );
|
||||
TEST_ASSERT(
|
||||
psa_export_public_key( key,
|
||||
public_key, public_key_length,
|
||||
&public_key_length ) == PSA_SUCCESS );
|
||||
TEST_ASSERT( psa_key_agreement( &generator,
|
||||
key,
|
||||
public_key, public_key_length,
|
||||
alg ) == PSA_SUCCESS );
|
||||
TEST_ASSERT( psa_generator_read( &generator,
|
||||
output,
|
||||
sizeof( output ) ) == PSA_SUCCESS );
|
||||
TEST_ASSERT( psa_generator_abort( &generator ) == PSA_SUCCESS );
|
||||
}
|
||||
ok = 1;
|
||||
|
||||
exit:
|
||||
mbedtls_free( public_key );
|
||||
return( ok );
|
||||
}
|
||||
|
||||
static int is_oid_of_key_type( psa_key_type_t type,
|
||||
const uint8_t *oid, size_t oid_length )
|
||||
{
|
||||
@ -737,6 +782,8 @@ static int exercise_key( psa_key_slot_t slot,
|
||||
ok = exercise_asymmetric_encryption_key( slot, usage, alg );
|
||||
else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
|
||||
ok = exercise_key_derivation_key( slot, usage, alg );
|
||||
else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
|
||||
ok = exercise_key_agreement_key( slot, usage, alg );
|
||||
else
|
||||
{
|
||||
char message[40];
|
||||
@ -1271,6 +1318,7 @@ void import_and_exercise_key( data_t *data,
|
||||
PSA_KEY_USAGE_ENCRYPT :
|
||||
PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT ) :
|
||||
PSA_ALG_IS_KEY_DERIVATION( alg ) ? PSA_KEY_USAGE_DERIVE :
|
||||
PSA_ALG_IS_KEY_AGREEMENT( alg ) ? PSA_KEY_USAGE_DERIVE :
|
||||
0 );
|
||||
psa_key_policy_t policy;
|
||||
psa_key_type_t got_type;
|
||||
@ -1642,6 +1690,61 @@ exit:
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void agreement_key_policy( int policy_usage,
|
||||
int policy_alg,
|
||||
int key_type_arg,
|
||||
data_t *key_data,
|
||||
int exercise_alg )
|
||||
{
|
||||
int key_slot = 1;
|
||||
psa_key_policy_t policy;
|
||||
psa_key_type_t key_type = key_type_arg;
|
||||
psa_key_type_t public_key_type;
|
||||
size_t key_bits;
|
||||
uint8_t *public_key = NULL;
|
||||
size_t public_key_length;
|
||||
psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
|
||||
psa_status_t status;
|
||||
|
||||
TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
|
||||
|
||||
psa_key_policy_init( &policy );
|
||||
psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
|
||||
TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS );
|
||||
|
||||
TEST_ASSERT( psa_import_key( key_slot, key_type,
|
||||
key_data->x, key_data->len ) == PSA_SUCCESS );
|
||||
|
||||
/* We need two keys to exercise key agreement. Exercise the
|
||||
* private key against its own public key. */
|
||||
TEST_ASSERT( psa_get_key_information( key_slot,
|
||||
&key_type,
|
||||
&key_bits ) == PSA_SUCCESS );
|
||||
public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( key_type );
|
||||
public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
|
||||
public_key = mbedtls_calloc( 1, public_key_length );
|
||||
TEST_ASSERT( public_key != NULL );
|
||||
TEST_ASSERT( psa_export_public_key( key_slot,
|
||||
public_key, public_key_length,
|
||||
&public_key_length ) == PSA_SUCCESS );
|
||||
|
||||
status = psa_key_agreement( &generator, key_slot,
|
||||
public_key, public_key_length,
|
||||
exercise_alg );
|
||||
if( policy_alg == exercise_alg &&
|
||||
( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
|
||||
TEST_ASSERT( status == PSA_SUCCESS );
|
||||
else
|
||||
TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED );
|
||||
|
||||
exit:
|
||||
psa_generator_abort( &generator );
|
||||
psa_destroy_key( key_slot );
|
||||
mbedtls_psa_crypto_free( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void key_lifetime( int lifetime_arg )
|
||||
{
|
||||
@ -3655,6 +3758,39 @@ exit:
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void key_agreement_setup( int alg_arg,
|
||||
int our_key_type_arg, data_t *our_key_data,
|
||||
data_t *peer_key_data,
|
||||
int expected_status_arg )
|
||||
{
|
||||
psa_key_slot_t our_key = 1;
|
||||
psa_algorithm_t alg = alg_arg;
|
||||
psa_key_type_t our_key_type = our_key_type_arg;
|
||||
psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
|
||||
psa_key_policy_t policy;
|
||||
|
||||
TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
|
||||
|
||||
psa_key_policy_init( &policy );
|
||||
psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
|
||||
TEST_ASSERT( psa_set_key_policy( our_key, &policy ) == PSA_SUCCESS );
|
||||
TEST_ASSERT( psa_import_key( our_key, our_key_type,
|
||||
our_key_data->x,
|
||||
our_key_data->len ) == PSA_SUCCESS );
|
||||
|
||||
TEST_ASSERT( psa_key_agreement( &generator,
|
||||
our_key,
|
||||
peer_key_data->x, peer_key_data->len,
|
||||
alg ) == expected_status_arg );
|
||||
|
||||
exit:
|
||||
psa_generator_abort( &generator );
|
||||
psa_destroy_key( our_key );
|
||||
mbedtls_psa_crypto_free( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void generate_random( int bytes_arg )
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user