xref: /optee_os/lib/libmbedtls/mbedtls/library/pk_wrap.c (revision b0563631928755fe864b97785160fb3088e9efdc)
1817466cbSJens Wiklander /*
2817466cbSJens Wiklander  *  Public Key abstraction layer: wrapper functions
3817466cbSJens Wiklander  *
47901324dSJerome Forissier  *  Copyright The Mbed TLS Contributors
5*b0563631STom Van Eyck  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6817466cbSJens Wiklander  */
7817466cbSJens Wiklander 
87901324dSJerome Forissier #include "common.h"
9817466cbSJens Wiklander 
1032b31808SJens Wiklander #include "mbedtls/platform_util.h"
1132b31808SJens Wiklander 
12817466cbSJens Wiklander #if defined(MBEDTLS_PK_C)
1332b31808SJens Wiklander #include "pk_wrap.h"
14*b0563631STom Van Eyck #include "pk_internal.h"
1511fa71b9SJerome Forissier #include "mbedtls/error.h"
16*b0563631STom Van Eyck #include "mbedtls/psa_util.h"
17817466cbSJens Wiklander 
18817466cbSJens Wiklander /* Even if RSA not activated, for the sake of RSA-alt */
19817466cbSJens Wiklander #include "mbedtls/rsa.h"
20817466cbSJens Wiklander 
21817466cbSJens Wiklander #if defined(MBEDTLS_ECP_C)
22817466cbSJens Wiklander #include "mbedtls/ecp.h"
23817466cbSJens Wiklander #endif
24817466cbSJens Wiklander 
25817466cbSJens Wiklander #if defined(MBEDTLS_ECDSA_C)
26817466cbSJens Wiklander #include "mbedtls/ecdsa.h"
27817466cbSJens Wiklander #endif
28817466cbSJens Wiklander 
2911fa71b9SJerome Forissier #if defined(MBEDTLS_USE_PSA_CRYPTO)
30*b0563631STom Van Eyck #include "psa_util_internal.h"
3111fa71b9SJerome Forissier #include "psa/crypto.h"
32*b0563631STom Van Eyck #include "mbedtls/psa_util.h"
33*b0563631STom Van Eyck 
34*b0563631STom Van Eyck #if defined(MBEDTLS_RSA_C)
35*b0563631STom Van Eyck #include "pkwrite.h"
36*b0563631STom Van Eyck #include "rsa_internal.h"
37*b0563631STom Van Eyck #endif
3832b31808SJens Wiklander 
3932b31808SJens Wiklander #if defined(MBEDTLS_PK_CAN_ECDSA_SOME)
4032b31808SJens Wiklander #include "mbedtls/asn1write.h"
4111fa71b9SJerome Forissier #include "mbedtls/asn1.h"
4211fa71b9SJerome Forissier #endif
4332b31808SJens Wiklander #endif  /* MBEDTLS_USE_PSA_CRYPTO */
4411fa71b9SJerome Forissier 
45817466cbSJens Wiklander #include "mbedtls/platform.h"
46817466cbSJens Wiklander 
47817466cbSJens Wiklander #include <limits.h>
483d3b0591SJens Wiklander #include <stdint.h>
4932b31808SJens Wiklander #include <string.h>
5032b31808SJens Wiklander 
51817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C)
rsa_can_do(mbedtls_pk_type_t type)52817466cbSJens Wiklander static int rsa_can_do(mbedtls_pk_type_t type)
53817466cbSJens Wiklander {
5432b31808SJens Wiklander     return type == MBEDTLS_PK_RSA ||
5532b31808SJens Wiklander            type == MBEDTLS_PK_RSASSA_PSS;
56817466cbSJens Wiklander }
57817466cbSJens Wiklander 
rsa_get_bitlen(mbedtls_pk_context * pk)58*b0563631STom Van Eyck static size_t rsa_get_bitlen(mbedtls_pk_context *pk)
59817466cbSJens Wiklander {
60*b0563631STom Van Eyck     const mbedtls_rsa_context *rsa = (const mbedtls_rsa_context *) pk->pk_ctx;
61*b0563631STom Van Eyck     return mbedtls_rsa_get_bitlen(rsa);
62817466cbSJens Wiklander }
63817466cbSJens Wiklander 
6432b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
rsa_verify_wrap(mbedtls_pk_context * pk,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hash_len,const unsigned char * sig,size_t sig_len)65*b0563631STom Van Eyck static int rsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
6632b31808SJens Wiklander                            const unsigned char *hash, size_t hash_len,
6732b31808SJens Wiklander                            const unsigned char *sig, size_t sig_len)
6832b31808SJens Wiklander {
69*b0563631STom Van Eyck     mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
7032b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
7132b31808SJens Wiklander     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
7232b31808SJens Wiklander     mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
7332b31808SJens Wiklander     psa_status_t status;
7432b31808SJens Wiklander     int key_len;
7532b31808SJens Wiklander     unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES];
76*b0563631STom Van Eyck     unsigned char *p = buf + sizeof(buf);
77*b0563631STom Van Eyck     psa_algorithm_t psa_alg_md;
7832b31808SJens Wiklander     size_t rsa_len = mbedtls_rsa_get_len(rsa);
7932b31808SJens Wiklander 
80*b0563631STom Van Eyck #if SIZE_MAX > UINT_MAX
8132b31808SJens Wiklander     if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) {
8232b31808SJens Wiklander         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
8332b31808SJens Wiklander     }
84*b0563631STom Van Eyck #endif
85*b0563631STom Van Eyck 
86*b0563631STom Van Eyck     if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) {
87*b0563631STom Van Eyck         psa_alg_md = PSA_ALG_RSA_PSS(mbedtls_md_psa_alg_from_type(md_alg));
88*b0563631STom Van Eyck     } else {
89*b0563631STom Van Eyck         psa_alg_md = PSA_ALG_RSA_PKCS1V15_SIGN(mbedtls_md_psa_alg_from_type(md_alg));
90*b0563631STom Van Eyck     }
9132b31808SJens Wiklander 
9232b31808SJens Wiklander     if (sig_len < rsa_len) {
9332b31808SJens Wiklander         return MBEDTLS_ERR_RSA_VERIFY_FAILED;
9432b31808SJens Wiklander     }
9532b31808SJens Wiklander 
96*b0563631STom Van Eyck     key_len = mbedtls_rsa_write_pubkey(rsa, buf, &p);
9732b31808SJens Wiklander     if (key_len <= 0) {
9832b31808SJens Wiklander         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
9932b31808SJens Wiklander     }
10032b31808SJens Wiklander 
10132b31808SJens Wiklander     psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH);
10232b31808SJens Wiklander     psa_set_key_algorithm(&attributes, psa_alg_md);
10332b31808SJens Wiklander     psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY);
10432b31808SJens Wiklander 
10532b31808SJens Wiklander     status = psa_import_key(&attributes,
10632b31808SJens Wiklander                             buf + sizeof(buf) - key_len, key_len,
10732b31808SJens Wiklander                             &key_id);
10832b31808SJens Wiklander     if (status != PSA_SUCCESS) {
10932b31808SJens Wiklander         ret = PSA_PK_TO_MBEDTLS_ERR(status);
11032b31808SJens Wiklander         goto cleanup;
11132b31808SJens Wiklander     }
11232b31808SJens Wiklander 
11332b31808SJens Wiklander     status = psa_verify_hash(key_id, psa_alg_md, hash, hash_len,
11432b31808SJens Wiklander                              sig, sig_len);
11532b31808SJens Wiklander     if (status != PSA_SUCCESS) {
11632b31808SJens Wiklander         ret = PSA_PK_RSA_TO_MBEDTLS_ERR(status);
11732b31808SJens Wiklander         goto cleanup;
11832b31808SJens Wiklander     }
11932b31808SJens Wiklander     ret = 0;
12032b31808SJens Wiklander 
12132b31808SJens Wiklander cleanup:
12232b31808SJens Wiklander     status = psa_destroy_key(key_id);
12332b31808SJens Wiklander     if (ret == 0 && status != PSA_SUCCESS) {
12432b31808SJens Wiklander         ret = PSA_PK_TO_MBEDTLS_ERR(status);
12532b31808SJens Wiklander     }
12632b31808SJens Wiklander 
12732b31808SJens Wiklander     return ret;
12832b31808SJens Wiklander }
129*b0563631STom Van Eyck #else /* MBEDTLS_USE_PSA_CRYPTO */
rsa_verify_wrap(mbedtls_pk_context * pk,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hash_len,const unsigned char * sig,size_t sig_len)130*b0563631STom Van Eyck static int rsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
131817466cbSJens Wiklander                            const unsigned char *hash, size_t hash_len,
132817466cbSJens Wiklander                            const unsigned char *sig, size_t sig_len)
133817466cbSJens Wiklander {
13411fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
135*b0563631STom Van Eyck     mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
1363d3b0591SJens Wiklander     size_t rsa_len = mbedtls_rsa_get_len(rsa);
137817466cbSJens Wiklander 
138*b0563631STom Van Eyck #if SIZE_MAX > UINT_MAX
13932b31808SJens Wiklander     if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) {
14032b31808SJens Wiklander         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
14132b31808SJens Wiklander     }
142*b0563631STom Van Eyck #endif
143817466cbSJens Wiklander 
14432b31808SJens Wiklander     if (sig_len < rsa_len) {
14532b31808SJens Wiklander         return MBEDTLS_ERR_RSA_VERIFY_FAILED;
14632b31808SJens Wiklander     }
147817466cbSJens Wiklander 
14832b31808SJens Wiklander     if ((ret = mbedtls_rsa_pkcs1_verify(rsa, md_alg,
14932b31808SJens Wiklander                                         (unsigned int) hash_len,
15032b31808SJens Wiklander                                         hash, sig)) != 0) {
15132b31808SJens Wiklander         return ret;
15232b31808SJens Wiklander     }
153817466cbSJens Wiklander 
1543d3b0591SJens Wiklander     /* The buffer contains a valid signature followed by extra data.
1553d3b0591SJens Wiklander      * We have a special error code for that so that so that callers can
1563d3b0591SJens Wiklander      * use mbedtls_pk_verify() to check "Does the buffer start with a
1573d3b0591SJens Wiklander      * valid signature?" and not just "Does the buffer contain a valid
1583d3b0591SJens Wiklander      * signature?". */
15932b31808SJens Wiklander     if (sig_len > rsa_len) {
16032b31808SJens Wiklander         return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
161817466cbSJens Wiklander     }
162817466cbSJens Wiklander 
16332b31808SJens Wiklander     return 0;
16432b31808SJens Wiklander }
165*b0563631STom Van Eyck #endif /* MBEDTLS_USE_PSA_CRYPTO */
16632b31808SJens Wiklander 
167*b0563631STom Van Eyck #if defined(MBEDTLS_USE_PSA_CRYPTO)
mbedtls_pk_psa_rsa_sign_ext(psa_algorithm_t alg,mbedtls_rsa_context * rsa_ctx,const unsigned char * hash,size_t hash_len,unsigned char * sig,size_t sig_size,size_t * sig_len)16832b31808SJens Wiklander int  mbedtls_pk_psa_rsa_sign_ext(psa_algorithm_t alg,
16932b31808SJens Wiklander                                  mbedtls_rsa_context *rsa_ctx,
17032b31808SJens Wiklander                                  const unsigned char *hash, size_t hash_len,
17132b31808SJens Wiklander                                  unsigned char *sig, size_t sig_size,
17232b31808SJens Wiklander                                  size_t *sig_len)
17332b31808SJens Wiklander {
17432b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
17532b31808SJens Wiklander     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
17632b31808SJens Wiklander     mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
17732b31808SJens Wiklander     psa_status_t status;
17832b31808SJens Wiklander     int key_len;
179*b0563631STom Van Eyck     unsigned char *buf = NULL;
180*b0563631STom Van Eyck     unsigned char *p;
181*b0563631STom Van Eyck 
182*b0563631STom Van Eyck     buf = mbedtls_calloc(1, MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES);
183*b0563631STom Van Eyck     if (buf == NULL) {
184*b0563631STom Van Eyck         return MBEDTLS_ERR_PK_ALLOC_FAILED;
185*b0563631STom Van Eyck     }
186*b0563631STom Van Eyck     p = buf + MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES;
18732b31808SJens Wiklander 
18832b31808SJens Wiklander     *sig_len = mbedtls_rsa_get_len(rsa_ctx);
18932b31808SJens Wiklander     if (sig_size < *sig_len) {
190*b0563631STom Van Eyck         mbedtls_free(buf);
19132b31808SJens Wiklander         return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
19232b31808SJens Wiklander     }
19332b31808SJens Wiklander 
194*b0563631STom Van Eyck     key_len = mbedtls_rsa_write_key(rsa_ctx, buf, &p);
19532b31808SJens Wiklander     if (key_len <= 0) {
196*b0563631STom Van Eyck         mbedtls_free(buf);
19732b31808SJens Wiklander         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
19832b31808SJens Wiklander     }
19932b31808SJens Wiklander     psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
20032b31808SJens Wiklander     psa_set_key_algorithm(&attributes, alg);
20132b31808SJens Wiklander     psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
20232b31808SJens Wiklander 
20332b31808SJens Wiklander     status = psa_import_key(&attributes,
204*b0563631STom Van Eyck                             buf + MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES - key_len, key_len,
20532b31808SJens Wiklander                             &key_id);
20632b31808SJens Wiklander     if (status != PSA_SUCCESS) {
20732b31808SJens Wiklander         ret = PSA_PK_TO_MBEDTLS_ERR(status);
20832b31808SJens Wiklander         goto cleanup;
20932b31808SJens Wiklander     }
21032b31808SJens Wiklander     status = psa_sign_hash(key_id, alg, hash, hash_len,
21132b31808SJens Wiklander                            sig, sig_size, sig_len);
21232b31808SJens Wiklander     if (status != PSA_SUCCESS) {
21332b31808SJens Wiklander         ret = PSA_PK_RSA_TO_MBEDTLS_ERR(status);
21432b31808SJens Wiklander         goto cleanup;
21532b31808SJens Wiklander     }
21632b31808SJens Wiklander 
21732b31808SJens Wiklander     ret = 0;
21832b31808SJens Wiklander 
21932b31808SJens Wiklander cleanup:
220*b0563631STom Van Eyck     mbedtls_free(buf);
22132b31808SJens Wiklander     status = psa_destroy_key(key_id);
22232b31808SJens Wiklander     if (ret == 0 && status != PSA_SUCCESS) {
22332b31808SJens Wiklander         ret = PSA_PK_TO_MBEDTLS_ERR(status);
22432b31808SJens Wiklander     }
22532b31808SJens Wiklander     return ret;
22632b31808SJens Wiklander }
227*b0563631STom Van Eyck #endif /* MBEDTLS_USE_PSA_CRYPTO */
22832b31808SJens Wiklander 
22932b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
rsa_sign_wrap(mbedtls_pk_context * pk,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hash_len,unsigned char * sig,size_t sig_size,size_t * sig_len,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)230*b0563631STom Van Eyck static int rsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
231817466cbSJens Wiklander                          const unsigned char *hash, size_t hash_len,
23232b31808SJens Wiklander                          unsigned char *sig, size_t sig_size, size_t *sig_len,
23332b31808SJens Wiklander                          int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
23432b31808SJens Wiklander {
23532b31808SJens Wiklander     ((void) f_rng);
23632b31808SJens Wiklander     ((void) p_rng);
23732b31808SJens Wiklander 
23832b31808SJens Wiklander     psa_algorithm_t psa_md_alg;
239*b0563631STom Van Eyck     psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
24032b31808SJens Wiklander     if (psa_md_alg == 0) {
24132b31808SJens Wiklander         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
24232b31808SJens Wiklander     }
243*b0563631STom Van Eyck     psa_algorithm_t psa_alg;
244*b0563631STom Van Eyck     if (mbedtls_rsa_get_padding_mode(mbedtls_pk_rsa(*pk)) == MBEDTLS_RSA_PKCS_V21) {
245*b0563631STom Van Eyck         psa_alg = PSA_ALG_RSA_PSS(psa_md_alg);
246*b0563631STom Van Eyck     } else {
247*b0563631STom Van Eyck         psa_alg = PSA_ALG_RSA_PKCS1V15_SIGN(psa_md_alg);
248*b0563631STom Van Eyck     }
24932b31808SJens Wiklander 
250*b0563631STom Van Eyck     return mbedtls_pk_psa_rsa_sign_ext(psa_alg, pk->pk_ctx, hash, hash_len,
25132b31808SJens Wiklander                                        sig, sig_size, sig_len);
25232b31808SJens Wiklander }
253*b0563631STom Van Eyck #else /* MBEDTLS_USE_PSA_CRYPTO */
rsa_sign_wrap(mbedtls_pk_context * pk,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hash_len,unsigned char * sig,size_t sig_size,size_t * sig_len,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)254*b0563631STom Van Eyck static int rsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
25532b31808SJens Wiklander                          const unsigned char *hash, size_t hash_len,
25632b31808SJens Wiklander                          unsigned char *sig, size_t sig_size, size_t *sig_len,
257817466cbSJens Wiklander                          int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
258817466cbSJens Wiklander {
259*b0563631STom Van Eyck     mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
2603d3b0591SJens Wiklander 
261*b0563631STom Van Eyck #if SIZE_MAX > UINT_MAX
26232b31808SJens Wiklander     if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) {
26332b31808SJens Wiklander         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
264817466cbSJens Wiklander     }
265*b0563631STom Van Eyck #endif
266817466cbSJens Wiklander 
26732b31808SJens Wiklander     *sig_len = mbedtls_rsa_get_len(rsa);
26832b31808SJens Wiklander     if (sig_size < *sig_len) {
26932b31808SJens Wiklander         return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
27032b31808SJens Wiklander     }
27132b31808SJens Wiklander 
27232b31808SJens Wiklander     return mbedtls_rsa_pkcs1_sign(rsa, f_rng, p_rng,
27332b31808SJens Wiklander                                   md_alg, (unsigned int) hash_len,
27432b31808SJens Wiklander                                   hash, sig);
27532b31808SJens Wiklander }
276*b0563631STom Van Eyck #endif /* MBEDTLS_USE_PSA_CRYPTO */
27732b31808SJens Wiklander 
27832b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
rsa_decrypt_wrap(mbedtls_pk_context * pk,const unsigned char * input,size_t ilen,unsigned char * output,size_t * olen,size_t osize,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)279*b0563631STom Van Eyck static int rsa_decrypt_wrap(mbedtls_pk_context *pk,
28032b31808SJens Wiklander                             const unsigned char *input, size_t ilen,
28132b31808SJens Wiklander                             unsigned char *output, size_t *olen, size_t osize,
28232b31808SJens Wiklander                             int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
28332b31808SJens Wiklander {
284*b0563631STom Van Eyck     mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
28532b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
28632b31808SJens Wiklander     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
28732b31808SJens Wiklander     mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
288*b0563631STom Van Eyck     psa_algorithm_t psa_md_alg, decrypt_alg;
28932b31808SJens Wiklander     psa_status_t status;
29032b31808SJens Wiklander     int key_len;
29132b31808SJens Wiklander     unsigned char buf[MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES];
292*b0563631STom Van Eyck     unsigned char *p = buf + sizeof(buf);
29332b31808SJens Wiklander 
29432b31808SJens Wiklander     ((void) f_rng);
29532b31808SJens Wiklander     ((void) p_rng);
29632b31808SJens Wiklander 
29732b31808SJens Wiklander     if (ilen != mbedtls_rsa_get_len(rsa)) {
29832b31808SJens Wiklander         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
29932b31808SJens Wiklander     }
30032b31808SJens Wiklander 
301*b0563631STom Van Eyck     key_len = mbedtls_rsa_write_key(rsa, buf, &p);
30232b31808SJens Wiklander     if (key_len <= 0) {
30332b31808SJens Wiklander         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
30432b31808SJens Wiklander     }
30532b31808SJens Wiklander 
30632b31808SJens Wiklander     psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
30732b31808SJens Wiklander     psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT);
308*b0563631STom Van Eyck     if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) {
309*b0563631STom Van Eyck         psa_md_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) mbedtls_rsa_get_md_alg(rsa));
310*b0563631STom Van Eyck         decrypt_alg = PSA_ALG_RSA_OAEP(psa_md_alg);
311*b0563631STom Van Eyck     } else {
312*b0563631STom Van Eyck         decrypt_alg = PSA_ALG_RSA_PKCS1V15_CRYPT;
313*b0563631STom Van Eyck     }
314*b0563631STom Van Eyck     psa_set_key_algorithm(&attributes, decrypt_alg);
31532b31808SJens Wiklander 
31632b31808SJens Wiklander     status = psa_import_key(&attributes,
31732b31808SJens Wiklander                             buf + sizeof(buf) - key_len, key_len,
31832b31808SJens Wiklander                             &key_id);
31932b31808SJens Wiklander     if (status != PSA_SUCCESS) {
32032b31808SJens Wiklander         ret = PSA_PK_TO_MBEDTLS_ERR(status);
32132b31808SJens Wiklander         goto cleanup;
32232b31808SJens Wiklander     }
32332b31808SJens Wiklander 
324*b0563631STom Van Eyck     status = psa_asymmetric_decrypt(key_id, decrypt_alg,
32532b31808SJens Wiklander                                     input, ilen,
32632b31808SJens Wiklander                                     NULL, 0,
32732b31808SJens Wiklander                                     output, osize, olen);
32832b31808SJens Wiklander     if (status != PSA_SUCCESS) {
32932b31808SJens Wiklander         ret = PSA_PK_RSA_TO_MBEDTLS_ERR(status);
33032b31808SJens Wiklander         goto cleanup;
33132b31808SJens Wiklander     }
33232b31808SJens Wiklander 
33332b31808SJens Wiklander     ret = 0;
33432b31808SJens Wiklander 
33532b31808SJens Wiklander cleanup:
33632b31808SJens Wiklander     mbedtls_platform_zeroize(buf, sizeof(buf));
33732b31808SJens Wiklander     status = psa_destroy_key(key_id);
33832b31808SJens Wiklander     if (ret == 0 && status != PSA_SUCCESS) {
33932b31808SJens Wiklander         ret = PSA_PK_TO_MBEDTLS_ERR(status);
34032b31808SJens Wiklander     }
34132b31808SJens Wiklander 
34232b31808SJens Wiklander     return ret;
34332b31808SJens Wiklander }
344*b0563631STom Van Eyck #else /* MBEDTLS_USE_PSA_CRYPTO */
rsa_decrypt_wrap(mbedtls_pk_context * pk,const unsigned char * input,size_t ilen,unsigned char * output,size_t * olen,size_t osize,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)345*b0563631STom Van Eyck static int rsa_decrypt_wrap(mbedtls_pk_context *pk,
346817466cbSJens Wiklander                             const unsigned char *input, size_t ilen,
347817466cbSJens Wiklander                             unsigned char *output, size_t *olen, size_t osize,
348817466cbSJens Wiklander                             int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
349817466cbSJens Wiklander {
350*b0563631STom Van Eyck     mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
3513d3b0591SJens Wiklander 
35232b31808SJens Wiklander     if (ilen != mbedtls_rsa_get_len(rsa)) {
35332b31808SJens Wiklander         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
354817466cbSJens Wiklander     }
355817466cbSJens Wiklander 
35632b31808SJens Wiklander     return mbedtls_rsa_pkcs1_decrypt(rsa, f_rng, p_rng,
35732b31808SJens Wiklander                                      olen, input, output, osize);
35832b31808SJens Wiklander }
359*b0563631STom Van Eyck #endif /* MBEDTLS_USE_PSA_CRYPTO */
36032b31808SJens Wiklander 
36132b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
rsa_encrypt_wrap(mbedtls_pk_context * pk,const unsigned char * input,size_t ilen,unsigned char * output,size_t * olen,size_t osize,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)362*b0563631STom Van Eyck static int rsa_encrypt_wrap(mbedtls_pk_context *pk,
36332b31808SJens Wiklander                             const unsigned char *input, size_t ilen,
36432b31808SJens Wiklander                             unsigned char *output, size_t *olen, size_t osize,
36532b31808SJens Wiklander                             int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
36632b31808SJens Wiklander {
367*b0563631STom Van Eyck     mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
36832b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
36932b31808SJens Wiklander     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
37032b31808SJens Wiklander     mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
371*b0563631STom Van Eyck     psa_algorithm_t psa_md_alg, psa_encrypt_alg;
37232b31808SJens Wiklander     psa_status_t status;
37332b31808SJens Wiklander     int key_len;
37432b31808SJens Wiklander     unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES];
375*b0563631STom Van Eyck     unsigned char *p = buf + sizeof(buf);
37632b31808SJens Wiklander 
37732b31808SJens Wiklander     ((void) f_rng);
37832b31808SJens Wiklander     ((void) p_rng);
37932b31808SJens Wiklander 
38032b31808SJens Wiklander     if (mbedtls_rsa_get_len(rsa) > osize) {
38132b31808SJens Wiklander         return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
38232b31808SJens Wiklander     }
38332b31808SJens Wiklander 
384*b0563631STom Van Eyck     key_len = mbedtls_rsa_write_pubkey(rsa, buf, &p);
38532b31808SJens Wiklander     if (key_len <= 0) {
38632b31808SJens Wiklander         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
38732b31808SJens Wiklander     }
38832b31808SJens Wiklander 
38932b31808SJens Wiklander     psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT);
390*b0563631STom Van Eyck     if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) {
391*b0563631STom Van Eyck         psa_md_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) mbedtls_rsa_get_md_alg(rsa));
392*b0563631STom Van Eyck         psa_encrypt_alg = PSA_ALG_RSA_OAEP(psa_md_alg);
393*b0563631STom Van Eyck     } else {
394*b0563631STom Van Eyck         psa_encrypt_alg = PSA_ALG_RSA_PKCS1V15_CRYPT;
395*b0563631STom Van Eyck     }
396*b0563631STom Van Eyck     psa_set_key_algorithm(&attributes, psa_encrypt_alg);
39732b31808SJens Wiklander     psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY);
39832b31808SJens Wiklander 
39932b31808SJens Wiklander     status = psa_import_key(&attributes,
40032b31808SJens Wiklander                             buf + sizeof(buf) - key_len, key_len,
40132b31808SJens Wiklander                             &key_id);
40232b31808SJens Wiklander     if (status != PSA_SUCCESS) {
40332b31808SJens Wiklander         ret = PSA_PK_TO_MBEDTLS_ERR(status);
40432b31808SJens Wiklander         goto cleanup;
40532b31808SJens Wiklander     }
40632b31808SJens Wiklander 
407*b0563631STom Van Eyck     status = psa_asymmetric_encrypt(key_id, psa_encrypt_alg,
40832b31808SJens Wiklander                                     input, ilen,
40932b31808SJens Wiklander                                     NULL, 0,
41032b31808SJens Wiklander                                     output, osize, olen);
41132b31808SJens Wiklander     if (status != PSA_SUCCESS) {
41232b31808SJens Wiklander         ret = PSA_PK_RSA_TO_MBEDTLS_ERR(status);
41332b31808SJens Wiklander         goto cleanup;
41432b31808SJens Wiklander     }
41532b31808SJens Wiklander 
41632b31808SJens Wiklander     ret = 0;
41732b31808SJens Wiklander 
41832b31808SJens Wiklander cleanup:
41932b31808SJens Wiklander     status = psa_destroy_key(key_id);
42032b31808SJens Wiklander     if (ret == 0 && status != PSA_SUCCESS) {
42132b31808SJens Wiklander         ret = PSA_PK_TO_MBEDTLS_ERR(status);
42232b31808SJens Wiklander     }
42332b31808SJens Wiklander 
42432b31808SJens Wiklander     return ret;
42532b31808SJens Wiklander }
426*b0563631STom Van Eyck #else /* MBEDTLS_USE_PSA_CRYPTO */
rsa_encrypt_wrap(mbedtls_pk_context * pk,const unsigned char * input,size_t ilen,unsigned char * output,size_t * olen,size_t osize,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)427*b0563631STom Van Eyck static int rsa_encrypt_wrap(mbedtls_pk_context *pk,
428817466cbSJens Wiklander                             const unsigned char *input, size_t ilen,
429817466cbSJens Wiklander                             unsigned char *output, size_t *olen, size_t osize,
430817466cbSJens Wiklander                             int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
431817466cbSJens Wiklander {
432*b0563631STom Van Eyck     mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
4333d3b0591SJens Wiklander     *olen = mbedtls_rsa_get_len(rsa);
434817466cbSJens Wiklander 
43532b31808SJens Wiklander     if (*olen > osize) {
43632b31808SJens Wiklander         return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
437817466cbSJens Wiklander     }
438817466cbSJens Wiklander 
43932b31808SJens Wiklander     return mbedtls_rsa_pkcs1_encrypt(rsa, f_rng, p_rng,
44032b31808SJens Wiklander                                      ilen, input, output);
44132b31808SJens Wiklander }
442*b0563631STom Van Eyck #endif /* MBEDTLS_USE_PSA_CRYPTO */
44332b31808SJens Wiklander 
rsa_check_pair_wrap(mbedtls_pk_context * pub,mbedtls_pk_context * prv,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)444*b0563631STom Van Eyck static int rsa_check_pair_wrap(mbedtls_pk_context *pub, mbedtls_pk_context *prv,
44532b31808SJens Wiklander                                int (*f_rng)(void *, unsigned char *, size_t),
44632b31808SJens Wiklander                                void *p_rng)
447817466cbSJens Wiklander {
44832b31808SJens Wiklander     (void) f_rng;
44932b31808SJens Wiklander     (void) p_rng;
450*b0563631STom Van Eyck     return mbedtls_rsa_check_pub_priv((const mbedtls_rsa_context *) pub->pk_ctx,
451*b0563631STom Van Eyck                                       (const mbedtls_rsa_context *) prv->pk_ctx);
452817466cbSJens Wiklander }
453817466cbSJens Wiklander 
rsa_alloc_wrap(void)454817466cbSJens Wiklander static void *rsa_alloc_wrap(void)
455817466cbSJens Wiklander {
456817466cbSJens Wiklander     void *ctx = mbedtls_calloc(1, sizeof(mbedtls_rsa_context));
457817466cbSJens Wiklander 
45832b31808SJens Wiklander     if (ctx != NULL) {
45932b31808SJens Wiklander         mbedtls_rsa_init((mbedtls_rsa_context *) ctx);
46032b31808SJens Wiklander     }
461817466cbSJens Wiklander 
46232b31808SJens Wiklander     return ctx;
463817466cbSJens Wiklander }
464817466cbSJens Wiklander 
rsa_free_wrap(void * ctx)465817466cbSJens Wiklander static void rsa_free_wrap(void *ctx)
466817466cbSJens Wiklander {
467817466cbSJens Wiklander     mbedtls_rsa_free((mbedtls_rsa_context *) ctx);
468817466cbSJens Wiklander     mbedtls_free(ctx);
469817466cbSJens Wiklander }
470817466cbSJens Wiklander 
rsa_debug(mbedtls_pk_context * pk,mbedtls_pk_debug_item * items)471*b0563631STom Van Eyck static void rsa_debug(mbedtls_pk_context *pk, mbedtls_pk_debug_item *items)
472817466cbSJens Wiklander {
47332b31808SJens Wiklander #if defined(MBEDTLS_RSA_ALT)
47432b31808SJens Wiklander     /* Not supported */
475*b0563631STom Van Eyck     (void) pk;
47632b31808SJens Wiklander     (void) items;
47732b31808SJens Wiklander #else
478*b0563631STom Van Eyck     mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
479*b0563631STom Van Eyck 
480817466cbSJens Wiklander     items->type = MBEDTLS_PK_DEBUG_MPI;
481817466cbSJens Wiklander     items->name = "rsa.N";
482*b0563631STom Van Eyck     items->value = &(rsa->N);
483817466cbSJens Wiklander 
484817466cbSJens Wiklander     items++;
485817466cbSJens Wiklander 
486817466cbSJens Wiklander     items->type = MBEDTLS_PK_DEBUG_MPI;
487817466cbSJens Wiklander     items->name = "rsa.E";
488*b0563631STom Van Eyck     items->value = &(rsa->E);
48932b31808SJens Wiklander #endif
490817466cbSJens Wiklander }
491817466cbSJens Wiklander 
492817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_rsa_info = {
493*b0563631STom Van Eyck     .type = MBEDTLS_PK_RSA,
494*b0563631STom Van Eyck     .name = "RSA",
495*b0563631STom Van Eyck     .get_bitlen = rsa_get_bitlen,
496*b0563631STom Van Eyck     .can_do = rsa_can_do,
497*b0563631STom Van Eyck     .verify_func = rsa_verify_wrap,
498*b0563631STom Van Eyck     .sign_func = rsa_sign_wrap,
4993d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
500*b0563631STom Van Eyck     .verify_rs_func = NULL,
501*b0563631STom Van Eyck     .sign_rs_func = NULL,
502*b0563631STom Van Eyck     .rs_alloc_func = NULL,
503*b0563631STom Van Eyck     .rs_free_func = NULL,
504*b0563631STom Van Eyck #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
505*b0563631STom Van Eyck     .decrypt_func = rsa_decrypt_wrap,
506*b0563631STom Van Eyck     .encrypt_func = rsa_encrypt_wrap,
507*b0563631STom Van Eyck     .check_pair_func = rsa_check_pair_wrap,
508*b0563631STom Van Eyck     .ctx_alloc_func = rsa_alloc_wrap,
509*b0563631STom Van Eyck     .ctx_free_func = rsa_free_wrap,
510*b0563631STom Van Eyck     .debug_func = rsa_debug,
511817466cbSJens Wiklander };
512817466cbSJens Wiklander #endif /* MBEDTLS_RSA_C */
513817466cbSJens Wiklander 
514*b0563631STom Van Eyck #if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
515817466cbSJens Wiklander /*
516817466cbSJens Wiklander  * Generic EC key
517817466cbSJens Wiklander  */
eckey_can_do(mbedtls_pk_type_t type)518817466cbSJens Wiklander static int eckey_can_do(mbedtls_pk_type_t type)
519817466cbSJens Wiklander {
52032b31808SJens Wiklander     return type == MBEDTLS_PK_ECKEY ||
521817466cbSJens Wiklander            type == MBEDTLS_PK_ECKEY_DH ||
52232b31808SJens Wiklander            type == MBEDTLS_PK_ECDSA;
523817466cbSJens Wiklander }
524817466cbSJens Wiklander 
eckey_get_bitlen(mbedtls_pk_context * pk)525*b0563631STom Van Eyck static size_t eckey_get_bitlen(mbedtls_pk_context *pk)
526817466cbSJens Wiklander {
527*b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
528*b0563631STom Van Eyck     return pk->ec_bits;
529*b0563631STom Van Eyck #else /* MBEDTLS_PK_USE_PSA_EC_DATA */
530*b0563631STom Van Eyck     mbedtls_ecp_keypair *ecp = (mbedtls_ecp_keypair *) pk->pk_ctx;
531*b0563631STom Van Eyck     return ecp->grp.pbits;
532*b0563631STom Van Eyck #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
533817466cbSJens Wiklander }
534817466cbSJens Wiklander 
53532b31808SJens Wiklander #if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY)
53632b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
537*b0563631STom Van Eyck /* Common helper for ECDSA verify using PSA functions. */
ecdsa_verify_psa(unsigned char * key,size_t key_len,psa_ecc_family_t curve,size_t curve_bits,const unsigned char * hash,size_t hash_len,const unsigned char * sig,size_t sig_len)538*b0563631STom Van Eyck static int ecdsa_verify_psa(unsigned char *key, size_t key_len,
539*b0563631STom Van Eyck                             psa_ecc_family_t curve, size_t curve_bits,
54032b31808SJens Wiklander                             const unsigned char *hash, size_t hash_len,
54132b31808SJens Wiklander                             const unsigned char *sig, size_t sig_len)
54232b31808SJens Wiklander {
54332b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
54432b31808SJens Wiklander     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
54532b31808SJens Wiklander     mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
54632b31808SJens Wiklander     psa_algorithm_t psa_sig_md = PSA_ALG_ECDSA_ANY;
547*b0563631STom Van Eyck     size_t signature_len = PSA_ECDSA_SIGNATURE_SIZE(curve_bits);
548*b0563631STom Van Eyck     size_t converted_sig_len;
549*b0563631STom Van Eyck     unsigned char extracted_sig[PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE];
550*b0563631STom Van Eyck     unsigned char *p;
551*b0563631STom Van Eyck     psa_status_t status;
55232b31808SJens Wiklander 
55332b31808SJens Wiklander     if (curve == 0) {
55432b31808SJens Wiklander         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
55532b31808SJens Wiklander     }
55632b31808SJens Wiklander 
55732b31808SJens Wiklander     psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve));
55832b31808SJens Wiklander     psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH);
55932b31808SJens Wiklander     psa_set_key_algorithm(&attributes, psa_sig_md);
56032b31808SJens Wiklander 
561*b0563631STom Van Eyck     status = psa_import_key(&attributes, key, key_len, &key_id);
56232b31808SJens Wiklander     if (status != PSA_SUCCESS) {
56332b31808SJens Wiklander         ret = PSA_PK_TO_MBEDTLS_ERR(status);
56432b31808SJens Wiklander         goto cleanup;
56532b31808SJens Wiklander     }
56632b31808SJens Wiklander 
567*b0563631STom Van Eyck     if (signature_len > sizeof(extracted_sig)) {
56832b31808SJens Wiklander         ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;
56932b31808SJens Wiklander         goto cleanup;
57032b31808SJens Wiklander     }
57132b31808SJens Wiklander 
57232b31808SJens Wiklander     p = (unsigned char *) sig;
573*b0563631STom Van Eyck     ret = mbedtls_ecdsa_der_to_raw(curve_bits, p, sig_len, extracted_sig,
574*b0563631STom Van Eyck                                    sizeof(extracted_sig), &converted_sig_len);
575*b0563631STom Van Eyck     if (ret != 0) {
57632b31808SJens Wiklander         goto cleanup;
57732b31808SJens Wiklander     }
57832b31808SJens Wiklander 
579*b0563631STom Van Eyck     if (converted_sig_len != signature_len) {
580*b0563631STom Van Eyck         ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;
581*b0563631STom Van Eyck         goto cleanup;
582*b0563631STom Van Eyck     }
583*b0563631STom Van Eyck 
584*b0563631STom Van Eyck     status = psa_verify_hash(key_id, psa_sig_md, hash, hash_len,
585*b0563631STom Van Eyck                              extracted_sig, signature_len);
58632b31808SJens Wiklander     if (status != PSA_SUCCESS) {
58732b31808SJens Wiklander         ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
58832b31808SJens Wiklander         goto cleanup;
58932b31808SJens Wiklander     }
59032b31808SJens Wiklander 
59132b31808SJens Wiklander     ret = 0;
59232b31808SJens Wiklander 
59332b31808SJens Wiklander cleanup:
59432b31808SJens Wiklander     status = psa_destroy_key(key_id);
59532b31808SJens Wiklander     if (ret == 0 && status != PSA_SUCCESS) {
59632b31808SJens Wiklander         ret = PSA_PK_TO_MBEDTLS_ERR(status);
59732b31808SJens Wiklander     }
59832b31808SJens Wiklander 
59932b31808SJens Wiklander     return ret;
60032b31808SJens Wiklander }
601*b0563631STom Van Eyck 
ecdsa_opaque_verify_wrap(mbedtls_pk_context * pk,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hash_len,const unsigned char * sig,size_t sig_len)602*b0563631STom Van Eyck static int ecdsa_opaque_verify_wrap(mbedtls_pk_context *pk,
603*b0563631STom Van Eyck                                     mbedtls_md_type_t md_alg,
604*b0563631STom Van Eyck                                     const unsigned char *hash, size_t hash_len,
605*b0563631STom Van Eyck                                     const unsigned char *sig, size_t sig_len)
606*b0563631STom Van Eyck {
607*b0563631STom Van Eyck     (void) md_alg;
608*b0563631STom Van Eyck     unsigned char key[MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN];
609*b0563631STom Van Eyck     size_t key_len;
610*b0563631STom Van Eyck     psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
611*b0563631STom Van Eyck     psa_ecc_family_t curve;
612*b0563631STom Van Eyck     size_t curve_bits;
613*b0563631STom Van Eyck     psa_status_t status;
614*b0563631STom Van Eyck 
615*b0563631STom Van Eyck     status = psa_get_key_attributes(pk->priv_id, &key_attr);
616*b0563631STom Van Eyck     if (status != PSA_SUCCESS) {
617*b0563631STom Van Eyck         return PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
618*b0563631STom Van Eyck     }
619*b0563631STom Van Eyck     curve = PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(&key_attr));
620*b0563631STom Van Eyck     curve_bits = psa_get_key_bits(&key_attr);
621*b0563631STom Van Eyck     psa_reset_key_attributes(&key_attr);
622*b0563631STom Van Eyck 
623*b0563631STom Van Eyck     status = psa_export_public_key(pk->priv_id, key, sizeof(key), &key_len);
624*b0563631STom Van Eyck     if (status != PSA_SUCCESS) {
625*b0563631STom Van Eyck         return PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
626*b0563631STom Van Eyck     }
627*b0563631STom Van Eyck 
628*b0563631STom Van Eyck     return ecdsa_verify_psa(key, key_len, curve, curve_bits,
629*b0563631STom Van Eyck                             hash, hash_len, sig, sig_len);
630*b0563631STom Van Eyck }
631*b0563631STom Van Eyck 
632*b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
ecdsa_verify_wrap(mbedtls_pk_context * pk,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hash_len,const unsigned char * sig,size_t sig_len)633*b0563631STom Van Eyck static int ecdsa_verify_wrap(mbedtls_pk_context *pk,
634*b0563631STom Van Eyck                              mbedtls_md_type_t md_alg,
635*b0563631STom Van Eyck                              const unsigned char *hash, size_t hash_len,
636*b0563631STom Van Eyck                              const unsigned char *sig, size_t sig_len)
637*b0563631STom Van Eyck {
638*b0563631STom Van Eyck     (void) md_alg;
639*b0563631STom Van Eyck     psa_ecc_family_t curve = pk->ec_family;
640*b0563631STom Van Eyck     size_t curve_bits = pk->ec_bits;
641*b0563631STom Van Eyck 
642*b0563631STom Van Eyck     return ecdsa_verify_psa(pk->pub_raw, pk->pub_raw_len, curve, curve_bits,
643*b0563631STom Van Eyck                             hash, hash_len, sig, sig_len);
644*b0563631STom Van Eyck }
645*b0563631STom Van Eyck #else /* MBEDTLS_PK_USE_PSA_EC_DATA */
ecdsa_verify_wrap(mbedtls_pk_context * pk,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hash_len,const unsigned char * sig,size_t sig_len)646*b0563631STom Van Eyck static int ecdsa_verify_wrap(mbedtls_pk_context *pk,
647*b0563631STom Van Eyck                              mbedtls_md_type_t md_alg,
648*b0563631STom Van Eyck                              const unsigned char *hash, size_t hash_len,
649*b0563631STom Van Eyck                              const unsigned char *sig, size_t sig_len)
650*b0563631STom Van Eyck {
651*b0563631STom Van Eyck     (void) md_alg;
652*b0563631STom Van Eyck     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
653*b0563631STom Van Eyck     mbedtls_ecp_keypair *ctx = pk->pk_ctx;
654*b0563631STom Van Eyck     unsigned char key[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
655*b0563631STom Van Eyck     size_t key_len;
656*b0563631STom Van Eyck     size_t curve_bits;
657*b0563631STom Van Eyck     psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(ctx->grp.id, &curve_bits);
658*b0563631STom Van Eyck 
659*b0563631STom Van Eyck     ret = mbedtls_ecp_point_write_binary(&ctx->grp, &ctx->Q,
660*b0563631STom Van Eyck                                          MBEDTLS_ECP_PF_UNCOMPRESSED,
661*b0563631STom Van Eyck                                          &key_len, key, sizeof(key));
662*b0563631STom Van Eyck     if (ret != 0) {
663*b0563631STom Van Eyck         return ret;
664*b0563631STom Van Eyck     }
665*b0563631STom Van Eyck 
666*b0563631STom Van Eyck     return ecdsa_verify_psa(key, key_len, curve, curve_bits,
667*b0563631STom Van Eyck                             hash, hash_len, sig, sig_len);
668*b0563631STom Van Eyck }
669*b0563631STom Van Eyck #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
67032b31808SJens Wiklander #else /* MBEDTLS_USE_PSA_CRYPTO */
ecdsa_verify_wrap(mbedtls_pk_context * pk,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hash_len,const unsigned char * sig,size_t sig_len)671*b0563631STom Van Eyck static int ecdsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
672817466cbSJens Wiklander                              const unsigned char *hash, size_t hash_len,
673817466cbSJens Wiklander                              const unsigned char *sig, size_t sig_len)
674817466cbSJens Wiklander {
67511fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
67632b31808SJens Wiklander     ((void) md_alg);
677817466cbSJens Wiklander 
678*b0563631STom Van Eyck     ret = mbedtls_ecdsa_read_signature((mbedtls_ecdsa_context *) pk->pk_ctx,
67932b31808SJens Wiklander                                        hash, hash_len, sig, sig_len);
680817466cbSJens Wiklander 
68132b31808SJens Wiklander     if (ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) {
68232b31808SJens Wiklander         return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
683817466cbSJens Wiklander     }
684817466cbSJens Wiklander 
68532b31808SJens Wiklander     return ret;
68632b31808SJens Wiklander }
68732b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
68832b31808SJens Wiklander #endif /* MBEDTLS_PK_CAN_ECDSA_VERIFY */
68932b31808SJens Wiklander 
69032b31808SJens Wiklander #if defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
69132b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
692*b0563631STom Van Eyck /* Common helper for ECDSA sign using PSA functions.
693*b0563631STom Van Eyck  * Instead of extracting key's properties in order to check which kind of ECDSA
694*b0563631STom Van Eyck  * signature it supports, we try both deterministic and non-deterministic.
69532b31808SJens Wiklander  */
ecdsa_sign_psa(mbedtls_svc_key_id_t key_id,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hash_len,unsigned char * sig,size_t sig_size,size_t * sig_len)696*b0563631STom Van Eyck static int ecdsa_sign_psa(mbedtls_svc_key_id_t key_id, mbedtls_md_type_t md_alg,
697*b0563631STom Van Eyck                           const unsigned char *hash, size_t hash_len,
698*b0563631STom Van Eyck                           unsigned char *sig, size_t sig_size, size_t *sig_len)
699817466cbSJens Wiklander {
70011fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
701*b0563631STom Van Eyck     psa_status_t status;
702*b0563631STom Van Eyck     psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
703*b0563631STom Van Eyck     size_t key_bits = 0;
704817466cbSJens Wiklander 
705*b0563631STom Van Eyck     status = psa_get_key_attributes(key_id, &key_attr);
706*b0563631STom Van Eyck     if (status != PSA_SUCCESS) {
707*b0563631STom Van Eyck         return PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
708*b0563631STom Van Eyck     }
709*b0563631STom Van Eyck     key_bits = psa_get_key_bits(&key_attr);
710*b0563631STom Van Eyck     psa_reset_key_attributes(&key_attr);
711*b0563631STom Van Eyck 
712*b0563631STom Van Eyck     status = psa_sign_hash(key_id,
713*b0563631STom Van Eyck                            PSA_ALG_DETERMINISTIC_ECDSA(mbedtls_md_psa_alg_from_type(md_alg)),
714*b0563631STom Van Eyck                            hash, hash_len, sig, sig_size, sig_len);
715*b0563631STom Van Eyck     if (status == PSA_SUCCESS) {
716*b0563631STom Van Eyck         goto done;
717*b0563631STom Van Eyck     } else if (status != PSA_ERROR_NOT_PERMITTED) {
718*b0563631STom Van Eyck         return PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
719817466cbSJens Wiklander     }
720817466cbSJens Wiklander 
721*b0563631STom Van Eyck     status = psa_sign_hash(key_id,
722*b0563631STom Van Eyck                            PSA_ALG_ECDSA(mbedtls_md_psa_alg_from_type(md_alg)),
723*b0563631STom Van Eyck                            hash, hash_len, sig, sig_size, sig_len);
724*b0563631STom Van Eyck     if (status != PSA_SUCCESS) {
725*b0563631STom Van Eyck         return PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
72632b31808SJens Wiklander     }
72732b31808SJens Wiklander 
728*b0563631STom Van Eyck done:
729*b0563631STom Van Eyck     ret = mbedtls_ecdsa_raw_to_der(key_bits, sig, *sig_len, sig, sig_size, sig_len);
730*b0563631STom Van Eyck 
731*b0563631STom Van Eyck     return ret;
73232b31808SJens Wiklander }
73332b31808SJens Wiklander 
ecdsa_opaque_sign_wrap(mbedtls_pk_context * pk,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hash_len,unsigned char * sig,size_t sig_size,size_t * sig_len,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)734*b0563631STom Van Eyck static int ecdsa_opaque_sign_wrap(mbedtls_pk_context *pk,
735*b0563631STom Van Eyck                                   mbedtls_md_type_t md_alg,
736*b0563631STom Van Eyck                                   const unsigned char *hash, size_t hash_len,
737*b0563631STom Van Eyck                                   unsigned char *sig, size_t sig_size,
738*b0563631STom Van Eyck                                   size_t *sig_len,
739*b0563631STom Van Eyck                                   int (*f_rng)(void *, unsigned char *, size_t),
740*b0563631STom Van Eyck                                   void *p_rng)
74132b31808SJens Wiklander {
742*b0563631STom Van Eyck     ((void) f_rng);
743*b0563631STom Van Eyck     ((void) p_rng);
74432b31808SJens Wiklander 
745*b0563631STom Van Eyck     return ecdsa_sign_psa(pk->priv_id, md_alg, hash, hash_len, sig, sig_size,
746*b0563631STom Van Eyck                           sig_len);
74732b31808SJens Wiklander }
74832b31808SJens Wiklander 
749*b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
750*b0563631STom Van Eyck /* When PK_USE_PSA_EC_DATA is defined opaque and non-opaque keys end up
751*b0563631STom Van Eyck  * using the same function. */
752*b0563631STom Van Eyck #define ecdsa_sign_wrap     ecdsa_opaque_sign_wrap
753*b0563631STom Van Eyck #else /* MBEDTLS_PK_USE_PSA_EC_DATA */
ecdsa_sign_wrap(mbedtls_pk_context * pk,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hash_len,unsigned char * sig,size_t sig_size,size_t * sig_len,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)754*b0563631STom Van Eyck static int ecdsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
75532b31808SJens Wiklander                            const unsigned char *hash, size_t hash_len,
75632b31808SJens Wiklander                            unsigned char *sig, size_t sig_size, size_t *sig_len,
75732b31808SJens Wiklander                            int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
75832b31808SJens Wiklander {
75932b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
76032b31808SJens Wiklander     mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
76132b31808SJens Wiklander     psa_status_t status;
762*b0563631STom Van Eyck     mbedtls_ecp_keypair *ctx = pk->pk_ctx;
763*b0563631STom Van Eyck     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
76432b31808SJens Wiklander     unsigned char buf[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH];
76532b31808SJens Wiklander     size_t curve_bits;
76632b31808SJens Wiklander     psa_ecc_family_t curve =
76732b31808SJens Wiklander         mbedtls_ecc_group_to_psa(ctx->grp.id, &curve_bits);
76832b31808SJens Wiklander     size_t key_len = PSA_BITS_TO_BYTES(curve_bits);
769*b0563631STom Van Eyck     psa_algorithm_t psa_hash = mbedtls_md_psa_alg_from_type(md_alg);
770*b0563631STom Van Eyck     psa_algorithm_t psa_sig_md = MBEDTLS_PK_PSA_ALG_ECDSA_MAYBE_DET(psa_hash);
77132b31808SJens Wiklander     ((void) f_rng);
77232b31808SJens Wiklander     ((void) p_rng);
77332b31808SJens Wiklander 
77432b31808SJens Wiklander     if (curve == 0) {
77532b31808SJens Wiklander         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
77632b31808SJens Wiklander     }
77732b31808SJens Wiklander 
77832b31808SJens Wiklander     if (key_len > sizeof(buf)) {
77932b31808SJens Wiklander         return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
78032b31808SJens Wiklander     }
78132b31808SJens Wiklander     ret = mbedtls_mpi_write_binary(&ctx->d, buf, key_len);
78232b31808SJens Wiklander     if (ret != 0) {
78332b31808SJens Wiklander         goto cleanup;
78432b31808SJens Wiklander     }
78532b31808SJens Wiklander 
78632b31808SJens Wiklander     psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
78732b31808SJens Wiklander     psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
78832b31808SJens Wiklander     psa_set_key_algorithm(&attributes, psa_sig_md);
78932b31808SJens Wiklander 
790*b0563631STom Van Eyck     status = psa_import_key(&attributes, buf, key_len, &key_id);
79132b31808SJens Wiklander     if (status != PSA_SUCCESS) {
79232b31808SJens Wiklander         ret = PSA_PK_TO_MBEDTLS_ERR(status);
79332b31808SJens Wiklander         goto cleanup;
79432b31808SJens Wiklander     }
79532b31808SJens Wiklander 
796*b0563631STom Van Eyck     ret = ecdsa_sign_psa(key_id, md_alg, hash, hash_len, sig, sig_size, sig_len);
79732b31808SJens Wiklander 
79832b31808SJens Wiklander cleanup:
79932b31808SJens Wiklander     mbedtls_platform_zeroize(buf, sizeof(buf));
80032b31808SJens Wiklander     status = psa_destroy_key(key_id);
80132b31808SJens Wiklander     if (ret == 0 && status != PSA_SUCCESS) {
80232b31808SJens Wiklander         ret = PSA_PK_TO_MBEDTLS_ERR(status);
80332b31808SJens Wiklander     }
80432b31808SJens Wiklander 
80532b31808SJens Wiklander     return ret;
80632b31808SJens Wiklander }
807*b0563631STom Van Eyck #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
80832b31808SJens Wiklander #else /* MBEDTLS_USE_PSA_CRYPTO */
ecdsa_sign_wrap(mbedtls_pk_context * pk,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hash_len,unsigned char * sig,size_t sig_size,size_t * sig_len,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)809*b0563631STom Van Eyck static int ecdsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
81032b31808SJens Wiklander                            const unsigned char *hash, size_t hash_len,
81132b31808SJens Wiklander                            unsigned char *sig, size_t sig_size, size_t *sig_len,
81232b31808SJens Wiklander                            int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
81332b31808SJens Wiklander {
814*b0563631STom Van Eyck     return mbedtls_ecdsa_write_signature((mbedtls_ecdsa_context *) pk->pk_ctx,
81532b31808SJens Wiklander                                          md_alg, hash, hash_len,
81632b31808SJens Wiklander                                          sig, sig_size, sig_len,
81732b31808SJens Wiklander                                          f_rng, p_rng);
81832b31808SJens Wiklander }
81932b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
82032b31808SJens Wiklander #endif /* MBEDTLS_PK_CAN_ECDSA_SIGN */
82132b31808SJens Wiklander 
82232b31808SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
8233d3b0591SJens Wiklander /* Forward declarations */
824*b0563631STom Van Eyck static int ecdsa_verify_rs_wrap(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
8253d3b0591SJens Wiklander                                 const unsigned char *hash, size_t hash_len,
8263d3b0591SJens Wiklander                                 const unsigned char *sig, size_t sig_len,
8273d3b0591SJens Wiklander                                 void *rs_ctx);
8283d3b0591SJens Wiklander 
829*b0563631STom Van Eyck static int ecdsa_sign_rs_wrap(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
8303d3b0591SJens Wiklander                               const unsigned char *hash, size_t hash_len,
83132b31808SJens Wiklander                               unsigned char *sig, size_t sig_size, size_t *sig_len,
8323d3b0591SJens Wiklander                               int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
8333d3b0591SJens Wiklander                               void *rs_ctx);
8343d3b0591SJens Wiklander 
8353d3b0591SJens Wiklander /*
8363d3b0591SJens Wiklander  * Restart context for ECDSA operations with ECKEY context
8373d3b0591SJens Wiklander  *
8383d3b0591SJens Wiklander  * We need to store an actual ECDSA context, as we need to pass the same to
8393d3b0591SJens Wiklander  * the underlying ecdsa function, so we can't create it on the fly every time.
8403d3b0591SJens Wiklander  */
84132b31808SJens Wiklander typedef struct {
8423d3b0591SJens Wiklander     mbedtls_ecdsa_restart_ctx ecdsa_rs;
8433d3b0591SJens Wiklander     mbedtls_ecdsa_context ecdsa_ctx;
8443d3b0591SJens Wiklander } eckey_restart_ctx;
8453d3b0591SJens Wiklander 
eckey_rs_alloc(void)8463d3b0591SJens Wiklander static void *eckey_rs_alloc(void)
8473d3b0591SJens Wiklander {
8483d3b0591SJens Wiklander     eckey_restart_ctx *rs_ctx;
8493d3b0591SJens Wiklander 
8503d3b0591SJens Wiklander     void *ctx = mbedtls_calloc(1, sizeof(eckey_restart_ctx));
8513d3b0591SJens Wiklander 
85232b31808SJens Wiklander     if (ctx != NULL) {
8533d3b0591SJens Wiklander         rs_ctx = ctx;
8543d3b0591SJens Wiklander         mbedtls_ecdsa_restart_init(&rs_ctx->ecdsa_rs);
8553d3b0591SJens Wiklander         mbedtls_ecdsa_init(&rs_ctx->ecdsa_ctx);
8563d3b0591SJens Wiklander     }
8573d3b0591SJens Wiklander 
85832b31808SJens Wiklander     return ctx;
8593d3b0591SJens Wiklander }
8603d3b0591SJens Wiklander 
eckey_rs_free(void * ctx)8613d3b0591SJens Wiklander static void eckey_rs_free(void *ctx)
8623d3b0591SJens Wiklander {
8633d3b0591SJens Wiklander     eckey_restart_ctx *rs_ctx;
8643d3b0591SJens Wiklander 
86532b31808SJens Wiklander     if (ctx == NULL) {
8663d3b0591SJens Wiklander         return;
86732b31808SJens Wiklander     }
8683d3b0591SJens Wiklander 
8693d3b0591SJens Wiklander     rs_ctx = ctx;
8703d3b0591SJens Wiklander     mbedtls_ecdsa_restart_free(&rs_ctx->ecdsa_rs);
8713d3b0591SJens Wiklander     mbedtls_ecdsa_free(&rs_ctx->ecdsa_ctx);
8723d3b0591SJens Wiklander 
8733d3b0591SJens Wiklander     mbedtls_free(ctx);
8743d3b0591SJens Wiklander }
8753d3b0591SJens Wiklander 
eckey_verify_rs_wrap(mbedtls_pk_context * pk,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hash_len,const unsigned char * sig,size_t sig_len,void * rs_ctx)876*b0563631STom Van Eyck static int eckey_verify_rs_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
8773d3b0591SJens Wiklander                                 const unsigned char *hash, size_t hash_len,
8783d3b0591SJens Wiklander                                 const unsigned char *sig, size_t sig_len,
8793d3b0591SJens Wiklander                                 void *rs_ctx)
8803d3b0591SJens Wiklander {
88111fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
8823d3b0591SJens Wiklander     eckey_restart_ctx *rs = rs_ctx;
8833d3b0591SJens Wiklander 
8843d3b0591SJens Wiklander     /* Should never happen */
88532b31808SJens Wiklander     if (rs == NULL) {
88632b31808SJens Wiklander         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
88732b31808SJens Wiklander     }
8883d3b0591SJens Wiklander 
8893d3b0591SJens Wiklander     /* set up our own sub-context if needed (that is, on first run) */
89032b31808SJens Wiklander     if (rs->ecdsa_ctx.grp.pbits == 0) {
891*b0563631STom Van Eyck         MBEDTLS_MPI_CHK(mbedtls_ecdsa_from_keypair(&rs->ecdsa_ctx, pk->pk_ctx));
89232b31808SJens Wiklander     }
8933d3b0591SJens Wiklander 
894*b0563631STom Van Eyck     MBEDTLS_MPI_CHK(ecdsa_verify_rs_wrap(pk,
8953d3b0591SJens Wiklander                                          md_alg, hash, hash_len,
8963d3b0591SJens Wiklander                                          sig, sig_len, &rs->ecdsa_rs));
8973d3b0591SJens Wiklander 
8983d3b0591SJens Wiklander cleanup:
89932b31808SJens Wiklander     return ret;
9003d3b0591SJens Wiklander }
9013d3b0591SJens Wiklander 
eckey_sign_rs_wrap(mbedtls_pk_context * pk,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hash_len,unsigned char * sig,size_t sig_size,size_t * sig_len,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,void * rs_ctx)902*b0563631STom Van Eyck static int eckey_sign_rs_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
9033d3b0591SJens Wiklander                               const unsigned char *hash, size_t hash_len,
90432b31808SJens Wiklander                               unsigned char *sig, size_t sig_size, size_t *sig_len,
9053d3b0591SJens Wiklander                               int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
9063d3b0591SJens Wiklander                               void *rs_ctx)
9073d3b0591SJens Wiklander {
90811fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
9093d3b0591SJens Wiklander     eckey_restart_ctx *rs = rs_ctx;
9103d3b0591SJens Wiklander 
9113d3b0591SJens Wiklander     /* Should never happen */
91232b31808SJens Wiklander     if (rs == NULL) {
91332b31808SJens Wiklander         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
91432b31808SJens Wiklander     }
9153d3b0591SJens Wiklander 
9163d3b0591SJens Wiklander     /* set up our own sub-context if needed (that is, on first run) */
91732b31808SJens Wiklander     if (rs->ecdsa_ctx.grp.pbits == 0) {
918*b0563631STom Van Eyck         MBEDTLS_MPI_CHK(mbedtls_ecdsa_from_keypair(&rs->ecdsa_ctx, pk->pk_ctx));
91932b31808SJens Wiklander     }
9203d3b0591SJens Wiklander 
921*b0563631STom Van Eyck     MBEDTLS_MPI_CHK(ecdsa_sign_rs_wrap(pk, md_alg,
92232b31808SJens Wiklander                                        hash, hash_len, sig, sig_size, sig_len,
9233d3b0591SJens Wiklander                                        f_rng, p_rng, &rs->ecdsa_rs));
9243d3b0591SJens Wiklander 
9253d3b0591SJens Wiklander cleanup:
92632b31808SJens Wiklander     return ret;
9273d3b0591SJens Wiklander }
92832b31808SJens Wiklander #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
929817466cbSJens Wiklander 
930*b0563631STom Van Eyck #if defined(MBEDTLS_USE_PSA_CRYPTO)
931*b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
eckey_check_pair_psa(mbedtls_pk_context * pub,mbedtls_pk_context * prv)932*b0563631STom Van Eyck static int eckey_check_pair_psa(mbedtls_pk_context *pub, mbedtls_pk_context *prv)
933*b0563631STom Van Eyck {
934*b0563631STom Van Eyck     psa_status_t status;
935*b0563631STom Van Eyck     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
936*b0563631STom Van Eyck     uint8_t prv_key_buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
937*b0563631STom Van Eyck     size_t prv_key_len;
938*b0563631STom Van Eyck     mbedtls_svc_key_id_t key_id = prv->priv_id;
939*b0563631STom Van Eyck 
940*b0563631STom Van Eyck     status = psa_export_public_key(key_id, prv_key_buf, sizeof(prv_key_buf),
941*b0563631STom Van Eyck                                    &prv_key_len);
942*b0563631STom Van Eyck     ret = PSA_PK_TO_MBEDTLS_ERR(status);
943*b0563631STom Van Eyck     if (ret != 0) {
944*b0563631STom Van Eyck         return ret;
945*b0563631STom Van Eyck     }
946*b0563631STom Van Eyck 
947*b0563631STom Van Eyck     if (memcmp(prv_key_buf, pub->pub_raw, pub->pub_raw_len) != 0) {
948*b0563631STom Van Eyck         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
949*b0563631STom Van Eyck     }
950*b0563631STom Van Eyck 
951*b0563631STom Van Eyck     return 0;
952*b0563631STom Van Eyck }
953*b0563631STom Van Eyck #else /* MBEDTLS_PK_USE_PSA_EC_DATA */
eckey_check_pair_psa(mbedtls_pk_context * pub,mbedtls_pk_context * prv)954*b0563631STom Van Eyck static int eckey_check_pair_psa(mbedtls_pk_context *pub, mbedtls_pk_context *prv)
955*b0563631STom Van Eyck {
956*b0563631STom Van Eyck     psa_status_t status;
957*b0563631STom Van Eyck     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
958*b0563631STom Van Eyck     uint8_t prv_key_buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
959*b0563631STom Van Eyck     size_t prv_key_len;
960*b0563631STom Van Eyck     psa_status_t destruction_status;
961*b0563631STom Van Eyck     mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
962*b0563631STom Van Eyck     psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
963*b0563631STom Van Eyck     uint8_t pub_key_buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
964*b0563631STom Van Eyck     size_t pub_key_len;
965*b0563631STom Van Eyck     size_t curve_bits;
966*b0563631STom Van Eyck     const psa_ecc_family_t curve =
967*b0563631STom Van Eyck         mbedtls_ecc_group_to_psa(mbedtls_pk_ec_ro(*prv)->grp.id, &curve_bits);
968*b0563631STom Van Eyck     const size_t curve_bytes = PSA_BITS_TO_BYTES(curve_bits);
969*b0563631STom Van Eyck 
970*b0563631STom Van Eyck     if (curve == 0) {
971*b0563631STom Van Eyck         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
972*b0563631STom Van Eyck     }
973*b0563631STom Van Eyck 
974*b0563631STom Van Eyck     psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
975*b0563631STom Van Eyck     psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT);
976*b0563631STom Van Eyck 
977*b0563631STom Van Eyck     ret = mbedtls_mpi_write_binary(&mbedtls_pk_ec_ro(*prv)->d,
978*b0563631STom Van Eyck                                    prv_key_buf, curve_bytes);
979*b0563631STom Van Eyck     if (ret != 0) {
980*b0563631STom Van Eyck         mbedtls_platform_zeroize(prv_key_buf, sizeof(prv_key_buf));
981*b0563631STom Van Eyck         return ret;
982*b0563631STom Van Eyck     }
983*b0563631STom Van Eyck 
984*b0563631STom Van Eyck     status = psa_import_key(&key_attr, prv_key_buf, curve_bytes, &key_id);
985*b0563631STom Van Eyck     mbedtls_platform_zeroize(prv_key_buf, sizeof(prv_key_buf));
986*b0563631STom Van Eyck     ret = PSA_PK_TO_MBEDTLS_ERR(status);
987*b0563631STom Van Eyck     if (ret != 0) {
988*b0563631STom Van Eyck         return ret;
989*b0563631STom Van Eyck     }
990*b0563631STom Van Eyck 
991*b0563631STom Van Eyck     // From now on prv_key_buf is used to store the public key of prv.
992*b0563631STom Van Eyck     status = psa_export_public_key(key_id, prv_key_buf, sizeof(prv_key_buf),
993*b0563631STom Van Eyck                                    &prv_key_len);
994*b0563631STom Van Eyck     ret = PSA_PK_TO_MBEDTLS_ERR(status);
995*b0563631STom Van Eyck     destruction_status = psa_destroy_key(key_id);
996*b0563631STom Van Eyck     if (ret != 0) {
997*b0563631STom Van Eyck         return ret;
998*b0563631STom Van Eyck     } else if (destruction_status != PSA_SUCCESS) {
999*b0563631STom Van Eyck         return PSA_PK_TO_MBEDTLS_ERR(destruction_status);
1000*b0563631STom Van Eyck     }
1001*b0563631STom Van Eyck 
1002*b0563631STom Van Eyck     ret = mbedtls_ecp_point_write_binary(&mbedtls_pk_ec_rw(*pub)->grp,
1003*b0563631STom Van Eyck                                          &mbedtls_pk_ec_rw(*pub)->Q,
1004*b0563631STom Van Eyck                                          MBEDTLS_ECP_PF_UNCOMPRESSED,
1005*b0563631STom Van Eyck                                          &pub_key_len, pub_key_buf,
1006*b0563631STom Van Eyck                                          sizeof(pub_key_buf));
1007*b0563631STom Van Eyck     if (ret != 0) {
1008*b0563631STom Van Eyck         return ret;
1009*b0563631STom Van Eyck     }
1010*b0563631STom Van Eyck 
1011*b0563631STom Van Eyck     if (memcmp(prv_key_buf, pub_key_buf, curve_bytes) != 0) {
1012*b0563631STom Van Eyck         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1013*b0563631STom Van Eyck     }
1014*b0563631STom Van Eyck 
1015*b0563631STom Van Eyck     return 0;
1016*b0563631STom Van Eyck }
1017*b0563631STom Van Eyck #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1018*b0563631STom Van Eyck 
eckey_check_pair_wrap(mbedtls_pk_context * pub,mbedtls_pk_context * prv,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)1019*b0563631STom Van Eyck static int eckey_check_pair_wrap(mbedtls_pk_context *pub, mbedtls_pk_context *prv,
102032b31808SJens Wiklander                                  int (*f_rng)(void *, unsigned char *, size_t),
102132b31808SJens Wiklander                                  void *p_rng)
1022817466cbSJens Wiklander {
1023*b0563631STom Van Eyck     (void) f_rng;
1024*b0563631STom Van Eyck     (void) p_rng;
1025*b0563631STom Van Eyck     return eckey_check_pair_psa(pub, prv);
1026*b0563631STom Van Eyck }
1027*b0563631STom Van Eyck #else /* MBEDTLS_USE_PSA_CRYPTO */
eckey_check_pair_wrap(mbedtls_pk_context * pub,mbedtls_pk_context * prv,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)1028*b0563631STom Van Eyck static int eckey_check_pair_wrap(mbedtls_pk_context *pub, mbedtls_pk_context *prv,
1029*b0563631STom Van Eyck                                  int (*f_rng)(void *, unsigned char *, size_t),
1030*b0563631STom Van Eyck                                  void *p_rng)
1031*b0563631STom Van Eyck {
1032*b0563631STom Van Eyck     return mbedtls_ecp_check_pub_priv((const mbedtls_ecp_keypair *) pub->pk_ctx,
1033*b0563631STom Van Eyck                                       (const mbedtls_ecp_keypair *) prv->pk_ctx,
103432b31808SJens Wiklander                                       f_rng, p_rng);
1035817466cbSJens Wiklander }
1036*b0563631STom Van Eyck #endif /* MBEDTLS_USE_PSA_CRYPTO */
1037817466cbSJens Wiklander 
1038*b0563631STom Van Eyck #if defined(MBEDTLS_USE_PSA_CRYPTO)
1039*b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1040*b0563631STom Van Eyck /* When PK_USE_PSA_EC_DATA is defined opaque and non-opaque keys end up
1041*b0563631STom Van Eyck  * using the same function. */
1042*b0563631STom Van Eyck #define ecdsa_opaque_check_pair_wrap    eckey_check_pair_wrap
1043*b0563631STom Van Eyck #else /* MBEDTLS_PK_USE_PSA_EC_DATA */
ecdsa_opaque_check_pair_wrap(mbedtls_pk_context * pub,mbedtls_pk_context * prv,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)1044*b0563631STom Van Eyck static int ecdsa_opaque_check_pair_wrap(mbedtls_pk_context *pub,
1045*b0563631STom Van Eyck                                         mbedtls_pk_context *prv,
1046*b0563631STom Van Eyck                                         int (*f_rng)(void *, unsigned char *, size_t),
1047*b0563631STom Van Eyck                                         void *p_rng)
1048*b0563631STom Van Eyck {
1049*b0563631STom Van Eyck     psa_status_t status;
1050*b0563631STom Van Eyck     uint8_t exp_pub_key[MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN];
1051*b0563631STom Van Eyck     size_t exp_pub_key_len = 0;
1052*b0563631STom Van Eyck     uint8_t pub_key[MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN];
1053*b0563631STom Van Eyck     size_t pub_key_len = 0;
1054*b0563631STom Van Eyck     int ret;
1055*b0563631STom Van Eyck     (void) f_rng;
1056*b0563631STom Van Eyck     (void) p_rng;
1057*b0563631STom Van Eyck 
1058*b0563631STom Van Eyck     status = psa_export_public_key(prv->priv_id, exp_pub_key, sizeof(exp_pub_key),
1059*b0563631STom Van Eyck                                    &exp_pub_key_len);
1060*b0563631STom Van Eyck     if (status != PSA_SUCCESS) {
1061*b0563631STom Van Eyck         ret = psa_pk_status_to_mbedtls(status);
1062*b0563631STom Van Eyck         return ret;
1063*b0563631STom Van Eyck     }
1064*b0563631STom Van Eyck     ret = mbedtls_ecp_point_write_binary(&(mbedtls_pk_ec_ro(*pub)->grp),
1065*b0563631STom Van Eyck                                          &(mbedtls_pk_ec_ro(*pub)->Q),
1066*b0563631STom Van Eyck                                          MBEDTLS_ECP_PF_UNCOMPRESSED,
1067*b0563631STom Van Eyck                                          &pub_key_len, pub_key, sizeof(pub_key));
1068*b0563631STom Van Eyck     if (ret != 0) {
1069*b0563631STom Van Eyck         return ret;
1070*b0563631STom Van Eyck     }
1071*b0563631STom Van Eyck     if ((exp_pub_key_len != pub_key_len) ||
1072*b0563631STom Van Eyck         memcmp(exp_pub_key, pub_key, exp_pub_key_len)) {
1073*b0563631STom Van Eyck         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1074*b0563631STom Van Eyck     }
1075*b0563631STom Van Eyck     return 0;
1076*b0563631STom Van Eyck }
1077*b0563631STom Van Eyck #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1078*b0563631STom Van Eyck #endif /* MBEDTLS_USE_PSA_CRYPTO */
1079*b0563631STom Van Eyck 
1080*b0563631STom Van Eyck #if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
eckey_alloc_wrap(void)1081817466cbSJens Wiklander static void *eckey_alloc_wrap(void)
1082817466cbSJens Wiklander {
1083817466cbSJens Wiklander     void *ctx = mbedtls_calloc(1, sizeof(mbedtls_ecp_keypair));
1084817466cbSJens Wiklander 
108532b31808SJens Wiklander     if (ctx != NULL) {
1086817466cbSJens Wiklander         mbedtls_ecp_keypair_init(ctx);
108732b31808SJens Wiklander     }
1088817466cbSJens Wiklander 
108932b31808SJens Wiklander     return ctx;
1090817466cbSJens Wiklander }
1091817466cbSJens Wiklander 
eckey_free_wrap(void * ctx)1092817466cbSJens Wiklander static void eckey_free_wrap(void *ctx)
1093817466cbSJens Wiklander {
1094817466cbSJens Wiklander     mbedtls_ecp_keypair_free((mbedtls_ecp_keypair *) ctx);
1095817466cbSJens Wiklander     mbedtls_free(ctx);
1096817466cbSJens Wiklander }
1097*b0563631STom Van Eyck #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1098817466cbSJens Wiklander 
eckey_debug(mbedtls_pk_context * pk,mbedtls_pk_debug_item * items)1099*b0563631STom Van Eyck static void eckey_debug(mbedtls_pk_context *pk, mbedtls_pk_debug_item *items)
1100817466cbSJens Wiklander {
1101*b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1102*b0563631STom Van Eyck     items->type = MBEDTLS_PK_DEBUG_PSA_EC;
1103*b0563631STom Van Eyck     items->name = "eckey.Q";
1104*b0563631STom Van Eyck     items->value = pk;
1105*b0563631STom Van Eyck #else /* MBEDTLS_PK_USE_PSA_EC_DATA */
1106*b0563631STom Van Eyck     mbedtls_ecp_keypair *ecp = (mbedtls_ecp_keypair *) pk->pk_ctx;
1107817466cbSJens Wiklander     items->type = MBEDTLS_PK_DEBUG_ECP;
1108817466cbSJens Wiklander     items->name = "eckey.Q";
1109*b0563631STom Van Eyck     items->value = &(ecp->Q);
1110*b0563631STom Van Eyck #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1111817466cbSJens Wiklander }
1112817466cbSJens Wiklander 
1113817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_eckey_info = {
1114*b0563631STom Van Eyck     .type = MBEDTLS_PK_ECKEY,
1115*b0563631STom Van Eyck     .name = "EC",
1116*b0563631STom Van Eyck     .get_bitlen = eckey_get_bitlen,
1117*b0563631STom Van Eyck     .can_do = eckey_can_do,
111832b31808SJens Wiklander #if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY)
1119*b0563631STom Van Eyck     .verify_func = ecdsa_verify_wrap,   /* Compatible key structures */
1120*b0563631STom Van Eyck #else /* MBEDTLS_PK_CAN_ECDSA_VERIFY */
1121*b0563631STom Van Eyck     .verify_func = NULL,
1122*b0563631STom Van Eyck #endif /* MBEDTLS_PK_CAN_ECDSA_VERIFY */
112332b31808SJens Wiklander #if defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
1124*b0563631STom Van Eyck     .sign_func = ecdsa_sign_wrap,   /* Compatible key structures */
1125*b0563631STom Van Eyck #else /* MBEDTLS_PK_CAN_ECDSA_VERIFY */
1126*b0563631STom Van Eyck     .sign_func = NULL,
1127*b0563631STom Van Eyck #endif /* MBEDTLS_PK_CAN_ECDSA_VERIFY */
112832b31808SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
1129*b0563631STom Van Eyck     .verify_rs_func = eckey_verify_rs_wrap,
1130*b0563631STom Van Eyck     .sign_rs_func = eckey_sign_rs_wrap,
1131*b0563631STom Van Eyck     .rs_alloc_func = eckey_rs_alloc,
1132*b0563631STom Van Eyck     .rs_free_func = eckey_rs_free,
1133*b0563631STom Van Eyck #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
1134*b0563631STom Van Eyck     .decrypt_func = NULL,
1135*b0563631STom Van Eyck     .encrypt_func = NULL,
1136*b0563631STom Van Eyck     .check_pair_func = eckey_check_pair_wrap,
1137*b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1138*b0563631STom Van Eyck     .ctx_alloc_func = NULL,
1139*b0563631STom Van Eyck     .ctx_free_func = NULL,
1140*b0563631STom Van Eyck #else /* MBEDTLS_PK_USE_PSA_EC_DATA */
1141*b0563631STom Van Eyck     .ctx_alloc_func = eckey_alloc_wrap,
1142*b0563631STom Van Eyck     .ctx_free_func = eckey_free_wrap,
1143*b0563631STom Van Eyck #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1144*b0563631STom Van Eyck     .debug_func = eckey_debug,
1145817466cbSJens Wiklander };
1146817466cbSJens Wiklander 
1147817466cbSJens Wiklander /*
1148817466cbSJens Wiklander  * EC key restricted to ECDH
1149817466cbSJens Wiklander  */
eckeydh_can_do(mbedtls_pk_type_t type)1150817466cbSJens Wiklander static int eckeydh_can_do(mbedtls_pk_type_t type)
1151817466cbSJens Wiklander {
115232b31808SJens Wiklander     return type == MBEDTLS_PK_ECKEY ||
115332b31808SJens Wiklander            type == MBEDTLS_PK_ECKEY_DH;
1154817466cbSJens Wiklander }
1155817466cbSJens Wiklander 
1156817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_eckeydh_info = {
1157*b0563631STom Van Eyck     .type = MBEDTLS_PK_ECKEY_DH,
1158*b0563631STom Van Eyck     .name = "EC_DH",
1159*b0563631STom Van Eyck     .get_bitlen = eckey_get_bitlen,         /* Same underlying key structure */
1160*b0563631STom Van Eyck     .can_do = eckeydh_can_do,
1161*b0563631STom Van Eyck     .verify_func = NULL,
1162*b0563631STom Van Eyck     .sign_func = NULL,
11633d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
1164*b0563631STom Van Eyck     .verify_rs_func = NULL,
1165*b0563631STom Van Eyck     .sign_rs_func = NULL,
1166*b0563631STom Van Eyck #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
1167*b0563631STom Van Eyck     .decrypt_func = NULL,
1168*b0563631STom Van Eyck     .encrypt_func = NULL,
1169*b0563631STom Van Eyck     .check_pair_func = eckey_check_pair_wrap,
1170*b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1171*b0563631STom Van Eyck     .ctx_alloc_func = NULL,
1172*b0563631STom Van Eyck     .ctx_free_func = NULL,
1173*b0563631STom Van Eyck #else /* MBEDTLS_PK_USE_PSA_EC_DATA */
1174*b0563631STom Van Eyck     .ctx_alloc_func = eckey_alloc_wrap,   /* Same underlying key structure */
1175*b0563631STom Van Eyck     .ctx_free_func = eckey_free_wrap,    /* Same underlying key structure */
1176*b0563631STom Van Eyck #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1177*b0563631STom Van Eyck     .debug_func = eckey_debug,            /* Same underlying key structure */
1178817466cbSJens Wiklander };
1179817466cbSJens Wiklander 
118032b31808SJens Wiklander #if defined(MBEDTLS_PK_CAN_ECDSA_SOME)
ecdsa_can_do(mbedtls_pk_type_t type)1181817466cbSJens Wiklander static int ecdsa_can_do(mbedtls_pk_type_t type)
1182817466cbSJens Wiklander {
118332b31808SJens Wiklander     return type == MBEDTLS_PK_ECDSA;
1184817466cbSJens Wiklander }
1185817466cbSJens Wiklander 
118632b31808SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
ecdsa_verify_rs_wrap(mbedtls_pk_context * pk,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hash_len,const unsigned char * sig,size_t sig_len,void * rs_ctx)1187*b0563631STom Van Eyck static int ecdsa_verify_rs_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
11883d3b0591SJens Wiklander                                 const unsigned char *hash, size_t hash_len,
11893d3b0591SJens Wiklander                                 const unsigned char *sig, size_t sig_len,
11903d3b0591SJens Wiklander                                 void *rs_ctx)
11913d3b0591SJens Wiklander {
119211fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
11933d3b0591SJens Wiklander     ((void) md_alg);
11943d3b0591SJens Wiklander 
11953d3b0591SJens Wiklander     ret = mbedtls_ecdsa_read_signature_restartable(
1196*b0563631STom Van Eyck         (mbedtls_ecdsa_context *) pk->pk_ctx,
11973d3b0591SJens Wiklander         hash, hash_len, sig, sig_len,
11983d3b0591SJens Wiklander         (mbedtls_ecdsa_restart_ctx *) rs_ctx);
11993d3b0591SJens Wiklander 
120032b31808SJens Wiklander     if (ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) {
120132b31808SJens Wiklander         return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
120232b31808SJens Wiklander     }
12033d3b0591SJens Wiklander 
120432b31808SJens Wiklander     return ret;
12053d3b0591SJens Wiklander }
12063d3b0591SJens Wiklander 
ecdsa_sign_rs_wrap(mbedtls_pk_context * pk,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hash_len,unsigned char * sig,size_t sig_size,size_t * sig_len,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,void * rs_ctx)1207*b0563631STom Van Eyck static int ecdsa_sign_rs_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
12083d3b0591SJens Wiklander                               const unsigned char *hash, size_t hash_len,
120932b31808SJens Wiklander                               unsigned char *sig, size_t sig_size, size_t *sig_len,
12103d3b0591SJens Wiklander                               int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
12113d3b0591SJens Wiklander                               void *rs_ctx)
12123d3b0591SJens Wiklander {
121332b31808SJens Wiklander     return mbedtls_ecdsa_write_signature_restartable(
1214*b0563631STom Van Eyck         (mbedtls_ecdsa_context *) pk->pk_ctx,
121532b31808SJens Wiklander         md_alg, hash, hash_len, sig, sig_size, sig_len, f_rng, p_rng,
121632b31808SJens Wiklander         (mbedtls_ecdsa_restart_ctx *) rs_ctx);
12173d3b0591SJens Wiklander 
12183d3b0591SJens Wiklander }
12193d3b0591SJens Wiklander 
ecdsa_rs_alloc(void)12203d3b0591SJens Wiklander static void *ecdsa_rs_alloc(void)
12213d3b0591SJens Wiklander {
12223d3b0591SJens Wiklander     void *ctx = mbedtls_calloc(1, sizeof(mbedtls_ecdsa_restart_ctx));
12233d3b0591SJens Wiklander 
122432b31808SJens Wiklander     if (ctx != NULL) {
12253d3b0591SJens Wiklander         mbedtls_ecdsa_restart_init(ctx);
122632b31808SJens Wiklander     }
12273d3b0591SJens Wiklander 
122832b31808SJens Wiklander     return ctx;
12293d3b0591SJens Wiklander }
12303d3b0591SJens Wiklander 
ecdsa_rs_free(void * ctx)12313d3b0591SJens Wiklander static void ecdsa_rs_free(void *ctx)
12323d3b0591SJens Wiklander {
12333d3b0591SJens Wiklander     mbedtls_ecdsa_restart_free(ctx);
12343d3b0591SJens Wiklander     mbedtls_free(ctx);
12353d3b0591SJens Wiklander }
123632b31808SJens Wiklander #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
12373d3b0591SJens Wiklander 
1238817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_ecdsa_info = {
1239*b0563631STom Van Eyck     .type = MBEDTLS_PK_ECDSA,
1240*b0563631STom Van Eyck     .name = "ECDSA",
1241*b0563631STom Van Eyck     .get_bitlen = eckey_get_bitlen,     /* Compatible key structures */
1242*b0563631STom Van Eyck     .can_do = ecdsa_can_do,
124332b31808SJens Wiklander #if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY)
1244*b0563631STom Van Eyck     .verify_func = ecdsa_verify_wrap,   /* Compatible key structures */
1245*b0563631STom Van Eyck #else /* MBEDTLS_PK_CAN_ECDSA_VERIFY */
1246*b0563631STom Van Eyck     .verify_func = NULL,
1247*b0563631STom Van Eyck #endif /* MBEDTLS_PK_CAN_ECDSA_VERIFY */
124832b31808SJens Wiklander #if defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
1249*b0563631STom Van Eyck     .sign_func = ecdsa_sign_wrap,   /* Compatible key structures */
1250*b0563631STom Van Eyck #else /* MBEDTLS_PK_CAN_ECDSA_SIGN */
1251*b0563631STom Van Eyck     .sign_func = NULL,
1252*b0563631STom Van Eyck #endif /* MBEDTLS_PK_CAN_ECDSA_SIGN */
125332b31808SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
1254*b0563631STom Van Eyck     .verify_rs_func = ecdsa_verify_rs_wrap,
1255*b0563631STom Van Eyck     .sign_rs_func = ecdsa_sign_rs_wrap,
1256*b0563631STom Van Eyck     .rs_alloc_func = ecdsa_rs_alloc,
1257*b0563631STom Van Eyck     .rs_free_func = ecdsa_rs_free,
1258*b0563631STom Van Eyck #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
1259*b0563631STom Van Eyck     .decrypt_func = NULL,
1260*b0563631STom Van Eyck     .encrypt_func = NULL,
1261*b0563631STom Van Eyck     .check_pair_func = eckey_check_pair_wrap,   /* Compatible key structures */
1262*b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1263*b0563631STom Van Eyck     .ctx_alloc_func = NULL,
1264*b0563631STom Van Eyck     .ctx_free_func = NULL,
1265*b0563631STom Van Eyck #else /* MBEDTLS_PK_USE_PSA_EC_DATA */
1266*b0563631STom Van Eyck     .ctx_alloc_func = eckey_alloc_wrap,   /* Compatible key structures */
1267*b0563631STom Van Eyck     .ctx_free_func = eckey_free_wrap,   /* Compatible key structures */
1268*b0563631STom Van Eyck #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1269*b0563631STom Van Eyck     .debug_func = eckey_debug,        /* Compatible key structures */
1270817466cbSJens Wiklander };
127132b31808SJens Wiklander #endif /* MBEDTLS_PK_CAN_ECDSA_SOME */
1272*b0563631STom Van Eyck #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
1273817466cbSJens Wiklander 
1274817466cbSJens Wiklander #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
1275817466cbSJens Wiklander /*
1276817466cbSJens Wiklander  * Support for alternative RSA-private implementations
1277817466cbSJens Wiklander  */
1278817466cbSJens Wiklander 
rsa_alt_can_do(mbedtls_pk_type_t type)1279817466cbSJens Wiklander static int rsa_alt_can_do(mbedtls_pk_type_t type)
1280817466cbSJens Wiklander {
128132b31808SJens Wiklander     return type == MBEDTLS_PK_RSA;
1282817466cbSJens Wiklander }
1283817466cbSJens Wiklander 
rsa_alt_get_bitlen(mbedtls_pk_context * pk)1284*b0563631STom Van Eyck static size_t rsa_alt_get_bitlen(mbedtls_pk_context *pk)
1285817466cbSJens Wiklander {
1286*b0563631STom Van Eyck     const mbedtls_rsa_alt_context *rsa_alt = pk->pk_ctx;
1287817466cbSJens Wiklander 
128832b31808SJens Wiklander     return 8 * rsa_alt->key_len_func(rsa_alt->key);
1289817466cbSJens Wiklander }
1290817466cbSJens Wiklander 
rsa_alt_sign_wrap(mbedtls_pk_context * pk,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hash_len,unsigned char * sig,size_t sig_size,size_t * sig_len,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)1291*b0563631STom Van Eyck static int rsa_alt_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
1292817466cbSJens Wiklander                              const unsigned char *hash, size_t hash_len,
129332b31808SJens Wiklander                              unsigned char *sig, size_t sig_size, size_t *sig_len,
1294817466cbSJens Wiklander                              int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
1295817466cbSJens Wiklander {
1296*b0563631STom Van Eyck     mbedtls_rsa_alt_context *rsa_alt = pk->pk_ctx;
1297817466cbSJens Wiklander 
1298*b0563631STom Van Eyck #if SIZE_MAX > UINT_MAX
129932b31808SJens Wiklander     if (UINT_MAX < hash_len) {
130032b31808SJens Wiklander         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
130132b31808SJens Wiklander     }
1302*b0563631STom Van Eyck #endif
1303817466cbSJens Wiklander 
1304817466cbSJens Wiklander     *sig_len = rsa_alt->key_len_func(rsa_alt->key);
130532b31808SJens Wiklander     if (*sig_len > MBEDTLS_PK_SIGNATURE_MAX_SIZE) {
130632b31808SJens Wiklander         return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
130732b31808SJens Wiklander     }
130832b31808SJens Wiklander     if (*sig_len > sig_size) {
130932b31808SJens Wiklander         return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
131032b31808SJens Wiklander     }
1311817466cbSJens Wiklander 
131232b31808SJens Wiklander     return rsa_alt->sign_func(rsa_alt->key, f_rng, p_rng,
131332b31808SJens Wiklander                               md_alg, (unsigned int) hash_len, hash, sig);
1314817466cbSJens Wiklander }
1315817466cbSJens Wiklander 
rsa_alt_decrypt_wrap(mbedtls_pk_context * pk,const unsigned char * input,size_t ilen,unsigned char * output,size_t * olen,size_t osize,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)1316*b0563631STom Van Eyck static int rsa_alt_decrypt_wrap(mbedtls_pk_context *pk,
1317817466cbSJens Wiklander                                 const unsigned char *input, size_t ilen,
1318817466cbSJens Wiklander                                 unsigned char *output, size_t *olen, size_t osize,
1319817466cbSJens Wiklander                                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
1320817466cbSJens Wiklander {
1321*b0563631STom Van Eyck     mbedtls_rsa_alt_context *rsa_alt = pk->pk_ctx;
1322817466cbSJens Wiklander 
1323817466cbSJens Wiklander     ((void) f_rng);
1324817466cbSJens Wiklander     ((void) p_rng);
1325817466cbSJens Wiklander 
132632b31808SJens Wiklander     if (ilen != rsa_alt->key_len_func(rsa_alt->key)) {
132732b31808SJens Wiklander         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
132832b31808SJens Wiklander     }
1329817466cbSJens Wiklander 
133032b31808SJens Wiklander     return rsa_alt->decrypt_func(rsa_alt->key,
133132b31808SJens Wiklander                                  olen, input, output, osize);
1332817466cbSJens Wiklander }
1333817466cbSJens Wiklander 
1334817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C)
rsa_alt_check_pair(mbedtls_pk_context * pub,mbedtls_pk_context * prv,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)1335*b0563631STom Van Eyck static int rsa_alt_check_pair(mbedtls_pk_context *pub, mbedtls_pk_context *prv,
133632b31808SJens Wiklander                               int (*f_rng)(void *, unsigned char *, size_t),
133732b31808SJens Wiklander                               void *p_rng)
1338817466cbSJens Wiklander {
1339817466cbSJens Wiklander     unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
1340817466cbSJens Wiklander     unsigned char hash[32];
1341817466cbSJens Wiklander     size_t sig_len = 0;
134211fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1343817466cbSJens Wiklander 
134432b31808SJens Wiklander     if (rsa_alt_get_bitlen(prv) != rsa_get_bitlen(pub)) {
134532b31808SJens Wiklander         return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
134632b31808SJens Wiklander     }
1347817466cbSJens Wiklander 
1348817466cbSJens Wiklander     memset(hash, 0x2a, sizeof(hash));
1349817466cbSJens Wiklander 
1350*b0563631STom Van Eyck     if ((ret = rsa_alt_sign_wrap(prv, MBEDTLS_MD_NONE,
1351817466cbSJens Wiklander                                  hash, sizeof(hash),
135232b31808SJens Wiklander                                  sig, sizeof(sig), &sig_len,
135332b31808SJens Wiklander                                  f_rng, p_rng)) != 0) {
135432b31808SJens Wiklander         return ret;
1355817466cbSJens Wiklander     }
1356817466cbSJens Wiklander 
1357*b0563631STom Van Eyck     if (rsa_verify_wrap(pub, MBEDTLS_MD_NONE,
135832b31808SJens Wiklander                         hash, sizeof(hash), sig, sig_len) != 0) {
135932b31808SJens Wiklander         return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
1360817466cbSJens Wiklander     }
1361817466cbSJens Wiklander 
136232b31808SJens Wiklander     return 0;
1363817466cbSJens Wiklander }
1364817466cbSJens Wiklander #endif /* MBEDTLS_RSA_C */
1365817466cbSJens Wiklander 
rsa_alt_alloc_wrap(void)1366817466cbSJens Wiklander static void *rsa_alt_alloc_wrap(void)
1367817466cbSJens Wiklander {
1368817466cbSJens Wiklander     void *ctx = mbedtls_calloc(1, sizeof(mbedtls_rsa_alt_context));
1369817466cbSJens Wiklander 
137032b31808SJens Wiklander     if (ctx != NULL) {
1371817466cbSJens Wiklander         memset(ctx, 0, sizeof(mbedtls_rsa_alt_context));
137232b31808SJens Wiklander     }
1373817466cbSJens Wiklander 
137432b31808SJens Wiklander     return ctx;
1375817466cbSJens Wiklander }
1376817466cbSJens Wiklander 
rsa_alt_free_wrap(void * ctx)1377817466cbSJens Wiklander static void rsa_alt_free_wrap(void *ctx)
1378817466cbSJens Wiklander {
1379*b0563631STom Van Eyck     mbedtls_zeroize_and_free(ctx, sizeof(mbedtls_rsa_alt_context));
1380817466cbSJens Wiklander }
1381817466cbSJens Wiklander 
1382817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
1383*b0563631STom Van Eyck     .type = MBEDTLS_PK_RSA_ALT,
1384*b0563631STom Van Eyck     .name = "RSA-alt",
1385*b0563631STom Van Eyck     .get_bitlen = rsa_alt_get_bitlen,
1386*b0563631STom Van Eyck     .can_do = rsa_alt_can_do,
1387*b0563631STom Van Eyck     .verify_func = NULL,
1388*b0563631STom Van Eyck     .sign_func = rsa_alt_sign_wrap,
13893d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
1390*b0563631STom Van Eyck     .verify_rs_func = NULL,
1391*b0563631STom Van Eyck     .sign_rs_func = NULL,
1392*b0563631STom Van Eyck     .rs_alloc_func = NULL,
1393*b0563631STom Van Eyck     .rs_free_func = NULL,
1394*b0563631STom Van Eyck #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
1395*b0563631STom Van Eyck     .decrypt_func = rsa_alt_decrypt_wrap,
1396*b0563631STom Van Eyck     .encrypt_func = NULL,
1397817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C)
1398*b0563631STom Van Eyck     .check_pair_func = rsa_alt_check_pair,
1399817466cbSJens Wiklander #else
1400*b0563631STom Van Eyck     .check_pair_func = NULL,
1401817466cbSJens Wiklander #endif
1402*b0563631STom Van Eyck     .ctx_alloc_func = rsa_alt_alloc_wrap,
1403*b0563631STom Van Eyck     .ctx_free_func = rsa_alt_free_wrap,
1404*b0563631STom Van Eyck     .debug_func = NULL,
1405817466cbSJens Wiklander };
1406817466cbSJens Wiklander #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
1407817466cbSJens Wiklander 
140811fa71b9SJerome Forissier #if defined(MBEDTLS_USE_PSA_CRYPTO)
opaque_get_bitlen(mbedtls_pk_context * pk)1409*b0563631STom Van Eyck static size_t opaque_get_bitlen(mbedtls_pk_context *pk)
141011fa71b9SJerome Forissier {
141111fa71b9SJerome Forissier     size_t bits;
141211fa71b9SJerome Forissier     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
141311fa71b9SJerome Forissier 
1414*b0563631STom Van Eyck     if (PSA_SUCCESS != psa_get_key_attributes(pk->priv_id, &attributes)) {
141532b31808SJens Wiklander         return 0;
141632b31808SJens Wiklander     }
141711fa71b9SJerome Forissier 
141811fa71b9SJerome Forissier     bits = psa_get_key_bits(&attributes);
141911fa71b9SJerome Forissier     psa_reset_key_attributes(&attributes);
142032b31808SJens Wiklander     return bits;
142111fa71b9SJerome Forissier }
142211fa71b9SJerome Forissier 
1423*b0563631STom Van Eyck #if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
ecdsa_opaque_can_do(mbedtls_pk_type_t type)1424*b0563631STom Van Eyck static int ecdsa_opaque_can_do(mbedtls_pk_type_t type)
142511fa71b9SJerome Forissier {
142632b31808SJens Wiklander     return type == MBEDTLS_PK_ECKEY ||
142732b31808SJens Wiklander            type == MBEDTLS_PK_ECDSA;
142811fa71b9SJerome Forissier }
142911fa71b9SJerome Forissier 
1430*b0563631STom Van Eyck const mbedtls_pk_info_t mbedtls_ecdsa_opaque_info = {
1431*b0563631STom Van Eyck     .type = MBEDTLS_PK_OPAQUE,
1432*b0563631STom Van Eyck     .name = "Opaque",
1433*b0563631STom Van Eyck     .get_bitlen = opaque_get_bitlen,
1434*b0563631STom Van Eyck     .can_do = ecdsa_opaque_can_do,
1435*b0563631STom Van Eyck #if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY)
1436*b0563631STom Van Eyck     .verify_func = ecdsa_opaque_verify_wrap,
1437*b0563631STom Van Eyck #else /* MBEDTLS_PK_CAN_ECDSA_VERIFY */
1438*b0563631STom Van Eyck     .verify_func = NULL,
1439*b0563631STom Van Eyck #endif /* MBEDTLS_PK_CAN_ECDSA_VERIFY */
1440*b0563631STom Van Eyck #if defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
1441*b0563631STom Van Eyck     .sign_func = ecdsa_opaque_sign_wrap,
1442*b0563631STom Van Eyck #else /* MBEDTLS_PK_CAN_ECDSA_SIGN */
1443*b0563631STom Van Eyck     .sign_func = NULL,
1444*b0563631STom Van Eyck #endif /* MBEDTLS_PK_CAN_ECDSA_SIGN */
1445*b0563631STom Van Eyck #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
1446*b0563631STom Van Eyck     .verify_rs_func = NULL,
1447*b0563631STom Van Eyck     .sign_rs_func = NULL,
1448*b0563631STom Van Eyck     .rs_alloc_func = NULL,
1449*b0563631STom Van Eyck     .rs_free_func = NULL,
1450*b0563631STom Van Eyck #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
1451*b0563631STom Van Eyck     .decrypt_func = NULL,
1452*b0563631STom Van Eyck     .encrypt_func = NULL,
1453*b0563631STom Van Eyck     .check_pair_func = ecdsa_opaque_check_pair_wrap,
1454*b0563631STom Van Eyck     .ctx_alloc_func = NULL,
1455*b0563631STom Van Eyck     .ctx_free_func = NULL,
1456*b0563631STom Van Eyck     .debug_func = NULL,
1457*b0563631STom Van Eyck };
1458*b0563631STom Van Eyck #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
1459*b0563631STom Van Eyck 
rsa_opaque_can_do(mbedtls_pk_type_t type)1460*b0563631STom Van Eyck static int rsa_opaque_can_do(mbedtls_pk_type_t type)
146111fa71b9SJerome Forissier {
146232b31808SJens Wiklander     return type == MBEDTLS_PK_RSA ||
146332b31808SJens Wiklander            type == MBEDTLS_PK_RSASSA_PSS;
146411fa71b9SJerome Forissier }
146511fa71b9SJerome Forissier 
1466*b0563631STom Van Eyck #if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
rsa_opaque_decrypt(mbedtls_pk_context * pk,const unsigned char * input,size_t ilen,unsigned char * output,size_t * olen,size_t osize,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)1467*b0563631STom Van Eyck static int rsa_opaque_decrypt(mbedtls_pk_context *pk,
1468*b0563631STom Van Eyck                               const unsigned char *input, size_t ilen,
1469*b0563631STom Van Eyck                               unsigned char *output, size_t *olen, size_t osize,
147011fa71b9SJerome Forissier                               int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
147111fa71b9SJerome Forissier {
147211fa71b9SJerome Forissier     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
147332b31808SJens Wiklander     psa_algorithm_t alg;
147432b31808SJens Wiklander     psa_key_type_t type;
147511fa71b9SJerome Forissier     psa_status_t status;
147611fa71b9SJerome Forissier 
147711fa71b9SJerome Forissier     /* PSA has its own RNG */
147811fa71b9SJerome Forissier     (void) f_rng;
147911fa71b9SJerome Forissier     (void) p_rng;
148011fa71b9SJerome Forissier 
1481*b0563631STom Van Eyck     status = psa_get_key_attributes(pk->priv_id, &attributes);
148232b31808SJens Wiklander     if (status != PSA_SUCCESS) {
148332b31808SJens Wiklander         return PSA_PK_TO_MBEDTLS_ERR(status);
148432b31808SJens Wiklander     }
148532b31808SJens Wiklander 
148632b31808SJens Wiklander     type = psa_get_key_type(&attributes);
1487*b0563631STom Van Eyck     alg = psa_get_key_algorithm(&attributes);
148811fa71b9SJerome Forissier     psa_reset_key_attributes(&attributes);
148932b31808SJens Wiklander 
1490*b0563631STom Van Eyck     if (!PSA_KEY_TYPE_IS_RSA(type)) {
149132b31808SJens Wiklander         return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
1492*b0563631STom Van Eyck     }
149311fa71b9SJerome Forissier 
1494*b0563631STom Van Eyck     status = psa_asymmetric_decrypt(pk->priv_id, alg, input, ilen, NULL, 0, output, osize, olen);
149532b31808SJens Wiklander     if (status != PSA_SUCCESS) {
149632b31808SJens Wiklander         return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
149711fa71b9SJerome Forissier     }
149811fa71b9SJerome Forissier 
149932b31808SJens Wiklander     return 0;
150032b31808SJens Wiklander }
1501*b0563631STom Van Eyck #endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC */
150232b31808SJens Wiklander 
rsa_opaque_sign_wrap(mbedtls_pk_context * pk,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hash_len,unsigned char * sig,size_t sig_size,size_t * sig_len,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)1503*b0563631STom Van Eyck static int rsa_opaque_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
1504*b0563631STom Van Eyck                                 const unsigned char *hash, size_t hash_len,
1505*b0563631STom Van Eyck                                 unsigned char *sig, size_t sig_size, size_t *sig_len,
150632b31808SJens Wiklander                                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
150732b31808SJens Wiklander {
1508*b0563631STom Van Eyck #if defined(MBEDTLS_RSA_C)
1509*b0563631STom Van Eyck     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1510*b0563631STom Van Eyck     psa_algorithm_t alg;
1511*b0563631STom Van Eyck     psa_key_type_t type;
151232b31808SJens Wiklander     psa_status_t status;
151332b31808SJens Wiklander 
151432b31808SJens Wiklander     /* PSA has its own RNG */
151532b31808SJens Wiklander     (void) f_rng;
151632b31808SJens Wiklander     (void) p_rng;
151732b31808SJens Wiklander 
1518*b0563631STom Van Eyck     status = psa_get_key_attributes(pk->priv_id, &attributes);
151932b31808SJens Wiklander     if (status != PSA_SUCCESS) {
1520*b0563631STom Van Eyck         return PSA_PK_TO_MBEDTLS_ERR(status);
1521*b0563631STom Van Eyck     }
1522*b0563631STom Van Eyck 
1523*b0563631STom Van Eyck     type = psa_get_key_type(&attributes);
1524*b0563631STom Van Eyck     alg = psa_get_key_algorithm(&attributes);
1525*b0563631STom Van Eyck     psa_reset_key_attributes(&attributes);
1526*b0563631STom Van Eyck 
1527*b0563631STom Van Eyck     if (PSA_KEY_TYPE_IS_RSA(type)) {
1528*b0563631STom Van Eyck         alg = (alg & ~PSA_ALG_HASH_MASK) | mbedtls_md_psa_alg_from_type(md_alg);
1529*b0563631STom Van Eyck     } else {
1530*b0563631STom Van Eyck         return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
1531*b0563631STom Van Eyck     }
1532*b0563631STom Van Eyck 
1533*b0563631STom Van Eyck     status = psa_sign_hash(pk->priv_id, alg, hash, hash_len, sig, sig_size, sig_len);
1534*b0563631STom Van Eyck     if (status != PSA_SUCCESS) {
1535*b0563631STom Van Eyck         if (PSA_KEY_TYPE_IS_RSA(type)) {
153632b31808SJens Wiklander             return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
1537*b0563631STom Van Eyck         } else {
1538*b0563631STom Van Eyck             return PSA_PK_TO_MBEDTLS_ERR(status);
1539*b0563631STom Van Eyck         }
154032b31808SJens Wiklander     }
154132b31808SJens Wiklander 
154232b31808SJens Wiklander     return 0;
1543*b0563631STom Van Eyck #else /* !MBEDTLS_RSA_C */
1544*b0563631STom Van Eyck     ((void) pk);
1545*b0563631STom Van Eyck     ((void) md_alg);
1546*b0563631STom Van Eyck     ((void) hash);
1547*b0563631STom Van Eyck     ((void) hash_len);
1548*b0563631STom Van Eyck     ((void) sig);
1549*b0563631STom Van Eyck     ((void) sig_size);
1550*b0563631STom Van Eyck     ((void) sig_len);
1551*b0563631STom Van Eyck     ((void) f_rng);
1552*b0563631STom Van Eyck     ((void) p_rng);
1553*b0563631STom Van Eyck     return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
1554*b0563631STom Van Eyck #endif /* !MBEDTLS_RSA_C */
155532b31808SJens Wiklander }
155632b31808SJens Wiklander 
1557*b0563631STom Van Eyck const mbedtls_pk_info_t mbedtls_rsa_opaque_info = {
1558*b0563631STom Van Eyck     .type = MBEDTLS_PK_OPAQUE,
1559*b0563631STom Van Eyck     .name = "Opaque",
1560*b0563631STom Van Eyck     .get_bitlen = opaque_get_bitlen,
1561*b0563631STom Van Eyck     .can_do = rsa_opaque_can_do,
1562*b0563631STom Van Eyck     .verify_func = NULL,
1563*b0563631STom Van Eyck     .sign_func = rsa_opaque_sign_wrap,
156432b31808SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
1565*b0563631STom Van Eyck     .verify_rs_func = NULL,
1566*b0563631STom Van Eyck     .sign_rs_func = NULL,
1567*b0563631STom Van Eyck     .rs_alloc_func = NULL,
1568*b0563631STom Van Eyck     .rs_free_func = NULL,
1569*b0563631STom Van Eyck #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
1570*b0563631STom Van Eyck #if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
1571*b0563631STom Van Eyck     .decrypt_func = rsa_opaque_decrypt,
1572*b0563631STom Van Eyck #else /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC */
1573*b0563631STom Van Eyck     .decrypt_func = NULL,
1574*b0563631STom Van Eyck #endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC */
1575*b0563631STom Van Eyck     .encrypt_func = NULL,
1576*b0563631STom Van Eyck     .check_pair_func = NULL,
1577*b0563631STom Van Eyck     .ctx_alloc_func = NULL,
1578*b0563631STom Van Eyck     .ctx_free_func = NULL,
1579*b0563631STom Van Eyck     .debug_func = NULL,
158011fa71b9SJerome Forissier };
158111fa71b9SJerome Forissier 
158211fa71b9SJerome Forissier #endif /* MBEDTLS_USE_PSA_CRYPTO */
158311fa71b9SJerome Forissier 
1584817466cbSJens Wiklander #endif /* MBEDTLS_PK_C */
1585