1a8e1175bSopenharmony_ci# Transitioning to the PSA API
2a8e1175bSopenharmony_ci
3a8e1175bSopenharmony_ci> I have code written for `mbedtls_` cryptography APIs. How do I migrate to `psa_` APIs?
4a8e1175bSopenharmony_ci
5a8e1175bSopenharmony_ci## Introduction
6a8e1175bSopenharmony_ci
7a8e1175bSopenharmony_ciMbed TLS is gradually moving from legacy `mbedtls_xxx` APIs to newer `psa_xxx` APIs for cryptography. Note that this only concerns cryptography APIs, not X.509 or SSL/TLS APIs.
8a8e1175bSopenharmony_ci
9a8e1175bSopenharmony_ciThis guide is intended to help migrate existing applications that use Mbed TLS for cryptography. It aims to cover common use cases, but cannot cover all possible scenarios.
10a8e1175bSopenharmony_ci
11a8e1175bSopenharmony_ci### Suggested reading
12a8e1175bSopenharmony_ci
13a8e1175bSopenharmony_ciThis document is long, but you probably don't need to read all of it. You should start with the following sections:
14a8e1175bSopenharmony_ci
15a8e1175bSopenharmony_ci1. [Where can I find documentation?](#where-can-i-find-documentation)
16a8e1175bSopenharmony_ci2. [General considerations](#general-considerations)
17a8e1175bSopenharmony_ci
18a8e1175bSopenharmony_ciThen use the [summary of API modules](#summary-of-api-modules), the table of contents or a text search to locate the sections that interest you, based on what legacy interfaces your code is currently using.
19a8e1175bSopenharmony_ci
20a8e1175bSopenharmony_ci### Where can I find documentation?
21a8e1175bSopenharmony_ci
22a8e1175bSopenharmony_ci**Tutorial**: See the [getting started guide](https://mbed-tls.readthedocs.io/en/latest/getting_started/psa/).
23a8e1175bSopenharmony_ci
24a8e1175bSopenharmony_ci**Reference**: The [PSA Crypto API specification](https://arm-software.github.io/psa-api/crypto/) is available online. Mbed TLS implements a large subset of the specification which is documented in the [`psa/crypto*.h` headers](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto_8h/).
25a8e1175bSopenharmony_ci
26a8e1175bSopenharmony_ci### Additional resources
27a8e1175bSopenharmony_ci
28a8e1175bSopenharmony_ci* [Mbed TLS open issues](https://github.com/Mbed-TLS/mbedtls/issues)
29a8e1175bSopenharmony_ci* [PSA API open issues](https://github.com/ARM-software/psa-api/issues) (not just cryptography APIs)
30a8e1175bSopenharmony_ci* [Mbed TLS mailing list](https://lists.trustedfirmware.org/mailman3/lists/mbed-tls.lists.trustedfirmware.org/)
31a8e1175bSopenharmony_ci
32a8e1175bSopenharmony_ci### Why change the API?
33a8e1175bSopenharmony_ci
34a8e1175bSopenharmony_ci* Mbed TLS APIs are traditionally very transparent: the caller can access internal fields of operations. This is less true in the 3.x major version than before, but still the case to some extent. This offers applications some flexibility, but it removes flexibility from the implementation. For example, it is hard to support hardware acceleration, because the API constrains how the data must be represented. PSA APIs were designed to be more opaque, giving more freedom to the implementation.
35a8e1175bSopenharmony_ci* Mbed TLS legacy APIs require key material to be present in the application memory. The PSA Crypto API natively supports operations on keys stored in an external [location](https://arm-software.github.io/psa-api/crypto/1.1/api/keys/lifetimes.html#c.psa_key_location_t) (secure enclave, secure element, HSM, etc.).
36a8e1175bSopenharmony_ci* PSA APIs have [consistent conventions](https://arm-software.github.io/psa-api/crypto/1.1/overview/conventions.html#parameter-conventions) which many legacy APIs in Mbed TLS do not follow. For example, many legacy cryptography functions require the caller to know how large an output buffer needs to be based on the selected algorithm, whereas in the PSA API, all buffer arguments have a well-defined size and those sizes are checked.
37a8e1175bSopenharmony_ci* Mbed TLS legacy APIs require passing around a random generator argument where needed. This has historically been problematic with functions that were created without an RNG argument but later needed one as part of a security countermeasure. The PSA crypto subsystem maintains a global random generator, resolving this problem.
38a8e1175bSopenharmony_ci
39a8e1175bSopenharmony_ci### Migration timeline
40a8e1175bSopenharmony_ci
41a8e1175bSopenharmony_ci* Mbed TLS 2.15.0 (Nov 2018): first release with a draft implementation of the PSA API.
42a8e1175bSopenharmony_ci* Mbed TLS 2.18.0 (Jun 2019): The PSA API is available in the default build.
43a8e1175bSopenharmony_ci* Mbed TLS 3.1.0 (Dec 2021): TLS 1.3 support is the first major feature that requires the PSA API.
44a8e1175bSopenharmony_ci* Mbed TLS 4.0.0 (2024?): X.509 and TLS require the PSA API. Removal of some legacy crypto APIs.
45a8e1175bSopenharmony_ci* Mbed TLS 5.0.0 (??): Removal of the remaining non-PSA crypto APIs.
46a8e1175bSopenharmony_ci
47a8e1175bSopenharmony_ci## General considerations
48a8e1175bSopenharmony_ci
49a8e1175bSopenharmony_ci### Configuration of the PSA subsystem
50a8e1175bSopenharmony_ci
51a8e1175bSopenharmony_ciTo make the PSA API available, make sure that the configuration option [`MBEDTLS_PSA_CRYPTO_C`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/mbedtls__config_8h/#c.MBEDTLS_PSA_CRYPTO_C) is enabled. (It is enabled in the default configuration.)
52a8e1175bSopenharmony_ci
53a8e1175bSopenharmony_ciYou should probably enable [`MBEDTLS_USE_PSA_CRYPTO`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/mbedtls__config_8h/#mbedtls__config_8h_1a70fd7b97d5f11170546583f2095942a6) as well (it is disabled by default). This option causes the PK, X.509 and TLS modules to use PSA crypto under the hood.
54a8e1175bSopenharmony_ci
55a8e1175bSopenharmony_ciBy default, the PSA crypto API offers a similar set of cryptographic mechanisms as those offered by the legacy API (configured by `MBEDTLS_XXX` macros). The PSA crypto API also has its own configuration mechanism; see “[Cryptographic mechanism availability](#cryptographic-mechanism-availability)”.
56a8e1175bSopenharmony_ci
57a8e1175bSopenharmony_ci### Header files
58a8e1175bSopenharmony_ci
59a8e1175bSopenharmony_ciApplications only need to include a single header file:
60a8e1175bSopenharmony_ci```
61a8e1175bSopenharmony_ci#include <psa/crypto.h>
62a8e1175bSopenharmony_ci```
63a8e1175bSopenharmony_ci
64a8e1175bSopenharmony_ci### General application layout
65a8e1175bSopenharmony_ci
66a8e1175bSopenharmony_ciBefore any cryptographic operation, call [`psa_crypto_init`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__initialization/#group__initialization_1ga2de150803fc2f7dc6101d5af7e921dd9) and check that it succeeds. (A failure indicates an abnormal system state from which most applications cannot recover.)
67a8e1175bSopenharmony_ci
68a8e1175bSopenharmony_ciIf you wish to free all resources associated with PSA cryptography, call [`mbedtls_psa_crypto_free`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__extra_8h/#_CPPv423mbedtls_psa_crypto_freev).
69a8e1175bSopenharmony_ci
70a8e1175bSopenharmony_ciThe PSA subsystem has an internal random generator. As a consequence, you do not need to instantiate one manually (no need to create an `mbedtls_entropy_context` and an `mbedtls_xxx_drbg_context`).
71a8e1175bSopenharmony_ci
72a8e1175bSopenharmony_ci### Error codes
73a8e1175bSopenharmony_ci
74a8e1175bSopenharmony_ciMbed TLS functions return a status of type `int`: 0 for success (or occasionally a positive value which is the output length), or a negative value `MBEDTLS_ERR_xxx` indicating an error.
75a8e1175bSopenharmony_ci
76a8e1175bSopenharmony_ciPSA functions return a status of type [`psa_status_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__error/#group__error_1ga05676e70ba5c6a7565aff3c36677c1f9): `PSA_SUCCESS == 0` for success, or a negative value [`PSA_ERROR_xxx`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__error/) indicating an error.
77a8e1175bSopenharmony_ci
78a8e1175bSopenharmony_ci### Memory management
79a8e1175bSopenharmony_ci
80a8e1175bSopenharmony_ciApart from keys, as described in “[Key management](#key-management)” below, APIs that need to preserve state between function calls store this state in a structure allocated by the calling code. For example, multipart operations store state in a multipart operation object.
81a8e1175bSopenharmony_ci
82a8e1175bSopenharmony_ciAll PSA operation objects must be zero-initialized (or equivalently, initialized with the provided `PSA_XXX_INIT` macro or `psa_xxx_init()` function) before calling any API function.
83a8e1175bSopenharmony_ci
84a8e1175bSopenharmony_ciFunctions that output data require an output buffer of sufficient size. For all PSA crypto API functions that have an output buffer, there is a corresponding macro, generally called `PSA_XXX_OUTPUT_SIZE`, that calculates a sufficient size for the output buffer, given the relevant parameters. In some cases, there may be macros with less precision which can be resolved at compile time. For example, for the size of a buffer containing a hash, you can use `PSA_HASH_LENGTH(hash_alg)` where `hash_alg` is a specific hash algorithm, or `PSA_HASH_MAX_SIZE` for a buffer that is long enough for any supported hash. See the relevant sections of this document and of the reference documentation for more details.
85a8e1175bSopenharmony_ci
86a8e1175bSopenharmony_ci#### Key management
87a8e1175bSopenharmony_ci
88a8e1175bSopenharmony_ciOne of the major differences between the legacy API and the PSA API is that in the PSA API, access to keys is indirect. Operations that require a key take a parameter of type [`psa_key_id_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__types_8h/#_CPPv412psa_key_id_t), which is an identifier for the key. This allows the API to be used with keys that are not directly accessible to the application, for example because they are stored in a secure environment that does not allow the key material to be exported.
89a8e1175bSopenharmony_ci
90a8e1175bSopenharmony_ciTo use a key:
91a8e1175bSopenharmony_ci
92a8e1175bSopenharmony_ci1. First create a key object with a key creation function. The two most common ones are [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b) if you have the key material available and [`psa_generate_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga1985eae417dfbccedf50d5fff54ea8c5) to create a random key. The key creation function has the key identifier as an output parameter.
93a8e1175bSopenharmony_ci2. Use the key as desired, passing the key identifier obtained during the key creation.
94a8e1175bSopenharmony_ci3. Finally destroy the key object with [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2).
95a8e1175bSopenharmony_ci
96a8e1175bSopenharmony_ciSee “[Cipher key management](#cipher-key-management)”, “[MAC key management](#mac-key-management)”, “[Key lifecycle for asymmetric cryptography](#key-lifecycle-for-asymmetric-cryptography)”, “[Creating keys for asymmetric cryptography](#creating-keys-for-asymmetric-cryptography)” and “[Diffie-Hellman key pair management](#diffie-hellman-key-pair-management)” for more details about key management in specific workflows, including information about choosing the key's attributes.
97a8e1175bSopenharmony_ci
98a8e1175bSopenharmony_ciIf you need access to the key material, call [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf). If you need the public key corresponding to a key pair object, call [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062).
99a8e1175bSopenharmony_ci
100a8e1175bSopenharmony_ciNote that a key consumes a key store entry, which is distinct from heap memory, until it is destroyed or the application exits. (This is not true for persistent keys, which instead consume disk space. Since persistent keys have no analog in the legacy API, we will not discuss them further in this document.)
101a8e1175bSopenharmony_ci
102a8e1175bSopenharmony_ci## Summary of API modules
103a8e1175bSopenharmony_ci
104a8e1175bSopenharmony_ci| Header | Function prefix | PSA equivalent |
105a8e1175bSopenharmony_ci| ------ | --------------- | -------------- |
106a8e1175bSopenharmony_ci| `aes.h` | `mbedtls_aes_` | [Symmetric encryption](#symmetric-encryption) |
107a8e1175bSopenharmony_ci| `aria.h` | `mbedtls_aria_` | [Symmetric encryption](#symmetric-encryption) |
108a8e1175bSopenharmony_ci| `asn1.h` | `mbedtls_asn1_` | No change ([PK support interface](#pk-format-support-interfaces)) |
109a8e1175bSopenharmony_ci| `asn1write.h` | `mbedtls_asn1_write_` | No change ([PK support interface](#pk-format-support-interfaces)) |
110a8e1175bSopenharmony_ci| `base64.h` | `mbedtls_base64_` | No change ([PK support interface](#pk-format-support-interfaces)) |
111a8e1175bSopenharmony_ci| `bignum.h` | `mbedtls_mpi_` | None (no low-level arithmetic) |
112a8e1175bSopenharmony_ci| `build_info.h` | `MBEDTLS_` | No change (not a crypto API) |
113a8e1175bSopenharmony_ci| `camellia.h` | `mbedtls_camellia_` | [Symmetric encryption](#symmetric-encryption) |
114a8e1175bSopenharmony_ci| `ccm.h` | `mbedtls_ccm_` | [Symmetric encryption](#symmetric-encryption), [Authenticated cipher operations](#authenticated-cipher-operations) |
115a8e1175bSopenharmony_ci| `chacha20.h` | `mbedtls_chacha20_` | [Symmetric encryption](#symmetric-encryption) |
116a8e1175bSopenharmony_ci| `chachapoly.h` | `mbedtls_chachapoly_` | [Symmetric encryption](#symmetric-encryption), [Authenticated cipher operations](#authenticated-cipher-operations) |
117a8e1175bSopenharmony_ci| `check_config.h` | N/A | No public APIs (internal support header) |
118a8e1175bSopenharmony_ci| `cipher.h` | `mbedtls_cipher_` | [Symmetric encryption](#symmetric-encryption) |
119a8e1175bSopenharmony_ci| `cmac.h` | `mbedtls_cipher_cmac_` | [Hashes and MAC](#hashes-and-mac), [MAC calculation](#mac-calculation) |
120a8e1175bSopenharmony_ci| `compat-2.x.h` | various | None (transitional APIs) |
121a8e1175bSopenharmony_ci| `config_psa.h` | N/A | No public APIs (internal support header) |
122a8e1175bSopenharmony_ci| `constant_time.h` | `mbedtls_ct_` | [Constant-time functions](#constant-time-functions) |
123a8e1175bSopenharmony_ci| `ctr_drbg.h` | `mbedtls_ctr_drbg_` | [Random generation interface](#random-generation-interface), [Deterministic pseudorandom generation](#deterministic-pseudorandom-generation) |
124a8e1175bSopenharmony_ci| `debug.h` | `mbedtls_debug_` | No change (not a crypto API) |
125a8e1175bSopenharmony_ci| `des.h` | `mbedtls_des_` | [Symmetric encryption](#symmetric-encryption) |
126a8e1175bSopenharmony_ci| `dhm.h` | `mbedtls_dhm_` | [Asymmetric cryptography](#asymmetric-cryptography) |
127a8e1175bSopenharmony_ci| `ecdh.h` | `mbedtls_ecdh_` | [Asymmetric cryptography](#asymmetric-cryptography) |
128a8e1175bSopenharmony_ci| `ecdsa.h` | `mbedtls_ecdsa_` | [Asymmetric cryptography](#asymmetric-cryptography) |
129a8e1175bSopenharmony_ci| `ecjpake.h` | `mbedtls_ecjpake_` | [EC-JPAKE](#ec-jpake) |
130a8e1175bSopenharmony_ci| `ecp.h` | `mbedtls_ecp_` | [Asymmetric cryptography](#asymmetric-cryptography) |
131a8e1175bSopenharmony_ci| `entropy.h` | `mbedtls_entropy_` | [Random generation interface](#random-generation-interface), [Entropy sources](#entropy-sources) |
132a8e1175bSopenharmony_ci| `error.h` | `mbedtls_*err*` | [Error messages](#error-messages) |
133a8e1175bSopenharmony_ci| `gcm.h` | `mbedtls_gcm_` | [Symmetric encryption](#symmetric-encryption), [Authenticated cipher operations](#authenticated-cipher-operations) |
134a8e1175bSopenharmony_ci| `hkdf.h` | `mbedtls_hkdf_` | [HKDF](#hkdf) |
135a8e1175bSopenharmony_ci| `hmac_drbg.h` | `mbedtls_hmac_drbg_` | [Random generation interface](#random-generation-interface), [Deterministic pseudorandom generation](#deterministic-pseudorandom-generation) |
136a8e1175bSopenharmony_ci| `lms.h` | `mbedtls_lms_` | No change ([LMS signatures](#lms-signatures)) |
137a8e1175bSopenharmony_ci| `mbedtls_config.h` | `MBEDTLS_` | [Compile-time configuration](#compile-time-configuration) |
138a8e1175bSopenharmony_ci| `md.h` | `mbedtls_md_` | [Hashes and MAC](#hashes-and-mac) |
139a8e1175bSopenharmony_ci| `md5.h` | `mbedtls_md5_` | [Hashes and MAC](#hashes-and-mac) |
140a8e1175bSopenharmony_ci| `memory_buffer_alloc.h` | `mbedtls_memory_buffer_alloc_` | No change (not a crypto API) |
141a8e1175bSopenharmony_ci| `net_sockets.h` | `mbedtls_net_` | No change (not a crypto API) |
142a8e1175bSopenharmony_ci| `nist_kw.h` | `mbedtls_nist_kw_` | Migration path not yet defined |
143a8e1175bSopenharmony_ci| `oid.h` | `mbedtls_oid_` | No change ([PK support interface](#pk-format-support-interfaces)) |
144a8e1175bSopenharmony_ci| `pem.h` | `mbedtls_pem_` | No change ([PK support interface](#pk-format-support-interfaces)) |
145a8e1175bSopenharmony_ci| `pk.h` | `mbedtls_pk_` | [Asymmetric cryptography](#asymmetric-cryptography) |
146a8e1175bSopenharmony_ci| `pkcs5.h` | `mbedtls_pkcs5_` | [PKCS#5 module](#pkcs5-module) |
147a8e1175bSopenharmony_ci| `pkcs7.h` | `mbedtls_pkcs7_` | No change (not a crypto API) |
148a8e1175bSopenharmony_ci| `pkcs12.h` | `mbedtls_pkcs12_` | [PKCS#12 module](#pkcs12-module) |
149a8e1175bSopenharmony_ci| `platform.h` | `mbedtls_platform_` | No change (not a crypto API) |
150a8e1175bSopenharmony_ci| `platform_time.h` | `mbedtls_*time*` | No change (not a crypto API) |
151a8e1175bSopenharmony_ci| `platform_util.h` | `mbedtls_platform_` | No change (not a crypto API) |
152a8e1175bSopenharmony_ci| `poly1305.h` | `mbedtls_poly1305_` | None (but there is Chacha20-Poly1305 [AEAD](#symmetric-encryption)) |
153a8e1175bSopenharmony_ci| `private_access.h` | N/A | No public APIs (internal support header) |
154a8e1175bSopenharmony_ci| `psa_util.h` | N/A | No public APIs (internal support header) |
155a8e1175bSopenharmony_ci| `ripemd160.h` | `mbedtls_ripemd160_` | [Hashes and MAC](#hashes-and-mac) |
156a8e1175bSopenharmony_ci| `rsa.h` | `mbedtls_rsa_` | [Asymmetric cryptography](#asymmetric-cryptography) |
157a8e1175bSopenharmony_ci| `sha1.h` | `mbedtls_sha1_` | [Hashes and MAC](#hashes-and-mac) |
158a8e1175bSopenharmony_ci| `sha3.h` | `mbedtls_sha3_` | [Hashes and MAC](#hashes-and-mac) |
159a8e1175bSopenharmony_ci| `sha256.h` | `mbedtls_sha256_` | [Hashes and MAC](#hashes-and-mac) |
160a8e1175bSopenharmony_ci| `sha512.h` | `mbedtls_sha512_` | [Hashes and MAC](#hashes-and-mac) |
161a8e1175bSopenharmony_ci| `ssl.h` | `mbedtls_ssl_` | No change (not a crypto API) |
162a8e1175bSopenharmony_ci| `ssl_cache.h` | `mbedtls_ssl_cache_` | No change (not a crypto API) |
163a8e1175bSopenharmony_ci| `ssl_ciphersuites.h` | `mbedtls_ssl_ciphersuite_` | No change (not a crypto API) |
164a8e1175bSopenharmony_ci| `ssl_cookie.h` | `mbedtls_ssl_cookie_` | No change (not a crypto API) |
165a8e1175bSopenharmony_ci| `ssl_ticket.h` | `mbedtls_ssl_ticket_` | No change (not a crypto API) |
166a8e1175bSopenharmony_ci| `threading.h` | `mbedtls_threading_` | No change (not a crypto API) |
167a8e1175bSopenharmony_ci| `timing.h` | `mbedtls_timing_` | No change (not a crypto API) |
168a8e1175bSopenharmony_ci| `version.h` | `mbedtls_version_` | No change (not a crypto API) |
169a8e1175bSopenharmony_ci| `x509.h` | `mbedtls_x509` | No change (not a crypto API) |
170a8e1175bSopenharmony_ci| `x509_crl.h` | `mbedtls_x509` | No change (not a crypto API) |
171a8e1175bSopenharmony_ci| `x509_crt.h` | `mbedtls_x509` | No change (not a crypto API) |
172a8e1175bSopenharmony_ci| `x509_csr.h` | `mbedtls_x509` | No change (not a crypto API) |
173a8e1175bSopenharmony_ci
174a8e1175bSopenharmony_ci## Compile-time configuration
175a8e1175bSopenharmony_ci
176a8e1175bSopenharmony_ci### Cryptographic mechanism availability
177a8e1175bSopenharmony_ci
178a8e1175bSopenharmony_ci**This section only applies if `MBEDTLS_PSA_CRYPTO_CONFIG` is enabled.** This option is disabled in the default configuration.
179a8e1175bSopenharmony_ci
180a8e1175bSopenharmony_ciWhen the configuration option [`MBEDTLS_PSA_CRYPTO_CONFIG`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/mbedtls__config_8h/#mbedtls__config_8h_1a5aca5ddcffb586acad82f9aef26db056) is enabled, the cryptographic mechanisms available through the PSA API are determined by the contents of the header file `"psa/crypto_config.h"`. You can override the file location with the macro [`MBEDTLS_PSA_CRYPTO_CONFIG_FILE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/mbedtls__config_8h/#mbedtls__config_8h_1a25f7e358caa101570cb9519705c2b873), and you can set [`MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/mbedtls__config_8h/#mbedtls__config_8h_1abd1870cc0d2681183a3018a7247cb137) to the path of an additional file (similar to `MBEDTLS_CONFIG_FILE` and `MBEDTLS_USER_CONFIG_FILE` for legacy configuration symbols).
181a8e1175bSopenharmony_ci
182a8e1175bSopenharmony_ciThe availability of cryptographic mechanisms in the PSA API is based on a systematic pattern:
183a8e1175bSopenharmony_ci
184a8e1175bSopenharmony_ci* To make `PSA_ALG_aaa` available, enable `PSA_WANT_ALG_aaa`.
185a8e1175bSopenharmony_ci  For parametrized algorithms, there is a `PSA_WANT_` symbol both for the main macro and for each argument. For example, to make `PSA_ALG_HMAC(PSA_ALG_SHA_256)` available, enable both `PSA_WANT_ALG_HMAC` and `PSA_WANT_ALG_SHA_256`.
186a8e1175bSopenharmony_ci
187a8e1175bSopenharmony_ci* To make `PSA_KEY_TYPE_ttt` available, enable `PSA_WANT_KEY_TYPE_ttt`.
188a8e1175bSopenharmony_ci
189a8e1175bSopenharmony_ci    As an exception, starting in Mbed TLS 3.5.0, for key pair types, the feature selection is more fine-grained, with an additional suffix:
190a8e1175bSopenharmony_ci    * `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_BASIC` enables basic support for the key type, and in particular support for operations with a key of that type for enabled algorithms. This is automatically enabled if any of the other `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_yyy` options are enabled.
191a8e1175bSopenharmony_ci    * `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_IMPORT` enables support for `psa_import_key` to import a key of that type.
192a8e1175bSopenharmony_ci    * `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_GENERATE` enables support for `psa_generate_key` to randomly generate a key of that type.
193a8e1175bSopenharmony_ci    * `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_DERIVE` enables support for `psa_key_derivation_output_key` to deterministically derive a key of that type.
194a8e1175bSopenharmony_ci    * `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_EXPORT` enables support for `psa_export_key` to export a key of that type.
195a8e1175bSopenharmony_ci
196a8e1175bSopenharmony_ci    Enabling any support for a key pair type automatically enables support for the corresponding public key type, as well as support for `psa_export_public_key` on the private key.
197a8e1175bSopenharmony_ci
198a8e1175bSopenharmony_ci* To make `PSA_ECC_FAMILY_fff` available for size sss, enable `PSA_WANT_ECC_fff_sss`.
199a8e1175bSopenharmony_ci
200a8e1175bSopenharmony_ciNote that all `PSA_WANT_xxx` symbols must be set to a non-zero value. In particular, setting `PSA_WANT_xxx` to an empty value may not be handled consistently.
201a8e1175bSopenharmony_ci
202a8e1175bSopenharmony_ciFor example, the following configuration enables hashing with SHA-256, AEAD with AES-GCM, signature with deterministic ECDSA using SHA-256 on the curve secp256r1 using a randomly generated key as well as the corresponding verification, and ECDH key exchange on secp256r1 and Curve25519.
203a8e1175bSopenharmony_ci
204a8e1175bSopenharmony_ci```
205a8e1175bSopenharmony_ci#define PSA_WANT_ALG_SHA_256 1
206a8e1175bSopenharmony_ci
207a8e1175bSopenharmony_ci#define PSA_WANT_KEY_TYPE_AES 1
208a8e1175bSopenharmony_ci#define PSA_WANT_ALG_GCM 1
209a8e1175bSopenharmony_ci
210a8e1175bSopenharmony_ci#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE 1
211a8e1175bSopenharmony_ci// ^^ In Mbed TLS <= 3.4, enable PSA_WANT_KEY_TYPE_ECC_KEY_PAIR instead
212a8e1175bSopenharmony_ci// ^^ implicitly enables PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC, PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY
213a8e1175bSopenharmony_ci#define PSA_WANT_ECC_SECP_R1_256 1 // secp256r1 (suitable for ECDSA and ECDH)
214a8e1175bSopenharmony_ci#define PSA_WANT_ECC_MONTGOMERY_255 1 // Curve25519 (suitable for ECDH)
215a8e1175bSopenharmony_ci#define PSA_WANT_ALG_DETERMINISTIC_ECDSA 1
216a8e1175bSopenharmony_ci#define PSA_WANT_ALG_ECDH
217a8e1175bSopenharmony_ci```
218a8e1175bSopenharmony_ci
219a8e1175bSopenharmony_ciIf a mechanism is not enabled by `PSA_WANT_xxx`, Mbed TLS will normally not include it. This allows builds that use few features to have a small code size. However, this is not guaranteed: a mechanism that is not explicitly requested can be enabled because it is a dependency of another configuration option, because it is used internally, or because the granularity is not fine enough to distinguish between it and another mechanism that is requested.
220a8e1175bSopenharmony_ci
221a8e1175bSopenharmony_ciUnder the hood, `PSA_WANT_xxx` enables the necessary legacy modules. Note that if a mechanism has a PSA accelerator driver, the corresponding legacy module is typically not needed. Thus applications that use a cryptographic mechanism both through the legacy API and through the PSA API need to explicitly enable both the `PSA_WANT_xxx` symbols and the `MBEDTLS_xxx` symbols.
222a8e1175bSopenharmony_ci
223a8e1175bSopenharmony_ci### Optimization options
224a8e1175bSopenharmony_ci
225a8e1175bSopenharmony_ciWhen PSA Crypto mechanisms are implemented by the built-in code from Mbed TLS, the legacy optimization options (e.g. `MBEDTLS_SHA256_SMALLER`, `MBEDTLS_ECP_WINDOW_SIZE`, etc.) apply to the PSA implementation as well (they invoke the same code under the hood).
226a8e1175bSopenharmony_ci
227a8e1175bSopenharmony_ciThe PSA Crypto API may use accelerator drivers. In this case any options controlling the driver behavior are driver-specific.
228a8e1175bSopenharmony_ci
229a8e1175bSopenharmony_ci### Alternative implementations (`MBEDTLS_xxx_ALT` options)
230a8e1175bSopenharmony_ci
231a8e1175bSopenharmony_ciIn the Mbed TLS legacy interface, you can replace some cryptographic primitives and modes by an alternative implementation, by enabling configuration options of the form `MBEDTLS_xxx_ALT` and linking with your own implementation of the affected function or module. Alternative implementations remain supported in Mbed TLS 3.x even if the application code uses the PSA API. However, they will be removed from the next version of the library.
232a8e1175bSopenharmony_ci
233a8e1175bSopenharmony_ciThe corresponding PSA feature is accelerator drivers. To implement an accelerator driver, see the [PSA cryptoprocessor driver example and guide](https://github.com/Mbed-TLS/mbedtls/blob/development/docs/psa-driver-example-and-guide.md). In an application that uses both the legacy interface and the PSA interface for the same mechanism, only some algorithms support calling a PSA driver from the legacy interface. See the [Guide to driver-only builds](https://github.com/Mbed-TLS/mbedtls/blob/development/docs/driver-only-builds.md) for more information.
234a8e1175bSopenharmony_ci
235a8e1175bSopenharmony_ci### Self-tests
236a8e1175bSopenharmony_ci
237a8e1175bSopenharmony_ciThere is currently [no PSA equivalent to the self-tests](https://github.com/Mbed-TLS/mbedtls/issues/7781) enabled by `MBEDTLS_SELF_TEST`.
238a8e1175bSopenharmony_ci
239a8e1175bSopenharmony_ci## Miscellaneous support modules
240a8e1175bSopenharmony_ci
241a8e1175bSopenharmony_ci### Error messages
242a8e1175bSopenharmony_ci
243a8e1175bSopenharmony_ciAt the time of writing, there is no equivalent to the error messages provided by `mbedtls_strerror`. However, you can use the companion program `programs/psa/psa_constant_names` to convert various numbers (`psa_status_t`, `psa_algorithm_t`, `psa_key_type_t`, `psa_ecc_family_t`, `psa_dh_family_t`, `psa_key_usage_t`) to a programmer-friendly representation. The conversion doesn't depend on the library configuration or the target platform, so you can use a native build of this program even if you cross-compile your application.
244a8e1175bSopenharmony_ci
245a8e1175bSopenharmony_ci```
246a8e1175bSopenharmony_ci$ programs/psa/psa_constant_names error -138
247a8e1175bSopenharmony_ciPSA_ERROR_BUFFER_TOO_SMALL
248a8e1175bSopenharmony_ci$ programs/psa/psa_constant_names type 0x7112
249a8e1175bSopenharmony_ciPSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)
250a8e1175bSopenharmony_ci$ programs/psa/psa_constant_names alg 0x06000609
251a8e1175bSopenharmony_ciPSA_ALG_ECDSA(PSA_ALG_SHA_256)
252a8e1175bSopenharmony_ci```
253a8e1175bSopenharmony_ci
254a8e1175bSopenharmony_ciThe other functions in `error.h` are specific to the construction of Mbed TLS error code and are not relevant to the PSA API. PSA error codes are never the combination of multiple codes.
255a8e1175bSopenharmony_ci
256a8e1175bSopenharmony_ci### Constant-time functions
257a8e1175bSopenharmony_ci
258a8e1175bSopenharmony_ciThe PSA API does not have an equivalent to the timing-side-channel-resistance utility functions in `constant_time.h`. Continue using `constant_time.h` as needed.
259a8e1175bSopenharmony_ci
260a8e1175bSopenharmony_ciNote that the PSA API does include features that reduce the need for `mbedtls_ct_memcmp`:
261a8e1175bSopenharmony_ci
262a8e1175bSopenharmony_ci* To compare a MAC with a reference value, use `psa_mac_verify` rather than `psa_mac_compute` followed by `mbedtls_ct_memcmp`, or use `psa_mac_verify_setup` and `psa_mac_verify_finish` in the multi-part case. See “[MAC calculation](#mac-calculation)”.
263a8e1175bSopenharmony_ci* The AEAD decryption functions take care of verifying the tag. See “[Authenticated cipher operations](#authenticated-cipher-operations)”.
264a8e1175bSopenharmony_ci
265a8e1175bSopenharmony_ci## Symmetric encryption
266a8e1175bSopenharmony_ci
267a8e1175bSopenharmony_ciAll PSA APIs have algorithm agility, where the functions depend only on the nature of the operation and the choice of a specific algorithm comes from an argument. There is no special API for a particular block cipher (`aes.h`, `aria.h`, `camellia.h`, `des.h`), a particular block cipher mode (`ccm.h`, `gcm.h`) or a particular stream cipher (`chacha20.h`, `chachapoly.h`). To migrate code using those low-level modules, please follow the recommendations in the following sections, using the same principles as the corresponding `cipher.h` API.
268a8e1175bSopenharmony_ci
269a8e1175bSopenharmony_ci### Cipher mechanism selection
270a8e1175bSopenharmony_ci
271a8e1175bSopenharmony_ciInstead of `mbedtls_cipher_id_t` (`MBEDTLS_CIPHER_ID_xxx` constants), `mbedtls_cipher_type_t` (`MBEDTLS_CIPHER_base_size_mode` constants), `mbedtls_cipher_mode_t` (`MBEDTLS_CIPHER_MODE_xxx` constants) and `mbedtls_cipher_padding_t` (`MBEDTLS_CIPHER_PADDING_xxx` constants), use the [`PSA_KEY_TYPE_xxx` and `PSA_ALG_xxx` constants](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/).
272a8e1175bSopenharmony_ci
273a8e1175bSopenharmony_ciFor modes that are based on a block cipher, the key type encodes the choice of block cipher:
274a8e1175bSopenharmony_ci[`PSA_KEY_TYPE_AES`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga6ee54579dcf278c677eda4bb1a29575e),
275a8e1175bSopenharmony_ci[`PSA_KEY_TYPE_ARIA`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#c.PSA_KEY_TYPE_ARIA),
276a8e1175bSopenharmony_ci[`PSA_KEY_TYPE_CAMELLIA`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gad8e5da742343fd5519f9d8a630c2ed81),
277a8e1175bSopenharmony_ci[`PSA_KEY_TYPE_DES`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga577562bfbbc691c820d55ec308333138).
278a8e1175bSopenharmony_ciThe algorithm encodes the mode and if relevant the padding type:
279a8e1175bSopenharmony_ci
280a8e1175bSopenharmony_ci* Unauthenticated cipher modes:
281a8e1175bSopenharmony_ci  [`PSA_ALG_CTR`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gad318309706a769cffdc64e4c7e06b2e9),
282a8e1175bSopenharmony_ci  [`PSA_ALG_CFB`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga0088c933e01d671f263a9a1f177cb5bc),
283a8e1175bSopenharmony_ci  [`PSA_ALG_OFB`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gae96bb421fa634c6fa8f571f0112f1ddb),
284a8e1175bSopenharmony_ci  [`PSA_ALG_XTS`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gaa722c0e426a797fd6d99623f59748125),
285a8e1175bSopenharmony_ci  [`PSA_ALG_ECB_NO_PADDING`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gab8f0609cd0f12cccc9c950fd5a81a0e3),
286a8e1175bSopenharmony_ci  [`PSA_ALG_CBC_NO_PADDING`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gacb332d72716958880ee7f97d8365ae66),
287a8e1175bSopenharmony_ci  [`PSA_ALG_CBC_PKCS7`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gaef50d2e9716eb6d476046608e4e0c78c),
288a8e1175bSopenharmony_ci  [`PSA_ALG_CCM_STAR_NO_TAG`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga89627bb27ec3ce642853ab8554a88572).
289a8e1175bSopenharmony_ci* Other padding modes, which are obsolete, are not available in the PSA API. If you need them, handle the padding in your application code and use the `NO_PADDING` algorithm.
290a8e1175bSopenharmony_ci* AEAD modes:
291a8e1175bSopenharmony_ci  [`PSA_ALG_CCM`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gac2c0e7d21f1b2df5e76bcb4a8f84273c),
292a8e1175bSopenharmony_ci  [`PSA_ALG_GCM`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga0d7d02b15aaae490d38277d99f1c637c).
293a8e1175bSopenharmony_ci* KW/KWP modes are not available in the PSA API at the time of writing.
294a8e1175bSopenharmony_ci
295a8e1175bSopenharmony_ciFor the ChaCha20 unauthenticated cipher, use [`PSA_KEY_TYPE_CHACHA20`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga901548883b3bce56cc21c3a22cf8d93c) with [`PSA_ALG_STREAM_CIPHER`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gad98c105198f7428f7d1dffcb2cd398cd).
296a8e1175bSopenharmony_ciFor the Chacha20+Poly1305 AEAD, use [`PSA_KEY_TYPE_CHACHA20`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga901548883b3bce56cc21c3a22cf8d93c) with [`PSA_ALG_CHACHA20_POLY1305`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga1fec55093541640a71bdd022d4adfb9c)
297a8e1175bSopenharmony_ci
298a8e1175bSopenharmony_ci### Cipher mechanism availability
299a8e1175bSopenharmony_ci
300a8e1175bSopenharmony_ciFor each key type value `PSA_KEY_TYPE_xxx`, the symbol `PSA_WANT_KEY_TYPE_xxx` is defined with a non-zero value if the library is built with support for that key type. For each algorithm value `PSA_ALG_yyy`, the symbol `PSA_WANT_ALG_yyy` is defined with a non-zero value if the library is built with support for that algorithm. Note that for a mechanism to be supported, both the key type and the algorithm must be supported.
301a8e1175bSopenharmony_ci
302a8e1175bSopenharmony_ciFor example, to test if AES-CBC-PKCS7 is supported, in the legacy API, you could write:
303a8e1175bSopenharmony_ci```
304a8e1175bSopenharmony_ci#if defined(MBEDTLS_AES_C) && \
305a8e1175bSopenharmony_ci    defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_CIPHER_PADDING_PKCS7)
306a8e1175bSopenharmony_ci```
307a8e1175bSopenharmony_ciThe equivalent in the PSA API is
308a8e1175bSopenharmony_ci```
309a8e1175bSopenharmony_ci#if PSA_WANT_KEY_TYPE_AES && PSA_WANT_ALG_CBC_PKCS7
310a8e1175bSopenharmony_ci```
311a8e1175bSopenharmony_ci
312a8e1175bSopenharmony_ci### Cipher metadata
313a8e1175bSopenharmony_ci
314a8e1175bSopenharmony_ciBoth APIs express key sizes in bits. Note however that in the PSA API, the size of a _buffer_ is always expressed in bytes, even if that buffer contains a key.
315a8e1175bSopenharmony_ci
316a8e1175bSopenharmony_ciThe following table lists corresponding PSA macros for maximum-size macros that take all supported algorithms into account.
317a8e1175bSopenharmony_ci
318a8e1175bSopenharmony_ci| Legacy macro | PSA macro |
319a8e1175bSopenharmony_ci| ------------ | --------- |
320a8e1175bSopenharmony_ci| `MBEDTLS_MAX_IV_LENGTH` | [`PSA_CIPHER_IV_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_IV_MAX_SIZE), [`PSA_AEAD_NONCE_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#crypto__sizes_8h_1ac2a332765ba4ccfc24935d6f7f48fcc7) |
321a8e1175bSopenharmony_ci| `MBEDTLS_MAX_BLOCK_LENGTH` | [`PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE) |
322a8e1175bSopenharmony_ci| `MBEDTLS_MAX_KEY_LENGTH` | no equivalent|
323a8e1175bSopenharmony_ci
324a8e1175bSopenharmony_ciThere is no equivalent to the type `mbedtls_cipher_info_t` and the functions `mbedtls_cipher_info_from_type` and `mbedtls_cipher_info_from_values` in the PSA API because it is unnecessary. All macros and functions operate directly on key type values (`psa_key_type_t`, `PSA_KEY_TYPE_xxx` constants) and algorithm values (`psa_algorithm_t`, `PSA_ALG_xxx` constants).
325a8e1175bSopenharmony_ci
326a8e1175bSopenharmony_ci| Legacy function | PSA macro |
327a8e1175bSopenharmony_ci| --------------- | --------- |
328a8e1175bSopenharmony_ci| `mbedtls_cipher_info_get_iv_size` | [`PSA_CIPHER_IV_LENGTH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_IV_LENGTH), [`PSA_AEAD_NONCE_LENGTH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_NONCE_LENGTH) |
329a8e1175bSopenharmony_ci| `mbedtls_cipher_info_get_block_size` | not available (use specific macros for the IV, nonce or tag length) |
330a8e1175bSopenharmony_ci
331a8e1175bSopenharmony_ciThe following features have no PSA equivalent:
332a8e1175bSopenharmony_ci
333a8e1175bSopenharmony_ci* `mbedtls_cipher_list`: the PSA API does not currently have a discovery mechanism for cryptographic mechanisms, but one may be added in the future.
334a8e1175bSopenharmony_ci* `mbedtls_cipher_info_has_variable_key_bitlen`, `mbedtls_cipher_info_has_variable_iv_size`: the PSA API does not currently have such mechanism for high-level metadata information.
335a8e1175bSopenharmony_ci* `mbedtls_cipher_info_from_string`: there is no equivalent of Mbed TLS's lookup based on a (nonstandard) name.
336a8e1175bSopenharmony_ci
337a8e1175bSopenharmony_ci### Cipher key management
338a8e1175bSopenharmony_ci
339a8e1175bSopenharmony_ciThe legacy API and the PSA API have a different organization of operations in several respects:
340a8e1175bSopenharmony_ci
341a8e1175bSopenharmony_ci* In the legacy API, each operation object contains the necessary key material. In the PSA API, an operation object contains a reference to a key object. To perform a cryptographic operation, you must create a key object first. However, for a one-shot operation, you do not need an operation object, just a single function call.
342a8e1175bSopenharmony_ci* The legacy API uses the same interface for authenticated and non-authenticated ciphers, while the PSA API has separate functions.
343a8e1175bSopenharmony_ci* The legacy API uses the same functions for encryption and decryption, while the PSA API has separate functions where applicable.
344a8e1175bSopenharmony_ci
345a8e1175bSopenharmony_ciHere is an overview of the lifecycle of a key object.
346a8e1175bSopenharmony_ci
347a8e1175bSopenharmony_ci1. First define the attributes of the key by filling a [`psa_key_attributes_t` structure](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga0ec645e1fdafe59d591104451ebf5680). You need to set the following parameters:
348a8e1175bSopenharmony_ci    * Call [`psa_set_key_type`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga6857ef0ecb3fa844d4536939d9c64025) to set the key type to the desired `PSA_KEY_TYPE_xxx` value (see “[Cipher mechanism selection](#cipher-mechanism-selection)”).
349a8e1175bSopenharmony_ci    * Call [`psa_set_key_bits`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaf61683ac87f87687a40262b5afbfa018) to set the key's size in bits. This is optional with `psa_import_key`, which determines the key size from the length of the key material.
350a8e1175bSopenharmony_ci    * Call [`psa_set_key_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaeb8341ca52baa0279475ea3fd3bcdc98) to set the algorithm to the desired `PSA_ALG_xxx` value (see “[Cipher mechanism selection](#cipher-mechanism-selection)”). By design, the same key cannot be used with multiple algorithms.
351a8e1175bSopenharmony_ci    * Call [`psa_set_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga42a65b3c4522ce9b67ea5ea7720e17de) to enable at least [`PSA_KEY_USAGE_ENCRYPT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#c.PSA_KEY_USAGE_ENCRYPT) or [`PSA_KEY_USAGE_DECRYPT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#c.PSA_KEY_USAGE_DECRYPT), depending on which direction you want to use the key in. To allow both directions, use the flag mask `PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_ENCRYPT`. The same policy flags cover authenticated and non-authenticated encryption/decryption.
352a8e1175bSopenharmony_ci2. Call one of the key creation functions, passing the attributes defined in the previous step, to get an identifier of type [`psa_key_id_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__types_8h/#_CPPv412psa_key_id_t) to the key object.
353a8e1175bSopenharmony_ci    * Use [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b) to directly import key material.
354a8e1175bSopenharmony_ci    * If the key is randomly generated, use [`psa_generate_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga1985eae417dfbccedf50d5fff54ea8c5).
355a8e1175bSopenharmony_ci    * If the key is derived from other material (for example from a key exchange), use the [key derivation interface](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/) and create the key with [`psa_key_derivation_output_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gada7a6e17222ea9e7a6be6864a00316e1).
356a8e1175bSopenharmony_ci3. Call the functions in the following sections to perform operations on the key. The same key object can be used in multiple operations.
357a8e1175bSopenharmony_ci4. To free the resources used by the key object, call [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2) after all operations with that key are finished.
358a8e1175bSopenharmony_ci
359a8e1175bSopenharmony_ci### Unauthenticated cipher operations
360a8e1175bSopenharmony_ci
361a8e1175bSopenharmony_ciRecall the workflow of an unauthenticated cipher operation in the legacy Mbed TLS cipher API:
362a8e1175bSopenharmony_ci
363a8e1175bSopenharmony_ci1. Create a cipher context of type `mbedtls_cipher_context_t` and initialize it with `mbedtls_cipher_init`.
364a8e1175bSopenharmony_ci2. Establish the operation parameters (algorithm, key, mode) with `mbedtls_cipher_setup`, `mbedtls_cipher_setkey` (or `mbedtls_cipher_setup_psa`), `mbedtls_cipher_set_padding_mode` if applicable.
365a8e1175bSopenharmony_ci3. Set the IV with `mbedtls_cipher_set_iv` (except for ECB which does not use an IV).
366a8e1175bSopenharmony_ci4. For a one-shot operation, call `mbedtls_cipher_crypt`. To pass the input in multiple parts, call `mbedtls_cipher_update` as many times as necessary followed by `mbedtls_cipher_finish`.
367a8e1175bSopenharmony_ci5. Finally free the resources associated with the operation object by calling `mbedtls_cipher_free`.
368a8e1175bSopenharmony_ci
369a8e1175bSopenharmony_ciFor a one-shot operation (where the whole plaintext or ciphertext is passed as a single input), the equivalent workflow with the PSA API is to call a single function:
370a8e1175bSopenharmony_ci
371a8e1175bSopenharmony_ci* [`psa_cipher_encrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1ga61f02fbfa681c2659546eca52277dbf1) to perform encryption with a random IV of the default size (indicated by [`PSA_CIPHER_IV_LENGTH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_IV_LENGTH)). (To encrypt with a specified IV, use the multi-part API described below.) You can use the macro [`PSA_CIPHER_ENCRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_ENCRYPT_OUTPUT_SIZE) or [`PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE) to determine a sufficient size for the output buffer.
372a8e1175bSopenharmony_ci* [`psa_cipher_decrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1gab3593f5f14d8c0431dd306d80929215e) to perform decryption with a specified IV. You can use the macro [`PSA_CIPHER_DECRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_DECRYPT_OUTPUT_SIZE) or [`PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE) to determine a sufficient size for the output buffer.
373a8e1175bSopenharmony_ci
374a8e1175bSopenharmony_ciFor a multi-part operation, the equivalent workflow with the PSA API is as follows:
375a8e1175bSopenharmony_ci
376a8e1175bSopenharmony_ci1. Create an operation object of type [`psa_cipher_operation_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1ga1399de29db657e3737bb09927aae51fa) and zero-initialize it (or use the corresponding `INIT` macro).
377a8e1175bSopenharmony_ci2. Select the key and algorithm with [`psa_cipher_encrypt_setup`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1ga587374c0eb8137a572f8e2fc409bb2b4) or [`psa_cipher_decrypt_setup`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1gaa4ba3a167066eaef2ea49abc5dcd1d4b) depending on the desired direction.
378a8e1175bSopenharmony_ci3. When encrypting with a random IV, use [`psa_cipher_generate_iv`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1ga29fd7d32a5729226a2f73e7b6487bd8a). When encrypting with a chosen IV, or when decrypting, set the IV with [`psa_cipher_set_iv`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1ga9caddac1a429a5032d6d4a907fb70ba1). Skip this step with ECB since it does not use an IV.
379a8e1175bSopenharmony_ci4. Call [`psa_cipher_update`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1gac3ca27ac6682917c48247d01fd96cd0f) as many times as needed. You can use [`PSA_CIPHER_UPDATE_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_UPDATE_OUTPUT_SIZE) or [`PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#crypto__sizes_8h_1ab1f6598efd6a7dc56e7ad7e34719eb32) to determine a sufficient size for the output buffer.
380a8e1175bSopenharmony_ci5. Call [`psa_cipher_finish`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1ga1dcb58b8befe23f8a4d7a1d49c99249b) to obtain the last part of the output. You can use [`PSA_CIPHER_FINISH_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_FINISH_OUTPUT_SIZE) or [`PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE) to determine a sufficient size for the output buffer.
381a8e1175bSopenharmony_ci
382a8e1175bSopenharmony_ciIf you need to interrupt the operation after calling the setup function without calling the finish function, call [`psa_cipher_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1gaad482cdca2098bca0620596aaa02eaa4).
383a8e1175bSopenharmony_ci
384a8e1175bSopenharmony_ci### Authenticated cipher operations
385a8e1175bSopenharmony_ci
386a8e1175bSopenharmony_ciRecall the workflow of an authenticated cipher operation in the legacy Mbed TLS cipher API (or similar workflows in the `chachapoly`, `ccm` and `gcm` modules):
387a8e1175bSopenharmony_ci
388a8e1175bSopenharmony_ci1. Create a cipher context of type `mbedtls_cipher_context_t` and initialize it with `mbedtls_cipher_init`.
389a8e1175bSopenharmony_ci2. Establish the operation parameters (algorithm, key, mode) with `mbedtls_cipher_setup`, `mbedtls_cipher_setkey` (or `mbedtls_cipher_setup_psa`), `mbedtls_cipher_set_padding_mode` if applicable.
390a8e1175bSopenharmony_ci3. Set the nonce with `mbedtls_cipher_set_iv` (or the `starts` function for low-level modules). For CCM, which requires direct use of the `ccm` module, also call `mbedtls_ccm_set_lengths` to set the length of the additional data and of the plaintext.
391a8e1175bSopenharmony_ci4. Call `mbedtls_cipher_update_ad` to pass the unencrypted additional data.
392a8e1175bSopenharmony_ci5. Call `mbedtls_cipher_update` as many times as necessary to pass the input plaintext or ciphertext.
393a8e1175bSopenharmony_ci6. Call `mbedtls_cipher_finish` to obtain the last part of the output. Then call `mbedtls_cipher_write_tag` (when encrypting) or `mbedtls_cipher_check_tag` (when decrypting) to process the authentication tag.
394a8e1175bSopenharmony_ci7. Finally free the resources associated with the operation object by calling `mbedtls_cipher_free`.
395a8e1175bSopenharmony_ci
396a8e1175bSopenharmony_ciSteps 3–6 can be replaced by a single call to `mbedtls_cipher_auth_encrypt_ext` or `mbedtls_cipher_auth_decrypt_ext` for a one-shot operation (where the whole plaintext or ciphertext is passed as a single input).
397a8e1175bSopenharmony_ci
398a8e1175bSopenharmony_ciFor a one-shot operation, the PSA API allows you to call a single function:
399a8e1175bSopenharmony_ci
400a8e1175bSopenharmony_ci* [`psa_aead_encrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gae72e1eb3c2da3ebd843bb9c8db8df509) to perform authenticated encryption with a random nonce of the default size (indicated by [`PSA_AEAD_NONCE_LENGTH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_NONCE_LENGTH)), with the authentication tag written at the end of the output. (To encrypt with a specified nonce, or to separate the tag from the rest of the ciphertext, use the multi-part API described below.)  You can use the macro [`PSA_AEAD_ENCRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_ENCRYPT_OUTPUT_SIZE) or [`PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE) to determine a sufficient size for the output buffer.
401a8e1175bSopenharmony_ci* [`psa_aead_decrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gae799f6196a22d50c216c947e0320d3ba) to perform authenticated decryption of a ciphertext with the authentication tag at the end. (If the tag is separate, use the multi-part API described below.) You can use the macro [`PSA_AEAD_DECRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_DECRYPT_OUTPUT_SIZE) or [`PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE) to determine a sufficient size for the output buffer.
402a8e1175bSopenharmony_ci
403a8e1175bSopenharmony_ciFor a multi-part operation, the equivalent workflow with the PSA API is as follows:
404a8e1175bSopenharmony_ci
405a8e1175bSopenharmony_ci1. Create an operation object of type [`psa_aead_operation_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1ga14f6a01afbaa8c5b3d8c5d345cbaa3ed) and zero-initialize it (or use the corresponding `INIT` macro).
406a8e1175bSopenharmony_ci2. Select the key and algorithm with [`psa_aead_encrypt_setup`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1ga2732c40ce8f3619d41359a329e9b46c4) or [`psa_aead_decrypt_setup`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gaaa5c5018e67a7a6514b7e76b9a14de26) depending on the desired direction.
407a8e1175bSopenharmony_ci3. When encrypting with a random nonce, use [`psa_aead_generate_nonce`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1ga5799df1c555efd35970b65be51cb07d1). When encrypting with a chosen nonce, or when decrypting, set the nonce with [`psa_aead_set_nonce`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1ga59132751a6f843d038924cb217b5e13b). If the algorithm is CCM, you must also call [`psa_aead_set_lengths`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gad3431e28d05002c2a7b0760610176050) before or after setting the nonce (for other algorithms, this is permitted but not needed).
408a8e1175bSopenharmony_ci4. Call [`psa_aead_update_ad`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1ga6d0eed03f832e5c9c91cb8adf2882569) as many times as needed.
409a8e1175bSopenharmony_ci5. Call [`psa_aead_update`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gaf6d49864951ca42136b4a9b71ea26e5c) as many times as needed. You can use [`PSA_AEAD_UPDATE_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_UPDATE_OUTPUT_SIZE) or [`PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE) to determine a sufficient size for the output buffer.
410a8e1175bSopenharmony_ci6. Finally:
411a8e1175bSopenharmony_ci    * When encrypting, call [`psa_aead_finish`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1ga759791bbe1763b377c3b5447641f1fc8) to obtain the last part of the ciphertext and the authentication tag. You can use [`PSA_AEAD_FINISH_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_FINISH_OUTPUT_SIZE) or [`PSA_AEAD_FINISH_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_FINISH_OUTPUT_MAX_SIZE) to determine a sufficient size for the output buffer.
412a8e1175bSopenharmony_ci    * When decrypting, call [`psa_aead_verify`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gae0280e2e61a185b893c36d858453f0d0) to obtain the last part of the plaintext and check the authentication tag. You can use [`PSA_AEAD_VERIFY_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_VERIFY_OUTPUT_SIZE) or [`PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE) to determine a sufficient size for the output buffer.
413a8e1175bSopenharmony_ci
414a8e1175bSopenharmony_ciIf you need to interrupt the operation after calling the setup function without calling the finish or verify function, call [`psa_aead_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gae8a5f93d92318c8f592ee9fbb9d36ba0).
415a8e1175bSopenharmony_ci
416a8e1175bSopenharmony_ci### Miscellaneous cipher operation management
417a8e1175bSopenharmony_ci
418a8e1175bSopenharmony_ciThe equivalent of `mbedtls_cipher_reset` is to call [`psa_cipher_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1gaad482cdca2098bca0620596aaa02eaa4) or [`psa_aead_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gae8a5f93d92318c8f592ee9fbb9d36ba0). Note that you must set the key again with a setup function: the PSA API does not have a special way to reuse an operation object with the same key.
419a8e1175bSopenharmony_ci
420a8e1175bSopenharmony_ciThere is no equivalent for the `mbedtls_cipher_get_xxx` functions to extract information from an ongoing PSA cipher or AEAD operation. Applications that need this information will need to save it from the key and operation parameters.
421a8e1175bSopenharmony_ci
422a8e1175bSopenharmony_ci## Hashes and MAC
423a8e1175bSopenharmony_ci
424a8e1175bSopenharmony_ciThe PSA API groups functions by purpose rather than by underlying primitive: there is a MAC API (equivalent to `md.h` for HMAC, and `cmac.h` for CMAC) and a hash API (equivalent to `md.h` for hashing). There is no special API for a particular hash algorithm (`md5.h`, `sha1.h`, `sha256.h`, `sha512.h`, `sha3.h`). To migrate code using those low-level modules, please follow the recommendations in the following section, using the same principles as the corresponding `md.h` API.
425a8e1175bSopenharmony_ci
426a8e1175bSopenharmony_ciThe PSA API does not have a direct interface for the AES-CMAC-PRF-128 algorithm from RFC 4615 calculated by `mbedtls_aes_cmac_prf_128` at the time of writing. You can implement it using the MAC interface with an AES key and the CMAC algorithm.
427a8e1175bSopenharmony_ci
428a8e1175bSopenharmony_ci### Hash mechanism selection
429a8e1175bSopenharmony_ci
430a8e1175bSopenharmony_ciThe equivalent to `mbedtls_md_type_t` and `MBEDTLS_MD_XXX` constants is the type `psa_algorithm_t` and `PSA_ALG_xxx` constants (the type encompasses all categories of cryptographic algorithms, not just hashes). PSA offers a similar selection of algorithms, but note that SHA-1 and SHA-2 are spelled slightly differently.
431a8e1175bSopenharmony_ci
432a8e1175bSopenharmony_ci| Mbed TLS constant      | PSA constant        |
433a8e1175bSopenharmony_ci| ---------------------- | ------------------- |
434a8e1175bSopenharmony_ci| `MBEDTLS_MD_MD5`       | `PSA_ALG_MD5`       |
435a8e1175bSopenharmony_ci| `MBEDTLS_MD_SHA1`      | `PSA_ALG_SHA_1`     |
436a8e1175bSopenharmony_ci| `MBEDTLS_MD_SHA224`    | `PSA_ALG_SHA_224`   |
437a8e1175bSopenharmony_ci| `MBEDTLS_MD_SHA256`    | `PSA_ALG_SHA_256`   |
438a8e1175bSopenharmony_ci| `MBEDTLS_MD_SHA384`    | `PSA_ALG_SHA_384`   |
439a8e1175bSopenharmony_ci| `MBEDTLS_MD_SHA512`    | `PSA_ALG_SHA_512`   |
440a8e1175bSopenharmony_ci| `MBEDTLS_MD_RIPEMD160` | `PSA_ALG_RIPEMD160` |
441a8e1175bSopenharmony_ci| `MBEDTLS_MD_SHA3_224`  | `PSA_ALG_SHA3_224`  |
442a8e1175bSopenharmony_ci| `MBEDTLS_MD_SHA3_256`  | `PSA_ALG_SHA3_256`  |
443a8e1175bSopenharmony_ci| `MBEDTLS_MD_SHA3_384`  | `PSA_ALG_SHA3_384`  |
444a8e1175bSopenharmony_ci| `MBEDTLS_MD_SHA3_512`  | `PSA_ALG_SHA3_512`  |
445a8e1175bSopenharmony_ci
446a8e1175bSopenharmony_ciThe following helper functions can be used to convert between the 2 types:
447a8e1175bSopenharmony_ci- `mbedtls_md_psa_alg_from_type()` converts from legacy `mbedtls_md_type_t` to PSA's `psa_algorithm_t`.
448a8e1175bSopenharmony_ci- `mbedtls_md_type_from_psa_alg()` converts from PSA's `psa_algorithm_t` to legacy `mbedtls_md_type_t`.
449a8e1175bSopenharmony_ci
450a8e1175bSopenharmony_ci### MAC mechanism selection
451a8e1175bSopenharmony_ci
452a8e1175bSopenharmony_ciPSA Crypto has a generic API with the same functions for all MAC mechanisms. The mechanism is determined by a combination of an algorithm value of type [`psa_algorithm_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gac2e4d47f1300d73c2f829a6d99252d69) and a key type value of type [`psa_key_type_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga63fce6880ca5933b5d6baa257febf1f6).
453a8e1175bSopenharmony_ci
454a8e1175bSopenharmony_ci* For HMAC, the algorithm is [`PSA_ALG_HMAC`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga70f397425684b3efcde1e0e34c28261f)`(hash)` where `hash` is the underlying hash algorithm (see “[Hash mechanism selection](#hash-mechanism-selection)”),
455a8e1175bSopenharmony_ci  for example `PSA_ALG_HMAC(PSA_ALG_SHA_256)` for HMAC-SHA-256.
456a8e1175bSopenharmony_ci  The key type is [`PSA_KEY_TYPE_HMAC`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__values_8h/#c.PSA_KEY_TYPE_HMAC) regardless of the hash algorithm.
457a8e1175bSopenharmony_ci* For CMAC, the algorithm is [`PSA_ALG_CMAC`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__values_8h/#c.PSA_ALG_CMAC) regardless of the underlying block cipher. The key type determines the block cipher:
458a8e1175bSopenharmony_ci  [`PSA_KEY_TYPE_AES`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga6ee54579dcf278c677eda4bb1a29575e),
459a8e1175bSopenharmony_ci  [`PSA_KEY_TYPE_ARIA`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#c.PSA_KEY_TYPE_ARIA),
460a8e1175bSopenharmony_ci  [`PSA_KEY_TYPE_CAMELLIA`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gad8e5da742343fd5519f9d8a630c2ed81) or
461a8e1175bSopenharmony_ci  [`PSA_KEY_TYPE_DES`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga577562bfbbc691c820d55ec308333138).
462a8e1175bSopenharmony_ci
463a8e1175bSopenharmony_ci### Hash and MAC mechanism availability
464a8e1175bSopenharmony_ci
465a8e1175bSopenharmony_ciFor each key type value `PSA_KEY_TYPE_xxx`, the symbol `PSA_WANT_KEY_TYPE_xxx` is defined with a non-zero value if the library is built with support for that key type. For each algorithm value `PSA_ALG_yyy`, the symbol `PSA_WANT_ALG_yyy` is defined with a non-zero value if the library is built with support for that algorithm. For a compound mechanism, all parts must be supported. In particular, for HMAC, all three of `PSA_WANT_KEY_TYPE_HMAC`, `PSA_WANT_ALG_HMAC` and the underlying hash must be enabled. (A configuration with only one of `PSA_WANT_KEY_TYPE_HMAC` and `PSA_WANT_ALG_HMAC` is technically possible but not useful.)
466a8e1175bSopenharmony_ci
467a8e1175bSopenharmony_ciFor example, to test if HMAC-SHA-256 is supported, in the legacy API, you could write:
468a8e1175bSopenharmony_ci```
469a8e1175bSopenharmony_ci#if defined(MBEDTLS_MD_C) && defined(MBEDTLS_SHA256_C)
470a8e1175bSopenharmony_ci```
471a8e1175bSopenharmony_ciThe equivalent in the PSA API is
472a8e1175bSopenharmony_ci```
473a8e1175bSopenharmony_ci#if PSA_WANT_KEY_TYPE_HMAC && PSA_WANT_ALG_HMAC && PSA_WANT_ALG_SHA_256
474a8e1175bSopenharmony_ci```
475a8e1175bSopenharmony_ci
476a8e1175bSopenharmony_ciTo test if AES-CMAC is supported, in the legacy API, you could write:
477a8e1175bSopenharmony_ci```
478a8e1175bSopenharmony_ciif defined(MBEDTLS_AES_C) && defined(MBEDTLS_CMAC_C)
479a8e1175bSopenharmony_ci```
480a8e1175bSopenharmony_ciThe equivalent in the PSA API is
481a8e1175bSopenharmony_ci```
482a8e1175bSopenharmony_ci#if PSA_WANT_KEY_TYPE_AES && PSA_WANT_ALG_CMAC
483a8e1175bSopenharmony_ci```
484a8e1175bSopenharmony_ci
485a8e1175bSopenharmony_ci### Hash algorithm metadata
486a8e1175bSopenharmony_ci
487a8e1175bSopenharmony_ciThere is no equivalent to the type `mbedtls_md_info_t` and the functions `mbedtls_md_info_from_type` and `mbedtls_md_get_type` in the PSA API because it is unnecessary. All macros and functions operate directly on algorithm (`psa_algorithm_t`, `PSA_ALG_xxx` constants).
488a8e1175bSopenharmony_ci
489a8e1175bSopenharmony_ci| Legacy macro | PSA macro |
490a8e1175bSopenharmony_ci| ------------ | --------- |
491a8e1175bSopenharmony_ci| `MBEDTLS_MD_MAX_SIZE` | [`PSA_HASH_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_HASH_MAX_SIZE) |
492a8e1175bSopenharmony_ci| `MBEDTLS_MD_MAX_BLOCK_SIZE` | [`PSA_HMAC_MAX_HASH_BLOCK_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_HMAC_MAX_HASH_BLOCK_SIZE) |
493a8e1175bSopenharmony_ci| `mbedtls_md_get_size` | [`PSA_HASH_LENGTH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_HASH_LENGTH) |
494a8e1175bSopenharmony_ci| `mbedtls_md_get_size_from_type` | [`PSA_HASH_LENGTH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_HASH_LENGTH) |
495a8e1175bSopenharmony_ci
496a8e1175bSopenharmony_ciThe following features have no PSA equivalent:
497a8e1175bSopenharmony_ci
498a8e1175bSopenharmony_ci* `mbedtls_md_list`: the PSA API does not currently have a discovery mechanism for cryptographic mechanisms, but one may be added in the future.
499a8e1175bSopenharmony_ci* `mbedtls_md_info_from_ctx`
500a8e1175bSopenharmony_ci* `mbedtls_cipher_info_from_string`, `mbedtls_md_get_name`: there is no equivalent of Mbed TLS's lookup based on a (nonstandard) name.
501a8e1175bSopenharmony_ci
502a8e1175bSopenharmony_ci### Hash calculation
503a8e1175bSopenharmony_ci
504a8e1175bSopenharmony_ciThe equivalent of `mbedtls_md` for a one-shot hash calculation is [`psa_hash_compute`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__hash/#group__hash_1gac69f7f19d96a56c28cf3799d11b12156). In addition, to compare the hash of a message with an expected value, you can call [`psa_hash_compare`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__hash/#group__hash_1ga0c08f4797bec96b886c8c8d7acc2a553) instead of `mbedtls_md` followed by `memcmp` or a constant-time equivalent.
505a8e1175bSopenharmony_ci
506a8e1175bSopenharmony_ciFor a multi-part hash calculation, the legacy process is as follows:
507a8e1175bSopenharmony_ci
508a8e1175bSopenharmony_ci1. Create a digest context of type `mbedtls_md_context_t` and initialize it with `mbedtls_md_init`.
509a8e1175bSopenharmony_ci2. Call `mbedtls_md_setup` to select the hash algorithm, with `hmac=0`. Then call `mbedtls_md_starts` to start the hash operation.
510a8e1175bSopenharmony_ci3. Call `mbedtls_md_update` as many times as necessary.
511a8e1175bSopenharmony_ci4. Call `mbedtls_md_finish`. If verifying the hash against an expected value, compare the result with the expected value.
512a8e1175bSopenharmony_ci5. Finally free the resources associated with the operation object by calling `mbedtls_md_free`.
513a8e1175bSopenharmony_ci
514a8e1175bSopenharmony_ciThe equivalent process in the PSA API is as follows:
515a8e1175bSopenharmony_ci
516a8e1175bSopenharmony_ci1. Create an operation object of type [`psa_hash_operation_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__hash/#group__hash_1ga3c4205d2ce66c4095fc5c78c25273fab) and zero-initialize it (or use the corresponding `INIT` macro).
517a8e1175bSopenharmony_ci2. Call [`psa_hash_setup`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__hash/#group__hash_1ga8d72896cf70fc4d514c5c6b978912515) to specify the algorithm.
518a8e1175bSopenharmony_ci3. Call [`psa_hash_update`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__hash/#group__hash_1ga65b16ef97d7f650899b7db4b7d1112ff) as many times as necessary.
519a8e1175bSopenharmony_ci4. To obtain the hash, call [`psa_hash_finish`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__hash/#group__hash_1ga4795fd06a0067b0adcd92e9627b8c97e). Alternatively, to verify the hash against an expected value, call [`psa_hash_verify`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__hash/#group__hash_1ga7be923c5700c9c70ef77ee9b76d1a5c0).
520a8e1175bSopenharmony_ci
521a8e1175bSopenharmony_ciIf you need to interrupt the operation after calling the setup function without calling the finish or verify function, call [`psa_hash_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__hash/#group__hash_1gab0b4d5f9912a615559497a467b532928).
522a8e1175bSopenharmony_ci
523a8e1175bSopenharmony_ciThere is no equivalent to `mbedtls_md_file` in the PSA API. Load the file data and calculate its hash.
524a8e1175bSopenharmony_ci
525a8e1175bSopenharmony_ci### MAC key management
526a8e1175bSopenharmony_ci
527a8e1175bSopenharmony_ciThe legacy API and the PSA API have a different organization of operations in several respects:
528a8e1175bSopenharmony_ci
529a8e1175bSopenharmony_ci* In the legacy API, each operation object contains the necessary key material. In the PSA API, an operation object contains a reference to a key object. To perform a cryptographic operation, you must create a key object first. However, for a one-shot operation, you do not need an operation object, just a single function call.
530a8e1175bSopenharmony_ci* The legacy API uses the same interface for authenticated and non-authenticated ciphers, while the PSA API has separate functions.
531a8e1175bSopenharmony_ci* The legacy API uses the same functions for encryption and decryption, while the PSA API has separate functions where applicable.
532a8e1175bSopenharmony_ci
533a8e1175bSopenharmony_ciHere is an overview of the lifecycle of a key object.
534a8e1175bSopenharmony_ci
535a8e1175bSopenharmony_ci1. First define the attributes of the key by filling a [`psa_key_attributes_t` structure](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga0ec645e1fdafe59d591104451ebf5680). You need to set the following parameters:
536a8e1175bSopenharmony_ci    * Call [`psa_set_key_type`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga6857ef0ecb3fa844d4536939d9c64025) to set the key type to the desired `PSA_KEY_TYPE_xxx` value (see “[Cipher mechanism selection](#cipher-mechanism-selection)”).
537a8e1175bSopenharmony_ci    * Call [`psa_set_key_bits`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaf61683ac87f87687a40262b5afbfa018) to set the key's size in bits. This is optional with `psa_import_key`, which determines the key size from the length of the key material.
538a8e1175bSopenharmony_ci    * Call [`psa_set_key_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaeb8341ca52baa0279475ea3fd3bcdc98) to set the algorithm to the desired `PSA_ALG_xxx` value (see “[Cipher mechanism selection](#cipher-mechanism-selection)”). By design, the same key cannot be used with multiple algorithms.
539a8e1175bSopenharmony_ci    * Call [`psa_set_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga42a65b3c4522ce9b67ea5ea7720e17de) to enable at least [`PSA_KEY_USAGE_SIGN_MESSAGE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#c.PSA_KEY_USAGE_SIGN_MESSAGE) to calculate a MAC or [`PSA_KEY_USAGE_VERIFY_MESSAGE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#c.PSA_KEY_USAGE_VERIFY_MESSAGE) to verify the MAC of a message. To allow both directions, use the flag mask `PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE`.
540a8e1175bSopenharmony_ci2. Call one of the key creation functions, passing the attributes defined in the previous step, to get an identifier of type [`psa_key_id_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__types_8h/#_CPPv412psa_key_id_t) to the key object.
541a8e1175bSopenharmony_ci    * Use [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b) to directly import key material.
542a8e1175bSopenharmony_ci    * If the key is randomly generated, use [`psa_generate_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga1985eae417dfbccedf50d5fff54ea8c5).
543a8e1175bSopenharmony_ci    * If the key is derived from other material (for example from a key exchange), use the [key derivation interface](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/) and create the key with [`psa_key_derivation_output_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gada7a6e17222ea9e7a6be6864a00316e1).
544a8e1175bSopenharmony_ci3. Call the functions in the following sections to perform operations on the key. The same key object can be used in multiple operations.
545a8e1175bSopenharmony_ci4. To free the resources used by the key object, call [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2) after all operations with that key are finished.
546a8e1175bSopenharmony_ci
547a8e1175bSopenharmony_ci### MAC calculation
548a8e1175bSopenharmony_ci
549a8e1175bSopenharmony_ciThe process for a HMAC operation in the legacy API is as follows:
550a8e1175bSopenharmony_ci
551a8e1175bSopenharmony_ci1. Create a digest context of type `mbedtls_md_context_t` and initialize it with `mbedtls_md_init`.
552a8e1175bSopenharmony_ci2. Call `mbedtls_md_setup` to select the hash algorithm, with `hmac=1`. Then call `mbedtls_md_hmac_starts` to set the key.
553a8e1175bSopenharmony_ci3. Call `mbedtls_md_hmac_update` as many times as necessary.
554a8e1175bSopenharmony_ci4. Call `mbedtls_md_hmac_finish`. If verifying the MAC against an expected value, compare the result with the expected value. Note that this comparison should be in constant time to avoid a side channel vulnerability, for example using `mbedtls_ct_memcmp`.
555a8e1175bSopenharmony_ci5. Finally free the resources associated with the operation object by calling `mbedtls_md_free`.
556a8e1175bSopenharmony_ci
557a8e1175bSopenharmony_ciThe process for a CMAC operation in the legacy API is as follows:
558a8e1175bSopenharmony_ci
559a8e1175bSopenharmony_ci1. Create a cipher context of type `mbedtls_cipher_context_t` and initialize it with `mbedtls_cipher_init`.
560a8e1175bSopenharmony_ci2. Call `mbedtls_cipher_setup` to select the block cipher. Then call `mbedtls_md_cmac_starts` to set the key.
561a8e1175bSopenharmony_ci3. Call `mbedtls_cipher_cmac_update` as many times as necessary.
562a8e1175bSopenharmony_ci4. Call `mbedtls_cipher_cmac_finish`. If verifying the MAC against an expected value, compare the result with the expected value. Note that this comparison should be in constant time to avoid a side channel vulnerability, for example using `mbedtls_ct_memcmp`.
563a8e1175bSopenharmony_ci5. Finally free the resources associated with the operation object by calling `mbedtls_cipher_free`.
564a8e1175bSopenharmony_ci
565a8e1175bSopenharmony_ciThe process in the PSA API to calculate a MAC is as follows:
566a8e1175bSopenharmony_ci
567a8e1175bSopenharmony_ci1. Create an operation object of type [`psa_mac_operation_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group___m_a_c/#group___m_a_c_1ga78f0838b0c4e3db28b26355624d4bd37) and zero-initialize it (or use the corresponding `INIT` macro).
568a8e1175bSopenharmony_ci2. Call [`psa_mac_sign_setup`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group___m_a_c/#group___m_a_c_1ga03bc3e3c0b7e55b20d2a238e418d46cd) to specify the algorithm and the key. See “[MAC key management](#mac-key-management)” for how to obtain a key identifier.
569a8e1175bSopenharmony_ci3. Call [`psa_mac_update`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group___m_a_c/#group___m_a_c_1ga5560af371497babefe03c9da4e8a1c05) as many times as necessary.
570a8e1175bSopenharmony_ci4. To obtain the MAC, call [`psa_mac_sign_finish`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group___m_a_c/#group___m_a_c_1gac22bc0125580c96724a09226cfbc97f2).
571a8e1175bSopenharmony_ci
572a8e1175bSopenharmony_ciTo verify a MAC against an expected value, use the following process instead:
573a8e1175bSopenharmony_ci
574a8e1175bSopenharmony_ci1. Create an operation object of type [`psa_mac_operation_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group___m_a_c/#group___m_a_c_1ga78f0838b0c4e3db28b26355624d4bd37) and zero-initialize it (or use the corresponding `INIT` macro).
575a8e1175bSopenharmony_ci2. Call [`psa_mac_verify_setup`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group___m_a_c/#group___m_a_c_1ga08ae327fcbc5f8e201172fe11e536984) to specify the algorithm and the key. See “[MAC key management](#mac-key-management)” for how to obtain a key identifier.
576a8e1175bSopenharmony_ci3. Call [`psa_mac_update`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group___m_a_c/#group___m_a_c_1ga5560af371497babefe03c9da4e8a1c05) as many times as necessary.
577a8e1175bSopenharmony_ci4. To verify the MAC against an expected value, call [`psa_mac_verify_finish`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group___m_a_c/#group___m_a_c_1gac92b2930d6728e1be4d011c05d485822).
578a8e1175bSopenharmony_ci
579a8e1175bSopenharmony_ciIf you need to interrupt the operation after calling the setup function without calling the finish function, call [`psa_mac_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group___m_a_c/#group___m_a_c_1gacd8dd54855ba1bc0a03f104f252884fd).
580a8e1175bSopenharmony_ci
581a8e1175bSopenharmony_ciThe PSA API also offers functions for a one-shot MAC calculation, similar to `mbedtls_cipher_cmac` and `mbedtls_md_hmac`:
582a8e1175bSopenharmony_ci
583a8e1175bSopenharmony_ci* [`psa_mac_compute`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group___m_a_c/#group___m_a_c_1gabf02ebd3595ea15436967092b5d52878) to calculate the MAC of a buffer in memory.
584a8e1175bSopenharmony_ci* [`psa_mac_verify`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group___m_a_c/#group___m_a_c_1gaf6988545df5d5e2466c34d753443b15a) to verify the MAC of a buffer in memory against an expected value.
585a8e1175bSopenharmony_ci
586a8e1175bSopenharmony_ciIn both cases, see “[MAC key management](#mac-key-management)” for how to obtain a key identifier.
587a8e1175bSopenharmony_ci
588a8e1175bSopenharmony_ci### Miscellaneous hash or MAC operation management
589a8e1175bSopenharmony_ci
590a8e1175bSopenharmony_ciThe equivalent of `mbedtls_md_reset`, `mbedtls_md_hmac_reset` or `mbedtls_cmac_reset` is to call [`psa_hash_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__hash/#group__hash_1gab0b4d5f9912a615559497a467b532928) or [`psa_mac_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group___m_a_c/#group___m_a_c_1gacd8dd54855ba1bc0a03f104f252884fd). Note that you must call a setup function to specify the algorithm and the key (for MAC) again, and they can be different ones.
591a8e1175bSopenharmony_ci
592a8e1175bSopenharmony_ciThe equivalent of `mbedtls_md_clone` to clone a hash operation is [`psa_hash_clone`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__hash/#group__hash_1ga39673348f3302b4646bd780034a5aeda). A PSA MAC operation cannot be cloned.
593a8e1175bSopenharmony_ci
594a8e1175bSopenharmony_ci## Key derivation
595a8e1175bSopenharmony_ci
596a8e1175bSopenharmony_ci### HKDF
597a8e1175bSopenharmony_ci
598a8e1175bSopenharmony_ciPSA Crypto provides access to HKDF, HKDF-Extract and HKDF-Expand via its [key derivation interface](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/). This is a generic interface using an operation object with one function call for each input and one function call for each output.
599a8e1175bSopenharmony_ci
600a8e1175bSopenharmony_ci1. Create an operation object of type [`psa_key_derivation_operation_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga5f099b63799a0959c3d46718c86c2609) and zero-initialize it (or use the corresponding `INIT` macro).
601a8e1175bSopenharmony_ci2. Call [`psa_key_derivation_setup`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gac0b6a76e45cceb1862752bf041701859) to select the algorithm, which is a value of type [`psa_algorithm_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gac2e4d47f1300d73c2f829a6d99252d69). For HKDF and variants, use one of the macros [`PSA_ALG_HKDF`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__values_8h/#c.PSA_ALG_HKDF), [`PSA_ALG_HKDF_EXTRACT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__values_8h/#c.PSA_ALG_HKDF_EXTRACT) or [`PSA_ALG_HKDF_EXPAND`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__values_8h/#c.PSA_ALG_HKDF_EXPAND) with the [hash algorithm](#hash-mechanism-selection) passed as an argument. For example `PSA_ALG_HKDF(PSA_ALG_SHA_256)` selects HKDF-SHA-256.
602a8e1175bSopenharmony_ci3. Call [`psa_key_derivation_input_bytes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga8fd934dfb0ca45cbf89542ef2a5494c2) on each of the inputs in the order listed below. (Use [`psa_key_derivation_input_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gab2d7ce8705dd8e4a093f4b8a21a0c15a) instead for an input that is a PSA key object.) The input step value for each step is as follows:
603a8e1175bSopenharmony_ci    1. [`PSA_KEY_DERIVATION_INPUT_SALT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__derivation/#group__derivation_1gab62757fb125243562c3947a752470d4a) for the salt used during the extraction step. Omit this step for HKDF-Expand. For HKDF, you may omit this step if the salt is empty.
604a8e1175bSopenharmony_ci    2. [`PSA_KEY_DERIVATION_INPUT_SECRET`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__derivation/#group__derivation_1ga0ddfbe764baba995c402b1b0ef59392e) for the secret input.
605a8e1175bSopenharmony_ci    3. [`PSA_KEY_DERIVATION_INPUT_INFO`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__derivation/#group__derivation_1gacef8df989e09c769233f4b779acb5b7d) for the info string used during the expansion step. Omit this step for HKDF-Extract.
606a8e1175bSopenharmony_ci4. Call [`psa_key_derivation_output_bytes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga06b7eb34a2fa88965f68e3d023fa12b9) to obtain the output of the derivation. You may call this function more than once to retrieve the output in successive chunks. Use [`psa_key_derivation_output_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gada7a6e17222ea9e7a6be6864a00316e1) instead if you want to use a chunk as a PSA key.
607a8e1175bSopenharmony_ci5. Call [`psa_key_derivation_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga90fdd2716124d0bd258826184824675f) to free the resources associated with the key derivation object.
608a8e1175bSopenharmony_ci
609a8e1175bSopenharmony_ci### PKCS#5 module
610a8e1175bSopenharmony_ci
611a8e1175bSopenharmony_ciApplications currently using `mbedtls_pkcs5_pbkdf2_hmac` or `mbedtls_pkcs5_pbkdf2_hmac_ext` can switch to the PSA key derivation API for PBKDF2. This is a generic interface using an operation object with one function call for each input and one function call for each output.
612a8e1175bSopenharmony_ci
613a8e1175bSopenharmony_ci1. Create an operation object of type [`psa_key_derivation_operation_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga5f099b63799a0959c3d46718c86c2609) and zero-initialize it (or use the corresponding `INIT` macro).
614a8e1175bSopenharmony_ci2. Call [`psa_key_derivation_setup`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gac0b6a76e45cceb1862752bf041701859) to select the algorithm, which is a value of type [`psa_algorithm_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gac2e4d47f1300d73c2f829a6d99252d69). For PBKDF2-HMAC, select `PSA_ALG_PBKDF2_HMAC(hash)` where `hash` is the underlying hash algorithm (see “[Hash mechanism selection](#hash-mechanism-selection)”).
615a8e1175bSopenharmony_ci3. Call `psa_key_derivation_input_cost` with the step `PSA_KEY_DERIVATION_INPUT_COST` to select the iteration count.
616a8e1175bSopenharmony_ci4. Call [`psa_key_derivation_input_bytes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga8fd934dfb0ca45cbf89542ef2a5494c2) on each of the inputs in the order listed below. (Use [`psa_key_derivation_input_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gab2d7ce8705dd8e4a093f4b8a21a0c15a) instead for an input that is a PSA key object.) The input step value for each step is as follows:
617a8e1175bSopenharmony_ci    1. [`PSA_KEY_DERIVATION_INPUT_SALT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__derivation/#group__derivation_1gab62757fb125243562c3947a752470d4a) for the salt used during the extraction step. You may repeat this step to pass the salt in pieces (for example a salt and a pepper).
618a8e1175bSopenharmony_ci    2. [`PSA_KEY_DERIVATION_INPUT_SECRET`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__derivation/#group__derivation_1ga0ddfbe764baba995c402b1b0ef59392e) for the password.
619a8e1175bSopenharmony_ci5. Call [`psa_key_derivation_output_bytes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga06b7eb34a2fa88965f68e3d023fa12b9) to obtain the output of the derivation. You may call this function more than once to retrieve the output in successive chunks.
620a8e1175bSopenharmony_ci  Use [`psa_key_derivation_output_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gada7a6e17222ea9e7a6be6864a00316e1) instead if you want to use a chunk as a PSA key.  
621a8e1175bSopenharmony_ci  If you want to verify the output against an expected value (for authentication, rather than to derive key material), call [`psa_key_derivation_verify_bytes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gaf01520beb7ba932143ffe733b0795b08) or [`psa_key_derivation_verify_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gac041714e34a94742e8ee006ac7dfea5a) instead of `psa_key_derivation_output_bytes`. (Note that the `verify` functions are not yet present in the 3.5 release of Mbed TLS. They are expected to be released in version 3.6.0.)
622a8e1175bSopenharmony_ci6. Call [`psa_key_derivation_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga90fdd2716124d0bd258826184824675f) to free the resources associated with the key derivation object.
623a8e1175bSopenharmony_ci
624a8e1175bSopenharmony_ciThe function `mbedtls_pkcs5_pbes2` is only intended as a support function to parse encrypted private keys in the PK module. It has no PSA equivalent.
625a8e1175bSopenharmony_ci
626a8e1175bSopenharmony_ci### PKCS#12 module
627a8e1175bSopenharmony_ci
628a8e1175bSopenharmony_ciThe functions `mbedtls_pkcs12_derivation` and `mbedtls_pkcs12_pbe` are only intended as support functions to parse encrypted private keys in the PK module. They have no PSA equivalent.
629a8e1175bSopenharmony_ci
630a8e1175bSopenharmony_ci## Random generation
631a8e1175bSopenharmony_ci
632a8e1175bSopenharmony_ci### Random generation interface
633a8e1175bSopenharmony_ci
634a8e1175bSopenharmony_ciThe PSA subsystem has an internal random generator. As a consequence, you do not need to instantiate one manually, so most applications using PSA crypto do not need the interfaces from `entropy.h`, `ctr_drbg.h` and `hmac_drbg.h`. See the next sections for remaining use cases for [entropy](#entropy-sources) and [DRBG](#deterministic-pseudorandom-generation).
635a8e1175bSopenharmony_ci
636a8e1175bSopenharmony_ciThe PSA API uses its internal random generator to generate keys (`psa_generate_key`), nonces for encryption (`psa_cipher_generate_iv`, `psa_cipher_encrypt`, `psa_aead_generate_nonce`, `psa_aead_encrypt`, `psa_asymmetric_encrypt`), and other random material as needed. If you need random data for some other purposes, call [`psa_generate_random`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga1985eae417dfbccedf50d5fff54ea8c5).
637a8e1175bSopenharmony_ci
638a8e1175bSopenharmony_ciIf your application mixes uses of the PSA crypto API and the mbedtls API and you need to pass an RNG argument to a legacy or X.509/TLS function, include the header file `<mbedtls/psa_util.h>` and use:
639a8e1175bSopenharmony_ci
640a8e1175bSopenharmony_ci* [`mbedtls_psa_get_random`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/psa__util_8h/#_CPPv422mbedtls_psa_get_randomPvPh6size_t) as the `f_rng` argument;
641a8e1175bSopenharmony_ci* [`MBEDTLS_PSA_RANDOM_STATE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/psa__util_8h/#c.MBEDTLS_PSA_RANDOM_STATE) as the `p_rng` argument.
642a8e1175bSopenharmony_ci
643a8e1175bSopenharmony_ciYou can remove the Mbed TLS RNG boilerplate (`mbedtls_entropy_init`, `mbedtls_ctr_drbg_init`, `mbedtls_ctr_drbg_seed`, `mbedtls_ctr_drbg_random`, `mbedtls_ctr_drbg_free`, `mbedtls_entropy_free` — or `hmac_drbg` equivalents of the `ctr_drbg` functions) once you have finished replacing the references to `mbedtls_ctr_drbg_random` (or `mbedtls_hmac_drbg_random`) by `mbedtls_psa_get_random`.
644a8e1175bSopenharmony_ci
645a8e1175bSopenharmony_ci### Entropy sources
646a8e1175bSopenharmony_ci
647a8e1175bSopenharmony_ciUnless explicitly configured otherwise, the PSA random generator uses the default entropy sources configured through the legacy interface (`MBEDTLS_ENTROPY_xxx` symbols). Its set of sources is equivalent to an entropy object configured with `mbedtls_entropy_init`.
648a8e1175bSopenharmony_ci
649a8e1175bSopenharmony_ciA future version of Mbed TLS will include a PSA interface for configuring entropy sources. This is likely to replace the legacy interface in Mbed TLS 4.0.
650a8e1175bSopenharmony_ci
651a8e1175bSopenharmony_ci### Deterministic pseudorandom generation
652a8e1175bSopenharmony_ci
653a8e1175bSopenharmony_ciThe PSA API does not have a dedicated interface for pseudorandom generation. The [key derivation interface](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/) can serve a similar purpose in some applications, but it does not offer CTR\_DRBG or HMAC\_DRBG. If you need these algorithms, keep using `ctr_drbg.h` and `hmac_drbg.h`, but note that they may be removed from the public API in Mbed TLS 4.0.
654a8e1175bSopenharmony_ci
655a8e1175bSopenharmony_ci## Asymmetric cryptography
656a8e1175bSopenharmony_ci
657a8e1175bSopenharmony_ciThe PSA API supports RSA (see “[RSA mechanism selection](#rsa-mechanism-selection)”), elliptic curve cryptography (see “[ECC mechanism selection](#elliptic-curve-mechanism-selection)” and “[EC-JPAKE](#ec-jpake)”) and finite-field Diffie-Hellman (see “[Diffie-Hellman mechanism selection](#diffie-hellman-mechanism-selection)”).
658a8e1175bSopenharmony_ci
659a8e1175bSopenharmony_ci### Key lifecycle for asymmetric cryptography
660a8e1175bSopenharmony_ci
661a8e1175bSopenharmony_ciIn the PSA API, keys are referenced by an identifier of type [`psa_key_id_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__types_8h/#_CPPv412psa_key_id_t).
662a8e1175bSopenharmony_ci(Some documentation references [`mbedtls_svc_key_id_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__types_8h/#_CPPv420mbedtls_svc_key_id_t); the two types are identical except when the library is configured for use in a multi-client cryptography service.)
663a8e1175bSopenharmony_ciThe PSA key identifier tends to play the same role as an `mbedtls_pk_context`, `mbedtls_rsa_context` or `mbedtls_ecp_keypair` structure in the legacy API. However, there are major differences in the way the two APIs can be used to create keys or to obtain information about a key.
664a8e1175bSopenharmony_ci
665a8e1175bSopenharmony_ciHere is an overview of the lifecycle of a PSA key object.
666a8e1175bSopenharmony_ci
667a8e1175bSopenharmony_ci1. First define the attributes of the key by filling a [`psa_key_attributes_t` structure](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga0ec645e1fdafe59d591104451ebf5680). You need to set the following parameters:
668a8e1175bSopenharmony_ci    * Call [`psa_set_key_type`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga6857ef0ecb3fa844d4536939d9c64025) to set the key type to the desired `PSA_KEY_TYPE_xxx` value (see “[RSA mechanism selection](#rsa-mechanism-selection)”, “[Elliptic curve mechanism selection](#elliptic-curve-mechanism-selection)” and “[Diffie-Hellman mechanism selection](#diffie-hellman-mechanism-selection)”).
669a8e1175bSopenharmony_ci    * Call [`psa_set_key_bits`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaf61683ac87f87687a40262b5afbfa018) to set the key's conceptual size in bits. This is optional with `psa_import_key`, which determines the key size from the length of the key material.
670a8e1175bSopenharmony_ci    * Call [`psa_set_key_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaeb8341ca52baa0279475ea3fd3bcdc98) to set the permitted algorithm to the desired `PSA_ALG_xxx` value (see “[RSA mechanism selection](#rsa-mechanism-selection)”, “[Elliptic curve mechanism selection](#elliptic-curve-mechanism-selection)” and “[Diffie-Hellman mechanism selection](#diffie-hellman-mechanism-selection)” as well as “[Public-key cryptography policies](#public-key-cryptography-policies)”).
671a8e1175bSopenharmony_ci    * Call [`psa_set_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga42a65b3c4522ce9b67ea5ea7720e17de) to enable the desired usage types (see “[Public-key cryptography policies](#public-key-cryptography-policies)”).
672a8e1175bSopenharmony_ci2. Call one of the key creation functions, passing the attributes defined in the previous step, to get an identifier of type [`psa_key_id_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__types_8h/#_CPPv412psa_key_id_t) to the key object.
673a8e1175bSopenharmony_ci    * Use [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b) to directly import key material.
674a8e1175bSopenharmony_ci    * If the key is randomly generated, use [`psa_generate_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga1985eae417dfbccedf50d5fff54ea8c5).
675a8e1175bSopenharmony_ci    * If the key is derived from other material (for example from a key exchange), use the [key derivation interface](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/) and create the key with [`psa_key_derivation_output_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gada7a6e17222ea9e7a6be6864a00316e1).
676a8e1175bSopenharmony_ci3. Call the functions in the following sections to perform operations on the key. The same key object can be used in multiple operations.
677a8e1175bSopenharmony_ci4. To free the resources used by the key object, call [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2) after all operations with that key are finished.
678a8e1175bSopenharmony_ci
679a8e1175bSopenharmony_ci### Public-key cryptography policies
680a8e1175bSopenharmony_ci
681a8e1175bSopenharmony_ciA key's policy indicates what algorithm(s) it can be used with (usage algorithm policy) and what operations are permitted (usage flags).
682a8e1175bSopenharmony_ci
683a8e1175bSopenharmony_ciThe following table lists the relevant usage flags for asymmetric cryptography. You can pass those flags (combined with bitwise-or) to [`psa_set_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga42a65b3c4522ce9b67ea5ea7720e17de).
684a8e1175bSopenharmony_ci
685a8e1175bSopenharmony_ci| Usage | Flag |
686a8e1175bSopenharmony_ci| ----- | ---- |
687a8e1175bSopenharmony_ci| export public key | 0 (always permitted) |
688a8e1175bSopenharmony_ci| export private key | [`PSA_KEY_USAGE_EXPORT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1ga7dddccdd1303176e87a4d20c87b589ed) |
689a8e1175bSopenharmony_ci| Sign a message directly | [`PSA_KEY_USAGE_SIGN_MESSAGE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1ga552117ac92b79500cae87d4e65a85c54) |
690a8e1175bSopenharmony_ci| Sign an already-calculated hash | at least one of [`PSA_KEY_USAGE_SIGN_MESSAGE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1ga552117ac92b79500cae87d4e65a85c54) or [`PSA_KEY_USAGE_SIGN_HASH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1ga552117ac92b79500cae87d4e65a85c54) |
691a8e1175bSopenharmony_ci| Verify a message directly | [`PSA_KEY_USAGE_VERIFY_MESSAGE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1gabea7ec4173f4f943110329ac2953b2b1) |
692a8e1175bSopenharmony_ci| Verify an already-calculated hash | at least one of [`PSA_KEY_USAGE_VERIFY_MESSAGE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1gabea7ec4173f4f943110329ac2953b2b1) or [`PSA_KEY_USAGE_VERIFY_HASH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1gafadf131ef2182045e3483d03aadaa1bd) |
693a8e1175bSopenharmony_ci| Encryption | [`PSA_KEY_USAGE_ENCRYPT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1ga75153b296d045d529d97203a6a995dad) |
694a8e1175bSopenharmony_ci| Decryption | [`PSA_KEY_USAGE_DECRYPT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1gac3f2d2e5983db1edde9f142ca9bf8e6a) |
695a8e1175bSopenharmony_ci| Key agreement | [`PSA_KEY_USAGE_DERIVE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1gaf19022acc5ef23cf12477f632b48a0b2) |
696a8e1175bSopenharmony_ci
697a8e1175bSopenharmony_ciThe sections “[RSA mechanism selection](#rsa-mechanism-selection)”, “[Elliptic curve mechanism selection](#elliptic-curve-mechanism-selection)” and “[Diffie-Hellman mechanism selection](#diffie-hellman-mechanism-selection)” cover the available algorithm values for each key type. Normally, a key can only be used with a single algorithm, following standard good practice. However, there are two ways to relax this requirement.
698a8e1175bSopenharmony_ci
699a8e1175bSopenharmony_ci* Many signature algorithms encode a hash algorithm. Sometimes the same key may need to be used to sign messages with multiple different hashes. In an algorithm policy, you can use [`PSA_ALG_ANY_HASH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__values_8h/#c.PSA_ALG_ANY_HASH) instead of a hash algorithm value to allow the key to be used with any hash. For example, `psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH))` allows the key to be used with RSASSA-PSS, with different hash algorithms in each operation.
700a8e1175bSopenharmony_ci* In addition to the algorithm (or wildcard) selected with [`psa_set_key_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaeb8341ca52baa0279475ea3fd3bcdc98), you can use [`psa_set_key_enrollment_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaffa134b74aa52aa3ed9397fcab4005aa) to permit a second algorithm (or wildcard). This is intended for scenarios where a key is normally used with a single algorithm, but needs to be used with a different algorithm for enrollment (such as an ECDH key for which an ECDSA proof-of-possession is also required).
701a8e1175bSopenharmony_ci
702a8e1175bSopenharmony_ci### Asymmetric cryptographic mechanisms
703a8e1175bSopenharmony_ci
704a8e1175bSopenharmony_ci#### RSA mechanism selection
705a8e1175bSopenharmony_ci
706a8e1175bSopenharmony_ciThe PK types `MBEDTLS_PK_RSA`, `MBEDTLS_PK_RSASSA_PSS` and `MBEDTLS_PK_RSA_ALT` correspond to RSA key types in the PSA API. In the PSA API, key pairs and public keys are separate object types.
707a8e1175bSopenharmony_ciSee “[RSA-ALT interface](#rsa-alt-interface)” for more information about `MBEDTLS_PK_RSA_ALT`.
708a8e1175bSopenharmony_ci
709a8e1175bSopenharmony_ciThe PSA API uses policies and algorithm parameters rather than key types to distinguish between RSA-based mechanisms. The PSA algorithm selection corresponds to the `mbedtls_pk_type_t` value passed to `mbedtls_pk_{sign,verify}_ext`. It also replaces the use of `mbedtls_rsa_set_padding` on an `mbedtls_rsa_context` object. See the list of algorithms below and the signature and encryption sections for more information.
710a8e1175bSopenharmony_ci
711a8e1175bSopenharmony_ciAn RSA public key has the type [`PSA_KEY_TYPE_RSA_PUBLIC_KEY`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga9ba0878f56c8bcd1995ac017a74f513b).
712a8e1175bSopenharmony_ci
713a8e1175bSopenharmony_ciAn RSA key pair has the type [`PSA_KEY_TYPE_RSA_KEY_PAIR`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga11745b110166e927e2abeabc7d532051). A key with this type can be used both for private-key and public-key operations (there is no separate key type for a private key without the corresponding public key).
714a8e1175bSopenharmony_ciYou can always use a private key for operations on the corresponding public key (as long as the policy permits it).
715a8e1175bSopenharmony_ci
716a8e1175bSopenharmony_ciThe following cryptographic algorithms work with RSA keys:
717a8e1175bSopenharmony_ci
718a8e1175bSopenharmony_ci* PKCS#1v1.5 RSA signature: [`PSA_ALG_RSA_PKCS1V15_SIGN`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga702ff75385a6ae7d4247033f479439af), [`PSA_ALG_RSA_PKCS1V15_SIGN_RAW`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga4215e2a78dcf834e9a625927faa2a817).
719a8e1175bSopenharmony_ci* PKCS#1v1.5 RSA encryption: [`PSA_ALG_RSA_PKCS1V15_CRYPT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga4c540d3abe43fb9abcb94f2bc51acef9).
720a8e1175bSopenharmony_ci* PKCS#1 RSASSA-PSS signature: [`PSA_ALG_RSA_PSS`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga62152bf4cb4bf6aace5e1be8f143564d), [`PSA_ALG_RSA_PSS_ANY_SALT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga9b7355a2cd6bde88177634d539127f2b).
721a8e1175bSopenharmony_ci* PKCS#1 RSAES-OAEP encryption: [`PSA_ALG_RSA_OAEP`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gaa1235dc3fdd9839c6c1b1a9857344c76).
722a8e1175bSopenharmony_ci
723a8e1175bSopenharmony_ci#### Elliptic curve mechanism selection
724a8e1175bSopenharmony_ci
725a8e1175bSopenharmony_ciThe PK types `MBEDTLS_PK_ECKEY`, `MBEDTLS_PK_ECKEY_DH` and `MBEDTLS_PK_ECDSA` correspond to elliptic-curve key types in the PSA API. In the PSA API, key pairs and public keys are separate object types. The PSA API uses policies and algorithm parameters rather than key types to distinguish between the PK EC types.
726a8e1175bSopenharmony_ci
727a8e1175bSopenharmony_ciAn ECC public key has the type [`PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gad54c03d3b47020e571a72cd01d978cf2) where `curve` is a curve family identifier.
728a8e1175bSopenharmony_ci
729a8e1175bSopenharmony_ciAn ECC key pair has the type [`PSA_KEY_TYPE_ECC_KEY_PAIR(curve)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga0b6f5d4d5037c54ffa850d8059c32df0) where `curve` is a curve family identifier. A key with this type can be used both for private-key and public-key operations (there is no separate key type for a private key without the corresponding public key).
730a8e1175bSopenharmony_ciYou can always use a private key for operations on the corresponding public key (as long as the policy permits it).
731a8e1175bSopenharmony_ci
732a8e1175bSopenharmony_ciA curve is fully determined by a curve family identifier and the private key size in bits. You can use the following functions to convert between the PSA and legacy elliptic curve designations:
733a8e1175bSopenharmony_ci- [`mbedtls_ecc_group_to_psa()`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__psa__tls__helpers/#group__psa__tls__helpers_1ga9c83c095adfec7da99401cf81e164f99) converts from the legacy curve type identifier to PSA curve family and bit-size.
734a8e1175bSopenharmony_ci- [`mbedtls_ecc_group_from_psa()`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__psa__tls__helpers/#group__psa__tls__helpers_1ga6243eb619d5b2f5fe4667811adeb8a12) converts from PSA curve family and bit-size to the legacy identifier.
735a8e1175bSopenharmony_ci
736a8e1175bSopenharmony_ciThe following table gives the correspondence between legacy and PSA elliptic curve designations.
737a8e1175bSopenharmony_ci
738a8e1175bSopenharmony_ci| Mbed TLS legacy curve identifier | PSA curve family | Curve bit-size |
739a8e1175bSopenharmony_ci| -------------------------------- | ---------------- | -------------- |
740a8e1175bSopenharmony_ci| `MBEDTLS_ECP_DP_SECP192R1` | [`PSA_ECC_FAMILY_SECP_R1`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga48bb340b5544ba617b0f5b89542665a7) | 192 |
741a8e1175bSopenharmony_ci| `MBEDTLS_ECP_DP_SECP224R1` | [`PSA_ECC_FAMILY_SECP_R1`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga48bb340b5544ba617b0f5b89542665a7) | 224 |
742a8e1175bSopenharmony_ci| `MBEDTLS_ECP_DP_SECP256R1` | [`PSA_ECC_FAMILY_SECP_R1`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga48bb340b5544ba617b0f5b89542665a7) | 256 |
743a8e1175bSopenharmony_ci| `MBEDTLS_ECP_DP_SECP384R1` | [`PSA_ECC_FAMILY_SECP_R1`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga48bb340b5544ba617b0f5b89542665a7) | 384 |
744a8e1175bSopenharmony_ci| `MBEDTLS_ECP_DP_SECP521R1` | [`PSA_ECC_FAMILY_SECP_R1`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga48bb340b5544ba617b0f5b89542665a7) | 521 |
745a8e1175bSopenharmony_ci| `MBEDTLS_ECP_DP_BP256R1` | [`PSA_ECC_FAMILY_BRAINPOOL_P_R1`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gac1643f1baf38b30d07c20a6eac697f15) | 256 |
746a8e1175bSopenharmony_ci| `MBEDTLS_ECP_DP_BP384R1` | [`PSA_ECC_FAMILY_BRAINPOOL_P_R1`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gac1643f1baf38b30d07c20a6eac697f15) | 384 |
747a8e1175bSopenharmony_ci| `MBEDTLS_ECP_DP_BP512R1` | [`PSA_ECC_FAMILY_BRAINPOOL_P_R1`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gac1643f1baf38b30d07c20a6eac697f15) | 512 |
748a8e1175bSopenharmony_ci| `MBEDTLS_ECP_DP_CURVE25519` | [`PSA_ECC_FAMILY_MONTGOMERY`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga1f624c5cdaf25b21287af33024e1aff8) | 255 |
749a8e1175bSopenharmony_ci| `MBEDTLS_ECP_DP_SECP192K1` | [`PSA_ECC_FAMILY_SECP_K1`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga48bb340b5544ba617b0f5b89542665a7) | 192 |
750a8e1175bSopenharmony_ci| `MBEDTLS_ECP_DP_SECP224K1` | not supported | N/A |
751a8e1175bSopenharmony_ci| `MBEDTLS_ECP_DP_SECP256K1` | [`PSA_ECC_FAMILY_SECP_K1`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga48bb340b5544ba617b0f5b89542665a7) | 256 |
752a8e1175bSopenharmony_ci| `MBEDTLS_ECP_DP_CURVE448` | [`PSA_ECC_FAMILY_MONTGOMERY`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga1f624c5cdaf25b21287af33024e1aff8) | 448 |
753a8e1175bSopenharmony_ci
754a8e1175bSopenharmony_ciThe following cryptographic algorithms work with ECC keys:
755a8e1175bSopenharmony_ci
756a8e1175bSopenharmony_ci* ECDH key agreement (including X25519 and X448): [`PSA_ALG_ECDH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gab2dbcf71b63785e7dd7b54a100edee43).
757a8e1175bSopenharmony_ci* ECDSA: [`PSA_ALG_ECDSA`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga7e3ce9f514a227d5ba5d8318870452e3), [`PSA_ALG_ECDSA_ANY`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga51d6b6044a62e33cae0cf64bfc3b22a4), [`PSA_ALG_DETERMINISTIC_ECDSA`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga11da566bcd341661c8de921e2ca5ed03).
758a8e1175bSopenharmony_ci* EC-JPAKE (see “[EC-JPAKE](#ec-jpake)”.
759a8e1175bSopenharmony_ci
760a8e1175bSopenharmony_ci#### Diffie-Hellman mechanism selection
761a8e1175bSopenharmony_ci
762a8e1175bSopenharmony_ciA finite-field Diffie-Hellman key pair has the type [`PSA_KEY_TYPE_DH_KEY_PAIR(group)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gab4f857c4cd56f5fe65ded421e61bcc8c) where `group` is a group family as explained below.
763a8e1175bSopenharmony_ci
764a8e1175bSopenharmony_ciA finite-field Diffie-Hellman public key has the type [`PSA_KEY_TYPE_DH_PUBLIC_KEY(group)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gaa22f0f2ea89b929f2fadc19890cc5d5c) where `group` is a group family as explained below. Due to the design of the API, there is rarely a need to use Diffie-Hellman public key objects.
765a8e1175bSopenharmony_ci
766a8e1175bSopenharmony_ciThe PSA API only supports Diffie-Hellman with predefined groups. A group is fully determined by a group family identifier and the public key size in bits.
767a8e1175bSopenharmony_ci
768a8e1175bSopenharmony_ci| Mbed TLS DH group P value | PSA DH group family | Bit-size |
769a8e1175bSopenharmony_ci| ------------------------- | ------------------- | -------- |
770a8e1175bSopenharmony_ci| `MBEDTLS_DHM_RFC7919_FFDHE2048_P_BIN` | [`PSA_DH_FAMILY_RFC7919`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga7be917e67fe4a567fb36864035822ff7) | 2048 |
771a8e1175bSopenharmony_ci| `MBEDTLS_DHM_RFC7919_FFDHE3072_P_BIN` | [`PSA_DH_FAMILY_RFC7919`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga7be917e67fe4a567fb36864035822ff7) | 3072 |
772a8e1175bSopenharmony_ci| `MBEDTLS_DHM_RFC7919_FFDHE4096_P_BIN` | [`PSA_DH_FAMILY_RFC7919`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga7be917e67fe4a567fb36864035822ff7) | 4096 |
773a8e1175bSopenharmony_ci| `MBEDTLS_DHM_RFC7919_FFDHE6144_P_BIN` | [`PSA_DH_FAMILY_RFC7919`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga7be917e67fe4a567fb36864035822ff7) | 6144 |
774a8e1175bSopenharmony_ci| `MBEDTLS_DHM_RFC7919_FFDHE8192_P_BIN` | [`PSA_DH_FAMILY_RFC7919`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga7be917e67fe4a567fb36864035822ff7) | 8192 |
775a8e1175bSopenharmony_ci
776a8e1175bSopenharmony_ciA finite-field Diffie-Hellman key can be used for key agreement with the algorithm [`PSA_ALG_FFDH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga0ebbb6f93a05b6511e6f108ffd2d1eb4).
777a8e1175bSopenharmony_ci
778a8e1175bSopenharmony_ci### Creating keys for asymmetric cryptography
779a8e1175bSopenharmony_ci
780a8e1175bSopenharmony_ciThe easiest way to create a key pair object is by randomly generating it with [`psa_generate_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga1985eae417dfbccedf50d5fff54ea8c5). Compared with the low-level functions from the legacy API (`mbedtls_rsa_gen_key`, `mbedtls_ecp_gen_privkey`, `mbedtls_ecp_gen_keypair`, `mbedtls_ecp_gen_keypair_base`, `mbedtls_ecdsa_genkey`), this directly creates an object that can be used with high-level APIs, but removes some of the flexibility. Note that if you want to export the generated private key, you must pass the flag [`PSA_KEY_USAGE_EXPORT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1ga7dddccdd1303176e87a4d20c87b589ed) to [`psa_set_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga42a65b3c4522ce9b67ea5ea7720e17de); exporting the public key with [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) is always permitted.
781a8e1175bSopenharmony_ci
782a8e1175bSopenharmony_ciFor RSA keys, `psa_generate_key` uses 65537 as the public exponent. You can use [`psa_generate_key_ext`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga6776360ae8046a4456a5f990f997da58) to select a different public exponent. As of Mbed TLS 3.6.0, selecting a different public exponent is only supported with the built-in RSA implementation, not with PSA drivers.
783a8e1175bSopenharmony_ci
784a8e1175bSopenharmony_ciTo create a key object from existing material, use [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b). This function has the same basic goal as the PK parse functions (`mbedtls_pk_parse_key`, `mbedtls_pk_parse_public_key`, `mbedtls_pk_parse_subpubkey`), but only supports a single format that just contains the number(s) that make up the key, with very little metadata. The table below summarizes the PSA import/export format for key pairs and public keys; see the documentation of [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) and [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) for more details.
785a8e1175bSopenharmony_ci
786a8e1175bSopenharmony_ci| Key type | PSA import/export format |
787a8e1175bSopenharmony_ci| -------- | ------------------------ |
788a8e1175bSopenharmony_ci| RSA key pair | PKCS#1 RSAPrivateKey DER encoding (including both private exponent and CRT parameters) |
789a8e1175bSopenharmony_ci| RSA public key | PKCS#1 RSAPublicKey DER encoding |
790a8e1175bSopenharmony_ci| ECC key pair | Fixed-length private value (not containing the public key) |
791a8e1175bSopenharmony_ci| ECC public key (Weierstrass curve) | Fixed-length uncompressed point |
792a8e1175bSopenharmony_ci| ECC public key (Montgomery curve) | Fixed-length public value |
793a8e1175bSopenharmony_ci| FFDH key pair | Fixed-length private value (not containing the public key) |
794a8e1175bSopenharmony_ci| FFDH public key | Fixed-length public value |
795a8e1175bSopenharmony_ci
796a8e1175bSopenharmony_ciThere is no equivalent of `mbedtls_pk_parse_keyfile` and `mbedtls_pk_parse_public_keyfile`. Either call the legacy function or load the file data manually.
797a8e1175bSopenharmony_ci
798a8e1175bSopenharmony_ciA future extension of the PSA API will support other import formats. Until those are implemented, see the following subsection for how to use the PK module for key parsing and construct a PSA key object from the PK object.
799a8e1175bSopenharmony_ci
800a8e1175bSopenharmony_ci### Creating a PSA key via PK
801a8e1175bSopenharmony_ci
802a8e1175bSopenharmony_ciYou can use the PK module as an intermediate step to create an RSA or ECC key for use with PSA. This is useful for use cases that the PSA API does not currently cover, such as:
803a8e1175bSopenharmony_ci
804a8e1175bSopenharmony_ci* Parsing a key in a format with metadata without knowing its type ahead of time.
805a8e1175bSopenharmony_ci* Parsing a key in a format that the PK module supports, but `psa_import_key` doesn't.
806a8e1175bSopenharmony_ci* Importing a key which you have in the form of a list of numbers, rather than the binary encoding required by `psa_import_key`.
807a8e1175bSopenharmony_ci* Importing a key with less information than what the PSA API needs, for example an ECC public key in a compressed format, an RSA private key without the private exponent, or an RSA private key without the CRT parameters.
808a8e1175bSopenharmony_ci
809a8e1175bSopenharmony_ciFor such use cases:
810a8e1175bSopenharmony_ci
811a8e1175bSopenharmony_ci1. First create a PK object with the desired key material.
812a8e1175bSopenharmony_ci2. Call [`mbedtls_pk_get_psa_attributes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1a7aa7b33cffb6981d95d1632631de9244) to fill PSA attributes corresponding to the PK key. Pass one of the following values as the `usage` parameter:
813a8e1175bSopenharmony_ci    * `PSA_KEY_USAGE_SIGN_HASH` or `PSA_KEY_USAGE_SIGN_MESSAGE` for a key pair used for signing.
814a8e1175bSopenharmony_ci    * `PSA_KEY_USAGE_DECRYPT` for a key pair used for decryption.
815a8e1175bSopenharmony_ci    * `PSA_KEY_USAGE_DERIVE` for a key pair used for key agreement.
816a8e1175bSopenharmony_ci    * `PSA_KEY_USAGE_VERIFY_HASH` or `PSA_KEY_USAGE_VERIFY_MESSAGE` for a public key pair used for signature verification.
817a8e1175bSopenharmony_ci    * `PSA_KEY_USAGE_ENCRYPT` for a key pair used for encryption.
818a8e1175bSopenharmony_ci3. Optionally, tweak the attributes (this is rarely necessary). For example:
819a8e1175bSopenharmony_ci    * Call [`psa_set_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga42a65b3c4522ce9b67ea5ea7720e17de), [`psa_set_key_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaeb8341ca52baa0279475ea3fd3bcdc98) and/or [`psa_set_key_enrollment_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__extra_8h/#group__attributes_1gaffa134b74aa52aa3ed9397fcab4005aa) to change the key's policy (by default, it allows what can be done through the PK module).
820a8e1175bSopenharmony_ci    · Call [`psa_set_key_id`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gae48fcfdc72a23e7499957d7f54ff5a64) and perhaps [`psa_set_key_lifetime`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gac03ccf09ca6d36cc3d5b43f8303db6f7) to create a PSA persistent key.
821a8e1175bSopenharmony_ci4. Call [`mbedtls_pk_import_into_psa`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1ad59835d14832daf0f4b4bd0a4555abb9) to import the key into the PSA key store.
822a8e1175bSopenharmony_ci5. You can now free the PK object with `mbedtls_pk_free`.
823a8e1175bSopenharmony_ci
824a8e1175bSopenharmony_ciHere is some sample code illustrating the above process, with error checking omitted.
825a8e1175bSopenharmony_ci
826a8e1175bSopenharmony_ci```
827a8e1175bSopenharmony_cimbedtls_pk_context pk;
828a8e1175bSopenharmony_cimbedtls_pk_init(&pk);
829a8e1175bSopenharmony_cimbedtls_pk_parse_key(&pk, key_buffer, key_buffer_length, NULL, 0,
830a8e1175bSopenharmony_ci                     mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE);
831a8e1175bSopenharmony_cipsa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
832a8e1175bSopenharmony_cimbedtls_pk_get_psa_attributes(&pk, PSA_KEY_USAGE_SIGN_HASH, &attributes);
833a8e1175bSopenharmony_cipsa_key_id_t key_id;
834a8e1175bSopenharmony_cimbedtls_pk_import_into_psa(&pk, &attributes, &key_id);
835a8e1175bSopenharmony_cimbedtls_pk_free(&pk);
836a8e1175bSopenharmony_cipsa_sign_hash(key_id, ...);
837a8e1175bSopenharmony_ci```
838a8e1175bSopenharmony_ci
839a8e1175bSopenharmony_ci#### Importing an elliptic curve key from ECP
840a8e1175bSopenharmony_ci
841a8e1175bSopenharmony_ciThis section explains how to use the `ecp.h` API to create an elliptic curve key in a format suitable for `psa_import_key`.
842a8e1175bSopenharmony_ci
843a8e1175bSopenharmony_ciYou can use this, for example, to import an ECC key in the form of a compressed point by calling `mbedtls_ecp_point_read_binary` then following the process below.
844a8e1175bSopenharmony_ci
845a8e1175bSopenharmony_ciThe following code snippet illustrates how to import a private key which is initially in an `mbedtls_ecp_keypair` object. (This includes `mbedtls_ecdsa_keypair` objects since that is just a type alias.) Error checks are omitted for simplicity. A future version of Mbed TLS [will provide a function to calculate the curve family](https://github.com/Mbed-TLS/mbedtls/issues/7764).
846a8e1175bSopenharmony_ci
847a8e1175bSopenharmony_ci```
848a8e1175bSopenharmony_cimbedtls_ecp_keypair ec;
849a8e1175bSopenharmony_cimbedtls_ecp_keypair_init(&ec);
850a8e1175bSopenharmony_ci// Omitted: fill ec with key material
851a8e1175bSopenharmony_ci// (the public key will not be used and does not need to be set)
852a8e1175bSopenharmony_ciunsigned char buf[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
853a8e1175bSopenharmony_cisize_t length;
854a8e1175bSopenharmony_cimbedtls_ecp_write_key_ext(&ec, &length, buf, sizeof(buf));
855a8e1175bSopenharmony_cipsa_ecc_curve_t curve = ...; // need to determine the curve family manually
856a8e1175bSopenharmony_cipsa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
857a8e1175bSopenharmony_cipsa_set_key_attributes(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
858a8e1175bSopenharmony_cipsa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_... | ...);
859a8e1175bSopenharmony_cipsa_set_key_algorithm(&attributes, PSA_ALGORITHM_...);
860a8e1175bSopenharmony_cipsa_key_id_t key_id = 0;
861a8e1175bSopenharmony_cipsa_import_key(&attributes, buf, length, &key_id);
862a8e1175bSopenharmony_cimbedtls_ecp_keypair_free(&ec);
863a8e1175bSopenharmony_ci```
864a8e1175bSopenharmony_ciThe following code snippet illustrates how to import a private key which is initially in an `mbedtls_ecp_keypair` object. Error checks are omitted for simplicity.
865a8e1175bSopenharmony_ci
866a8e1175bSopenharmony_ci```
867a8e1175bSopenharmony_cimbedtls_ecp_group grp;
868a8e1175bSopenharmony_cimbedtls_ecp_group_init(&grp);
869a8e1175bSopenharmony_cimbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_...);
870a8e1175bSopenharmony_cimbedtls_ecp_point pt;
871a8e1175bSopenharmony_cimbedtls_ecp_point_init(&pt);
872a8e1175bSopenharmony_ci// Omitted: fill pt with key material
873a8e1175bSopenharmony_ciunsigned char buf[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_PUBLIC_KEY_MAX_SIZE)];
874a8e1175bSopenharmony_cisize_t length;
875a8e1175bSopenharmony_cimbedtls_ecp_point_write_binary(&grp, &pt, &length, buf, sizeof(buf));
876a8e1175bSopenharmony_cipsa_ecc_curve_t curve = ...; // need to determine the curve family manually
877a8e1175bSopenharmony_cipsa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
878a8e1175bSopenharmony_cipsa_set_key_attributes(&attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve));
879a8e1175bSopenharmony_cipsa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_... | ...);
880a8e1175bSopenharmony_cipsa_set_key_algorithm(&attributes, PSA_ALGORITHM_...);
881a8e1175bSopenharmony_cipsa_key_id_t key_id = 0;
882a8e1175bSopenharmony_cipsa_import_key(&attributes, buf, length, &key_id);
883a8e1175bSopenharmony_cimbedtls_ecp_point_free(&pt);
884a8e1175bSopenharmony_cimbedtls_ecp_group_free(&grp);
885a8e1175bSopenharmony_ci```
886a8e1175bSopenharmony_ci
887a8e1175bSopenharmony_ci### Key pair and public key metadata
888a8e1175bSopenharmony_ci
889a8e1175bSopenharmony_ciThere is no equivalent to the type `mbedtls_pk_info_t` and the functions `mbedtls_pk_info_from_type` in the PSA API because it is unnecessary. All macros and functions operate directly on key type values (`psa_key_type_t`, `PSA_KEY_TYPE_xxx` constants) and algorithm values (`psa_algorithm_t`, `PSA_ALG_xxx` constants).
890a8e1175bSopenharmony_ci
891a8e1175bSopenharmony_ciYou can call [`psa_get_key_attributes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gacbbf5c11eac6cd70c87ffb936e1b9be2) to populate a structure with the attributes of a key, then functions such as [`psa_get_key_type`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gae4fb812af4f57aa1ad85e335a865b918) and [`psa_get_key_bits`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga5bee85c2164ad3d4c0d42501241eeb06) to obtain a key's type (`PSA_KEY_TYPE_xxx` value) and size (nominal size in bits).
892a8e1175bSopenharmony_ci
893a8e1175bSopenharmony_ciThe bit-size from `psa_get_key_bits` is the same as the one from `mbedtls_pk_get_bitlen`. To convert to bytes as `mbedtls_pk_get_len` or `mbedtls_rsa_get_len` do, you can use the macro `PSA_BITS_TO_BYTES`. However, note that the PSA API has generic macros for each related buffer size (export, signature size, etc.), so you should generally use those instead. The present document lists those macros where it explains the usage of the corresponding function.
894a8e1175bSopenharmony_ci
895a8e1175bSopenharmony_ciMost code that calls `mbedtls_pk_get_type` or `mbedtls_pk_can_do` only requires the key's type as reported by [`psa_get_key_type`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gae4fb812af4f57aa1ad85e335a865b918). For code that uses both `mbedtls_pk_context` objects and PSA metadata encoding, [`mbedtls_pk_can_do_ext`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1a256d3e8d4323a45aafa7d2b6c59a36f6) checks the compatibility between a key object and a mechanism. If needed, you can also access a key's policy from its attributes with [`psa_get_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaa1af20f142ca722222c6d98678a0c448), [`psa_get_key_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gac255da850a00bbed925390044f016b34) and [`psa_get_key_enrollment_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga39803b62a97198cf630854db9b53c588). The algorithm policy also conveys the padding and hash information provided by `mbedtls_rsa_get_padding_mode` and `mbedtls_rsa_get_md_alg`.
896a8e1175bSopenharmony_ci
897a8e1175bSopenharmony_ci### Exporting a public key or a key pair
898a8e1175bSopenharmony_ci
899a8e1175bSopenharmony_ciTo export a PSA key pair or public key, call [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf). If the key is a key pair, its policy must allow `PSA_KEY_USAGE_EXPORT` (see “[Public-key cryptography policies](#public-key-cryptography-policies)”).
900a8e1175bSopenharmony_ci
901a8e1175bSopenharmony_ciTo export a PSA public key or to export the public key of a PSA key pair object, call [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062). This is always permitted regardless of the key's policy.
902a8e1175bSopenharmony_ci
903a8e1175bSopenharmony_ciThe export format is the same format used for `psa_import_key`, described in “[Creating keys for asymmetric cryptography](#creating-keys-for-asymmetric-cryptography)” above.
904a8e1175bSopenharmony_ci
905a8e1175bSopenharmony_ciA future extension of the PSA API will support other export formats. Until those are implemented, see “[Exposing a PSA key via PK](#exposing-a-psa-key-via-pk)” for ways to use the PK module to format a PSA key.
906a8e1175bSopenharmony_ci
907a8e1175bSopenharmony_ci#### Exposing a PSA key via PK
908a8e1175bSopenharmony_ci
909a8e1175bSopenharmony_ciThis section discusses how to use a PSA key in a context that requires a PK object, such as PK formatting functions (`mbedtls_pk_write_key_der`, `mbedtls_pk_write_pubkey_der`, `mbedtls_pk_write_pubkey_pem`, `mbedtls_pk_write_key_pem` or `mbedtls_pk_write_pubkey`), Mbed TLS X.509 functions, Mbed TLS SSL functions, or another API that involves `mbedtls_pk_context` objects. The PSA key must be an RSA or ECC key since the PK module does not support DH keys. Three functions from `pk.h` help with that:
910a8e1175bSopenharmony_ci
911a8e1175bSopenharmony_ci* [`mbedtls_pk_copy_from_psa`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1ab8e88836fd9ee344ffe630c40447bd08) copies a PSA key into a PK object. The PSA key must be exportable. The PK object remains valid even if the PSA key is destroyed.
912a8e1175bSopenharmony_ci* [`mbedtls_pk_copy_public_from_psa`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1a2a50247a528889c12ea0ddddb8b15a4e) copies the public part of a PSA key into a PK object. The PK object remains valid even if the PSA key is destroyed.
913a8e1175bSopenharmony_ci* [`mbedtls_pk_setup_opaque`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1a4c04ac22ab9c1ae09cc29438c308bf05) sets up a PK object that wraps the PSA key. This functionality is only available when `MBEDTLS_USE_PSA_CRYPTO` is enabled. The PK object has the type `MBEDTLS_PK_OPAQUE` regardless of whether the key is an RSA or ECC key. The PK object can only be used as permitted by the PSA key's policy. The PK object contains a reference to the PSA key identifier, therefore PSA key must not be destroyed as long as the PK object remains alive.
914a8e1175bSopenharmony_ci
915a8e1175bSopenharmony_ciHere is some sample code illustrating how to use the PK module to format a PSA public key or the public key of a PSA key pair.
916a8e1175bSopenharmony_ci```
917a8e1175bSopenharmony_ciint write_psa_pubkey(psa_key_id_t key_id,
918a8e1175bSopenharmony_ci                     unsigned char *buf, size_t size, size_t *len) {
919a8e1175bSopenharmony_ci    mbedtls_pk_context pk;
920a8e1175bSopenharmony_ci    mbedtls_pk_init(&pk);
921a8e1175bSopenharmony_ci    int ret = mbedtls_pk_copy_public_from_psa(key_id, &pk);
922a8e1175bSopenharmony_ci    if (ret != 0) goto exit;
923a8e1175bSopenharmony_ci    ret = mbedtls_pk_write_pubkey_der(&pk, buf, size);
924a8e1175bSopenharmony_ci    if (ret < 0) goto exit;
925a8e1175bSopenharmony_ci    *len = ret;
926a8e1175bSopenharmony_ci    memmove(buf, buf + size - ret, ret);
927a8e1175bSopenharmony_ci    ret = 0;
928a8e1175bSopenharmony_ciexit:
929a8e1175bSopenharmony_ci    mbedtls_pk_free(&pk);
930a8e1175bSopenharmony_ci}
931a8e1175bSopenharmony_ci```
932a8e1175bSopenharmony_ci
933a8e1175bSopenharmony_ci### Signature operations
934a8e1175bSopenharmony_ci
935a8e1175bSopenharmony_ciThe equivalent of `mbedtls_pk_sign` or `mbedtls_pk_sign_ext` to sign an already calculated hash is [`psa_sign_hash`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__asymmetric/#group__asymmetric_1ga785e746a31a7b2a35ae5175c5ace3c5c).
936a8e1175bSopenharmony_ciThe key must be a key pair allowing the usage `PSA_KEY_USAGE_SIGN_HASH` (see “[Public-key cryptography policies](#public-key-cryptography-policies)”).
937a8e1175bSopenharmony_ciUse [`PSA_SIGN_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_SIGN_OUTPUT_SIZE) or [`PSA_SIGNATURE_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_SIGNATURE_MAX_SIZE) (similar to `MBEDTLS_PK_SIGNATURE_MAX_SIZE`) to determine a sufficient size for the output buffer.
938a8e1175bSopenharmony_ciThis is also the equivalent of the type-specific functions `mbedtls_rsa_pkcs1_sign`, `mbedtls_rsa_rsassa_pkcs1_v15_sign`, `mbedtls_rsa_rsassa_pss_sign`, `mbedtls_rsa_rsassa_pss_sign_ext`, `mbedtls_ecdsa_sign`, `mbedtls_ecdsa_sign_det_ext` and `mbedtls_ecdsa_write_signature`. Note that the PSA API uses the raw format for ECDSA signatures, not the ASN.1 format; see “[ECDSA signature](#ecdsa-signature)” for more details.
939a8e1175bSopenharmony_ci
940a8e1175bSopenharmony_ciThe equivalent of `mbedtls_pk_verify` or `mbedtls_pk_verify_ext` to verify an already calculated hash is [`psa_verify_hash`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__asymmetric/#group__asymmetric_1gae2ffbf01e5266391aff22b101a49f5f5).
941a8e1175bSopenharmony_ciThe key must be a public key (or a key pair) allowing the usage `PSA_KEY_USAGE_VERIFY_HASH` (see “[Public-key cryptography policies](#public-key-cryptography-policies)”).
942a8e1175bSopenharmony_ciThis is also the equivalent of the type-specific functions `mbedtls_rsa_pkcs1_verify`, `mbedtls_rsa_rsassa_pkcs1_v15_verify`, `mbedtls_rsa_rsassa_pss_verify`, `mbedtls_rsa_rsassa_pss_verify_ext`, `mbedtls_ecdsa_verify` amd `mbedtls_ecdsa_read_signature`. Note that the PSA API uses the raw format for ECDSA signatures, not the ASN.1 format; see “[ECDSA signature](#ecdsa-signature)” for more details.
943a8e1175bSopenharmony_ci
944a8e1175bSopenharmony_ciGenerally, `psa_sign_hash` and `psa_verify_hash` require the input to have the correct length for the hash (this has historically not always been enforced in the corresponding legacy APIs).
945a8e1175bSopenharmony_ci
946a8e1175bSopenharmony_ciSee also “[Restartable ECDSA signature](#restartable-ecdsa-signature)” for a restartable variant of this API.
947a8e1175bSopenharmony_ci
948a8e1175bSopenharmony_ciThe PSA API also has functions [`psa_sign_message`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__asymmetric/#group__asymmetric_1ga963ecadae9c38c85826f9a13cf1529b9) and [`psa_verify_message`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__asymmetric/#group__asymmetric_1ga01c11f480b185a4268bebd013df7c14c). These functions combine the hash calculation with the signature calculation or verification.
949a8e1175bSopenharmony_ciFor `psa_sign_message`, either the usage flag `PSA_KEY_USAGE_SIGN_MESSAGE` or `PSA_KEY_USAGE_SIGN_HASH` is sufficient.
950a8e1175bSopenharmony_ciFor `psa_verify_message`, either the usage flag `PSA_KEY_USAGE_VERIFY_MESSAGE` or `PSA_KEY_USAGE_VERIFY_HASH` is sufficient.
951a8e1175bSopenharmony_ci
952a8e1175bSopenharmony_ciMost signature algorithms involve a hash algorithm. See “[Hash mechanism selection](#hash-mechanism-selection)”.
953a8e1175bSopenharmony_ci
954a8e1175bSopenharmony_ciThe following subsections describe the PSA signature mechanisms that correspond to legacy Mbed TLS mechanisms.
955a8e1175bSopenharmony_ci
956a8e1175bSopenharmony_ci#### ECDSA signature
957a8e1175bSopenharmony_ci
958a8e1175bSopenharmony_ci**Note: in the PSA API, the format of an ECDSA signature is the raw fixed-size format. This is different from the legacy API** which uses the ASN.1 DER format for ECDSA signatures. To convert between the two formats, use [`mbedtls_ecdsa_raw_to_der`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/psa__util_8h/#group__psa__tls__helpers_1ga9295799b5437bdff8ce8abd524c5ef2e) or [`mbedtls_ecdsa_der_to_raw`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/psa__util_8h/#group__psa__tls__helpers_1ga33b3cf65d5992ccc724b7ee00186ae61).
959a8e1175bSopenharmony_ci
960a8e1175bSopenharmony_ci<!-- The following are specific to the DER format and therefore have no PSA equivalent: MBEDTLS_ECDSA_MAX_SIG_LEN, MBEDTLS_ECDSA_MAX_LEN -->
961a8e1175bSopenharmony_ci
962a8e1175bSopenharmony_ciECDSA is the mechanism provided by `mbedtls_pk_sign` and `mbedtls_pk_verify` for ECDSA keys, as well as by `mbedtls_ecdsa_sign`, `mbedtls_ecdsa_sign_det_ext`, `mbedtls_ecdsa_write_signature`, `mbedtls_ecdsa_verify` and `mbedtls_ecdsa_read_signature`.
963a8e1175bSopenharmony_ci
964a8e1175bSopenharmony_ciThe PSA API offers three algorithm constructors for ECDSA. They differ only for signature, and have exactly the same behavior for verification.
965a8e1175bSopenharmony_ci
966a8e1175bSopenharmony_ci* [`PSA_ALG_ECDSA(hash)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga7e3ce9f514a227d5ba5d8318870452e3) is a randomized ECDSA signature of a hash calculated with the algorithm `hash`.
967a8e1175bSopenharmony_ci* [`PSA_ALG_ECDSA_ANY`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga51d6b6044a62e33cae0cf64bfc3b22a4) is equivalent to `PSA_ALG_ECDSA`, but does not require specifying a hash as part of the algorithm. It can only be used with `psa_sign_hash` and `psa_verify_hash`, with no constraint on the length of the hash.
968a8e1175bSopenharmony_ci* [`PSA_ALG_DETERMINISTIC_ECDSA(hash)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga11da566bcd341661c8de921e2ca5ed03) is a deterministic ECDSA signature of a hash calculated with the algorithm `hash`. This is the same as the functionality offered by `MBEDTLS_ECDSA_DETERMINISTIC` in the legacy API.
969a8e1175bSopenharmony_ci    * For `psa_sign_message` with `PSA_ALG_DETERMINISTIC_ECDSA`, the same hash algorithm is used to hash the message and to parametrize the deterministic signature generation.
970a8e1175bSopenharmony_ci
971a8e1175bSopenharmony_ciUnlike the legacy API, where `mbedtls_pk_sign` and `mbedtls_ecdsa_write_signature` automatically select deterministic ECDSA if both are available, the PSA API requires the application to select the preferred variant. ECDSA verification cannot distinguish between randomized and deterministic ECDSA (except in so far as if the same message is signed twice and the signatures are different, then at least one of the signatures is not the determinstic variant), so in most cases switching between the two is a compatible change.
972a8e1175bSopenharmony_ci
973a8e1175bSopenharmony_ci#### Restartable ECDSA signature
974a8e1175bSopenharmony_ci
975a8e1175bSopenharmony_ciThe legacy API includes an API for “restartable” ECC operations: the operation returns after doing partial computation, and can be resumed. This is intended for highly constrained devices where long cryptographic calculations need to be broken up to poll some inputs, where interrupt-based scheduling is not desired. The legacy API consists of the functions `mbedtls_pk_sign_restartable`, `mbedtls_pk_verify_restartable`, `mbedtls_ecdsa_sign_restartable`, `mbedtls_ecdsa_verify_restartable`, `mbedtls_ecdsa_write_signature_restartable`, `mbedtls_ecdsa_read_signature_restartable`, as well as several configuration and data manipulation functions.
976a8e1175bSopenharmony_ci
977a8e1175bSopenharmony_ciThe PSA API offers similar functionality via “interruptible” public-key operations. As of Mbed TLS 3.5, it is only implemented for ECDSA, for the same curves as the legacy API. This will likely be extended to ECDH in the short term. At the time of writing, no extension is planned to other curves or other algorithms.
978a8e1175bSopenharmony_ci
979a8e1175bSopenharmony_ciThe flow of operations for an interruptible signature operation is as follows:
980a8e1175bSopenharmony_ci
981a8e1175bSopenharmony_ci1. Create an operation object of type [`psa_sign_hash_interruptible_operation_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1ga6948d4653175b1b530a265540066a7e7) and zero-initialize it (or use the corresponding `INIT` macro).
982a8e1175bSopenharmony_ci2. Call [`psa_sign_hash_start`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1ga441988da830205182b3e791352537fac) with the private key object and the hash to verify.
983a8e1175bSopenharmony_ci3. Call [`psa_sign_hash_complete`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1ga79849aaa7004a85d2ffbc4b658a333dd) repeatedly until it returns a status other than `PSA_OPERATION_INCOMPLETE`.
984a8e1175bSopenharmony_ci
985a8e1175bSopenharmony_ciThe flow of operations for an interruptible signature verification operation is as follows:
986a8e1175bSopenharmony_ci
987a8e1175bSopenharmony_ci1. Create an operation object of type [`psa_verify_hash_interruptible_operation_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1ga537054cf4909ad1426331ae4ce7148bb) and zero-initialize it (or use the corresponding `INIT` macro).
988a8e1175bSopenharmony_ci2. Call [`psa_verify_hash_start`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1ga912eb51fb94056858f451f276ee289cb) with the private key object and the hash and signature to verify.
989a8e1175bSopenharmony_ci3. Call [`psa_verify_hash_complete`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1ga67fe82352bc2f8c0343e231a70a5bc7d) repeatedly until it returns a status other than `PSA_OPERATION_INCOMPLETE`.
990a8e1175bSopenharmony_ci
991a8e1175bSopenharmony_ciIf you need to cancel the operation after calling the start function without waiting for the loop calling the complete function to finish, call [`psa_sign_hash_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1gae893a4813aa8e03bd201fe4f1bbbb403) or [`psa_verify_hash_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1ga18dc9c0cc27d590c5e3b186094d90f88).
992a8e1175bSopenharmony_ci
993a8e1175bSopenharmony_ciCall [`psa_interruptible_set_max_ops`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1ga6d86790b31657c13705214f373af869e) to set the number of basic operations per call. This is the same unit as `mbedtls_ecp_set_max_ops`. You can retrieve the current value with [`psa_interruptible_get_max_ops`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1ga73e66a6d93f2690b626fcea20ada62b2). The value is [`PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible/#group__interruptible_1gad19c1da7f6b7d59d5873d5b68eb943d4) if operations are not restartable, which corresponds to `mbedtls_ecp_restart_is_enabled()` being false.
994a8e1175bSopenharmony_ci
995a8e1175bSopenharmony_ci#### PKCS#1 v1.5 RSA signature
996a8e1175bSopenharmony_ci
997a8e1175bSopenharmony_ciThis mechanism corresponds to `mbedtls_pk_sign`, `mbedtls_pk_verify`, `mbedtls_rsa_pkcs1_sign` and `mbedtls_rsa_pkcs1_verify` for an RSA key, unless PSS has been selected with `mbedtls_rsa_set_padding` on the underlying RSA key context. This mechanism also corresponds to `mbedtls_rsa_rsassa_pkcs1_v15_sign` and `mbedtls_rsa_rsassa_pkcs1_v15_verify`.
998a8e1175bSopenharmony_ci
999a8e1175bSopenharmony_ciThe PSA API has two algorithm constructors:
1000a8e1175bSopenharmony_ci
1001a8e1175bSopenharmony_ci* [`PSA_ALG_RSA_PKCS1V15_SIGN(hash)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga702ff75385a6ae7d4247033f479439af) formats the hash as specified in PKCS#1. The hash algorithm corresponds to the `md_alg` parameter of the legacy functions.
1002a8e1175bSopenharmony_ci* [`PSA_ALG_RSA_PKCS1V15_SIGN_RAW`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga4215e2a78dcf834e9a625927faa2a817) uses the “hash” input in lieu of a DigestInfo structure. This is the same as calling the legacy functions with `md_alg=MBEDTLS_MD_NONE`.
1003a8e1175bSopenharmony_ci
1004a8e1175bSopenharmony_ci#### PKCS#1 RSASSA-PSS signature
1005a8e1175bSopenharmony_ci
1006a8e1175bSopenharmony_ciThis mechanism corresponds to `mbedtls_pk_sign_ext` and `mbedtls_pk_verify_ext` for an RSA key, as well as `mbedtls_pk_sign`, `mbedtls_pk_verify`, `mbedtls_rsa_pkcs1_sign` and `mbedtls_rsa_pkcs1_verify` if PSS has been selected on the underlying RSA context with `mbedlts_rsa_set_padding`.
1007a8e1175bSopenharmony_ciIt also corresponds to `mbedtls_rsa_rsassa_pss_sign` and `mbedtls_rsa_rsassa_pss_sign_ext`, `mbedtls_rsa_rsassa_pss_verify` and `mbedtls_rsa_rsassa_pss_verify_ext`.
1008a8e1175bSopenharmony_ci
1009a8e1175bSopenharmony_ciThe PSA API has two algorithm constructors: [`PSA_ALG_RSA_PSS(hash)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga62152bf4cb4bf6aace5e1be8f143564d) and [`PSA_ALG_RSA_PSS_ANY_SALT(hash)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga9b7355a2cd6bde88177634d539127f2b). They differ only for verification, and have exactly the same behavior for signature. The hash algorithm `hash` corresponds to the `md_alg` parameter passed to the legacy API. It is used to hash the message, to create the salted hash, and for the mask generation with MGF1. The PSA API does not support using different hash algorithms for these different purposes.
1010a8e1175bSopenharmony_ci
1011a8e1175bSopenharmony_ciWith respect to the salt length:
1012a8e1175bSopenharmony_ci
1013a8e1175bSopenharmony_ci* When signing, the salt is random, and the salt length is the largest possible salt length up to the hash length. This is the same as passing `MBEDTLS_RSA_SALT_LEN_ANY` as the salt length to `xxx_ext` legacy functions or using a legacy function that does not have a `saltlen` argument.
1014a8e1175bSopenharmony_ci* When verifying, `PSA_ALG_RSA_PSS` requires the the salt length to the largest possible salt length up to the hash length (i.e. the same that would be used for signing).
1015a8e1175bSopenharmony_ci* When verifying, `PSA_ALG_RSA_PSS_ANY_SALT` accepts any salt length. This is the same as passing `MBEDTLS_RSA_SALT_LEN_ANY` as the salt length to `xxx_ext` legacy functions or using a legacy function that does not have a `saltlen` argument.
1016a8e1175bSopenharmony_ci
1017a8e1175bSopenharmony_ci### Asymmetric encryption and decryption
1018a8e1175bSopenharmony_ci
1019a8e1175bSopenharmony_ciThe equivalent of `mbedtls_pk_encrypt`, `mbedtls_rsa_pkcs1_encrypt`, `mbedtls_rsa_rsaes_pkcs1_v15_encrypt` or `mbedtls_rsa_rsaes_oaep_encrypt` to encrypt a short message (typically a symmetric key) is [`psa_asymmetric_encrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__asymmetric/#group__asymmetric_1gaa17f61e4ddafd1823d2c834b3706c290).
1020a8e1175bSopenharmony_ciThe key must be a public key (or a key pair) allowing the usage `PSA_KEY_USAGE_ENCRYPT` (see “[Public-key cryptography policies](#public-key-cryptography-policies)”).
1021a8e1175bSopenharmony_ciUse the macro [`PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#crypto__sizes_8h_1a66ba3bd93e5ec52870ccc3848778bad8) or [`PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE) to determine the output buffer size.
1022a8e1175bSopenharmony_ci
1023a8e1175bSopenharmony_ciThe equivalent of `mbedtls_pk_decrypt`, `mbedtls_rsa_pkcs1_decrypt`, `mbedtls_rsa_rsaes_pkcs1_v15_decrypt` or `mbedtls_rsa_rsaes_oaep_decrypt` to decrypt a short message (typically a symmetric key) is [`psa_asymmetric_decrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__asymmetric/#group__asymmetric_1ga4f968756f6b22aab362b598b202d83d7).
1024a8e1175bSopenharmony_ciThe key must be a key pair allowing the usage `PSA_KEY_USAGE_DECRYPT` (see “[Public-key cryptography policies](#public-key-cryptography-policies)”).
1025a8e1175bSopenharmony_ciUse the macro [`PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#crypto__sizes_8h_1a61a246f3eac41989821d982e56fea6c1) or [`PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE) to determine the output buffer size.
1026a8e1175bSopenharmony_ci
1027a8e1175bSopenharmony_ciThe following subsections describe the PSA asymmetric encryption mechanisms that correspond to legacy Mbed TLS mechanisms.
1028a8e1175bSopenharmony_ci
1029a8e1175bSopenharmony_ci#### RSA PKCS#1v1.5 encryption
1030a8e1175bSopenharmony_ci
1031a8e1175bSopenharmony_ciThis is the mechanism used by the PK functions and by `mbedtls_rsa_pkcs1_{encrypt,decrypt}` unless `mbedtls_rsa_set_padding` has been called on the underlying RSA key context.
1032a8e1175bSopenharmony_ciThis is also the mechanism used by `mbedtls_rsa_rsaes_pkcs1_v15_{encrypt,decrypt}`.
1033a8e1175bSopenharmony_ci
1034a8e1175bSopenharmony_ciThe PSA algorithm is [`PSA_ALG_RSA_PKCS1V15_CRYPT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga4c540d3abe43fb9abcb94f2bc51acef9).
1035a8e1175bSopenharmony_ci
1036a8e1175bSopenharmony_ciBeware that PKCS#1v1.5 decryption is subject to padding oracle attacks. Revealing when `psa_asymmetric_decrypt` returns `PSA_ERROR_INVALID_PADDING` may allow an adversary to decrypt arbitrary ciphertexts.
1037a8e1175bSopenharmony_ci
1038a8e1175bSopenharmony_ci#### RSA RSAES-OAEP
1039a8e1175bSopenharmony_ci
1040a8e1175bSopenharmony_ciThis is the mechanism used by `mbedtls_rsa_rsaes_oaep_{encrypt,decrypt}`.
1041a8e1175bSopenharmony_ci
1042a8e1175bSopenharmony_ciThe PSA algorithm is [`PSA_ALG_RSA_OAEP(hash)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gaa1235dc3fdd9839c6c1b1a9857344c76) where `hash` is a hash algorithm value (`PSA_ALG_xxx`, see “[Hash mechanism selection](#hash-mechanism-selection)”).
1043a8e1175bSopenharmony_ci
1044a8e1175bSopenharmony_ciAs with the PK API, the mask generation is MGF1, the label is empty, and the same hash algorithm is used for MGF1 and to hash the label. The PSA API does not offer a way to choose a different label or a different hash algorithm for the label.
1045a8e1175bSopenharmony_ci
1046a8e1175bSopenharmony_ci### Private-public key consistency
1047a8e1175bSopenharmony_ci
1048a8e1175bSopenharmony_ciThere is no direct equivalent of the functions `mbedtls_rsa_check_privkey`, `mbedtls_rsa_check_pubkey`,`mbedtls_ecp_check_privkey`, `mbedtls_ecp_check_pubkey`. The PSA API performs some basic checks when it imports a key, and may perform additional checks before performing an operation if needed, so it will never perform an operation on a key that does not satisfy these checks, but the details of when the check is performed may change between versions of the library.
1049a8e1175bSopenharmony_ci
1050a8e1175bSopenharmony_ciThe legacy API provides functions `mbedtls_pk_check_pair`, `mbedtls_rsa_check_pub_priv` and `mbedtls_ecp_check_pub_priv`, which can be used to check the consistency between a private key and a public key. To perform such a check with the PSA API, you can export the public keys; this works because the PSA representation of public keys is canonical.
1051a8e1175bSopenharmony_ci
1052a8e1175bSopenharmony_ci* Prepare a key object containing the private key, for example with [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b).
1053a8e1175bSopenharmony_ci* Prepare a key object containing the public key, for example with [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b).
1054a8e1175bSopenharmony_ci* Export both public keys with [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) (this is possible regardless of the usage policies on the keys) and compare the output.
1055a8e1175bSopenharmony_ci    ```
1056a8e1175bSopenharmony_ci    // Error checking omitted
1057a8e1175bSopenharmony_ci    unsigned char pub1[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1058a8e1175bSopenharmony_ci    unsigned char pub2[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1059a8e1175bSopenharmony_ci    size_t length1, length2;
1060a8e1175bSopenharmony_ci    psa_export_public_key(key1, pub1, sizeof(pub1), &length1);
1061a8e1175bSopenharmony_ci    psa_export_public_key(key2, pub2, sizeof(pub2), &length2);
1062a8e1175bSopenharmony_ci    if (length1 == length2 && !memcmp(pub1, pub2, length1))
1063a8e1175bSopenharmony_ci        puts("The keys match");
1064a8e1175bSopenharmony_ci    else
1065a8e1175bSopenharmony_ci        puts("The keys do not match");
1066a8e1175bSopenharmony_ci    ```
1067a8e1175bSopenharmony_ci
1068a8e1175bSopenharmony_ci### PK functionality with no PSA equivalent
1069a8e1175bSopenharmony_ci
1070a8e1175bSopenharmony_ciThere is no PSA equivalent of the debug functionality provided by `mbedtls_pk_debug`. Use `psa_export_key` to export the key if desired.
1071a8e1175bSopenharmony_ci
1072a8e1175bSopenharmony_ciThere is no PSA equivalent to Mbed TLS's custom key type names exposed by `mbedtls_pk_get_name`.
1073a8e1175bSopenharmony_ci
1074a8e1175bSopenharmony_ci### Key agreement
1075a8e1175bSopenharmony_ci
1076a8e1175bSopenharmony_ciThe PSA API has a generic interface for key agreement, covering the main use of both `ecdh.h` and `dhm.h`.
1077a8e1175bSopenharmony_ci
1078a8e1175bSopenharmony_ci<!-- TODO: static FFDH/ECDH (including `mbedtls_ecdh_get_params`)
1079a8e1175bSopenharmony_ci https://github.com/Mbed-TLS/mbedtls/pull/7766#discussion_r1410568541
1080a8e1175bSopenharmony_ci -->
1081a8e1175bSopenharmony_ci
1082a8e1175bSopenharmony_ci#### Diffie-Hellman key pair management
1083a8e1175bSopenharmony_ci
1084a8e1175bSopenharmony_ciThe PSA API manipulates keys as such, rather than via an operation context. Thus, to use Diffie-Hellman, you need to create a key object, then perform the key exchange, then destroy the key. There is no equivalent to the types `mbedtls_ecdh_context` and `mbedtls_dhm_context`.
1085a8e1175bSopenharmony_ci
1086a8e1175bSopenharmony_ciHere is an overview of the lifecycle of a key object.
1087a8e1175bSopenharmony_ci
1088a8e1175bSopenharmony_ci1. First define the attributes of the key by filling a [`psa_key_attributes_t` structure](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga0ec645e1fdafe59d591104451ebf5680). You need to set the following parameters:
1089a8e1175bSopenharmony_ci    * Call [`psa_set_key_type`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga6857ef0ecb3fa844d4536939d9c64025) to set the key type to the desired `PSA_KEY_TYPE_xxx` value:
1090a8e1175bSopenharmony_ci        * [`PSA_KEY_TYPE_DH_KEY_PAIR(group)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gab4f857c4cd56f5fe65ded421e61bcc8c) for finite-field Diffie-Hellman (see “[Diffie-Hellman mechanism selection](#diffie-hellman-mechanism-selection)”).
1091a8e1175bSopenharmony_ci    * [`PSA_KEY_TYPE_ECC_KEY_PAIR(curve)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga0b6f5d4d5037c54ffa850d8059c32df0) for elliptic-curve Diffie-Hellman (see “[Elliptic curve mechanism selection](#elliptic-curve-mechanism-selection)”).
1092a8e1175bSopenharmony_ci    * Call [`psa_set_key_bits`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaf61683ac87f87687a40262b5afbfa018) to set the private key size in bits. This is optional with `psa_import_key`, which determines the key size from the length of the key material.
1093a8e1175bSopenharmony_ci    * Call [`psa_set_key_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaeb8341ca52baa0279475ea3fd3bcdc98) to select the appropriate algorithm:
1094a8e1175bSopenharmony_ci    * [`PSA_ALG_ECDH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gab2dbcf71b63785e7dd7b54a100edee43) or [`PSA_ALG_FFDH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga0ebbb6f93a05b6511e6f108ffd2d1eb4) for a raw key agreement.
1095a8e1175bSopenharmony_ci    * [`PSA_ALG_KEY_AGREEMENT(ka, kdf)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga78bb81cffb87a635c247725eeb2a2682) if the key will be used as part of a key derivation, where:
1096a8e1175bSopenharmony_ci        * `ka` is either `PSA_ALG_ECDH` or `PSA_ALG_FFDH`.
1097a8e1175bSopenharmony_ci        * `kdf` is a key derivation algorithm.
1098a8e1175bSopenharmony_ci    * Call [`psa_set_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga42a65b3c4522ce9b67ea5ea7720e17de) to enable at least [`PSA_KEY_USAGE_DERIVE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#c.PSA_KEY_USAGE_DERIVE). See “[Public-key cryptography policies](#public-key-cryptography-policies)” for more information.
1099a8e1175bSopenharmony_ci2. Call one of the key creation functions, passing the attributes defined in the previous step, to get an identifier of type [`psa_key_id_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__types_8h/#_CPPv412psa_key_id_t) to the key object.
1100a8e1175bSopenharmony_ci    * Use [`psa_generate_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga1985eae417dfbccedf50d5fff54ea8c5) to generate a random key. This is normally the case for a Diffie-Hellman key.
1101a8e1175bSopenharmony_ci    * Use [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b) to directly import key material.
1102a8e1175bSopenharmony_ci    * If the key is derived deterministically from other material, use the [key derivation interface](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/) and create the key with [`psa_key_derivation_output_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gada7a6e17222ea9e7a6be6864a00316e1).
1103a8e1175bSopenharmony_ci3. Call the functions in the following sections to perform operations on the key. The same key object can be used in multiple operations.
1104a8e1175bSopenharmony_ci4. To free the resources used by the key object, call [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2) after all operations with that key are finished.
1105a8e1175bSopenharmony_ci
1106a8e1175bSopenharmony_ci#### Performing a key agreement
1107a8e1175bSopenharmony_ci
1108a8e1175bSopenharmony_ciCall [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) to obtain the public key that needs to be sent to the other party.
1109a8e1175bSopenharmony_ciUse the macros [`PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE) or [`PSA_EXPORT_PUBLIC_KEY_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) to determine a sufficient size for the output buffer.
1110a8e1175bSopenharmony_ci
1111a8e1175bSopenharmony_ciCall [`psa_raw_key_agreement`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga90fdd2716124d0bd258826184824675f) to calculate the shared secret from your private key and the other party's public key.
1112a8e1175bSopenharmony_ciUse the macros [`PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE) or [`PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE) to determine a sufficient size for the output buffer.
1113a8e1175bSopenharmony_ci
1114a8e1175bSopenharmony_ciCall [`psa_key_derivation_key_agreement`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga2cd5a8ac906747d3204ec442db78745f) instead of `psa_raw_key_agreement` to use the resulting shared secret as the secret input to a key derivation. See “[HKDF](#hkdf)” for an example of the key derivation interface.
1115a8e1175bSopenharmony_ci
1116a8e1175bSopenharmony_ci#### Translating a legacy key agreement contextless workflow
1117a8e1175bSopenharmony_ci
1118a8e1175bSopenharmony_ciA typical workflow for ECDH using the legacy API without a context object is:
1119a8e1175bSopenharmony_ci
1120a8e1175bSopenharmony_ci1. Initialize objects:
1121a8e1175bSopenharmony_ci    * `mbedtls_ecp_group grp` for the curve;
1122a8e1175bSopenharmony_ci    * `mbedtls_mpi our_priv` for our private key;
1123a8e1175bSopenharmony_ci    * `mbedtls_ecp_point our_pub` for our public key;
1124a8e1175bSopenharmony_ci    * `mbedtls_ecp_point their_pub` for their public key (this may be the same variable as `our_pub` if the application does not need to hold both at the same time);
1125a8e1175bSopenharmony_ci    * `mbedtls_mpi z` for the shared secret (this may be the same variable as `our_priv` when doing ephemeral ECDH).
1126a8e1175bSopenharmony_ci2. Call `mbedtls_ecp_group_load` on `grp` to select the curve.
1127a8e1175bSopenharmony_ci3. Call `mbedtls_ecdh_gen_public` on `grp`, `our_priv` (output) and `our_pub` (output) to generate a key pair and retrieve the corresponding public key.
1128a8e1175bSopenharmony_ci4. Send `our_pub` to the peer. Retrieve the peer's public key and import it into `their_pub`. These two actions may be performed in either order.
1129a8e1175bSopenharmony_ci5. Call `mbedtls_ecdh_compute_shared` on `grp`, `z` (output), `their_pub` and `our_priv`. Use the raw shared secret `z`, typically, to construct a shared key.
1130a8e1175bSopenharmony_ci6. Free `grp`, `our_priv`, `our_pub`, `their_pub` and `z`.
1131a8e1175bSopenharmony_ci
1132a8e1175bSopenharmony_ciThe corresponding workflow with the PSA API is as follows:
1133a8e1175bSopenharmony_ci
1134a8e1175bSopenharmony_ci1. Initialize objects:
1135a8e1175bSopenharmony_ci    * `psa_key_id_t our_key`: a handle to our key pair;
1136a8e1175bSopenharmony_ci    * `psa_key_attributes_t attributes`: key attributes used in steps 2–3;;
1137a8e1175bSopenharmony_ci    * `our_pub`: a buffer of size [`PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(key_type, bits)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE) (where `key_type` is the value passed to `psa_set_key_size` in step 2) or [`PSA_EXPORT_PUBLIC_KEY_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) to hold our key.
1138a8e1175bSopenharmony_ci    * `their_pub`: a buffer of the same size, to hold the peer's key. This can be the same as `our_pub` if the application does not need to hold both at the same time;
1139a8e1175bSopenharmony_ci    * `shared_secret`: a buffer of size [`PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(key_type, bits)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE) or [`PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE) (if not using a key derivation operation).
1140a8e1175bSopenharmony_ci2. Prepare an attribute structure as described in “[Diffie-Hellman key pair management](#diffie-hellman-key-pair-management)”, in particular selecting the curve with `psa_set_key_type`.
1141a8e1175bSopenharmony_ci3. Call [`psa_generate_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga1985eae417dfbccedf50d5fff54ea8c5) on `attributes` and `our_key` (output) to generate a key pair, then [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) on `our_key` and `our_pub` (output) to obtain our public key.
1142a8e1175bSopenharmony_ci4. Send `our_pub` to the peer. Retrieve the peer's public key and import it into `their_pub`. These two actions may be performed in either order.
1143a8e1175bSopenharmony_ci5. Call [`psa_raw_key_agreement`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga90fdd2716124d0bd258826184824675f) on `our_key`, `their_pub` and `shared_secret` (output).  
1144a8e1175bSopenharmony_ci   Alternatively, call `psa_key_derivation_key_agreement` to use the shared secret directly in a key derivation operation (see “[Performing a key agreement](#performing-a-key-agreement)”).
1145a8e1175bSopenharmony_ci6. Call [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2) on `key_id`, and free the memory buffers.
1146a8e1175bSopenharmony_ci
1147a8e1175bSopenharmony_ciSteps 4–6 are only performed once for a "true" ephemeral Diffie-Hellman. They may be repeated multiple times for a "fake ephemeral" Diffie-Hellman where the same private key is used for multiple key exchanges, but it not saved.
1148a8e1175bSopenharmony_ci
1149a8e1175bSopenharmony_ci#### Translating a legacy ephemeral key agreement TLS server workflow
1150a8e1175bSopenharmony_ci
1151a8e1175bSopenharmony_ciThe legacy API offers the following workflow for an ephemeral Diffie-Hellman key agreement in a TLS 1.2 server. The PSA version of this workflow can also be used with other protocols, on the side of the party that selects the curve or group and sends its public key first.
1152a8e1175bSopenharmony_ci
1153a8e1175bSopenharmony_ci1. Setup phase:
1154a8e1175bSopenharmony_ci    1. Initialize a context of type `mbedtls_ecdh_context` or `mbedtls_dhm_context` with `mbedtls_ecdh_init` or `mbedtls_dhm_init`.
1155a8e1175bSopenharmony_ci    2. Call `mbedtls_ecdh_setup` or `mbedtls_dhm_set_group` to select the curve or group.
1156a8e1175bSopenharmony_ci    3. Call `mbedtls_ecdh_make_params` or `mbedtls_dhm_make_params` to generate our key pair and obtain a TLS ServerKeyExchange message encoding the selected curve/group and our public key.
1157a8e1175bSopenharmony_ci2. Send the ServerKeyExchange message to the peer.
1158a8e1175bSopenharmony_ci3. Retrieve the peer's public key.
1159a8e1175bSopenharmony_ci4. Call `mbedtls_ecdh_read_public` or `mbedtls_dhm_read_public` on the peer's public key, then call `mbedtls_ecdh_calc_secret` or `mbedtls_dhm_calc_secret` to calculate the shared secret.
1160a8e1175bSopenharmony_ci5. Free the context with `mbedtls_ecdh_free` or `mbedtls_dhm_free`.
1161a8e1175bSopenharmony_ci
1162a8e1175bSopenharmony_ciThe corresponding workflow with the PSA API is as follows:
1163a8e1175bSopenharmony_ci
1164a8e1175bSopenharmony_ci1. Setup phase:
1165a8e1175bSopenharmony_ci    1. Generate an ECDH or DHM key pair with `psa_generate_key` as described in “[Diffie-Hellman key pair management](#diffie-hellman-key-pair-management)”.
1166a8e1175bSopenharmony_ci    2. Call [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) to obtain our public key.
1167a8e1175bSopenharmony_ci    3. Format a ServerKeyExchange message containing the curve/group selection and our public key.
1168a8e1175bSopenharmony_ci2. Send the ServerKeyExchange message to the peer.
1169a8e1175bSopenharmony_ci3. Retrieve the peer's public key.
1170a8e1175bSopenharmony_ci4. Call [`psa_raw_key_agreement`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga90fdd2716124d0bd258826184824675f) on `our_key`, `their_pub` and `shared_secret` (output).  
1171a8e1175bSopenharmony_ci   Alternatively, call `psa_key_derivation_key_agreement` to use the shared secret directly in a key derivation operation (see “[Performing a key agreement](#performing-a-key-agreement)”).
1172a8e1175bSopenharmony_ci5. Call [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2) to free the resources associated with our key pair.
1173a8e1175bSopenharmony_ci
1174a8e1175bSopenharmony_ci#### Translating a legacy ephemeral key agreement TLS client workflow
1175a8e1175bSopenharmony_ci
1176a8e1175bSopenharmony_ciThe legacy API offers the following workflow for an ephemeral Diffie-Hellman key agreement in a TLS 1.2 client. The PSA version of this workflow can also be used with other protocols, on the side of the party that receives a message indicating both the choice of curve or group, and the peer's public key.
1177a8e1175bSopenharmony_ci
1178a8e1175bSopenharmony_ci1. Upon reception of a TLS ServerKeyExchange message received from the peer, which encodes the selected curve/group and the peer's public key:
1179a8e1175bSopenharmony_ci    1. Initialize a context of type `mbedtls_ecdh_context` or `mbedtls_dhm_context` with `mbedtls_ecdh_init` or `mbedtls_dhm_init`.
1180a8e1175bSopenharmony_ci    2. Call `mbedtls_ecdh_read_params` or `mbedtls_dhm_read_params` to input the data from the ServerKeyExchange message.
1181a8e1175bSopenharmony_ci2. Call `mbedtls_ecdh_make_public` or `mbedtls_dh_make_public` to generate our private key and export our public key.
1182a8e1175bSopenharmony_ci3. Send our public key to the peer.
1183a8e1175bSopenharmony_ci4. Call `mbedtls_ecdh_calc_secret` or `mbedtls_dhm_calc_secret` to calculate the shared secret.
1184a8e1175bSopenharmony_ci5. Free the context with `mbedtls_ecdh_free` or `mbedtls_dhm_free`.
1185a8e1175bSopenharmony_ci
1186a8e1175bSopenharmony_ciThe corresponding workflow with the PSA API is as follows:
1187a8e1175bSopenharmony_ci
1188a8e1175bSopenharmony_ci1. Upon reception of a TLS ServerKeyExchange message received from the peer, which encodes the selected curve/group and the peer's public key:
1189a8e1175bSopenharmony_ci    1. Decode the selected curve/group and use this to determine a PSA key type (`PSA_KEY_TYPE_ECC_KEY_PAIR(curve)` or `PSA_KEY_TYPE_DH_KEY_PAIR(group)`), a key size and an algorithm.
1190a8e1175bSopenharmony_ci2. Generate an ECDH or DHM key pair with `psa_generate_key` as described in “[Diffie-Hellman key pair management](#diffie-hellman-key-pair-management)”.
1191a8e1175bSopenharmony_ci   Call [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) to obtain our public key.
1192a8e1175bSopenharmony_ci3. Send our public key to the peer.
1193a8e1175bSopenharmony_ci4. Call [`psa_raw_key_agreement`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga90fdd2716124d0bd258826184824675f) on `our_key`, `their_pub` and `shared_secret` (output).  
1194a8e1175bSopenharmony_ci   Alternatively, call `psa_key_derivation_key_agreement` to use the shared secret directly in a key derivation operation (see “[Performing a key agreement](#performing-a-key-agreement)”).
1195a8e1175bSopenharmony_ci5. Call [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2) to free the resources associated with our key pair.
1196a8e1175bSopenharmony_ci
1197a8e1175bSopenharmony_ci#### ECDH and DHM metadata functions
1198a8e1175bSopenharmony_ci
1199a8e1175bSopenharmony_ciYou can obtain data and metadata from an ECDH key agreement through the PSA API as follows:
1200a8e1175bSopenharmony_ci
1201a8e1175bSopenharmony_ci* With either side, accessing the group: call [`psa_get_key_attributes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gacbbf5c11eac6cd70c87ffb936e1b9be2) on the key identifier, then [`psa_get_key_type`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gae4fb812af4f57aa1ad85e335a865b918) and [`psa_get_key_bits`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga5bee85c2164ad3d4c0d42501241eeb06) to obtain metadata about the key.
1202a8e1175bSopenharmony_ci* Accessing our public key: call [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) on the PSA key identifier.
1203a8e1175bSopenharmony_ci* Accessing our private key: call [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) on the key identifier. Note that the key policy must allow `PSA_KEY_USAGE_EXPORT` (see “[Public-key cryptography policies](#public-key-cryptography-policies)”).
1204a8e1175bSopenharmony_ci* Accessing the peer's public key: there is no PSA equivalent since the PSA API only uses the peer's public key to immediately calculate the shared secret. If your application needs the peer's public key for some other purpose, store it separately.
1205a8e1175bSopenharmony_ci
1206a8e1175bSopenharmony_ciThe functions `mbedtls_dhm_get_bitlen`, `mbedtls_dhm_get_len` and `mbedtls_dhm_get_value` allow the caller to obtain metadata about the keys used for the key exchange. The PSA equivalents access the key identifier:
1207a8e1175bSopenharmony_ci
1208a8e1175bSopenharmony_ci* `mbedtls_dhm_get_bitlen`, `mbedtls_dhm_get_len`: call [`psa_get_key_attributes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gacbbf5c11eac6cd70c87ffb936e1b9be2) on the PSA key identifier, then [`psa_get_key_bits`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga5bee85c2164ad3d4c0d42501241eeb06).
1209a8e1175bSopenharmony_ci* `mbedtls_dhm_get_value` for `MBEDTLS_DHM_PARAM_X` (our private key): call [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) on the key identifier. Note that the key policy must allow `PSA_KEY_USAGE_EXPORT` (see “[Public-key cryptography policies](#public-key-cryptography-policies)”).
1210a8e1175bSopenharmony_ci* `mbedtls_dhm_get_value` for `MBEDTLS_DHM_PARAM_GX` (our public key): call [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) on the PSA key identifier.
1211a8e1175bSopenharmony_ci* `mbedtls_dhm_get_value` for `MBEDTLS_DHM_PARAM_GY` (peer's public key): the there is no PSA equivalent since the PSA API only uses the peer's public key to immediately calculate the shared secret. If your application needs the peer's public key for some other purpose, store it separately.
1212a8e1175bSopenharmony_ci* `mbedtls_dhm_get_value` for `MBEDTLS_DHM_PARAM_K` (shared secret): this is the value calculated by `psa_raw_key_agreement` or `psa_key_derivation_key_agreement`. If you need to use it multiple times (for example to derive multiple values independently), call `psa_raw_key_agreement` and make a copy.
1213a8e1175bSopenharmony_ci* `mbedtls_dhm_get_value` for `MBEDTLS_DHM_PARAM_P` or `MBEDTLS_DHM_PARAM_G` (group parameters): [there is no PSA API to retrieve these values](https://github.com/Mbed-TLS/mbedtls/issues/7780).
1214a8e1175bSopenharmony_ci
1215a8e1175bSopenharmony_ciThe PSA API for finite-field Diffie-Hellman only supports predefined groups. Therefore there is no equivalent to `mbedtls_dhm_parse_dhm`, `mbedtls_dhm_parse_dhmfile`, and the `MBEDTLS_DHM_xxx_BIN` macros.
1216a8e1175bSopenharmony_ci
1217a8e1175bSopenharmony_ci#### Restartable key agreement
1218a8e1175bSopenharmony_ci
1219a8e1175bSopenharmony_ciRestartable key agreement (enabled by `mbedtls_ecdh_enable_restart`) is not yet available through the PSA API. It will be added under the name “interruptible key agreement” in a future version of the library, with an interface that's similar to the interruptible signature interface described in “[Restartable ECDSA signature](#restartable-ecdsa-signature)”.
1220a8e1175bSopenharmony_ci
1221a8e1175bSopenharmony_ci### Additional information about Elliptic-curve cryptography
1222a8e1175bSopenharmony_ci
1223a8e1175bSopenharmony_ci#### Information about a curve
1224a8e1175bSopenharmony_ci
1225a8e1175bSopenharmony_ciThe legacy API identifies a curve by an `MBEDTLS_ECP_DP_xxx` value of type `mbedtls_ecp_group_id`. The PSA API identifies a curve by a `PSA_ECC_FAMILY_xxx` value and the private value's bit-size. See “[Elliptic curve mechanism selection](#elliptic-curve-mechanism-selection)” for the correspondence between the two sets of values.
1226a8e1175bSopenharmony_ci
1227a8e1175bSopenharmony_ciThere is no PSA equivalent of the `mbedtls_ecp_group` data structure (and so no equivalent to `mbedtls_ecp_group_init`, `mbedtls_ecp_group_load`, `mbedtls_ecp_group_copy` and `mbedtls_ecp_group_free`) or of the `mbedtls_ecp_curve_info` data structure (and so no equivalent to `mbedtls_ecp_curve_info_from_grp_id`) because they are not needed. All API elements identify the curve directly by its family and size.
1228a8e1175bSopenharmony_ci
1229a8e1175bSopenharmony_ciThe bit-size used by the PSA API is the size of the private key. For most curves, the PSA bit-size, the `bit_size` field in `mbedtls_ecp_curve_info`, the `nbits` field in `mbedtls_ecp_group` and the `pbits` field in `mbedtls_ecp_group` are the same. The following table lists curves for which they are different.
1230a8e1175bSopenharmony_ci
1231a8e1175bSopenharmony_ci| Curve | `grp->nbits` | `grp->pbits` | `curve_info->bit_size` | PSA bit-size |
1232a8e1175bSopenharmony_ci| ----- | ------------ | ------------ | ---------------------- | ------------ |
1233a8e1175bSopenharmony_ci| secp224k1 | 225 | 224 | 224 | not supported |
1234a8e1175bSopenharmony_ci| Curve25519 | 253 | 255 | 256 | 255 |
1235a8e1175bSopenharmony_ci| Curve448 | 446 | 448 | 448 | 448 |
1236a8e1175bSopenharmony_ci
1237a8e1175bSopenharmony_ciThere is no exact PSA equivalent of the type `mbedtls_ecp_curve_type` and the function `mbedtls_ecp_get_type`, but the curve family encodes the same information. `PSA_ECC_FAMILY_MONTGOMERY` is the only Montgomery family. All other families supported in Mbed TLS 3.4.0 are short Weierstrass families.
1238a8e1175bSopenharmony_ci
1239a8e1175bSopenharmony_ciThere is no PSA equivalent for the following functionality:
1240a8e1175bSopenharmony_ci
1241a8e1175bSopenharmony_ci* The `name` field of `mbedtls_ecp_curve_info`, and the function `mbedtls_ecp_curve_info_from_name`. There is no equivalent of Mbed TLS's lookup based on the name used for the curve in TLS specifications.
1242a8e1175bSopenharmony_ci* The `tls_id` field of `mbedtls_ecp_curve_info`, the constant `MBEDTLS_ECP_TLS_NAMED_CURVE`, and the functions `mbedtls_ecp_curve_info_from_tls_id`, `mbedtls_ecp_tls_read_group`, `mbedtls_ecp_tls_read_group_id` and `mbedtls_ecp_tls_write_group`. The PSA crypto API does not have this dedicated support for the TLS protocol.
1243a8e1175bSopenharmony_ci* Retrieving the parameters of a curve from the fields of an `mbedtls_ecp_group` structure.
1244a8e1175bSopenharmony_ci
1245a8e1175bSopenharmony_ci#### Information about supported curves
1246a8e1175bSopenharmony_ci
1247a8e1175bSopenharmony_ciThe PSA API does not currently have a discovery mechanism for cryptographic mechanisms (although one may be added in the future). Thus there is no equivalent for `MBEDTLS_ECP_DP_MAX` and the functions `mbedtls_ecp_curve_list` and `mbedtls_ecp_grp_id_list`.
1248a8e1175bSopenharmony_ci
1249a8e1175bSopenharmony_ciThe API provides macros that give the maximum supported sizes for various kinds of objects. The following table lists equivalents for `MBEDTLS_ECP_MAX_xxx` macros.
1250a8e1175bSopenharmony_ci
1251a8e1175bSopenharmony_ci| Legacy macro | PSA equivalent |
1252a8e1175bSopenharmony_ci| ------------ | -------------- |
1253a8e1175bSopenharmony_ci| `MBEDTLS_ECP_MAX_BITS` | [`PSA_VENDOR_ECC_MAX_CURVE_BITS`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_VENDOR_ECC_MAX_CURVE_BITS) |
1254a8e1175bSopenharmony_ci| `MBEDTLS_ECP_MAX_BYTES` | `PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)` |
1255a8e1175bSopenharmony_ci| `MBEDTLS_ECP_MAX_PT_LEN` | [`PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE) |
1256a8e1175bSopenharmony_ci
1257a8e1175bSopenharmony_ci#### Restartable ECC
1258a8e1175bSopenharmony_ci
1259a8e1175bSopenharmony_ciThe PSA API supports the equivalent of restartable operations, but only for signatures at the time of writing. See “[Restartable ECDSA signature](#restartable-ecdsa-signature)”.
1260a8e1175bSopenharmony_ci
1261a8e1175bSopenharmony_ciThere is no PSA API for elliptic curve arithmetic as such, and therefore no equivalent of `mbedtls_ecp_restart_ctx` and functions that operate on it.
1262a8e1175bSopenharmony_ci
1263a8e1175bSopenharmony_ciThere is PSA no equivalent of the `MBEDTLS_ECP_OPS_xxx` constants.
1264a8e1175bSopenharmony_ci
1265a8e1175bSopenharmony_ci#### ECC functionality with no PSA equivalent
1266a8e1175bSopenharmony_ci
1267a8e1175bSopenharmony_ciThere is no PSA equivalent of `mbedtls_ecdsa_can_do` and `mbedtls_ecdh_can_do` to query the capabilities of a curve at runtime. Check the documentation of each curve family to see what algorithms it supports.
1268a8e1175bSopenharmony_ci
1269a8e1175bSopenharmony_ciThere is no PSA equivalent to the types `mbedtls_ecdsa_context` and `mbedtls_ecdsa_restart_ctx`, and to basic ECDSA context manipulation functions including `mbedtls_ecdsa_from_keypair`, because they are not needed: the PSA API does not have ECDSA-specific context types.
1270a8e1175bSopenharmony_ci
1271a8e1175bSopenharmony_ci#### No curve arithmetic
1272a8e1175bSopenharmony_ci
1273a8e1175bSopenharmony_ciThe PSA API is a cryptography API, not an arithmetic API. As a consequence, there is no PSA equivalent for the ECC arithmetic functionality exposed by `ecp.h`:
1274a8e1175bSopenharmony_ci
1275a8e1175bSopenharmony_ci* Manipulation of point objects and input-output: the type `mbedtls_ecp_point` and functions operating on it (`mbedtls_ecp_point_xxx`, `mbedtls_ecp_copy`, `mbedtls_ecp_{set,is}_zero`, `mbedtls_ecp_tls_{read,write}_point`). Note that the PSA export format for public keys corresponds to the uncompressed point format (`MBEDTLS_ECP_PF_UNCOMPRESSED`), so [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b), [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) and [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) are equivalent to `mbedtls_ecp_point_read_binary` and `mbedtls_ecp_point_write_binary` for uncompressed points. The PSA API does not currently support compressed points, but it is likely that such support will be added in the future.
1276a8e1175bSopenharmony_ci* Manipulation of key pairs as such, with a bridge to bignum arithmetic (`mbedtls_ecp_keypair` type, `mbedtls_ecp_export`). However, the PSA export format for ECC private keys used by [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b), [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) is the same as the format used by `mbedtls_ecp_read_key` and `mbedtls_ecp_write_key_ext`.
1277a8e1175bSopenharmony_ci* Elliptic curve arithmetic (`mbedtls_ecp_mul`, `mbedtls_ecp_muladd` and their restartable variants).
1278a8e1175bSopenharmony_ci
1279a8e1175bSopenharmony_ci### Additional information about RSA
1280a8e1175bSopenharmony_ci
1281a8e1175bSopenharmony_ci#### RSA-ALT interface
1282a8e1175bSopenharmony_ci
1283a8e1175bSopenharmony_ciImplementers of the RSA-ALT interface (`MBEDTLS_PK_RSA_ALT` pk type, `mbedtls_pk_setup_rsa_alt` setup function) should migrate to the [PSA cryptoprocessor driver interface](https://github.com/Mbed-TLS/mbedtls/blob/development/docs/psa-driver-example-and-guide.md).
1284a8e1175bSopenharmony_ci
1285a8e1175bSopenharmony_ci* If the purpose of the ALT interface is acceleration only: use the accelerator driver interface. This is fully transparent to application code.
1286a8e1175bSopenharmony_ci* If the purpose of the ALT interface is to isolate the private key in a high-security environment: use the opaque driver interface. This is mostly transparent to user code. Code that uses a key via its key identifier does not need to know whether the key is transparent (equivalent of `MBEDTLS_PK_RSA`) or opaque (equivalent of `MBEDTLS_PK_RSA_ALT`). When creating a key, it will be transparent by default; to create an opaque key, call [`psa_set_key_lifetime`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gac03ccf09ca6d36cc3d5b43f8303db6f7) to set the key's location to the chosen location value for the driver, e.g.
1287a8e1175bSopenharmony_ci    ```
1288a8e1175bSopenharmony_ci    psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(
1289a8e1175bSopenharmony_ci        PSA_KEY_PERSISTENCE_VOLATILE, MY_RSA_DRIVER_LOCATION));
1290a8e1175bSopenharmony_ci    ```
1291a8e1175bSopenharmony_ci
1292a8e1175bSopenharmony_ciThe PSA subsystem uses its internal random generator both for randomized algorithms and to generate blinding values. As a consequence, none of the API functions take an RNG parameter.
1293a8e1175bSopenharmony_ci
1294a8e1175bSopenharmony_ci#### RSA functionality with no PSA equivalent
1295a8e1175bSopenharmony_ci
1296a8e1175bSopenharmony_ciThe PSA API does not provide direct access to the exponentiation primitive as with `mbedtls_rsa_public` and `mbedtls_rsa_private`. If you need an RSA-based mechanism that is not supported by the PSA API, please [submit an issue on GitHub](https://github.com/ARM-software/psa-api/issues) so that we can extend the API to support it.
1297a8e1175bSopenharmony_ci
1298a8e1175bSopenharmony_ciThe PSA API does not support constructing RSA keys progressively from numbers with `mbedtls_rsa_import` or `mbedtls_rsa_import_raw` followed by `mbedtls_rsa_complete`. See “[Importing a PK key by wrapping](#importing-a-pk-key-by-wrapping)”.
1299a8e1175bSopenharmony_ci
1300a8e1175bSopenharmony_ciThere is no direct equivalent of `mbedtls_rsa_export`, `mbedtls_rsa_export_raw` and `mbedtls_rsa_export_crt` to export some of the numbers in a key. You can export the whole key with `psa_export_key`, or with `psa_export_public_key` to export the public key from a key pair object. See also “[Exporting a public key or a key pair](#exporting-a-public-key-or-a-key-pair)”.
1301a8e1175bSopenharmony_ci
1302a8e1175bSopenharmony_ciA PSA key object is immutable, so there is no need for an equivalent of `mbedtls_rsa_copy`. (There is a function `psa_copy_key`, but it is only useful to make a copy of a key with a different policy of ownership; both concepts are out of scope of this document since they have no equivalent in the legacy API.)
1303a8e1175bSopenharmony_ci
1304a8e1175bSopenharmony_ci### LMS signatures
1305a8e1175bSopenharmony_ci
1306a8e1175bSopenharmony_ciA future version of Mbed TLS will support LMS keys and signatures through the PSA API (`psa_generate_key`, `psa_export_public_key`, `psa_import_key`, `psa_sign_hash`, `psa_verify_hash`, etc.). However, this is likely to happen after Mbed TLS 4.0, therefore the next major version of Mbed TLS will likely keep the existing `lms.h` interface.
1307a8e1175bSopenharmony_ci
1308a8e1175bSopenharmony_ci### PK format support interfaces
1309a8e1175bSopenharmony_ci
1310a8e1175bSopenharmony_ciThe interfaces in `base64.h`, `asn1.h`, `asn1write.h`, `oid.h` and `pem.h` are intended to support X.509 and key file formats. They have no PSA equivalent since they are not directly about cryptography.
1311a8e1175bSopenharmony_ci
1312a8e1175bSopenharmony_ciIn Mbed TLS 4.0, we are planning to keep the ASN.1 interfaces mostly unchanged. The evolution of Base64, OID and PEM as separate interfaces is still undecided at the time of writing.
1313a8e1175bSopenharmony_ci
1314a8e1175bSopenharmony_ci## EC-JPAKE
1315a8e1175bSopenharmony_ci
1316a8e1175bSopenharmony_ciThe PSA API exposes EC-JPAKE via the algorithm [`PSA_ALG_JPAKE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__extra_8h/#c.PSA_ALG_JPAKE) and the PAKE API functions. At the time of writing, the PAKE API is still experimental, but it should offer the same functionality as the legacy `ecjpake.h`. Please consult the documentation of your version of Mbed TLS for more information.
1317a8e1175bSopenharmony_ci
1318a8e1175bSopenharmony_ciPlease note a few differences between the two APIs: the legacy API is geared towards the use of EC-JPAKE in TLS 1.2, whereas the PSA API is protocol-agnostic.
1319a8e1175bSopenharmony_ci
1320a8e1175bSopenharmony_ci* The PSA API is finer-grained and offers more flexibility in message ordering. Where the legacy API makes a single function call, the PSA API may require multiple calls.
1321a8e1175bSopenharmony_ci* The legacy API uses the TLS 1.2 wire format in the input or output format of several functions. In particular, one of the messages embeds the curve identifier in the TLS protocol. The PSA API uses protocol-agnostic formats.
1322a8e1175bSopenharmony_ci* The legacy API always applies the key derivation specified by TLS 1.2 to the shared secret. With the PSA API, use a key derivation with `PSA_ALG_TLS12_ECJPAKE_TO_PMS` for the same calculation.
1323