mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-03-29 13:20:21 +00:00
Merge pull request #8041 from mpg/tfm-p256m
Test TF-M config with p256-m driver
This commit is contained in:
commit
5edb942708
45
3rdparty/p256-m/p256-m/p256-m.c
vendored
45
3rdparty/p256-m/p256-m/p256-m.c
vendored
@ -1466,4 +1466,49 @@ int p256_ecdsa_verify(const uint8_t sig[64], const uint8_t pub[64],
|
||||
return P256_INVALID_SIGNATURE;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Key management utilities
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
int p256_validate_pubkey(const uint8_t pub[64])
|
||||
{
|
||||
uint32_t x[8], y[8];
|
||||
int ret = point_from_bytes(x, y, pub);
|
||||
|
||||
return ret == 0 ? P256_SUCCESS : P256_INVALID_PUBKEY;
|
||||
}
|
||||
|
||||
int p256_validate_privkey(const uint8_t priv[32])
|
||||
{
|
||||
uint32_t s[8];
|
||||
int ret = scalar_from_bytes(s, priv);
|
||||
zeroize(s, sizeof(s));
|
||||
|
||||
return ret == 0 ? P256_SUCCESS : P256_INVALID_PRIVKEY;
|
||||
}
|
||||
|
||||
int p256_public_from_private(uint8_t pub[64], const uint8_t priv[32])
|
||||
{
|
||||
int ret;
|
||||
uint32_t s[8];
|
||||
|
||||
ret = scalar_from_bytes(s, priv);
|
||||
if (ret != 0)
|
||||
return P256_INVALID_PRIVKEY;
|
||||
|
||||
/* compute and ouput the associated public key */
|
||||
uint32_t x[8], y[8];
|
||||
scalar_mult(x, y, p256_gx, p256_gy, s);
|
||||
|
||||
/* the associated public key is not a secret, the scalar was */
|
||||
CT_UNPOISON(x, 32);
|
||||
CT_UNPOISON(y, 32);
|
||||
zeroize(s, sizeof(s));
|
||||
|
||||
point_to_bytes(pub, x, y);
|
||||
return P256_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
39
3rdparty/p256-m/p256-m/p256-m.h
vendored
39
3rdparty/p256-m/p256-m/p256-m.h
vendored
@ -89,6 +89,45 @@ int p256_ecdsa_sign(uint8_t sig[64], const uint8_t priv[32],
|
||||
int p256_ecdsa_verify(const uint8_t sig[64], const uint8_t pub[64],
|
||||
const uint8_t *hash, size_t hlen);
|
||||
|
||||
/*
|
||||
* Public key validation
|
||||
*
|
||||
* Note: you never need to call this function, as all other functions always
|
||||
* validate their input; however it's availabe if you want to validate the key
|
||||
* without performing an operation.
|
||||
*
|
||||
* [in] pub: the public key, as two big-endian integers
|
||||
*
|
||||
* return: P256_SUCCESS if the key is valid
|
||||
* P256_INVALID_PUBKEY if pub is invalid
|
||||
*/
|
||||
int p256_validate_pubkey(const uint8_t pub[64]);
|
||||
|
||||
/*
|
||||
* Private key validation
|
||||
*
|
||||
* Note: you never need to call this function, as all other functions always
|
||||
* validate their input; however it's availabe if you want to validate the key
|
||||
* without performing an operation.
|
||||
*
|
||||
* [in] priv: the private key, as a big-endian integer
|
||||
*
|
||||
* return: P256_SUCCESS if the key is valid
|
||||
* P256_INVALID_PRIVKEY if priv is invalid
|
||||
*/
|
||||
int p256_validate_privkey(const uint8_t priv[32]);
|
||||
|
||||
/*
|
||||
* Compute public key from private key
|
||||
*
|
||||
* [out] pub: the associated public key, as two big-endian integers
|
||||
* [in] priv: the private key, as a big-endian integer
|
||||
*
|
||||
* return: P256_SUCCESS on success
|
||||
* P256_INVALID_PRIVKEY if priv is invalid
|
||||
*/
|
||||
int p256_public_from_private(uint8_t pub[64], const uint8_t priv[32]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
184
3rdparty/p256-m/p256-m_driver_entrypoints.c
vendored
184
3rdparty/p256-m/p256-m_driver_entrypoints.c
vendored
@ -24,6 +24,7 @@
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_crypto_driver_wrappers.h"
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED)
|
||||
|
||||
@ -37,10 +38,20 @@
|
||||
* total of 65 bytes.
|
||||
*
|
||||
* p256-m's internal format for private keys matches PSA. Its format for public
|
||||
* keys is only 64 bytes; the same as PSA but without the leading byte (0x04).
|
||||
* keys is only 64 bytes: the same as PSA but without the leading byte (0x04).
|
||||
* Hence, when passing public keys from PSA to p256-m, the leading byte is
|
||||
* removed.
|
||||
*
|
||||
* Shared secret and signature have the same format between PSA and p256-m.
|
||||
*/
|
||||
#define PSA_PUBKEY_SIZE 65
|
||||
#define PSA_PUBKEY_HEADER_BYTE 0x04
|
||||
#define P256_PUBKEY_SIZE 64
|
||||
#define PRIVKEY_SIZE 32
|
||||
#define SHARED_SECRET_SIZE 32
|
||||
#define SIGNATURE_SIZE 64
|
||||
|
||||
#define CURVE_BITS 256
|
||||
|
||||
/* Convert between p256-m and PSA error codes */
|
||||
static psa_status_t p256_to_psa_error(int ret)
|
||||
@ -59,6 +70,83 @@ static psa_status_t p256_to_psa_error(int ret)
|
||||
}
|
||||
}
|
||||
|
||||
psa_status_t p256_transparent_import_key(const psa_key_attributes_t *attributes,
|
||||
const uint8_t *data,
|
||||
size_t data_length,
|
||||
uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
size_t *key_buffer_length,
|
||||
size_t *bits)
|
||||
{
|
||||
/* Check the key size */
|
||||
if (*bits != 0 && *bits != CURVE_BITS) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* Validate the key (and its type and size) */
|
||||
psa_key_type_t type = psa_get_key_type(attributes);
|
||||
if (type == PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1)) {
|
||||
if (data_length != PSA_PUBKEY_SIZE) {
|
||||
return *bits == 0 ? PSA_ERROR_NOT_SUPPORTED : PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
/* See INFORMATION ON PSA KEY EXPORT FORMATS near top of file */
|
||||
if (p256_validate_pubkey(data + 1) != P256_SUCCESS) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
} else if (type == PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)) {
|
||||
if (data_length != PRIVKEY_SIZE) {
|
||||
return *bits == 0 ? PSA_ERROR_NOT_SUPPORTED : PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (p256_validate_privkey(data) != P256_SUCCESS) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
} else {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
*bits = CURVE_BITS;
|
||||
|
||||
/* We only support the export format for input, so just copy. */
|
||||
if (key_buffer_size < data_length) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
memcpy(key_buffer, data, data_length);
|
||||
*key_buffer_length = data_length;
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t p256_transparent_export_public_key(const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
uint8_t *data,
|
||||
size_t data_size,
|
||||
size_t *data_length)
|
||||
{
|
||||
/* Is this the right curve? */
|
||||
size_t bits = psa_get_key_bits(attributes);
|
||||
psa_key_type_t type = psa_get_key_type(attributes);
|
||||
if (bits != CURVE_BITS || type != PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* Validate sizes, as p256-m expects fixed-size buffers */
|
||||
if (key_buffer_size != PRIVKEY_SIZE) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (data_size < PSA_PUBKEY_SIZE) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
/* See INFORMATION ON PSA KEY EXPORT FORMATS near top of file */
|
||||
data[0] = PSA_PUBKEY_HEADER_BYTE;
|
||||
int ret = p256_public_from_private(data + 1, key_buffer);
|
||||
if (ret == P256_SUCCESS) {
|
||||
*data_length = PSA_PUBKEY_SIZE;
|
||||
}
|
||||
|
||||
return p256_to_psa_error(ret);
|
||||
}
|
||||
|
||||
psa_status_t p256_transparent_generate_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
uint8_t *key_buffer,
|
||||
@ -69,13 +157,9 @@ psa_status_t p256_transparent_generate_key(
|
||||
* of driver entry-points. (void) used to avoid compiler warning. */
|
||||
(void) attributes;
|
||||
|
||||
psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
|
||||
|
||||
/*
|
||||
* p256-m generates a 32 byte private key, and expects to write to a buffer
|
||||
* that is of that size. */
|
||||
if (key_buffer_size != 32) {
|
||||
return status;
|
||||
/* Validate sizes, as p256-m expects fixed-size buffers */
|
||||
if (key_buffer_size != PRIVKEY_SIZE) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -83,15 +167,14 @@ psa_status_t p256_transparent_generate_key(
|
||||
* keys. Allocate a buffer to which the public key will be written. The
|
||||
* private key will be written to key_buffer, which is passed to this
|
||||
* function as an argument. */
|
||||
uint8_t public_key_buffer[64];
|
||||
uint8_t public_key_buffer[P256_PUBKEY_SIZE];
|
||||
|
||||
status = p256_to_psa_error(
|
||||
p256_gen_keypair(key_buffer, public_key_buffer));
|
||||
if (status == PSA_SUCCESS) {
|
||||
*key_buffer_length = 32;
|
||||
int ret = p256_gen_keypair(key_buffer, public_key_buffer);
|
||||
if (ret == P256_SUCCESS) {
|
||||
*key_buffer_length = PRIVKEY_SIZE;
|
||||
}
|
||||
|
||||
return status;
|
||||
return p256_to_psa_error(ret);
|
||||
}
|
||||
|
||||
psa_status_t p256_transparent_key_agreement(
|
||||
@ -111,25 +194,22 @@ psa_status_t p256_transparent_key_agreement(
|
||||
(void) attributes;
|
||||
(void) alg;
|
||||
|
||||
/*
|
||||
* Check that private key = 32 bytes, peer public key = 65 bytes,
|
||||
* and that the shared secret buffer is big enough. */
|
||||
psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
|
||||
if (key_buffer_size != 32 || shared_secret_size < 32 ||
|
||||
peer_key_length != 65) {
|
||||
return status;
|
||||
/* Validate sizes, as p256-m expects fixed-size buffers */
|
||||
if (key_buffer_size != PRIVKEY_SIZE || peer_key_length != PSA_PUBKEY_SIZE) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (shared_secret_size < SHARED_SECRET_SIZE) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
/* We add 1 to peer_key pointer to omit the leading byte of the public key
|
||||
* representation (0x04). See information about PSA key formats at the top
|
||||
* of the file. */
|
||||
status = p256_to_psa_error(
|
||||
p256_ecdh_shared_secret(shared_secret, key_buffer, peer_key+1));
|
||||
if (status == PSA_SUCCESS) {
|
||||
*shared_secret_length = 32;
|
||||
/* See INFORMATION ON PSA KEY EXPORT FORMATS near top of file */
|
||||
const uint8_t *peer_key_p256m = peer_key + 1;
|
||||
int ret = p256_ecdh_shared_secret(shared_secret, key_buffer, peer_key_p256m);
|
||||
if (ret == P256_SUCCESS) {
|
||||
*shared_secret_length = SHARED_SECRET_SIZE;
|
||||
}
|
||||
|
||||
return status;
|
||||
return p256_to_psa_error(ret);
|
||||
}
|
||||
|
||||
psa_status_t p256_transparent_sign_hash(
|
||||
@ -149,21 +229,23 @@ psa_status_t p256_transparent_sign_hash(
|
||||
(void) attributes;
|
||||
(void) alg;
|
||||
|
||||
psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
|
||||
if (key_buffer_size != 32 || signature_size != 64) {
|
||||
return status;
|
||||
/* Validate sizes, as p256-m expects fixed-size buffers */
|
||||
if (key_buffer_size != PRIVKEY_SIZE) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (signature_size < SIGNATURE_SIZE) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
status = p256_to_psa_error(
|
||||
p256_ecdsa_sign(signature, key_buffer, hash, hash_length));
|
||||
if (status == PSA_SUCCESS) {
|
||||
*signature_length = 64;
|
||||
int ret = p256_ecdsa_sign(signature, key_buffer, hash, hash_length);
|
||||
if (ret == P256_SUCCESS) {
|
||||
*signature_length = SIGNATURE_SIZE;
|
||||
}
|
||||
|
||||
return status;
|
||||
return p256_to_psa_error(ret);
|
||||
}
|
||||
|
||||
/* This function expects the key buffer to contain a 65 byte public key,
|
||||
/* This function expects the key buffer to contain a PSA public key,
|
||||
* as exported by psa_export_public_key() */
|
||||
static psa_status_t p256_verify_hash_with_public_key(
|
||||
const uint8_t *key_buffer,
|
||||
@ -173,19 +255,19 @@ static psa_status_t p256_verify_hash_with_public_key(
|
||||
const uint8_t *signature,
|
||||
size_t signature_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
|
||||
if (key_buffer_size != 65 || signature_length != 64 || *key_buffer != 0x04) {
|
||||
return status;
|
||||
/* Validate sizes, as p256-m expects fixed-size buffers */
|
||||
if (key_buffer_size != PSA_PUBKEY_SIZE || *key_buffer != PSA_PUBKEY_HEADER_BYTE) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (signature_length != SIGNATURE_SIZE) {
|
||||
return PSA_ERROR_INVALID_SIGNATURE;
|
||||
}
|
||||
|
||||
/* We add 1 to public_key_buffer pointer to omit the leading byte of the
|
||||
* public key representation (0x04). See information about PSA key formats
|
||||
* at the top of the file. */
|
||||
const uint8_t *public_key_buffer = key_buffer + 1;
|
||||
status = p256_to_psa_error(
|
||||
p256_ecdsa_verify(signature, public_key_buffer, hash, hash_length));
|
||||
/* See INFORMATION ON PSA KEY EXPORT FORMATS near top of file */
|
||||
const uint8_t *public_key_p256m = key_buffer + 1;
|
||||
int ret = p256_ecdsa_verify(signature, public_key_p256m, hash, hash_length);
|
||||
|
||||
return status;
|
||||
return p256_to_psa_error(ret);
|
||||
}
|
||||
|
||||
psa_status_t p256_transparent_verify_hash(
|
||||
@ -203,10 +285,10 @@ psa_status_t p256_transparent_verify_hash(
|
||||
(void) alg;
|
||||
|
||||
psa_status_t status;
|
||||
uint8_t public_key_buffer[65];
|
||||
size_t public_key_buffer_size = 65;
|
||||
uint8_t public_key_buffer[PSA_PUBKEY_SIZE];
|
||||
size_t public_key_buffer_size = PSA_PUBKEY_SIZE;
|
||||
|
||||
size_t public_key_length = 65;
|
||||
size_t public_key_length = PSA_PUBKEY_SIZE;
|
||||
/* As p256-m doesn't require dynamic allocation, we want to avoid it in
|
||||
* the entrypoint functions as well. psa_driver_wrapper_export_public_key()
|
||||
* requires size_t*, so we use a pointer to a stack variable. */
|
||||
|
99
3rdparty/p256-m/p256-m_driver_entrypoints.h
vendored
99
3rdparty/p256-m/p256-m_driver_entrypoints.h
vendored
@ -29,6 +29,66 @@
|
||||
|
||||
#include "psa/crypto_types.h"
|
||||
|
||||
/** Import SECP256R1 key.
|
||||
*
|
||||
* \param[in] attributes The attributes of the key to use for the
|
||||
* operation.
|
||||
* \param[in] data The raw key material. For private keys
|
||||
* this must be a big-endian integer of 32
|
||||
* bytes; for public key this must be an
|
||||
* uncompressed ECPoint (65 bytes).
|
||||
* \param[in] data_length The size of the raw key material.
|
||||
* \param[out] key_buffer The buffer to contain the key data in
|
||||
* output format upon successful return.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param[out] key_buffer_length The length of the data written in \p
|
||||
* key_buffer in bytes.
|
||||
* \param[out] bits The bitsize of the key.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success. Keypair generated and stored in buffer.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* The input is not supported by this driver (not SECP256R1).
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* The input is invalid.
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* \p key_buffer_size is too small.
|
||||
*/
|
||||
psa_status_t p256_transparent_import_key(const psa_key_attributes_t *attributes,
|
||||
const uint8_t *data,
|
||||
size_t data_length,
|
||||
uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
size_t *key_buffer_length,
|
||||
size_t *bits);
|
||||
|
||||
/** Export SECP256R1 public key, from the private key.
|
||||
*
|
||||
* \param[in] attributes The attributes of the key to use for the
|
||||
* operation.
|
||||
* \param[in] key_buffer The private key in the export format.
|
||||
* \param[in] key_buffer_size The size of the private key in bytes.
|
||||
* \param[out] data The buffer to contain the public key in
|
||||
* the export format upon successful return.
|
||||
* \param[in] data_size The size of the \p data buffer in bytes.
|
||||
* \param[out] data_length The length written to \p data in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success. Keypair generated and stored in buffer.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* The input is not supported by this driver (not SECP256R1).
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* The input is invalid.
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* \p key_buffer_size is too small.
|
||||
*/
|
||||
psa_status_t p256_transparent_export_public_key(const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
uint8_t *data,
|
||||
size_t data_size,
|
||||
size_t *data_length);
|
||||
|
||||
/** Generate SECP256R1 ECC Key Pair.
|
||||
* Interface function which calls the p256-m key generation function and
|
||||
* places it in the key buffer provided by the caller (Mbed TLS) in the
|
||||
@ -44,9 +104,10 @@
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success. Keypair generated and stored in buffer.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* \retval #PSA_ERROR_GENERIC_ERROR
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* \p key_buffer_size is too small.
|
||||
* \retval #PSA_ERROR_GENERIC_ERROR
|
||||
* The internal RNG failed.
|
||||
*/
|
||||
psa_status_t p256_transparent_generate_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
@ -72,9 +133,12 @@ psa_status_t p256_transparent_generate_key(
|
||||
* bytes.
|
||||
* \param[out] shared_secret_length On success, the number of bytes that
|
||||
* make up the returned shared secret.
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success. Shared secret successfully calculated.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success. Shared secret successfully calculated.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* The input is invalid.
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* \p shared_secret_size is too small.
|
||||
*/
|
||||
psa_status_t p256_transparent_key_agreement(
|
||||
const psa_key_attributes_t *attributes,
|
||||
@ -103,10 +167,14 @@ psa_status_t p256_transparent_key_agreement(
|
||||
* \param[out] signature_length On success, the number of bytes
|
||||
* that make up the returned signature value.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success. Hash was signed successfully.
|
||||
* respectively of the key.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* The input is invalid.
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* \p signature_size is too small.
|
||||
* \retval #PSA_ERROR_GENERIC_ERROR
|
||||
* The internal RNG failed.
|
||||
*/
|
||||
psa_status_t p256_transparent_sign_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
@ -142,12 +210,13 @@ psa_status_t p256_transparent_sign_hash(
|
||||
* \param[in] signature Buffer containing the signature to verify.
|
||||
* \param[in] signature_length Size of the \p signature buffer in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The signature is valid.
|
||||
* \retval #PSA_ERROR_INVALID_SIGNATURE
|
||||
* The calculation was performed successfully, but the passed
|
||||
* signature is not a valid signature.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* \retval #PSA_SUCCESS
|
||||
* The signature is valid.
|
||||
* \retval #PSA_ERROR_INVALID_SIGNATURE
|
||||
* The calculation was performed successfully, but the passed
|
||||
* signature is not a valid signature.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* The input is invalid.
|
||||
*/
|
||||
psa_status_t p256_transparent_verify_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
|
@ -173,11 +173,11 @@ typedef struct mbedtls_pk_rsassa_pss_options {
|
||||
|
||||
/* Internal helper to define which fields in the pk_context structure below
|
||||
* should be used for EC keys: legacy ecp_keypair or the raw (PSA friendly)
|
||||
* format. It should be noticed that this only affects how data is stored, not
|
||||
* format. It should be noted that this only affects how data is stored, not
|
||||
* which functions are used for various operations. The overall picture looks
|
||||
* like this:
|
||||
* - if USE_PSA is not defined and ECP_C is then use ecp_keypair data structure
|
||||
* and legacy functions
|
||||
* - if USE_PSA is not defined and ECP_C is defined then use ecp_keypair data
|
||||
* structure and legacy functions
|
||||
* - if USE_PSA is defined and
|
||||
* - if ECP_C then use ecp_keypair structure, convert data to a PSA friendly
|
||||
* format and use PSA functions
|
||||
@ -185,13 +185,13 @@ typedef struct mbedtls_pk_rsassa_pss_options {
|
||||
*
|
||||
* The main reason for the "intermediate" (USE_PSA + ECP_C) above is that as long
|
||||
* as ECP_C is defined mbedtls_pk_ec() gives the user a read/write access to the
|
||||
* ecp_keypair structure inside the pk_context so he/she can modify it using
|
||||
* ecp_keypair structure inside the pk_context so they can modify it using
|
||||
* ECP functions which are not under PK module's control.
|
||||
*/
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) && \
|
||||
!defined(MBEDTLS_ECP_C)
|
||||
#define MBEDTLS_PK_USE_PSA_EC_DATA
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_ECP_C */
|
||||
#endif
|
||||
|
||||
/* Helper symbol to state that the PK module has support for EC keys. This
|
||||
* can either be provided through the legacy ECP solution or through the
|
||||
@ -200,28 +200,6 @@ typedef struct mbedtls_pk_rsassa_pss_options {
|
||||
#define MBEDTLS_PK_HAVE_ECC_KEYS
|
||||
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA || MBEDTLS_ECP_C */
|
||||
|
||||
/* Internal helper to define which fields in the pk_context structure below
|
||||
* should be used for EC keys: legacy ecp_keypair or the raw (PSA friendly)
|
||||
* format. It should be noted that this only affect how data is stored, not
|
||||
* which functions are used for various operations. The overall picture looks
|
||||
* like this:
|
||||
* - if USE_PSA is not defined and ECP_C is then use ecp_keypair data structure
|
||||
* and legacy functions
|
||||
* - if USE_PSA is defined and
|
||||
* - if ECP_C then use ecp_keypair structure, convert data to a PSA friendly
|
||||
* format and use PSA functions
|
||||
* - if !ECP_C then use new raw data and PSA functions directly.
|
||||
*
|
||||
* The main reason for the "intermediate" (USE_PSA + ECP_C) above is that as long
|
||||
* as ECP_C is defined mbedtls_pk_ec() gives the user read/write access to the
|
||||
* ecp_keypair structure inside the pk_context so they can modify it using
|
||||
* ECP functions which are not under the PK module's control.
|
||||
*/
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) && \
|
||||
!defined(MBEDTLS_ECP_C)
|
||||
#define MBEDTLS_PK_USE_PSA_EC_DATA
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_ECP_C */
|
||||
|
||||
/**
|
||||
* \brief Types for interfacing with the debug module
|
||||
*/
|
||||
|
@ -1 +1 @@
|
||||
["mbedtls_test_opaque_driver.json","mbedtls_test_transparent_driver.json"]
|
||||
["mbedtls_test_opaque_driver.json","mbedtls_test_transparent_driver.json","p256_transparent_driver.json"]
|
||||
|
20
scripts/data_files/driver_jsons/p256_transparent_driver.json
Normal file
20
scripts/data_files/driver_jsons/p256_transparent_driver.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"prefix": "p256",
|
||||
"type": "transparent",
|
||||
"mbedtls/h_condition": "defined(MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED)",
|
||||
"headers": ["../3rdparty/p256-m/p256-m_driver_entrypoints.h"],
|
||||
"capabilities": [
|
||||
{
|
||||
"mbedtls/c_condition": "defined(MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED)",
|
||||
"_comment_entry_points": "This is not the complete list of entry points supported by this driver, only those that are currently supported in JSON. See docs/psa-driver-example-and-guide.md",
|
||||
"entry_points": ["import_key", "export_public_key"],
|
||||
"algorithms": ["PSA_ALG_ECDH", "PSA_ALG_ECDSA(PSA_ALG_ANY_HASH)"],
|
||||
"key_types": [
|
||||
"PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)",
|
||||
"PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1)"
|
||||
],
|
||||
"key_sizes": [256],
|
||||
"fallback": false
|
||||
}
|
||||
]
|
||||
}
|
@ -2884,6 +2884,105 @@ component_test_psa_crypto_config_reference_ecc_ffdh_no_bignum () {
|
||||
common_test_psa_crypto_config_reference_ecc_ffdh_no_bignum "ECC_DH"
|
||||
}
|
||||
|
||||
# Helper for setting common configurations between:
|
||||
# - component_test_tfm_config_p256m_driver_accel_ec()
|
||||
# - component_test_tfm_config()
|
||||
common_tfm_config () {
|
||||
# Enable TF-M config
|
||||
cp configs/tfm_mbedcrypto_config_profile_medium.h "$CONFIG_H"
|
||||
cp configs/crypto_config_profile_medium.h "$CRYPTO_CONFIG_H"
|
||||
|
||||
# Adjust for the fact that we're building outside the TF-M environment.
|
||||
#
|
||||
# TF-M has separation, our build doesn't
|
||||
scripts/config.py unset MBEDTLS_PSA_CRYPTO_SPM
|
||||
scripts/config.py unset MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
|
||||
# TF-M provdes its own (dummy) implemenation, from their tree
|
||||
scripts/config.py unset MBEDTLS_AES_DECRYPT_ALT
|
||||
scripts/config.py unset MBEDTLS_AES_SETKEY_DEC_ALT
|
||||
# We have an OS that provides entropy, use it
|
||||
scripts/config.py unset MBEDTLS_NO_PLATFORM_ENTROPY
|
||||
|
||||
# Other config adjustments to make the tests pass.
|
||||
# Those should probably be adopted upstream.
|
||||
#
|
||||
# - USE_PSA_CRYPTO for PK_HAVE_ECC_KEYS
|
||||
echo "#define MBEDTLS_USE_PSA_CRYPTO" >> "$CONFIG_H"
|
||||
# pkparse.c and pkwrite.c fail to link without this
|
||||
echo "#define MBEDTLS_OID_C" >> "$CONFIG_H"
|
||||
# - ASN1_[PARSE/WRITE]_C found by check_config.h for pkparse/pkwrite
|
||||
echo "#define MBEDTLS_ASN1_PARSE_C" >> "$CONFIG_H"
|
||||
echo "#define MBEDTLS_ASN1_WRITE_C" >> "$CONFIG_H"
|
||||
# - MD_C for HKDF_C
|
||||
echo "#define MBEDTLS_MD_C" >> "$CONFIG_H"
|
||||
|
||||
# Config adjustments for better test coverage in our environment.
|
||||
# These are not needed just to build and pass tests.
|
||||
#
|
||||
# Enable filesystem I/O for the benefit of PK parse/write tests.
|
||||
echo "#define MBEDTLS_FS_IO" >> "$CONFIG_H"
|
||||
# Disable this for maximal ASan efficiency
|
||||
scripts/config.py unset MBEDTLS_MEMORY_BUFFER_ALLOC_C
|
||||
|
||||
# Config adjustments for features that are not supported
|
||||
# when using only drivers / by p256-m
|
||||
#
|
||||
# Disable all the features that auto-enable ECP_LIGHT (see build_info.h)
|
||||
scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE
|
||||
# Disable deterministic ECDSA as p256-m only does randomized
|
||||
scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_DETERMINISTIC_ECDSA
|
||||
|
||||
}
|
||||
|
||||
# Keep this in sync with component_test_tfm_config() as they are both meant
|
||||
# to be used in analyze_outcomes.py for driver's coverage analysis.
|
||||
component_test_tfm_config_p256m_driver_accel_ec () {
|
||||
msg "build: TF-M config + p256m driver + accel ECDH(E)/ECDSA"
|
||||
|
||||
common_tfm_config
|
||||
|
||||
# Set the list of accelerated components in order to remove them from
|
||||
# builtin support.
|
||||
loc_accel_list="ALG_ECDSA \
|
||||
ALG_ECDH \
|
||||
KEY_TYPE_ECC_KEY_PAIR_BASIC \
|
||||
KEY_TYPE_ECC_KEY_PAIR_IMPORT \
|
||||
KEY_TYPE_ECC_KEY_PAIR_EXPORT \
|
||||
KEY_TYPE_ECC_KEY_PAIR_GENERATE \
|
||||
KEY_TYPE_ECC_PUBLIC_KEY"
|
||||
loc_accel_flags="$( echo "$loc_accel_list" | sed 's/[^ ]* */-DMBEDTLS_PSA_ACCEL_&/g' )"
|
||||
|
||||
# Build crypto library specifying we want to use P256M code for EC operations
|
||||
make CFLAGS="$ASAN_CFLAGS $loc_accel_flags -DMBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED" LDFLAGS="$ASAN_CFLAGS"
|
||||
|
||||
# Make sure any built-in EC alg was not re-enabled by accident (additive config)
|
||||
not grep mbedtls_ecdsa_ library/ecdsa.o
|
||||
not grep mbedtls_ecdh_ library/ecdh.o
|
||||
not grep mbedtls_ecjpake_ library/ecjpake.o
|
||||
# Also ensure that ECP, RSA, DHM or BIGNUM modules were not re-enabled
|
||||
not grep mbedtls_ecp_ library/ecp.o
|
||||
not grep mbedtls_rsa_ library/rsa.o
|
||||
not grep mbedtls_dhm_ library/dhm.o
|
||||
not grep mbedtls_mpi_ library/bignum.o
|
||||
|
||||
# Run the tests
|
||||
msg "test: TF-M config + p256m driver + accel ECDH(E)/ECDSA"
|
||||
make test
|
||||
}
|
||||
|
||||
# Keep this in sync with component_test_tfm_config_p256m_driver_accel_ec() as
|
||||
# they are both meant to be used in analyze_outcomes.py for driver's coverage
|
||||
# analysis.
|
||||
component_test_tfm_config() {
|
||||
common_tfm_config
|
||||
|
||||
msg "build: TF-M config"
|
||||
make tests
|
||||
|
||||
msg "test: TF-M config"
|
||||
make test
|
||||
}
|
||||
|
||||
# Helper function used in:
|
||||
# - component_test_psa_crypto_config_accel_all_curves_except_p192
|
||||
# - component_test_psa_crypto_config_accel_all_curves_except_x25519
|
||||
|
@ -521,6 +521,102 @@ TASKS = {
|
||||
'ignored_tests': {}
|
||||
}
|
||||
},
|
||||
'analyze_driver_vs_reference_tfm_config': {
|
||||
'test_function': do_analyze_driver_vs_reference,
|
||||
'args': {
|
||||
'component_ref': 'test_tfm_config',
|
||||
'component_driver': 'test_tfm_config_p256m_driver_accel_ec',
|
||||
'ignored_suites': [
|
||||
# Ignore test suites for the modules that are disabled in the
|
||||
# accelerated test case.
|
||||
'ecp',
|
||||
'ecdsa',
|
||||
'ecdh',
|
||||
'ecjpake',
|
||||
'bignum_core',
|
||||
'bignum_random',
|
||||
'bignum_mod',
|
||||
'bignum_mod_raw',
|
||||
'bignum.generated',
|
||||
'bignum.misc',
|
||||
],
|
||||
'ignored_tests': {
|
||||
# Ignore all tests that require DERIVE support which is disabled
|
||||
# in the driver version
|
||||
'test_suite_psa_crypto': [
|
||||
'PSA key agreement setup: ECDH + HKDF-SHA-256: good',
|
||||
('PSA key agreement setup: ECDH + HKDF-SHA-256: good, key algorithm broader '
|
||||
'than required'),
|
||||
'PSA key agreement setup: ECDH + HKDF-SHA-256: public key not on curve',
|
||||
'PSA key agreement setup: KDF instead of a key agreement algorithm',
|
||||
'PSA key agreement setup: bad key agreement algorithm',
|
||||
'PSA key agreement: ECDH SECP256R1 (RFC 5903) + HKDF-SHA-256: capacity=8160',
|
||||
'PSA key agreement: ECDH SECP256R1 (RFC 5903) + HKDF-SHA-256: read 0+32',
|
||||
'PSA key agreement: ECDH SECP256R1 (RFC 5903) + HKDF-SHA-256: read 1+31',
|
||||
'PSA key agreement: ECDH SECP256R1 (RFC 5903) + HKDF-SHA-256: read 31+1',
|
||||
'PSA key agreement: ECDH SECP256R1 (RFC 5903) + HKDF-SHA-256: read 32+0',
|
||||
'PSA key agreement: ECDH SECP256R1 (RFC 5903) + HKDF-SHA-256: read 32+32',
|
||||
'PSA key agreement: ECDH SECP256R1 (RFC 5903) + HKDF-SHA-256: read 64+0',
|
||||
'PSA key derivation: ECDH on P256 with HKDF-SHA256, info first',
|
||||
'PSA key derivation: ECDH on P256 with HKDF-SHA256, key output',
|
||||
'PSA key derivation: ECDH on P256 with HKDF-SHA256, missing info',
|
||||
'PSA key derivation: ECDH on P256 with HKDF-SHA256, omitted salt',
|
||||
'PSA key derivation: ECDH on P256 with HKDF-SHA256, raw output',
|
||||
'PSA key derivation: ECDH on P256 with HKDF-SHA256, salt after secret',
|
||||
'PSA key derivation: ECDH with TLS 1.2 PRF SHA-256, good case',
|
||||
'PSA key derivation: ECDH with TLS 1.2 PRF SHA-256, missing label',
|
||||
'PSA key derivation: ECDH with TLS 1.2 PRF SHA-256, missing label and secret',
|
||||
'PSA key derivation: ECDH with TLS 1.2 PRF SHA-256, no inputs',
|
||||
'PSA key derivation: HKDF-SHA-256 -> ECC secp256r1',
|
||||
'PSA key derivation: HKDF-SHA-256 -> ECC secp256r1 (1 redraw)',
|
||||
'PSA key derivation: HKDF-SHA-256 -> ECC secp256r1, exercise ECDSA',
|
||||
'PSA key derivation: TLS 1.2 Mix-PSK-to-MS, SHA-256, 0+48, ka',
|
||||
'PSA key derivation: TLS 1.2 Mix-PSK-to-MS, SHA-256, 24+24, ka',
|
||||
'PSA key derivation: TLS 1.2 Mix-PSK-to-MS, SHA-256, 48+0, ka',
|
||||
'PSA key derivation: TLS 1.2 Mix-PSK-to-MS, bad state #1, ka',
|
||||
'PSA key derivation: TLS 1.2 Mix-PSK-to-MS, bad state #3, ka',
|
||||
'PSA key derivation: TLS 1.2 Mix-PSK-to-MS, bad state #4, ka',
|
||||
'PSA key derivation: bits=7 invalid for ECC BRAINPOOL_P_R1 (ECC enabled)',
|
||||
'PSA key derivation: bits=7 invalid for ECC MONTGOMERY (ECC enabled)',
|
||||
'PSA key derivation: bits=7 invalid for ECC SECP_K1 (ECC enabled)',
|
||||
'PSA key derivation: bits=7 invalid for ECC SECP_R1 (ECC enabled)',
|
||||
'PSA key derivation: bits=7 invalid for ECC SECP_R2 (ECC enabled)',
|
||||
'PSA key derivation: bits=7 invalid for ECC SECT_K1 (ECC enabled)',
|
||||
'PSA key derivation: bits=7 invalid for ECC SECT_R1 (ECC enabled)',
|
||||
'PSA key derivation: bits=7 invalid for ECC SECT_R2 (ECC enabled)',
|
||||
'PSA raw key agreement: ECDH SECP256R1 (RFC 5903)',
|
||||
],
|
||||
'test_suite_random': [
|
||||
'PSA classic wrapper: ECDSA signature (SECP256R1)',
|
||||
],
|
||||
'test_suite_psa_crypto_pake': [
|
||||
'PSA PAKE: ecjpake size macros',
|
||||
],
|
||||
'test_suite_asn1parse': [
|
||||
# This test depends on BIGNUM_C
|
||||
'INTEGER too large for mpi',
|
||||
],
|
||||
'test_suite_asn1write': [
|
||||
# Following tests depends on BIGNUM_C
|
||||
'ASN.1 Write mpi 0 (1 limb)',
|
||||
'ASN.1 Write mpi 0 (null)',
|
||||
'ASN.1 Write mpi 0x100',
|
||||
'ASN.1 Write mpi 0x7f',
|
||||
'ASN.1 Write mpi 0x7f with leading 0 limb',
|
||||
'ASN.1 Write mpi 0x80',
|
||||
'ASN.1 Write mpi 0x80 with leading 0 limb',
|
||||
'ASN.1 Write mpi 0xff',
|
||||
'ASN.1 Write mpi 1',
|
||||
'ASN.1 Write mpi, 127*8 bits',
|
||||
'ASN.1 Write mpi, 127*8+1 bits',
|
||||
'ASN.1 Write mpi, 127*8-1 bits',
|
||||
'ASN.1 Write mpi, 255*8 bits',
|
||||
'ASN.1 Write mpi, 255*8-1 bits',
|
||||
'ASN.1 Write mpi, 256*8-1 bits',
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def main():
|
||||
|
@ -1366,7 +1366,21 @@ void import_with_data(data_t *data, int type_arg,
|
||||
psa_set_key_bits(&attributes, attr_bits);
|
||||
|
||||
status = psa_import_key(&attributes, data->x, data->len, &key);
|
||||
TEST_EQUAL(status, expected_status);
|
||||
/* When expecting INVALID_ARGUMENT, also accept NOT_SUPPORTED.
|
||||
*
|
||||
* This can happen with a type supported only by a driver:
|
||||
* - the driver sees the invalid data (for example wrong size) and thinks
|
||||
* "well perhaps this is a key size I don't support" so it returns
|
||||
* NOT_SUPPORTED which is correct at this point;
|
||||
* - we fallback to built-ins, which don't support this type, so return
|
||||
* NOT_SUPPORTED which again is correct at this point.
|
||||
*/
|
||||
if (expected_status == PSA_ERROR_INVALID_ARGUMENT &&
|
||||
status == PSA_ERROR_NOT_SUPPORTED) {
|
||||
; // OK
|
||||
} else {
|
||||
TEST_EQUAL(status, expected_status);
|
||||
}
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user