1a8e1175bSopenharmony_ci/* 2a8e1175bSopenharmony_ci * PSA RSA layer on top of Mbed TLS 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#if defined(MBEDTLS_PSA_CRYPTO_C) 12a8e1175bSopenharmony_ci 13a8e1175bSopenharmony_ci#include <psa/crypto.h> 14a8e1175bSopenharmony_ci#include "psa/crypto_values.h" 15a8e1175bSopenharmony_ci#include "psa_crypto_core.h" 16a8e1175bSopenharmony_ci#include "psa_crypto_random_impl.h" 17a8e1175bSopenharmony_ci#include "psa_crypto_rsa.h" 18a8e1175bSopenharmony_ci#include "psa_crypto_hash.h" 19a8e1175bSopenharmony_ci#include "mbedtls/psa_util.h" 20a8e1175bSopenharmony_ci 21a8e1175bSopenharmony_ci#include <stdlib.h> 22a8e1175bSopenharmony_ci#include <string.h> 23a8e1175bSopenharmony_ci#include "mbedtls/platform.h" 24a8e1175bSopenharmony_ci 25a8e1175bSopenharmony_ci#include <mbedtls/rsa.h> 26a8e1175bSopenharmony_ci#include <mbedtls/error.h> 27a8e1175bSopenharmony_ci#include "rsa_internal.h" 28a8e1175bSopenharmony_ci 29a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \ 30a8e1175bSopenharmony_ci defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || \ 31a8e1175bSopenharmony_ci defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \ 32a8e1175bSopenharmony_ci defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) || \ 33a8e1175bSopenharmony_ci defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) || \ 34a8e1175bSopenharmony_ci defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || \ 35a8e1175bSopenharmony_ci defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) 36a8e1175bSopenharmony_ci 37a8e1175bSopenharmony_ci/* Mbed TLS doesn't support non-byte-aligned key sizes (i.e. key sizes 38a8e1175bSopenharmony_ci * that are not a multiple of 8) well. For example, there is only 39a8e1175bSopenharmony_ci * mbedtls_rsa_get_len(), which returns a number of bytes, and no 40a8e1175bSopenharmony_ci * way to return the exact bit size of a key. 41a8e1175bSopenharmony_ci * To keep things simple, reject non-byte-aligned key sizes. */ 42a8e1175bSopenharmony_cistatic psa_status_t psa_check_rsa_key_byte_aligned( 43a8e1175bSopenharmony_ci const mbedtls_rsa_context *rsa) 44a8e1175bSopenharmony_ci{ 45a8e1175bSopenharmony_ci mbedtls_mpi n; 46a8e1175bSopenharmony_ci psa_status_t status; 47a8e1175bSopenharmony_ci mbedtls_mpi_init(&n); 48a8e1175bSopenharmony_ci status = mbedtls_to_psa_error( 49a8e1175bSopenharmony_ci mbedtls_rsa_export(rsa, &n, NULL, NULL, NULL, NULL)); 50a8e1175bSopenharmony_ci if (status == PSA_SUCCESS) { 51a8e1175bSopenharmony_ci if (mbedtls_mpi_bitlen(&n) % 8 != 0) { 52a8e1175bSopenharmony_ci status = PSA_ERROR_NOT_SUPPORTED; 53a8e1175bSopenharmony_ci } 54a8e1175bSopenharmony_ci } 55a8e1175bSopenharmony_ci mbedtls_mpi_free(&n); 56a8e1175bSopenharmony_ci return status; 57a8e1175bSopenharmony_ci} 58a8e1175bSopenharmony_ci 59a8e1175bSopenharmony_cipsa_status_t mbedtls_psa_rsa_load_representation( 60a8e1175bSopenharmony_ci psa_key_type_t type, const uint8_t *data, size_t data_length, 61a8e1175bSopenharmony_ci mbedtls_rsa_context **p_rsa) 62a8e1175bSopenharmony_ci{ 63a8e1175bSopenharmony_ci psa_status_t status; 64a8e1175bSopenharmony_ci size_t bits; 65a8e1175bSopenharmony_ci 66a8e1175bSopenharmony_ci *p_rsa = mbedtls_calloc(1, sizeof(mbedtls_rsa_context)); 67a8e1175bSopenharmony_ci if (*p_rsa == NULL) { 68a8e1175bSopenharmony_ci return PSA_ERROR_INSUFFICIENT_MEMORY; 69a8e1175bSopenharmony_ci } 70a8e1175bSopenharmony_ci mbedtls_rsa_init(*p_rsa); 71a8e1175bSopenharmony_ci 72a8e1175bSopenharmony_ci /* Parse the data. */ 73a8e1175bSopenharmony_ci if (PSA_KEY_TYPE_IS_KEY_PAIR(type)) { 74a8e1175bSopenharmony_ci status = mbedtls_to_psa_error(mbedtls_rsa_parse_key(*p_rsa, data, data_length)); 75a8e1175bSopenharmony_ci } else { 76a8e1175bSopenharmony_ci status = mbedtls_to_psa_error(mbedtls_rsa_parse_pubkey(*p_rsa, data, data_length)); 77a8e1175bSopenharmony_ci } 78a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 79a8e1175bSopenharmony_ci goto exit; 80a8e1175bSopenharmony_ci } 81a8e1175bSopenharmony_ci 82a8e1175bSopenharmony_ci /* The size of an RSA key doesn't have to be a multiple of 8. Mbed TLS 83a8e1175bSopenharmony_ci * supports non-byte-aligned key sizes, but not well. For example, 84a8e1175bSopenharmony_ci * mbedtls_rsa_get_len() returns the key size in bytes, not in bits. */ 85a8e1175bSopenharmony_ci bits = PSA_BYTES_TO_BITS(mbedtls_rsa_get_len(*p_rsa)); 86a8e1175bSopenharmony_ci if (bits > PSA_VENDOR_RSA_MAX_KEY_BITS) { 87a8e1175bSopenharmony_ci status = PSA_ERROR_NOT_SUPPORTED; 88a8e1175bSopenharmony_ci goto exit; 89a8e1175bSopenharmony_ci } 90a8e1175bSopenharmony_ci status = psa_check_rsa_key_byte_aligned(*p_rsa); 91a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 92a8e1175bSopenharmony_ci goto exit; 93a8e1175bSopenharmony_ci } 94a8e1175bSopenharmony_ci 95a8e1175bSopenharmony_ciexit: 96a8e1175bSopenharmony_ci return status; 97a8e1175bSopenharmony_ci} 98a8e1175bSopenharmony_ci#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || 99a8e1175bSopenharmony_ci * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || 100a8e1175bSopenharmony_ci * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || 101a8e1175bSopenharmony_ci * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) || 102a8e1175bSopenharmony_ci * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) || 103a8e1175bSopenharmony_ci * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || 104a8e1175bSopenharmony_ci * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */ 105a8e1175bSopenharmony_ci 106a8e1175bSopenharmony_ci#if (defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) && \ 107a8e1175bSopenharmony_ci defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT)) || \ 108a8e1175bSopenharmony_ci defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) 109a8e1175bSopenharmony_cipsa_status_t mbedtls_psa_rsa_import_key( 110a8e1175bSopenharmony_ci const psa_key_attributes_t *attributes, 111a8e1175bSopenharmony_ci const uint8_t *data, size_t data_length, 112a8e1175bSopenharmony_ci uint8_t *key_buffer, size_t key_buffer_size, 113a8e1175bSopenharmony_ci size_t *key_buffer_length, size_t *bits) 114a8e1175bSopenharmony_ci{ 115a8e1175bSopenharmony_ci psa_status_t status; 116a8e1175bSopenharmony_ci mbedtls_rsa_context *rsa = NULL; 117a8e1175bSopenharmony_ci 118a8e1175bSopenharmony_ci /* Parse input */ 119a8e1175bSopenharmony_ci status = mbedtls_psa_rsa_load_representation(attributes->type, 120a8e1175bSopenharmony_ci data, 121a8e1175bSopenharmony_ci data_length, 122a8e1175bSopenharmony_ci &rsa); 123a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 124a8e1175bSopenharmony_ci goto exit; 125a8e1175bSopenharmony_ci } 126a8e1175bSopenharmony_ci 127a8e1175bSopenharmony_ci *bits = (psa_key_bits_t) PSA_BYTES_TO_BITS(mbedtls_rsa_get_len(rsa)); 128a8e1175bSopenharmony_ci 129a8e1175bSopenharmony_ci /* Re-export the data to PSA export format, such that we can store export 130a8e1175bSopenharmony_ci * representation in the key slot. Export representation in case of RSA is 131a8e1175bSopenharmony_ci * the smallest representation that's allowed as input, so a straight-up 132a8e1175bSopenharmony_ci * allocation of the same size as the input buffer will be large enough. */ 133a8e1175bSopenharmony_ci status = mbedtls_psa_rsa_export_key(attributes->type, 134a8e1175bSopenharmony_ci rsa, 135a8e1175bSopenharmony_ci key_buffer, 136a8e1175bSopenharmony_ci key_buffer_size, 137a8e1175bSopenharmony_ci key_buffer_length); 138a8e1175bSopenharmony_ciexit: 139a8e1175bSopenharmony_ci /* Always free the RSA object */ 140a8e1175bSopenharmony_ci mbedtls_rsa_free(rsa); 141a8e1175bSopenharmony_ci mbedtls_free(rsa); 142a8e1175bSopenharmony_ci 143a8e1175bSopenharmony_ci return status; 144a8e1175bSopenharmony_ci} 145a8e1175bSopenharmony_ci#endif /* (defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) && 146a8e1175bSopenharmony_ci * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT)) || 147a8e1175bSopenharmony_ci * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */ 148a8e1175bSopenharmony_ci 149a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || \ 150a8e1175bSopenharmony_ci defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) 151a8e1175bSopenharmony_cipsa_status_t mbedtls_psa_rsa_export_key(psa_key_type_t type, 152a8e1175bSopenharmony_ci mbedtls_rsa_context *rsa, 153a8e1175bSopenharmony_ci uint8_t *data, 154a8e1175bSopenharmony_ci size_t data_size, 155a8e1175bSopenharmony_ci size_t *data_length) 156a8e1175bSopenharmony_ci{ 157a8e1175bSopenharmony_ci int ret; 158a8e1175bSopenharmony_ci uint8_t *end = data + data_size; 159a8e1175bSopenharmony_ci 160a8e1175bSopenharmony_ci /* PSA Crypto API defines the format of an RSA key as a DER-encoded 161a8e1175bSopenharmony_ci * representation of the non-encrypted PKCS#1 RSAPrivateKey for a 162a8e1175bSopenharmony_ci * private key and of the RFC3279 RSAPublicKey for a public key. */ 163a8e1175bSopenharmony_ci if (PSA_KEY_TYPE_IS_KEY_PAIR(type)) { 164a8e1175bSopenharmony_ci ret = mbedtls_rsa_write_key(rsa, data, &end); 165a8e1175bSopenharmony_ci } else { 166a8e1175bSopenharmony_ci ret = mbedtls_rsa_write_pubkey(rsa, data, &end); 167a8e1175bSopenharmony_ci } 168a8e1175bSopenharmony_ci 169a8e1175bSopenharmony_ci if (ret < 0) { 170a8e1175bSopenharmony_ci /* Clean up in case pk_write failed halfway through. */ 171a8e1175bSopenharmony_ci memset(data, 0, data_size); 172a8e1175bSopenharmony_ci return mbedtls_to_psa_error(ret); 173a8e1175bSopenharmony_ci } 174a8e1175bSopenharmony_ci 175a8e1175bSopenharmony_ci /* The mbedtls_pk_xxx functions write to the end of the buffer. 176a8e1175bSopenharmony_ci * Move the data to the beginning and erase remaining data 177a8e1175bSopenharmony_ci * at the original location. */ 178a8e1175bSopenharmony_ci if (2 * (size_t) ret <= data_size) { 179a8e1175bSopenharmony_ci memcpy(data, data + data_size - ret, ret); 180a8e1175bSopenharmony_ci memset(data + data_size - ret, 0, ret); 181a8e1175bSopenharmony_ci } else if ((size_t) ret < data_size) { 182a8e1175bSopenharmony_ci memmove(data, data + data_size - ret, ret); 183a8e1175bSopenharmony_ci memset(data + ret, 0, data_size - ret); 184a8e1175bSopenharmony_ci } 185a8e1175bSopenharmony_ci 186a8e1175bSopenharmony_ci *data_length = ret; 187a8e1175bSopenharmony_ci return PSA_SUCCESS; 188a8e1175bSopenharmony_ci} 189a8e1175bSopenharmony_ci 190a8e1175bSopenharmony_cipsa_status_t mbedtls_psa_rsa_export_public_key( 191a8e1175bSopenharmony_ci const psa_key_attributes_t *attributes, 192a8e1175bSopenharmony_ci const uint8_t *key_buffer, size_t key_buffer_size, 193a8e1175bSopenharmony_ci uint8_t *data, size_t data_size, size_t *data_length) 194a8e1175bSopenharmony_ci{ 195a8e1175bSopenharmony_ci psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 196a8e1175bSopenharmony_ci mbedtls_rsa_context *rsa = NULL; 197a8e1175bSopenharmony_ci 198a8e1175bSopenharmony_ci status = mbedtls_psa_rsa_load_representation( 199a8e1175bSopenharmony_ci attributes->type, key_buffer, key_buffer_size, &rsa); 200a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 201a8e1175bSopenharmony_ci return status; 202a8e1175bSopenharmony_ci } 203a8e1175bSopenharmony_ci 204a8e1175bSopenharmony_ci status = mbedtls_psa_rsa_export_key(PSA_KEY_TYPE_RSA_PUBLIC_KEY, 205a8e1175bSopenharmony_ci rsa, 206a8e1175bSopenharmony_ci data, 207a8e1175bSopenharmony_ci data_size, 208a8e1175bSopenharmony_ci data_length); 209a8e1175bSopenharmony_ci 210a8e1175bSopenharmony_ci mbedtls_rsa_free(rsa); 211a8e1175bSopenharmony_ci mbedtls_free(rsa); 212a8e1175bSopenharmony_ci 213a8e1175bSopenharmony_ci return status; 214a8e1175bSopenharmony_ci} 215a8e1175bSopenharmony_ci#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || 216a8e1175bSopenharmony_ci * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */ 217a8e1175bSopenharmony_ci 218a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE) 219a8e1175bSopenharmony_cistatic psa_status_t psa_rsa_read_exponent(const uint8_t *e_bytes, 220a8e1175bSopenharmony_ci size_t e_length, 221a8e1175bSopenharmony_ci int *exponent) 222a8e1175bSopenharmony_ci{ 223a8e1175bSopenharmony_ci size_t i; 224a8e1175bSopenharmony_ci uint32_t acc = 0; 225a8e1175bSopenharmony_ci 226a8e1175bSopenharmony_ci /* Mbed TLS encodes the public exponent as an int. For simplicity, only 227a8e1175bSopenharmony_ci * support values that fit in a 32-bit integer, which is larger than 228a8e1175bSopenharmony_ci * int on just about every platform anyway. */ 229a8e1175bSopenharmony_ci if (e_length > sizeof(acc)) { 230a8e1175bSopenharmony_ci return PSA_ERROR_NOT_SUPPORTED; 231a8e1175bSopenharmony_ci } 232a8e1175bSopenharmony_ci for (i = 0; i < e_length; i++) { 233a8e1175bSopenharmony_ci acc = (acc << 8) | e_bytes[i]; 234a8e1175bSopenharmony_ci } 235a8e1175bSopenharmony_ci if (acc > INT_MAX) { 236a8e1175bSopenharmony_ci return PSA_ERROR_NOT_SUPPORTED; 237a8e1175bSopenharmony_ci } 238a8e1175bSopenharmony_ci *exponent = acc; 239a8e1175bSopenharmony_ci return PSA_SUCCESS; 240a8e1175bSopenharmony_ci} 241a8e1175bSopenharmony_ci 242a8e1175bSopenharmony_cipsa_status_t mbedtls_psa_rsa_generate_key( 243a8e1175bSopenharmony_ci const psa_key_attributes_t *attributes, 244a8e1175bSopenharmony_ci const psa_key_production_parameters_t *params, size_t params_data_length, 245a8e1175bSopenharmony_ci uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length) 246a8e1175bSopenharmony_ci{ 247a8e1175bSopenharmony_ci psa_status_t status; 248a8e1175bSopenharmony_ci mbedtls_rsa_context rsa; 249a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 250a8e1175bSopenharmony_ci int exponent = 65537; 251a8e1175bSopenharmony_ci 252a8e1175bSopenharmony_ci if (params_data_length != 0) { 253a8e1175bSopenharmony_ci status = psa_rsa_read_exponent(params->data, params_data_length, 254a8e1175bSopenharmony_ci &exponent); 255a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 256a8e1175bSopenharmony_ci return status; 257a8e1175bSopenharmony_ci } 258a8e1175bSopenharmony_ci } 259a8e1175bSopenharmony_ci 260a8e1175bSopenharmony_ci mbedtls_rsa_init(&rsa); 261a8e1175bSopenharmony_ci ret = mbedtls_rsa_gen_key(&rsa, 262a8e1175bSopenharmony_ci mbedtls_psa_get_random, 263a8e1175bSopenharmony_ci MBEDTLS_PSA_RANDOM_STATE, 264a8e1175bSopenharmony_ci (unsigned int) attributes->bits, 265a8e1175bSopenharmony_ci exponent); 266a8e1175bSopenharmony_ci if (ret != 0) { 267a8e1175bSopenharmony_ci return mbedtls_to_psa_error(ret); 268a8e1175bSopenharmony_ci } 269a8e1175bSopenharmony_ci 270a8e1175bSopenharmony_ci status = mbedtls_psa_rsa_export_key(attributes->type, 271a8e1175bSopenharmony_ci &rsa, key_buffer, key_buffer_size, 272a8e1175bSopenharmony_ci key_buffer_length); 273a8e1175bSopenharmony_ci mbedtls_rsa_free(&rsa); 274a8e1175bSopenharmony_ci 275a8e1175bSopenharmony_ci return status; 276a8e1175bSopenharmony_ci} 277a8e1175bSopenharmony_ci#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE) */ 278a8e1175bSopenharmony_ci 279a8e1175bSopenharmony_ci/****************************************************************/ 280a8e1175bSopenharmony_ci/* Sign/verify hashes */ 281a8e1175bSopenharmony_ci/****************************************************************/ 282a8e1175bSopenharmony_ci 283a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \ 284a8e1175bSopenharmony_ci defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) 285a8e1175bSopenharmony_ci 286a8e1175bSopenharmony_ci/* Decode the hash algorithm from alg and store the mbedtls encoding in 287a8e1175bSopenharmony_ci * md_alg. Verify that the hash length is acceptable. */ 288a8e1175bSopenharmony_cistatic psa_status_t psa_rsa_decode_md_type(psa_algorithm_t alg, 289a8e1175bSopenharmony_ci size_t hash_length, 290a8e1175bSopenharmony_ci mbedtls_md_type_t *md_alg) 291a8e1175bSopenharmony_ci{ 292a8e1175bSopenharmony_ci psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg); 293a8e1175bSopenharmony_ci *md_alg = mbedtls_md_type_from_psa_alg(hash_alg); 294a8e1175bSopenharmony_ci 295a8e1175bSopenharmony_ci /* The Mbed TLS RSA module uses an unsigned int for hash length 296a8e1175bSopenharmony_ci * parameters. Validate that it fits so that we don't risk an 297a8e1175bSopenharmony_ci * overflow later. */ 298a8e1175bSopenharmony_ci#if SIZE_MAX > UINT_MAX 299a8e1175bSopenharmony_ci if ((int)hash_length > (int)UINT_MAX) { 300a8e1175bSopenharmony_ci return PSA_ERROR_INVALID_ARGUMENT; 301a8e1175bSopenharmony_ci } 302a8e1175bSopenharmony_ci#endif 303a8e1175bSopenharmony_ci 304a8e1175bSopenharmony_ci /* For signatures using a hash, the hash length must be correct. */ 305a8e1175bSopenharmony_ci if (alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW) { 306a8e1175bSopenharmony_ci if (*md_alg == MBEDTLS_MD_NONE) { 307a8e1175bSopenharmony_ci return PSA_ERROR_NOT_SUPPORTED; 308a8e1175bSopenharmony_ci } 309a8e1175bSopenharmony_ci if (mbedtls_md_get_size_from_type(*md_alg) != hash_length) { 310a8e1175bSopenharmony_ci return PSA_ERROR_INVALID_ARGUMENT; 311a8e1175bSopenharmony_ci } 312a8e1175bSopenharmony_ci } 313a8e1175bSopenharmony_ci 314a8e1175bSopenharmony_ci return PSA_SUCCESS; 315a8e1175bSopenharmony_ci} 316a8e1175bSopenharmony_ci 317a8e1175bSopenharmony_cipsa_status_t mbedtls_psa_rsa_sign_hash( 318a8e1175bSopenharmony_ci const psa_key_attributes_t *attributes, 319a8e1175bSopenharmony_ci const uint8_t *key_buffer, size_t key_buffer_size, 320a8e1175bSopenharmony_ci psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, 321a8e1175bSopenharmony_ci uint8_t *signature, size_t signature_size, size_t *signature_length) 322a8e1175bSopenharmony_ci{ 323a8e1175bSopenharmony_ci psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 324a8e1175bSopenharmony_ci mbedtls_rsa_context *rsa = NULL; 325a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 326a8e1175bSopenharmony_ci mbedtls_md_type_t md_alg; 327a8e1175bSopenharmony_ci 328a8e1175bSopenharmony_ci status = mbedtls_psa_rsa_load_representation(attributes->type, 329a8e1175bSopenharmony_ci key_buffer, 330a8e1175bSopenharmony_ci key_buffer_size, 331a8e1175bSopenharmony_ci &rsa); 332a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 333a8e1175bSopenharmony_ci return status; 334a8e1175bSopenharmony_ci } 335a8e1175bSopenharmony_ci 336a8e1175bSopenharmony_ci status = psa_rsa_decode_md_type(alg, hash_length, &md_alg); 337a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 338a8e1175bSopenharmony_ci goto exit; 339a8e1175bSopenharmony_ci } 340a8e1175bSopenharmony_ci 341a8e1175bSopenharmony_ci if (signature_size < mbedtls_rsa_get_len(rsa)) { 342a8e1175bSopenharmony_ci status = PSA_ERROR_BUFFER_TOO_SMALL; 343a8e1175bSopenharmony_ci goto exit; 344a8e1175bSopenharmony_ci } 345a8e1175bSopenharmony_ci 346a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) 347a8e1175bSopenharmony_ci if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) { 348a8e1175bSopenharmony_ci ret = mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V15, 349a8e1175bSopenharmony_ci MBEDTLS_MD_NONE); 350a8e1175bSopenharmony_ci if (ret == 0) { 351a8e1175bSopenharmony_ci ret = mbedtls_rsa_pkcs1_sign(rsa, 352a8e1175bSopenharmony_ci mbedtls_psa_get_random, 353a8e1175bSopenharmony_ci MBEDTLS_PSA_RANDOM_STATE, 354a8e1175bSopenharmony_ci md_alg, 355a8e1175bSopenharmony_ci (unsigned int) hash_length, 356a8e1175bSopenharmony_ci hash, 357a8e1175bSopenharmony_ci signature); 358a8e1175bSopenharmony_ci } 359a8e1175bSopenharmony_ci } else 360a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */ 361a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) 362a8e1175bSopenharmony_ci if (PSA_ALG_IS_RSA_PSS(alg)) { 363a8e1175bSopenharmony_ci ret = mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, md_alg); 364a8e1175bSopenharmony_ci 365a8e1175bSopenharmony_ci if (ret == 0) { 366a8e1175bSopenharmony_ci ret = mbedtls_rsa_rsassa_pss_sign(rsa, 367a8e1175bSopenharmony_ci mbedtls_psa_get_random, 368a8e1175bSopenharmony_ci MBEDTLS_PSA_RANDOM_STATE, 369a8e1175bSopenharmony_ci MBEDTLS_MD_NONE, 370a8e1175bSopenharmony_ci (unsigned int) hash_length, 371a8e1175bSopenharmony_ci hash, 372a8e1175bSopenharmony_ci signature); 373a8e1175bSopenharmony_ci } 374a8e1175bSopenharmony_ci } else 375a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */ 376a8e1175bSopenharmony_ci { 377a8e1175bSopenharmony_ci status = PSA_ERROR_INVALID_ARGUMENT; 378a8e1175bSopenharmony_ci goto exit; 379a8e1175bSopenharmony_ci } 380a8e1175bSopenharmony_ci 381a8e1175bSopenharmony_ci if (ret == 0) { 382a8e1175bSopenharmony_ci *signature_length = mbedtls_rsa_get_len(rsa); 383a8e1175bSopenharmony_ci } 384a8e1175bSopenharmony_ci status = mbedtls_to_psa_error(ret); 385a8e1175bSopenharmony_ci 386a8e1175bSopenharmony_ciexit: 387a8e1175bSopenharmony_ci mbedtls_rsa_free(rsa); 388a8e1175bSopenharmony_ci mbedtls_free(rsa); 389a8e1175bSopenharmony_ci 390a8e1175bSopenharmony_ci return status; 391a8e1175bSopenharmony_ci} 392a8e1175bSopenharmony_ci 393a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) 394a8e1175bSopenharmony_cistatic int rsa_pss_expected_salt_len(psa_algorithm_t alg, 395a8e1175bSopenharmony_ci const mbedtls_rsa_context *rsa, 396a8e1175bSopenharmony_ci size_t hash_length) 397a8e1175bSopenharmony_ci{ 398a8e1175bSopenharmony_ci if (PSA_ALG_IS_RSA_PSS_ANY_SALT(alg)) { 399a8e1175bSopenharmony_ci return MBEDTLS_RSA_SALT_LEN_ANY; 400a8e1175bSopenharmony_ci } 401a8e1175bSopenharmony_ci /* Otherwise: standard salt length, i.e. largest possible salt length 402a8e1175bSopenharmony_ci * up to the hash length. */ 403a8e1175bSopenharmony_ci int klen = (int) mbedtls_rsa_get_len(rsa); // known to fit 404a8e1175bSopenharmony_ci int hlen = (int) hash_length; // known to fit 405a8e1175bSopenharmony_ci int room = klen - 2 - hlen; 406a8e1175bSopenharmony_ci if (room < 0) { 407a8e1175bSopenharmony_ci return 0; // there is no valid signature in this case anyway 408a8e1175bSopenharmony_ci } else if (room > hlen) { 409a8e1175bSopenharmony_ci return hlen; 410a8e1175bSopenharmony_ci } else { 411a8e1175bSopenharmony_ci return room; 412a8e1175bSopenharmony_ci } 413a8e1175bSopenharmony_ci} 414a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */ 415a8e1175bSopenharmony_ci 416a8e1175bSopenharmony_cipsa_status_t mbedtls_psa_rsa_verify_hash( 417a8e1175bSopenharmony_ci const psa_key_attributes_t *attributes, 418a8e1175bSopenharmony_ci const uint8_t *key_buffer, size_t key_buffer_size, 419a8e1175bSopenharmony_ci psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, 420a8e1175bSopenharmony_ci const uint8_t *signature, size_t signature_length) 421a8e1175bSopenharmony_ci{ 422a8e1175bSopenharmony_ci psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 423a8e1175bSopenharmony_ci mbedtls_rsa_context *rsa = NULL; 424a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 425a8e1175bSopenharmony_ci mbedtls_md_type_t md_alg; 426a8e1175bSopenharmony_ci 427a8e1175bSopenharmony_ci status = mbedtls_psa_rsa_load_representation(attributes->type, 428a8e1175bSopenharmony_ci key_buffer, 429a8e1175bSopenharmony_ci key_buffer_size, 430a8e1175bSopenharmony_ci &rsa); 431a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 432a8e1175bSopenharmony_ci goto exit; 433a8e1175bSopenharmony_ci } 434a8e1175bSopenharmony_ci 435a8e1175bSopenharmony_ci status = psa_rsa_decode_md_type(alg, hash_length, &md_alg); 436a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 437a8e1175bSopenharmony_ci goto exit; 438a8e1175bSopenharmony_ci } 439a8e1175bSopenharmony_ci 440a8e1175bSopenharmony_ci if (signature_length != mbedtls_rsa_get_len(rsa)) { 441a8e1175bSopenharmony_ci status = PSA_ERROR_INVALID_SIGNATURE; 442a8e1175bSopenharmony_ci goto exit; 443a8e1175bSopenharmony_ci } 444a8e1175bSopenharmony_ci 445a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) 446a8e1175bSopenharmony_ci if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) { 447a8e1175bSopenharmony_ci ret = mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V15, 448a8e1175bSopenharmony_ci MBEDTLS_MD_NONE); 449a8e1175bSopenharmony_ci if (ret == 0) { 450a8e1175bSopenharmony_ci ret = mbedtls_rsa_pkcs1_verify(rsa, 451a8e1175bSopenharmony_ci md_alg, 452a8e1175bSopenharmony_ci (unsigned int) hash_length, 453a8e1175bSopenharmony_ci hash, 454a8e1175bSopenharmony_ci signature); 455a8e1175bSopenharmony_ci } 456a8e1175bSopenharmony_ci } else 457a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */ 458a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) 459a8e1175bSopenharmony_ci if (PSA_ALG_IS_RSA_PSS(alg)) { 460a8e1175bSopenharmony_ci ret = mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, md_alg); 461a8e1175bSopenharmony_ci if (ret == 0) { 462a8e1175bSopenharmony_ci int slen = rsa_pss_expected_salt_len(alg, rsa, hash_length); 463a8e1175bSopenharmony_ci ret = mbedtls_rsa_rsassa_pss_verify_ext(rsa, 464a8e1175bSopenharmony_ci md_alg, 465a8e1175bSopenharmony_ci (unsigned) hash_length, 466a8e1175bSopenharmony_ci hash, 467a8e1175bSopenharmony_ci md_alg, 468a8e1175bSopenharmony_ci slen, 469a8e1175bSopenharmony_ci signature); 470a8e1175bSopenharmony_ci } 471a8e1175bSopenharmony_ci } else 472a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */ 473a8e1175bSopenharmony_ci { 474a8e1175bSopenharmony_ci status = PSA_ERROR_INVALID_ARGUMENT; 475a8e1175bSopenharmony_ci goto exit; 476a8e1175bSopenharmony_ci } 477a8e1175bSopenharmony_ci 478a8e1175bSopenharmony_ci /* Mbed TLS distinguishes "invalid padding" from "valid padding but 479a8e1175bSopenharmony_ci * the rest of the signature is invalid". This has little use in 480a8e1175bSopenharmony_ci * practice and PSA doesn't report this distinction. */ 481a8e1175bSopenharmony_ci status = (ret == MBEDTLS_ERR_RSA_INVALID_PADDING) ? 482a8e1175bSopenharmony_ci PSA_ERROR_INVALID_SIGNATURE : 483a8e1175bSopenharmony_ci mbedtls_to_psa_error(ret); 484a8e1175bSopenharmony_ci 485a8e1175bSopenharmony_ciexit: 486a8e1175bSopenharmony_ci mbedtls_rsa_free(rsa); 487a8e1175bSopenharmony_ci mbedtls_free(rsa); 488a8e1175bSopenharmony_ci 489a8e1175bSopenharmony_ci return status; 490a8e1175bSopenharmony_ci} 491a8e1175bSopenharmony_ci 492a8e1175bSopenharmony_ci#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || 493a8e1175bSopenharmony_ci * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */ 494a8e1175bSopenharmony_ci 495a8e1175bSopenharmony_ci/****************************************************************/ 496a8e1175bSopenharmony_ci/* Asymmetric cryptography */ 497a8e1175bSopenharmony_ci/****************************************************************/ 498a8e1175bSopenharmony_ci 499a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) 500a8e1175bSopenharmony_cistatic int psa_rsa_oaep_set_padding_mode(psa_algorithm_t alg, 501a8e1175bSopenharmony_ci mbedtls_rsa_context *rsa) 502a8e1175bSopenharmony_ci{ 503a8e1175bSopenharmony_ci psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH(alg); 504a8e1175bSopenharmony_ci mbedtls_md_type_t md_alg = mbedtls_md_type_from_psa_alg(hash_alg); 505a8e1175bSopenharmony_ci 506a8e1175bSopenharmony_ci /* Just to get the error status right, as rsa_set_padding() doesn't 507a8e1175bSopenharmony_ci * distinguish between "bad RSA algorithm" and "unknown hash". */ 508a8e1175bSopenharmony_ci if (mbedtls_md_info_from_type(md_alg) == NULL) { 509a8e1175bSopenharmony_ci return PSA_ERROR_NOT_SUPPORTED; 510a8e1175bSopenharmony_ci } 511a8e1175bSopenharmony_ci 512a8e1175bSopenharmony_ci return mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, md_alg); 513a8e1175bSopenharmony_ci} 514a8e1175bSopenharmony_ci#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */ 515a8e1175bSopenharmony_ci 516a8e1175bSopenharmony_cipsa_status_t mbedtls_psa_asymmetric_encrypt(const psa_key_attributes_t *attributes, 517a8e1175bSopenharmony_ci const uint8_t *key_buffer, 518a8e1175bSopenharmony_ci size_t key_buffer_size, 519a8e1175bSopenharmony_ci psa_algorithm_t alg, 520a8e1175bSopenharmony_ci const uint8_t *input, 521a8e1175bSopenharmony_ci size_t input_length, 522a8e1175bSopenharmony_ci const uint8_t *salt, 523a8e1175bSopenharmony_ci size_t salt_length, 524a8e1175bSopenharmony_ci uint8_t *output, 525a8e1175bSopenharmony_ci size_t output_size, 526a8e1175bSopenharmony_ci size_t *output_length) 527a8e1175bSopenharmony_ci{ 528a8e1175bSopenharmony_ci psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 529a8e1175bSopenharmony_ci (void) key_buffer; 530a8e1175bSopenharmony_ci (void) key_buffer_size; 531a8e1175bSopenharmony_ci (void) input; 532a8e1175bSopenharmony_ci (void) input_length; 533a8e1175bSopenharmony_ci (void) salt; 534a8e1175bSopenharmony_ci (void) salt_length; 535a8e1175bSopenharmony_ci (void) output; 536a8e1175bSopenharmony_ci (void) output_size; 537a8e1175bSopenharmony_ci (void) output_length; 538a8e1175bSopenharmony_ci 539a8e1175bSopenharmony_ci if (PSA_KEY_TYPE_IS_RSA(attributes->type)) { 540a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \ 541a8e1175bSopenharmony_ci defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) 542a8e1175bSopenharmony_ci mbedtls_rsa_context *rsa = NULL; 543a8e1175bSopenharmony_ci status = mbedtls_psa_rsa_load_representation(attributes->type, 544a8e1175bSopenharmony_ci key_buffer, 545a8e1175bSopenharmony_ci key_buffer_size, 546a8e1175bSopenharmony_ci &rsa); 547a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 548a8e1175bSopenharmony_ci goto rsa_exit; 549a8e1175bSopenharmony_ci } 550a8e1175bSopenharmony_ci 551a8e1175bSopenharmony_ci if (output_size < mbedtls_rsa_get_len(rsa)) { 552a8e1175bSopenharmony_ci status = PSA_ERROR_BUFFER_TOO_SMALL; 553a8e1175bSopenharmony_ci goto rsa_exit; 554a8e1175bSopenharmony_ci } 555a8e1175bSopenharmony_ci#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || 556a8e1175bSopenharmony_ci * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */ 557a8e1175bSopenharmony_ci if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) { 558a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) 559a8e1175bSopenharmony_ci status = mbedtls_to_psa_error( 560a8e1175bSopenharmony_ci mbedtls_rsa_pkcs1_encrypt(rsa, 561a8e1175bSopenharmony_ci mbedtls_psa_get_random, 562a8e1175bSopenharmony_ci MBEDTLS_PSA_RANDOM_STATE, 563a8e1175bSopenharmony_ci input_length, 564a8e1175bSopenharmony_ci input, 565a8e1175bSopenharmony_ci output)); 566a8e1175bSopenharmony_ci#else 567a8e1175bSopenharmony_ci status = PSA_ERROR_NOT_SUPPORTED; 568a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */ 569a8e1175bSopenharmony_ci } else 570a8e1175bSopenharmony_ci if (PSA_ALG_IS_RSA_OAEP(alg)) { 571a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) 572a8e1175bSopenharmony_ci status = mbedtls_to_psa_error( 573a8e1175bSopenharmony_ci psa_rsa_oaep_set_padding_mode(alg, rsa)); 574a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 575a8e1175bSopenharmony_ci goto rsa_exit; 576a8e1175bSopenharmony_ci } 577a8e1175bSopenharmony_ci 578a8e1175bSopenharmony_ci status = mbedtls_to_psa_error( 579a8e1175bSopenharmony_ci mbedtls_rsa_rsaes_oaep_encrypt(rsa, 580a8e1175bSopenharmony_ci mbedtls_psa_get_random, 581a8e1175bSopenharmony_ci MBEDTLS_PSA_RANDOM_STATE, 582a8e1175bSopenharmony_ci salt, salt_length, 583a8e1175bSopenharmony_ci input_length, 584a8e1175bSopenharmony_ci input, 585a8e1175bSopenharmony_ci output)); 586a8e1175bSopenharmony_ci#else 587a8e1175bSopenharmony_ci status = PSA_ERROR_NOT_SUPPORTED; 588a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */ 589a8e1175bSopenharmony_ci } else { 590a8e1175bSopenharmony_ci status = PSA_ERROR_INVALID_ARGUMENT; 591a8e1175bSopenharmony_ci } 592a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \ 593a8e1175bSopenharmony_ci defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) 594a8e1175bSopenharmony_cirsa_exit: 595a8e1175bSopenharmony_ci if (status == PSA_SUCCESS) { 596a8e1175bSopenharmony_ci *output_length = mbedtls_rsa_get_len(rsa); 597a8e1175bSopenharmony_ci } 598a8e1175bSopenharmony_ci 599a8e1175bSopenharmony_ci mbedtls_rsa_free(rsa); 600a8e1175bSopenharmony_ci mbedtls_free(rsa); 601a8e1175bSopenharmony_ci#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || 602a8e1175bSopenharmony_ci * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */ 603a8e1175bSopenharmony_ci } else { 604a8e1175bSopenharmony_ci status = PSA_ERROR_NOT_SUPPORTED; 605a8e1175bSopenharmony_ci } 606a8e1175bSopenharmony_ci 607a8e1175bSopenharmony_ci return status; 608a8e1175bSopenharmony_ci} 609a8e1175bSopenharmony_ci 610a8e1175bSopenharmony_cipsa_status_t mbedtls_psa_asymmetric_decrypt(const psa_key_attributes_t *attributes, 611a8e1175bSopenharmony_ci const uint8_t *key_buffer, 612a8e1175bSopenharmony_ci size_t key_buffer_size, 613a8e1175bSopenharmony_ci psa_algorithm_t alg, 614a8e1175bSopenharmony_ci const uint8_t *input, 615a8e1175bSopenharmony_ci size_t input_length, 616a8e1175bSopenharmony_ci const uint8_t *salt, 617a8e1175bSopenharmony_ci size_t salt_length, 618a8e1175bSopenharmony_ci uint8_t *output, 619a8e1175bSopenharmony_ci size_t output_size, 620a8e1175bSopenharmony_ci size_t *output_length) 621a8e1175bSopenharmony_ci{ 622a8e1175bSopenharmony_ci psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 623a8e1175bSopenharmony_ci (void) key_buffer; 624a8e1175bSopenharmony_ci (void) key_buffer_size; 625a8e1175bSopenharmony_ci (void) input; 626a8e1175bSopenharmony_ci (void) input_length; 627a8e1175bSopenharmony_ci (void) salt; 628a8e1175bSopenharmony_ci (void) salt_length; 629a8e1175bSopenharmony_ci (void) output; 630a8e1175bSopenharmony_ci (void) output_size; 631a8e1175bSopenharmony_ci (void) output_length; 632a8e1175bSopenharmony_ci 633a8e1175bSopenharmony_ci *output_length = 0; 634a8e1175bSopenharmony_ci 635a8e1175bSopenharmony_ci if (attributes->type == PSA_KEY_TYPE_RSA_KEY_PAIR) { 636a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \ 637a8e1175bSopenharmony_ci defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) 638a8e1175bSopenharmony_ci mbedtls_rsa_context *rsa = NULL; 639a8e1175bSopenharmony_ci status = mbedtls_psa_rsa_load_representation(attributes->type, 640a8e1175bSopenharmony_ci key_buffer, 641a8e1175bSopenharmony_ci key_buffer_size, 642a8e1175bSopenharmony_ci &rsa); 643a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 644a8e1175bSopenharmony_ci goto rsa_exit; 645a8e1175bSopenharmony_ci } 646a8e1175bSopenharmony_ci 647a8e1175bSopenharmony_ci if (input_length != mbedtls_rsa_get_len(rsa)) { 648a8e1175bSopenharmony_ci status = PSA_ERROR_INVALID_ARGUMENT; 649a8e1175bSopenharmony_ci goto rsa_exit; 650a8e1175bSopenharmony_ci } 651a8e1175bSopenharmony_ci#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || 652a8e1175bSopenharmony_ci * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */ 653a8e1175bSopenharmony_ci 654a8e1175bSopenharmony_ci if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) { 655a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) 656a8e1175bSopenharmony_ci status = mbedtls_to_psa_error( 657a8e1175bSopenharmony_ci mbedtls_rsa_pkcs1_decrypt(rsa, 658a8e1175bSopenharmony_ci mbedtls_psa_get_random, 659a8e1175bSopenharmony_ci MBEDTLS_PSA_RANDOM_STATE, 660a8e1175bSopenharmony_ci output_length, 661a8e1175bSopenharmony_ci input, 662a8e1175bSopenharmony_ci output, 663a8e1175bSopenharmony_ci output_size)); 664a8e1175bSopenharmony_ci#else 665a8e1175bSopenharmony_ci status = PSA_ERROR_NOT_SUPPORTED; 666a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */ 667a8e1175bSopenharmony_ci } else 668a8e1175bSopenharmony_ci if (PSA_ALG_IS_RSA_OAEP(alg)) { 669a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) 670a8e1175bSopenharmony_ci status = mbedtls_to_psa_error( 671a8e1175bSopenharmony_ci psa_rsa_oaep_set_padding_mode(alg, rsa)); 672a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 673a8e1175bSopenharmony_ci goto rsa_exit; 674a8e1175bSopenharmony_ci } 675a8e1175bSopenharmony_ci 676a8e1175bSopenharmony_ci status = mbedtls_to_psa_error( 677a8e1175bSopenharmony_ci mbedtls_rsa_rsaes_oaep_decrypt(rsa, 678a8e1175bSopenharmony_ci mbedtls_psa_get_random, 679a8e1175bSopenharmony_ci MBEDTLS_PSA_RANDOM_STATE, 680a8e1175bSopenharmony_ci salt, salt_length, 681a8e1175bSopenharmony_ci output_length, 682a8e1175bSopenharmony_ci input, 683a8e1175bSopenharmony_ci output, 684a8e1175bSopenharmony_ci output_size)); 685a8e1175bSopenharmony_ci#else 686a8e1175bSopenharmony_ci status = PSA_ERROR_NOT_SUPPORTED; 687a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */ 688a8e1175bSopenharmony_ci } else { 689a8e1175bSopenharmony_ci status = PSA_ERROR_INVALID_ARGUMENT; 690a8e1175bSopenharmony_ci } 691a8e1175bSopenharmony_ci 692a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \ 693a8e1175bSopenharmony_ci defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) 694a8e1175bSopenharmony_cirsa_exit: 695a8e1175bSopenharmony_ci mbedtls_rsa_free(rsa); 696a8e1175bSopenharmony_ci mbedtls_free(rsa); 697a8e1175bSopenharmony_ci#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || 698a8e1175bSopenharmony_ci * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */ 699a8e1175bSopenharmony_ci } else { 700a8e1175bSopenharmony_ci status = PSA_ERROR_NOT_SUPPORTED; 701a8e1175bSopenharmony_ci } 702a8e1175bSopenharmony_ci 703a8e1175bSopenharmony_ci return status; 704a8e1175bSopenharmony_ci} 705a8e1175bSopenharmony_ci 706a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_CRYPTO_C */ 707