1a8e1175bSopenharmony_ci/*
2a8e1175bSopenharmony_ci *  Public Key abstraction layer: wrapper functions
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#include "mbedtls/platform_util.h"
11a8e1175bSopenharmony_ci
12a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_C)
13a8e1175bSopenharmony_ci#include "pk_wrap.h"
14a8e1175bSopenharmony_ci#include "pk_internal.h"
15a8e1175bSopenharmony_ci#include "mbedtls/error.h"
16a8e1175bSopenharmony_ci#include "mbedtls/psa_util.h"
17a8e1175bSopenharmony_ci
18a8e1175bSopenharmony_ci/* Even if RSA not activated, for the sake of RSA-alt */
19a8e1175bSopenharmony_ci#include "mbedtls/rsa.h"
20a8e1175bSopenharmony_ci
21a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_C)
22a8e1175bSopenharmony_ci#include "mbedtls/ecp.h"
23a8e1175bSopenharmony_ci#endif
24a8e1175bSopenharmony_ci
25a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDSA_C)
26a8e1175bSopenharmony_ci#include "mbedtls/ecdsa.h"
27a8e1175bSopenharmony_ci#endif
28a8e1175bSopenharmony_ci
29a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
30a8e1175bSopenharmony_ci#include "psa_util_internal.h"
31a8e1175bSopenharmony_ci#include "psa/crypto.h"
32a8e1175bSopenharmony_ci#include "mbedtls/psa_util.h"
33a8e1175bSopenharmony_ci
34a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C)
35a8e1175bSopenharmony_ci#include "pkwrite.h"
36a8e1175bSopenharmony_ci#include "rsa_internal.h"
37a8e1175bSopenharmony_ci#endif
38a8e1175bSopenharmony_ci
39a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_CAN_ECDSA_SOME)
40a8e1175bSopenharmony_ci#include "mbedtls/asn1write.h"
41a8e1175bSopenharmony_ci#include "mbedtls/asn1.h"
42a8e1175bSopenharmony_ci#endif
43a8e1175bSopenharmony_ci#endif  /* MBEDTLS_USE_PSA_CRYPTO */
44a8e1175bSopenharmony_ci
45a8e1175bSopenharmony_ci#include "mbedtls/platform.h"
46a8e1175bSopenharmony_ci
47a8e1175bSopenharmony_ci#include <limits.h>
48a8e1175bSopenharmony_ci#include <stdint.h>
49a8e1175bSopenharmony_ci#include <string.h>
50a8e1175bSopenharmony_ci
51a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C)
52a8e1175bSopenharmony_cistatic int rsa_can_do(mbedtls_pk_type_t type)
53a8e1175bSopenharmony_ci{
54a8e1175bSopenharmony_ci    return type == MBEDTLS_PK_RSA ||
55a8e1175bSopenharmony_ci           type == MBEDTLS_PK_RSASSA_PSS;
56a8e1175bSopenharmony_ci}
57a8e1175bSopenharmony_ci
58a8e1175bSopenharmony_cistatic size_t rsa_get_bitlen(mbedtls_pk_context *pk)
59a8e1175bSopenharmony_ci{
60a8e1175bSopenharmony_ci    const mbedtls_rsa_context *rsa = (const mbedtls_rsa_context *) pk->pk_ctx;
61a8e1175bSopenharmony_ci    return mbedtls_rsa_get_bitlen(rsa);
62a8e1175bSopenharmony_ci}
63a8e1175bSopenharmony_ci
64a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
65a8e1175bSopenharmony_cistatic int rsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
66a8e1175bSopenharmony_ci                           const unsigned char *hash, size_t hash_len,
67a8e1175bSopenharmony_ci                           const unsigned char *sig, size_t sig_len)
68a8e1175bSopenharmony_ci{
69a8e1175bSopenharmony_ci    mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
70a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
71a8e1175bSopenharmony_ci    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
72a8e1175bSopenharmony_ci    mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
73a8e1175bSopenharmony_ci    psa_status_t status;
74a8e1175bSopenharmony_ci    int key_len;
75a8e1175bSopenharmony_ci    unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES];
76a8e1175bSopenharmony_ci    unsigned char *p = buf + sizeof(buf);
77a8e1175bSopenharmony_ci    psa_algorithm_t psa_alg_md;
78a8e1175bSopenharmony_ci    size_t rsa_len = mbedtls_rsa_get_len(rsa);
79a8e1175bSopenharmony_ci
80a8e1175bSopenharmony_ci#if SIZE_MAX > UINT_MAX
81a8e1175bSopenharmony_ci    if (md_alg == MBEDTLS_MD_NONE && (int)UINT_MAX < (int)hash_len) {
82a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
83a8e1175bSopenharmony_ci    }
84a8e1175bSopenharmony_ci#endif
85a8e1175bSopenharmony_ci
86a8e1175bSopenharmony_ci    if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) {
87a8e1175bSopenharmony_ci        psa_alg_md = PSA_ALG_RSA_PSS(mbedtls_md_psa_alg_from_type(md_alg));
88a8e1175bSopenharmony_ci    } else {
89a8e1175bSopenharmony_ci        psa_alg_md = PSA_ALG_RSA_PKCS1V15_SIGN(mbedtls_md_psa_alg_from_type(md_alg));
90a8e1175bSopenharmony_ci    }
91a8e1175bSopenharmony_ci
92a8e1175bSopenharmony_ci    if (sig_len < rsa_len) {
93a8e1175bSopenharmony_ci        return MBEDTLS_ERR_RSA_VERIFY_FAILED;
94a8e1175bSopenharmony_ci    }
95a8e1175bSopenharmony_ci
96a8e1175bSopenharmony_ci    key_len = mbedtls_rsa_write_pubkey(rsa, buf, &p);
97a8e1175bSopenharmony_ci    if (key_len <= 0) {
98a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
99a8e1175bSopenharmony_ci    }
100a8e1175bSopenharmony_ci
101a8e1175bSopenharmony_ci    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH);
102a8e1175bSopenharmony_ci    psa_set_key_algorithm(&attributes, psa_alg_md);
103a8e1175bSopenharmony_ci    psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY);
104a8e1175bSopenharmony_ci
105a8e1175bSopenharmony_ci    status = psa_import_key(&attributes,
106a8e1175bSopenharmony_ci                            buf + sizeof(buf) - key_len, key_len,
107a8e1175bSopenharmony_ci                            &key_id);
108a8e1175bSopenharmony_ci    if (status != PSA_SUCCESS) {
109a8e1175bSopenharmony_ci        ret = PSA_PK_TO_MBEDTLS_ERR(status);
110a8e1175bSopenharmony_ci        goto cleanup;
111a8e1175bSopenharmony_ci    }
112a8e1175bSopenharmony_ci
113a8e1175bSopenharmony_ci    status = psa_verify_hash(key_id, psa_alg_md, hash, hash_len,
114a8e1175bSopenharmony_ci                             sig, sig_len);
115a8e1175bSopenharmony_ci    if (status != PSA_SUCCESS) {
116a8e1175bSopenharmony_ci        ret = PSA_PK_RSA_TO_MBEDTLS_ERR(status);
117a8e1175bSopenharmony_ci        goto cleanup;
118a8e1175bSopenharmony_ci    }
119a8e1175bSopenharmony_ci    ret = 0;
120a8e1175bSopenharmony_ci
121a8e1175bSopenharmony_cicleanup:
122a8e1175bSopenharmony_ci    status = psa_destroy_key(key_id);
123a8e1175bSopenharmony_ci    if (ret == 0 && status != PSA_SUCCESS) {
124a8e1175bSopenharmony_ci        ret = PSA_PK_TO_MBEDTLS_ERR(status);
125a8e1175bSopenharmony_ci    }
126a8e1175bSopenharmony_ci
127a8e1175bSopenharmony_ci    return ret;
128a8e1175bSopenharmony_ci}
129a8e1175bSopenharmony_ci#else /* MBEDTLS_USE_PSA_CRYPTO */
130a8e1175bSopenharmony_cistatic int rsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
131a8e1175bSopenharmony_ci                           const unsigned char *hash, size_t hash_len,
132a8e1175bSopenharmony_ci                           const unsigned char *sig, size_t sig_len)
133a8e1175bSopenharmony_ci{
134a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
135a8e1175bSopenharmony_ci    mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
136a8e1175bSopenharmony_ci    size_t rsa_len = mbedtls_rsa_get_len(rsa);
137a8e1175bSopenharmony_ci
138a8e1175bSopenharmony_ci#if SIZE_MAX > UINT_MAX
139a8e1175bSopenharmony_ci    if (md_alg == MBEDTLS_MD_NONE && (int)UINT_MAX < (int)hash_len) {
140a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
141a8e1175bSopenharmony_ci    }
142a8e1175bSopenharmony_ci#endif
143a8e1175bSopenharmony_ci
144a8e1175bSopenharmony_ci    if (sig_len < rsa_len) {
145a8e1175bSopenharmony_ci        return MBEDTLS_ERR_RSA_VERIFY_FAILED;
146a8e1175bSopenharmony_ci    }
147a8e1175bSopenharmony_ci
148a8e1175bSopenharmony_ci    if ((ret = mbedtls_rsa_pkcs1_verify(rsa, md_alg,
149a8e1175bSopenharmony_ci                                        (unsigned int) hash_len,
150a8e1175bSopenharmony_ci                                        hash, sig)) != 0) {
151a8e1175bSopenharmony_ci        return ret;
152a8e1175bSopenharmony_ci    }
153a8e1175bSopenharmony_ci
154a8e1175bSopenharmony_ci    /* The buffer contains a valid signature followed by extra data.
155a8e1175bSopenharmony_ci     * We have a special error code for that so that so that callers can
156a8e1175bSopenharmony_ci     * use mbedtls_pk_verify() to check "Does the buffer start with a
157a8e1175bSopenharmony_ci     * valid signature?" and not just "Does the buffer contain a valid
158a8e1175bSopenharmony_ci     * signature?". */
159a8e1175bSopenharmony_ci    if (sig_len > rsa_len) {
160a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
161a8e1175bSopenharmony_ci    }
162a8e1175bSopenharmony_ci
163a8e1175bSopenharmony_ci    return 0;
164a8e1175bSopenharmony_ci}
165a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
166a8e1175bSopenharmony_ci
167a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
168a8e1175bSopenharmony_ciint  mbedtls_pk_psa_rsa_sign_ext(psa_algorithm_t alg,
169a8e1175bSopenharmony_ci                                 mbedtls_rsa_context *rsa_ctx,
170a8e1175bSopenharmony_ci                                 const unsigned char *hash, size_t hash_len,
171a8e1175bSopenharmony_ci                                 unsigned char *sig, size_t sig_size,
172a8e1175bSopenharmony_ci                                 size_t *sig_len)
173a8e1175bSopenharmony_ci{
174a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
175a8e1175bSopenharmony_ci    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
176a8e1175bSopenharmony_ci    mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
177a8e1175bSopenharmony_ci    psa_status_t status;
178a8e1175bSopenharmony_ci    int key_len;
179a8e1175bSopenharmony_ci    unsigned char *buf = NULL;
180a8e1175bSopenharmony_ci    unsigned char *p;
181a8e1175bSopenharmony_ci
182a8e1175bSopenharmony_ci    buf = mbedtls_calloc(1, MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES);
183a8e1175bSopenharmony_ci    if (buf == NULL) {
184a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_ALLOC_FAILED;
185a8e1175bSopenharmony_ci    }
186a8e1175bSopenharmony_ci    p = buf + MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES;
187a8e1175bSopenharmony_ci
188a8e1175bSopenharmony_ci    *sig_len = mbedtls_rsa_get_len(rsa_ctx);
189a8e1175bSopenharmony_ci    if (sig_size < *sig_len) {
190a8e1175bSopenharmony_ci        mbedtls_free(buf);
191a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
192a8e1175bSopenharmony_ci    }
193a8e1175bSopenharmony_ci
194a8e1175bSopenharmony_ci    key_len = mbedtls_rsa_write_key(rsa_ctx, buf, &p);
195a8e1175bSopenharmony_ci    if (key_len <= 0) {
196a8e1175bSopenharmony_ci        mbedtls_free(buf);
197a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
198a8e1175bSopenharmony_ci    }
199a8e1175bSopenharmony_ci    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
200a8e1175bSopenharmony_ci    psa_set_key_algorithm(&attributes, alg);
201a8e1175bSopenharmony_ci    psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
202a8e1175bSopenharmony_ci
203a8e1175bSopenharmony_ci    status = psa_import_key(&attributes,
204a8e1175bSopenharmony_ci                            buf + MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES - key_len, key_len,
205a8e1175bSopenharmony_ci                            &key_id);
206a8e1175bSopenharmony_ci    if (status != PSA_SUCCESS) {
207a8e1175bSopenharmony_ci        ret = PSA_PK_TO_MBEDTLS_ERR(status);
208a8e1175bSopenharmony_ci        goto cleanup;
209a8e1175bSopenharmony_ci    }
210a8e1175bSopenharmony_ci    status = psa_sign_hash(key_id, alg, hash, hash_len,
211a8e1175bSopenharmony_ci                           sig, sig_size, sig_len);
212a8e1175bSopenharmony_ci    if (status != PSA_SUCCESS) {
213a8e1175bSopenharmony_ci        ret = PSA_PK_RSA_TO_MBEDTLS_ERR(status);
214a8e1175bSopenharmony_ci        goto cleanup;
215a8e1175bSopenharmony_ci    }
216a8e1175bSopenharmony_ci
217a8e1175bSopenharmony_ci    ret = 0;
218a8e1175bSopenharmony_ci
219a8e1175bSopenharmony_cicleanup:
220a8e1175bSopenharmony_ci    mbedtls_free(buf);
221a8e1175bSopenharmony_ci    status = psa_destroy_key(key_id);
222a8e1175bSopenharmony_ci    if (ret == 0 && status != PSA_SUCCESS) {
223a8e1175bSopenharmony_ci        ret = PSA_PK_TO_MBEDTLS_ERR(status);
224a8e1175bSopenharmony_ci    }
225a8e1175bSopenharmony_ci    return ret;
226a8e1175bSopenharmony_ci}
227a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
228a8e1175bSopenharmony_ci
229a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
230a8e1175bSopenharmony_cistatic int rsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
231a8e1175bSopenharmony_ci                         const unsigned char *hash, size_t hash_len,
232a8e1175bSopenharmony_ci                         unsigned char *sig, size_t sig_size, size_t *sig_len,
233a8e1175bSopenharmony_ci                         int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
234a8e1175bSopenharmony_ci{
235a8e1175bSopenharmony_ci    ((void) f_rng);
236a8e1175bSopenharmony_ci    ((void) p_rng);
237a8e1175bSopenharmony_ci
238a8e1175bSopenharmony_ci    psa_algorithm_t psa_md_alg;
239a8e1175bSopenharmony_ci    psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
240a8e1175bSopenharmony_ci    if (psa_md_alg == 0) {
241a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
242a8e1175bSopenharmony_ci    }
243a8e1175bSopenharmony_ci    psa_algorithm_t psa_alg;
244a8e1175bSopenharmony_ci    if (mbedtls_rsa_get_padding_mode(mbedtls_pk_rsa(*pk)) == MBEDTLS_RSA_PKCS_V21) {
245a8e1175bSopenharmony_ci        psa_alg = PSA_ALG_RSA_PSS(psa_md_alg);
246a8e1175bSopenharmony_ci    } else {
247a8e1175bSopenharmony_ci        psa_alg = PSA_ALG_RSA_PKCS1V15_SIGN(psa_md_alg);
248a8e1175bSopenharmony_ci    }
249a8e1175bSopenharmony_ci
250a8e1175bSopenharmony_ci    return mbedtls_pk_psa_rsa_sign_ext(psa_alg, pk->pk_ctx, hash, hash_len,
251a8e1175bSopenharmony_ci                                       sig, sig_size, sig_len);
252a8e1175bSopenharmony_ci}
253a8e1175bSopenharmony_ci#else /* MBEDTLS_USE_PSA_CRYPTO */
254a8e1175bSopenharmony_cistatic int rsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
255a8e1175bSopenharmony_ci                         const unsigned char *hash, size_t hash_len,
256a8e1175bSopenharmony_ci                         unsigned char *sig, size_t sig_size, size_t *sig_len,
257a8e1175bSopenharmony_ci                         int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
258a8e1175bSopenharmony_ci{
259a8e1175bSopenharmony_ci    mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
260a8e1175bSopenharmony_ci
261a8e1175bSopenharmony_ci#if SIZE_MAX > UINT_MAX
262a8e1175bSopenharmony_ci    if (md_alg == MBEDTLS_MD_NONE && (int)UINT_MAX < (int)hash_len) {
263a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
264a8e1175bSopenharmony_ci    }
265a8e1175bSopenharmony_ci#endif
266a8e1175bSopenharmony_ci
267a8e1175bSopenharmony_ci    *sig_len = mbedtls_rsa_get_len(rsa);
268a8e1175bSopenharmony_ci    if (sig_size < *sig_len) {
269a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
270a8e1175bSopenharmony_ci    }
271a8e1175bSopenharmony_ci
272a8e1175bSopenharmony_ci    return mbedtls_rsa_pkcs1_sign(rsa, f_rng, p_rng,
273a8e1175bSopenharmony_ci                                  md_alg, (unsigned int) hash_len,
274a8e1175bSopenharmony_ci                                  hash, sig);
275a8e1175bSopenharmony_ci}
276a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
277a8e1175bSopenharmony_ci
278a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
279a8e1175bSopenharmony_cistatic int rsa_decrypt_wrap(mbedtls_pk_context *pk,
280a8e1175bSopenharmony_ci                            const unsigned char *input, size_t ilen,
281a8e1175bSopenharmony_ci                            unsigned char *output, size_t *olen, size_t osize,
282a8e1175bSopenharmony_ci                            int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
283a8e1175bSopenharmony_ci{
284a8e1175bSopenharmony_ci    mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
285a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
286a8e1175bSopenharmony_ci    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
287a8e1175bSopenharmony_ci    mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
288a8e1175bSopenharmony_ci    psa_algorithm_t psa_md_alg, decrypt_alg;
289a8e1175bSopenharmony_ci    psa_status_t status;
290a8e1175bSopenharmony_ci    int key_len;
291a8e1175bSopenharmony_ci    unsigned char buf[MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES];
292a8e1175bSopenharmony_ci    unsigned char *p = buf + sizeof(buf);
293a8e1175bSopenharmony_ci
294a8e1175bSopenharmony_ci    ((void) f_rng);
295a8e1175bSopenharmony_ci    ((void) p_rng);
296a8e1175bSopenharmony_ci
297a8e1175bSopenharmony_ci    if (ilen != mbedtls_rsa_get_len(rsa)) {
298a8e1175bSopenharmony_ci        return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
299a8e1175bSopenharmony_ci    }
300a8e1175bSopenharmony_ci
301a8e1175bSopenharmony_ci    key_len = mbedtls_rsa_write_key(rsa, buf, &p);
302a8e1175bSopenharmony_ci    if (key_len <= 0) {
303a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
304a8e1175bSopenharmony_ci    }
305a8e1175bSopenharmony_ci
306a8e1175bSopenharmony_ci    psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
307a8e1175bSopenharmony_ci    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT);
308a8e1175bSopenharmony_ci    if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) {
309a8e1175bSopenharmony_ci        psa_md_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) mbedtls_rsa_get_md_alg(rsa));
310a8e1175bSopenharmony_ci        decrypt_alg = PSA_ALG_RSA_OAEP(psa_md_alg);
311a8e1175bSopenharmony_ci    } else {
312a8e1175bSopenharmony_ci        decrypt_alg = PSA_ALG_RSA_PKCS1V15_CRYPT;
313a8e1175bSopenharmony_ci    }
314a8e1175bSopenharmony_ci    psa_set_key_algorithm(&attributes, decrypt_alg);
315a8e1175bSopenharmony_ci
316a8e1175bSopenharmony_ci    status = psa_import_key(&attributes,
317a8e1175bSopenharmony_ci                            buf + sizeof(buf) - key_len, key_len,
318a8e1175bSopenharmony_ci                            &key_id);
319a8e1175bSopenharmony_ci    if (status != PSA_SUCCESS) {
320a8e1175bSopenharmony_ci        ret = PSA_PK_TO_MBEDTLS_ERR(status);
321a8e1175bSopenharmony_ci        goto cleanup;
322a8e1175bSopenharmony_ci    }
323a8e1175bSopenharmony_ci
324a8e1175bSopenharmony_ci    status = psa_asymmetric_decrypt(key_id, decrypt_alg,
325a8e1175bSopenharmony_ci                                    input, ilen,
326a8e1175bSopenharmony_ci                                    NULL, 0,
327a8e1175bSopenharmony_ci                                    output, osize, olen);
328a8e1175bSopenharmony_ci    if (status != PSA_SUCCESS) {
329a8e1175bSopenharmony_ci        ret = PSA_PK_RSA_TO_MBEDTLS_ERR(status);
330a8e1175bSopenharmony_ci        goto cleanup;
331a8e1175bSopenharmony_ci    }
332a8e1175bSopenharmony_ci
333a8e1175bSopenharmony_ci    ret = 0;
334a8e1175bSopenharmony_ci
335a8e1175bSopenharmony_cicleanup:
336a8e1175bSopenharmony_ci    mbedtls_platform_zeroize(buf, sizeof(buf));
337a8e1175bSopenharmony_ci    status = psa_destroy_key(key_id);
338a8e1175bSopenharmony_ci    if (ret == 0 && status != PSA_SUCCESS) {
339a8e1175bSopenharmony_ci        ret = PSA_PK_TO_MBEDTLS_ERR(status);
340a8e1175bSopenharmony_ci    }
341a8e1175bSopenharmony_ci
342a8e1175bSopenharmony_ci    return ret;
343a8e1175bSopenharmony_ci}
344a8e1175bSopenharmony_ci#else /* MBEDTLS_USE_PSA_CRYPTO */
345a8e1175bSopenharmony_cistatic int rsa_decrypt_wrap(mbedtls_pk_context *pk,
346a8e1175bSopenharmony_ci                            const unsigned char *input, size_t ilen,
347a8e1175bSopenharmony_ci                            unsigned char *output, size_t *olen, size_t osize,
348a8e1175bSopenharmony_ci                            int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
349a8e1175bSopenharmony_ci{
350a8e1175bSopenharmony_ci    mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
351a8e1175bSopenharmony_ci
352a8e1175bSopenharmony_ci    if (ilen != mbedtls_rsa_get_len(rsa)) {
353a8e1175bSopenharmony_ci        return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
354a8e1175bSopenharmony_ci    }
355a8e1175bSopenharmony_ci
356a8e1175bSopenharmony_ci    return mbedtls_rsa_pkcs1_decrypt(rsa, f_rng, p_rng,
357a8e1175bSopenharmony_ci                                     olen, input, output, osize);
358a8e1175bSopenharmony_ci}
359a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
360a8e1175bSopenharmony_ci
361a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
362a8e1175bSopenharmony_cistatic int rsa_encrypt_wrap(mbedtls_pk_context *pk,
363a8e1175bSopenharmony_ci                            const unsigned char *input, size_t ilen,
364a8e1175bSopenharmony_ci                            unsigned char *output, size_t *olen, size_t osize,
365a8e1175bSopenharmony_ci                            int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
366a8e1175bSopenharmony_ci{
367a8e1175bSopenharmony_ci    mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
368a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
369a8e1175bSopenharmony_ci    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
370a8e1175bSopenharmony_ci    mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
371a8e1175bSopenharmony_ci    psa_algorithm_t psa_md_alg, psa_encrypt_alg;
372a8e1175bSopenharmony_ci    psa_status_t status;
373a8e1175bSopenharmony_ci    int key_len;
374a8e1175bSopenharmony_ci    unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES];
375a8e1175bSopenharmony_ci    unsigned char *p = buf + sizeof(buf);
376a8e1175bSopenharmony_ci
377a8e1175bSopenharmony_ci    ((void) f_rng);
378a8e1175bSopenharmony_ci    ((void) p_rng);
379a8e1175bSopenharmony_ci
380a8e1175bSopenharmony_ci    if (mbedtls_rsa_get_len(rsa) > osize) {
381a8e1175bSopenharmony_ci        return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
382a8e1175bSopenharmony_ci    }
383a8e1175bSopenharmony_ci
384a8e1175bSopenharmony_ci    key_len = mbedtls_rsa_write_pubkey(rsa, buf, &p);
385a8e1175bSopenharmony_ci    if (key_len <= 0) {
386a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
387a8e1175bSopenharmony_ci    }
388a8e1175bSopenharmony_ci
389a8e1175bSopenharmony_ci    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT);
390a8e1175bSopenharmony_ci    if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) {
391a8e1175bSopenharmony_ci        psa_md_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) mbedtls_rsa_get_md_alg(rsa));
392a8e1175bSopenharmony_ci        psa_encrypt_alg = PSA_ALG_RSA_OAEP(psa_md_alg);
393a8e1175bSopenharmony_ci    } else {
394a8e1175bSopenharmony_ci        psa_encrypt_alg = PSA_ALG_RSA_PKCS1V15_CRYPT;
395a8e1175bSopenharmony_ci    }
396a8e1175bSopenharmony_ci    psa_set_key_algorithm(&attributes, psa_encrypt_alg);
397a8e1175bSopenharmony_ci    psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY);
398a8e1175bSopenharmony_ci
399a8e1175bSopenharmony_ci    status = psa_import_key(&attributes,
400a8e1175bSopenharmony_ci                            buf + sizeof(buf) - key_len, key_len,
401a8e1175bSopenharmony_ci                            &key_id);
402a8e1175bSopenharmony_ci    if (status != PSA_SUCCESS) {
403a8e1175bSopenharmony_ci        ret = PSA_PK_TO_MBEDTLS_ERR(status);
404a8e1175bSopenharmony_ci        goto cleanup;
405a8e1175bSopenharmony_ci    }
406a8e1175bSopenharmony_ci
407a8e1175bSopenharmony_ci    status = psa_asymmetric_encrypt(key_id, psa_encrypt_alg,
408a8e1175bSopenharmony_ci                                    input, ilen,
409a8e1175bSopenharmony_ci                                    NULL, 0,
410a8e1175bSopenharmony_ci                                    output, osize, olen);
411a8e1175bSopenharmony_ci    if (status != PSA_SUCCESS) {
412a8e1175bSopenharmony_ci        ret = PSA_PK_RSA_TO_MBEDTLS_ERR(status);
413a8e1175bSopenharmony_ci        goto cleanup;
414a8e1175bSopenharmony_ci    }
415a8e1175bSopenharmony_ci
416a8e1175bSopenharmony_ci    ret = 0;
417a8e1175bSopenharmony_ci
418a8e1175bSopenharmony_cicleanup:
419a8e1175bSopenharmony_ci    status = psa_destroy_key(key_id);
420a8e1175bSopenharmony_ci    if (ret == 0 && status != PSA_SUCCESS) {
421a8e1175bSopenharmony_ci        ret = PSA_PK_TO_MBEDTLS_ERR(status);
422a8e1175bSopenharmony_ci    }
423a8e1175bSopenharmony_ci
424a8e1175bSopenharmony_ci    return ret;
425a8e1175bSopenharmony_ci}
426a8e1175bSopenharmony_ci#else /* MBEDTLS_USE_PSA_CRYPTO */
427a8e1175bSopenharmony_cistatic int rsa_encrypt_wrap(mbedtls_pk_context *pk,
428a8e1175bSopenharmony_ci                            const unsigned char *input, size_t ilen,
429a8e1175bSopenharmony_ci                            unsigned char *output, size_t *olen, size_t osize,
430a8e1175bSopenharmony_ci                            int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
431a8e1175bSopenharmony_ci{
432a8e1175bSopenharmony_ci    mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
433a8e1175bSopenharmony_ci    *olen = mbedtls_rsa_get_len(rsa);
434a8e1175bSopenharmony_ci
435a8e1175bSopenharmony_ci    if (*olen > osize) {
436a8e1175bSopenharmony_ci        return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
437a8e1175bSopenharmony_ci    }
438a8e1175bSopenharmony_ci
439a8e1175bSopenharmony_ci    return mbedtls_rsa_pkcs1_encrypt(rsa, f_rng, p_rng,
440a8e1175bSopenharmony_ci                                     ilen, input, output);
441a8e1175bSopenharmony_ci}
442a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
443a8e1175bSopenharmony_ci
444a8e1175bSopenharmony_cistatic int rsa_check_pair_wrap(mbedtls_pk_context *pub, mbedtls_pk_context *prv,
445a8e1175bSopenharmony_ci                               int (*f_rng)(void *, unsigned char *, size_t),
446a8e1175bSopenharmony_ci                               void *p_rng)
447a8e1175bSopenharmony_ci{
448a8e1175bSopenharmony_ci    (void) f_rng;
449a8e1175bSopenharmony_ci    (void) p_rng;
450a8e1175bSopenharmony_ci    return mbedtls_rsa_check_pub_priv((const mbedtls_rsa_context *) pub->pk_ctx,
451a8e1175bSopenharmony_ci                                      (const mbedtls_rsa_context *) prv->pk_ctx);
452a8e1175bSopenharmony_ci}
453a8e1175bSopenharmony_ci
454a8e1175bSopenharmony_cistatic void *rsa_alloc_wrap(void)
455a8e1175bSopenharmony_ci{
456a8e1175bSopenharmony_ci    void *ctx = mbedtls_calloc(1, sizeof(mbedtls_rsa_context));
457a8e1175bSopenharmony_ci
458a8e1175bSopenharmony_ci    if (ctx != NULL) {
459a8e1175bSopenharmony_ci        mbedtls_rsa_init((mbedtls_rsa_context *) ctx);
460a8e1175bSopenharmony_ci    }
461a8e1175bSopenharmony_ci
462a8e1175bSopenharmony_ci    return ctx;
463a8e1175bSopenharmony_ci}
464a8e1175bSopenharmony_ci
465a8e1175bSopenharmony_cistatic void rsa_free_wrap(void *ctx)
466a8e1175bSopenharmony_ci{
467a8e1175bSopenharmony_ci    mbedtls_rsa_free((mbedtls_rsa_context *) ctx);
468a8e1175bSopenharmony_ci    mbedtls_free(ctx);
469a8e1175bSopenharmony_ci}
470a8e1175bSopenharmony_ci
471a8e1175bSopenharmony_cistatic void rsa_debug(mbedtls_pk_context *pk, mbedtls_pk_debug_item *items)
472a8e1175bSopenharmony_ci{
473a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_ALT)
474a8e1175bSopenharmony_ci    /* Not supported */
475a8e1175bSopenharmony_ci    (void) pk;
476a8e1175bSopenharmony_ci    (void) items;
477a8e1175bSopenharmony_ci#else
478a8e1175bSopenharmony_ci    mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
479a8e1175bSopenharmony_ci
480a8e1175bSopenharmony_ci    items->type = MBEDTLS_PK_DEBUG_MPI;
481a8e1175bSopenharmony_ci    items->name = "rsa.N";
482a8e1175bSopenharmony_ci    items->value = &(rsa->N);
483a8e1175bSopenharmony_ci
484a8e1175bSopenharmony_ci    items++;
485a8e1175bSopenharmony_ci
486a8e1175bSopenharmony_ci    items->type = MBEDTLS_PK_DEBUG_MPI;
487a8e1175bSopenharmony_ci    items->name = "rsa.E";
488a8e1175bSopenharmony_ci    items->value = &(rsa->E);
489a8e1175bSopenharmony_ci#endif
490a8e1175bSopenharmony_ci}
491a8e1175bSopenharmony_ci
492a8e1175bSopenharmony_ciconst mbedtls_pk_info_t mbedtls_rsa_info = {
493a8e1175bSopenharmony_ci    .type = MBEDTLS_PK_RSA,
494a8e1175bSopenharmony_ci    .name = "RSA",
495a8e1175bSopenharmony_ci    .get_bitlen = rsa_get_bitlen,
496a8e1175bSopenharmony_ci    .can_do = rsa_can_do,
497a8e1175bSopenharmony_ci    .verify_func = rsa_verify_wrap,
498a8e1175bSopenharmony_ci    .sign_func = rsa_sign_wrap,
499a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
500a8e1175bSopenharmony_ci    .verify_rs_func = NULL,
501a8e1175bSopenharmony_ci    .sign_rs_func = NULL,
502a8e1175bSopenharmony_ci    .rs_alloc_func = NULL,
503a8e1175bSopenharmony_ci    .rs_free_func = NULL,
504a8e1175bSopenharmony_ci#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
505a8e1175bSopenharmony_ci    .decrypt_func = rsa_decrypt_wrap,
506a8e1175bSopenharmony_ci    .encrypt_func = rsa_encrypt_wrap,
507a8e1175bSopenharmony_ci    .check_pair_func = rsa_check_pair_wrap,
508a8e1175bSopenharmony_ci    .ctx_alloc_func = rsa_alloc_wrap,
509a8e1175bSopenharmony_ci    .ctx_free_func = rsa_free_wrap,
510a8e1175bSopenharmony_ci    .debug_func = rsa_debug,
511a8e1175bSopenharmony_ci};
512a8e1175bSopenharmony_ci#endif /* MBEDTLS_RSA_C */
513a8e1175bSopenharmony_ci
514a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
515a8e1175bSopenharmony_ci/*
516a8e1175bSopenharmony_ci * Generic EC key
517a8e1175bSopenharmony_ci */
518a8e1175bSopenharmony_cistatic int eckey_can_do(mbedtls_pk_type_t type)
519a8e1175bSopenharmony_ci{
520a8e1175bSopenharmony_ci    return type == MBEDTLS_PK_ECKEY ||
521a8e1175bSopenharmony_ci           type == MBEDTLS_PK_ECKEY_DH ||
522a8e1175bSopenharmony_ci           type == MBEDTLS_PK_ECDSA;
523a8e1175bSopenharmony_ci}
524a8e1175bSopenharmony_ci
525a8e1175bSopenharmony_cistatic size_t eckey_get_bitlen(mbedtls_pk_context *pk)
526a8e1175bSopenharmony_ci{
527a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
528a8e1175bSopenharmony_ci    return pk->ec_bits;
529a8e1175bSopenharmony_ci#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
530a8e1175bSopenharmony_ci    mbedtls_ecp_keypair *ecp = (mbedtls_ecp_keypair *) pk->pk_ctx;
531a8e1175bSopenharmony_ci    return ecp->grp.pbits;
532a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
533a8e1175bSopenharmony_ci}
534a8e1175bSopenharmony_ci
535a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY)
536a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
537a8e1175bSopenharmony_ci/* Common helper for ECDSA verify using PSA functions. */
538a8e1175bSopenharmony_cistatic int ecdsa_verify_psa(unsigned char *key, size_t key_len,
539a8e1175bSopenharmony_ci                            psa_ecc_family_t curve, size_t curve_bits,
540a8e1175bSopenharmony_ci                            const unsigned char *hash, size_t hash_len,
541a8e1175bSopenharmony_ci                            const unsigned char *sig, size_t sig_len)
542a8e1175bSopenharmony_ci{
543a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
544a8e1175bSopenharmony_ci    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
545a8e1175bSopenharmony_ci    mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
546a8e1175bSopenharmony_ci    psa_algorithm_t psa_sig_md = PSA_ALG_ECDSA_ANY;
547a8e1175bSopenharmony_ci    size_t signature_len = PSA_ECDSA_SIGNATURE_SIZE(curve_bits);
548a8e1175bSopenharmony_ci    size_t converted_sig_len;
549a8e1175bSopenharmony_ci    unsigned char extracted_sig[PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE];
550a8e1175bSopenharmony_ci    unsigned char *p;
551a8e1175bSopenharmony_ci    psa_status_t status;
552a8e1175bSopenharmony_ci
553a8e1175bSopenharmony_ci    if (curve == 0) {
554a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
555a8e1175bSopenharmony_ci    }
556a8e1175bSopenharmony_ci
557a8e1175bSopenharmony_ci    psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve));
558a8e1175bSopenharmony_ci    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH);
559a8e1175bSopenharmony_ci    psa_set_key_algorithm(&attributes, psa_sig_md);
560a8e1175bSopenharmony_ci
561a8e1175bSopenharmony_ci    status = psa_import_key(&attributes, key, key_len, &key_id);
562a8e1175bSopenharmony_ci    if (status != PSA_SUCCESS) {
563a8e1175bSopenharmony_ci        ret = PSA_PK_TO_MBEDTLS_ERR(status);
564a8e1175bSopenharmony_ci        goto cleanup;
565a8e1175bSopenharmony_ci    }
566a8e1175bSopenharmony_ci
567a8e1175bSopenharmony_ci    if (signature_len > sizeof(extracted_sig)) {
568a8e1175bSopenharmony_ci        ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;
569a8e1175bSopenharmony_ci        goto cleanup;
570a8e1175bSopenharmony_ci    }
571a8e1175bSopenharmony_ci
572a8e1175bSopenharmony_ci    p = (unsigned char *) sig;
573a8e1175bSopenharmony_ci    ret = mbedtls_ecdsa_der_to_raw(curve_bits, p, sig_len, extracted_sig,
574a8e1175bSopenharmony_ci                                   sizeof(extracted_sig), &converted_sig_len);
575a8e1175bSopenharmony_ci    if (ret != 0) {
576a8e1175bSopenharmony_ci        goto cleanup;
577a8e1175bSopenharmony_ci    }
578a8e1175bSopenharmony_ci
579a8e1175bSopenharmony_ci    if (converted_sig_len != signature_len) {
580a8e1175bSopenharmony_ci        ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;
581a8e1175bSopenharmony_ci        goto cleanup;
582a8e1175bSopenharmony_ci    }
583a8e1175bSopenharmony_ci
584a8e1175bSopenharmony_ci    status = psa_verify_hash(key_id, psa_sig_md, hash, hash_len,
585a8e1175bSopenharmony_ci                             extracted_sig, signature_len);
586a8e1175bSopenharmony_ci    if (status != PSA_SUCCESS) {
587a8e1175bSopenharmony_ci        ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
588a8e1175bSopenharmony_ci        goto cleanup;
589a8e1175bSopenharmony_ci    }
590a8e1175bSopenharmony_ci
591a8e1175bSopenharmony_ci    ret = 0;
592a8e1175bSopenharmony_ci
593a8e1175bSopenharmony_cicleanup:
594a8e1175bSopenharmony_ci    status = psa_destroy_key(key_id);
595a8e1175bSopenharmony_ci    if (ret == 0 && status != PSA_SUCCESS) {
596a8e1175bSopenharmony_ci        ret = PSA_PK_TO_MBEDTLS_ERR(status);
597a8e1175bSopenharmony_ci    }
598a8e1175bSopenharmony_ci
599a8e1175bSopenharmony_ci    return ret;
600a8e1175bSopenharmony_ci}
601a8e1175bSopenharmony_ci
602a8e1175bSopenharmony_cistatic int ecdsa_opaque_verify_wrap(mbedtls_pk_context *pk,
603a8e1175bSopenharmony_ci                                    mbedtls_md_type_t md_alg,
604a8e1175bSopenharmony_ci                                    const unsigned char *hash, size_t hash_len,
605a8e1175bSopenharmony_ci                                    const unsigned char *sig, size_t sig_len)
606a8e1175bSopenharmony_ci{
607a8e1175bSopenharmony_ci    (void) md_alg;
608a8e1175bSopenharmony_ci    unsigned char key[MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN];
609a8e1175bSopenharmony_ci    size_t key_len;
610a8e1175bSopenharmony_ci    psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
611a8e1175bSopenharmony_ci    psa_ecc_family_t curve;
612a8e1175bSopenharmony_ci    size_t curve_bits;
613a8e1175bSopenharmony_ci    psa_status_t status;
614a8e1175bSopenharmony_ci
615a8e1175bSopenharmony_ci    status = psa_get_key_attributes(pk->priv_id, &key_attr);
616a8e1175bSopenharmony_ci    if (status != PSA_SUCCESS) {
617a8e1175bSopenharmony_ci        return PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
618a8e1175bSopenharmony_ci    }
619a8e1175bSopenharmony_ci    curve = PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(&key_attr));
620a8e1175bSopenharmony_ci    curve_bits = psa_get_key_bits(&key_attr);
621a8e1175bSopenharmony_ci    psa_reset_key_attributes(&key_attr);
622a8e1175bSopenharmony_ci
623a8e1175bSopenharmony_ci    status = psa_export_public_key(pk->priv_id, key, sizeof(key), &key_len);
624a8e1175bSopenharmony_ci    if (status != PSA_SUCCESS) {
625a8e1175bSopenharmony_ci        return PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
626a8e1175bSopenharmony_ci    }
627a8e1175bSopenharmony_ci
628a8e1175bSopenharmony_ci    return ecdsa_verify_psa(key, key_len, curve, curve_bits,
629a8e1175bSopenharmony_ci                            hash, hash_len, sig, sig_len);
630a8e1175bSopenharmony_ci}
631a8e1175bSopenharmony_ci
632a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
633a8e1175bSopenharmony_cistatic int ecdsa_verify_wrap(mbedtls_pk_context *pk,
634a8e1175bSopenharmony_ci                             mbedtls_md_type_t md_alg,
635a8e1175bSopenharmony_ci                             const unsigned char *hash, size_t hash_len,
636a8e1175bSopenharmony_ci                             const unsigned char *sig, size_t sig_len)
637a8e1175bSopenharmony_ci{
638a8e1175bSopenharmony_ci    (void) md_alg;
639a8e1175bSopenharmony_ci    psa_ecc_family_t curve = pk->ec_family;
640a8e1175bSopenharmony_ci    size_t curve_bits = pk->ec_bits;
641a8e1175bSopenharmony_ci
642a8e1175bSopenharmony_ci    return ecdsa_verify_psa(pk->pub_raw, pk->pub_raw_len, curve, curve_bits,
643a8e1175bSopenharmony_ci                            hash, hash_len, sig, sig_len);
644a8e1175bSopenharmony_ci}
645a8e1175bSopenharmony_ci#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
646a8e1175bSopenharmony_cistatic int ecdsa_verify_wrap(mbedtls_pk_context *pk,
647a8e1175bSopenharmony_ci                             mbedtls_md_type_t md_alg,
648a8e1175bSopenharmony_ci                             const unsigned char *hash, size_t hash_len,
649a8e1175bSopenharmony_ci                             const unsigned char *sig, size_t sig_len)
650a8e1175bSopenharmony_ci{
651a8e1175bSopenharmony_ci    (void) md_alg;
652a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
653a8e1175bSopenharmony_ci    mbedtls_ecp_keypair *ctx = pk->pk_ctx;
654a8e1175bSopenharmony_ci    unsigned char key[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
655a8e1175bSopenharmony_ci    size_t key_len;
656a8e1175bSopenharmony_ci    size_t curve_bits;
657a8e1175bSopenharmony_ci    psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(ctx->grp.id, &curve_bits);
658a8e1175bSopenharmony_ci
659a8e1175bSopenharmony_ci    ret = mbedtls_ecp_point_write_binary(&ctx->grp, &ctx->Q,
660a8e1175bSopenharmony_ci                                         MBEDTLS_ECP_PF_UNCOMPRESSED,
661a8e1175bSopenharmony_ci                                         &key_len, key, sizeof(key));
662a8e1175bSopenharmony_ci    if (ret != 0) {
663a8e1175bSopenharmony_ci        return ret;
664a8e1175bSopenharmony_ci    }
665a8e1175bSopenharmony_ci
666a8e1175bSopenharmony_ci    return ecdsa_verify_psa(key, key_len, curve, curve_bits,
667a8e1175bSopenharmony_ci                            hash, hash_len, sig, sig_len);
668a8e1175bSopenharmony_ci}
669a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
670a8e1175bSopenharmony_ci#else /* MBEDTLS_USE_PSA_CRYPTO */
671a8e1175bSopenharmony_cistatic int ecdsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
672a8e1175bSopenharmony_ci                             const unsigned char *hash, size_t hash_len,
673a8e1175bSopenharmony_ci                             const unsigned char *sig, size_t sig_len)
674a8e1175bSopenharmony_ci{
675a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
676a8e1175bSopenharmony_ci    ((void) md_alg);
677a8e1175bSopenharmony_ci
678a8e1175bSopenharmony_ci    ret = mbedtls_ecdsa_read_signature((mbedtls_ecdsa_context *) pk->pk_ctx,
679a8e1175bSopenharmony_ci                                       hash, hash_len, sig, sig_len);
680a8e1175bSopenharmony_ci
681a8e1175bSopenharmony_ci    if (ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) {
682a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
683a8e1175bSopenharmony_ci    }
684a8e1175bSopenharmony_ci
685a8e1175bSopenharmony_ci    return ret;
686a8e1175bSopenharmony_ci}
687a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
688a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_CAN_ECDSA_VERIFY */
689a8e1175bSopenharmony_ci
690a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
691a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
692a8e1175bSopenharmony_ci/* Common helper for ECDSA sign using PSA functions.
693a8e1175bSopenharmony_ci * Instead of extracting key's properties in order to check which kind of ECDSA
694a8e1175bSopenharmony_ci * signature it supports, we try both deterministic and non-deterministic.
695a8e1175bSopenharmony_ci */
696a8e1175bSopenharmony_cistatic int ecdsa_sign_psa(mbedtls_svc_key_id_t key_id, mbedtls_md_type_t md_alg,
697a8e1175bSopenharmony_ci                          const unsigned char *hash, size_t hash_len,
698a8e1175bSopenharmony_ci                          unsigned char *sig, size_t sig_size, size_t *sig_len)
699a8e1175bSopenharmony_ci{
700a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
701a8e1175bSopenharmony_ci    psa_status_t status;
702a8e1175bSopenharmony_ci    psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
703a8e1175bSopenharmony_ci    size_t key_bits = 0;
704a8e1175bSopenharmony_ci
705a8e1175bSopenharmony_ci    status = psa_get_key_attributes(key_id, &key_attr);
706a8e1175bSopenharmony_ci    if (status != PSA_SUCCESS) {
707a8e1175bSopenharmony_ci        return PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
708a8e1175bSopenharmony_ci    }
709a8e1175bSopenharmony_ci    key_bits = psa_get_key_bits(&key_attr);
710a8e1175bSopenharmony_ci    psa_reset_key_attributes(&key_attr);
711a8e1175bSopenharmony_ci
712a8e1175bSopenharmony_ci    status = psa_sign_hash(key_id,
713a8e1175bSopenharmony_ci                           PSA_ALG_DETERMINISTIC_ECDSA(mbedtls_md_psa_alg_from_type(md_alg)),
714a8e1175bSopenharmony_ci                           hash, hash_len, sig, sig_size, sig_len);
715a8e1175bSopenharmony_ci    if (status == PSA_SUCCESS) {
716a8e1175bSopenharmony_ci        goto done;
717a8e1175bSopenharmony_ci    } else if (status != PSA_ERROR_NOT_PERMITTED) {
718a8e1175bSopenharmony_ci        return PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
719a8e1175bSopenharmony_ci    }
720a8e1175bSopenharmony_ci
721a8e1175bSopenharmony_ci    status = psa_sign_hash(key_id,
722a8e1175bSopenharmony_ci                           PSA_ALG_ECDSA(mbedtls_md_psa_alg_from_type(md_alg)),
723a8e1175bSopenharmony_ci                           hash, hash_len, sig, sig_size, sig_len);
724a8e1175bSopenharmony_ci    if (status != PSA_SUCCESS) {
725a8e1175bSopenharmony_ci        return PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
726a8e1175bSopenharmony_ci    }
727a8e1175bSopenharmony_ci
728a8e1175bSopenharmony_cidone:
729a8e1175bSopenharmony_ci    ret = mbedtls_ecdsa_raw_to_der(key_bits, sig, *sig_len, sig, sig_size, sig_len);
730a8e1175bSopenharmony_ci
731a8e1175bSopenharmony_ci    return ret;
732a8e1175bSopenharmony_ci}
733a8e1175bSopenharmony_ci
734a8e1175bSopenharmony_cistatic int ecdsa_opaque_sign_wrap(mbedtls_pk_context *pk,
735a8e1175bSopenharmony_ci                                  mbedtls_md_type_t md_alg,
736a8e1175bSopenharmony_ci                                  const unsigned char *hash, size_t hash_len,
737a8e1175bSopenharmony_ci                                  unsigned char *sig, size_t sig_size,
738a8e1175bSopenharmony_ci                                  size_t *sig_len,
739a8e1175bSopenharmony_ci                                  int (*f_rng)(void *, unsigned char *, size_t),
740a8e1175bSopenharmony_ci                                  void *p_rng)
741a8e1175bSopenharmony_ci{
742a8e1175bSopenharmony_ci    ((void) f_rng);
743a8e1175bSopenharmony_ci    ((void) p_rng);
744a8e1175bSopenharmony_ci
745a8e1175bSopenharmony_ci    return ecdsa_sign_psa(pk->priv_id, md_alg, hash, hash_len, sig, sig_size,
746a8e1175bSopenharmony_ci                          sig_len);
747a8e1175bSopenharmony_ci}
748a8e1175bSopenharmony_ci
749a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
750a8e1175bSopenharmony_ci/* When PK_USE_PSA_EC_DATA is defined opaque and non-opaque keys end up
751a8e1175bSopenharmony_ci * using the same function. */
752a8e1175bSopenharmony_ci#define ecdsa_sign_wrap     ecdsa_opaque_sign_wrap
753a8e1175bSopenharmony_ci#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
754a8e1175bSopenharmony_cistatic int ecdsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
755a8e1175bSopenharmony_ci                           const unsigned char *hash, size_t hash_len,
756a8e1175bSopenharmony_ci                           unsigned char *sig, size_t sig_size, size_t *sig_len,
757a8e1175bSopenharmony_ci                           int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
758a8e1175bSopenharmony_ci{
759a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
760a8e1175bSopenharmony_ci    mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
761a8e1175bSopenharmony_ci    psa_status_t status;
762a8e1175bSopenharmony_ci    mbedtls_ecp_keypair *ctx = pk->pk_ctx;
763a8e1175bSopenharmony_ci    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
764a8e1175bSopenharmony_ci    unsigned char buf[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH];
765a8e1175bSopenharmony_ci    size_t curve_bits;
766a8e1175bSopenharmony_ci    psa_ecc_family_t curve =
767a8e1175bSopenharmony_ci        mbedtls_ecc_group_to_psa(ctx->grp.id, &curve_bits);
768a8e1175bSopenharmony_ci    size_t key_len = PSA_BITS_TO_BYTES(curve_bits);
769a8e1175bSopenharmony_ci    psa_algorithm_t psa_hash = mbedtls_md_psa_alg_from_type(md_alg);
770a8e1175bSopenharmony_ci    psa_algorithm_t psa_sig_md = MBEDTLS_PK_PSA_ALG_ECDSA_MAYBE_DET(psa_hash);
771a8e1175bSopenharmony_ci    ((void) f_rng);
772a8e1175bSopenharmony_ci    ((void) p_rng);
773a8e1175bSopenharmony_ci
774a8e1175bSopenharmony_ci    if (curve == 0) {
775a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
776a8e1175bSopenharmony_ci    }
777a8e1175bSopenharmony_ci
778a8e1175bSopenharmony_ci    if (key_len > sizeof(buf)) {
779a8e1175bSopenharmony_ci        return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
780a8e1175bSopenharmony_ci    }
781a8e1175bSopenharmony_ci    ret = mbedtls_mpi_write_binary(&ctx->d, buf, key_len);
782a8e1175bSopenharmony_ci    if (ret != 0) {
783a8e1175bSopenharmony_ci        goto cleanup;
784a8e1175bSopenharmony_ci    }
785a8e1175bSopenharmony_ci
786a8e1175bSopenharmony_ci    psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
787a8e1175bSopenharmony_ci    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
788a8e1175bSopenharmony_ci    psa_set_key_algorithm(&attributes, psa_sig_md);
789a8e1175bSopenharmony_ci
790a8e1175bSopenharmony_ci    status = psa_import_key(&attributes, buf, key_len, &key_id);
791a8e1175bSopenharmony_ci    if (status != PSA_SUCCESS) {
792a8e1175bSopenharmony_ci        ret = PSA_PK_TO_MBEDTLS_ERR(status);
793a8e1175bSopenharmony_ci        goto cleanup;
794a8e1175bSopenharmony_ci    }
795a8e1175bSopenharmony_ci
796a8e1175bSopenharmony_ci    ret = ecdsa_sign_psa(key_id, md_alg, hash, hash_len, sig, sig_size, sig_len);
797a8e1175bSopenharmony_ci
798a8e1175bSopenharmony_cicleanup:
799a8e1175bSopenharmony_ci    mbedtls_platform_zeroize(buf, sizeof(buf));
800a8e1175bSopenharmony_ci    status = psa_destroy_key(key_id);
801a8e1175bSopenharmony_ci    if (ret == 0 && status != PSA_SUCCESS) {
802a8e1175bSopenharmony_ci        ret = PSA_PK_TO_MBEDTLS_ERR(status);
803a8e1175bSopenharmony_ci    }
804a8e1175bSopenharmony_ci
805a8e1175bSopenharmony_ci    return ret;
806a8e1175bSopenharmony_ci}
807a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
808a8e1175bSopenharmony_ci#else /* MBEDTLS_USE_PSA_CRYPTO */
809a8e1175bSopenharmony_cistatic int ecdsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
810a8e1175bSopenharmony_ci                           const unsigned char *hash, size_t hash_len,
811a8e1175bSopenharmony_ci                           unsigned char *sig, size_t sig_size, size_t *sig_len,
812a8e1175bSopenharmony_ci                           int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
813a8e1175bSopenharmony_ci{
814a8e1175bSopenharmony_ci    return mbedtls_ecdsa_write_signature((mbedtls_ecdsa_context *) pk->pk_ctx,
815a8e1175bSopenharmony_ci                                         md_alg, hash, hash_len,
816a8e1175bSopenharmony_ci                                         sig, sig_size, sig_len,
817a8e1175bSopenharmony_ci                                         f_rng, p_rng);
818a8e1175bSopenharmony_ci}
819a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
820a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_CAN_ECDSA_SIGN */
821a8e1175bSopenharmony_ci
822a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
823a8e1175bSopenharmony_ci/* Forward declarations */
824a8e1175bSopenharmony_cistatic int ecdsa_verify_rs_wrap(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
825a8e1175bSopenharmony_ci                                const unsigned char *hash, size_t hash_len,
826a8e1175bSopenharmony_ci                                const unsigned char *sig, size_t sig_len,
827a8e1175bSopenharmony_ci                                void *rs_ctx);
828a8e1175bSopenharmony_ci
829a8e1175bSopenharmony_cistatic int ecdsa_sign_rs_wrap(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
830a8e1175bSopenharmony_ci                              const unsigned char *hash, size_t hash_len,
831a8e1175bSopenharmony_ci                              unsigned char *sig, size_t sig_size, size_t *sig_len,
832a8e1175bSopenharmony_ci                              int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
833a8e1175bSopenharmony_ci                              void *rs_ctx);
834a8e1175bSopenharmony_ci
835a8e1175bSopenharmony_ci/*
836a8e1175bSopenharmony_ci * Restart context for ECDSA operations with ECKEY context
837a8e1175bSopenharmony_ci *
838a8e1175bSopenharmony_ci * We need to store an actual ECDSA context, as we need to pass the same to
839a8e1175bSopenharmony_ci * the underlying ecdsa function, so we can't create it on the fly every time.
840a8e1175bSopenharmony_ci */
841a8e1175bSopenharmony_citypedef struct {
842a8e1175bSopenharmony_ci    mbedtls_ecdsa_restart_ctx ecdsa_rs;
843a8e1175bSopenharmony_ci    mbedtls_ecdsa_context ecdsa_ctx;
844a8e1175bSopenharmony_ci} eckey_restart_ctx;
845a8e1175bSopenharmony_ci
846a8e1175bSopenharmony_cistatic void *eckey_rs_alloc(void)
847a8e1175bSopenharmony_ci{
848a8e1175bSopenharmony_ci    eckey_restart_ctx *rs_ctx;
849a8e1175bSopenharmony_ci
850a8e1175bSopenharmony_ci    void *ctx = mbedtls_calloc(1, sizeof(eckey_restart_ctx));
851a8e1175bSopenharmony_ci
852a8e1175bSopenharmony_ci    if (ctx != NULL) {
853a8e1175bSopenharmony_ci        rs_ctx = ctx;
854a8e1175bSopenharmony_ci        mbedtls_ecdsa_restart_init(&rs_ctx->ecdsa_rs);
855a8e1175bSopenharmony_ci        mbedtls_ecdsa_init(&rs_ctx->ecdsa_ctx);
856a8e1175bSopenharmony_ci    }
857a8e1175bSopenharmony_ci
858a8e1175bSopenharmony_ci    return ctx;
859a8e1175bSopenharmony_ci}
860a8e1175bSopenharmony_ci
861a8e1175bSopenharmony_cistatic void eckey_rs_free(void *ctx)
862a8e1175bSopenharmony_ci{
863a8e1175bSopenharmony_ci    eckey_restart_ctx *rs_ctx;
864a8e1175bSopenharmony_ci
865a8e1175bSopenharmony_ci    if (ctx == NULL) {
866a8e1175bSopenharmony_ci        return;
867a8e1175bSopenharmony_ci    }
868a8e1175bSopenharmony_ci
869a8e1175bSopenharmony_ci    rs_ctx = ctx;
870a8e1175bSopenharmony_ci    mbedtls_ecdsa_restart_free(&rs_ctx->ecdsa_rs);
871a8e1175bSopenharmony_ci    mbedtls_ecdsa_free(&rs_ctx->ecdsa_ctx);
872a8e1175bSopenharmony_ci
873a8e1175bSopenharmony_ci    mbedtls_free(ctx);
874a8e1175bSopenharmony_ci}
875a8e1175bSopenharmony_ci
876a8e1175bSopenharmony_cistatic int eckey_verify_rs_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
877a8e1175bSopenharmony_ci                                const unsigned char *hash, size_t hash_len,
878a8e1175bSopenharmony_ci                                const unsigned char *sig, size_t sig_len,
879a8e1175bSopenharmony_ci                                void *rs_ctx)
880a8e1175bSopenharmony_ci{
881a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
882a8e1175bSopenharmony_ci    eckey_restart_ctx *rs = rs_ctx;
883a8e1175bSopenharmony_ci
884a8e1175bSopenharmony_ci    /* Should never happen */
885a8e1175bSopenharmony_ci    if (rs == NULL) {
886a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
887a8e1175bSopenharmony_ci    }
888a8e1175bSopenharmony_ci
889a8e1175bSopenharmony_ci    /* set up our own sub-context if needed (that is, on first run) */
890a8e1175bSopenharmony_ci    if (rs->ecdsa_ctx.grp.pbits == 0) {
891a8e1175bSopenharmony_ci        MBEDTLS_MPI_CHK(mbedtls_ecdsa_from_keypair(&rs->ecdsa_ctx, pk->pk_ctx));
892a8e1175bSopenharmony_ci    }
893a8e1175bSopenharmony_ci
894a8e1175bSopenharmony_ci    MBEDTLS_MPI_CHK(ecdsa_verify_rs_wrap(pk,
895a8e1175bSopenharmony_ci                                         md_alg, hash, hash_len,
896a8e1175bSopenharmony_ci                                         sig, sig_len, &rs->ecdsa_rs));
897a8e1175bSopenharmony_ci
898a8e1175bSopenharmony_cicleanup:
899a8e1175bSopenharmony_ci    return ret;
900a8e1175bSopenharmony_ci}
901a8e1175bSopenharmony_ci
902a8e1175bSopenharmony_cistatic int eckey_sign_rs_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
903a8e1175bSopenharmony_ci                              const unsigned char *hash, size_t hash_len,
904a8e1175bSopenharmony_ci                              unsigned char *sig, size_t sig_size, size_t *sig_len,
905a8e1175bSopenharmony_ci                              int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
906a8e1175bSopenharmony_ci                              void *rs_ctx)
907a8e1175bSopenharmony_ci{
908a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
909a8e1175bSopenharmony_ci    eckey_restart_ctx *rs = rs_ctx;
910a8e1175bSopenharmony_ci
911a8e1175bSopenharmony_ci    /* Should never happen */
912a8e1175bSopenharmony_ci    if (rs == NULL) {
913a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
914a8e1175bSopenharmony_ci    }
915a8e1175bSopenharmony_ci
916a8e1175bSopenharmony_ci    /* set up our own sub-context if needed (that is, on first run) */
917a8e1175bSopenharmony_ci    if (rs->ecdsa_ctx.grp.pbits == 0) {
918a8e1175bSopenharmony_ci        MBEDTLS_MPI_CHK(mbedtls_ecdsa_from_keypair(&rs->ecdsa_ctx, pk->pk_ctx));
919a8e1175bSopenharmony_ci    }
920a8e1175bSopenharmony_ci
921a8e1175bSopenharmony_ci    MBEDTLS_MPI_CHK(ecdsa_sign_rs_wrap(pk, md_alg,
922a8e1175bSopenharmony_ci                                       hash, hash_len, sig, sig_size, sig_len,
923a8e1175bSopenharmony_ci                                       f_rng, p_rng, &rs->ecdsa_rs));
924a8e1175bSopenharmony_ci
925a8e1175bSopenharmony_cicleanup:
926a8e1175bSopenharmony_ci    return ret;
927a8e1175bSopenharmony_ci}
928a8e1175bSopenharmony_ci#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
929a8e1175bSopenharmony_ci
930a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
931a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
932a8e1175bSopenharmony_cistatic int eckey_check_pair_psa(mbedtls_pk_context *pub, mbedtls_pk_context *prv)
933a8e1175bSopenharmony_ci{
934a8e1175bSopenharmony_ci    psa_status_t status;
935a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
936a8e1175bSopenharmony_ci    uint8_t prv_key_buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
937a8e1175bSopenharmony_ci    size_t prv_key_len;
938a8e1175bSopenharmony_ci    mbedtls_svc_key_id_t key_id = prv->priv_id;
939a8e1175bSopenharmony_ci
940a8e1175bSopenharmony_ci    status = psa_export_public_key(key_id, prv_key_buf, sizeof(prv_key_buf),
941a8e1175bSopenharmony_ci                                   &prv_key_len);
942a8e1175bSopenharmony_ci    ret = PSA_PK_TO_MBEDTLS_ERR(status);
943a8e1175bSopenharmony_ci    if (ret != 0) {
944a8e1175bSopenharmony_ci        return ret;
945a8e1175bSopenharmony_ci    }
946a8e1175bSopenharmony_ci
947a8e1175bSopenharmony_ci    if (memcmp(prv_key_buf, pub->pub_raw, pub->pub_raw_len) != 0) {
948a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
949a8e1175bSopenharmony_ci    }
950a8e1175bSopenharmony_ci
951a8e1175bSopenharmony_ci    return 0;
952a8e1175bSopenharmony_ci}
953a8e1175bSopenharmony_ci#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
954a8e1175bSopenharmony_cistatic int eckey_check_pair_psa(mbedtls_pk_context *pub, mbedtls_pk_context *prv)
955a8e1175bSopenharmony_ci{
956a8e1175bSopenharmony_ci    psa_status_t status;
957a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
958a8e1175bSopenharmony_ci    uint8_t prv_key_buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
959a8e1175bSopenharmony_ci    size_t prv_key_len;
960a8e1175bSopenharmony_ci    psa_status_t destruction_status;
961a8e1175bSopenharmony_ci    mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
962a8e1175bSopenharmony_ci    psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
963a8e1175bSopenharmony_ci    uint8_t pub_key_buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
964a8e1175bSopenharmony_ci    size_t pub_key_len;
965a8e1175bSopenharmony_ci    size_t curve_bits;
966a8e1175bSopenharmony_ci    const psa_ecc_family_t curve =
967a8e1175bSopenharmony_ci        mbedtls_ecc_group_to_psa(mbedtls_pk_ec_ro(*prv)->grp.id, &curve_bits);
968a8e1175bSopenharmony_ci    const size_t curve_bytes = PSA_BITS_TO_BYTES(curve_bits);
969a8e1175bSopenharmony_ci
970a8e1175bSopenharmony_ci    if (curve == 0) {
971a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
972a8e1175bSopenharmony_ci    }
973a8e1175bSopenharmony_ci
974a8e1175bSopenharmony_ci    psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
975a8e1175bSopenharmony_ci    psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT);
976a8e1175bSopenharmony_ci
977a8e1175bSopenharmony_ci    ret = mbedtls_mpi_write_binary(&mbedtls_pk_ec_ro(*prv)->d,
978a8e1175bSopenharmony_ci                                   prv_key_buf, curve_bytes);
979a8e1175bSopenharmony_ci    if (ret != 0) {
980a8e1175bSopenharmony_ci        mbedtls_platform_zeroize(prv_key_buf, sizeof(prv_key_buf));
981a8e1175bSopenharmony_ci        return ret;
982a8e1175bSopenharmony_ci    }
983a8e1175bSopenharmony_ci
984a8e1175bSopenharmony_ci    status = psa_import_key(&key_attr, prv_key_buf, curve_bytes, &key_id);
985a8e1175bSopenharmony_ci    mbedtls_platform_zeroize(prv_key_buf, sizeof(prv_key_buf));
986a8e1175bSopenharmony_ci    ret = PSA_PK_TO_MBEDTLS_ERR(status);
987a8e1175bSopenharmony_ci    if (ret != 0) {
988a8e1175bSopenharmony_ci        return ret;
989a8e1175bSopenharmony_ci    }
990a8e1175bSopenharmony_ci
991a8e1175bSopenharmony_ci    // From now on prv_key_buf is used to store the public key of prv.
992a8e1175bSopenharmony_ci    status = psa_export_public_key(key_id, prv_key_buf, sizeof(prv_key_buf),
993a8e1175bSopenharmony_ci                                   &prv_key_len);
994a8e1175bSopenharmony_ci    ret = PSA_PK_TO_MBEDTLS_ERR(status);
995a8e1175bSopenharmony_ci    destruction_status = psa_destroy_key(key_id);
996a8e1175bSopenharmony_ci    if (ret != 0) {
997a8e1175bSopenharmony_ci        return ret;
998a8e1175bSopenharmony_ci    } else if (destruction_status != PSA_SUCCESS) {
999a8e1175bSopenharmony_ci        return PSA_PK_TO_MBEDTLS_ERR(destruction_status);
1000a8e1175bSopenharmony_ci    }
1001a8e1175bSopenharmony_ci
1002a8e1175bSopenharmony_ci    ret = mbedtls_ecp_point_write_binary(&mbedtls_pk_ec_rw(*pub)->grp,
1003a8e1175bSopenharmony_ci                                         &mbedtls_pk_ec_rw(*pub)->Q,
1004a8e1175bSopenharmony_ci                                         MBEDTLS_ECP_PF_UNCOMPRESSED,
1005a8e1175bSopenharmony_ci                                         &pub_key_len, pub_key_buf,
1006a8e1175bSopenharmony_ci                                         sizeof(pub_key_buf));
1007a8e1175bSopenharmony_ci    if (ret != 0) {
1008a8e1175bSopenharmony_ci        return ret;
1009a8e1175bSopenharmony_ci    }
1010a8e1175bSopenharmony_ci
1011a8e1175bSopenharmony_ci    if (memcmp(prv_key_buf, pub_key_buf, curve_bytes) != 0) {
1012a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1013a8e1175bSopenharmony_ci    }
1014a8e1175bSopenharmony_ci
1015a8e1175bSopenharmony_ci    return 0;
1016a8e1175bSopenharmony_ci}
1017a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1018a8e1175bSopenharmony_ci
1019a8e1175bSopenharmony_cistatic int eckey_check_pair_wrap(mbedtls_pk_context *pub, mbedtls_pk_context *prv,
1020a8e1175bSopenharmony_ci                                 int (*f_rng)(void *, unsigned char *, size_t),
1021a8e1175bSopenharmony_ci                                 void *p_rng)
1022a8e1175bSopenharmony_ci{
1023a8e1175bSopenharmony_ci    (void) f_rng;
1024a8e1175bSopenharmony_ci    (void) p_rng;
1025a8e1175bSopenharmony_ci    return eckey_check_pair_psa(pub, prv);
1026a8e1175bSopenharmony_ci}
1027a8e1175bSopenharmony_ci#else /* MBEDTLS_USE_PSA_CRYPTO */
1028a8e1175bSopenharmony_cistatic int eckey_check_pair_wrap(mbedtls_pk_context *pub, mbedtls_pk_context *prv,
1029a8e1175bSopenharmony_ci                                 int (*f_rng)(void *, unsigned char *, size_t),
1030a8e1175bSopenharmony_ci                                 void *p_rng)
1031a8e1175bSopenharmony_ci{
1032a8e1175bSopenharmony_ci    return mbedtls_ecp_check_pub_priv((const mbedtls_ecp_keypair *) pub->pk_ctx,
1033a8e1175bSopenharmony_ci                                      (const mbedtls_ecp_keypair *) prv->pk_ctx,
1034a8e1175bSopenharmony_ci                                      f_rng, p_rng);
1035a8e1175bSopenharmony_ci}
1036a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
1037a8e1175bSopenharmony_ci
1038a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1039a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1040a8e1175bSopenharmony_ci/* When PK_USE_PSA_EC_DATA is defined opaque and non-opaque keys end up
1041a8e1175bSopenharmony_ci * using the same function. */
1042a8e1175bSopenharmony_ci#define ecdsa_opaque_check_pair_wrap    eckey_check_pair_wrap
1043a8e1175bSopenharmony_ci#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
1044a8e1175bSopenharmony_cistatic int ecdsa_opaque_check_pair_wrap(mbedtls_pk_context *pub,
1045a8e1175bSopenharmony_ci                                        mbedtls_pk_context *prv,
1046a8e1175bSopenharmony_ci                                        int (*f_rng)(void *, unsigned char *, size_t),
1047a8e1175bSopenharmony_ci                                        void *p_rng)
1048a8e1175bSopenharmony_ci{
1049a8e1175bSopenharmony_ci    psa_status_t status;
1050a8e1175bSopenharmony_ci    uint8_t exp_pub_key[MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN];
1051a8e1175bSopenharmony_ci    size_t exp_pub_key_len = 0;
1052a8e1175bSopenharmony_ci    uint8_t pub_key[MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN];
1053a8e1175bSopenharmony_ci    size_t pub_key_len = 0;
1054a8e1175bSopenharmony_ci    int ret;
1055a8e1175bSopenharmony_ci    (void) f_rng;
1056a8e1175bSopenharmony_ci    (void) p_rng;
1057a8e1175bSopenharmony_ci
1058a8e1175bSopenharmony_ci    status = psa_export_public_key(prv->priv_id, exp_pub_key, sizeof(exp_pub_key),
1059a8e1175bSopenharmony_ci                                   &exp_pub_key_len);
1060a8e1175bSopenharmony_ci    if (status != PSA_SUCCESS) {
1061a8e1175bSopenharmony_ci        ret = psa_pk_status_to_mbedtls(status);
1062a8e1175bSopenharmony_ci        return ret;
1063a8e1175bSopenharmony_ci    }
1064a8e1175bSopenharmony_ci    ret = mbedtls_ecp_point_write_binary(&(mbedtls_pk_ec_ro(*pub)->grp),
1065a8e1175bSopenharmony_ci                                         &(mbedtls_pk_ec_ro(*pub)->Q),
1066a8e1175bSopenharmony_ci                                         MBEDTLS_ECP_PF_UNCOMPRESSED,
1067a8e1175bSopenharmony_ci                                         &pub_key_len, pub_key, sizeof(pub_key));
1068a8e1175bSopenharmony_ci    if (ret != 0) {
1069a8e1175bSopenharmony_ci        return ret;
1070a8e1175bSopenharmony_ci    }
1071a8e1175bSopenharmony_ci    if ((exp_pub_key_len != pub_key_len) ||
1072a8e1175bSopenharmony_ci        memcmp(exp_pub_key, pub_key, exp_pub_key_len)) {
1073a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1074a8e1175bSopenharmony_ci    }
1075a8e1175bSopenharmony_ci    return 0;
1076a8e1175bSopenharmony_ci}
1077a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1078a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
1079a8e1175bSopenharmony_ci
1080a8e1175bSopenharmony_ci#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1081a8e1175bSopenharmony_cistatic void *eckey_alloc_wrap(void)
1082a8e1175bSopenharmony_ci{
1083a8e1175bSopenharmony_ci    void *ctx = mbedtls_calloc(1, sizeof(mbedtls_ecp_keypair));
1084a8e1175bSopenharmony_ci
1085a8e1175bSopenharmony_ci    if (ctx != NULL) {
1086a8e1175bSopenharmony_ci        mbedtls_ecp_keypair_init(ctx);
1087a8e1175bSopenharmony_ci    }
1088a8e1175bSopenharmony_ci
1089a8e1175bSopenharmony_ci    return ctx;
1090a8e1175bSopenharmony_ci}
1091a8e1175bSopenharmony_ci
1092a8e1175bSopenharmony_cistatic void eckey_free_wrap(void *ctx)
1093a8e1175bSopenharmony_ci{
1094a8e1175bSopenharmony_ci    mbedtls_ecp_keypair_free((mbedtls_ecp_keypair *) ctx);
1095a8e1175bSopenharmony_ci    mbedtls_free(ctx);
1096a8e1175bSopenharmony_ci}
1097a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1098a8e1175bSopenharmony_ci
1099a8e1175bSopenharmony_cistatic void eckey_debug(mbedtls_pk_context *pk, mbedtls_pk_debug_item *items)
1100a8e1175bSopenharmony_ci{
1101a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1102a8e1175bSopenharmony_ci    items->type = MBEDTLS_PK_DEBUG_PSA_EC;
1103a8e1175bSopenharmony_ci    items->name = "eckey.Q";
1104a8e1175bSopenharmony_ci    items->value = pk;
1105a8e1175bSopenharmony_ci#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
1106a8e1175bSopenharmony_ci    mbedtls_ecp_keypair *ecp = (mbedtls_ecp_keypair *) pk->pk_ctx;
1107a8e1175bSopenharmony_ci    items->type = MBEDTLS_PK_DEBUG_ECP;
1108a8e1175bSopenharmony_ci    items->name = "eckey.Q";
1109a8e1175bSopenharmony_ci    items->value = &(ecp->Q);
1110a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1111a8e1175bSopenharmony_ci}
1112a8e1175bSopenharmony_ci
1113a8e1175bSopenharmony_ciconst mbedtls_pk_info_t mbedtls_eckey_info = {
1114a8e1175bSopenharmony_ci    .type = MBEDTLS_PK_ECKEY,
1115a8e1175bSopenharmony_ci    .name = "EC",
1116a8e1175bSopenharmony_ci    .get_bitlen = eckey_get_bitlen,
1117a8e1175bSopenharmony_ci    .can_do = eckey_can_do,
1118a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY)
1119a8e1175bSopenharmony_ci    .verify_func = ecdsa_verify_wrap,   /* Compatible key structures */
1120a8e1175bSopenharmony_ci#else /* MBEDTLS_PK_CAN_ECDSA_VERIFY */
1121a8e1175bSopenharmony_ci    .verify_func = NULL,
1122a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_CAN_ECDSA_VERIFY */
1123a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
1124a8e1175bSopenharmony_ci    .sign_func = ecdsa_sign_wrap,   /* Compatible key structures */
1125a8e1175bSopenharmony_ci#else /* MBEDTLS_PK_CAN_ECDSA_VERIFY */
1126a8e1175bSopenharmony_ci    .sign_func = NULL,
1127a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_CAN_ECDSA_VERIFY */
1128a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
1129a8e1175bSopenharmony_ci    .verify_rs_func = eckey_verify_rs_wrap,
1130a8e1175bSopenharmony_ci    .sign_rs_func = eckey_sign_rs_wrap,
1131a8e1175bSopenharmony_ci    .rs_alloc_func = eckey_rs_alloc,
1132a8e1175bSopenharmony_ci    .rs_free_func = eckey_rs_free,
1133a8e1175bSopenharmony_ci#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
1134a8e1175bSopenharmony_ci    .decrypt_func = NULL,
1135a8e1175bSopenharmony_ci    .encrypt_func = NULL,
1136a8e1175bSopenharmony_ci    .check_pair_func = eckey_check_pair_wrap,
1137a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1138a8e1175bSopenharmony_ci    .ctx_alloc_func = NULL,
1139a8e1175bSopenharmony_ci    .ctx_free_func = NULL,
1140a8e1175bSopenharmony_ci#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
1141a8e1175bSopenharmony_ci    .ctx_alloc_func = eckey_alloc_wrap,
1142a8e1175bSopenharmony_ci    .ctx_free_func = eckey_free_wrap,
1143a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1144a8e1175bSopenharmony_ci    .debug_func = eckey_debug,
1145a8e1175bSopenharmony_ci};
1146a8e1175bSopenharmony_ci
1147a8e1175bSopenharmony_ci/*
1148a8e1175bSopenharmony_ci * EC key restricted to ECDH
1149a8e1175bSopenharmony_ci */
1150a8e1175bSopenharmony_cistatic int eckeydh_can_do(mbedtls_pk_type_t type)
1151a8e1175bSopenharmony_ci{
1152a8e1175bSopenharmony_ci    return type == MBEDTLS_PK_ECKEY ||
1153a8e1175bSopenharmony_ci           type == MBEDTLS_PK_ECKEY_DH;
1154a8e1175bSopenharmony_ci}
1155a8e1175bSopenharmony_ci
1156a8e1175bSopenharmony_ciconst mbedtls_pk_info_t mbedtls_eckeydh_info = {
1157a8e1175bSopenharmony_ci    .type = MBEDTLS_PK_ECKEY_DH,
1158a8e1175bSopenharmony_ci    .name = "EC_DH",
1159a8e1175bSopenharmony_ci    .get_bitlen = eckey_get_bitlen,         /* Same underlying key structure */
1160a8e1175bSopenharmony_ci    .can_do = eckeydh_can_do,
1161a8e1175bSopenharmony_ci    .verify_func = NULL,
1162a8e1175bSopenharmony_ci    .sign_func = NULL,
1163a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
1164a8e1175bSopenharmony_ci    .verify_rs_func = NULL,
1165a8e1175bSopenharmony_ci    .sign_rs_func = NULL,
1166a8e1175bSopenharmony_ci#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
1167a8e1175bSopenharmony_ci    .decrypt_func = NULL,
1168a8e1175bSopenharmony_ci    .encrypt_func = NULL,
1169a8e1175bSopenharmony_ci    .check_pair_func = eckey_check_pair_wrap,
1170a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1171a8e1175bSopenharmony_ci    .ctx_alloc_func = NULL,
1172a8e1175bSopenharmony_ci    .ctx_free_func = NULL,
1173a8e1175bSopenharmony_ci#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
1174a8e1175bSopenharmony_ci    .ctx_alloc_func = eckey_alloc_wrap,   /* Same underlying key structure */
1175a8e1175bSopenharmony_ci    .ctx_free_func = eckey_free_wrap,    /* Same underlying key structure */
1176a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1177a8e1175bSopenharmony_ci    .debug_func = eckey_debug,            /* Same underlying key structure */
1178a8e1175bSopenharmony_ci};
1179a8e1175bSopenharmony_ci
1180a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_CAN_ECDSA_SOME)
1181a8e1175bSopenharmony_cistatic int ecdsa_can_do(mbedtls_pk_type_t type)
1182a8e1175bSopenharmony_ci{
1183a8e1175bSopenharmony_ci    return type == MBEDTLS_PK_ECDSA;
1184a8e1175bSopenharmony_ci}
1185a8e1175bSopenharmony_ci
1186a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
1187a8e1175bSopenharmony_cistatic int ecdsa_verify_rs_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
1188a8e1175bSopenharmony_ci                                const unsigned char *hash, size_t hash_len,
1189a8e1175bSopenharmony_ci                                const unsigned char *sig, size_t sig_len,
1190a8e1175bSopenharmony_ci                                void *rs_ctx)
1191a8e1175bSopenharmony_ci{
1192a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1193a8e1175bSopenharmony_ci    ((void) md_alg);
1194a8e1175bSopenharmony_ci
1195a8e1175bSopenharmony_ci    ret = mbedtls_ecdsa_read_signature_restartable(
1196a8e1175bSopenharmony_ci        (mbedtls_ecdsa_context *) pk->pk_ctx,
1197a8e1175bSopenharmony_ci        hash, hash_len, sig, sig_len,
1198a8e1175bSopenharmony_ci        (mbedtls_ecdsa_restart_ctx *) rs_ctx);
1199a8e1175bSopenharmony_ci
1200a8e1175bSopenharmony_ci    if (ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) {
1201a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
1202a8e1175bSopenharmony_ci    }
1203a8e1175bSopenharmony_ci
1204a8e1175bSopenharmony_ci    return ret;
1205a8e1175bSopenharmony_ci}
1206a8e1175bSopenharmony_ci
1207a8e1175bSopenharmony_cistatic int ecdsa_sign_rs_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
1208a8e1175bSopenharmony_ci                              const unsigned char *hash, size_t hash_len,
1209a8e1175bSopenharmony_ci                              unsigned char *sig, size_t sig_size, size_t *sig_len,
1210a8e1175bSopenharmony_ci                              int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
1211a8e1175bSopenharmony_ci                              void *rs_ctx)
1212a8e1175bSopenharmony_ci{
1213a8e1175bSopenharmony_ci    return mbedtls_ecdsa_write_signature_restartable(
1214a8e1175bSopenharmony_ci        (mbedtls_ecdsa_context *) pk->pk_ctx,
1215a8e1175bSopenharmony_ci        md_alg, hash, hash_len, sig, sig_size, sig_len, f_rng, p_rng,
1216a8e1175bSopenharmony_ci        (mbedtls_ecdsa_restart_ctx *) rs_ctx);
1217a8e1175bSopenharmony_ci
1218a8e1175bSopenharmony_ci}
1219a8e1175bSopenharmony_ci
1220a8e1175bSopenharmony_cistatic void *ecdsa_rs_alloc(void)
1221a8e1175bSopenharmony_ci{
1222a8e1175bSopenharmony_ci    void *ctx = mbedtls_calloc(1, sizeof(mbedtls_ecdsa_restart_ctx));
1223a8e1175bSopenharmony_ci
1224a8e1175bSopenharmony_ci    if (ctx != NULL) {
1225a8e1175bSopenharmony_ci        mbedtls_ecdsa_restart_init(ctx);
1226a8e1175bSopenharmony_ci    }
1227a8e1175bSopenharmony_ci
1228a8e1175bSopenharmony_ci    return ctx;
1229a8e1175bSopenharmony_ci}
1230a8e1175bSopenharmony_ci
1231a8e1175bSopenharmony_cistatic void ecdsa_rs_free(void *ctx)
1232a8e1175bSopenharmony_ci{
1233a8e1175bSopenharmony_ci    mbedtls_ecdsa_restart_free(ctx);
1234a8e1175bSopenharmony_ci    mbedtls_free(ctx);
1235a8e1175bSopenharmony_ci}
1236a8e1175bSopenharmony_ci#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
1237a8e1175bSopenharmony_ci
1238a8e1175bSopenharmony_ciconst mbedtls_pk_info_t mbedtls_ecdsa_info = {
1239a8e1175bSopenharmony_ci    .type = MBEDTLS_PK_ECDSA,
1240a8e1175bSopenharmony_ci    .name = "ECDSA",
1241a8e1175bSopenharmony_ci    .get_bitlen = eckey_get_bitlen,     /* Compatible key structures */
1242a8e1175bSopenharmony_ci    .can_do = ecdsa_can_do,
1243a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY)
1244a8e1175bSopenharmony_ci    .verify_func = ecdsa_verify_wrap,   /* Compatible key structures */
1245a8e1175bSopenharmony_ci#else /* MBEDTLS_PK_CAN_ECDSA_VERIFY */
1246a8e1175bSopenharmony_ci    .verify_func = NULL,
1247a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_CAN_ECDSA_VERIFY */
1248a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
1249a8e1175bSopenharmony_ci    .sign_func = ecdsa_sign_wrap,   /* Compatible key structures */
1250a8e1175bSopenharmony_ci#else /* MBEDTLS_PK_CAN_ECDSA_SIGN */
1251a8e1175bSopenharmony_ci    .sign_func = NULL,
1252a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_CAN_ECDSA_SIGN */
1253a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
1254a8e1175bSopenharmony_ci    .verify_rs_func = ecdsa_verify_rs_wrap,
1255a8e1175bSopenharmony_ci    .sign_rs_func = ecdsa_sign_rs_wrap,
1256a8e1175bSopenharmony_ci    .rs_alloc_func = ecdsa_rs_alloc,
1257a8e1175bSopenharmony_ci    .rs_free_func = ecdsa_rs_free,
1258a8e1175bSopenharmony_ci#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
1259a8e1175bSopenharmony_ci    .decrypt_func = NULL,
1260a8e1175bSopenharmony_ci    .encrypt_func = NULL,
1261a8e1175bSopenharmony_ci    .check_pair_func = eckey_check_pair_wrap,   /* Compatible key structures */
1262a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1263a8e1175bSopenharmony_ci    .ctx_alloc_func = NULL,
1264a8e1175bSopenharmony_ci    .ctx_free_func = NULL,
1265a8e1175bSopenharmony_ci#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
1266a8e1175bSopenharmony_ci    .ctx_alloc_func = eckey_alloc_wrap,   /* Compatible key structures */
1267a8e1175bSopenharmony_ci    .ctx_free_func = eckey_free_wrap,   /* Compatible key structures */
1268a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1269a8e1175bSopenharmony_ci    .debug_func = eckey_debug,        /* Compatible key structures */
1270a8e1175bSopenharmony_ci};
1271a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_CAN_ECDSA_SOME */
1272a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
1273a8e1175bSopenharmony_ci
1274a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
1275a8e1175bSopenharmony_ci/*
1276a8e1175bSopenharmony_ci * Support for alternative RSA-private implementations
1277a8e1175bSopenharmony_ci */
1278a8e1175bSopenharmony_ci
1279a8e1175bSopenharmony_cistatic int rsa_alt_can_do(mbedtls_pk_type_t type)
1280a8e1175bSopenharmony_ci{
1281a8e1175bSopenharmony_ci    return type == MBEDTLS_PK_RSA;
1282a8e1175bSopenharmony_ci}
1283a8e1175bSopenharmony_ci
1284a8e1175bSopenharmony_cistatic size_t rsa_alt_get_bitlen(mbedtls_pk_context *pk)
1285a8e1175bSopenharmony_ci{
1286a8e1175bSopenharmony_ci    const mbedtls_rsa_alt_context *rsa_alt = pk->pk_ctx;
1287a8e1175bSopenharmony_ci
1288a8e1175bSopenharmony_ci    return 8 * rsa_alt->key_len_func(rsa_alt->key);
1289a8e1175bSopenharmony_ci}
1290a8e1175bSopenharmony_ci
1291a8e1175bSopenharmony_cistatic int rsa_alt_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
1292a8e1175bSopenharmony_ci                             const unsigned char *hash, size_t hash_len,
1293a8e1175bSopenharmony_ci                             unsigned char *sig, size_t sig_size, size_t *sig_len,
1294a8e1175bSopenharmony_ci                             int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
1295a8e1175bSopenharmony_ci{
1296a8e1175bSopenharmony_ci    mbedtls_rsa_alt_context *rsa_alt = pk->pk_ctx;
1297a8e1175bSopenharmony_ci
1298a8e1175bSopenharmony_ci#if SIZE_MAX > UINT_MAX
1299a8e1175bSopenharmony_ci    if (UINT_MAX < hash_len) {
1300a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1301a8e1175bSopenharmony_ci    }
1302a8e1175bSopenharmony_ci#endif
1303a8e1175bSopenharmony_ci
1304a8e1175bSopenharmony_ci    *sig_len = rsa_alt->key_len_func(rsa_alt->key);
1305a8e1175bSopenharmony_ci    if (*sig_len > MBEDTLS_PK_SIGNATURE_MAX_SIZE) {
1306a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1307a8e1175bSopenharmony_ci    }
1308a8e1175bSopenharmony_ci    if (*sig_len > sig_size) {
1309a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
1310a8e1175bSopenharmony_ci    }
1311a8e1175bSopenharmony_ci
1312a8e1175bSopenharmony_ci    return rsa_alt->sign_func(rsa_alt->key, f_rng, p_rng,
1313a8e1175bSopenharmony_ci                              md_alg, (unsigned int) hash_len, hash, sig);
1314a8e1175bSopenharmony_ci}
1315a8e1175bSopenharmony_ci
1316a8e1175bSopenharmony_cistatic int rsa_alt_decrypt_wrap(mbedtls_pk_context *pk,
1317a8e1175bSopenharmony_ci                                const unsigned char *input, size_t ilen,
1318a8e1175bSopenharmony_ci                                unsigned char *output, size_t *olen, size_t osize,
1319a8e1175bSopenharmony_ci                                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
1320a8e1175bSopenharmony_ci{
1321a8e1175bSopenharmony_ci    mbedtls_rsa_alt_context *rsa_alt = pk->pk_ctx;
1322a8e1175bSopenharmony_ci
1323a8e1175bSopenharmony_ci    ((void) f_rng);
1324a8e1175bSopenharmony_ci    ((void) p_rng);
1325a8e1175bSopenharmony_ci
1326a8e1175bSopenharmony_ci    if (ilen != rsa_alt->key_len_func(rsa_alt->key)) {
1327a8e1175bSopenharmony_ci        return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1328a8e1175bSopenharmony_ci    }
1329a8e1175bSopenharmony_ci
1330a8e1175bSopenharmony_ci    return rsa_alt->decrypt_func(rsa_alt->key,
1331a8e1175bSopenharmony_ci                                 olen, input, output, osize);
1332a8e1175bSopenharmony_ci}
1333a8e1175bSopenharmony_ci
1334a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C)
1335a8e1175bSopenharmony_cistatic int rsa_alt_check_pair(mbedtls_pk_context *pub, mbedtls_pk_context *prv,
1336a8e1175bSopenharmony_ci                              int (*f_rng)(void *, unsigned char *, size_t),
1337a8e1175bSopenharmony_ci                              void *p_rng)
1338a8e1175bSopenharmony_ci{
1339a8e1175bSopenharmony_ci    unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
1340a8e1175bSopenharmony_ci    unsigned char hash[32];
1341a8e1175bSopenharmony_ci    size_t sig_len = 0;
1342a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1343a8e1175bSopenharmony_ci
1344a8e1175bSopenharmony_ci    if (rsa_alt_get_bitlen(prv) != rsa_get_bitlen(pub)) {
1345a8e1175bSopenharmony_ci        return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
1346a8e1175bSopenharmony_ci    }
1347a8e1175bSopenharmony_ci
1348a8e1175bSopenharmony_ci    memset(hash, 0x2a, sizeof(hash));
1349a8e1175bSopenharmony_ci
1350a8e1175bSopenharmony_ci    if ((ret = rsa_alt_sign_wrap(prv, MBEDTLS_MD_NONE,
1351a8e1175bSopenharmony_ci                                 hash, sizeof(hash),
1352a8e1175bSopenharmony_ci                                 sig, sizeof(sig), &sig_len,
1353a8e1175bSopenharmony_ci                                 f_rng, p_rng)) != 0) {
1354a8e1175bSopenharmony_ci        return ret;
1355a8e1175bSopenharmony_ci    }
1356a8e1175bSopenharmony_ci
1357a8e1175bSopenharmony_ci    if (rsa_verify_wrap(pub, MBEDTLS_MD_NONE,
1358a8e1175bSopenharmony_ci                        hash, sizeof(hash), sig, sig_len) != 0) {
1359a8e1175bSopenharmony_ci        return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
1360a8e1175bSopenharmony_ci    }
1361a8e1175bSopenharmony_ci
1362a8e1175bSopenharmony_ci    return 0;
1363a8e1175bSopenharmony_ci}
1364a8e1175bSopenharmony_ci#endif /* MBEDTLS_RSA_C */
1365a8e1175bSopenharmony_ci
1366a8e1175bSopenharmony_cistatic void *rsa_alt_alloc_wrap(void)
1367a8e1175bSopenharmony_ci{
1368a8e1175bSopenharmony_ci    void *ctx = mbedtls_calloc(1, sizeof(mbedtls_rsa_alt_context));
1369a8e1175bSopenharmony_ci
1370a8e1175bSopenharmony_ci    if (ctx != NULL) {
1371a8e1175bSopenharmony_ci        memset(ctx, 0, sizeof(mbedtls_rsa_alt_context));
1372a8e1175bSopenharmony_ci    }
1373a8e1175bSopenharmony_ci
1374a8e1175bSopenharmony_ci    return ctx;
1375a8e1175bSopenharmony_ci}
1376a8e1175bSopenharmony_ci
1377a8e1175bSopenharmony_cistatic void rsa_alt_free_wrap(void *ctx)
1378a8e1175bSopenharmony_ci{
1379a8e1175bSopenharmony_ci    mbedtls_zeroize_and_free(ctx, sizeof(mbedtls_rsa_alt_context));
1380a8e1175bSopenharmony_ci}
1381a8e1175bSopenharmony_ci
1382a8e1175bSopenharmony_ciconst mbedtls_pk_info_t mbedtls_rsa_alt_info = {
1383a8e1175bSopenharmony_ci    .type = MBEDTLS_PK_RSA_ALT,
1384a8e1175bSopenharmony_ci    .name = "RSA-alt",
1385a8e1175bSopenharmony_ci    .get_bitlen = rsa_alt_get_bitlen,
1386a8e1175bSopenharmony_ci    .can_do = rsa_alt_can_do,
1387a8e1175bSopenharmony_ci    .verify_func = NULL,
1388a8e1175bSopenharmony_ci    .sign_func = rsa_alt_sign_wrap,
1389a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
1390a8e1175bSopenharmony_ci    .verify_rs_func = NULL,
1391a8e1175bSopenharmony_ci    .sign_rs_func = NULL,
1392a8e1175bSopenharmony_ci    .rs_alloc_func = NULL,
1393a8e1175bSopenharmony_ci    .rs_free_func = NULL,
1394a8e1175bSopenharmony_ci#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
1395a8e1175bSopenharmony_ci    .decrypt_func = rsa_alt_decrypt_wrap,
1396a8e1175bSopenharmony_ci    .encrypt_func = NULL,
1397a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C)
1398a8e1175bSopenharmony_ci    .check_pair_func = rsa_alt_check_pair,
1399a8e1175bSopenharmony_ci#else
1400a8e1175bSopenharmony_ci    .check_pair_func = NULL,
1401a8e1175bSopenharmony_ci#endif
1402a8e1175bSopenharmony_ci    .ctx_alloc_func = rsa_alt_alloc_wrap,
1403a8e1175bSopenharmony_ci    .ctx_free_func = rsa_alt_free_wrap,
1404a8e1175bSopenharmony_ci    .debug_func = NULL,
1405a8e1175bSopenharmony_ci};
1406a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
1407a8e1175bSopenharmony_ci
1408a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1409a8e1175bSopenharmony_cistatic size_t opaque_get_bitlen(mbedtls_pk_context *pk)
1410a8e1175bSopenharmony_ci{
1411a8e1175bSopenharmony_ci    size_t bits;
1412a8e1175bSopenharmony_ci    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1413a8e1175bSopenharmony_ci
1414a8e1175bSopenharmony_ci    if (PSA_SUCCESS != psa_get_key_attributes(pk->priv_id, &attributes)) {
1415a8e1175bSopenharmony_ci        return 0;
1416a8e1175bSopenharmony_ci    }
1417a8e1175bSopenharmony_ci
1418a8e1175bSopenharmony_ci    bits = psa_get_key_bits(&attributes);
1419a8e1175bSopenharmony_ci    psa_reset_key_attributes(&attributes);
1420a8e1175bSopenharmony_ci    return bits;
1421a8e1175bSopenharmony_ci}
1422a8e1175bSopenharmony_ci
1423a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
1424a8e1175bSopenharmony_cistatic int ecdsa_opaque_can_do(mbedtls_pk_type_t type)
1425a8e1175bSopenharmony_ci{
1426a8e1175bSopenharmony_ci    return type == MBEDTLS_PK_ECKEY ||
1427a8e1175bSopenharmony_ci           type == MBEDTLS_PK_ECDSA;
1428a8e1175bSopenharmony_ci}
1429a8e1175bSopenharmony_ci
1430a8e1175bSopenharmony_ciconst mbedtls_pk_info_t mbedtls_ecdsa_opaque_info = {
1431a8e1175bSopenharmony_ci    .type = MBEDTLS_PK_OPAQUE,
1432a8e1175bSopenharmony_ci    .name = "Opaque",
1433a8e1175bSopenharmony_ci    .get_bitlen = opaque_get_bitlen,
1434a8e1175bSopenharmony_ci    .can_do = ecdsa_opaque_can_do,
1435a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY)
1436a8e1175bSopenharmony_ci    .verify_func = ecdsa_opaque_verify_wrap,
1437a8e1175bSopenharmony_ci#else /* MBEDTLS_PK_CAN_ECDSA_VERIFY */
1438a8e1175bSopenharmony_ci    .verify_func = NULL,
1439a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_CAN_ECDSA_VERIFY */
1440a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
1441a8e1175bSopenharmony_ci    .sign_func = ecdsa_opaque_sign_wrap,
1442a8e1175bSopenharmony_ci#else /* MBEDTLS_PK_CAN_ECDSA_SIGN */
1443a8e1175bSopenharmony_ci    .sign_func = NULL,
1444a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_CAN_ECDSA_SIGN */
1445a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
1446a8e1175bSopenharmony_ci    .verify_rs_func = NULL,
1447a8e1175bSopenharmony_ci    .sign_rs_func = NULL,
1448a8e1175bSopenharmony_ci    .rs_alloc_func = NULL,
1449a8e1175bSopenharmony_ci    .rs_free_func = NULL,
1450a8e1175bSopenharmony_ci#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
1451a8e1175bSopenharmony_ci    .decrypt_func = NULL,
1452a8e1175bSopenharmony_ci    .encrypt_func = NULL,
1453a8e1175bSopenharmony_ci    .check_pair_func = ecdsa_opaque_check_pair_wrap,
1454a8e1175bSopenharmony_ci    .ctx_alloc_func = NULL,
1455a8e1175bSopenharmony_ci    .ctx_free_func = NULL,
1456a8e1175bSopenharmony_ci    .debug_func = NULL,
1457a8e1175bSopenharmony_ci};
1458a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
1459a8e1175bSopenharmony_ci
1460a8e1175bSopenharmony_cistatic int rsa_opaque_can_do(mbedtls_pk_type_t type)
1461a8e1175bSopenharmony_ci{
1462a8e1175bSopenharmony_ci    return type == MBEDTLS_PK_RSA ||
1463a8e1175bSopenharmony_ci           type == MBEDTLS_PK_RSASSA_PSS;
1464a8e1175bSopenharmony_ci}
1465a8e1175bSopenharmony_ci
1466a8e1175bSopenharmony_ci#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
1467a8e1175bSopenharmony_cistatic int rsa_opaque_decrypt(mbedtls_pk_context *pk,
1468a8e1175bSopenharmony_ci                              const unsigned char *input, size_t ilen,
1469a8e1175bSopenharmony_ci                              unsigned char *output, size_t *olen, size_t osize,
1470a8e1175bSopenharmony_ci                              int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
1471a8e1175bSopenharmony_ci{
1472a8e1175bSopenharmony_ci    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1473a8e1175bSopenharmony_ci    psa_algorithm_t alg;
1474a8e1175bSopenharmony_ci    psa_key_type_t type;
1475a8e1175bSopenharmony_ci    psa_status_t status;
1476a8e1175bSopenharmony_ci
1477a8e1175bSopenharmony_ci    /* PSA has its own RNG */
1478a8e1175bSopenharmony_ci    (void) f_rng;
1479a8e1175bSopenharmony_ci    (void) p_rng;
1480a8e1175bSopenharmony_ci
1481a8e1175bSopenharmony_ci    status = psa_get_key_attributes(pk->priv_id, &attributes);
1482a8e1175bSopenharmony_ci    if (status != PSA_SUCCESS) {
1483a8e1175bSopenharmony_ci        return PSA_PK_TO_MBEDTLS_ERR(status);
1484a8e1175bSopenharmony_ci    }
1485a8e1175bSopenharmony_ci
1486a8e1175bSopenharmony_ci    type = psa_get_key_type(&attributes);
1487a8e1175bSopenharmony_ci    alg = psa_get_key_algorithm(&attributes);
1488a8e1175bSopenharmony_ci    psa_reset_key_attributes(&attributes);
1489a8e1175bSopenharmony_ci
1490a8e1175bSopenharmony_ci    if (!PSA_KEY_TYPE_IS_RSA(type)) {
1491a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
1492a8e1175bSopenharmony_ci    }
1493a8e1175bSopenharmony_ci
1494a8e1175bSopenharmony_ci    status = psa_asymmetric_decrypt(pk->priv_id, alg, input, ilen, NULL, 0, output, osize, olen);
1495a8e1175bSopenharmony_ci    if (status != PSA_SUCCESS) {
1496a8e1175bSopenharmony_ci        return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
1497a8e1175bSopenharmony_ci    }
1498a8e1175bSopenharmony_ci
1499a8e1175bSopenharmony_ci    return 0;
1500a8e1175bSopenharmony_ci}
1501a8e1175bSopenharmony_ci#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC */
1502a8e1175bSopenharmony_ci
1503a8e1175bSopenharmony_cistatic int rsa_opaque_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
1504a8e1175bSopenharmony_ci                                const unsigned char *hash, size_t hash_len,
1505a8e1175bSopenharmony_ci                                unsigned char *sig, size_t sig_size, size_t *sig_len,
1506a8e1175bSopenharmony_ci                                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
1507a8e1175bSopenharmony_ci{
1508a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C)
1509a8e1175bSopenharmony_ci    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1510a8e1175bSopenharmony_ci    psa_algorithm_t alg;
1511a8e1175bSopenharmony_ci    psa_key_type_t type;
1512a8e1175bSopenharmony_ci    psa_status_t status;
1513a8e1175bSopenharmony_ci
1514a8e1175bSopenharmony_ci    /* PSA has its own RNG */
1515a8e1175bSopenharmony_ci    (void) f_rng;
1516a8e1175bSopenharmony_ci    (void) p_rng;
1517a8e1175bSopenharmony_ci
1518a8e1175bSopenharmony_ci    status = psa_get_key_attributes(pk->priv_id, &attributes);
1519a8e1175bSopenharmony_ci    if (status != PSA_SUCCESS) {
1520a8e1175bSopenharmony_ci        return PSA_PK_TO_MBEDTLS_ERR(status);
1521a8e1175bSopenharmony_ci    }
1522a8e1175bSopenharmony_ci
1523a8e1175bSopenharmony_ci    type = psa_get_key_type(&attributes);
1524a8e1175bSopenharmony_ci    alg = psa_get_key_algorithm(&attributes);
1525a8e1175bSopenharmony_ci    psa_reset_key_attributes(&attributes);
1526a8e1175bSopenharmony_ci
1527a8e1175bSopenharmony_ci    if (PSA_KEY_TYPE_IS_RSA(type)) {
1528a8e1175bSopenharmony_ci        alg = (alg & ~PSA_ALG_HASH_MASK) | mbedtls_md_psa_alg_from_type(md_alg);
1529a8e1175bSopenharmony_ci    } else {
1530a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
1531a8e1175bSopenharmony_ci    }
1532a8e1175bSopenharmony_ci
1533a8e1175bSopenharmony_ci    status = psa_sign_hash(pk->priv_id, alg, hash, hash_len, sig, sig_size, sig_len);
1534a8e1175bSopenharmony_ci    if (status != PSA_SUCCESS) {
1535a8e1175bSopenharmony_ci        if (PSA_KEY_TYPE_IS_RSA(type)) {
1536a8e1175bSopenharmony_ci            return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
1537a8e1175bSopenharmony_ci        } else {
1538a8e1175bSopenharmony_ci            return PSA_PK_TO_MBEDTLS_ERR(status);
1539a8e1175bSopenharmony_ci        }
1540a8e1175bSopenharmony_ci    }
1541a8e1175bSopenharmony_ci
1542a8e1175bSopenharmony_ci    return 0;
1543a8e1175bSopenharmony_ci#else /* !MBEDTLS_RSA_C */
1544a8e1175bSopenharmony_ci    ((void) pk);
1545a8e1175bSopenharmony_ci    ((void) md_alg);
1546a8e1175bSopenharmony_ci    ((void) hash);
1547a8e1175bSopenharmony_ci    ((void) hash_len);
1548a8e1175bSopenharmony_ci    ((void) sig);
1549a8e1175bSopenharmony_ci    ((void) sig_size);
1550a8e1175bSopenharmony_ci    ((void) sig_len);
1551a8e1175bSopenharmony_ci    ((void) f_rng);
1552a8e1175bSopenharmony_ci    ((void) p_rng);
1553a8e1175bSopenharmony_ci    return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
1554a8e1175bSopenharmony_ci#endif /* !MBEDTLS_RSA_C */
1555a8e1175bSopenharmony_ci}
1556a8e1175bSopenharmony_ci
1557a8e1175bSopenharmony_ciconst mbedtls_pk_info_t mbedtls_rsa_opaque_info = {
1558a8e1175bSopenharmony_ci    .type = MBEDTLS_PK_OPAQUE,
1559a8e1175bSopenharmony_ci    .name = "Opaque",
1560a8e1175bSopenharmony_ci    .get_bitlen = opaque_get_bitlen,
1561a8e1175bSopenharmony_ci    .can_do = rsa_opaque_can_do,
1562a8e1175bSopenharmony_ci    .verify_func = NULL,
1563a8e1175bSopenharmony_ci    .sign_func = rsa_opaque_sign_wrap,
1564a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
1565a8e1175bSopenharmony_ci    .verify_rs_func = NULL,
1566a8e1175bSopenharmony_ci    .sign_rs_func = NULL,
1567a8e1175bSopenharmony_ci    .rs_alloc_func = NULL,
1568a8e1175bSopenharmony_ci    .rs_free_func = NULL,
1569a8e1175bSopenharmony_ci#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
1570a8e1175bSopenharmony_ci#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
1571a8e1175bSopenharmony_ci    .decrypt_func = rsa_opaque_decrypt,
1572a8e1175bSopenharmony_ci#else /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC */
1573a8e1175bSopenharmony_ci    .decrypt_func = NULL,
1574a8e1175bSopenharmony_ci#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC */
1575a8e1175bSopenharmony_ci    .encrypt_func = NULL,
1576a8e1175bSopenharmony_ci    .check_pair_func = NULL,
1577a8e1175bSopenharmony_ci    .ctx_alloc_func = NULL,
1578a8e1175bSopenharmony_ci    .ctx_free_func = NULL,
1579a8e1175bSopenharmony_ci    .debug_func = NULL,
1580a8e1175bSopenharmony_ci};
1581a8e1175bSopenharmony_ci
1582a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
1583a8e1175bSopenharmony_ci
1584a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_C */
1585