1a8e1175bSopenharmony_ci/*
2a8e1175bSopenharmony_ci *  Public Key abstraction layer
3a8e1175bSopenharmony_ci *
4a8e1175bSopenharmony_ci *  Copyright The Mbed TLS Contributors
5a8e1175bSopenharmony_ci *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6a8e1175bSopenharmony_ci */
7a8e1175bSopenharmony_ci
8a8e1175bSopenharmony_ci#include "common.h"
9a8e1175bSopenharmony_ci
10a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_C)
11a8e1175bSopenharmony_ci#include "mbedtls/pk.h"
12a8e1175bSopenharmony_ci#include "pk_wrap.h"
13a8e1175bSopenharmony_ci#include "pkwrite.h"
14a8e1175bSopenharmony_ci#include "pk_internal.h"
15a8e1175bSopenharmony_ci
16a8e1175bSopenharmony_ci#include "mbedtls/platform_util.h"
17a8e1175bSopenharmony_ci#include "mbedtls/error.h"
18a8e1175bSopenharmony_ci
19a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C)
20a8e1175bSopenharmony_ci#include "mbedtls/rsa.h"
21a8e1175bSopenharmony_ci#include "rsa_internal.h"
22a8e1175bSopenharmony_ci#endif
23a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
24a8e1175bSopenharmony_ci#include "mbedtls/ecp.h"
25a8e1175bSopenharmony_ci#endif
26a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDSA_C)
27a8e1175bSopenharmony_ci#include "mbedtls/ecdsa.h"
28a8e1175bSopenharmony_ci#endif
29a8e1175bSopenharmony_ci
30a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
31a8e1175bSopenharmony_ci#include "psa_util_internal.h"
32a8e1175bSopenharmony_ci#include "mbedtls/psa_util.h"
33a8e1175bSopenharmony_ci#endif
34a8e1175bSopenharmony_ci
35a8e1175bSopenharmony_ci#include <limits.h>
36a8e1175bSopenharmony_ci#include <stdint.h>
37a8e1175bSopenharmony_ci
38a8e1175bSopenharmony_ci#define PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE \
39a8e1175bSopenharmony_ci    (PSA_EXPORT_KEY_PAIR_MAX_SIZE > PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) ? \
40a8e1175bSopenharmony_ci    PSA_EXPORT_KEY_PAIR_MAX_SIZE : PSA_EXPORT_PUBLIC_KEY_MAX_SIZE
41a8e1175bSopenharmony_ci
42a8e1175bSopenharmony_ci/*
43a8e1175bSopenharmony_ci * Initialise a mbedtls_pk_context
44a8e1175bSopenharmony_ci */
45a8e1175bSopenharmony_civoid mbedtls_pk_init(mbedtls_pk_context *ctx)
46a8e1175bSopenharmony_ci{
47a8e1175bSopenharmony_ci    ctx->pk_info = NULL;
48a8e1175bSopenharmony_ci    ctx->pk_ctx = NULL;
49a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
50a8e1175bSopenharmony_ci    ctx->priv_id = MBEDTLS_SVC_KEY_ID_INIT;
51a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
52a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
53a8e1175bSopenharmony_ci    memset(ctx->pub_raw, 0, sizeof(ctx->pub_raw));
54a8e1175bSopenharmony_ci    ctx->pub_raw_len = 0;
55a8e1175bSopenharmony_ci    ctx->ec_family = 0;
56a8e1175bSopenharmony_ci    ctx->ec_bits = 0;
57a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
58a8e1175bSopenharmony_ci}
59a8e1175bSopenharmony_ci
60a8e1175bSopenharmony_ci/*
61a8e1175bSopenharmony_ci * Free (the components of) a mbedtls_pk_context
62a8e1175bSopenharmony_ci */
63a8e1175bSopenharmony_civoid mbedtls_pk_free(mbedtls_pk_context *ctx)
64a8e1175bSopenharmony_ci{
65a8e1175bSopenharmony_ci    if (ctx == NULL) {
66a8e1175bSopenharmony_ci        return;
67a8e1175bSopenharmony_ci    }
68a8e1175bSopenharmony_ci
69a8e1175bSopenharmony_ci    if ((ctx->pk_info != NULL) && (ctx->pk_info->ctx_free_func != NULL)) {
70a8e1175bSopenharmony_ci        ctx->pk_info->ctx_free_func(ctx->pk_ctx);
71a8e1175bSopenharmony_ci    }
72a8e1175bSopenharmony_ci
73a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
74a8e1175bSopenharmony_ci    /* The ownership of the priv_id key for opaque keys is external of the PK
75a8e1175bSopenharmony_ci     * module. It's the user responsibility to clear it after use. */
76a8e1175bSopenharmony_ci    if ((ctx->pk_info != NULL) && (ctx->pk_info->type != MBEDTLS_PK_OPAQUE)) {
77a8e1175bSopenharmony_ci        psa_destroy_key(ctx->priv_id);
78a8e1175bSopenharmony_ci    }
79a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
80a8e1175bSopenharmony_ci
81a8e1175bSopenharmony_ci    mbedtls_platform_zeroize(ctx, sizeof(mbedtls_pk_context));
82a8e1175bSopenharmony_ci}
83a8e1175bSopenharmony_ci
84a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
85a8e1175bSopenharmony_ci/*
86a8e1175bSopenharmony_ci * Initialize a restart context
87a8e1175bSopenharmony_ci */
88a8e1175bSopenharmony_civoid mbedtls_pk_restart_init(mbedtls_pk_restart_ctx *ctx)
89a8e1175bSopenharmony_ci{
90a8e1175bSopenharmony_ci    ctx->pk_info = NULL;
91a8e1175bSopenharmony_ci    ctx->rs_ctx = NULL;
92a8e1175bSopenharmony_ci}
93a8e1175bSopenharmony_ci
94a8e1175bSopenharmony_ci/*
95a8e1175bSopenharmony_ci * Free the components of a restart context
96a8e1175bSopenharmony_ci */
97a8e1175bSopenharmony_civoid mbedtls_pk_restart_free(mbedtls_pk_restart_ctx *ctx)
98a8e1175bSopenharmony_ci{
99a8e1175bSopenharmony_ci    if (ctx == NULL || ctx->pk_info == NULL ||
100a8e1175bSopenharmony_ci        ctx->pk_info->rs_free_func == NULL) {
101a8e1175bSopenharmony_ci        return;
102a8e1175bSopenharmony_ci    }
103a8e1175bSopenharmony_ci
104a8e1175bSopenharmony_ci    ctx->pk_info->rs_free_func(ctx->rs_ctx);
105a8e1175bSopenharmony_ci
106a8e1175bSopenharmony_ci    ctx->pk_info = NULL;
107a8e1175bSopenharmony_ci    ctx->rs_ctx = NULL;
108a8e1175bSopenharmony_ci}
109a8e1175bSopenharmony_ci#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
110a8e1175bSopenharmony_ci
111a8e1175bSopenharmony_ci/*
112a8e1175bSopenharmony_ci * Get pk_info structure from type
113a8e1175bSopenharmony_ci */
114a8e1175bSopenharmony_ciconst mbedtls_pk_info_t *mbedtls_pk_info_from_type(mbedtls_pk_type_t pk_type)
115a8e1175bSopenharmony_ci{
116a8e1175bSopenharmony_ci    switch (pk_type) {
117a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C)
118a8e1175bSopenharmony_ci        case MBEDTLS_PK_RSA:
119a8e1175bSopenharmony_ci            return &mbedtls_rsa_info;
120a8e1175bSopenharmony_ci#endif /* MBEDTLS_RSA_C */
121a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
122a8e1175bSopenharmony_ci        case MBEDTLS_PK_ECKEY:
123a8e1175bSopenharmony_ci            return &mbedtls_eckey_info;
124a8e1175bSopenharmony_ci        case MBEDTLS_PK_ECKEY_DH:
125a8e1175bSopenharmony_ci            return &mbedtls_eckeydh_info;
126a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
127a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_CAN_ECDSA_SOME)
128a8e1175bSopenharmony_ci        case MBEDTLS_PK_ECDSA:
129a8e1175bSopenharmony_ci            return &mbedtls_ecdsa_info;
130a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_CAN_ECDSA_SOME */
131a8e1175bSopenharmony_ci        /* MBEDTLS_PK_RSA_ALT omitted on purpose */
132a8e1175bSopenharmony_ci        default:
133a8e1175bSopenharmony_ci            return NULL;
134a8e1175bSopenharmony_ci    }
135a8e1175bSopenharmony_ci}
136a8e1175bSopenharmony_ci
137a8e1175bSopenharmony_ci/*
138a8e1175bSopenharmony_ci * Initialise context
139a8e1175bSopenharmony_ci */
140a8e1175bSopenharmony_ciint mbedtls_pk_setup(mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info)
141a8e1175bSopenharmony_ci{
142a8e1175bSopenharmony_ci    if (info == NULL || ctx->pk_info != NULL) {
143a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
144a8e1175bSopenharmony_ci    }
145a8e1175bSopenharmony_ci
146a8e1175bSopenharmony_ci    if ((info->ctx_alloc_func != NULL) &&
147a8e1175bSopenharmony_ci        ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL)) {
148a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_ALLOC_FAILED;
149a8e1175bSopenharmony_ci    }
150a8e1175bSopenharmony_ci
151a8e1175bSopenharmony_ci    ctx->pk_info = info;
152a8e1175bSopenharmony_ci
153a8e1175bSopenharmony_ci    return 0;
154a8e1175bSopenharmony_ci}
155a8e1175bSopenharmony_ci
156a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
157a8e1175bSopenharmony_ci/*
158a8e1175bSopenharmony_ci * Initialise a PSA-wrapping context
159a8e1175bSopenharmony_ci */
160a8e1175bSopenharmony_ciint mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx,
161a8e1175bSopenharmony_ci                            const mbedtls_svc_key_id_t key)
162a8e1175bSopenharmony_ci{
163a8e1175bSopenharmony_ci    const mbedtls_pk_info_t *info = NULL;
164a8e1175bSopenharmony_ci    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
165a8e1175bSopenharmony_ci    psa_key_type_t type;
166a8e1175bSopenharmony_ci
167a8e1175bSopenharmony_ci    if (ctx == NULL || ctx->pk_info != NULL) {
168a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
169a8e1175bSopenharmony_ci    }
170a8e1175bSopenharmony_ci
171a8e1175bSopenharmony_ci    if (PSA_SUCCESS != psa_get_key_attributes(key, &attributes)) {
172a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
173a8e1175bSopenharmony_ci    }
174a8e1175bSopenharmony_ci    type = psa_get_key_type(&attributes);
175a8e1175bSopenharmony_ci    psa_reset_key_attributes(&attributes);
176a8e1175bSopenharmony_ci
177a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
178a8e1175bSopenharmony_ci    if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
179a8e1175bSopenharmony_ci        info = &mbedtls_ecdsa_opaque_info;
180a8e1175bSopenharmony_ci    } else
181a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
182a8e1175bSopenharmony_ci    if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
183a8e1175bSopenharmony_ci        info = &mbedtls_rsa_opaque_info;
184a8e1175bSopenharmony_ci    } else {
185a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
186a8e1175bSopenharmony_ci    }
187a8e1175bSopenharmony_ci
188a8e1175bSopenharmony_ci    ctx->pk_info = info;
189a8e1175bSopenharmony_ci    ctx->priv_id = key;
190a8e1175bSopenharmony_ci
191a8e1175bSopenharmony_ci    return 0;
192a8e1175bSopenharmony_ci}
193a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
194a8e1175bSopenharmony_ci
195a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
196a8e1175bSopenharmony_ci/*
197a8e1175bSopenharmony_ci * Initialize an RSA-alt context
198a8e1175bSopenharmony_ci */
199a8e1175bSopenharmony_ciint mbedtls_pk_setup_rsa_alt(mbedtls_pk_context *ctx, void *key,
200a8e1175bSopenharmony_ci                             mbedtls_pk_rsa_alt_decrypt_func decrypt_func,
201a8e1175bSopenharmony_ci                             mbedtls_pk_rsa_alt_sign_func sign_func,
202a8e1175bSopenharmony_ci                             mbedtls_pk_rsa_alt_key_len_func key_len_func)
203a8e1175bSopenharmony_ci{
204a8e1175bSopenharmony_ci    mbedtls_rsa_alt_context *rsa_alt;
205a8e1175bSopenharmony_ci    const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info;
206a8e1175bSopenharmony_ci
207a8e1175bSopenharmony_ci    if (ctx->pk_info != NULL) {
208a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
209a8e1175bSopenharmony_ci    }
210a8e1175bSopenharmony_ci
211a8e1175bSopenharmony_ci    if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL) {
212a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_ALLOC_FAILED;
213a8e1175bSopenharmony_ci    }
214a8e1175bSopenharmony_ci
215a8e1175bSopenharmony_ci    ctx->pk_info = info;
216a8e1175bSopenharmony_ci
217a8e1175bSopenharmony_ci    rsa_alt = (mbedtls_rsa_alt_context *) ctx->pk_ctx;
218a8e1175bSopenharmony_ci
219a8e1175bSopenharmony_ci    rsa_alt->key = key;
220a8e1175bSopenharmony_ci    rsa_alt->decrypt_func = decrypt_func;
221a8e1175bSopenharmony_ci    rsa_alt->sign_func = sign_func;
222a8e1175bSopenharmony_ci    rsa_alt->key_len_func = key_len_func;
223a8e1175bSopenharmony_ci
224a8e1175bSopenharmony_ci    return 0;
225a8e1175bSopenharmony_ci}
226a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
227a8e1175bSopenharmony_ci
228a8e1175bSopenharmony_ci/*
229a8e1175bSopenharmony_ci * Tell if a PK can do the operations of the given type
230a8e1175bSopenharmony_ci */
231a8e1175bSopenharmony_ciint mbedtls_pk_can_do(const mbedtls_pk_context *ctx, mbedtls_pk_type_t type)
232a8e1175bSopenharmony_ci{
233a8e1175bSopenharmony_ci    /* A context with null pk_info is not set up yet and can't do anything.
234a8e1175bSopenharmony_ci     * For backward compatibility, also accept NULL instead of a context
235a8e1175bSopenharmony_ci     * pointer. */
236a8e1175bSopenharmony_ci    if (ctx == NULL || ctx->pk_info == NULL) {
237a8e1175bSopenharmony_ci        return 0;
238a8e1175bSopenharmony_ci    }
239a8e1175bSopenharmony_ci
240a8e1175bSopenharmony_ci    return ctx->pk_info->can_do(type);
241a8e1175bSopenharmony_ci}
242a8e1175bSopenharmony_ci
243a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
244a8e1175bSopenharmony_ci/*
245a8e1175bSopenharmony_ci * Tell if a PK can do the operations of the given PSA algorithm
246a8e1175bSopenharmony_ci */
247a8e1175bSopenharmony_ciint mbedtls_pk_can_do_ext(const mbedtls_pk_context *ctx, psa_algorithm_t alg,
248a8e1175bSopenharmony_ci                          psa_key_usage_t usage)
249a8e1175bSopenharmony_ci{
250a8e1175bSopenharmony_ci    psa_key_usage_t key_usage;
251a8e1175bSopenharmony_ci
252a8e1175bSopenharmony_ci    /* A context with null pk_info is not set up yet and can't do anything.
253a8e1175bSopenharmony_ci     * For backward compatibility, also accept NULL instead of a context
254a8e1175bSopenharmony_ci     * pointer. */
255a8e1175bSopenharmony_ci    if (ctx == NULL || ctx->pk_info == NULL) {
256a8e1175bSopenharmony_ci        return 0;
257a8e1175bSopenharmony_ci    }
258a8e1175bSopenharmony_ci
259a8e1175bSopenharmony_ci    /* Filter out non allowed algorithms */
260a8e1175bSopenharmony_ci    if (PSA_ALG_IS_ECDSA(alg) == 0 &&
261a8e1175bSopenharmony_ci        PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) == 0 &&
262a8e1175bSopenharmony_ci        PSA_ALG_IS_RSA_PSS(alg) == 0 &&
263a8e1175bSopenharmony_ci        alg != PSA_ALG_RSA_PKCS1V15_CRYPT &&
264a8e1175bSopenharmony_ci        PSA_ALG_IS_ECDH(alg) == 0) {
265a8e1175bSopenharmony_ci        return 0;
266a8e1175bSopenharmony_ci    }
267a8e1175bSopenharmony_ci
268a8e1175bSopenharmony_ci    /* Filter out non allowed usage flags */
269a8e1175bSopenharmony_ci    if (usage == 0 ||
270a8e1175bSopenharmony_ci        (usage & ~(PSA_KEY_USAGE_SIGN_HASH |
271a8e1175bSopenharmony_ci                   PSA_KEY_USAGE_DECRYPT |
272a8e1175bSopenharmony_ci                   PSA_KEY_USAGE_DERIVE)) != 0) {
273a8e1175bSopenharmony_ci        return 0;
274a8e1175bSopenharmony_ci    }
275a8e1175bSopenharmony_ci
276a8e1175bSopenharmony_ci    /* Wildcard hash is not allowed */
277a8e1175bSopenharmony_ci    if (PSA_ALG_IS_SIGN_HASH(alg) &&
278a8e1175bSopenharmony_ci        PSA_ALG_SIGN_GET_HASH(alg) == PSA_ALG_ANY_HASH) {
279a8e1175bSopenharmony_ci        return 0;
280a8e1175bSopenharmony_ci    }
281a8e1175bSopenharmony_ci
282a8e1175bSopenharmony_ci    if (mbedtls_pk_get_type(ctx) != MBEDTLS_PK_OPAQUE) {
283a8e1175bSopenharmony_ci        mbedtls_pk_type_t type;
284a8e1175bSopenharmony_ci
285a8e1175bSopenharmony_ci        if (PSA_ALG_IS_ECDSA(alg) || PSA_ALG_IS_ECDH(alg)) {
286a8e1175bSopenharmony_ci            type = MBEDTLS_PK_ECKEY;
287a8e1175bSopenharmony_ci        } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) ||
288a8e1175bSopenharmony_ci                   alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
289a8e1175bSopenharmony_ci            type = MBEDTLS_PK_RSA;
290a8e1175bSopenharmony_ci        } else if (PSA_ALG_IS_RSA_PSS(alg)) {
291a8e1175bSopenharmony_ci            type = MBEDTLS_PK_RSASSA_PSS;
292a8e1175bSopenharmony_ci        } else {
293a8e1175bSopenharmony_ci            return 0;
294a8e1175bSopenharmony_ci        }
295a8e1175bSopenharmony_ci
296a8e1175bSopenharmony_ci        if (ctx->pk_info->can_do(type) == 0) {
297a8e1175bSopenharmony_ci            return 0;
298a8e1175bSopenharmony_ci        }
299a8e1175bSopenharmony_ci
300a8e1175bSopenharmony_ci        switch (type) {
301a8e1175bSopenharmony_ci            case MBEDTLS_PK_ECKEY:
302a8e1175bSopenharmony_ci                key_usage = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_DERIVE;
303a8e1175bSopenharmony_ci                break;
304a8e1175bSopenharmony_ci            case MBEDTLS_PK_RSA:
305a8e1175bSopenharmony_ci            case MBEDTLS_PK_RSASSA_PSS:
306a8e1175bSopenharmony_ci                key_usage = PSA_KEY_USAGE_SIGN_HASH |
307a8e1175bSopenharmony_ci                            PSA_KEY_USAGE_SIGN_MESSAGE |
308a8e1175bSopenharmony_ci                            PSA_KEY_USAGE_DECRYPT;
309a8e1175bSopenharmony_ci                break;
310a8e1175bSopenharmony_ci            default:
311a8e1175bSopenharmony_ci                /* Should never happen */
312a8e1175bSopenharmony_ci                return 0;
313a8e1175bSopenharmony_ci        }
314a8e1175bSopenharmony_ci
315a8e1175bSopenharmony_ci        return (key_usage & usage) == usage;
316a8e1175bSopenharmony_ci    }
317a8e1175bSopenharmony_ci
318a8e1175bSopenharmony_ci    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
319a8e1175bSopenharmony_ci    psa_status_t status;
320a8e1175bSopenharmony_ci
321a8e1175bSopenharmony_ci    status = psa_get_key_attributes(ctx->priv_id, &attributes);
322a8e1175bSopenharmony_ci    if (status != PSA_SUCCESS) {
323a8e1175bSopenharmony_ci        return 0;
324a8e1175bSopenharmony_ci    }
325a8e1175bSopenharmony_ci
326a8e1175bSopenharmony_ci    psa_algorithm_t key_alg = psa_get_key_algorithm(&attributes);
327a8e1175bSopenharmony_ci    /* Key's enrollment is available only when an Mbed TLS implementation of PSA
328a8e1175bSopenharmony_ci     * Crypto is being used, i.e. when MBEDTLS_PSA_CRYPTO_C is defined.
329a8e1175bSopenharmony_ci     * Even though we don't officially support using other implementations of PSA
330a8e1175bSopenharmony_ci     * Crypto with TLS and X.509 (yet), we try to keep vendor's customizations
331a8e1175bSopenharmony_ci     * separated. */
332a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_CRYPTO_C)
333a8e1175bSopenharmony_ci    psa_algorithm_t key_alg2 = psa_get_key_enrollment_algorithm(&attributes);
334a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_CRYPTO_C */
335a8e1175bSopenharmony_ci    key_usage = psa_get_key_usage_flags(&attributes);
336a8e1175bSopenharmony_ci    psa_reset_key_attributes(&attributes);
337a8e1175bSopenharmony_ci
338a8e1175bSopenharmony_ci    if ((key_usage & usage) != usage) {
339a8e1175bSopenharmony_ci        return 0;
340a8e1175bSopenharmony_ci    }
341a8e1175bSopenharmony_ci
342a8e1175bSopenharmony_ci    /*
343a8e1175bSopenharmony_ci     * Common case: the key alg [or alg2] only allows alg.
344a8e1175bSopenharmony_ci     * This will match PSA_ALG_RSA_PKCS1V15_CRYPT & PSA_ALG_IS_ECDH
345a8e1175bSopenharmony_ci     * directly.
346a8e1175bSopenharmony_ci     * This would also match ECDSA/RSA_PKCS1V15_SIGN/RSA_PSS with
347a8e1175bSopenharmony_ci     * a fixed hash on key_alg [or key_alg2].
348a8e1175bSopenharmony_ci     */
349a8e1175bSopenharmony_ci    if (alg == key_alg) {
350a8e1175bSopenharmony_ci        return 1;
351a8e1175bSopenharmony_ci    }
352a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_CRYPTO_C)
353a8e1175bSopenharmony_ci    if (alg == key_alg2) {
354a8e1175bSopenharmony_ci        return 1;
355a8e1175bSopenharmony_ci    }
356a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_CRYPTO_C */
357a8e1175bSopenharmony_ci
358a8e1175bSopenharmony_ci    /*
359a8e1175bSopenharmony_ci     * If key_alg [or key_alg2] is a hash-and-sign with a wildcard for the hash,
360a8e1175bSopenharmony_ci     * and alg is the same hash-and-sign family with any hash,
361a8e1175bSopenharmony_ci     * then alg is compliant with this key alg
362a8e1175bSopenharmony_ci     */
363a8e1175bSopenharmony_ci    if (PSA_ALG_IS_SIGN_HASH(alg)) {
364a8e1175bSopenharmony_ci        if (PSA_ALG_IS_SIGN_HASH(key_alg) &&
365a8e1175bSopenharmony_ci            PSA_ALG_SIGN_GET_HASH(key_alg) == PSA_ALG_ANY_HASH &&
366a8e1175bSopenharmony_ci            (alg & ~PSA_ALG_HASH_MASK) == (key_alg & ~PSA_ALG_HASH_MASK)) {
367a8e1175bSopenharmony_ci            return 1;
368a8e1175bSopenharmony_ci        }
369a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_CRYPTO_C)
370a8e1175bSopenharmony_ci        if (PSA_ALG_IS_SIGN_HASH(key_alg2) &&
371a8e1175bSopenharmony_ci            PSA_ALG_SIGN_GET_HASH(key_alg2) == PSA_ALG_ANY_HASH &&
372a8e1175bSopenharmony_ci            (alg & ~PSA_ALG_HASH_MASK) == (key_alg2 & ~PSA_ALG_HASH_MASK)) {
373a8e1175bSopenharmony_ci            return 1;
374a8e1175bSopenharmony_ci        }
375a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_CRYPTO_C */
376a8e1175bSopenharmony_ci    }
377a8e1175bSopenharmony_ci
378a8e1175bSopenharmony_ci    return 0;
379a8e1175bSopenharmony_ci}
380a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
381a8e1175bSopenharmony_ci
382a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
383a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C)
384a8e1175bSopenharmony_cistatic psa_algorithm_t psa_algorithm_for_rsa(const mbedtls_rsa_context *rsa,
385a8e1175bSopenharmony_ci                                             int want_crypt)
386a8e1175bSopenharmony_ci{
387a8e1175bSopenharmony_ci    if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) {
388a8e1175bSopenharmony_ci        if (want_crypt) {
389a8e1175bSopenharmony_ci            mbedtls_md_type_t md_type = (mbedtls_md_type_t) mbedtls_rsa_get_md_alg(rsa);
390a8e1175bSopenharmony_ci            return PSA_ALG_RSA_OAEP(mbedtls_md_psa_alg_from_type(md_type));
391a8e1175bSopenharmony_ci        } else {
392a8e1175bSopenharmony_ci            return PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH);
393a8e1175bSopenharmony_ci        }
394a8e1175bSopenharmony_ci    } else {
395a8e1175bSopenharmony_ci        if (want_crypt) {
396a8e1175bSopenharmony_ci            return PSA_ALG_RSA_PKCS1V15_CRYPT;
397a8e1175bSopenharmony_ci        } else {
398a8e1175bSopenharmony_ci            return PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH);
399a8e1175bSopenharmony_ci        }
400a8e1175bSopenharmony_ci    }
401a8e1175bSopenharmony_ci}
402a8e1175bSopenharmony_ci#endif /* MBEDTLS_RSA_C */
403a8e1175bSopenharmony_ci
404a8e1175bSopenharmony_ciint mbedtls_pk_get_psa_attributes(const mbedtls_pk_context *pk,
405a8e1175bSopenharmony_ci                                  psa_key_usage_t usage,
406a8e1175bSopenharmony_ci                                  psa_key_attributes_t *attributes)
407a8e1175bSopenharmony_ci{
408a8e1175bSopenharmony_ci    mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk);
409a8e1175bSopenharmony_ci
410a8e1175bSopenharmony_ci    psa_key_usage_t more_usage = usage;
411a8e1175bSopenharmony_ci    if (usage == PSA_KEY_USAGE_SIGN_MESSAGE) {
412a8e1175bSopenharmony_ci        more_usage |= PSA_KEY_USAGE_VERIFY_MESSAGE;
413a8e1175bSopenharmony_ci    } else if (usage == PSA_KEY_USAGE_SIGN_HASH) {
414a8e1175bSopenharmony_ci        more_usage |= PSA_KEY_USAGE_VERIFY_HASH;
415a8e1175bSopenharmony_ci    } else if (usage == PSA_KEY_USAGE_DECRYPT) {
416a8e1175bSopenharmony_ci        more_usage |= PSA_KEY_USAGE_ENCRYPT;
417a8e1175bSopenharmony_ci    }
418a8e1175bSopenharmony_ci    more_usage |= PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY;
419a8e1175bSopenharmony_ci
420a8e1175bSopenharmony_ci    int want_private = !(usage == PSA_KEY_USAGE_VERIFY_MESSAGE ||
421a8e1175bSopenharmony_ci                         usage == PSA_KEY_USAGE_VERIFY_HASH ||
422a8e1175bSopenharmony_ci                         usage == PSA_KEY_USAGE_ENCRYPT);
423a8e1175bSopenharmony_ci
424a8e1175bSopenharmony_ci    switch (pk_type) {
425a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C)
426a8e1175bSopenharmony_ci        case MBEDTLS_PK_RSA:
427a8e1175bSopenharmony_ci        {
428a8e1175bSopenharmony_ci            int want_crypt = 0; /* 0: sign/verify; 1: encrypt/decrypt */
429a8e1175bSopenharmony_ci            switch (usage) {
430a8e1175bSopenharmony_ci                case PSA_KEY_USAGE_SIGN_MESSAGE:
431a8e1175bSopenharmony_ci                case PSA_KEY_USAGE_SIGN_HASH:
432a8e1175bSopenharmony_ci                case PSA_KEY_USAGE_VERIFY_MESSAGE:
433a8e1175bSopenharmony_ci                case PSA_KEY_USAGE_VERIFY_HASH:
434a8e1175bSopenharmony_ci                    /* Nothing to do. */
435a8e1175bSopenharmony_ci                    break;
436a8e1175bSopenharmony_ci                case PSA_KEY_USAGE_DECRYPT:
437a8e1175bSopenharmony_ci                case PSA_KEY_USAGE_ENCRYPT:
438a8e1175bSopenharmony_ci                    want_crypt = 1;
439a8e1175bSopenharmony_ci                    break;
440a8e1175bSopenharmony_ci                default:
441a8e1175bSopenharmony_ci                    return MBEDTLS_ERR_PK_TYPE_MISMATCH;
442a8e1175bSopenharmony_ci            }
443a8e1175bSopenharmony_ci            /* Detect the presence of a private key in a way that works both
444a8e1175bSopenharmony_ci             * in CRT and non-CRT configurations. */
445a8e1175bSopenharmony_ci            mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
446a8e1175bSopenharmony_ci            int has_private = (mbedtls_rsa_check_privkey(rsa) == 0);
447a8e1175bSopenharmony_ci            if (want_private && !has_private) {
448a8e1175bSopenharmony_ci                return MBEDTLS_ERR_PK_TYPE_MISMATCH;
449a8e1175bSopenharmony_ci            }
450a8e1175bSopenharmony_ci            psa_set_key_type(attributes, (want_private ?
451a8e1175bSopenharmony_ci                                          PSA_KEY_TYPE_RSA_KEY_PAIR :
452a8e1175bSopenharmony_ci                                          PSA_KEY_TYPE_RSA_PUBLIC_KEY));
453a8e1175bSopenharmony_ci            psa_set_key_bits(attributes, mbedtls_pk_get_bitlen(pk));
454a8e1175bSopenharmony_ci            psa_set_key_algorithm(attributes,
455a8e1175bSopenharmony_ci                                  psa_algorithm_for_rsa(rsa, want_crypt));
456a8e1175bSopenharmony_ci            break;
457a8e1175bSopenharmony_ci        }
458a8e1175bSopenharmony_ci#endif /* MBEDTLS_RSA_C */
459a8e1175bSopenharmony_ci
460a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
461a8e1175bSopenharmony_ci        case MBEDTLS_PK_ECKEY:
462a8e1175bSopenharmony_ci        case MBEDTLS_PK_ECKEY_DH:
463a8e1175bSopenharmony_ci        case MBEDTLS_PK_ECDSA:
464a8e1175bSopenharmony_ci        {
465a8e1175bSopenharmony_ci            int sign_ok = (pk_type != MBEDTLS_PK_ECKEY_DH);
466a8e1175bSopenharmony_ci            int derive_ok = (pk_type != MBEDTLS_PK_ECDSA);
467a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
468a8e1175bSopenharmony_ci            psa_ecc_family_t family = pk->ec_family;
469a8e1175bSopenharmony_ci            size_t bits = pk->ec_bits;
470a8e1175bSopenharmony_ci            int has_private = 0;
471a8e1175bSopenharmony_ci            if (pk->priv_id != MBEDTLS_SVC_KEY_ID_INIT) {
472a8e1175bSopenharmony_ci                has_private = 1;
473a8e1175bSopenharmony_ci            }
474a8e1175bSopenharmony_ci#else
475a8e1175bSopenharmony_ci            const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
476a8e1175bSopenharmony_ci            int has_private = (ec->d.n != 0);
477a8e1175bSopenharmony_ci            size_t bits = 0;
478a8e1175bSopenharmony_ci            psa_ecc_family_t family =
479a8e1175bSopenharmony_ci                mbedtls_ecc_group_to_psa(ec->grp.id, &bits);
480a8e1175bSopenharmony_ci#endif
481a8e1175bSopenharmony_ci            psa_algorithm_t alg = 0;
482a8e1175bSopenharmony_ci            switch (usage) {
483a8e1175bSopenharmony_ci                case PSA_KEY_USAGE_SIGN_MESSAGE:
484a8e1175bSopenharmony_ci                case PSA_KEY_USAGE_SIGN_HASH:
485a8e1175bSopenharmony_ci                case PSA_KEY_USAGE_VERIFY_MESSAGE:
486a8e1175bSopenharmony_ci                case PSA_KEY_USAGE_VERIFY_HASH:
487a8e1175bSopenharmony_ci                    if (!sign_ok) {
488a8e1175bSopenharmony_ci                        return MBEDTLS_ERR_PK_TYPE_MISMATCH;
489a8e1175bSopenharmony_ci                    }
490a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
491a8e1175bSopenharmony_ci                    alg = PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_ANY_HASH);
492a8e1175bSopenharmony_ci#else
493a8e1175bSopenharmony_ci                    alg = PSA_ALG_ECDSA(PSA_ALG_ANY_HASH);
494a8e1175bSopenharmony_ci#endif
495a8e1175bSopenharmony_ci                    break;
496a8e1175bSopenharmony_ci                case PSA_KEY_USAGE_DERIVE:
497a8e1175bSopenharmony_ci                    alg = PSA_ALG_ECDH;
498a8e1175bSopenharmony_ci                    if (!derive_ok) {
499a8e1175bSopenharmony_ci                        return MBEDTLS_ERR_PK_TYPE_MISMATCH;
500a8e1175bSopenharmony_ci                    }
501a8e1175bSopenharmony_ci                    break;
502a8e1175bSopenharmony_ci                default:
503a8e1175bSopenharmony_ci                    return MBEDTLS_ERR_PK_TYPE_MISMATCH;
504a8e1175bSopenharmony_ci            }
505a8e1175bSopenharmony_ci            if (want_private && !has_private) {
506a8e1175bSopenharmony_ci                return MBEDTLS_ERR_PK_TYPE_MISMATCH;
507a8e1175bSopenharmony_ci            }
508a8e1175bSopenharmony_ci            psa_set_key_type(attributes, (want_private ?
509a8e1175bSopenharmony_ci                                          PSA_KEY_TYPE_ECC_KEY_PAIR(family) :
510a8e1175bSopenharmony_ci                                          PSA_KEY_TYPE_ECC_PUBLIC_KEY(family)));
511a8e1175bSopenharmony_ci            psa_set_key_bits(attributes, bits);
512a8e1175bSopenharmony_ci            psa_set_key_algorithm(attributes, alg);
513a8e1175bSopenharmony_ci            break;
514a8e1175bSopenharmony_ci        }
515a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
516a8e1175bSopenharmony_ci
517a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
518a8e1175bSopenharmony_ci        case MBEDTLS_PK_RSA_ALT:
519a8e1175bSopenharmony_ci            return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
520a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
521a8e1175bSopenharmony_ci
522a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
523a8e1175bSopenharmony_ci        case MBEDTLS_PK_OPAQUE:
524a8e1175bSopenharmony_ci        {
525a8e1175bSopenharmony_ci            psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT;
526a8e1175bSopenharmony_ci            psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
527a8e1175bSopenharmony_ci            status = psa_get_key_attributes(pk->priv_id, &old_attributes);
528a8e1175bSopenharmony_ci            if (status != PSA_SUCCESS) {
529a8e1175bSopenharmony_ci                return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
530a8e1175bSopenharmony_ci            }
531a8e1175bSopenharmony_ci            psa_key_type_t old_type = psa_get_key_type(&old_attributes);
532a8e1175bSopenharmony_ci            switch (usage) {
533a8e1175bSopenharmony_ci                case PSA_KEY_USAGE_SIGN_MESSAGE:
534a8e1175bSopenharmony_ci                case PSA_KEY_USAGE_SIGN_HASH:
535a8e1175bSopenharmony_ci                case PSA_KEY_USAGE_VERIFY_MESSAGE:
536a8e1175bSopenharmony_ci                case PSA_KEY_USAGE_VERIFY_HASH:
537a8e1175bSopenharmony_ci                    if (!(PSA_KEY_TYPE_IS_ECC_KEY_PAIR(old_type) ||
538a8e1175bSopenharmony_ci                          old_type == PSA_KEY_TYPE_RSA_KEY_PAIR)) {
539a8e1175bSopenharmony_ci                        return MBEDTLS_ERR_PK_TYPE_MISMATCH;
540a8e1175bSopenharmony_ci                    }
541a8e1175bSopenharmony_ci                    break;
542a8e1175bSopenharmony_ci                case PSA_KEY_USAGE_DECRYPT:
543a8e1175bSopenharmony_ci                case PSA_KEY_USAGE_ENCRYPT:
544a8e1175bSopenharmony_ci                    if (old_type != PSA_KEY_TYPE_RSA_KEY_PAIR) {
545a8e1175bSopenharmony_ci                        return MBEDTLS_ERR_PK_TYPE_MISMATCH;
546a8e1175bSopenharmony_ci                    }
547a8e1175bSopenharmony_ci                    break;
548a8e1175bSopenharmony_ci                case PSA_KEY_USAGE_DERIVE:
549a8e1175bSopenharmony_ci                    if (!(PSA_KEY_TYPE_IS_ECC_KEY_PAIR(old_type))) {
550a8e1175bSopenharmony_ci                        return MBEDTLS_ERR_PK_TYPE_MISMATCH;
551a8e1175bSopenharmony_ci                    }
552a8e1175bSopenharmony_ci                    break;
553a8e1175bSopenharmony_ci                default:
554a8e1175bSopenharmony_ci                    return MBEDTLS_ERR_PK_TYPE_MISMATCH;
555a8e1175bSopenharmony_ci            }
556a8e1175bSopenharmony_ci            psa_key_type_t new_type = old_type;
557a8e1175bSopenharmony_ci            /* Opaque keys are always key pairs, so we don't need a check
558a8e1175bSopenharmony_ci             * on the input if the required usage is private. We just need
559a8e1175bSopenharmony_ci             * to adjust the type correctly if the required usage is public. */
560a8e1175bSopenharmony_ci            if (!want_private) {
561a8e1175bSopenharmony_ci                new_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(new_type);
562a8e1175bSopenharmony_ci            }
563a8e1175bSopenharmony_ci            more_usage = psa_get_key_usage_flags(&old_attributes);
564a8e1175bSopenharmony_ci            if ((usage & more_usage) == 0) {
565a8e1175bSopenharmony_ci                return MBEDTLS_ERR_PK_TYPE_MISMATCH;
566a8e1175bSopenharmony_ci            }
567a8e1175bSopenharmony_ci            psa_set_key_type(attributes, new_type);
568a8e1175bSopenharmony_ci            psa_set_key_bits(attributes, psa_get_key_bits(&old_attributes));
569a8e1175bSopenharmony_ci            psa_set_key_algorithm(attributes, psa_get_key_algorithm(&old_attributes));
570a8e1175bSopenharmony_ci            break;
571a8e1175bSopenharmony_ci        }
572a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
573a8e1175bSopenharmony_ci
574a8e1175bSopenharmony_ci        default:
575a8e1175bSopenharmony_ci            return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
576a8e1175bSopenharmony_ci    }
577a8e1175bSopenharmony_ci
578a8e1175bSopenharmony_ci    psa_set_key_usage_flags(attributes, more_usage);
579a8e1175bSopenharmony_ci    /* Key's enrollment is available only when an Mbed TLS implementation of PSA
580a8e1175bSopenharmony_ci     * Crypto is being used, i.e. when MBEDTLS_PSA_CRYPTO_C is defined.
581a8e1175bSopenharmony_ci     * Even though we don't officially support using other implementations of PSA
582a8e1175bSopenharmony_ci     * Crypto with TLS and X.509 (yet), we try to keep vendor's customizations
583a8e1175bSopenharmony_ci     * separated. */
584a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_CRYPTO_C)
585a8e1175bSopenharmony_ci    psa_set_key_enrollment_algorithm(attributes, PSA_ALG_NONE);
586a8e1175bSopenharmony_ci#endif
587a8e1175bSopenharmony_ci
588a8e1175bSopenharmony_ci    return 0;
589a8e1175bSopenharmony_ci}
590a8e1175bSopenharmony_ci
591a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) || defined(MBEDTLS_USE_PSA_CRYPTO)
592a8e1175bSopenharmony_cistatic psa_status_t export_import_into_psa(mbedtls_svc_key_id_t old_key_id,
593a8e1175bSopenharmony_ci                                           const psa_key_attributes_t *attributes,
594a8e1175bSopenharmony_ci                                           mbedtls_svc_key_id_t *new_key_id)
595a8e1175bSopenharmony_ci{
596a8e1175bSopenharmony_ci    unsigned char key_buffer[PSA_EXPORT_KEY_PAIR_MAX_SIZE];
597a8e1175bSopenharmony_ci    size_t key_length = 0;
598a8e1175bSopenharmony_ci    psa_status_t status = psa_export_key(old_key_id,
599a8e1175bSopenharmony_ci                                         key_buffer, sizeof(key_buffer),
600a8e1175bSopenharmony_ci                                         &key_length);
601a8e1175bSopenharmony_ci    if (status != PSA_SUCCESS) {
602a8e1175bSopenharmony_ci        return status;
603a8e1175bSopenharmony_ci    }
604a8e1175bSopenharmony_ci    status = psa_import_key(attributes, key_buffer, key_length, new_key_id);
605a8e1175bSopenharmony_ci    mbedtls_platform_zeroize(key_buffer, key_length);
606a8e1175bSopenharmony_ci    return status;
607a8e1175bSopenharmony_ci}
608a8e1175bSopenharmony_ci
609a8e1175bSopenharmony_cistatic int copy_into_psa(mbedtls_svc_key_id_t old_key_id,
610a8e1175bSopenharmony_ci                         const psa_key_attributes_t *attributes,
611a8e1175bSopenharmony_ci                         mbedtls_svc_key_id_t *new_key_id)
612a8e1175bSopenharmony_ci{
613a8e1175bSopenharmony_ci    /* Normally, we prefer copying: it's more efficient and works even
614a8e1175bSopenharmony_ci     * for non-exportable keys. */
615a8e1175bSopenharmony_ci    psa_status_t status = psa_copy_key(old_key_id, attributes, new_key_id);
616a8e1175bSopenharmony_ci    if (status == PSA_ERROR_NOT_PERMITTED /*missing COPY usage*/ ||
617a8e1175bSopenharmony_ci        status == PSA_ERROR_INVALID_ARGUMENT /*incompatible policy*/) {
618a8e1175bSopenharmony_ci        /* There are edge cases where copying won't work, but export+import
619a8e1175bSopenharmony_ci         * might:
620a8e1175bSopenharmony_ci         * - If the old key does not allow PSA_KEY_USAGE_COPY.
621a8e1175bSopenharmony_ci         * - If the old key's usage does not allow what attributes wants.
622a8e1175bSopenharmony_ci         *   Because the key was intended for use in the pk module, and may
623a8e1175bSopenharmony_ci         *   have had a policy chosen solely for what pk needs rather than
624a8e1175bSopenharmony_ci         *   based on a detailed understanding of PSA policies, we are a bit
625a8e1175bSopenharmony_ci         *   more liberal than psa_copy_key() here.
626a8e1175bSopenharmony_ci         */
627a8e1175bSopenharmony_ci        /* Here we need to check that the types match, otherwise we risk
628a8e1175bSopenharmony_ci         * importing nonsensical data. */
629a8e1175bSopenharmony_ci        psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT;
630a8e1175bSopenharmony_ci        status = psa_get_key_attributes(old_key_id, &old_attributes);
631a8e1175bSopenharmony_ci        if (status != PSA_SUCCESS) {
632a8e1175bSopenharmony_ci            return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
633a8e1175bSopenharmony_ci        }
634a8e1175bSopenharmony_ci        psa_key_type_t old_type = psa_get_key_type(&old_attributes);
635a8e1175bSopenharmony_ci        psa_reset_key_attributes(&old_attributes);
636a8e1175bSopenharmony_ci        if (old_type != psa_get_key_type(attributes)) {
637a8e1175bSopenharmony_ci            return MBEDTLS_ERR_PK_TYPE_MISMATCH;
638a8e1175bSopenharmony_ci        }
639a8e1175bSopenharmony_ci        status = export_import_into_psa(old_key_id, attributes, new_key_id);
640a8e1175bSopenharmony_ci    }
641a8e1175bSopenharmony_ci    return PSA_PK_TO_MBEDTLS_ERR(status);
642a8e1175bSopenharmony_ci}
643a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_USE_PSA_EC_DATA || MBEDTLS_USE_PSA_CRYPTO */
644a8e1175bSopenharmony_ci
645a8e1175bSopenharmony_cistatic int import_pair_into_psa(const mbedtls_pk_context *pk,
646a8e1175bSopenharmony_ci                                const psa_key_attributes_t *attributes,
647a8e1175bSopenharmony_ci                                mbedtls_svc_key_id_t *key_id)
648a8e1175bSopenharmony_ci{
649a8e1175bSopenharmony_ci    switch (mbedtls_pk_get_type(pk)) {
650a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C)
651a8e1175bSopenharmony_ci        case MBEDTLS_PK_RSA:
652a8e1175bSopenharmony_ci        {
653a8e1175bSopenharmony_ci            if (psa_get_key_type(attributes) != PSA_KEY_TYPE_RSA_KEY_PAIR) {
654a8e1175bSopenharmony_ci                return MBEDTLS_ERR_PK_TYPE_MISMATCH;
655a8e1175bSopenharmony_ci            }
656a8e1175bSopenharmony_ci            unsigned char key_buffer[
657a8e1175bSopenharmony_ci                PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS)];
658a8e1175bSopenharmony_ci            unsigned char *const key_end = key_buffer + sizeof(key_buffer);
659a8e1175bSopenharmony_ci            unsigned char *key_data = key_end;
660a8e1175bSopenharmony_ci            int ret = mbedtls_rsa_write_key(mbedtls_pk_rsa(*pk),
661a8e1175bSopenharmony_ci                                            key_buffer, &key_data);
662a8e1175bSopenharmony_ci            if (ret < 0) {
663a8e1175bSopenharmony_ci                return ret;
664a8e1175bSopenharmony_ci            }
665a8e1175bSopenharmony_ci            size_t key_length = key_end - key_data;
666a8e1175bSopenharmony_ci            ret = PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes,
667a8e1175bSopenharmony_ci                                                       key_data, key_length,
668a8e1175bSopenharmony_ci                                                       key_id));
669a8e1175bSopenharmony_ci            mbedtls_platform_zeroize(key_data, key_length);
670a8e1175bSopenharmony_ci            return ret;
671a8e1175bSopenharmony_ci        }
672a8e1175bSopenharmony_ci#endif /* MBEDTLS_RSA_C */
673a8e1175bSopenharmony_ci
674a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
675a8e1175bSopenharmony_ci        case MBEDTLS_PK_ECKEY:
676a8e1175bSopenharmony_ci        case MBEDTLS_PK_ECKEY_DH:
677a8e1175bSopenharmony_ci        case MBEDTLS_PK_ECDSA:
678a8e1175bSopenharmony_ci        {
679a8e1175bSopenharmony_ci            /* We need to check the curve family, otherwise the import could
680a8e1175bSopenharmony_ci             * succeed with nonsensical data.
681a8e1175bSopenharmony_ci             * We don't check the bit-size: it's optional in attributes,
682a8e1175bSopenharmony_ci             * and if it's specified, psa_import_key() will know from the key
683a8e1175bSopenharmony_ci             * data length and will check that the bit-size matches. */
684a8e1175bSopenharmony_ci            psa_key_type_t to_type = psa_get_key_type(attributes);
685a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
686a8e1175bSopenharmony_ci            psa_ecc_family_t from_family = pk->ec_family;
687a8e1175bSopenharmony_ci#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
688a8e1175bSopenharmony_ci            const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
689a8e1175bSopenharmony_ci            size_t from_bits = 0;
690a8e1175bSopenharmony_ci            psa_ecc_family_t from_family = mbedtls_ecc_group_to_psa(ec->grp.id,
691a8e1175bSopenharmony_ci                                                                    &from_bits);
692a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
693a8e1175bSopenharmony_ci            if (to_type != PSA_KEY_TYPE_ECC_KEY_PAIR(from_family)) {
694a8e1175bSopenharmony_ci                return MBEDTLS_ERR_PK_TYPE_MISMATCH;
695a8e1175bSopenharmony_ci            }
696a8e1175bSopenharmony_ci
697a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
698a8e1175bSopenharmony_ci            if (mbedtls_svc_key_id_is_null(pk->priv_id)) {
699a8e1175bSopenharmony_ci                /* We have a public key and want a key pair. */
700a8e1175bSopenharmony_ci                return MBEDTLS_ERR_PK_TYPE_MISMATCH;
701a8e1175bSopenharmony_ci            }
702a8e1175bSopenharmony_ci            return copy_into_psa(pk->priv_id, attributes, key_id);
703a8e1175bSopenharmony_ci#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
704a8e1175bSopenharmony_ci            if (ec->d.n == 0) {
705a8e1175bSopenharmony_ci                /* Private key not set. Assume the input is a public key only.
706a8e1175bSopenharmony_ci                 * (The other possibility is that it's an incomplete object
707a8e1175bSopenharmony_ci                 * where the group is set but neither the public key nor
708a8e1175bSopenharmony_ci                 * the private key. This is not possible through ecp.h
709a8e1175bSopenharmony_ci                 * functions, so we don't bother reporting a more suitable
710a8e1175bSopenharmony_ci                 * error in that case.) */
711a8e1175bSopenharmony_ci                return MBEDTLS_ERR_PK_TYPE_MISMATCH;
712a8e1175bSopenharmony_ci            }
713a8e1175bSopenharmony_ci            unsigned char key_buffer[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
714a8e1175bSopenharmony_ci            size_t key_length = 0;
715a8e1175bSopenharmony_ci            int ret = mbedtls_ecp_write_key_ext(ec, &key_length,
716a8e1175bSopenharmony_ci                                                key_buffer, sizeof(key_buffer));
717a8e1175bSopenharmony_ci            if (ret < 0) {
718a8e1175bSopenharmony_ci                return ret;
719a8e1175bSopenharmony_ci            }
720a8e1175bSopenharmony_ci            ret = PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes,
721a8e1175bSopenharmony_ci                                                       key_buffer, key_length,
722a8e1175bSopenharmony_ci                                                       key_id));
723a8e1175bSopenharmony_ci            mbedtls_platform_zeroize(key_buffer, key_length);
724a8e1175bSopenharmony_ci            return ret;
725a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
726a8e1175bSopenharmony_ci        }
727a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
728a8e1175bSopenharmony_ci
729a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
730a8e1175bSopenharmony_ci        case MBEDTLS_PK_OPAQUE:
731a8e1175bSopenharmony_ci            return copy_into_psa(pk->priv_id, attributes, key_id);
732a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
733a8e1175bSopenharmony_ci
734a8e1175bSopenharmony_ci        default:
735a8e1175bSopenharmony_ci            return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
736a8e1175bSopenharmony_ci    }
737a8e1175bSopenharmony_ci}
738a8e1175bSopenharmony_ci
739a8e1175bSopenharmony_cistatic int import_public_into_psa(const mbedtls_pk_context *pk,
740a8e1175bSopenharmony_ci                                  const psa_key_attributes_t *attributes,
741a8e1175bSopenharmony_ci                                  mbedtls_svc_key_id_t *key_id)
742a8e1175bSopenharmony_ci{
743a8e1175bSopenharmony_ci    psa_key_type_t psa_type = psa_get_key_type(attributes);
744a8e1175bSopenharmony_ci
745a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C) ||                                           \
746a8e1175bSopenharmony_ci    (defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA)) || \
747a8e1175bSopenharmony_ci    defined(MBEDTLS_USE_PSA_CRYPTO)
748a8e1175bSopenharmony_ci    unsigned char key_buffer[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
749a8e1175bSopenharmony_ci#endif
750a8e1175bSopenharmony_ci    unsigned char *key_data = NULL;
751a8e1175bSopenharmony_ci    size_t key_length = 0;
752a8e1175bSopenharmony_ci
753a8e1175bSopenharmony_ci    switch (mbedtls_pk_get_type(pk)) {
754a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C)
755a8e1175bSopenharmony_ci        case MBEDTLS_PK_RSA:
756a8e1175bSopenharmony_ci        {
757a8e1175bSopenharmony_ci            if (psa_type != PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
758a8e1175bSopenharmony_ci                return MBEDTLS_ERR_PK_TYPE_MISMATCH;
759a8e1175bSopenharmony_ci            }
760a8e1175bSopenharmony_ci            unsigned char *const key_end = key_buffer + sizeof(key_buffer);
761a8e1175bSopenharmony_ci            key_data = key_end;
762a8e1175bSopenharmony_ci            int ret = mbedtls_rsa_write_pubkey(mbedtls_pk_rsa(*pk),
763a8e1175bSopenharmony_ci                                               key_buffer, &key_data);
764a8e1175bSopenharmony_ci            if (ret < 0) {
765a8e1175bSopenharmony_ci                return ret;
766a8e1175bSopenharmony_ci            }
767a8e1175bSopenharmony_ci            key_length = (size_t) ret;
768a8e1175bSopenharmony_ci            break;
769a8e1175bSopenharmony_ci        }
770a8e1175bSopenharmony_ci#endif /*MBEDTLS_RSA_C */
771a8e1175bSopenharmony_ci
772a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
773a8e1175bSopenharmony_ci        case MBEDTLS_PK_ECKEY:
774a8e1175bSopenharmony_ci        case MBEDTLS_PK_ECKEY_DH:
775a8e1175bSopenharmony_ci        case MBEDTLS_PK_ECDSA:
776a8e1175bSopenharmony_ci        {
777a8e1175bSopenharmony_ci            /* We need to check the curve family, otherwise the import could
778a8e1175bSopenharmony_ci             * succeed with nonsensical data.
779a8e1175bSopenharmony_ci             * We don't check the bit-size: it's optional in attributes,
780a8e1175bSopenharmony_ci             * and if it's specified, psa_import_key() will know from the key
781a8e1175bSopenharmony_ci             * data length and will check that the bit-size matches. */
782a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
783a8e1175bSopenharmony_ci            if (psa_type != PSA_KEY_TYPE_ECC_PUBLIC_KEY(pk->ec_family)) {
784a8e1175bSopenharmony_ci                return MBEDTLS_ERR_PK_TYPE_MISMATCH;
785a8e1175bSopenharmony_ci            }
786a8e1175bSopenharmony_ci            key_data = (unsigned char *) pk->pub_raw;
787a8e1175bSopenharmony_ci            key_length = pk->pub_raw_len;
788a8e1175bSopenharmony_ci#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
789a8e1175bSopenharmony_ci            const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
790a8e1175bSopenharmony_ci            size_t from_bits = 0;
791a8e1175bSopenharmony_ci            psa_ecc_family_t from_family = mbedtls_ecc_group_to_psa(ec->grp.id,
792a8e1175bSopenharmony_ci                                                                    &from_bits);
793a8e1175bSopenharmony_ci            if (psa_type != PSA_KEY_TYPE_ECC_PUBLIC_KEY(from_family)) {
794a8e1175bSopenharmony_ci                return MBEDTLS_ERR_PK_TYPE_MISMATCH;
795a8e1175bSopenharmony_ci            }
796a8e1175bSopenharmony_ci            int ret = mbedtls_ecp_write_public_key(
797a8e1175bSopenharmony_ci                ec, MBEDTLS_ECP_PF_UNCOMPRESSED,
798a8e1175bSopenharmony_ci                &key_length, key_buffer, sizeof(key_buffer));
799a8e1175bSopenharmony_ci            if (ret < 0) {
800a8e1175bSopenharmony_ci                return ret;
801a8e1175bSopenharmony_ci            }
802a8e1175bSopenharmony_ci            key_data = key_buffer;
803a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
804a8e1175bSopenharmony_ci            break;
805a8e1175bSopenharmony_ci        }
806a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
807a8e1175bSopenharmony_ci
808a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
809a8e1175bSopenharmony_ci        case MBEDTLS_PK_OPAQUE:
810a8e1175bSopenharmony_ci        {
811a8e1175bSopenharmony_ci            psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT;
812a8e1175bSopenharmony_ci            psa_status_t status =
813a8e1175bSopenharmony_ci                psa_get_key_attributes(pk->priv_id, &old_attributes);
814a8e1175bSopenharmony_ci            if (status != PSA_SUCCESS) {
815a8e1175bSopenharmony_ci                return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
816a8e1175bSopenharmony_ci            }
817a8e1175bSopenharmony_ci            psa_key_type_t old_type = psa_get_key_type(&old_attributes);
818a8e1175bSopenharmony_ci            psa_reset_key_attributes(&old_attributes);
819a8e1175bSopenharmony_ci            if (psa_type != PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(old_type)) {
820a8e1175bSopenharmony_ci                return MBEDTLS_ERR_PK_TYPE_MISMATCH;
821a8e1175bSopenharmony_ci            }
822a8e1175bSopenharmony_ci            status = psa_export_public_key(pk->priv_id,
823a8e1175bSopenharmony_ci                                           key_buffer, sizeof(key_buffer),
824a8e1175bSopenharmony_ci                                           &key_length);
825a8e1175bSopenharmony_ci            if (status != PSA_SUCCESS) {
826a8e1175bSopenharmony_ci                return PSA_PK_TO_MBEDTLS_ERR(status);
827a8e1175bSopenharmony_ci            }
828a8e1175bSopenharmony_ci            key_data = key_buffer;
829a8e1175bSopenharmony_ci            break;
830a8e1175bSopenharmony_ci        }
831a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
832a8e1175bSopenharmony_ci
833a8e1175bSopenharmony_ci        default:
834a8e1175bSopenharmony_ci            return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
835a8e1175bSopenharmony_ci    }
836a8e1175bSopenharmony_ci
837a8e1175bSopenharmony_ci    return PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes,
838a8e1175bSopenharmony_ci                                                key_data, key_length,
839a8e1175bSopenharmony_ci                                                key_id));
840a8e1175bSopenharmony_ci}
841a8e1175bSopenharmony_ci
842a8e1175bSopenharmony_ciint mbedtls_pk_import_into_psa(const mbedtls_pk_context *pk,
843a8e1175bSopenharmony_ci                               const psa_key_attributes_t *attributes,
844a8e1175bSopenharmony_ci                               mbedtls_svc_key_id_t *key_id)
845a8e1175bSopenharmony_ci{
846a8e1175bSopenharmony_ci    /* Set the output immediately so that it won't contain garbage even
847a8e1175bSopenharmony_ci     * if we error out before calling psa_import_key(). */
848a8e1175bSopenharmony_ci    *key_id = MBEDTLS_SVC_KEY_ID_INIT;
849a8e1175bSopenharmony_ci
850a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
851a8e1175bSopenharmony_ci    if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_RSA_ALT) {
852a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
853a8e1175bSopenharmony_ci    }
854a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
855a8e1175bSopenharmony_ci
856a8e1175bSopenharmony_ci    int want_public = PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(attributes));
857a8e1175bSopenharmony_ci    if (want_public) {
858a8e1175bSopenharmony_ci        return import_public_into_psa(pk, attributes, key_id);
859a8e1175bSopenharmony_ci    } else {
860a8e1175bSopenharmony_ci        return import_pair_into_psa(pk, attributes, key_id);
861a8e1175bSopenharmony_ci    }
862a8e1175bSopenharmony_ci}
863a8e1175bSopenharmony_ci
864a8e1175bSopenharmony_cistatic int copy_from_psa(mbedtls_svc_key_id_t key_id,
865a8e1175bSopenharmony_ci                         mbedtls_pk_context *pk,
866a8e1175bSopenharmony_ci                         int public_only)
867a8e1175bSopenharmony_ci{
868a8e1175bSopenharmony_ci    psa_status_t status;
869a8e1175bSopenharmony_ci    psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
870a8e1175bSopenharmony_ci    psa_key_type_t key_type;
871a8e1175bSopenharmony_ci    psa_algorithm_t alg_type;
872a8e1175bSopenharmony_ci    size_t key_bits;
873a8e1175bSopenharmony_ci    /* Use a buffer size large enough to contain either a key pair or public key. */
874a8e1175bSopenharmony_ci    unsigned char exp_key[PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE];
875a8e1175bSopenharmony_ci    size_t exp_key_len;
876a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;
877a8e1175bSopenharmony_ci
878a8e1175bSopenharmony_ci    if (pk == NULL) {
879a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
880a8e1175bSopenharmony_ci    }
881a8e1175bSopenharmony_ci
882a8e1175bSopenharmony_ci    status = psa_get_key_attributes(key_id, &key_attr);
883a8e1175bSopenharmony_ci    if (status != PSA_SUCCESS) {
884a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
885a8e1175bSopenharmony_ci    }
886a8e1175bSopenharmony_ci
887a8e1175bSopenharmony_ci    if (public_only) {
888a8e1175bSopenharmony_ci        status = psa_export_public_key(key_id, exp_key, sizeof(exp_key), &exp_key_len);
889a8e1175bSopenharmony_ci    } else {
890a8e1175bSopenharmony_ci        status = psa_export_key(key_id, exp_key, sizeof(exp_key), &exp_key_len);
891a8e1175bSopenharmony_ci    }
892a8e1175bSopenharmony_ci    if (status != PSA_SUCCESS) {
893a8e1175bSopenharmony_ci        ret = PSA_PK_TO_MBEDTLS_ERR(status);
894a8e1175bSopenharmony_ci        goto exit;
895a8e1175bSopenharmony_ci    }
896a8e1175bSopenharmony_ci
897a8e1175bSopenharmony_ci    key_type = psa_get_key_type(&key_attr);
898a8e1175bSopenharmony_ci    if (public_only) {
899a8e1175bSopenharmony_ci        key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(key_type);
900a8e1175bSopenharmony_ci    }
901a8e1175bSopenharmony_ci    key_bits = psa_get_key_bits(&key_attr);
902a8e1175bSopenharmony_ci    alg_type = psa_get_key_algorithm(&key_attr);
903a8e1175bSopenharmony_ci
904a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C)
905a8e1175bSopenharmony_ci    if ((key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) ||
906a8e1175bSopenharmony_ci        (key_type == PSA_KEY_TYPE_RSA_PUBLIC_KEY)) {
907a8e1175bSopenharmony_ci
908a8e1175bSopenharmony_ci        ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA));
909a8e1175bSopenharmony_ci        if (ret != 0) {
910a8e1175bSopenharmony_ci            goto exit;
911a8e1175bSopenharmony_ci        }
912a8e1175bSopenharmony_ci
913a8e1175bSopenharmony_ci        if (key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
914a8e1175bSopenharmony_ci            ret = mbedtls_rsa_parse_key(mbedtls_pk_rsa(*pk), exp_key, exp_key_len);
915a8e1175bSopenharmony_ci        } else {
916a8e1175bSopenharmony_ci            ret = mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(*pk), exp_key, exp_key_len);
917a8e1175bSopenharmony_ci        }
918a8e1175bSopenharmony_ci        if (ret != 0) {
919a8e1175bSopenharmony_ci            goto exit;
920a8e1175bSopenharmony_ci        }
921a8e1175bSopenharmony_ci
922a8e1175bSopenharmony_ci        mbedtls_md_type_t md_type = MBEDTLS_MD_NONE;
923a8e1175bSopenharmony_ci        if (PSA_ALG_GET_HASH(alg_type) != PSA_ALG_ANY_HASH) {
924a8e1175bSopenharmony_ci            md_type = mbedtls_md_type_from_psa_alg(alg_type);
925a8e1175bSopenharmony_ci        }
926a8e1175bSopenharmony_ci
927a8e1175bSopenharmony_ci        if (PSA_ALG_IS_RSA_OAEP(alg_type) || PSA_ALG_IS_RSA_PSS(alg_type)) {
928a8e1175bSopenharmony_ci            ret = mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk), MBEDTLS_RSA_PKCS_V21, md_type);
929a8e1175bSopenharmony_ci        } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg_type) ||
930a8e1175bSopenharmony_ci                   alg_type == PSA_ALG_RSA_PKCS1V15_CRYPT) {
931a8e1175bSopenharmony_ci            ret = mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk), MBEDTLS_RSA_PKCS_V15, md_type);
932a8e1175bSopenharmony_ci        }
933a8e1175bSopenharmony_ci        if (ret != 0) {
934a8e1175bSopenharmony_ci            goto exit;
935a8e1175bSopenharmony_ci        }
936a8e1175bSopenharmony_ci    } else
937a8e1175bSopenharmony_ci#endif /* MBEDTLS_RSA_C */
938a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
939a8e1175bSopenharmony_ci    if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) ||
940a8e1175bSopenharmony_ci        PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type)) {
941a8e1175bSopenharmony_ci        mbedtls_ecp_group_id grp_id;
942a8e1175bSopenharmony_ci
943a8e1175bSopenharmony_ci        ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY));
944a8e1175bSopenharmony_ci        if (ret != 0) {
945a8e1175bSopenharmony_ci            goto exit;
946a8e1175bSopenharmony_ci        }
947a8e1175bSopenharmony_ci
948a8e1175bSopenharmony_ci        grp_id = mbedtls_ecc_group_from_psa(PSA_KEY_TYPE_ECC_GET_FAMILY(key_type), key_bits);
949a8e1175bSopenharmony_ci        ret = mbedtls_pk_ecc_set_group(pk, grp_id);
950a8e1175bSopenharmony_ci        if (ret != 0) {
951a8e1175bSopenharmony_ci            goto exit;
952a8e1175bSopenharmony_ci        }
953a8e1175bSopenharmony_ci
954a8e1175bSopenharmony_ci        if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type)) {
955a8e1175bSopenharmony_ci            ret = mbedtls_pk_ecc_set_key(pk, exp_key, exp_key_len);
956a8e1175bSopenharmony_ci            if (ret != 0) {
957a8e1175bSopenharmony_ci                goto exit;
958a8e1175bSopenharmony_ci            }
959a8e1175bSopenharmony_ci            ret = mbedtls_pk_ecc_set_pubkey_from_prv(pk, exp_key, exp_key_len,
960a8e1175bSopenharmony_ci                                                     mbedtls_psa_get_random,
961a8e1175bSopenharmony_ci                                                     MBEDTLS_PSA_RANDOM_STATE);
962a8e1175bSopenharmony_ci        } else {
963a8e1175bSopenharmony_ci            ret = mbedtls_pk_ecc_set_pubkey(pk, exp_key, exp_key_len);
964a8e1175bSopenharmony_ci        }
965a8e1175bSopenharmony_ci        if (ret != 0) {
966a8e1175bSopenharmony_ci            goto exit;
967a8e1175bSopenharmony_ci        }
968a8e1175bSopenharmony_ci    } else
969a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
970a8e1175bSopenharmony_ci    {
971a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
972a8e1175bSopenharmony_ci    }
973a8e1175bSopenharmony_ci
974a8e1175bSopenharmony_ciexit:
975a8e1175bSopenharmony_ci    psa_reset_key_attributes(&key_attr);
976a8e1175bSopenharmony_ci    mbedtls_platform_zeroize(exp_key, sizeof(exp_key));
977a8e1175bSopenharmony_ci
978a8e1175bSopenharmony_ci    return ret;
979a8e1175bSopenharmony_ci}
980a8e1175bSopenharmony_ci
981a8e1175bSopenharmony_ciint mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id,
982a8e1175bSopenharmony_ci                             mbedtls_pk_context *pk)
983a8e1175bSopenharmony_ci{
984a8e1175bSopenharmony_ci    return copy_from_psa(key_id, pk, 0);
985a8e1175bSopenharmony_ci}
986a8e1175bSopenharmony_ci
987a8e1175bSopenharmony_ciint mbedtls_pk_copy_public_from_psa(mbedtls_svc_key_id_t key_id,
988a8e1175bSopenharmony_ci                                    mbedtls_pk_context *pk)
989a8e1175bSopenharmony_ci{
990a8e1175bSopenharmony_ci    return copy_from_psa(key_id, pk, 1);
991a8e1175bSopenharmony_ci}
992a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
993a8e1175bSopenharmony_ci
994a8e1175bSopenharmony_ci/*
995a8e1175bSopenharmony_ci * Helper for mbedtls_pk_sign and mbedtls_pk_verify
996a8e1175bSopenharmony_ci */
997a8e1175bSopenharmony_cistatic inline int pk_hashlen_helper(mbedtls_md_type_t md_alg, size_t *hash_len)
998a8e1175bSopenharmony_ci{
999a8e1175bSopenharmony_ci    if (*hash_len != 0) {
1000a8e1175bSopenharmony_ci        return 0;
1001a8e1175bSopenharmony_ci    }
1002a8e1175bSopenharmony_ci
1003a8e1175bSopenharmony_ci    *hash_len = mbedtls_md_get_size_from_type(md_alg);
1004a8e1175bSopenharmony_ci
1005a8e1175bSopenharmony_ci    if (*hash_len == 0) {
1006a8e1175bSopenharmony_ci        return -1;
1007a8e1175bSopenharmony_ci    }
1008a8e1175bSopenharmony_ci
1009a8e1175bSopenharmony_ci    return 0;
1010a8e1175bSopenharmony_ci}
1011a8e1175bSopenharmony_ci
1012a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
1013a8e1175bSopenharmony_ci/*
1014a8e1175bSopenharmony_ci * Helper to set up a restart context if needed
1015a8e1175bSopenharmony_ci */
1016a8e1175bSopenharmony_cistatic int pk_restart_setup(mbedtls_pk_restart_ctx *ctx,
1017a8e1175bSopenharmony_ci                            const mbedtls_pk_info_t *info)
1018a8e1175bSopenharmony_ci{
1019a8e1175bSopenharmony_ci    /* Don't do anything if already set up or invalid */
1020a8e1175bSopenharmony_ci    if (ctx == NULL || ctx->pk_info != NULL) {
1021a8e1175bSopenharmony_ci        return 0;
1022a8e1175bSopenharmony_ci    }
1023a8e1175bSopenharmony_ci
1024a8e1175bSopenharmony_ci    /* Should never happen when we're called */
1025a8e1175bSopenharmony_ci    if (info->rs_alloc_func == NULL || info->rs_free_func == NULL) {
1026a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1027a8e1175bSopenharmony_ci    }
1028a8e1175bSopenharmony_ci
1029a8e1175bSopenharmony_ci    if ((ctx->rs_ctx = info->rs_alloc_func()) == NULL) {
1030a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_ALLOC_FAILED;
1031a8e1175bSopenharmony_ci    }
1032a8e1175bSopenharmony_ci
1033a8e1175bSopenharmony_ci    ctx->pk_info = info;
1034a8e1175bSopenharmony_ci
1035a8e1175bSopenharmony_ci    return 0;
1036a8e1175bSopenharmony_ci}
1037a8e1175bSopenharmony_ci#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
1038a8e1175bSopenharmony_ci
1039a8e1175bSopenharmony_ci/*
1040a8e1175bSopenharmony_ci * Verify a signature (restartable)
1041a8e1175bSopenharmony_ci */
1042a8e1175bSopenharmony_ciint mbedtls_pk_verify_restartable(mbedtls_pk_context *ctx,
1043a8e1175bSopenharmony_ci                                  mbedtls_md_type_t md_alg,
1044a8e1175bSopenharmony_ci                                  const unsigned char *hash, size_t hash_len,
1045a8e1175bSopenharmony_ci                                  const unsigned char *sig, size_t sig_len,
1046a8e1175bSopenharmony_ci                                  mbedtls_pk_restart_ctx *rs_ctx)
1047a8e1175bSopenharmony_ci{
1048a8e1175bSopenharmony_ci    if ((md_alg != MBEDTLS_MD_NONE || hash_len != 0) && hash == NULL) {
1049a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1050a8e1175bSopenharmony_ci    }
1051a8e1175bSopenharmony_ci
1052a8e1175bSopenharmony_ci    if (ctx->pk_info == NULL ||
1053a8e1175bSopenharmony_ci        pk_hashlen_helper(md_alg, &hash_len) != 0) {
1054a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1055a8e1175bSopenharmony_ci    }
1056a8e1175bSopenharmony_ci
1057a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
1058a8e1175bSopenharmony_ci    /* optimization: use non-restartable version if restart disabled */
1059a8e1175bSopenharmony_ci    if (rs_ctx != NULL &&
1060a8e1175bSopenharmony_ci        mbedtls_ecp_restart_is_enabled() &&
1061a8e1175bSopenharmony_ci        ctx->pk_info->verify_rs_func != NULL) {
1062a8e1175bSopenharmony_ci        int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1063a8e1175bSopenharmony_ci
1064a8e1175bSopenharmony_ci        if ((ret = pk_restart_setup(rs_ctx, ctx->pk_info)) != 0) {
1065a8e1175bSopenharmony_ci            return ret;
1066a8e1175bSopenharmony_ci        }
1067a8e1175bSopenharmony_ci
1068a8e1175bSopenharmony_ci        ret = ctx->pk_info->verify_rs_func(ctx,
1069a8e1175bSopenharmony_ci                                           md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx);
1070a8e1175bSopenharmony_ci
1071a8e1175bSopenharmony_ci        if (ret != MBEDTLS_ERR_ECP_IN_PROGRESS) {
1072a8e1175bSopenharmony_ci            mbedtls_pk_restart_free(rs_ctx);
1073a8e1175bSopenharmony_ci        }
1074a8e1175bSopenharmony_ci
1075a8e1175bSopenharmony_ci        return ret;
1076a8e1175bSopenharmony_ci    }
1077a8e1175bSopenharmony_ci#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
1078a8e1175bSopenharmony_ci    (void) rs_ctx;
1079a8e1175bSopenharmony_ci#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
1080a8e1175bSopenharmony_ci
1081a8e1175bSopenharmony_ci    if (ctx->pk_info->verify_func == NULL) {
1082a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_TYPE_MISMATCH;
1083a8e1175bSopenharmony_ci    }
1084a8e1175bSopenharmony_ci
1085a8e1175bSopenharmony_ci    return ctx->pk_info->verify_func(ctx, md_alg, hash, hash_len,
1086a8e1175bSopenharmony_ci                                     sig, sig_len);
1087a8e1175bSopenharmony_ci}
1088a8e1175bSopenharmony_ci
1089a8e1175bSopenharmony_ci/*
1090a8e1175bSopenharmony_ci * Verify a signature
1091a8e1175bSopenharmony_ci */
1092a8e1175bSopenharmony_ciint mbedtls_pk_verify(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
1093a8e1175bSopenharmony_ci                      const unsigned char *hash, size_t hash_len,
1094a8e1175bSopenharmony_ci                      const unsigned char *sig, size_t sig_len)
1095a8e1175bSopenharmony_ci{
1096a8e1175bSopenharmony_ci    return mbedtls_pk_verify_restartable(ctx, md_alg, hash, hash_len,
1097a8e1175bSopenharmony_ci                                         sig, sig_len, NULL);
1098a8e1175bSopenharmony_ci}
1099a8e1175bSopenharmony_ci
1100a8e1175bSopenharmony_ci/*
1101a8e1175bSopenharmony_ci * Verify a signature with options
1102a8e1175bSopenharmony_ci */
1103a8e1175bSopenharmony_ciint mbedtls_pk_verify_ext(mbedtls_pk_type_t type, const void *options,
1104a8e1175bSopenharmony_ci                          mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
1105a8e1175bSopenharmony_ci                          const unsigned char *hash, size_t hash_len,
1106a8e1175bSopenharmony_ci                          const unsigned char *sig, size_t sig_len)
1107a8e1175bSopenharmony_ci{
1108a8e1175bSopenharmony_ci    if ((md_alg != MBEDTLS_MD_NONE || hash_len != 0) && hash == NULL) {
1109a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1110a8e1175bSopenharmony_ci    }
1111a8e1175bSopenharmony_ci
1112a8e1175bSopenharmony_ci    if (ctx->pk_info == NULL) {
1113a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1114a8e1175bSopenharmony_ci    }
1115a8e1175bSopenharmony_ci
1116a8e1175bSopenharmony_ci    if (!mbedtls_pk_can_do(ctx, type)) {
1117a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_TYPE_MISMATCH;
1118a8e1175bSopenharmony_ci    }
1119a8e1175bSopenharmony_ci
1120a8e1175bSopenharmony_ci    if (type != MBEDTLS_PK_RSASSA_PSS) {
1121a8e1175bSopenharmony_ci        /* General case: no options */
1122a8e1175bSopenharmony_ci        if (options != NULL) {
1123a8e1175bSopenharmony_ci            return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1124a8e1175bSopenharmony_ci        }
1125a8e1175bSopenharmony_ci
1126a8e1175bSopenharmony_ci        return mbedtls_pk_verify(ctx, md_alg, hash, hash_len, sig, sig_len);
1127a8e1175bSopenharmony_ci    }
1128a8e1175bSopenharmony_ci
1129a8e1175bSopenharmony_ci    /* Ensure the PK context is of the right type otherwise mbedtls_pk_rsa()
1130a8e1175bSopenharmony_ci     * below would return a NULL pointer. */
1131a8e1175bSopenharmony_ci    if (mbedtls_pk_get_type(ctx) != MBEDTLS_PK_RSA) {
1132a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
1133a8e1175bSopenharmony_ci    }
1134a8e1175bSopenharmony_ci
1135a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
1136a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1137a8e1175bSopenharmony_ci    const mbedtls_pk_rsassa_pss_options *pss_opts;
1138a8e1175bSopenharmony_ci
1139a8e1175bSopenharmony_ci#if SIZE_MAX > UINT_MAX
1140a8e1175bSopenharmony_ci    if (md_alg == MBEDTLS_MD_NONE && (int)UINT_MAX < (int)hash_len) {
1141a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1142a8e1175bSopenharmony_ci    }
1143a8e1175bSopenharmony_ci#endif
1144a8e1175bSopenharmony_ci
1145a8e1175bSopenharmony_ci    if (options == NULL) {
1146a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1147a8e1175bSopenharmony_ci    }
1148a8e1175bSopenharmony_ci
1149a8e1175bSopenharmony_ci    pss_opts = (const mbedtls_pk_rsassa_pss_options *) options;
1150a8e1175bSopenharmony_ci
1151a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1152a8e1175bSopenharmony_ci    if (pss_opts->mgf1_hash_id == md_alg) {
1153a8e1175bSopenharmony_ci        unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES];
1154a8e1175bSopenharmony_ci        unsigned char *p;
1155a8e1175bSopenharmony_ci        int key_len;
1156a8e1175bSopenharmony_ci        size_t signature_length;
1157a8e1175bSopenharmony_ci        psa_status_t status = PSA_ERROR_DATA_CORRUPT;
1158a8e1175bSopenharmony_ci        psa_status_t destruction_status = PSA_ERROR_DATA_CORRUPT;
1159a8e1175bSopenharmony_ci
1160a8e1175bSopenharmony_ci        psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
1161a8e1175bSopenharmony_ci        mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
1162a8e1175bSopenharmony_ci        psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1163a8e1175bSopenharmony_ci        psa_algorithm_t psa_sig_alg = PSA_ALG_RSA_PSS_ANY_SALT(psa_md_alg);
1164a8e1175bSopenharmony_ci        p = buf + sizeof(buf);
1165a8e1175bSopenharmony_ci        key_len = mbedtls_rsa_write_pubkey(mbedtls_pk_rsa(*ctx), buf, &p);
1166a8e1175bSopenharmony_ci
1167a8e1175bSopenharmony_ci        if (key_len < 0) {
1168a8e1175bSopenharmony_ci            return key_len;
1169a8e1175bSopenharmony_ci        }
1170a8e1175bSopenharmony_ci
1171a8e1175bSopenharmony_ci        psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY);
1172a8e1175bSopenharmony_ci        psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH);
1173a8e1175bSopenharmony_ci        psa_set_key_algorithm(&attributes, psa_sig_alg);
1174a8e1175bSopenharmony_ci
1175a8e1175bSopenharmony_ci        status = psa_import_key(&attributes,
1176a8e1175bSopenharmony_ci                                buf + sizeof(buf) - key_len, key_len,
1177a8e1175bSopenharmony_ci                                &key_id);
1178a8e1175bSopenharmony_ci        if (status != PSA_SUCCESS) {
1179a8e1175bSopenharmony_ci            psa_destroy_key(key_id);
1180a8e1175bSopenharmony_ci            return PSA_PK_TO_MBEDTLS_ERR(status);
1181a8e1175bSopenharmony_ci        }
1182a8e1175bSopenharmony_ci
1183a8e1175bSopenharmony_ci        /* This function requires returning MBEDTLS_ERR_PK_SIG_LEN_MISMATCH
1184a8e1175bSopenharmony_ci         * on a valid signature with trailing data in a buffer, but
1185a8e1175bSopenharmony_ci         * mbedtls_psa_rsa_verify_hash requires the sig_len to be exact,
1186a8e1175bSopenharmony_ci         * so for this reason the passed sig_len is overwritten. Smaller
1187a8e1175bSopenharmony_ci         * signature lengths should not be accepted for verification. */
1188a8e1175bSopenharmony_ci        signature_length = sig_len > mbedtls_pk_get_len(ctx) ?
1189a8e1175bSopenharmony_ci                           mbedtls_pk_get_len(ctx) : sig_len;
1190a8e1175bSopenharmony_ci        status = psa_verify_hash(key_id, psa_sig_alg, hash,
1191a8e1175bSopenharmony_ci                                 hash_len, sig, signature_length);
1192a8e1175bSopenharmony_ci        destruction_status = psa_destroy_key(key_id);
1193a8e1175bSopenharmony_ci
1194a8e1175bSopenharmony_ci        if (status == PSA_SUCCESS && sig_len > mbedtls_pk_get_len(ctx)) {
1195a8e1175bSopenharmony_ci            return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
1196a8e1175bSopenharmony_ci        }
1197a8e1175bSopenharmony_ci
1198a8e1175bSopenharmony_ci        if (status == PSA_SUCCESS) {
1199a8e1175bSopenharmony_ci            status = destruction_status;
1200a8e1175bSopenharmony_ci        }
1201a8e1175bSopenharmony_ci
1202a8e1175bSopenharmony_ci        return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
1203a8e1175bSopenharmony_ci    } else
1204a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
1205a8e1175bSopenharmony_ci    {
1206a8e1175bSopenharmony_ci        if (sig_len < mbedtls_pk_get_len(ctx)) {
1207a8e1175bSopenharmony_ci            return MBEDTLS_ERR_RSA_VERIFY_FAILED;
1208a8e1175bSopenharmony_ci        }
1209a8e1175bSopenharmony_ci
1210a8e1175bSopenharmony_ci        ret = mbedtls_rsa_rsassa_pss_verify_ext(mbedtls_pk_rsa(*ctx),
1211a8e1175bSopenharmony_ci                                                md_alg, (unsigned int) hash_len, hash,
1212a8e1175bSopenharmony_ci                                                pss_opts->mgf1_hash_id,
1213a8e1175bSopenharmony_ci                                                pss_opts->expected_salt_len,
1214a8e1175bSopenharmony_ci                                                sig);
1215a8e1175bSopenharmony_ci        if (ret != 0) {
1216a8e1175bSopenharmony_ci            return ret;
1217a8e1175bSopenharmony_ci        }
1218a8e1175bSopenharmony_ci
1219a8e1175bSopenharmony_ci        if (sig_len > mbedtls_pk_get_len(ctx)) {
1220a8e1175bSopenharmony_ci            return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
1221a8e1175bSopenharmony_ci        }
1222a8e1175bSopenharmony_ci
1223a8e1175bSopenharmony_ci        return 0;
1224a8e1175bSopenharmony_ci    }
1225a8e1175bSopenharmony_ci#else
1226a8e1175bSopenharmony_ci    return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
1227a8e1175bSopenharmony_ci#endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */
1228a8e1175bSopenharmony_ci}
1229a8e1175bSopenharmony_ci
1230a8e1175bSopenharmony_ci/*
1231a8e1175bSopenharmony_ci * Make a signature (restartable)
1232a8e1175bSopenharmony_ci */
1233a8e1175bSopenharmony_ciint mbedtls_pk_sign_restartable(mbedtls_pk_context *ctx,
1234a8e1175bSopenharmony_ci                                mbedtls_md_type_t md_alg,
1235a8e1175bSopenharmony_ci                                const unsigned char *hash, size_t hash_len,
1236a8e1175bSopenharmony_ci                                unsigned char *sig, size_t sig_size, size_t *sig_len,
1237a8e1175bSopenharmony_ci                                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
1238a8e1175bSopenharmony_ci                                mbedtls_pk_restart_ctx *rs_ctx)
1239a8e1175bSopenharmony_ci{
1240a8e1175bSopenharmony_ci    if ((md_alg != MBEDTLS_MD_NONE || hash_len != 0) && hash == NULL) {
1241a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1242a8e1175bSopenharmony_ci    }
1243a8e1175bSopenharmony_ci
1244a8e1175bSopenharmony_ci    if (ctx->pk_info == NULL || pk_hashlen_helper(md_alg, &hash_len) != 0) {
1245a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1246a8e1175bSopenharmony_ci    }
1247a8e1175bSopenharmony_ci
1248a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
1249a8e1175bSopenharmony_ci    /* optimization: use non-restartable version if restart disabled */
1250a8e1175bSopenharmony_ci    if (rs_ctx != NULL &&
1251a8e1175bSopenharmony_ci        mbedtls_ecp_restart_is_enabled() &&
1252a8e1175bSopenharmony_ci        ctx->pk_info->sign_rs_func != NULL) {
1253a8e1175bSopenharmony_ci        int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1254a8e1175bSopenharmony_ci
1255a8e1175bSopenharmony_ci        if ((ret = pk_restart_setup(rs_ctx, ctx->pk_info)) != 0) {
1256a8e1175bSopenharmony_ci            return ret;
1257a8e1175bSopenharmony_ci        }
1258a8e1175bSopenharmony_ci
1259a8e1175bSopenharmony_ci        ret = ctx->pk_info->sign_rs_func(ctx, md_alg,
1260a8e1175bSopenharmony_ci                                         hash, hash_len,
1261a8e1175bSopenharmony_ci                                         sig, sig_size, sig_len,
1262a8e1175bSopenharmony_ci                                         f_rng, p_rng, rs_ctx->rs_ctx);
1263a8e1175bSopenharmony_ci
1264a8e1175bSopenharmony_ci        if (ret != MBEDTLS_ERR_ECP_IN_PROGRESS) {
1265a8e1175bSopenharmony_ci            mbedtls_pk_restart_free(rs_ctx);
1266a8e1175bSopenharmony_ci        }
1267a8e1175bSopenharmony_ci
1268a8e1175bSopenharmony_ci        return ret;
1269a8e1175bSopenharmony_ci    }
1270a8e1175bSopenharmony_ci#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
1271a8e1175bSopenharmony_ci    (void) rs_ctx;
1272a8e1175bSopenharmony_ci#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
1273a8e1175bSopenharmony_ci
1274a8e1175bSopenharmony_ci    if (ctx->pk_info->sign_func == NULL) {
1275a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_TYPE_MISMATCH;
1276a8e1175bSopenharmony_ci    }
1277a8e1175bSopenharmony_ci
1278a8e1175bSopenharmony_ci    return ctx->pk_info->sign_func(ctx, md_alg,
1279a8e1175bSopenharmony_ci                                   hash, hash_len,
1280a8e1175bSopenharmony_ci                                   sig, sig_size, sig_len,
1281a8e1175bSopenharmony_ci                                   f_rng, p_rng);
1282a8e1175bSopenharmony_ci}
1283a8e1175bSopenharmony_ci
1284a8e1175bSopenharmony_ci/*
1285a8e1175bSopenharmony_ci * Make a signature
1286a8e1175bSopenharmony_ci */
1287a8e1175bSopenharmony_ciint mbedtls_pk_sign(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
1288a8e1175bSopenharmony_ci                    const unsigned char *hash, size_t hash_len,
1289a8e1175bSopenharmony_ci                    unsigned char *sig, size_t sig_size, size_t *sig_len,
1290a8e1175bSopenharmony_ci                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
1291a8e1175bSopenharmony_ci{
1292a8e1175bSopenharmony_ci    return mbedtls_pk_sign_restartable(ctx, md_alg, hash, hash_len,
1293a8e1175bSopenharmony_ci                                       sig, sig_size, sig_len,
1294a8e1175bSopenharmony_ci                                       f_rng, p_rng, NULL);
1295a8e1175bSopenharmony_ci}
1296a8e1175bSopenharmony_ci
1297a8e1175bSopenharmony_ci/*
1298a8e1175bSopenharmony_ci * Make a signature given a signature type.
1299a8e1175bSopenharmony_ci */
1300a8e1175bSopenharmony_ciint mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type,
1301a8e1175bSopenharmony_ci                        mbedtls_pk_context *ctx,
1302a8e1175bSopenharmony_ci                        mbedtls_md_type_t md_alg,
1303a8e1175bSopenharmony_ci                        const unsigned char *hash, size_t hash_len,
1304a8e1175bSopenharmony_ci                        unsigned char *sig, size_t sig_size, size_t *sig_len,
1305a8e1175bSopenharmony_ci                        int (*f_rng)(void *, unsigned char *, size_t),
1306a8e1175bSopenharmony_ci                        void *p_rng)
1307a8e1175bSopenharmony_ci{
1308a8e1175bSopenharmony_ci    if (ctx->pk_info == NULL) {
1309a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1310a8e1175bSopenharmony_ci    }
1311a8e1175bSopenharmony_ci
1312a8e1175bSopenharmony_ci    if (!mbedtls_pk_can_do(ctx, pk_type)) {
1313a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_TYPE_MISMATCH;
1314a8e1175bSopenharmony_ci    }
1315a8e1175bSopenharmony_ci
1316a8e1175bSopenharmony_ci    if (pk_type != MBEDTLS_PK_RSASSA_PSS) {
1317a8e1175bSopenharmony_ci        return mbedtls_pk_sign(ctx, md_alg, hash, hash_len,
1318a8e1175bSopenharmony_ci                               sig, sig_size, sig_len, f_rng, p_rng);
1319a8e1175bSopenharmony_ci    }
1320a8e1175bSopenharmony_ci
1321a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
1322a8e1175bSopenharmony_ci
1323a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1324a8e1175bSopenharmony_ci    const psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
1325a8e1175bSopenharmony_ci    if (psa_md_alg == 0) {
1326a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1327a8e1175bSopenharmony_ci    }
1328a8e1175bSopenharmony_ci
1329a8e1175bSopenharmony_ci    if (mbedtls_pk_get_type(ctx) == MBEDTLS_PK_OPAQUE) {
1330a8e1175bSopenharmony_ci        psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
1331a8e1175bSopenharmony_ci        psa_algorithm_t psa_alg, sign_alg;
1332a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_CRYPTO_C)
1333a8e1175bSopenharmony_ci        psa_algorithm_t psa_enrollment_alg;
1334a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_CRYPTO_C */
1335a8e1175bSopenharmony_ci        psa_status_t status;
1336a8e1175bSopenharmony_ci
1337a8e1175bSopenharmony_ci        status = psa_get_key_attributes(ctx->priv_id, &key_attr);
1338a8e1175bSopenharmony_ci        if (status != PSA_SUCCESS) {
1339a8e1175bSopenharmony_ci            return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
1340a8e1175bSopenharmony_ci        }
1341a8e1175bSopenharmony_ci        psa_alg = psa_get_key_algorithm(&key_attr);
1342a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_CRYPTO_C)
1343a8e1175bSopenharmony_ci        psa_enrollment_alg = psa_get_key_enrollment_algorithm(&key_attr);
1344a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_CRYPTO_C */
1345a8e1175bSopenharmony_ci        psa_reset_key_attributes(&key_attr);
1346a8e1175bSopenharmony_ci
1347a8e1175bSopenharmony_ci        /* Since we're PK type is MBEDTLS_PK_RSASSA_PSS at least one between
1348a8e1175bSopenharmony_ci         * alg and enrollment alg should be of type RSA_PSS. */
1349a8e1175bSopenharmony_ci        if (PSA_ALG_IS_RSA_PSS(psa_alg)) {
1350a8e1175bSopenharmony_ci            sign_alg = psa_alg;
1351a8e1175bSopenharmony_ci        }
1352a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_CRYPTO_C)
1353a8e1175bSopenharmony_ci        else if (PSA_ALG_IS_RSA_PSS(psa_enrollment_alg)) {
1354a8e1175bSopenharmony_ci            sign_alg = psa_enrollment_alg;
1355a8e1175bSopenharmony_ci        }
1356a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_CRYPTO_C */
1357a8e1175bSopenharmony_ci        else {
1358a8e1175bSopenharmony_ci            /* The opaque key has no RSA PSS algorithm associated. */
1359a8e1175bSopenharmony_ci            return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1360a8e1175bSopenharmony_ci        }
1361a8e1175bSopenharmony_ci        /* Adjust the hashing algorithm. */
1362a8e1175bSopenharmony_ci        sign_alg = (sign_alg & ~PSA_ALG_HASH_MASK) | PSA_ALG_GET_HASH(psa_md_alg);
1363a8e1175bSopenharmony_ci
1364a8e1175bSopenharmony_ci        status = psa_sign_hash(ctx->priv_id, sign_alg,
1365a8e1175bSopenharmony_ci                               hash, hash_len,
1366a8e1175bSopenharmony_ci                               sig, sig_size, sig_len);
1367a8e1175bSopenharmony_ci        return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
1368a8e1175bSopenharmony_ci    }
1369a8e1175bSopenharmony_ci
1370a8e1175bSopenharmony_ci    return mbedtls_pk_psa_rsa_sign_ext(PSA_ALG_RSA_PSS(psa_md_alg),
1371a8e1175bSopenharmony_ci                                       ctx->pk_ctx, hash, hash_len,
1372a8e1175bSopenharmony_ci                                       sig, sig_size, sig_len);
1373a8e1175bSopenharmony_ci#else /* MBEDTLS_USE_PSA_CRYPTO */
1374a8e1175bSopenharmony_ci
1375a8e1175bSopenharmony_ci    if (sig_size < mbedtls_pk_get_len(ctx)) {
1376a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
1377a8e1175bSopenharmony_ci    }
1378a8e1175bSopenharmony_ci
1379a8e1175bSopenharmony_ci    if (pk_hashlen_helper(md_alg, &hash_len) != 0) {
1380a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1381a8e1175bSopenharmony_ci    }
1382a8e1175bSopenharmony_ci
1383a8e1175bSopenharmony_ci    mbedtls_rsa_context *const rsa_ctx = mbedtls_pk_rsa(*ctx);
1384a8e1175bSopenharmony_ci
1385a8e1175bSopenharmony_ci    const int ret = mbedtls_rsa_rsassa_pss_sign_no_mode_check(rsa_ctx, f_rng, p_rng, md_alg,
1386a8e1175bSopenharmony_ci                                                              (unsigned int) hash_len, hash, sig);
1387a8e1175bSopenharmony_ci    if (ret == 0) {
1388a8e1175bSopenharmony_ci        *sig_len = rsa_ctx->len;
1389a8e1175bSopenharmony_ci    }
1390a8e1175bSopenharmony_ci    return ret;
1391a8e1175bSopenharmony_ci
1392a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
1393a8e1175bSopenharmony_ci
1394a8e1175bSopenharmony_ci#else
1395a8e1175bSopenharmony_ci    return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
1396a8e1175bSopenharmony_ci#endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */
1397a8e1175bSopenharmony_ci}
1398a8e1175bSopenharmony_ci
1399a8e1175bSopenharmony_ci/*
1400a8e1175bSopenharmony_ci * Decrypt message
1401a8e1175bSopenharmony_ci */
1402a8e1175bSopenharmony_ciint mbedtls_pk_decrypt(mbedtls_pk_context *ctx,
1403a8e1175bSopenharmony_ci                       const unsigned char *input, size_t ilen,
1404a8e1175bSopenharmony_ci                       unsigned char *output, size_t *olen, size_t osize,
1405a8e1175bSopenharmony_ci                       int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
1406a8e1175bSopenharmony_ci{
1407a8e1175bSopenharmony_ci    if (ctx->pk_info == NULL) {
1408a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1409a8e1175bSopenharmony_ci    }
1410a8e1175bSopenharmony_ci
1411a8e1175bSopenharmony_ci    if (ctx->pk_info->decrypt_func == NULL) {
1412a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_TYPE_MISMATCH;
1413a8e1175bSopenharmony_ci    }
1414a8e1175bSopenharmony_ci
1415a8e1175bSopenharmony_ci    return ctx->pk_info->decrypt_func(ctx, input, ilen,
1416a8e1175bSopenharmony_ci                                      output, olen, osize, f_rng, p_rng);
1417a8e1175bSopenharmony_ci}
1418a8e1175bSopenharmony_ci
1419a8e1175bSopenharmony_ci/*
1420a8e1175bSopenharmony_ci * Encrypt message
1421a8e1175bSopenharmony_ci */
1422a8e1175bSopenharmony_ciint mbedtls_pk_encrypt(mbedtls_pk_context *ctx,
1423a8e1175bSopenharmony_ci                       const unsigned char *input, size_t ilen,
1424a8e1175bSopenharmony_ci                       unsigned char *output, size_t *olen, size_t osize,
1425a8e1175bSopenharmony_ci                       int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
1426a8e1175bSopenharmony_ci{
1427a8e1175bSopenharmony_ci    if (ctx->pk_info == NULL) {
1428a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1429a8e1175bSopenharmony_ci    }
1430a8e1175bSopenharmony_ci
1431a8e1175bSopenharmony_ci    if (ctx->pk_info->encrypt_func == NULL) {
1432a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_TYPE_MISMATCH;
1433a8e1175bSopenharmony_ci    }
1434a8e1175bSopenharmony_ci
1435a8e1175bSopenharmony_ci    return ctx->pk_info->encrypt_func(ctx, input, ilen,
1436a8e1175bSopenharmony_ci                                      output, olen, osize, f_rng, p_rng);
1437a8e1175bSopenharmony_ci}
1438a8e1175bSopenharmony_ci
1439a8e1175bSopenharmony_ci/*
1440a8e1175bSopenharmony_ci * Check public-private key pair
1441a8e1175bSopenharmony_ci */
1442a8e1175bSopenharmony_ciint mbedtls_pk_check_pair(const mbedtls_pk_context *pub,
1443a8e1175bSopenharmony_ci                          const mbedtls_pk_context *prv,
1444a8e1175bSopenharmony_ci                          int (*f_rng)(void *, unsigned char *, size_t),
1445a8e1175bSopenharmony_ci                          void *p_rng)
1446a8e1175bSopenharmony_ci{
1447a8e1175bSopenharmony_ci    if (pub->pk_info == NULL ||
1448a8e1175bSopenharmony_ci        prv->pk_info == NULL) {
1449a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1450a8e1175bSopenharmony_ci    }
1451a8e1175bSopenharmony_ci
1452a8e1175bSopenharmony_ci    if (f_rng == NULL) {
1453a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1454a8e1175bSopenharmony_ci    }
1455a8e1175bSopenharmony_ci
1456a8e1175bSopenharmony_ci    if (prv->pk_info->check_pair_func == NULL) {
1457a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
1458a8e1175bSopenharmony_ci    }
1459a8e1175bSopenharmony_ci
1460a8e1175bSopenharmony_ci    if (prv->pk_info->type == MBEDTLS_PK_RSA_ALT) {
1461a8e1175bSopenharmony_ci        if (pub->pk_info->type != MBEDTLS_PK_RSA) {
1462a8e1175bSopenharmony_ci            return MBEDTLS_ERR_PK_TYPE_MISMATCH;
1463a8e1175bSopenharmony_ci        }
1464a8e1175bSopenharmony_ci    } else {
1465a8e1175bSopenharmony_ci        if ((prv->pk_info->type != MBEDTLS_PK_OPAQUE) &&
1466a8e1175bSopenharmony_ci            (pub->pk_info != prv->pk_info)) {
1467a8e1175bSopenharmony_ci            return MBEDTLS_ERR_PK_TYPE_MISMATCH;
1468a8e1175bSopenharmony_ci        }
1469a8e1175bSopenharmony_ci    }
1470a8e1175bSopenharmony_ci
1471a8e1175bSopenharmony_ci    return prv->pk_info->check_pair_func((mbedtls_pk_context *) pub,
1472a8e1175bSopenharmony_ci                                         (mbedtls_pk_context *) prv,
1473a8e1175bSopenharmony_ci                                         f_rng, p_rng);
1474a8e1175bSopenharmony_ci}
1475a8e1175bSopenharmony_ci
1476a8e1175bSopenharmony_ci/*
1477a8e1175bSopenharmony_ci * Get key size in bits
1478a8e1175bSopenharmony_ci */
1479a8e1175bSopenharmony_cisize_t mbedtls_pk_get_bitlen(const mbedtls_pk_context *ctx)
1480a8e1175bSopenharmony_ci{
1481a8e1175bSopenharmony_ci    /* For backward compatibility, accept NULL or a context that
1482a8e1175bSopenharmony_ci     * isn't set up yet, and return a fake value that should be safe. */
1483a8e1175bSopenharmony_ci    if (ctx == NULL || ctx->pk_info == NULL) {
1484a8e1175bSopenharmony_ci        return 0;
1485a8e1175bSopenharmony_ci    }
1486a8e1175bSopenharmony_ci
1487a8e1175bSopenharmony_ci    return ctx->pk_info->get_bitlen((mbedtls_pk_context *) ctx);
1488a8e1175bSopenharmony_ci}
1489a8e1175bSopenharmony_ci
1490a8e1175bSopenharmony_ci/*
1491a8e1175bSopenharmony_ci * Export debug information
1492a8e1175bSopenharmony_ci */
1493a8e1175bSopenharmony_ciint mbedtls_pk_debug(const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items)
1494a8e1175bSopenharmony_ci{
1495a8e1175bSopenharmony_ci    if (ctx->pk_info == NULL) {
1496a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1497a8e1175bSopenharmony_ci    }
1498a8e1175bSopenharmony_ci
1499a8e1175bSopenharmony_ci    if (ctx->pk_info->debug_func == NULL) {
1500a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_TYPE_MISMATCH;
1501a8e1175bSopenharmony_ci    }
1502a8e1175bSopenharmony_ci
1503a8e1175bSopenharmony_ci    ctx->pk_info->debug_func((mbedtls_pk_context *) ctx, items);
1504a8e1175bSopenharmony_ci    return 0;
1505a8e1175bSopenharmony_ci}
1506a8e1175bSopenharmony_ci
1507a8e1175bSopenharmony_ci/*
1508a8e1175bSopenharmony_ci * Access the PK type name
1509a8e1175bSopenharmony_ci */
1510a8e1175bSopenharmony_ciconst char *mbedtls_pk_get_name(const mbedtls_pk_context *ctx)
1511a8e1175bSopenharmony_ci{
1512a8e1175bSopenharmony_ci    if (ctx == NULL || ctx->pk_info == NULL) {
1513a8e1175bSopenharmony_ci        return "invalid PK";
1514a8e1175bSopenharmony_ci    }
1515a8e1175bSopenharmony_ci
1516a8e1175bSopenharmony_ci    return ctx->pk_info->name;
1517a8e1175bSopenharmony_ci}
1518a8e1175bSopenharmony_ci
1519a8e1175bSopenharmony_ci/*
1520a8e1175bSopenharmony_ci * Access the PK type
1521a8e1175bSopenharmony_ci */
1522a8e1175bSopenharmony_cimbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx)
1523a8e1175bSopenharmony_ci{
1524a8e1175bSopenharmony_ci    if (ctx == NULL || ctx->pk_info == NULL) {
1525a8e1175bSopenharmony_ci        return MBEDTLS_PK_NONE;
1526a8e1175bSopenharmony_ci    }
1527a8e1175bSopenharmony_ci
1528a8e1175bSopenharmony_ci    return ctx->pk_info->type;
1529a8e1175bSopenharmony_ci}
1530a8e1175bSopenharmony_ci
1531a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_C */
1532