Private EC key format: change to raw secret value (doc, import)

Change the import/export format of private elliptic curve keys from
RFC 5915 to the raw secret value. This commit updates the format
specification and the import code, but not the export code.
This commit is contained in:
Gilles Peskine 2018-10-29 19:24:33 +01:00
parent 5b802a366a
commit f76aa7789b
2 changed files with 86 additions and 17 deletions

View file

@ -1343,23 +1343,11 @@ psa_status_t psa_get_key_information(psa_key_slot_t key,
* }
* ```
* - For elliptic curve key pairs (key types for which
* #PSA_KEY_TYPE_IS_ECC_KEYPAIR is true), the format is the
* non-encrypted DER encoding of the representation defined by RFC 5915 as
* `ECPrivateKey`, version 1. The `ECParameters` field must be a
* `namedCurve` OID as specified in RFC 5480 §2.1.1.1. The public key
* must be present and must be an `ECPoint` in the same format
* (uncompressed variant) an ECC public key of the
* corresponding type exported with psa_export_public_key().
* ```
* ECPrivateKey ::= SEQUENCE {
* version INTEGER, -- must be 1
* privateKey OCTET STRING,
* -- `ceiling(log2(n)/8)`-byte string, big endian,
* -- where n is the order of the curve.
* parameters [0] IMPLICIT ECParameters {{ namedCurve }}, -- mandatory
* publicKey [1] IMPLICIT BIT STRING -- mandatory
* }
* ```
* #PSA_KEY_TYPE_IS_ECC_KEYPAIR is true), the format is
* a big-endian representation of the private point as a
* `ceiling(log2(n)/8)`-byte string where `n` is the order of the curve.
* This is the content of the `privateKey` field of the `ECPrivateKey`
* format defined by RFC 5915.
* - For public keys (key types for which #PSA_KEY_TYPE_IS_PUBLIC_KEY is
* true), the format is the same as for psa_export_public_key().
*

View file

@ -262,6 +262,23 @@ static psa_status_t mbedtls_to_psa_error( int ret )
case MBEDTLS_ERR_MD_HW_ACCEL_FAILED:
return( PSA_ERROR_HARDWARE_FAILURE );
case MBEDTLS_ERR_MPI_FILE_IO_ERROR:
return( PSA_ERROR_STORAGE_FAILURE );
case MBEDTLS_ERR_MPI_BAD_INPUT_DATA:
return( PSA_ERROR_INVALID_ARGUMENT );
case MBEDTLS_ERR_MPI_INVALID_CHARACTER:
return( PSA_ERROR_INVALID_ARGUMENT );
case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:
return( PSA_ERROR_BUFFER_TOO_SMALL );
case MBEDTLS_ERR_MPI_NEGATIVE_VALUE:
return( PSA_ERROR_INVALID_ARGUMENT );
case MBEDTLS_ERR_MPI_DIVISION_BY_ZERO:
return( PSA_ERROR_INVALID_ARGUMENT );
case MBEDTLS_ERR_MPI_NOT_ACCEPTABLE:
return( PSA_ERROR_INVALID_ARGUMENT );
case MBEDTLS_ERR_MPI_ALLOC_FAILED:
return( PSA_ERROR_INSUFFICIENT_MEMORY );
case MBEDTLS_ERR_PK_ALLOC_FAILED:
return( PSA_ERROR_INSUFFICIENT_MEMORY );
case MBEDTLS_ERR_PK_TYPE_MISMATCH:
@ -572,6 +589,7 @@ static psa_status_t psa_import_rsa_key( mbedtls_pk_context *pk,
#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C) */
#if defined(MBEDTLS_ECP_C) && defined(MBEDTLS_PK_PARSE_C)
/* Import an elliptic curve parsed by the mbedtls pk module. */
static psa_status_t psa_import_ecp_key( psa_ecc_curve_t expected_curve,
mbedtls_pk_context *pk,
mbedtls_ecp_keypair **p_ecp )
@ -590,6 +608,58 @@ static psa_status_t psa_import_ecp_key( psa_ecc_curve_t expected_curve,
}
#endif /* defined(MBEDTLS_ECP_C) && defined(MBEDTLS_PK_PARSE_C) */
#if defined(MBEDTLS_ECP_C)
/* Import a private key given as a byte string which is the private value
* in big-endian order. */
static psa_status_t psa_import_ec_private_key( psa_ecc_curve_t curve,
const uint8_t *data,
size_t data_length,
mbedtls_ecp_keypair **p_ecp )
{
psa_status_t status = PSA_ERROR_TAMPERING_DETECTED;
mbedtls_ecp_keypair *ecp = NULL;
mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
*p_ecp = NULL;
ecp = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
if( ecp == NULL )
return( PSA_ERROR_INSUFFICIENT_MEMORY );
/* Load the group. */
status = mbedtls_to_psa_error(
mbedtls_ecp_group_load( &ecp->grp, grp_id ) );
if( status != PSA_SUCCESS )
goto exit;
/* Load the secret value. */
status = mbedtls_to_psa_error(
mbedtls_mpi_read_binary( &ecp->d, data, data_length ) );
if( status != PSA_SUCCESS )
goto exit;
/* Validate the private key. */
status = mbedtls_to_psa_error(
mbedtls_ecp_check_privkey( &ecp->grp, &ecp->d ) );
if( status != PSA_SUCCESS )
goto exit;
/* Calculate the public key from the private key. */
status = mbedtls_to_psa_error(
mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
mbedtls_ctr_drbg_random, &global_data.ctr_drbg ) );
if( status != PSA_SUCCESS )
goto exit;
*p_ecp = ecp;
return( PSA_SUCCESS );
exit:
if( ecp != NULL )
{
mbedtls_ecp_keypair_free( ecp );
mbedtls_free( ecp );
}
return( status );
}
#endif /* defined(MBEDTLS_ECP_C) */
psa_status_t psa_import_key( psa_key_slot_t key,
psa_key_type_t type,
const uint8_t *data,
@ -615,6 +685,17 @@ psa_status_t psa_import_key( psa_key_slot_t key,
memcpy( slot->data.raw.data, data, data_length );
}
else
#if defined(MBEDTLS_ECP_C)
if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( type ) )
{
status = psa_import_ec_private_key( PSA_KEY_TYPE_GET_CURVE( type ),
data, data_length,
&slot->data.ecp );
if( status != PSA_SUCCESS )
return( status );
}
else
#endif /* MBEDTLS_ECP_C */
#if defined(MBEDTLS_PK_PARSE_C)
if( PSA_KEY_TYPE_IS_RSA( type ) || PSA_KEY_TYPE_IS_ECC( type ) )
{