1a8e1175bSopenharmony_ci/* 2a8e1175bSopenharmony_ci * PSA hashing layer on top of Mbed TLS software crypto 3a8e1175bSopenharmony_ci */ 4a8e1175bSopenharmony_ci/* 5a8e1175bSopenharmony_ci * Copyright The Mbed TLS Contributors 6a8e1175bSopenharmony_ci * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 7a8e1175bSopenharmony_ci */ 8a8e1175bSopenharmony_ci 9a8e1175bSopenharmony_ci#include "common.h" 10a8e1175bSopenharmony_ci 11a8e1175bSopenharmony_ci/* This is needed for MBEDTLS_ERR_XXX macros */ 12a8e1175bSopenharmony_ci#include <mbedtls/error.h> 13a8e1175bSopenharmony_ci 14a8e1175bSopenharmony_ci#if defined(MBEDTLS_ASN1_WRITE_C) 15a8e1175bSopenharmony_ci#include <mbedtls/asn1write.h> 16a8e1175bSopenharmony_ci#include <psa/crypto_sizes.h> 17a8e1175bSopenharmony_ci#endif 18a8e1175bSopenharmony_ci 19a8e1175bSopenharmony_ci#include "psa_util_internal.h" 20a8e1175bSopenharmony_ci 21a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) 22a8e1175bSopenharmony_ci 23a8e1175bSopenharmony_ci#include <psa/crypto.h> 24a8e1175bSopenharmony_ci 25a8e1175bSopenharmony_ci#if defined(MBEDTLS_MD_LIGHT) 26a8e1175bSopenharmony_ci#include <mbedtls/md.h> 27a8e1175bSopenharmony_ci#endif 28a8e1175bSopenharmony_ci#if defined(MBEDTLS_LMS_C) 29a8e1175bSopenharmony_ci#include <mbedtls/lms.h> 30a8e1175bSopenharmony_ci#endif 31a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_TLS_C) && \ 32a8e1175bSopenharmony_ci (defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)) 33a8e1175bSopenharmony_ci#include <mbedtls/ssl.h> 34a8e1175bSopenharmony_ci#endif 35a8e1175bSopenharmony_ci#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) || \ 36a8e1175bSopenharmony_ci defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) 37a8e1175bSopenharmony_ci#include <mbedtls/rsa.h> 38a8e1175bSopenharmony_ci#endif 39a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) && \ 40a8e1175bSopenharmony_ci defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) 41a8e1175bSopenharmony_ci#include <mbedtls/ecp.h> 42a8e1175bSopenharmony_ci#endif 43a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_C) 44a8e1175bSopenharmony_ci#include <mbedtls/pk.h> 45a8e1175bSopenharmony_ci#endif 46a8e1175bSopenharmony_ci#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) 47a8e1175bSopenharmony_ci#include <mbedtls/cipher.h> 48a8e1175bSopenharmony_ci#endif 49a8e1175bSopenharmony_ci#include <mbedtls/entropy.h> 50a8e1175bSopenharmony_ci 51a8e1175bSopenharmony_ci/* PSA_SUCCESS is kept at the top of each error table since 52a8e1175bSopenharmony_ci * it's the most common status when everything functions properly. */ 53a8e1175bSopenharmony_ci#if defined(MBEDTLS_MD_LIGHT) 54a8e1175bSopenharmony_ciconst mbedtls_error_pair_t psa_to_md_errors[] = 55a8e1175bSopenharmony_ci{ 56a8e1175bSopenharmony_ci { PSA_SUCCESS, 0 }, 57a8e1175bSopenharmony_ci { PSA_ERROR_NOT_SUPPORTED, MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE }, 58a8e1175bSopenharmony_ci { PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_MD_BAD_INPUT_DATA }, 59a8e1175bSopenharmony_ci { PSA_ERROR_INSUFFICIENT_MEMORY, MBEDTLS_ERR_MD_ALLOC_FAILED } 60a8e1175bSopenharmony_ci}; 61a8e1175bSopenharmony_ci#endif 62a8e1175bSopenharmony_ci 63a8e1175bSopenharmony_ci#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) 64a8e1175bSopenharmony_ciconst mbedtls_error_pair_t psa_to_cipher_errors[] = 65a8e1175bSopenharmony_ci{ 66a8e1175bSopenharmony_ci { PSA_SUCCESS, 0 }, 67a8e1175bSopenharmony_ci { PSA_ERROR_NOT_SUPPORTED, MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE }, 68a8e1175bSopenharmony_ci { PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA }, 69a8e1175bSopenharmony_ci { PSA_ERROR_INSUFFICIENT_MEMORY, MBEDTLS_ERR_CIPHER_ALLOC_FAILED } 70a8e1175bSopenharmony_ci}; 71a8e1175bSopenharmony_ci#endif 72a8e1175bSopenharmony_ci 73a8e1175bSopenharmony_ci#if defined(MBEDTLS_LMS_C) 74a8e1175bSopenharmony_ciconst mbedtls_error_pair_t psa_to_lms_errors[] = 75a8e1175bSopenharmony_ci{ 76a8e1175bSopenharmony_ci { PSA_SUCCESS, 0 }, 77a8e1175bSopenharmony_ci { PSA_ERROR_BUFFER_TOO_SMALL, MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL }, 78a8e1175bSopenharmony_ci { PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_LMS_BAD_INPUT_DATA } 79a8e1175bSopenharmony_ci}; 80a8e1175bSopenharmony_ci#endif 81a8e1175bSopenharmony_ci 82a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_TLS_C) && \ 83a8e1175bSopenharmony_ci (defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)) 84a8e1175bSopenharmony_ciconst mbedtls_error_pair_t psa_to_ssl_errors[] = 85a8e1175bSopenharmony_ci{ 86a8e1175bSopenharmony_ci { PSA_SUCCESS, 0 }, 87a8e1175bSopenharmony_ci { PSA_ERROR_INSUFFICIENT_MEMORY, MBEDTLS_ERR_SSL_ALLOC_FAILED }, 88a8e1175bSopenharmony_ci { PSA_ERROR_NOT_SUPPORTED, MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE }, 89a8e1175bSopenharmony_ci { PSA_ERROR_INVALID_SIGNATURE, MBEDTLS_ERR_SSL_INVALID_MAC }, 90a8e1175bSopenharmony_ci { PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_SSL_BAD_INPUT_DATA }, 91a8e1175bSopenharmony_ci { PSA_ERROR_BAD_STATE, MBEDTLS_ERR_SSL_INTERNAL_ERROR }, 92a8e1175bSopenharmony_ci { PSA_ERROR_BUFFER_TOO_SMALL, MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL } 93a8e1175bSopenharmony_ci}; 94a8e1175bSopenharmony_ci#endif 95a8e1175bSopenharmony_ci 96a8e1175bSopenharmony_ci#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) || \ 97a8e1175bSopenharmony_ci defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) 98a8e1175bSopenharmony_ciconst mbedtls_error_pair_t psa_to_pk_rsa_errors[] = 99a8e1175bSopenharmony_ci{ 100a8e1175bSopenharmony_ci { PSA_SUCCESS, 0 }, 101a8e1175bSopenharmony_ci { PSA_ERROR_NOT_PERMITTED, MBEDTLS_ERR_RSA_BAD_INPUT_DATA }, 102a8e1175bSopenharmony_ci { PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_RSA_BAD_INPUT_DATA }, 103a8e1175bSopenharmony_ci { PSA_ERROR_INVALID_HANDLE, MBEDTLS_ERR_RSA_BAD_INPUT_DATA }, 104a8e1175bSopenharmony_ci { PSA_ERROR_BUFFER_TOO_SMALL, MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE }, 105a8e1175bSopenharmony_ci { PSA_ERROR_INSUFFICIENT_ENTROPY, MBEDTLS_ERR_RSA_RNG_FAILED }, 106a8e1175bSopenharmony_ci { PSA_ERROR_INVALID_SIGNATURE, MBEDTLS_ERR_RSA_VERIFY_FAILED }, 107a8e1175bSopenharmony_ci { PSA_ERROR_INVALID_PADDING, MBEDTLS_ERR_RSA_INVALID_PADDING } 108a8e1175bSopenharmony_ci}; 109a8e1175bSopenharmony_ci#endif 110a8e1175bSopenharmony_ci 111a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) && \ 112a8e1175bSopenharmony_ci defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) 113a8e1175bSopenharmony_ciconst mbedtls_error_pair_t psa_to_pk_ecdsa_errors[] = 114a8e1175bSopenharmony_ci{ 115a8e1175bSopenharmony_ci { PSA_SUCCESS, 0 }, 116a8e1175bSopenharmony_ci { PSA_ERROR_NOT_PERMITTED, MBEDTLS_ERR_ECP_BAD_INPUT_DATA }, 117a8e1175bSopenharmony_ci { PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_ECP_BAD_INPUT_DATA }, 118a8e1175bSopenharmony_ci { PSA_ERROR_INVALID_HANDLE, MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE }, 119a8e1175bSopenharmony_ci { PSA_ERROR_BUFFER_TOO_SMALL, MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL }, 120a8e1175bSopenharmony_ci { PSA_ERROR_INSUFFICIENT_ENTROPY, MBEDTLS_ERR_ECP_RANDOM_FAILED }, 121a8e1175bSopenharmony_ci { PSA_ERROR_INVALID_SIGNATURE, MBEDTLS_ERR_ECP_VERIFY_FAILED } 122a8e1175bSopenharmony_ci}; 123a8e1175bSopenharmony_ci#endif 124a8e1175bSopenharmony_ci 125a8e1175bSopenharmony_ciint psa_generic_status_to_mbedtls(psa_status_t status) 126a8e1175bSopenharmony_ci{ 127a8e1175bSopenharmony_ci switch (status) { 128a8e1175bSopenharmony_ci case PSA_SUCCESS: 129a8e1175bSopenharmony_ci return 0; 130a8e1175bSopenharmony_ci case PSA_ERROR_NOT_SUPPORTED: 131a8e1175bSopenharmony_ci return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED; 132a8e1175bSopenharmony_ci case PSA_ERROR_CORRUPTION_DETECTED: 133a8e1175bSopenharmony_ci return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 134a8e1175bSopenharmony_ci case PSA_ERROR_COMMUNICATION_FAILURE: 135a8e1175bSopenharmony_ci case PSA_ERROR_HARDWARE_FAILURE: 136a8e1175bSopenharmony_ci return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; 137a8e1175bSopenharmony_ci case PSA_ERROR_NOT_PERMITTED: 138a8e1175bSopenharmony_ci default: 139a8e1175bSopenharmony_ci return MBEDTLS_ERR_ERROR_GENERIC_ERROR; 140a8e1175bSopenharmony_ci } 141a8e1175bSopenharmony_ci} 142a8e1175bSopenharmony_ci 143a8e1175bSopenharmony_ciint psa_status_to_mbedtls(psa_status_t status, 144a8e1175bSopenharmony_ci const mbedtls_error_pair_t *local_translations, 145a8e1175bSopenharmony_ci size_t local_errors_num, 146a8e1175bSopenharmony_ci int (*fallback_f)(psa_status_t)) 147a8e1175bSopenharmony_ci{ 148a8e1175bSopenharmony_ci for (size_t i = 0; i < local_errors_num; i++) { 149a8e1175bSopenharmony_ci if (status == local_translations[i].psa_status) { 150a8e1175bSopenharmony_ci return local_translations[i].mbedtls_error; 151a8e1175bSopenharmony_ci } 152a8e1175bSopenharmony_ci } 153a8e1175bSopenharmony_ci return fallback_f(status); 154a8e1175bSopenharmony_ci} 155a8e1175bSopenharmony_ci 156a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_C) 157a8e1175bSopenharmony_ciint psa_pk_status_to_mbedtls(psa_status_t status) 158a8e1175bSopenharmony_ci{ 159a8e1175bSopenharmony_ci switch (status) { 160a8e1175bSopenharmony_ci case PSA_ERROR_INVALID_HANDLE: 161a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; 162a8e1175bSopenharmony_ci case PSA_ERROR_BUFFER_TOO_SMALL: 163a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL; 164a8e1175bSopenharmony_ci case PSA_ERROR_NOT_SUPPORTED: 165a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 166a8e1175bSopenharmony_ci case PSA_ERROR_INVALID_ARGUMENT: 167a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_INVALID_ALG; 168a8e1175bSopenharmony_ci case PSA_ERROR_NOT_PERMITTED: 169a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 170a8e1175bSopenharmony_ci case PSA_ERROR_INSUFFICIENT_MEMORY: 171a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_ALLOC_FAILED; 172a8e1175bSopenharmony_ci case PSA_ERROR_BAD_STATE: 173a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 174a8e1175bSopenharmony_ci case PSA_ERROR_DATA_CORRUPT: 175a8e1175bSopenharmony_ci case PSA_ERROR_DATA_INVALID: 176a8e1175bSopenharmony_ci case PSA_ERROR_STORAGE_FAILURE: 177a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_FILE_IO_ERROR; 178a8e1175bSopenharmony_ci default: 179a8e1175bSopenharmony_ci return psa_generic_status_to_mbedtls(status); 180a8e1175bSopenharmony_ci } 181a8e1175bSopenharmony_ci} 182a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_C */ 183a8e1175bSopenharmony_ci 184a8e1175bSopenharmony_ci/****************************************************************/ 185a8e1175bSopenharmony_ci/* Key management */ 186a8e1175bSopenharmony_ci/****************************************************************/ 187a8e1175bSopenharmony_ci 188a8e1175bSopenharmony_ci#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) 189a8e1175bSopenharmony_cipsa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid, 190a8e1175bSopenharmony_ci size_t *bits) 191a8e1175bSopenharmony_ci{ 192a8e1175bSopenharmony_ci switch (grpid) { 193a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_HAVE_SECP192R1) 194a8e1175bSopenharmony_ci case MBEDTLS_ECP_DP_SECP192R1: 195a8e1175bSopenharmony_ci *bits = 192; 196a8e1175bSopenharmony_ci return PSA_ECC_FAMILY_SECP_R1; 197a8e1175bSopenharmony_ci#endif 198a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_HAVE_SECP224R1) 199a8e1175bSopenharmony_ci case MBEDTLS_ECP_DP_SECP224R1: 200a8e1175bSopenharmony_ci *bits = 224; 201a8e1175bSopenharmony_ci return PSA_ECC_FAMILY_SECP_R1; 202a8e1175bSopenharmony_ci#endif 203a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_HAVE_SECP256R1) 204a8e1175bSopenharmony_ci case MBEDTLS_ECP_DP_SECP256R1: 205a8e1175bSopenharmony_ci *bits = 256; 206a8e1175bSopenharmony_ci return PSA_ECC_FAMILY_SECP_R1; 207a8e1175bSopenharmony_ci#endif 208a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_HAVE_SECP384R1) 209a8e1175bSopenharmony_ci case MBEDTLS_ECP_DP_SECP384R1: 210a8e1175bSopenharmony_ci *bits = 384; 211a8e1175bSopenharmony_ci return PSA_ECC_FAMILY_SECP_R1; 212a8e1175bSopenharmony_ci#endif 213a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_HAVE_SECP521R1) 214a8e1175bSopenharmony_ci case MBEDTLS_ECP_DP_SECP521R1: 215a8e1175bSopenharmony_ci *bits = 521; 216a8e1175bSopenharmony_ci return PSA_ECC_FAMILY_SECP_R1; 217a8e1175bSopenharmony_ci#endif 218a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_HAVE_BP256R1) 219a8e1175bSopenharmony_ci case MBEDTLS_ECP_DP_BP256R1: 220a8e1175bSopenharmony_ci *bits = 256; 221a8e1175bSopenharmony_ci return PSA_ECC_FAMILY_BRAINPOOL_P_R1; 222a8e1175bSopenharmony_ci#endif 223a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_HAVE_BP384R1) 224a8e1175bSopenharmony_ci case MBEDTLS_ECP_DP_BP384R1: 225a8e1175bSopenharmony_ci *bits = 384; 226a8e1175bSopenharmony_ci return PSA_ECC_FAMILY_BRAINPOOL_P_R1; 227a8e1175bSopenharmony_ci#endif 228a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_HAVE_BP512R1) 229a8e1175bSopenharmony_ci case MBEDTLS_ECP_DP_BP512R1: 230a8e1175bSopenharmony_ci *bits = 512; 231a8e1175bSopenharmony_ci return PSA_ECC_FAMILY_BRAINPOOL_P_R1; 232a8e1175bSopenharmony_ci#endif 233a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_HAVE_CURVE25519) 234a8e1175bSopenharmony_ci case MBEDTLS_ECP_DP_CURVE25519: 235a8e1175bSopenharmony_ci *bits = 255; 236a8e1175bSopenharmony_ci return PSA_ECC_FAMILY_MONTGOMERY; 237a8e1175bSopenharmony_ci#endif 238a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_HAVE_SECP192K1) 239a8e1175bSopenharmony_ci case MBEDTLS_ECP_DP_SECP192K1: 240a8e1175bSopenharmony_ci *bits = 192; 241a8e1175bSopenharmony_ci return PSA_ECC_FAMILY_SECP_K1; 242a8e1175bSopenharmony_ci#endif 243a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_HAVE_SECP224K1) 244a8e1175bSopenharmony_ci /* secp224k1 is not and will not be supported in PSA (#3541). */ 245a8e1175bSopenharmony_ci#endif 246a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_HAVE_SECP256K1) 247a8e1175bSopenharmony_ci case MBEDTLS_ECP_DP_SECP256K1: 248a8e1175bSopenharmony_ci *bits = 256; 249a8e1175bSopenharmony_ci return PSA_ECC_FAMILY_SECP_K1; 250a8e1175bSopenharmony_ci#endif 251a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_HAVE_CURVE448) 252a8e1175bSopenharmony_ci case MBEDTLS_ECP_DP_CURVE448: 253a8e1175bSopenharmony_ci *bits = 448; 254a8e1175bSopenharmony_ci return PSA_ECC_FAMILY_MONTGOMERY; 255a8e1175bSopenharmony_ci#endif 256a8e1175bSopenharmony_ci default: 257a8e1175bSopenharmony_ci *bits = 0; 258a8e1175bSopenharmony_ci return 0; 259a8e1175bSopenharmony_ci } 260a8e1175bSopenharmony_ci} 261a8e1175bSopenharmony_ci 262a8e1175bSopenharmony_cimbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t family, 263a8e1175bSopenharmony_ci size_t bits) 264a8e1175bSopenharmony_ci{ 265a8e1175bSopenharmony_ci switch (family) { 266a8e1175bSopenharmony_ci case PSA_ECC_FAMILY_SECP_R1: 267a8e1175bSopenharmony_ci switch (bits) { 268a8e1175bSopenharmony_ci#if defined(PSA_WANT_ECC_SECP_R1_192) 269a8e1175bSopenharmony_ci case 192: 270a8e1175bSopenharmony_ci return MBEDTLS_ECP_DP_SECP192R1; 271a8e1175bSopenharmony_ci#endif 272a8e1175bSopenharmony_ci#if defined(PSA_WANT_ECC_SECP_R1_224) 273a8e1175bSopenharmony_ci case 224: 274a8e1175bSopenharmony_ci return MBEDTLS_ECP_DP_SECP224R1; 275a8e1175bSopenharmony_ci#endif 276a8e1175bSopenharmony_ci#if defined(PSA_WANT_ECC_SECP_R1_256) 277a8e1175bSopenharmony_ci case 256: 278a8e1175bSopenharmony_ci return MBEDTLS_ECP_DP_SECP256R1; 279a8e1175bSopenharmony_ci#endif 280a8e1175bSopenharmony_ci#if defined(PSA_WANT_ECC_SECP_R1_384) 281a8e1175bSopenharmony_ci case 384: 282a8e1175bSopenharmony_ci return MBEDTLS_ECP_DP_SECP384R1; 283a8e1175bSopenharmony_ci#endif 284a8e1175bSopenharmony_ci#if defined(PSA_WANT_ECC_SECP_R1_521) 285a8e1175bSopenharmony_ci case 521: 286a8e1175bSopenharmony_ci return MBEDTLS_ECP_DP_SECP521R1; 287a8e1175bSopenharmony_ci#endif 288a8e1175bSopenharmony_ci } 289a8e1175bSopenharmony_ci break; 290a8e1175bSopenharmony_ci 291a8e1175bSopenharmony_ci case PSA_ECC_FAMILY_BRAINPOOL_P_R1: 292a8e1175bSopenharmony_ci switch (bits) { 293a8e1175bSopenharmony_ci#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256) 294a8e1175bSopenharmony_ci case 256: 295a8e1175bSopenharmony_ci return MBEDTLS_ECP_DP_BP256R1; 296a8e1175bSopenharmony_ci#endif 297a8e1175bSopenharmony_ci#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384) 298a8e1175bSopenharmony_ci case 384: 299a8e1175bSopenharmony_ci return MBEDTLS_ECP_DP_BP384R1; 300a8e1175bSopenharmony_ci#endif 301a8e1175bSopenharmony_ci#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512) 302a8e1175bSopenharmony_ci case 512: 303a8e1175bSopenharmony_ci return MBEDTLS_ECP_DP_BP512R1; 304a8e1175bSopenharmony_ci#endif 305a8e1175bSopenharmony_ci } 306a8e1175bSopenharmony_ci break; 307a8e1175bSopenharmony_ci 308a8e1175bSopenharmony_ci case PSA_ECC_FAMILY_MONTGOMERY: 309a8e1175bSopenharmony_ci switch (bits) { 310a8e1175bSopenharmony_ci#if defined(PSA_WANT_ECC_MONTGOMERY_255) 311a8e1175bSopenharmony_ci case 255: 312a8e1175bSopenharmony_ci return MBEDTLS_ECP_DP_CURVE25519; 313a8e1175bSopenharmony_ci#endif 314a8e1175bSopenharmony_ci#if defined(PSA_WANT_ECC_MONTGOMERY_448) 315a8e1175bSopenharmony_ci case 448: 316a8e1175bSopenharmony_ci return MBEDTLS_ECP_DP_CURVE448; 317a8e1175bSopenharmony_ci#endif 318a8e1175bSopenharmony_ci } 319a8e1175bSopenharmony_ci break; 320a8e1175bSopenharmony_ci 321a8e1175bSopenharmony_ci case PSA_ECC_FAMILY_SECP_K1: 322a8e1175bSopenharmony_ci switch (bits) { 323a8e1175bSopenharmony_ci#if defined(PSA_WANT_ECC_SECP_K1_192) 324a8e1175bSopenharmony_ci case 192: 325a8e1175bSopenharmony_ci return MBEDTLS_ECP_DP_SECP192K1; 326a8e1175bSopenharmony_ci#endif 327a8e1175bSopenharmony_ci#if defined(PSA_WANT_ECC_SECP_K1_224) 328a8e1175bSopenharmony_ci /* secp224k1 is not and will not be supported in PSA (#3541). */ 329a8e1175bSopenharmony_ci#endif 330a8e1175bSopenharmony_ci#if defined(PSA_WANT_ECC_SECP_K1_256) 331a8e1175bSopenharmony_ci case 256: 332a8e1175bSopenharmony_ci return MBEDTLS_ECP_DP_SECP256K1; 333a8e1175bSopenharmony_ci#endif 334a8e1175bSopenharmony_ci } 335a8e1175bSopenharmony_ci break; 336a8e1175bSopenharmony_ci } 337a8e1175bSopenharmony_ci 338a8e1175bSopenharmony_ci return MBEDTLS_ECP_DP_NONE; 339a8e1175bSopenharmony_ci} 340a8e1175bSopenharmony_ci#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */ 341a8e1175bSopenharmony_ci 342a8e1175bSopenharmony_ci/* Wrapper function allowing the classic API to use the PSA RNG. 343a8e1175bSopenharmony_ci * 344a8e1175bSopenharmony_ci * `mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE, ...)` calls 345a8e1175bSopenharmony_ci * `psa_generate_random(...)`. The state parameter is ignored since the 346a8e1175bSopenharmony_ci * PSA API doesn't support passing an explicit state. 347a8e1175bSopenharmony_ci */ 348a8e1175bSopenharmony_ciint mbedtls_psa_get_random(void *p_rng, 349a8e1175bSopenharmony_ci unsigned char *output, 350a8e1175bSopenharmony_ci size_t output_size) 351a8e1175bSopenharmony_ci{ 352a8e1175bSopenharmony_ci /* This function takes a pointer to the RNG state because that's what 353a8e1175bSopenharmony_ci * classic mbedtls functions using an RNG expect. The PSA RNG manages 354a8e1175bSopenharmony_ci * its own state internally and doesn't let the caller access that state. 355a8e1175bSopenharmony_ci * So we just ignore the state parameter, and in practice we'll pass 356a8e1175bSopenharmony_ci * NULL. */ 357a8e1175bSopenharmony_ci (void) p_rng; 358a8e1175bSopenharmony_ci psa_status_t status = psa_generate_random(output, output_size); 359a8e1175bSopenharmony_ci if (status == PSA_SUCCESS) { 360a8e1175bSopenharmony_ci return 0; 361a8e1175bSopenharmony_ci } else { 362a8e1175bSopenharmony_ci return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; 363a8e1175bSopenharmony_ci } 364a8e1175bSopenharmony_ci} 365a8e1175bSopenharmony_ci 366a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ 367a8e1175bSopenharmony_ci 368a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA) 369a8e1175bSopenharmony_ci 370a8e1175bSopenharmony_ci/** 371a8e1175bSopenharmony_ci * \brief Convert a single raw coordinate to DER ASN.1 format. The output der 372a8e1175bSopenharmony_ci * buffer is filled backward (i.e. starting from its end). 373a8e1175bSopenharmony_ci * 374a8e1175bSopenharmony_ci * \param raw_buf Buffer containing the raw coordinate to be 375a8e1175bSopenharmony_ci * converted. 376a8e1175bSopenharmony_ci * \param raw_len Length of raw_buf in bytes. This must be > 0. 377a8e1175bSopenharmony_ci * \param der_buf_start Pointer to the beginning of the buffer which 378a8e1175bSopenharmony_ci * will be filled with the DER converted data. 379a8e1175bSopenharmony_ci * \param der_buf_end End of the buffer used to store the DER output. 380a8e1175bSopenharmony_ci * 381a8e1175bSopenharmony_ci * \return On success, the amount of data (in bytes) written to 382a8e1175bSopenharmony_ci * the DER buffer. 383a8e1175bSopenharmony_ci * \return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL if the provided der 384a8e1175bSopenharmony_ci * buffer is too small to contain all the converted data. 385a8e1175bSopenharmony_ci * \return MBEDTLS_ERR_ASN1_INVALID_DATA if the input raw 386a8e1175bSopenharmony_ci * coordinate is null (i.e. all zeros). 387a8e1175bSopenharmony_ci * 388a8e1175bSopenharmony_ci * \warning Raw and der buffer must not be overlapping. 389a8e1175bSopenharmony_ci */ 390a8e1175bSopenharmony_cistatic int convert_raw_to_der_single_int(const unsigned char *raw_buf, size_t raw_len, 391a8e1175bSopenharmony_ci unsigned char *der_buf_start, 392a8e1175bSopenharmony_ci unsigned char *der_buf_end) 393a8e1175bSopenharmony_ci{ 394a8e1175bSopenharmony_ci unsigned char *p = der_buf_end; 395a8e1175bSopenharmony_ci int len; 396a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 397a8e1175bSopenharmony_ci 398a8e1175bSopenharmony_ci /* ASN.1 DER encoding requires minimal length, so skip leading 0s. 399a8e1175bSopenharmony_ci * Provided input MPIs should not be 0, but as a failsafe measure, still 400a8e1175bSopenharmony_ci * detect that and return error in case. */ 401a8e1175bSopenharmony_ci while (*raw_buf == 0x00) { 402a8e1175bSopenharmony_ci ++raw_buf; 403a8e1175bSopenharmony_ci --raw_len; 404a8e1175bSopenharmony_ci if (raw_len == 0) { 405a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_INVALID_DATA; 406a8e1175bSopenharmony_ci } 407a8e1175bSopenharmony_ci } 408a8e1175bSopenharmony_ci len = (int) raw_len; 409a8e1175bSopenharmony_ci 410a8e1175bSopenharmony_ci /* Copy the raw coordinate to the end of der_buf. */ 411a8e1175bSopenharmony_ci if ((p - der_buf_start) < len) { 412a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; 413a8e1175bSopenharmony_ci } 414a8e1175bSopenharmony_ci p -= len; 415a8e1175bSopenharmony_ci memcpy(p, raw_buf, len); 416a8e1175bSopenharmony_ci 417a8e1175bSopenharmony_ci /* If MSb is 1, ASN.1 requires that we prepend a 0. */ 418a8e1175bSopenharmony_ci if (*p & 0x80) { 419a8e1175bSopenharmony_ci if ((p - der_buf_start) < 1) { 420a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; 421a8e1175bSopenharmony_ci } 422a8e1175bSopenharmony_ci --p; 423a8e1175bSopenharmony_ci *p = 0x00; 424a8e1175bSopenharmony_ci ++len; 425a8e1175bSopenharmony_ci } 426a8e1175bSopenharmony_ci 427a8e1175bSopenharmony_ci MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, der_buf_start, len)); 428a8e1175bSopenharmony_ci MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, der_buf_start, MBEDTLS_ASN1_INTEGER)); 429a8e1175bSopenharmony_ci 430a8e1175bSopenharmony_ci return len; 431a8e1175bSopenharmony_ci} 432a8e1175bSopenharmony_ci 433a8e1175bSopenharmony_ciint mbedtls_ecdsa_raw_to_der(size_t bits, const unsigned char *raw, size_t raw_len, 434a8e1175bSopenharmony_ci unsigned char *der, size_t der_size, size_t *der_len) 435a8e1175bSopenharmony_ci{ 436a8e1175bSopenharmony_ci unsigned char r[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)]; 437a8e1175bSopenharmony_ci unsigned char s[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)]; 438a8e1175bSopenharmony_ci const size_t coordinate_len = PSA_BITS_TO_BYTES(bits); 439a8e1175bSopenharmony_ci size_t len = 0; 440a8e1175bSopenharmony_ci unsigned char *p = der + der_size; 441a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 442a8e1175bSopenharmony_ci 443a8e1175bSopenharmony_ci if (raw_len != (2 * coordinate_len)) { 444a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_INVALID_DATA; 445a8e1175bSopenharmony_ci } 446a8e1175bSopenharmony_ci if (coordinate_len > sizeof(r)) { 447a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; 448a8e1175bSopenharmony_ci } 449a8e1175bSopenharmony_ci /* Since raw and der buffers might overlap, dump r and s before starting 450a8e1175bSopenharmony_ci * the conversion. */ 451a8e1175bSopenharmony_ci memcpy(r, raw, coordinate_len); 452a8e1175bSopenharmony_ci memcpy(s, raw + coordinate_len, coordinate_len); 453a8e1175bSopenharmony_ci 454a8e1175bSopenharmony_ci /* der buffer will initially be written starting from its end so we pick s 455a8e1175bSopenharmony_ci * first and then r. */ 456a8e1175bSopenharmony_ci ret = convert_raw_to_der_single_int(s, coordinate_len, der, p); 457a8e1175bSopenharmony_ci if (ret < 0) { 458a8e1175bSopenharmony_ci return ret; 459a8e1175bSopenharmony_ci } 460a8e1175bSopenharmony_ci p -= ret; 461a8e1175bSopenharmony_ci len += ret; 462a8e1175bSopenharmony_ci 463a8e1175bSopenharmony_ci ret = convert_raw_to_der_single_int(r, coordinate_len, der, p); 464a8e1175bSopenharmony_ci if (ret < 0) { 465a8e1175bSopenharmony_ci return ret; 466a8e1175bSopenharmony_ci } 467a8e1175bSopenharmony_ci p -= ret; 468a8e1175bSopenharmony_ci len += ret; 469a8e1175bSopenharmony_ci 470a8e1175bSopenharmony_ci /* Add ASN.1 header (len + tag). */ 471a8e1175bSopenharmony_ci MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, der, len)); 472a8e1175bSopenharmony_ci MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, der, 473a8e1175bSopenharmony_ci MBEDTLS_ASN1_CONSTRUCTED | 474a8e1175bSopenharmony_ci MBEDTLS_ASN1_SEQUENCE)); 475a8e1175bSopenharmony_ci 476a8e1175bSopenharmony_ci /* memmove the content of der buffer to its beginnig. */ 477a8e1175bSopenharmony_ci memmove(der, p, len); 478a8e1175bSopenharmony_ci *der_len = len; 479a8e1175bSopenharmony_ci 480a8e1175bSopenharmony_ci return 0; 481a8e1175bSopenharmony_ci} 482a8e1175bSopenharmony_ci 483a8e1175bSopenharmony_ci/** 484a8e1175bSopenharmony_ci * \brief Convert a single integer from ASN.1 DER format to raw. 485a8e1175bSopenharmony_ci * 486a8e1175bSopenharmony_ci * \param der Buffer containing the DER integer value to be 487a8e1175bSopenharmony_ci * converted. 488a8e1175bSopenharmony_ci * \param der_len Length of the der buffer in bytes. 489a8e1175bSopenharmony_ci * \param raw Output buffer that will be filled with the 490a8e1175bSopenharmony_ci * converted data. This should be at least 491a8e1175bSopenharmony_ci * coordinate_size bytes and it must be zeroed before 492a8e1175bSopenharmony_ci * calling this function. 493a8e1175bSopenharmony_ci * \param coordinate_size Size (in bytes) of a single coordinate in raw 494a8e1175bSopenharmony_ci * format. 495a8e1175bSopenharmony_ci * 496a8e1175bSopenharmony_ci * \return On success, the amount of DER data parsed from the 497a8e1175bSopenharmony_ci * provided der buffer. 498a8e1175bSopenharmony_ci * \return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the integer tag 499a8e1175bSopenharmony_ci * is missing in the der buffer. 500a8e1175bSopenharmony_ci * \return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the integer 501a8e1175bSopenharmony_ci * is null (i.e. all zeros) or if the output raw buffer 502a8e1175bSopenharmony_ci * is too small to contain the converted raw value. 503a8e1175bSopenharmony_ci * 504a8e1175bSopenharmony_ci * \warning Der and raw buffers must not be overlapping. 505a8e1175bSopenharmony_ci */ 506a8e1175bSopenharmony_cistatic int convert_der_to_raw_single_int(unsigned char *der, size_t der_len, 507a8e1175bSopenharmony_ci unsigned char *raw, size_t coordinate_size) 508a8e1175bSopenharmony_ci{ 509a8e1175bSopenharmony_ci unsigned char *p = der; 510a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 511a8e1175bSopenharmony_ci size_t unpadded_len, padding_len = 0; 512a8e1175bSopenharmony_ci 513a8e1175bSopenharmony_ci /* Get the length of ASN.1 element (i.e. the integer we need to parse). */ 514a8e1175bSopenharmony_ci ret = mbedtls_asn1_get_tag(&p, p + der_len, &unpadded_len, 515a8e1175bSopenharmony_ci MBEDTLS_ASN1_INTEGER); 516a8e1175bSopenharmony_ci if (ret != 0) { 517a8e1175bSopenharmony_ci return ret; 518a8e1175bSopenharmony_ci } 519a8e1175bSopenharmony_ci 520a8e1175bSopenharmony_ci /* It's invalid to have: 521a8e1175bSopenharmony_ci * - unpadded_len == 0. 522a8e1175bSopenharmony_ci * - MSb set without a leading 0x00 (leading 0x00 is checked below). */ 523a8e1175bSopenharmony_ci if (((unpadded_len == 0) || (*p & 0x80) != 0)) { 524a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_INVALID_DATA; 525a8e1175bSopenharmony_ci } 526a8e1175bSopenharmony_ci 527a8e1175bSopenharmony_ci /* Skip possible leading zero */ 528a8e1175bSopenharmony_ci if (*p == 0x00) { 529a8e1175bSopenharmony_ci p++; 530a8e1175bSopenharmony_ci unpadded_len--; 531a8e1175bSopenharmony_ci /* It is not allowed to have more than 1 leading zero. 532a8e1175bSopenharmony_ci * Ignore the case in which unpadded_len = 0 because that's a 0 encoded 533a8e1175bSopenharmony_ci * in ASN.1 format (i.e. 020100). */ 534a8e1175bSopenharmony_ci if ((unpadded_len > 0) && (*p == 0x00)) { 535a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_INVALID_DATA; 536a8e1175bSopenharmony_ci } 537a8e1175bSopenharmony_ci } 538a8e1175bSopenharmony_ci 539a8e1175bSopenharmony_ci if (unpadded_len > coordinate_size) { 540a8e1175bSopenharmony_ci /* Parsed number is longer than the maximum expected value. */ 541a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_INVALID_DATA; 542a8e1175bSopenharmony_ci } 543a8e1175bSopenharmony_ci padding_len = coordinate_size - unpadded_len; 544a8e1175bSopenharmony_ci /* raw buffer was already zeroed by the calling function so zero-padding 545a8e1175bSopenharmony_ci * operation is skipped here. */ 546a8e1175bSopenharmony_ci memcpy(raw + padding_len, p, unpadded_len); 547a8e1175bSopenharmony_ci p += unpadded_len; 548a8e1175bSopenharmony_ci 549a8e1175bSopenharmony_ci return (int) (p - der); 550a8e1175bSopenharmony_ci} 551a8e1175bSopenharmony_ci 552a8e1175bSopenharmony_ciint mbedtls_ecdsa_der_to_raw(size_t bits, const unsigned char *der, size_t der_len, 553a8e1175bSopenharmony_ci unsigned char *raw, size_t raw_size, size_t *raw_len) 554a8e1175bSopenharmony_ci{ 555a8e1175bSopenharmony_ci unsigned char raw_tmp[PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE]; 556a8e1175bSopenharmony_ci unsigned char *p = (unsigned char *) der; 557a8e1175bSopenharmony_ci size_t data_len; 558a8e1175bSopenharmony_ci size_t coordinate_size = PSA_BITS_TO_BYTES(bits); 559a8e1175bSopenharmony_ci int ret; 560a8e1175bSopenharmony_ci 561a8e1175bSopenharmony_ci /* The output raw buffer should be at least twice the size of a raw 562a8e1175bSopenharmony_ci * coordinate in order to store r and s. */ 563a8e1175bSopenharmony_ci if (raw_size < coordinate_size * 2) { 564a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; 565a8e1175bSopenharmony_ci } 566a8e1175bSopenharmony_ci if (2 * coordinate_size > sizeof(raw_tmp)) { 567a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; 568a8e1175bSopenharmony_ci } 569a8e1175bSopenharmony_ci 570a8e1175bSopenharmony_ci /* Check that the provided input DER buffer has the right header. */ 571a8e1175bSopenharmony_ci ret = mbedtls_asn1_get_tag(&p, der + der_len, &data_len, 572a8e1175bSopenharmony_ci MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); 573a8e1175bSopenharmony_ci if (ret != 0) { 574a8e1175bSopenharmony_ci return ret; 575a8e1175bSopenharmony_ci } 576a8e1175bSopenharmony_ci 577a8e1175bSopenharmony_ci memset(raw_tmp, 0, 2 * coordinate_size); 578a8e1175bSopenharmony_ci 579a8e1175bSopenharmony_ci /* Extract r */ 580a8e1175bSopenharmony_ci ret = convert_der_to_raw_single_int(p, data_len, raw_tmp, coordinate_size); 581a8e1175bSopenharmony_ci if (ret < 0) { 582a8e1175bSopenharmony_ci return ret; 583a8e1175bSopenharmony_ci } 584a8e1175bSopenharmony_ci p += ret; 585a8e1175bSopenharmony_ci data_len -= ret; 586a8e1175bSopenharmony_ci 587a8e1175bSopenharmony_ci /* Extract s */ 588a8e1175bSopenharmony_ci ret = convert_der_to_raw_single_int(p, data_len, raw_tmp + coordinate_size, 589a8e1175bSopenharmony_ci coordinate_size); 590a8e1175bSopenharmony_ci if (ret < 0) { 591a8e1175bSopenharmony_ci return ret; 592a8e1175bSopenharmony_ci } 593a8e1175bSopenharmony_ci p += ret; 594a8e1175bSopenharmony_ci data_len -= ret; 595a8e1175bSopenharmony_ci 596a8e1175bSopenharmony_ci /* Check that we consumed all the input der data. */ 597a8e1175bSopenharmony_ci if ((size_t) (p - der) != der_len) { 598a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; 599a8e1175bSopenharmony_ci } 600a8e1175bSopenharmony_ci 601a8e1175bSopenharmony_ci memcpy(raw, raw_tmp, 2 * coordinate_size); 602a8e1175bSopenharmony_ci *raw_len = 2 * coordinate_size; 603a8e1175bSopenharmony_ci 604a8e1175bSopenharmony_ci return 0; 605a8e1175bSopenharmony_ci} 606a8e1175bSopenharmony_ci 607a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_UTIL_HAVE_ECDSA */ 608