mbedtls/tests/suites/test_suite_pk.function
Gilles Peskine d6fc3501c0 Test mbedtls_pk_import_into_psa with different bits
This was only tested with opaque keys. Since the code paths are different
depending on the PK type, we also need to test RSA and ECKEY.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2024-02-15 17:15:29 +01:00

2134 lines
78 KiB
C

/* BEGIN_HEADER */
#include "mbedtls/pk.h"
#include "pk_internal.h"
/* For error codes */
#include "mbedtls/asn1.h"
#include "mbedtls/base64.h"
#include "mbedtls/ecp.h"
#include "mbedtls/error.h"
#include "mbedtls/rsa.h"
#include "pk_internal.h"
#include <limits.h>
#include <stdint.h>
/* Needed only for test case data under #if defined(MBEDTLS_USE_PSA_CRYPTO),
* but the test code generator requires test case data to be valid C code
* unconditionally (https://github.com/Mbed-TLS/mbedtls/issues/2023). */
#include "psa/crypto.h"
#include "mbedtls/psa_util.h"
/* Used for properly sizing the key buffer in pk_genkey_ec() */
#include "psa_util_internal.h"
#define RSA_KEY_SIZE MBEDTLS_RSA_GEN_KEY_MIN_BITS
#define RSA_KEY_LEN (MBEDTLS_RSA_GEN_KEY_MIN_BITS/8)
#if defined(MBEDTLS_RSA_C) || \
defined(MBEDTLS_PK_RSA_ALT_SUPPORT) || \
defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_USE_PSA_CRYPTO)
#define PK_CAN_SIGN_SOME
#endif
/* MBEDTLS_TEST_PK_PSA_SIGN is enabled when:
* - The build has PK_[PARSE/WRITE]_C for RSA or ECDSA signature.
* - The build has built-in ECC and ECDSA signature.
*/
#if (defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_PK_WRITE_C) && \
((defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)) || \
defined(MBEDTLS_PK_CAN_ECDSA_SIGN))) || \
(defined(MBEDTLS_ECP_C) && defined(MBEDTLS_PK_CAN_ECDSA_SIGN))
#define MBEDTLS_TEST_PK_PSA_SIGN
#endif
#if defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
/* Pick an elliptic curve that's supported by PSA. Note that the curve is
* not guaranteed to be supported by the ECP module.
*
* This should always find a curve if ECC is enabled in the build, except in
* one edge case: in a build with MBEDTLS_PSA_CRYPTO_CONFIG disabled and
* where the only legacy curve is secp224k1, which is not supported in PSA,
* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY ends up enabled but PSA does not
* support any curve.
*/
/* First try all the curves that can do both ECDSA and ECDH, then try
* the ECDH-only curves. (There are no curves that can do ECDSA but not ECDH.)
* This way, if ECDSA is enabled then the curve that's selected here will
* be ECDSA-capable, and likewise for ECDH. */
#if defined(PSA_WANT_ECC_SECP_R1_192)
#define MBEDTLS_TEST_PSA_ECC_ONE_FAMILY PSA_ECC_FAMILY_SECP_R1
#define MBEDTLS_TEST_PSA_ECC_ONE_CURVE_BITS 192
#define MBEDTLS_TEST_ECP_DP_ONE_CURVE MBEDTLS_ECP_DP_SECP192R1
#elif defined(PSA_WANT_ECC_SECP_R1_224)
#define MBEDTLS_TEST_PSA_ECC_ONE_FAMILY PSA_ECC_FAMILY_SECP_R1
#define MBEDTLS_TEST_PSA_ECC_ONE_CURVE_BITS 224
#define MBEDTLS_TEST_ECP_DP_ONE_CURVE MBEDTLS_ECP_DP_SECP224R1
#elif defined(PSA_WANT_ECC_SECP_R1_256)
#define MBEDTLS_TEST_PSA_ECC_ONE_FAMILY PSA_ECC_FAMILY_SECP_R1
#define MBEDTLS_TEST_PSA_ECC_ONE_CURVE_BITS 256
#define MBEDTLS_TEST_ECP_DP_ONE_CURVE MBEDTLS_ECP_DP_SECP256R1
#elif defined(PSA_WANT_ECC_SECP_R1_384)
#define MBEDTLS_TEST_PSA_ECC_ONE_FAMILY PSA_ECC_FAMILY_SECP_R1
#define MBEDTLS_TEST_PSA_ECC_ONE_CURVE_BITS 384
#define MBEDTLS_TEST_ECP_DP_ONE_CURVE MBEDTLS_ECP_DP_SECP384R1
#elif defined(PSA_WANT_ECC_SECP_R1_521)
#define MBEDTLS_TEST_PSA_ECC_ONE_FAMILY PSA_ECC_FAMILY_SECP_R1
#define MBEDTLS_TEST_PSA_ECC_ONE_CURVE_BITS 521
#define MBEDTLS_TEST_ECP_DP_ONE_CURVE MBEDTLS_ECP_DP_SECP521R1
#elif defined(PSA_WANT_ECC_SECP_K1_192)
#define MBEDTLS_TEST_PSA_ECC_ONE_FAMILY PSA_ECC_FAMILY_SECP_K1
#define MBEDTLS_TEST_PSA_ECC_ONE_CURVE_BITS 192
#define MBEDTLS_TEST_ECP_DP_ONE_CURVE MBEDTLS_ECP_DP_SECP192K1
#elif defined(PSA_WANT_ECC_SECP_K1_224)
#define MBEDTLS_TEST_PSA_ECC_ONE_FAMILY PSA_ECC_FAMILY_SECP_K1
#define MBEDTLS_TEST_PSA_ECC_ONE_CURVE_BITS 224
#define MBEDTLS_TEST_ECP_DP_ONE_CURVE MBEDTLS_ECP_DP_SECP224K1
#elif defined(PSA_WANT_ECC_SECP_K1_256)
#define MBEDTLS_TEST_PSA_ECC_ONE_FAMILY PSA_ECC_FAMILY_SECP_K1
#define MBEDTLS_TEST_PSA_ECC_ONE_CURVE_BITS 256
#define MBEDTLS_TEST_ECP_DP_ONE_CURVE MBEDTLS_ECP_DP_SECP256K1
#elif defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256)
#define MBEDTLS_TEST_PSA_ECC_ONE_FAMILY PSA_ECC_FAMILY_BRAINPOOL_P_R1
#define MBEDTLS_TEST_PSA_ECC_ONE_CURVE_BITS 256
#define MBEDTLS_TEST_ECP_DP_ONE_CURVE MBEDTLS_ECP_DP_BP256R1
#elif defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384)
#define MBEDTLS_TEST_PSA_ECC_ONE_FAMILY PSA_ECC_FAMILY_BRAINPOOL_P_R1
#define MBEDTLS_TEST_PSA_ECC_ONE_CURVE_BITS 384
#define MBEDTLS_TEST_ECP_DP_ONE_CURVE MBEDTLS_ECP_DP_BP384R1
#elif defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512)
#define MBEDTLS_TEST_PSA_ECC_ONE_FAMILY PSA_ECC_FAMILY_BRAINPOOL_P_R1
#define MBEDTLS_TEST_PSA_ECC_ONE_CURVE_BITS 512
#define MBEDTLS_TEST_ECP_DP_ONE_CURVE MBEDTLS_ECP_DP_BP512R1
#elif defined(PSA_WANT_ECC_MONTGOMERY_255)
#define MBEDTLS_TEST_PSA_ECC_ONE_FAMILY PSA_ECC_FAMILY_MONTGOMERY
#define MBEDTLS_TEST_PSA_ECC_ONE_CURVE_BITS 255
#define MBEDTLS_TEST_ECP_DP_ONE_CURVE MBEDTLS_ECP_DP_CURVE25519
#elif defined(PSA_WANT_ECC_MONTGOMERY_448)
#define MBEDTLS_TEST_PSA_ECC_ONE_FAMILY PSA_ECC_FAMILY_MONTGOMERY
#define MBEDTLS_TEST_PSA_ECC_ONE_CURVE_BITS 448
#define MBEDTLS_TEST_ECP_DP_ONE_CURVE MBEDTLS_ECP_DP_CURVE448
#endif /* curve selection */
#if defined(MBEDTLS_TEST_PSA_ECC_ONE_FAMILY)
#define MBEDTLS_TEST_PSA_ECC_AT_LEAST_ONE_CURVE
#endif
/* Pick a second curve, for tests that need two supported curves of the
* same size. For simplicity, we only handle a subset of configurations,
* and both curves will support both ECDH and ECDSA. */
#if defined(PSA_WANT_ECC_SECP_R1_192) && defined(PSA_WANT_ECC_SECP_K1_192)
/* Identical redefinition of the ONE macros, to confirm that they have
* the values we expect here. */
#define MBEDTLS_TEST_PSA_ECC_ONE_FAMILY PSA_ECC_FAMILY_SECP_R1
#define MBEDTLS_TEST_PSA_ECC_ANOTHER_FAMILY PSA_ECC_FAMILY_SECP_K1
#define MBEDTLS_TEST_PSA_ECC_ONE_CURVE_BITS 192
#define MBEDTLS_TEST_PSA_ECC_HAVE_TWO_FAMILIES
#elif defined(PSA_WANT_ECC_SECP_R1_256) && defined(PSA_WANT_ECC_SECP_K1_256)
#define MBEDTLS_TEST_PSA_ECC_ONE_FAMILY PSA_ECC_FAMILY_SECP_R1
#define MBEDTLS_TEST_PSA_ECC_ANOTHER_FAMILY PSA_ECC_FAMILY_SECP_K1
#define MBEDTLS_TEST_PSA_ECC_ONE_CURVE_BITS 256
#define MBEDTLS_TEST_PSA_ECC_HAVE_TWO_FAMILIES
#endif
/* Pick a second bit-size, for tests that need two supported curves of the
* same family. For simplicity, we only handle a subset of configurations,
* and both curves will support both ECDH and ECDSA. */
#if defined(PSA_WANT_ECC_SECP_R1_192) && defined(PSA_WANT_ECC_SECP_R1_256)
/* Identical redefinition of the ONE macros, to confirm that they have
* the values we expect here. */
#define MBEDTLS_TEST_PSA_ECC_ONE_FAMILY PSA_ECC_FAMILY_SECP_R1
#define MBEDTLS_TEST_PSA_ECC_ONE_CURVE_BITS 192
#define MBEDTLS_TEST_PSA_ECC_ANOTHER_CURVE_BITS 256
#define MBEDTLS_TEST_PSA_ECC_HAVE_TWO_BITS
#elif defined(PSA_WANT_ECC_SECP_R1_256) && defined(PSA_WANT_ECC_SECP_R1_384)
#define MBEDTLS_TEST_PSA_ECC_ONE_FAMILY PSA_ECC_FAMILY_SECP_R1
#define MBEDTLS_TEST_PSA_ECC_ONE_CURVE_BITS 256
#define MBEDTLS_TEST_PSA_ECC_ANOTHER_CURVE_BITS 384
#define MBEDTLS_TEST_PSA_ECC_HAVE_TWO_BITS
#endif
#endif /* defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) */
/* Always define the macros so that we can use them in test data. */
#if !defined(MBEDTLS_TEST_PSA_ECC_ONE_FAMILY)
#define MBEDTLS_TEST_PSA_ECC_ONE_FAMILY 0
#define MBEDTLS_TEST_PSA_ECC_ONE_CURVE_BITS 0
#define MBEDTLS_TEST_ECP_DP_ONE_CURVE 0
#endif
#if !defined(MBEDTLS_TEST_PSA_ECC_ANOTHER_FAMILY)
#define MBEDTLS_TEST_PSA_ECC_ANOTHER_FAMILY 0
#endif
#if !defined(MBEDTLS_TEST_PSA_ECC_ANOTHER_CURVE_BITS)
#define MBEDTLS_TEST_PSA_ECC_ANOTHER_CURVE_BITS 0
#endif
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
static int pk_genkey_ec(mbedtls_pk_context *pk, mbedtls_ecp_group_id grp_id)
{
psa_status_t status;
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
size_t curve_bits;
psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(grp_id, &curve_bits);
int ret;
if (curve == 0) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
psa_set_key_bits(&key_attr, curve_bits);
psa_key_usage_t usage = PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY;
psa_algorithm_t sign_alg = 0;
psa_algorithm_t derive_alg = 0;
if (mbedtls_pk_get_type(pk) != MBEDTLS_PK_ECDSA) {
usage |= PSA_KEY_USAGE_DERIVE;
derive_alg = PSA_ALG_ECDH;
}
if (mbedtls_pk_get_type(pk) != MBEDTLS_PK_ECKEY_DH &&
curve != PSA_ECC_FAMILY_MONTGOMERY) {
usage |= PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE;
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
sign_alg = PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_ANY_HASH);
#else
sign_alg = PSA_ALG_ECDSA(PSA_ALG_ANY_HASH);
#endif
}
if (derive_alg != 0) {
psa_set_key_algorithm(&key_attr, derive_alg);
if (sign_alg != 0) {
psa_set_key_enrollment_algorithm(&key_attr, sign_alg);
}
} else {
psa_set_key_algorithm(&key_attr, sign_alg);
}
psa_set_key_usage_flags(&key_attr, usage);
status = psa_generate_key(&key_attr, &pk->priv_id);
if (status != PSA_SUCCESS) {
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
}
status = psa_export_public_key(pk->priv_id, pk->pub_raw, sizeof(pk->pub_raw),
&pk->pub_raw_len);
if (status != PSA_SUCCESS) {
ret = MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
goto exit;
}
pk->ec_family = curve;
pk->ec_bits = curve_bits;
return 0;
exit:
status = psa_destroy_key(pk->priv_id);
return (ret != 0) ? ret : psa_pk_status_to_mbedtls(status);
}
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
/** Generate a key of the desired type.
*
* \param pk The PK object to fill. It must have been initialized
* with mbedtls_pk_setup().
* \param curve_or_keybits - For RSA keys, the key size in bits.
* - For EC keys, the curve (\c MBEDTLS_ECP_DP_xxx).
*
* \return The status from the underlying type-specific key
* generation function.
* \return -1 if the key type is not recognized.
*/
static int pk_genkey(mbedtls_pk_context *pk, int curve_or_keybits)
{
(void) pk;
(void) curve_or_keybits;
#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_RSA) {
return mbedtls_rsa_gen_key(mbedtls_pk_rsa(*pk),
mbedtls_test_rnd_std_rand, NULL,
curve_or_keybits, 3);
}
#endif
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_ECKEY ||
mbedtls_pk_get_type(pk) == MBEDTLS_PK_ECKEY_DH ||
mbedtls_pk_get_type(pk) == MBEDTLS_PK_ECDSA) {
int ret;
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
ret = pk_genkey_ec(pk, curve_or_keybits);
if (ret != 0) {
return ret;
}
return 0;
#else
ret = mbedtls_ecp_group_load(&mbedtls_pk_ec_rw(*pk)->grp, curve_or_keybits);
if (ret != 0) {
return ret;
}
return mbedtls_ecp_gen_keypair(&mbedtls_pk_ec_rw(*pk)->grp,
&mbedtls_pk_ec_rw(*pk)->d,
&mbedtls_pk_ec_rw(*pk)->Q,
mbedtls_test_rnd_std_rand, NULL);
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
}
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
return -1;
}
#if defined(MBEDTLS_PSA_CRYPTO_C)
static psa_key_usage_t pk_get_psa_attributes_implied_usage(
psa_key_usage_t expected_usage)
{
/* Usage implied universally */
if (expected_usage & PSA_KEY_USAGE_SIGN_HASH) {
expected_usage |= PSA_KEY_USAGE_SIGN_MESSAGE;
}
if (expected_usage & PSA_KEY_USAGE_VERIFY_HASH) {
expected_usage |= PSA_KEY_USAGE_VERIFY_MESSAGE;
}
/* Usage implied by mbedtls_pk_get_psa_attributes() */
if (expected_usage & PSA_KEY_USAGE_SIGN_HASH) {
expected_usage |= PSA_KEY_USAGE_VERIFY_HASH;
}
if (expected_usage & PSA_KEY_USAGE_SIGN_MESSAGE) {
expected_usage |= PSA_KEY_USAGE_VERIFY_MESSAGE;
}
if (expected_usage & PSA_KEY_USAGE_DECRYPT) {
expected_usage |= PSA_KEY_USAGE_ENCRYPT;
}
expected_usage |= PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY;
return expected_usage;
}
#endif /* MBEDTLS_PSA_CRYPTO_C */
#if defined(MBEDTLS_RSA_C)
int mbedtls_rsa_decrypt_func(void *ctx, size_t *olen,
const unsigned char *input, unsigned char *output,
size_t output_max_len)
{
return mbedtls_rsa_pkcs1_decrypt((mbedtls_rsa_context *) ctx,
mbedtls_test_rnd_std_rand, NULL,
olen, input, output, output_max_len);
}
int mbedtls_rsa_sign_func(void *ctx,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
mbedtls_md_type_t md_alg, unsigned int hashlen,
const unsigned char *hash, unsigned char *sig)
{
((void) f_rng);
((void) p_rng);
return mbedtls_rsa_pkcs1_sign((mbedtls_rsa_context *) ctx,
mbedtls_test_rnd_std_rand, NULL,
md_alg, hashlen, hash, sig);
}
size_t mbedtls_rsa_key_len_func(void *ctx)
{
return ((const mbedtls_rsa_context *) ctx)->len;
}
#endif /* MBEDTLS_RSA_C */
typedef enum {
/* The values are compatible with thinking of "from pair" as a boolean. */
FROM_PUBLIC = 0,
FROM_PAIR = 1
} from_pair_t;
#if defined(MBEDTLS_PSA_CRYPTO_C)
static int pk_setup_for_type(mbedtls_pk_type_t pk_type, int want_pair,
mbedtls_pk_context *pk, psa_key_type_t *psa_type)
{
if (pk_type == MBEDTLS_PK_NONE) {
return 0;
}
TEST_EQUAL(mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(pk_type)), 0);
switch (pk_type) {
#if defined(MBEDTLS_RSA_C)
case MBEDTLS_PK_RSA:
{
*psa_type = PSA_KEY_TYPE_RSA_KEY_PAIR;
mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
if (want_pair) {
#if defined(MBEDTLS_GENPRIME)
TEST_EQUAL(mbedtls_rsa_gen_key(
rsa,
mbedtls_test_rnd_std_rand, NULL,
MBEDTLS_RSA_GEN_KEY_MIN_BITS, 65537), 0);
#else
TEST_FAIL("I don't know how to create an RSA key pair in this configuration.");
#endif
} else {
unsigned char N[PSA_BITS_TO_BYTES(MBEDTLS_RSA_GEN_KEY_MIN_BITS)] = { 0xff };
N[sizeof(N) - 1] = 0x03;
const unsigned char E[1] = { 0x03 };
TEST_EQUAL(mbedtls_rsa_import_raw(rsa,
N, sizeof(N),
NULL, 0, NULL, 0, NULL, 0,
E, sizeof(E)), 0);
TEST_EQUAL(mbedtls_rsa_complete(rsa), 0);
}
break;
}
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
case MBEDTLS_PK_ECKEY:
case MBEDTLS_PK_ECKEY_DH:
case MBEDTLS_PK_ECDSA:
{
mbedtls_ecp_group_id grp_id = MBEDTLS_TEST_ECP_DP_ONE_CURVE;
size_t bits;
*psa_type = PSA_KEY_TYPE_ECC_KEY_PAIR(mbedtls_ecc_group_to_psa(grp_id, &bits));
TEST_EQUAL(pk_genkey(pk, grp_id), 0);
if (!want_pair) {
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
psa_key_attributes_t pub_attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_set_key_type(&pub_attributes,
PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(*psa_type));
psa_set_key_usage_flags(&pub_attributes,
PSA_KEY_USAGE_EXPORT |
PSA_KEY_USAGE_COPY |
PSA_KEY_USAGE_VERIFY_MESSAGE |
PSA_KEY_USAGE_VERIFY_HASH);
psa_set_key_algorithm(&pub_attributes, PSA_ALG_ECDSA_ANY);
PSA_ASSERT(psa_destroy_key(pk->priv_id));
pk->priv_id = MBEDTLS_SVC_KEY_ID_INIT;
#else
mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*pk);
mbedtls_mpi_free(&ec->d);
#endif
}
break;
}
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
default:
TEST_FAIL("Unknown PK type in test data");
break;
}
if (!want_pair) {
*psa_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(*psa_type);
}
return 0;
exit:
return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
}
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/*
* Generate an ECC key using PSA and return the key identifier of that key,
* or 0 if the key generation failed.
* The key uses NIST P-256 and is usable for signing with SHA-256.
*/
mbedtls_svc_key_id_t pk_psa_genkey_ecc(void)
{
mbedtls_svc_key_id_t key;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
const psa_key_type_t type =
PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1);
const size_t bits = 256;
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256));
psa_set_key_type(&attributes, type);
psa_set_key_bits(&attributes, bits);
PSA_ASSERT(psa_generate_key(&attributes, &key));
exit:
return key;
}
/*
* Generate an RSA key using PSA and return the key identifier of that key,
* or 0 if the key generation failed.
*/
mbedtls_svc_key_id_t pk_psa_genkey_rsa(void)
{
mbedtls_svc_key_id_t key;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
const psa_key_type_t type = PSA_KEY_TYPE_RSA_KEY_PAIR;
const size_t bits = 1024;
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_SIGN_RAW);
psa_set_key_type(&attributes, type);
psa_set_key_bits(&attributes, bits);
PSA_ASSERT(psa_generate_key(&attributes, &key));
exit:
return key;
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/* END_HEADER */
/* BEGIN_DEPENDENCIES
* depends_on:MBEDTLS_PK_C
* END_DEPENDENCIES
*/
/* BEGIN_CASE depends_on:MBEDTLS_USE_PSA_CRYPTO */
void pk_psa_utils(int key_is_rsa)
{
mbedtls_pk_context pk, pk2;
mbedtls_svc_key_id_t key;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
const char * const name = "Opaque";
size_t bitlen;
mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
unsigned char b1[1], b2[1];
size_t len;
mbedtls_pk_debug_item dbg;
mbedtls_pk_init(&pk);
mbedtls_pk_init(&pk2);
USE_PSA_INIT();
TEST_ASSERT(mbedtls_pk_setup_opaque(&pk, MBEDTLS_SVC_KEY_ID_INIT) ==
MBEDTLS_ERR_PK_BAD_INPUT_DATA);
mbedtls_pk_free(&pk);
mbedtls_pk_init(&pk);
if (key_is_rsa) {
bitlen = 1024; /* hardcoded in genkey() */
key = pk_psa_genkey_rsa();
} else {
bitlen = 256; /* hardcoded in genkey() */
key = pk_psa_genkey_ecc();
}
if (mbedtls_svc_key_id_is_null(key)) {
goto exit;
}
TEST_ASSERT(mbedtls_pk_setup_opaque(&pk, key) == 0);
TEST_ASSERT(mbedtls_pk_get_type(&pk) == MBEDTLS_PK_OPAQUE);
TEST_ASSERT(strcmp(mbedtls_pk_get_name(&pk), name) == 0);
TEST_ASSERT(mbedtls_pk_get_bitlen(&pk) == bitlen);
TEST_ASSERT(mbedtls_pk_get_len(&pk) == bitlen / 8);
if (key_is_rsa) {
TEST_ASSERT(mbedtls_pk_can_do(&pk, MBEDTLS_PK_ECKEY) == 0);
TEST_ASSERT(mbedtls_pk_can_do(&pk, MBEDTLS_PK_ECDSA) == 0);
TEST_ASSERT(mbedtls_pk_can_do(&pk, MBEDTLS_PK_RSA) == 1);
} else {
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);
}
/* unsupported operations: verify, decrypt, encrypt */
if (key_is_rsa == 1) {
TEST_ASSERT(mbedtls_pk_verify(&pk, md_alg,
b1, sizeof(b1), b2, sizeof(b2))
== MBEDTLS_ERR_PK_TYPE_MISMATCH);
} else {
TEST_ASSERT(mbedtls_pk_decrypt(&pk, b1, sizeof(b1),
b2, &len, sizeof(b2),
NULL, NULL)
== MBEDTLS_ERR_PK_TYPE_MISMATCH);
}
TEST_ASSERT(mbedtls_pk_encrypt(&pk, b1, sizeof(b1),
b2, &len, sizeof(b2),
NULL, NULL)
== MBEDTLS_ERR_PK_TYPE_MISMATCH);
/* unsupported functions: check_pair, debug */
if (key_is_rsa) {
TEST_ASSERT(mbedtls_pk_setup(&pk2,
mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)) == 0);
} else {
TEST_ASSERT(mbedtls_pk_setup(&pk2,
mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)) == 0);
}
TEST_ASSERT(mbedtls_pk_check_pair(&pk, &pk2,
mbedtls_test_rnd_std_rand, NULL)
== MBEDTLS_ERR_PK_TYPE_MISMATCH);
TEST_ASSERT(mbedtls_pk_debug(&pk, &dbg)
== MBEDTLS_ERR_PK_TYPE_MISMATCH);
/* test that freeing the context does not destroy the key */
mbedtls_pk_free(&pk);
TEST_ASSERT(PSA_SUCCESS == psa_get_key_attributes(key, &attributes));
TEST_ASSERT(PSA_SUCCESS == psa_destroy_key(key));
exit:
/*
* Key attributes may have been returned by psa_get_key_attributes()
* thus reset them as required.
*/
psa_reset_key_attributes(&attributes);
mbedtls_pk_free(&pk); /* redundant except upon error */
mbedtls_pk_free(&pk2);
USE_PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_USE_PSA_CRYPTO */
void pk_can_do_ext(int opaque_key, int key_type, int key_usage, int key_alg,
int key_alg2, int curve_or_keybits, int alg_check, int usage_check,
int result)
{
mbedtls_pk_context pk;
mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mbedtls_pk_init(&pk);
USE_PSA_INIT();
if (opaque_key == 1) {
psa_set_key_usage_flags(&attributes, key_usage);
psa_set_key_algorithm(&attributes, key_alg);
if (key_alg2 != 0) {
psa_set_key_enrollment_algorithm(&attributes, key_alg2);
}
psa_set_key_type(&attributes, key_type);
psa_set_key_bits(&attributes, curve_or_keybits);
PSA_ASSERT(psa_generate_key(&attributes, &key));
if (mbedtls_svc_key_id_is_null(key)) {
goto exit;
}
TEST_EQUAL(mbedtls_pk_setup_opaque(&pk, key), 0);
TEST_EQUAL(mbedtls_pk_get_type(&pk), MBEDTLS_PK_OPAQUE);
} else {
TEST_EQUAL(mbedtls_pk_setup(&pk,
mbedtls_pk_info_from_type(key_type)), 0);
TEST_EQUAL(pk_genkey(&pk, curve_or_keybits), 0);
TEST_EQUAL(mbedtls_pk_get_type(&pk), key_type);
}
TEST_EQUAL(mbedtls_pk_can_do_ext(&pk, alg_check, usage_check), result);
exit:
psa_reset_key_attributes(&attributes);
PSA_ASSERT(psa_destroy_key(key));
mbedtls_pk_free(&pk);
USE_PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE */
void pk_invalid_param()
{
mbedtls_pk_context ctx;
mbedtls_pk_type_t pk_type = 0;
unsigned char buf[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
size_t buf_size = sizeof(buf);
mbedtls_pk_init(&ctx);
USE_PSA_INIT();
TEST_EQUAL(MBEDTLS_ERR_PK_BAD_INPUT_DATA,
mbedtls_pk_verify_restartable(&ctx, MBEDTLS_MD_NONE,
NULL, buf_size,
buf, buf_size,
NULL));
TEST_EQUAL(MBEDTLS_ERR_PK_BAD_INPUT_DATA,
mbedtls_pk_verify_restartable(&ctx, MBEDTLS_MD_SHA256,
NULL, 0,
buf, buf_size,
NULL));
TEST_EQUAL(MBEDTLS_ERR_PK_BAD_INPUT_DATA,
mbedtls_pk_verify_ext(pk_type, NULL,
&ctx, MBEDTLS_MD_NONE,
NULL, buf_size,
buf, buf_size));
TEST_EQUAL(MBEDTLS_ERR_PK_BAD_INPUT_DATA,
mbedtls_pk_verify_ext(pk_type, NULL,
&ctx, MBEDTLS_MD_SHA256,
NULL, 0,
buf, buf_size));
TEST_EQUAL(MBEDTLS_ERR_PK_BAD_INPUT_DATA,
mbedtls_pk_sign_restartable(&ctx, MBEDTLS_MD_NONE,
NULL, buf_size,
buf, buf_size, &buf_size,
NULL, NULL,
NULL));
TEST_EQUAL(MBEDTLS_ERR_PK_BAD_INPUT_DATA,
mbedtls_pk_sign_restartable(&ctx, MBEDTLS_MD_SHA256,
NULL, 0,
buf, buf_size, &buf_size,
NULL, NULL,
NULL));
TEST_EQUAL(MBEDTLS_ERR_PK_BAD_INPUT_DATA,
mbedtls_pk_sign_ext(pk_type, &ctx, MBEDTLS_MD_NONE,
NULL, buf_size,
buf, buf_size, &buf_size,
NULL, NULL));
TEST_EQUAL(MBEDTLS_ERR_PK_BAD_INPUT_DATA,
mbedtls_pk_sign_ext(pk_type, &ctx, MBEDTLS_MD_SHA256,
NULL, 0,
buf, buf_size, &buf_size,
NULL, NULL));
exit:
mbedtls_pk_free(&ctx);
USE_PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE */
void valid_parameters()
{
mbedtls_pk_context pk;
unsigned char buf[1];
size_t len;
void *options = NULL;
mbedtls_pk_init(&pk);
USE_PSA_INIT();
TEST_ASSERT(mbedtls_pk_setup(&pk, NULL) ==
MBEDTLS_ERR_PK_BAD_INPUT_DATA);
/* In informational functions, we accept NULL where a context pointer
* is expected because that's what the library has done forever.
* We do not document that NULL is accepted, so we may wish to change
* the behavior in a future version. */
TEST_ASSERT(mbedtls_pk_get_bitlen(NULL) == 0);
TEST_ASSERT(mbedtls_pk_get_len(NULL) == 0);
TEST_ASSERT(mbedtls_pk_can_do(NULL, MBEDTLS_PK_NONE) == 0);
TEST_ASSERT(mbedtls_pk_sign_restartable(&pk,
MBEDTLS_MD_NONE,
NULL, 0,
buf, sizeof(buf), &len,
mbedtls_test_rnd_std_rand, NULL,
NULL) ==
MBEDTLS_ERR_PK_BAD_INPUT_DATA);
TEST_ASSERT(mbedtls_pk_sign(&pk,
MBEDTLS_MD_NONE,
NULL, 0,
buf, sizeof(buf), &len,
mbedtls_test_rnd_std_rand, NULL) ==
MBEDTLS_ERR_PK_BAD_INPUT_DATA);
TEST_ASSERT(mbedtls_pk_sign_ext(MBEDTLS_PK_NONE, &pk,
MBEDTLS_MD_NONE,
NULL, 0,
buf, sizeof(buf), &len,
mbedtls_test_rnd_std_rand, NULL) ==
MBEDTLS_ERR_PK_BAD_INPUT_DATA);
TEST_ASSERT(mbedtls_pk_verify_restartable(&pk,
MBEDTLS_MD_NONE,
NULL, 0,
buf, sizeof(buf),
NULL) ==
MBEDTLS_ERR_PK_BAD_INPUT_DATA);
TEST_ASSERT(mbedtls_pk_verify(&pk,
MBEDTLS_MD_NONE,
NULL, 0,
buf, sizeof(buf)) ==
MBEDTLS_ERR_PK_BAD_INPUT_DATA);
TEST_ASSERT(mbedtls_pk_verify_ext(MBEDTLS_PK_NONE, options,
&pk,
MBEDTLS_MD_NONE,
NULL, 0,
buf, sizeof(buf)) ==
MBEDTLS_ERR_PK_BAD_INPUT_DATA);
TEST_ASSERT(mbedtls_pk_encrypt(&pk,
NULL, 0,
NULL, &len, 0,
mbedtls_test_rnd_std_rand, NULL) ==
MBEDTLS_ERR_PK_BAD_INPUT_DATA);
TEST_ASSERT(mbedtls_pk_decrypt(&pk,
NULL, 0,
NULL, &len, 0,
mbedtls_test_rnd_std_rand, NULL) ==
MBEDTLS_ERR_PK_BAD_INPUT_DATA);
#if defined(MBEDTLS_PK_PARSE_C)
TEST_ASSERT(mbedtls_pk_parse_key(&pk, NULL, 0, NULL, 1,
mbedtls_test_rnd_std_rand, NULL) ==
MBEDTLS_ERR_PK_KEY_INVALID_FORMAT);
TEST_ASSERT(mbedtls_pk_parse_public_key(&pk, NULL, 0) ==
MBEDTLS_ERR_PK_KEY_INVALID_FORMAT);
#endif /* MBEDTLS_PK_PARSE_C */
USE_PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_PK_WRITE_C */
void valid_parameters_pkwrite(data_t *key_data)
{
mbedtls_pk_context pk;
/* For the write tests to be effective, we need a valid key pair. */
mbedtls_pk_init(&pk);
USE_PSA_INIT();
TEST_ASSERT(mbedtls_pk_parse_key(&pk,
key_data->x, key_data->len, NULL, 0,
mbedtls_test_rnd_std_rand, NULL) == 0);
TEST_ASSERT(mbedtls_pk_write_key_der(&pk, NULL, 0) ==
MBEDTLS_ERR_ASN1_BUF_TOO_SMALL);
TEST_ASSERT(mbedtls_pk_write_pubkey_der(&pk, NULL, 0) ==
MBEDTLS_ERR_ASN1_BUF_TOO_SMALL);
#if defined(MBEDTLS_PEM_WRITE_C)
TEST_ASSERT(mbedtls_pk_write_key_pem(&pk, NULL, 0) ==
MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL);
TEST_ASSERT(mbedtls_pk_write_pubkey_pem(&pk, NULL, 0) ==
MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL);
#endif /* MBEDTLS_PEM_WRITE_C */
exit:
mbedtls_pk_free(&pk);
USE_PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE */
void pk_utils(int type, int curve_or_keybits, int bitlen, int len, char *name)
{
mbedtls_pk_context pk;
mbedtls_pk_init(&pk);
USE_PSA_INIT();
TEST_ASSERT(mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(type)) == 0);
TEST_ASSERT(pk_genkey(&pk, curve_or_keybits) == 0);
TEST_ASSERT((int) mbedtls_pk_get_type(&pk) == type);
TEST_ASSERT(mbedtls_pk_can_do(&pk, type));
TEST_ASSERT(mbedtls_pk_get_bitlen(&pk) == (unsigned) bitlen);
TEST_ASSERT(mbedtls_pk_get_len(&pk) == (unsigned) len);
TEST_ASSERT(strcmp(mbedtls_pk_get_name(&pk), name) == 0);
exit:
mbedtls_pk_free(&pk);
USE_PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_FS_IO */
void mbedtls_pk_check_pair(char *pub_file, char *prv_file, int ret)
{
mbedtls_pk_context pub, prv, alt;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
mbedtls_svc_key_id_t opaque_key_id = MBEDTLS_SVC_KEY_ID_INIT;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
mbedtls_pk_init(&pub);
mbedtls_pk_init(&prv);
mbedtls_pk_init(&alt);
USE_PSA_INIT();
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/* mbedtls_pk_check_pair() returns either PK or ECP error codes depending
on MBEDTLS_USE_PSA_CRYPTO so here we dynamically translate between the
two */
if (ret == MBEDTLS_ERR_ECP_BAD_INPUT_DATA) {
ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
TEST_ASSERT(mbedtls_pk_parse_public_keyfile(&pub, pub_file) == 0);
TEST_ASSERT(mbedtls_pk_parse_keyfile(&prv, prv_file, NULL,
mbedtls_test_rnd_std_rand, NULL)
== 0);
TEST_ASSERT(mbedtls_pk_check_pair(&pub, &prv,
mbedtls_test_rnd_std_rand, NULL)
== ret);
#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
if (mbedtls_pk_get_type(&prv) == MBEDTLS_PK_RSA) {
TEST_ASSERT(mbedtls_pk_setup_rsa_alt(&alt, mbedtls_pk_rsa(prv),
mbedtls_rsa_decrypt_func, mbedtls_rsa_sign_func,
mbedtls_rsa_key_len_func) == 0);
TEST_ASSERT(mbedtls_pk_check_pair(&pub, &alt,
mbedtls_test_rnd_std_rand, NULL)
== ret);
}
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if (mbedtls_pk_get_type(&prv) == MBEDTLS_PK_ECKEY) {
TEST_EQUAL(mbedtls_pk_wrap_as_opaque(&prv, &opaque_key_id,
PSA_ALG_ANY_HASH,
PSA_KEY_USAGE_EXPORT, 0), 0);
TEST_EQUAL(mbedtls_pk_check_pair(&pub, &prv, mbedtls_test_rnd_std_rand,
NULL), ret);
}
#endif
exit:
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_destroy_key(opaque_key_id);
#endif /* MBEDTLS_USE_PSA_CRYPTO */
mbedtls_pk_free(&pub);
mbedtls_pk_free(&prv);
mbedtls_pk_free(&alt);
USE_PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_RSA_C */
void pk_rsa_verify_test_vec(data_t *message_str, int digest, int mod,
char *input_N, char *input_E,
data_t *result_str, int result)
{
mbedtls_rsa_context *rsa;
mbedtls_pk_context pk;
mbedtls_pk_restart_ctx *rs_ctx = NULL;
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
mbedtls_pk_restart_ctx ctx;
rs_ctx = &ctx;
mbedtls_pk_restart_init(rs_ctx);
// this setting would ensure restart would happen if ECC was used
mbedtls_ecp_set_max_ops(1);
#endif
mbedtls_pk_init(&pk);
USE_PSA_INIT();
TEST_ASSERT(mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)) == 0);
rsa = mbedtls_pk_rsa(pk);
rsa->len = mod / 8;
TEST_ASSERT(mbedtls_test_read_mpi(&rsa->N, input_N) == 0);
TEST_ASSERT(mbedtls_test_read_mpi(&rsa->E, input_E) == 0);
TEST_ASSERT(mbedtls_pk_verify(&pk, digest, message_str->x, 0,
result_str->x, mbedtls_pk_get_len(&pk)) == result);
TEST_ASSERT(mbedtls_pk_verify_restartable(&pk, digest, message_str->x, 0,
result_str->x, mbedtls_pk_get_len(
&pk), rs_ctx) == result);
exit:
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
mbedtls_pk_restart_free(rs_ctx);
#endif
mbedtls_pk_free(&pk);
USE_PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_RSA_C */
void pk_rsa_verify_ext_test_vec(data_t *message_str, int digest,
int mod, char *input_N,
char *input_E, data_t *result_str,
int pk_type, int mgf1_hash_id,
int salt_len, int sig_len,
int result)
{
mbedtls_rsa_context *rsa;
mbedtls_pk_context pk;
mbedtls_pk_rsassa_pss_options pss_opts;
void *options;
int ret;
mbedtls_pk_init(&pk);
MD_OR_USE_PSA_INIT();
TEST_ASSERT(mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)) == 0);
rsa = mbedtls_pk_rsa(pk);
rsa->len = mod / 8;
TEST_ASSERT(mbedtls_test_read_mpi(&rsa->N, input_N) == 0);
TEST_ASSERT(mbedtls_test_read_mpi(&rsa->E, input_E) == 0);
if (mgf1_hash_id < 0) {
options = NULL;
} else {
options = &pss_opts;
pss_opts.mgf1_hash_id = mgf1_hash_id;
pss_opts.expected_salt_len = salt_len;
}
ret = mbedtls_pk_verify_ext(pk_type, options, &pk,
digest, message_str->x, message_str->len,
result_str->x, sig_len);
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if (result == MBEDTLS_ERR_RSA_INVALID_PADDING) {
/* Mbed TLS distinguishes "invalid padding" from "valid padding but
* the rest of the signature is invalid". This has little use in
* practice and PSA doesn't report this distinction.
* In this case, PSA returns PSA_ERROR_INVALID_SIGNATURE translated
* to MBEDTLS_ERR_RSA_VERIFY_FAILED.
* However, currently `mbedtls_pk_verify_ext()` may use either the
* PSA or the Mbed TLS API, depending on the PSS options used.
* So, it may return either INVALID_PADDING or INVALID_SIGNATURE.
*/
TEST_ASSERT(ret == result || ret == MBEDTLS_ERR_RSA_VERIFY_FAILED);
} else
#endif
{
TEST_EQUAL(ret, result);
}
exit:
mbedtls_pk_free(&pk);
MD_OR_USE_PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_PK_CAN_ECDSA_VERIFY */
void pk_ec_test_vec(int type, int id, data_t *key, data_t *hash,
data_t *sig, int ret)
{
mbedtls_pk_context pk;
mbedtls_pk_init(&pk);
USE_PSA_INIT();
TEST_ASSERT(mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(type)) == 0);
TEST_ASSERT(mbedtls_pk_can_do(&pk, MBEDTLS_PK_ECDSA));
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
TEST_ASSERT(key->len <= MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN);
memcpy(pk.pub_raw, key->x, key->len);
pk.ec_family = mbedtls_ecc_group_to_psa(id, &(pk.ec_bits));
pk.pub_raw_len = key->len;
#else
mbedtls_ecp_keypair *eckey = (mbedtls_ecp_keypair *) mbedtls_pk_ec(pk);
TEST_ASSERT(mbedtls_ecp_group_load(&eckey->grp, id) == 0);
TEST_ASSERT(mbedtls_ecp_point_read_binary(&eckey->grp, &eckey->Q,
key->x, key->len) == 0);
#endif
// MBEDTLS_MD_NONE is used since it will be ignored.
TEST_ASSERT(mbedtls_pk_verify(&pk, MBEDTLS_MD_NONE,
hash->x, hash->len, sig->x, sig->len) == ret);
exit:
mbedtls_pk_free(&pk);
USE_PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE:MBEDTLS_ECDSA_C:MBEDTLS_ECDSA_DETERMINISTIC */
void pk_sign_verify_restart(int pk_type, int grp_id, char *d_str,
char *QX_str, char *QY_str,
int md_alg, data_t *hash, data_t *sig_check,
int max_ops, int min_restart, int max_restart)
{
int ret, cnt_restart;
mbedtls_pk_restart_ctx rs_ctx;
mbedtls_pk_context prv, pub;
unsigned char sig[MBEDTLS_ECDSA_MAX_LEN];
size_t slen;
mbedtls_pk_restart_init(&rs_ctx);
mbedtls_pk_init(&prv);
mbedtls_pk_init(&pub);
USE_PSA_INIT();
memset(sig, 0, sizeof(sig));
TEST_ASSERT(mbedtls_pk_setup(&prv, mbedtls_pk_info_from_type(pk_type)) == 0);
TEST_ASSERT(mbedtls_ecp_group_load(&mbedtls_pk_ec_rw(prv)->grp, grp_id) == 0);
TEST_ASSERT(mbedtls_test_read_mpi(&mbedtls_pk_ec_rw(prv)->d, d_str) == 0);
TEST_ASSERT(mbedtls_pk_setup(&pub, mbedtls_pk_info_from_type(pk_type)) == 0);
TEST_ASSERT(mbedtls_ecp_group_load(&mbedtls_pk_ec_rw(pub)->grp, grp_id) == 0);
TEST_ASSERT(mbedtls_ecp_point_read_string(&mbedtls_pk_ec_rw(pub)->Q, 16, QX_str, QY_str) == 0);
mbedtls_ecp_set_max_ops(max_ops);
slen = sizeof(sig);
cnt_restart = 0;
do {
ret = mbedtls_pk_sign_restartable(&prv, md_alg, hash->x, hash->len,
sig, sizeof(sig), &slen,
mbedtls_test_rnd_std_rand, NULL,
&rs_ctx);
} while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart);
TEST_ASSERT(ret == 0);
TEST_ASSERT(slen == sig_check->len);
TEST_ASSERT(memcmp(sig, sig_check->x, slen) == 0);
TEST_ASSERT(cnt_restart >= min_restart);
TEST_ASSERT(cnt_restart <= max_restart);
cnt_restart = 0;
do {
ret = mbedtls_pk_verify_restartable(&pub, md_alg,
hash->x, hash->len, sig, slen, &rs_ctx);
} while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart);
TEST_ASSERT(ret == 0);
TEST_ASSERT(cnt_restart >= min_restart);
TEST_ASSERT(cnt_restart <= max_restart);
sig[0]++;
do {
ret = mbedtls_pk_verify_restartable(&pub, md_alg,
hash->x, hash->len, sig, slen, &rs_ctx);
} while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
TEST_ASSERT(ret != 0);
sig[0]--;
/* Do we leak memory when aborting? try verify then sign
* This test only makes sense when we actually restart */
if (min_restart > 0) {
ret = mbedtls_pk_verify_restartable(&pub, md_alg,
hash->x, hash->len, sig, slen, &rs_ctx);
TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
mbedtls_pk_restart_free(&rs_ctx);
slen = sizeof(sig);
ret = mbedtls_pk_sign_restartable(&prv, md_alg, hash->x, hash->len,
sig, sizeof(sig), &slen,
mbedtls_test_rnd_std_rand, NULL,
&rs_ctx);
TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
}
exit:
mbedtls_pk_restart_free(&rs_ctx);
mbedtls_pk_free(&prv);
mbedtls_pk_free(&pub);
USE_PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_MD_CAN_SHA256:PK_CAN_SIGN_SOME */
void pk_sign_verify(int type, int curve_or_keybits, int sign_ret, int verify_ret)
{
mbedtls_pk_context pk;
size_t sig_len;
unsigned char hash[32]; // Hard-coded for SHA256
size_t hash_len = sizeof(hash);
unsigned char sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE];
void *rs_ctx = NULL;
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
mbedtls_pk_restart_ctx ctx;
rs_ctx = &ctx;
mbedtls_pk_restart_init(rs_ctx);
/* This value is large enough that the operation will complete in one run.
* See comments at the top of ecp_test_vect_restart in
* test_suite_ecp.function for estimates of operation counts. */
mbedtls_ecp_set_max_ops(42000);
#endif
mbedtls_pk_init(&pk);
MD_OR_USE_PSA_INIT();
memset(hash, 0x2a, sizeof(hash));
memset(sig, 0, sizeof(sig));
TEST_ASSERT(mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(type)) == 0);
TEST_ASSERT(pk_genkey(&pk, curve_or_keybits) == 0);
TEST_ASSERT(mbedtls_pk_sign_restartable(&pk, MBEDTLS_MD_SHA256,
hash, hash_len,
sig, sizeof(sig), &sig_len,
mbedtls_test_rnd_std_rand, NULL,
rs_ctx) == sign_ret);
if (sign_ret == 0) {
TEST_ASSERT(sig_len <= MBEDTLS_PK_SIGNATURE_MAX_SIZE);
} else {
sig_len = MBEDTLS_PK_SIGNATURE_MAX_SIZE;
}
TEST_ASSERT(mbedtls_pk_verify(&pk, MBEDTLS_MD_SHA256,
hash, hash_len, sig, sig_len) == verify_ret);
if (verify_ret == 0) {
hash[0]++;
TEST_ASSERT(mbedtls_pk_verify(&pk, MBEDTLS_MD_SHA256,
hash, hash_len, sig, sig_len) != 0);
hash[0]--;
sig[0]++;
TEST_ASSERT(mbedtls_pk_verify(&pk, MBEDTLS_MD_SHA256,
hash, hash_len, sig, sig_len) != 0);
sig[0]--;
}
TEST_ASSERT(mbedtls_pk_sign(&pk, MBEDTLS_MD_SHA256, hash, hash_len,
sig, sizeof(sig), &sig_len,
mbedtls_test_rnd_std_rand,
NULL) == sign_ret);
if (sign_ret == 0) {
TEST_ASSERT(sig_len <= MBEDTLS_PK_SIGNATURE_MAX_SIZE);
} else {
sig_len = MBEDTLS_PK_SIGNATURE_MAX_SIZE;
}
TEST_ASSERT(mbedtls_pk_verify_restartable(&pk, MBEDTLS_MD_SHA256,
hash, hash_len, sig, sig_len, rs_ctx) == verify_ret);
if (verify_ret == 0) {
hash[0]++;
TEST_ASSERT(mbedtls_pk_verify_restartable(&pk, MBEDTLS_MD_SHA256,
hash, sizeof(hash), sig, sig_len, rs_ctx) != 0);
hash[0]--;
sig[0]++;
TEST_ASSERT(mbedtls_pk_verify_restartable(&pk, MBEDTLS_MD_SHA256,
hash, sizeof(hash), sig, sig_len, rs_ctx) != 0);
sig[0]--;
}
exit:
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
mbedtls_pk_restart_free(rs_ctx);
#endif
mbedtls_pk_free(&pk);
MD_OR_USE_PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_RSA_C */
void pk_rsa_encrypt_decrypt_test(data_t *message, int mod,
char *input_P, char *input_Q,
char *input_N, char *input_E,
int ret)
{
unsigned char output[300], result[300];
mbedtls_test_rnd_pseudo_info rnd_info;
mbedtls_mpi N, P, Q, E;
mbedtls_rsa_context *rsa;
mbedtls_pk_context pk;
size_t olen, rlen;
mbedtls_pk_init(&pk);
mbedtls_mpi_init(&N); mbedtls_mpi_init(&P);
mbedtls_mpi_init(&Q); mbedtls_mpi_init(&E);
USE_PSA_INIT();
memset(&rnd_info, 0, sizeof(mbedtls_test_rnd_pseudo_info));
memset(output, 0, sizeof(output));
/* encryption test */
/* init pk-rsa context */
TEST_ASSERT(mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)) == 0);
rsa = mbedtls_pk_rsa(pk);
/* load public key */
rsa->len = mod / 8;
TEST_ASSERT(mbedtls_test_read_mpi(&rsa->N, input_N) == 0);
TEST_ASSERT(mbedtls_test_read_mpi(&rsa->E, input_E) == 0);
TEST_ASSERT(mbedtls_pk_encrypt(&pk, message->x, message->len,
output, &olen, sizeof(output),
mbedtls_test_rnd_pseudo_rand, &rnd_info) == ret);
/* decryption test */
mbedtls_mpi_init(&N); mbedtls_mpi_init(&P);
mbedtls_mpi_init(&Q); mbedtls_mpi_init(&E);
/* init pk-rsa context */
mbedtls_pk_free(&pk);
TEST_ASSERT(mbedtls_pk_setup(&pk,
mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)) == 0);
rsa = mbedtls_pk_rsa(pk);
/* load public key */
TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
/* load private key */
TEST_ASSERT(mbedtls_test_read_mpi(&P, input_P) == 0);
TEST_ASSERT(mbedtls_test_read_mpi(&Q, input_Q) == 0);
TEST_ASSERT(mbedtls_rsa_import(rsa, &N, &P, &Q, NULL, &E) == 0);
TEST_ASSERT(mbedtls_rsa_get_len(rsa) == (size_t) (mod / 8));
TEST_ASSERT(mbedtls_rsa_complete(rsa) == 0);
memset(result, 0, sizeof(result));
rlen = 0;
TEST_ASSERT(mbedtls_pk_decrypt(&pk, output, olen,
result, &rlen, sizeof(result),
mbedtls_test_rnd_pseudo_rand, &rnd_info) == ret);
if (ret == 0) {
TEST_ASSERT(rlen == message->len);
TEST_ASSERT(memcmp(result, message->x, rlen) == 0);
}
exit:
mbedtls_mpi_free(&N); mbedtls_mpi_free(&P);
mbedtls_mpi_free(&Q); mbedtls_mpi_free(&E);
mbedtls_pk_free(&pk);
USE_PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_RSA_C */
void pk_rsa_decrypt_test_vec(data_t *cipher, int mod,
char *input_P, char *input_Q,
char *input_N, char *input_E,
data_t *clear, int ret)
{
unsigned char output[256];
mbedtls_test_rnd_pseudo_info rnd_info;
mbedtls_mpi N, P, Q, E;
mbedtls_rsa_context *rsa;
mbedtls_pk_context pk;
size_t olen;
mbedtls_pk_init(&pk);
mbedtls_mpi_init(&N); mbedtls_mpi_init(&P);
mbedtls_mpi_init(&Q); mbedtls_mpi_init(&E);
USE_PSA_INIT();
memset(&rnd_info, 0, sizeof(mbedtls_test_rnd_pseudo_info));
/* init pk-rsa context */
TEST_ASSERT(mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)) == 0);
rsa = mbedtls_pk_rsa(pk);
/* load public key */
TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
/* load private key */
TEST_ASSERT(mbedtls_test_read_mpi(&P, input_P) == 0);
TEST_ASSERT(mbedtls_test_read_mpi(&Q, input_Q) == 0);
TEST_ASSERT(mbedtls_rsa_import(rsa, &N, &P, &Q, NULL, &E) == 0);
TEST_ASSERT(mbedtls_rsa_get_len(rsa) == (size_t) (mod / 8));
TEST_ASSERT(mbedtls_rsa_complete(rsa) == 0);
/* decryption test */
memset(output, 0, sizeof(output));
olen = 0;
TEST_ASSERT(mbedtls_pk_decrypt(&pk, cipher->x, cipher->len,
output, &olen, sizeof(output),
mbedtls_test_rnd_pseudo_rand, &rnd_info) == ret);
if (ret == 0) {
TEST_ASSERT(olen == clear->len);
TEST_ASSERT(memcmp(output, clear->x, olen) == 0);
}
exit:
mbedtls_mpi_free(&N); mbedtls_mpi_free(&P);
mbedtls_mpi_free(&Q); mbedtls_mpi_free(&E);
mbedtls_pk_free(&pk);
USE_PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_USE_PSA_CRYPTO */
void pk_wrap_rsa_decrypt_test_vec(data_t *cipher, int mod,
char *input_P, char *input_Q,
char *input_N, char *input_E,
data_t *clear, int ret)
{
unsigned char output[256];
mbedtls_test_rnd_pseudo_info rnd_info;
mbedtls_mpi N, P, Q, E;
mbedtls_rsa_context *rsa;
mbedtls_pk_context pk;
mbedtls_svc_key_id_t key_id;
size_t olen;
mbedtls_pk_init(&pk);
mbedtls_mpi_init(&N); mbedtls_mpi_init(&P);
mbedtls_mpi_init(&Q); mbedtls_mpi_init(&E);
USE_PSA_INIT();
memset(&rnd_info, 0, sizeof(mbedtls_test_rnd_pseudo_info));
/* init pk-rsa context */
TEST_EQUAL(mbedtls_pk_setup(&pk,
mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)), 0);
rsa = mbedtls_pk_rsa(pk);
/* load public key */
TEST_EQUAL(mbedtls_test_read_mpi(&N, input_N), 0);
TEST_EQUAL(mbedtls_test_read_mpi(&E, input_E), 0);
/* load private key */
TEST_EQUAL(mbedtls_test_read_mpi(&P, input_P), 0);
TEST_EQUAL(mbedtls_test_read_mpi(&Q, input_Q), 0);
TEST_EQUAL(mbedtls_rsa_import(rsa, &N, &P, &Q, NULL, &E), 0);
TEST_EQUAL(mbedtls_rsa_get_len(rsa), (size_t) (mod / 8));
TEST_EQUAL(mbedtls_rsa_complete(rsa), 0);
/* Turn PK context into an opaque one. */
TEST_EQUAL(mbedtls_pk_wrap_as_opaque(&pk, &key_id,
PSA_ALG_RSA_PKCS1V15_CRYPT,
PSA_KEY_USAGE_DECRYPT,
PSA_ALG_NONE), 0);
/* decryption test */
memset(output, 0, sizeof(output));
olen = 0;
TEST_EQUAL(mbedtls_pk_decrypt(&pk, cipher->x, cipher->len,
output, &olen, sizeof(output),
mbedtls_test_rnd_pseudo_rand, &rnd_info), ret);
if (ret == 0) {
TEST_EQUAL(olen, clear->len);
TEST_EQUAL(memcmp(output, clear->x, olen), 0);
}
TEST_EQUAL(PSA_SUCCESS, psa_destroy_key(key_id));
exit:
mbedtls_mpi_free(&N); mbedtls_mpi_free(&P);
mbedtls_mpi_free(&Q); mbedtls_mpi_free(&E);
mbedtls_pk_free(&pk);
USE_PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE */
void pk_ec_nocrypt(int type)
{
mbedtls_pk_context pk;
unsigned char output[100];
unsigned char input[100];
mbedtls_test_rnd_pseudo_info rnd_info;
size_t olen = 0;
int ret = MBEDTLS_ERR_PK_TYPE_MISMATCH;
mbedtls_pk_init(&pk);
USE_PSA_INIT();
memset(&rnd_info, 0, sizeof(mbedtls_test_rnd_pseudo_info));
memset(output, 0, sizeof(output));
memset(input, 0, sizeof(input));
TEST_ASSERT(mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(type)) == 0);
TEST_ASSERT(mbedtls_pk_encrypt(&pk, input, sizeof(input),
output, &olen, sizeof(output),
mbedtls_test_rnd_pseudo_rand, &rnd_info) == ret);
TEST_ASSERT(mbedtls_pk_decrypt(&pk, input, sizeof(input),
output, &olen, sizeof(output),
mbedtls_test_rnd_pseudo_rand, &rnd_info) == ret);
exit:
mbedtls_pk_free(&pk);
USE_PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_RSA_C */
void pk_rsa_overflow()
{
mbedtls_pk_context pk;
size_t hash_len = UINT_MAX + 1, sig_len = UINT_MAX + 1;
unsigned char hash[50], sig[100];
mbedtls_pk_init(&pk);
USE_PSA_INIT();
memset(hash, 0x2a, sizeof(hash));
memset(sig, 0, sizeof(sig));
TEST_EQUAL(mbedtls_pk_setup(&pk,
mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)), 0);
#if defined(MBEDTLS_PKCS1_V21)
TEST_EQUAL(mbedtls_pk_verify_ext(MBEDTLS_PK_RSASSA_PSS, NULL, &pk,
MBEDTLS_MD_NONE, hash, hash_len, sig, sig_len),
MBEDTLS_ERR_PK_BAD_INPUT_DATA);
#endif /* MBEDTLS_PKCS1_V21 */
TEST_EQUAL(mbedtls_pk_verify(&pk, MBEDTLS_MD_NONE, hash, hash_len,
sig, sig_len),
MBEDTLS_ERR_PK_BAD_INPUT_DATA);
#if defined(MBEDTLS_PKCS1_V21)
TEST_EQUAL(mbedtls_pk_sign_ext(MBEDTLS_PK_RSASSA_PSS, &pk,
MBEDTLS_MD_NONE, hash, hash_len,
sig, sizeof(sig), &sig_len,
mbedtls_test_rnd_std_rand, NULL),
MBEDTLS_ERR_PK_BAD_INPUT_DATA);
#endif /* MBEDTLS_PKCS1_V21 */
TEST_EQUAL(mbedtls_pk_sign(&pk, MBEDTLS_MD_NONE, hash, hash_len,
sig, sizeof(sig), &sig_len,
mbedtls_test_rnd_std_rand, NULL),
MBEDTLS_ERR_PK_BAD_INPUT_DATA);
exit:
mbedtls_pk_free(&pk);
USE_PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_PK_RSA_ALT_SUPPORT */
void pk_rsa_alt()
{
/*
* An rsa_alt context can only do private operations (decrypt, sign).
* Test it against the public operations (encrypt, verify) of a
* corresponding rsa context.
*/
mbedtls_rsa_context raw;
mbedtls_pk_context rsa, alt;
mbedtls_pk_debug_item dbg_items[10];
unsigned char hash[50], sig[RSA_KEY_LEN];
unsigned char msg[50], ciph[RSA_KEY_LEN], test[50];
size_t sig_len, ciph_len, test_len;
int ret = MBEDTLS_ERR_PK_TYPE_MISMATCH;
mbedtls_rsa_init(&raw);
mbedtls_pk_init(&rsa);
mbedtls_pk_init(&alt);
USE_PSA_INIT();
memset(hash, 0x2a, sizeof(hash));
memset(sig, 0, sizeof(sig));
memset(msg, 0x2a, sizeof(msg));
memset(ciph, 0, sizeof(ciph));
memset(test, 0, sizeof(test));
/* Initialize PK RSA context with random key */
TEST_ASSERT(mbedtls_pk_setup(&rsa,
mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)) == 0);
TEST_ASSERT(pk_genkey(&rsa, RSA_KEY_SIZE) == 0);
/* Extract key to the raw rsa context */
TEST_ASSERT(mbedtls_rsa_copy(&raw, mbedtls_pk_rsa(rsa)) == 0);
/* Initialize PK RSA_ALT context */
TEST_ASSERT(mbedtls_pk_setup_rsa_alt(&alt, (void *) &raw,
mbedtls_rsa_decrypt_func, mbedtls_rsa_sign_func,
mbedtls_rsa_key_len_func) == 0);
/* Test administrative functions */
TEST_ASSERT(mbedtls_pk_can_do(&alt, MBEDTLS_PK_RSA));
TEST_ASSERT(mbedtls_pk_get_bitlen(&alt) == RSA_KEY_SIZE);
TEST_ASSERT(mbedtls_pk_get_len(&alt) == RSA_KEY_LEN);
TEST_ASSERT(mbedtls_pk_get_type(&alt) == MBEDTLS_PK_RSA_ALT);
TEST_ASSERT(strcmp(mbedtls_pk_get_name(&alt), "RSA-alt") == 0);
#if defined(MBEDTLS_PSA_CRYPTO_C)
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
TEST_EQUAL(mbedtls_pk_get_psa_attributes(&alt,
PSA_KEY_USAGE_ENCRYPT,
&attributes),
MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE);
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
TEST_EQUAL(mbedtls_pk_import_into_psa(&alt, &attributes, &key_id),
MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE);
#endif /* MBEDTLS_PSA_CRYPTO_C */
/* Test signature */
#if SIZE_MAX > UINT_MAX
TEST_ASSERT(mbedtls_pk_sign(&alt, MBEDTLS_MD_NONE, hash, SIZE_MAX,
sig, sizeof(sig), &sig_len,
mbedtls_test_rnd_std_rand, NULL)
== MBEDTLS_ERR_PK_BAD_INPUT_DATA);
#endif /* SIZE_MAX > UINT_MAX */
TEST_ASSERT(mbedtls_pk_sign(&alt, MBEDTLS_MD_NONE, hash, sizeof(hash),
sig, sizeof(sig), &sig_len,
mbedtls_test_rnd_std_rand, NULL)
== 0);
TEST_ASSERT(sig_len == RSA_KEY_LEN);
TEST_ASSERT(mbedtls_pk_verify(&rsa, MBEDTLS_MD_NONE,
hash, sizeof(hash), sig, sig_len) == 0);
/* Test decrypt */
TEST_ASSERT(mbedtls_pk_encrypt(&rsa, msg, sizeof(msg),
ciph, &ciph_len, sizeof(ciph),
mbedtls_test_rnd_std_rand, NULL) == 0);
TEST_ASSERT(mbedtls_pk_decrypt(&alt, ciph, ciph_len,
test, &test_len, sizeof(test),
mbedtls_test_rnd_std_rand, NULL) == 0);
TEST_ASSERT(test_len == sizeof(msg));
TEST_ASSERT(memcmp(test, msg, test_len) == 0);
/* Test forbidden operations */
TEST_ASSERT(mbedtls_pk_encrypt(&alt, msg, sizeof(msg),
ciph, &ciph_len, sizeof(ciph),
mbedtls_test_rnd_std_rand, NULL) == ret);
TEST_ASSERT(mbedtls_pk_verify(&alt, MBEDTLS_MD_NONE,
hash, sizeof(hash), sig, sig_len) == ret);
TEST_ASSERT(mbedtls_pk_debug(&alt, dbg_items) == ret);
exit:
mbedtls_rsa_free(&raw);
mbedtls_pk_free(&rsa); mbedtls_pk_free(&alt);
USE_PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_MD_CAN_SHA256:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_PK_PSA_SIGN */
void pk_psa_sign(int curve_or_keybits, int psa_type, int expected_bits)
{
mbedtls_pk_context pk;
unsigned char hash[32];
unsigned char sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE];
unsigned char pkey_legacy[200];
unsigned char pkey_psa[200];
unsigned char *pkey_legacy_start, *pkey_psa_start;
psa_algorithm_t alg_psa;
size_t sig_len, klen_legacy, klen_psa;
int ret;
mbedtls_svc_key_id_t key_id;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
/*
* This tests making signatures with a wrapped PSA key:
* - generate a fresh ECP/RSA legacy PK context
* - wrap it in a PK context and make a signature this way
* - extract the public key
* - parse it to a PK context and verify the signature this way
*/
mbedtls_pk_init(&pk);
USE_PSA_INIT();
#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
if (PSA_KEY_TYPE_IS_RSA(psa_type)) {
/* Create legacy RSA public/private key in PK context. */
TEST_ASSERT(mbedtls_pk_setup(&pk,
mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)) == 0);
TEST_ASSERT(mbedtls_rsa_gen_key(mbedtls_pk_rsa(pk),
mbedtls_test_rnd_std_rand, NULL,
curve_or_keybits, 3) == 0);
alg_psa = PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256);
} else
#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */
#if defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(psa_type)) {
mbedtls_ecp_group_id grpid = curve_or_keybits;
/* Create legacy EC public/private key in PK context. */
TEST_ASSERT(mbedtls_pk_setup(&pk,
mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)) == 0);
TEST_ASSERT(pk_genkey(&pk, grpid) == 0);
alg_psa = PSA_ALG_ECDSA(PSA_ALG_SHA_256);
} else
#endif /* MBEDTLS_PK_CAN_ECDSA_SIGN */
{
(void) curve_or_keybits;
TEST_ASSUME(!"Opaque PK key not supported in this configuration");
}
/* Export underlying public key for re-importing in a legacy context. */
#if defined(MBEDTLS_PK_WRITE_C)
ret = mbedtls_pk_write_pubkey_der(&pk, pkey_legacy,
sizeof(pkey_legacy));
TEST_ASSERT(ret >= 0);
klen_legacy = (size_t) ret;
/* mbedtls_pk_write_pubkey_der() writes backwards in the data buffer. */
pkey_legacy_start = pkey_legacy + sizeof(pkey_legacy) - klen_legacy;
#else
ret = mbedtls_ecp_point_write_binary(&(mbedtls_pk_ec_ro(pk)->grp),
&(mbedtls_pk_ec_ro(pk)->Q),
MBEDTLS_ECP_PF_UNCOMPRESSED,
&klen_legacy, pkey_legacy,
sizeof(pkey_legacy));
TEST_EQUAL(ret, 0);
pkey_legacy_start = pkey_legacy;
#endif /* MBEDTLS_PK_WRITE_C */
/* Turn PK context into an opaque one. */
TEST_ASSERT(mbedtls_pk_wrap_as_opaque(&pk, &key_id, alg_psa,
PSA_KEY_USAGE_SIGN_HASH,
PSA_ALG_NONE) == 0);
PSA_ASSERT(psa_get_key_attributes(key_id, &attributes));
TEST_EQUAL(psa_get_key_type(&attributes), (psa_key_type_t) psa_type);
TEST_EQUAL(psa_get_key_bits(&attributes), (size_t) expected_bits);
TEST_EQUAL(psa_get_key_lifetime(&attributes),
PSA_KEY_LIFETIME_VOLATILE);
memset(hash, 0x2a, sizeof(hash));
memset(sig, 0, sizeof(sig));
TEST_ASSERT(mbedtls_pk_sign(&pk, MBEDTLS_MD_SHA256,
hash, sizeof(hash), sig, sizeof(sig), &sig_len,
NULL, NULL) == 0);
/* Only opaque EC keys support verification. */
if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(psa_type)) {
TEST_ASSERT(mbedtls_pk_verify(&pk, MBEDTLS_MD_SHA256,
hash, sizeof(hash), sig, sig_len) == 0);
}
/* Export underlying public key for re-importing in a psa context. */
#if defined(MBEDTLS_PK_WRITE_C)
ret = mbedtls_pk_write_pubkey_der(&pk, pkey_psa,
sizeof(pkey_psa));
TEST_ASSERT(ret >= 0);
klen_psa = (size_t) ret;
/* mbedtls_pk_write_pubkey_der() writes backwards in the data buffer. */
pkey_psa_start = pkey_psa + sizeof(pkey_psa) - klen_psa;
#else
psa_status_t status;
status = psa_export_public_key(key_id, pkey_psa, sizeof(pkey_psa),
&klen_psa);
TEST_EQUAL(status, PSA_SUCCESS);
pkey_psa_start = pkey_psa;
#endif /* MBEDTLS_PK_WRITE_C */
TEST_ASSERT(klen_psa == klen_legacy);
TEST_ASSERT(memcmp(pkey_psa_start, pkey_legacy_start, klen_psa) == 0);
mbedtls_pk_free(&pk);
TEST_ASSERT(PSA_SUCCESS == psa_destroy_key(key_id));
mbedtls_pk_init(&pk);
/* If we used "pk_write" previously, then we go for a "pk_parse" here;
* otherwise if we went for "ecp_point_write_binary" then we'll go
* for a "ecp_point_read_binary" here. This allows to drop dependencies
* on "PK_WRITE" and "PK_PARSE" if required */
#if defined(MBEDTLS_PK_WRITE_C) && defined(MBEDTLS_PK_PARSE_C)
TEST_EQUAL(mbedtls_pk_parse_public_key(&pk, pkey_legacy_start,
klen_legacy), 0);
#else
TEST_EQUAL(mbedtls_pk_setup(&pk,
mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)), 0);
TEST_EQUAL(mbedtls_ecp_group_load(
&(mbedtls_pk_ec_rw(pk)->grp),
(mbedtls_ecp_group_id) curve_or_keybits), 0);
TEST_EQUAL(mbedtls_ecp_point_read_binary(&(mbedtls_pk_ec_ro(pk)->grp),
&(mbedtls_pk_ec_rw(pk)->Q),
pkey_legacy_start, klen_legacy), 0);
#endif
TEST_ASSERT(mbedtls_pk_verify(&pk, MBEDTLS_MD_SHA256,
hash, sizeof(hash), sig, sig_len) == 0);
exit:
/*
* Key attributes may have been returned by psa_get_key_attributes()
* thus reset them as required.
*/
psa_reset_key_attributes(&attributes);
mbedtls_pk_free(&pk);
USE_PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
void pk_sign_ext(int pk_type, int curve_or_keybits, int key_pk_type, int md_alg)
{
mbedtls_pk_context pk;
size_t sig_len;
unsigned char sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE];
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
size_t hash_len = mbedtls_md_get_size_from_type(md_alg);
void const *options = NULL;
mbedtls_pk_rsassa_pss_options rsassa_pss_options;
memset(hash, 0x2a, sizeof(hash));
memset(sig, 0, sizeof(sig));
mbedtls_pk_init(&pk);
MD_OR_USE_PSA_INIT();
TEST_EQUAL(mbedtls_pk_setup(&pk,
mbedtls_pk_info_from_type(pk_type)), 0);
TEST_EQUAL(pk_genkey(&pk, curve_or_keybits), 0);
TEST_EQUAL(mbedtls_pk_sign_ext(key_pk_type, &pk, md_alg, hash, hash_len,
sig, sizeof(sig), &sig_len,
mbedtls_test_rnd_std_rand, NULL), 0);
if (key_pk_type == MBEDTLS_PK_RSASSA_PSS) {
rsassa_pss_options.mgf1_hash_id = md_alg;
TEST_ASSERT(hash_len != 0);
rsassa_pss_options.expected_salt_len = hash_len;
options = (const void *) &rsassa_pss_options;
}
TEST_EQUAL(mbedtls_pk_verify_ext(key_pk_type, options, &pk, md_alg,
hash, hash_len, sig, sig_len), 0);
exit:
mbedtls_pk_free(&pk);
MD_OR_USE_PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME:MBEDTLS_USE_PSA_CRYPTO */
void pk_psa_wrap_sign_ext(int pk_type, int key_bits, int key_pk_type, int md_alg)
{
mbedtls_pk_context pk;
size_t sig_len, pkey_len;
mbedtls_svc_key_id_t key_id;
unsigned char sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE];
unsigned char pkey[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
unsigned char *pkey_start;
unsigned char hash[PSA_HASH_MAX_SIZE];
psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
psa_algorithm_t psa_alg;
size_t hash_len = PSA_HASH_LENGTH(psa_md_alg);
void const *options = NULL;
mbedtls_pk_rsassa_pss_options rsassa_pss_options;
int ret;
mbedtls_pk_init(&pk);
PSA_INIT();
/* Create legacy RSA public/private key in PK context. */
mbedtls_pk_init(&pk);
TEST_EQUAL(mbedtls_pk_setup(&pk,
mbedtls_pk_info_from_type(pk_type)), 0);
TEST_EQUAL(mbedtls_rsa_gen_key(mbedtls_pk_rsa(pk),
mbedtls_test_rnd_std_rand, NULL,
key_bits, 3), 0);
/* Export underlying public key for re-importing in a legacy context. */
ret = mbedtls_pk_write_pubkey_der(&pk, pkey, sizeof(pkey));
TEST_ASSERT(ret >= 0);
pkey_len = (size_t) ret;
/* mbedtls_pk_write_pubkey_der() writes backwards in the data buffer. */
pkey_start = pkey + sizeof(pkey) - pkey_len;
if (key_pk_type == MBEDTLS_PK_RSA) {
psa_alg = PSA_ALG_RSA_PKCS1V15_SIGN(psa_md_alg);
} else if (key_pk_type == MBEDTLS_PK_RSASSA_PSS) {
psa_alg = PSA_ALG_RSA_PSS(psa_md_alg);
} else {
TEST_ASSUME(!"PK key type not supported in this configuration");
}
/* Turn PK context into an opaque one. */
TEST_EQUAL(mbedtls_pk_wrap_as_opaque(&pk, &key_id, psa_alg,
PSA_KEY_USAGE_SIGN_HASH,
PSA_ALG_NONE), 0);
memset(hash, 0x2a, sizeof(hash));
memset(sig, 0, sizeof(sig));
TEST_EQUAL(mbedtls_pk_sign_ext(key_pk_type, &pk, md_alg, hash, hash_len,
sig, sizeof(sig), &sig_len,
mbedtls_test_rnd_std_rand, NULL), 0);
mbedtls_pk_free(&pk);
TEST_EQUAL(PSA_SUCCESS, psa_destroy_key(key_id));
mbedtls_pk_init(&pk);
TEST_EQUAL(mbedtls_pk_parse_public_key(&pk, pkey_start, pkey_len), 0);
if (key_pk_type == MBEDTLS_PK_RSASSA_PSS) {
rsassa_pss_options.mgf1_hash_id = md_alg;
TEST_ASSERT(hash_len != 0);
rsassa_pss_options.expected_salt_len = hash_len;
options = (const void *) &rsassa_pss_options;
}
TEST_EQUAL(mbedtls_pk_verify_ext(key_pk_type, options, &pk, md_alg,
hash, hash_len, sig, sig_len), 0);
exit:
mbedtls_pk_free(&pk);
PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_C */
void pk_get_psa_attributes(int pk_type, int from_pair,
int usage_arg,
int to_pair, int expected_alg)
{
mbedtls_pk_context pk;
mbedtls_pk_init(&pk);
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_key_usage_t usage = usage_arg;
mbedtls_svc_key_id_t new_key_id = MBEDTLS_SVC_KEY_ID_INIT;
PSA_INIT();
psa_key_type_t expected_psa_type = 0;
TEST_EQUAL(pk_setup_for_type(pk_type, from_pair,
&pk, &expected_psa_type), 0);
if (!to_pair) {
expected_psa_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(expected_psa_type);
}
psa_key_lifetime_t lifetime = PSA_KEY_LIFETIME_VOLATILE; //TODO: diversity
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; //TODO: diversity
psa_set_key_id(&attributes, key_id);
psa_set_key_lifetime(&attributes, lifetime);
psa_set_key_enrollment_algorithm(&attributes, 42);
psa_key_usage_t expected_usage = pk_get_psa_attributes_implied_usage(usage);
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
/* When the resulting algorithm is ECDSA, the compile-time configuration
* can cause it to be either deterministic or randomized ECDSA.
* Rather than have two near-identical sets of test data depending on
* the configuration, always use randomized in the test data and
* tweak the expected result here. */
if (expected_alg == PSA_ALG_ECDSA(PSA_ALG_ANY_HASH)) {
expected_alg = PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_ANY_HASH);
}
#endif
TEST_EQUAL(mbedtls_pk_get_psa_attributes(&pk, usage, &attributes), 0);
TEST_EQUAL(psa_get_key_lifetime(&attributes), lifetime);
TEST_ASSERT(mbedtls_svc_key_id_equal(psa_get_key_id(&attributes),
key_id));
TEST_EQUAL(psa_get_key_type(&attributes), expected_psa_type);
TEST_EQUAL(psa_get_key_bits(&attributes),
mbedtls_pk_get_bitlen(&pk));
TEST_EQUAL(psa_get_key_usage_flags(&attributes), expected_usage);
TEST_EQUAL(psa_get_key_algorithm(&attributes), expected_alg);
TEST_EQUAL(psa_get_key_enrollment_algorithm(&attributes), PSA_ALG_NONE);
TEST_EQUAL(mbedtls_pk_import_into_psa(&pk, &attributes, &new_key_id), 0);
exit:
mbedtls_pk_free(&pk);
psa_reset_key_attributes(&attributes);
psa_destroy_key(new_key_id);
PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_GENPRIME */
void pk_rsa_v21_get_psa_attributes(int md_type, int from_pair,
int usage_arg,
int to_pair, int expected_alg)
{
mbedtls_pk_context pk;
mbedtls_pk_init(&pk);
psa_key_usage_t usage = usage_arg;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mbedtls_svc_key_id_t new_key_id = MBEDTLS_SVC_KEY_ID_INIT;
PSA_INIT();
psa_key_type_t expected_psa_type = 0;
TEST_EQUAL(pk_setup_for_type(MBEDTLS_PK_RSA, from_pair,
&pk, &expected_psa_type), 0);
mbedtls_rsa_context *rsa = mbedtls_pk_rsa(pk);
TEST_EQUAL(mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, md_type), 0);
if (!to_pair) {
expected_psa_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(expected_psa_type);
}
psa_key_usage_t expected_usage = pk_get_psa_attributes_implied_usage(usage);
TEST_EQUAL(mbedtls_pk_get_psa_attributes(&pk, usage, &attributes), 0);
TEST_EQUAL(psa_get_key_lifetime(&attributes), PSA_KEY_LIFETIME_VOLATILE);
TEST_ASSERT(mbedtls_svc_key_id_equal(psa_get_key_id(&attributes),
MBEDTLS_SVC_KEY_ID_INIT));
TEST_EQUAL(psa_get_key_type(&attributes), expected_psa_type);
TEST_EQUAL(psa_get_key_bits(&attributes),
mbedtls_pk_get_bitlen(&pk));
TEST_EQUAL(psa_get_key_usage_flags(&attributes), expected_usage);
TEST_EQUAL(psa_get_key_algorithm(&attributes), expected_alg);
TEST_EQUAL(psa_get_key_enrollment_algorithm(&attributes), PSA_ALG_NONE);
TEST_EQUAL(mbedtls_pk_import_into_psa(&pk, &attributes, &new_key_id), 0);
exit:
mbedtls_pk_free(&pk);
psa_reset_key_attributes(&attributes);
psa_destroy_key(new_key_id);
PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_C */
void pk_get_psa_attributes_fail(int pk_type, int from_pair,
int usage_arg,
int expected_ret)
{
mbedtls_pk_context pk;
mbedtls_pk_init(&pk);
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_key_usage_t usage = usage_arg;
PSA_INIT();
psa_key_type_t expected_psa_type;
TEST_EQUAL(pk_setup_for_type(pk_type, from_pair,
&pk, &expected_psa_type), 0);
TEST_EQUAL(mbedtls_pk_get_psa_attributes(&pk, usage, &attributes),
expected_ret);
exit:
mbedtls_pk_free(&pk);
psa_reset_key_attributes(&attributes);
PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_USE_PSA_CRYPTO */
void pk_get_psa_attributes_opaque(int from_type_arg, int from_bits_arg,
int from_usage_arg, int from_alg_arg,
int usage_arg,
int expected_ret,
int to_pair, int expected_usage_arg)
{
mbedtls_pk_context pk;
mbedtls_pk_init(&pk);
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mbedtls_svc_key_id_t old_key_id = MBEDTLS_SVC_KEY_ID_INIT;
psa_key_type_t from_type = from_type_arg;
size_t bits = from_bits_arg;
psa_key_usage_t from_usage = from_usage_arg;
psa_algorithm_t alg = from_alg_arg;
psa_key_usage_t usage = usage_arg;
psa_key_usage_t expected_usage = expected_usage_arg;
mbedtls_svc_key_id_t new_key_id = MBEDTLS_SVC_KEY_ID_INIT;
PSA_INIT();
psa_set_key_type(&attributes, from_type);
psa_set_key_bits(&attributes, bits);
psa_set_key_usage_flags(&attributes, from_usage);
psa_set_key_algorithm(&attributes, alg);
psa_set_key_enrollment_algorithm(&attributes, 42);
//TODO: test with persistent key
PSA_ASSERT(psa_generate_key(&attributes, &old_key_id));
TEST_EQUAL(mbedtls_pk_setup_opaque(&pk, old_key_id), 0);
psa_key_type_t expected_psa_type =
to_pair ? from_type : PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(from_type);
TEST_EQUAL(mbedtls_pk_get_psa_attributes(&pk, usage, &attributes),
expected_ret);
if (expected_ret == 0) {
TEST_EQUAL(psa_get_key_lifetime(&attributes), PSA_KEY_LIFETIME_VOLATILE);
TEST_ASSERT(mbedtls_svc_key_id_equal(psa_get_key_id(&attributes),
MBEDTLS_SVC_KEY_ID_INIT));
TEST_EQUAL(psa_get_key_type(&attributes), expected_psa_type);
TEST_EQUAL(psa_get_key_bits(&attributes), bits);
TEST_EQUAL(psa_get_key_usage_flags(&attributes), expected_usage);
TEST_EQUAL(psa_get_key_algorithm(&attributes), alg);
TEST_EQUAL(psa_get_key_enrollment_algorithm(&attributes), PSA_ALG_NONE);
int expected_import_ret = 0;
if (to_pair &&
!(from_usage & (PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_EXPORT))) {
expected_import_ret = MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
TEST_EQUAL(mbedtls_pk_import_into_psa(&pk, &attributes, &new_key_id),
expected_import_ret);
}
exit:
mbedtls_pk_free(&pk);
psa_destroy_key(old_key_id);
psa_destroy_key(new_key_id);
psa_reset_key_attributes(&attributes);
PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_C */
void pk_import_into_psa_fail(int pk_type, int from_pair,
int type_arg, int bits_arg,
int expected_ret)
{
mbedtls_pk_context pk;
mbedtls_pk_init(&pk);
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_key_type_t type = type_arg;
size_t bits = bits_arg;
mbedtls_svc_key_id_t key_id = mbedtls_svc_key_id_make(0, 42);
PSA_INIT();
psa_key_type_t expected_psa_type;
TEST_EQUAL(pk_setup_for_type(pk_type, from_pair,
&pk, &expected_psa_type), 0);
psa_set_key_type(&attributes, type);
psa_set_key_bits(&attributes, bits);
TEST_EQUAL(mbedtls_pk_import_into_psa(&pk, &attributes, &key_id),
expected_ret);
TEST_ASSERT(mbedtls_svc_key_id_equal(key_id, MBEDTLS_SVC_KEY_ID_INIT));
exit:
psa_destroy_key(key_id);
mbedtls_pk_free(&pk);
psa_reset_key_attributes(&attributes);
PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_USE_PSA_CRYPTO */
void pk_import_into_psa_opaque(int from_type, int from_bits,
int from_usage, int from_alg,
int to_type, int to_bits,
int to_usage, int to_alg,
int expected_ret)
{
mbedtls_pk_context pk;
mbedtls_pk_init(&pk);
psa_key_attributes_t from_attributes = PSA_KEY_ATTRIBUTES_INIT;
mbedtls_svc_key_id_t from_key_id = MBEDTLS_SVC_KEY_ID_INIT;
psa_key_attributes_t to_attributes = PSA_KEY_ATTRIBUTES_INIT;
mbedtls_svc_key_id_t to_key_id = MBEDTLS_SVC_KEY_ID_INIT;
psa_key_attributes_t actual_attributes = PSA_KEY_ATTRIBUTES_INIT;
PSA_INIT();
psa_set_key_type(&from_attributes, from_type);
psa_set_key_bits(&from_attributes, from_bits);
psa_set_key_usage_flags(&from_attributes, from_usage);
psa_set_key_algorithm(&from_attributes, from_alg);
PSA_ASSERT(psa_generate_key(&from_attributes, &from_key_id));
TEST_EQUAL(mbedtls_pk_setup_opaque(&pk, from_key_id), 0);
psa_set_key_type(&to_attributes, to_type);
psa_set_key_bits(&to_attributes, to_bits);
psa_set_key_usage_flags(&to_attributes, to_usage);
psa_set_key_algorithm(&to_attributes, to_alg);
TEST_EQUAL(mbedtls_pk_import_into_psa(&pk, &to_attributes, &to_key_id),
expected_ret);
if (expected_ret == 0) {
PSA_ASSERT(psa_get_key_attributes(to_key_id, &actual_attributes));
TEST_EQUAL(to_type, psa_get_key_type(&actual_attributes));
if (to_bits != 0) {
TEST_EQUAL(to_bits, psa_get_key_bits(&actual_attributes));
}
TEST_EQUAL(to_alg, psa_get_key_algorithm(&actual_attributes));
psa_key_usage_t expected_usage = to_usage;
if (expected_usage & PSA_KEY_USAGE_SIGN_HASH) {
expected_usage |= PSA_KEY_USAGE_SIGN_MESSAGE;
}
if (expected_usage & PSA_KEY_USAGE_VERIFY_HASH) {
expected_usage |= PSA_KEY_USAGE_VERIFY_MESSAGE;
}
TEST_EQUAL(expected_usage, psa_get_key_usage_flags(&actual_attributes));
} else {
TEST_ASSERT(mbedtls_svc_key_id_equal(to_key_id, MBEDTLS_SVC_KEY_ID_INIT));
}
exit:
mbedtls_pk_free(&pk);
psa_destroy_key(from_key_id);
psa_destroy_key(to_key_id);
psa_reset_key_attributes(&from_attributes);
psa_reset_key_attributes(&to_attributes);
psa_reset_key_attributes(&actual_attributes);
PSA_DONE();
}
/* END_CASE */