1*62c56f98SSadaf Ebrahimi /*
2*62c56f98SSadaf Ebrahimi * Public Key abstraction layer
3*62c56f98SSadaf Ebrahimi *
4*62c56f98SSadaf Ebrahimi * Copyright The Mbed TLS Contributors
5*62c56f98SSadaf Ebrahimi * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6*62c56f98SSadaf Ebrahimi */
7*62c56f98SSadaf Ebrahimi
8*62c56f98SSadaf Ebrahimi #include "common.h"
9*62c56f98SSadaf Ebrahimi
10*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PK_C)
11*62c56f98SSadaf Ebrahimi #include "mbedtls/pk.h"
12*62c56f98SSadaf Ebrahimi #include "pk_wrap.h"
13*62c56f98SSadaf Ebrahimi #include "pkwrite.h"
14*62c56f98SSadaf Ebrahimi #include "pk_internal.h"
15*62c56f98SSadaf Ebrahimi
16*62c56f98SSadaf Ebrahimi #include "mbedtls/platform_util.h"
17*62c56f98SSadaf Ebrahimi #include "mbedtls/error.h"
18*62c56f98SSadaf Ebrahimi
19*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_RSA_C)
20*62c56f98SSadaf Ebrahimi #include "mbedtls/rsa.h"
21*62c56f98SSadaf Ebrahimi #endif
22*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
23*62c56f98SSadaf Ebrahimi #include "mbedtls/ecp.h"
24*62c56f98SSadaf Ebrahimi #endif
25*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_ECDSA_C)
26*62c56f98SSadaf Ebrahimi #include "mbedtls/ecdsa.h"
27*62c56f98SSadaf Ebrahimi #endif
28*62c56f98SSadaf Ebrahimi
29*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_CRYPTO_C)
30*62c56f98SSadaf Ebrahimi #include "psa_util_internal.h"
31*62c56f98SSadaf Ebrahimi #include "md_psa.h"
32*62c56f98SSadaf Ebrahimi #endif
33*62c56f98SSadaf Ebrahimi
34*62c56f98SSadaf Ebrahimi #include <limits.h>
35*62c56f98SSadaf Ebrahimi #include <stdint.h>
36*62c56f98SSadaf Ebrahimi
37*62c56f98SSadaf Ebrahimi /*
38*62c56f98SSadaf Ebrahimi * Initialise a mbedtls_pk_context
39*62c56f98SSadaf Ebrahimi */
mbedtls_pk_init(mbedtls_pk_context * ctx)40*62c56f98SSadaf Ebrahimi void mbedtls_pk_init(mbedtls_pk_context *ctx)
41*62c56f98SSadaf Ebrahimi {
42*62c56f98SSadaf Ebrahimi ctx->pk_info = NULL;
43*62c56f98SSadaf Ebrahimi ctx->pk_ctx = NULL;
44*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_CRYPTO_C)
45*62c56f98SSadaf Ebrahimi ctx->priv_id = MBEDTLS_SVC_KEY_ID_INIT;
46*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PSA_CRYPTO_C */
47*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
48*62c56f98SSadaf Ebrahimi memset(ctx->pub_raw, 0, sizeof(ctx->pub_raw));
49*62c56f98SSadaf Ebrahimi ctx->pub_raw_len = 0;
50*62c56f98SSadaf Ebrahimi ctx->ec_family = 0;
51*62c56f98SSadaf Ebrahimi ctx->ec_bits = 0;
52*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
53*62c56f98SSadaf Ebrahimi }
54*62c56f98SSadaf Ebrahimi
55*62c56f98SSadaf Ebrahimi /*
56*62c56f98SSadaf Ebrahimi * Free (the components of) a mbedtls_pk_context
57*62c56f98SSadaf Ebrahimi */
mbedtls_pk_free(mbedtls_pk_context * ctx)58*62c56f98SSadaf Ebrahimi void mbedtls_pk_free(mbedtls_pk_context *ctx)
59*62c56f98SSadaf Ebrahimi {
60*62c56f98SSadaf Ebrahimi if (ctx == NULL) {
61*62c56f98SSadaf Ebrahimi return;
62*62c56f98SSadaf Ebrahimi }
63*62c56f98SSadaf Ebrahimi
64*62c56f98SSadaf Ebrahimi if ((ctx->pk_info != NULL) && (ctx->pk_info->ctx_free_func != NULL)) {
65*62c56f98SSadaf Ebrahimi ctx->pk_info->ctx_free_func(ctx->pk_ctx);
66*62c56f98SSadaf Ebrahimi }
67*62c56f98SSadaf Ebrahimi
68*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
69*62c56f98SSadaf Ebrahimi /* The ownership of the priv_id key for opaque keys is external of the PK
70*62c56f98SSadaf Ebrahimi * module. It's the user responsibility to clear it after use. */
71*62c56f98SSadaf Ebrahimi if ((ctx->pk_info != NULL) && (ctx->pk_info->type != MBEDTLS_PK_OPAQUE)) {
72*62c56f98SSadaf Ebrahimi psa_destroy_key(ctx->priv_id);
73*62c56f98SSadaf Ebrahimi }
74*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
75*62c56f98SSadaf Ebrahimi
76*62c56f98SSadaf Ebrahimi mbedtls_platform_zeroize(ctx, sizeof(mbedtls_pk_context));
77*62c56f98SSadaf Ebrahimi }
78*62c56f98SSadaf Ebrahimi
79*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
80*62c56f98SSadaf Ebrahimi /*
81*62c56f98SSadaf Ebrahimi * Initialize a restart context
82*62c56f98SSadaf Ebrahimi */
mbedtls_pk_restart_init(mbedtls_pk_restart_ctx * ctx)83*62c56f98SSadaf Ebrahimi void mbedtls_pk_restart_init(mbedtls_pk_restart_ctx *ctx)
84*62c56f98SSadaf Ebrahimi {
85*62c56f98SSadaf Ebrahimi ctx->pk_info = NULL;
86*62c56f98SSadaf Ebrahimi ctx->rs_ctx = NULL;
87*62c56f98SSadaf Ebrahimi }
88*62c56f98SSadaf Ebrahimi
89*62c56f98SSadaf Ebrahimi /*
90*62c56f98SSadaf Ebrahimi * Free the components of a restart context
91*62c56f98SSadaf Ebrahimi */
mbedtls_pk_restart_free(mbedtls_pk_restart_ctx * ctx)92*62c56f98SSadaf Ebrahimi void mbedtls_pk_restart_free(mbedtls_pk_restart_ctx *ctx)
93*62c56f98SSadaf Ebrahimi {
94*62c56f98SSadaf Ebrahimi if (ctx == NULL || ctx->pk_info == NULL ||
95*62c56f98SSadaf Ebrahimi ctx->pk_info->rs_free_func == NULL) {
96*62c56f98SSadaf Ebrahimi return;
97*62c56f98SSadaf Ebrahimi }
98*62c56f98SSadaf Ebrahimi
99*62c56f98SSadaf Ebrahimi ctx->pk_info->rs_free_func(ctx->rs_ctx);
100*62c56f98SSadaf Ebrahimi
101*62c56f98SSadaf Ebrahimi ctx->pk_info = NULL;
102*62c56f98SSadaf Ebrahimi ctx->rs_ctx = NULL;
103*62c56f98SSadaf Ebrahimi }
104*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
105*62c56f98SSadaf Ebrahimi
106*62c56f98SSadaf Ebrahimi /*
107*62c56f98SSadaf Ebrahimi * Get pk_info structure from type
108*62c56f98SSadaf Ebrahimi */
mbedtls_pk_info_from_type(mbedtls_pk_type_t pk_type)109*62c56f98SSadaf Ebrahimi const mbedtls_pk_info_t *mbedtls_pk_info_from_type(mbedtls_pk_type_t pk_type)
110*62c56f98SSadaf Ebrahimi {
111*62c56f98SSadaf Ebrahimi switch (pk_type) {
112*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_RSA_C)
113*62c56f98SSadaf Ebrahimi case MBEDTLS_PK_RSA:
114*62c56f98SSadaf Ebrahimi return &mbedtls_rsa_info;
115*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_RSA_C */
116*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
117*62c56f98SSadaf Ebrahimi case MBEDTLS_PK_ECKEY:
118*62c56f98SSadaf Ebrahimi return &mbedtls_eckey_info;
119*62c56f98SSadaf Ebrahimi case MBEDTLS_PK_ECKEY_DH:
120*62c56f98SSadaf Ebrahimi return &mbedtls_eckeydh_info;
121*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
122*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PK_CAN_ECDSA_SOME)
123*62c56f98SSadaf Ebrahimi case MBEDTLS_PK_ECDSA:
124*62c56f98SSadaf Ebrahimi return &mbedtls_ecdsa_info;
125*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PK_CAN_ECDSA_SOME */
126*62c56f98SSadaf Ebrahimi /* MBEDTLS_PK_RSA_ALT omitted on purpose */
127*62c56f98SSadaf Ebrahimi default:
128*62c56f98SSadaf Ebrahimi return NULL;
129*62c56f98SSadaf Ebrahimi }
130*62c56f98SSadaf Ebrahimi }
131*62c56f98SSadaf Ebrahimi
132*62c56f98SSadaf Ebrahimi /*
133*62c56f98SSadaf Ebrahimi * Initialise context
134*62c56f98SSadaf Ebrahimi */
mbedtls_pk_setup(mbedtls_pk_context * ctx,const mbedtls_pk_info_t * info)135*62c56f98SSadaf Ebrahimi int mbedtls_pk_setup(mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info)
136*62c56f98SSadaf Ebrahimi {
137*62c56f98SSadaf Ebrahimi if (info == NULL || ctx->pk_info != NULL) {
138*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
139*62c56f98SSadaf Ebrahimi }
140*62c56f98SSadaf Ebrahimi
141*62c56f98SSadaf Ebrahimi if ((info->ctx_alloc_func != NULL) &&
142*62c56f98SSadaf Ebrahimi ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL)) {
143*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_ALLOC_FAILED;
144*62c56f98SSadaf Ebrahimi }
145*62c56f98SSadaf Ebrahimi
146*62c56f98SSadaf Ebrahimi ctx->pk_info = info;
147*62c56f98SSadaf Ebrahimi
148*62c56f98SSadaf Ebrahimi return 0;
149*62c56f98SSadaf Ebrahimi }
150*62c56f98SSadaf Ebrahimi
151*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_USE_PSA_CRYPTO)
152*62c56f98SSadaf Ebrahimi /*
153*62c56f98SSadaf Ebrahimi * Initialise a PSA-wrapping context
154*62c56f98SSadaf Ebrahimi */
mbedtls_pk_setup_opaque(mbedtls_pk_context * ctx,const mbedtls_svc_key_id_t key)155*62c56f98SSadaf Ebrahimi int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx,
156*62c56f98SSadaf Ebrahimi const mbedtls_svc_key_id_t key)
157*62c56f98SSadaf Ebrahimi {
158*62c56f98SSadaf Ebrahimi const mbedtls_pk_info_t *info = NULL;
159*62c56f98SSadaf Ebrahimi psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
160*62c56f98SSadaf Ebrahimi psa_key_type_t type;
161*62c56f98SSadaf Ebrahimi
162*62c56f98SSadaf Ebrahimi if (ctx == NULL || ctx->pk_info != NULL) {
163*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
164*62c56f98SSadaf Ebrahimi }
165*62c56f98SSadaf Ebrahimi
166*62c56f98SSadaf Ebrahimi if (PSA_SUCCESS != psa_get_key_attributes(key, &attributes)) {
167*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
168*62c56f98SSadaf Ebrahimi }
169*62c56f98SSadaf Ebrahimi type = psa_get_key_type(&attributes);
170*62c56f98SSadaf Ebrahimi psa_reset_key_attributes(&attributes);
171*62c56f98SSadaf Ebrahimi
172*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
173*62c56f98SSadaf Ebrahimi if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
174*62c56f98SSadaf Ebrahimi info = &mbedtls_ecdsa_opaque_info;
175*62c56f98SSadaf Ebrahimi } else
176*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
177*62c56f98SSadaf Ebrahimi if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
178*62c56f98SSadaf Ebrahimi info = &mbedtls_rsa_opaque_info;
179*62c56f98SSadaf Ebrahimi } else {
180*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
181*62c56f98SSadaf Ebrahimi }
182*62c56f98SSadaf Ebrahimi
183*62c56f98SSadaf Ebrahimi ctx->pk_info = info;
184*62c56f98SSadaf Ebrahimi ctx->priv_id = key;
185*62c56f98SSadaf Ebrahimi
186*62c56f98SSadaf Ebrahimi return 0;
187*62c56f98SSadaf Ebrahimi }
188*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_USE_PSA_CRYPTO */
189*62c56f98SSadaf Ebrahimi
190*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
191*62c56f98SSadaf Ebrahimi /*
192*62c56f98SSadaf Ebrahimi * Initialize an RSA-alt context
193*62c56f98SSadaf Ebrahimi */
mbedtls_pk_setup_rsa_alt(mbedtls_pk_context * ctx,void * key,mbedtls_pk_rsa_alt_decrypt_func decrypt_func,mbedtls_pk_rsa_alt_sign_func sign_func,mbedtls_pk_rsa_alt_key_len_func key_len_func)194*62c56f98SSadaf Ebrahimi int mbedtls_pk_setup_rsa_alt(mbedtls_pk_context *ctx, void *key,
195*62c56f98SSadaf Ebrahimi mbedtls_pk_rsa_alt_decrypt_func decrypt_func,
196*62c56f98SSadaf Ebrahimi mbedtls_pk_rsa_alt_sign_func sign_func,
197*62c56f98SSadaf Ebrahimi mbedtls_pk_rsa_alt_key_len_func key_len_func)
198*62c56f98SSadaf Ebrahimi {
199*62c56f98SSadaf Ebrahimi mbedtls_rsa_alt_context *rsa_alt;
200*62c56f98SSadaf Ebrahimi const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info;
201*62c56f98SSadaf Ebrahimi
202*62c56f98SSadaf Ebrahimi if (ctx->pk_info != NULL) {
203*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
204*62c56f98SSadaf Ebrahimi }
205*62c56f98SSadaf Ebrahimi
206*62c56f98SSadaf Ebrahimi if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL) {
207*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_ALLOC_FAILED;
208*62c56f98SSadaf Ebrahimi }
209*62c56f98SSadaf Ebrahimi
210*62c56f98SSadaf Ebrahimi ctx->pk_info = info;
211*62c56f98SSadaf Ebrahimi
212*62c56f98SSadaf Ebrahimi rsa_alt = (mbedtls_rsa_alt_context *) ctx->pk_ctx;
213*62c56f98SSadaf Ebrahimi
214*62c56f98SSadaf Ebrahimi rsa_alt->key = key;
215*62c56f98SSadaf Ebrahimi rsa_alt->decrypt_func = decrypt_func;
216*62c56f98SSadaf Ebrahimi rsa_alt->sign_func = sign_func;
217*62c56f98SSadaf Ebrahimi rsa_alt->key_len_func = key_len_func;
218*62c56f98SSadaf Ebrahimi
219*62c56f98SSadaf Ebrahimi return 0;
220*62c56f98SSadaf Ebrahimi }
221*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
222*62c56f98SSadaf Ebrahimi
223*62c56f98SSadaf Ebrahimi /*
224*62c56f98SSadaf Ebrahimi * Tell if a PK can do the operations of the given type
225*62c56f98SSadaf Ebrahimi */
mbedtls_pk_can_do(const mbedtls_pk_context * ctx,mbedtls_pk_type_t type)226*62c56f98SSadaf Ebrahimi int mbedtls_pk_can_do(const mbedtls_pk_context *ctx, mbedtls_pk_type_t type)
227*62c56f98SSadaf Ebrahimi {
228*62c56f98SSadaf Ebrahimi /* A context with null pk_info is not set up yet and can't do anything.
229*62c56f98SSadaf Ebrahimi * For backward compatibility, also accept NULL instead of a context
230*62c56f98SSadaf Ebrahimi * pointer. */
231*62c56f98SSadaf Ebrahimi if (ctx == NULL || ctx->pk_info == NULL) {
232*62c56f98SSadaf Ebrahimi return 0;
233*62c56f98SSadaf Ebrahimi }
234*62c56f98SSadaf Ebrahimi
235*62c56f98SSadaf Ebrahimi return ctx->pk_info->can_do(type);
236*62c56f98SSadaf Ebrahimi }
237*62c56f98SSadaf Ebrahimi
238*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_USE_PSA_CRYPTO)
239*62c56f98SSadaf Ebrahimi /*
240*62c56f98SSadaf Ebrahimi * Tell if a PK can do the operations of the given PSA algorithm
241*62c56f98SSadaf Ebrahimi */
mbedtls_pk_can_do_ext(const mbedtls_pk_context * ctx,psa_algorithm_t alg,psa_key_usage_t usage)242*62c56f98SSadaf Ebrahimi int mbedtls_pk_can_do_ext(const mbedtls_pk_context *ctx, psa_algorithm_t alg,
243*62c56f98SSadaf Ebrahimi psa_key_usage_t usage)
244*62c56f98SSadaf Ebrahimi {
245*62c56f98SSadaf Ebrahimi psa_key_usage_t key_usage;
246*62c56f98SSadaf Ebrahimi
247*62c56f98SSadaf Ebrahimi /* A context with null pk_info is not set up yet and can't do anything.
248*62c56f98SSadaf Ebrahimi * For backward compatibility, also accept NULL instead of a context
249*62c56f98SSadaf Ebrahimi * pointer. */
250*62c56f98SSadaf Ebrahimi if (ctx == NULL || ctx->pk_info == NULL) {
251*62c56f98SSadaf Ebrahimi return 0;
252*62c56f98SSadaf Ebrahimi }
253*62c56f98SSadaf Ebrahimi
254*62c56f98SSadaf Ebrahimi /* Filter out non allowed algorithms */
255*62c56f98SSadaf Ebrahimi if (PSA_ALG_IS_ECDSA(alg) == 0 &&
256*62c56f98SSadaf Ebrahimi PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) == 0 &&
257*62c56f98SSadaf Ebrahimi PSA_ALG_IS_RSA_PSS(alg) == 0 &&
258*62c56f98SSadaf Ebrahimi alg != PSA_ALG_RSA_PKCS1V15_CRYPT &&
259*62c56f98SSadaf Ebrahimi PSA_ALG_IS_ECDH(alg) == 0) {
260*62c56f98SSadaf Ebrahimi return 0;
261*62c56f98SSadaf Ebrahimi }
262*62c56f98SSadaf Ebrahimi
263*62c56f98SSadaf Ebrahimi /* Filter out non allowed usage flags */
264*62c56f98SSadaf Ebrahimi if (usage == 0 ||
265*62c56f98SSadaf Ebrahimi (usage & ~(PSA_KEY_USAGE_SIGN_HASH |
266*62c56f98SSadaf Ebrahimi PSA_KEY_USAGE_DECRYPT |
267*62c56f98SSadaf Ebrahimi PSA_KEY_USAGE_DERIVE)) != 0) {
268*62c56f98SSadaf Ebrahimi return 0;
269*62c56f98SSadaf Ebrahimi }
270*62c56f98SSadaf Ebrahimi
271*62c56f98SSadaf Ebrahimi /* Wildcard hash is not allowed */
272*62c56f98SSadaf Ebrahimi if (PSA_ALG_IS_SIGN_HASH(alg) &&
273*62c56f98SSadaf Ebrahimi PSA_ALG_SIGN_GET_HASH(alg) == PSA_ALG_ANY_HASH) {
274*62c56f98SSadaf Ebrahimi return 0;
275*62c56f98SSadaf Ebrahimi }
276*62c56f98SSadaf Ebrahimi
277*62c56f98SSadaf Ebrahimi if (mbedtls_pk_get_type(ctx) != MBEDTLS_PK_OPAQUE) {
278*62c56f98SSadaf Ebrahimi mbedtls_pk_type_t type;
279*62c56f98SSadaf Ebrahimi
280*62c56f98SSadaf Ebrahimi if (PSA_ALG_IS_ECDSA(alg) || PSA_ALG_IS_ECDH(alg)) {
281*62c56f98SSadaf Ebrahimi type = MBEDTLS_PK_ECKEY;
282*62c56f98SSadaf Ebrahimi } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) ||
283*62c56f98SSadaf Ebrahimi alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
284*62c56f98SSadaf Ebrahimi type = MBEDTLS_PK_RSA;
285*62c56f98SSadaf Ebrahimi } else if (PSA_ALG_IS_RSA_PSS(alg)) {
286*62c56f98SSadaf Ebrahimi type = MBEDTLS_PK_RSASSA_PSS;
287*62c56f98SSadaf Ebrahimi } else {
288*62c56f98SSadaf Ebrahimi return 0;
289*62c56f98SSadaf Ebrahimi }
290*62c56f98SSadaf Ebrahimi
291*62c56f98SSadaf Ebrahimi if (ctx->pk_info->can_do(type) == 0) {
292*62c56f98SSadaf Ebrahimi return 0;
293*62c56f98SSadaf Ebrahimi }
294*62c56f98SSadaf Ebrahimi
295*62c56f98SSadaf Ebrahimi switch (type) {
296*62c56f98SSadaf Ebrahimi case MBEDTLS_PK_ECKEY:
297*62c56f98SSadaf Ebrahimi key_usage = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_DERIVE;
298*62c56f98SSadaf Ebrahimi break;
299*62c56f98SSadaf Ebrahimi case MBEDTLS_PK_RSA:
300*62c56f98SSadaf Ebrahimi case MBEDTLS_PK_RSASSA_PSS:
301*62c56f98SSadaf Ebrahimi key_usage = PSA_KEY_USAGE_SIGN_HASH |
302*62c56f98SSadaf Ebrahimi PSA_KEY_USAGE_SIGN_MESSAGE |
303*62c56f98SSadaf Ebrahimi PSA_KEY_USAGE_DECRYPT;
304*62c56f98SSadaf Ebrahimi break;
305*62c56f98SSadaf Ebrahimi default:
306*62c56f98SSadaf Ebrahimi /* Should never happen */
307*62c56f98SSadaf Ebrahimi return 0;
308*62c56f98SSadaf Ebrahimi }
309*62c56f98SSadaf Ebrahimi
310*62c56f98SSadaf Ebrahimi return (key_usage & usage) == usage;
311*62c56f98SSadaf Ebrahimi }
312*62c56f98SSadaf Ebrahimi
313*62c56f98SSadaf Ebrahimi psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
314*62c56f98SSadaf Ebrahimi psa_algorithm_t key_alg, key_alg2;
315*62c56f98SSadaf Ebrahimi psa_status_t status;
316*62c56f98SSadaf Ebrahimi
317*62c56f98SSadaf Ebrahimi status = psa_get_key_attributes(ctx->priv_id, &attributes);
318*62c56f98SSadaf Ebrahimi if (status != PSA_SUCCESS) {
319*62c56f98SSadaf Ebrahimi return 0;
320*62c56f98SSadaf Ebrahimi }
321*62c56f98SSadaf Ebrahimi
322*62c56f98SSadaf Ebrahimi key_alg = psa_get_key_algorithm(&attributes);
323*62c56f98SSadaf Ebrahimi key_alg2 = psa_get_key_enrollment_algorithm(&attributes);
324*62c56f98SSadaf Ebrahimi key_usage = psa_get_key_usage_flags(&attributes);
325*62c56f98SSadaf Ebrahimi psa_reset_key_attributes(&attributes);
326*62c56f98SSadaf Ebrahimi
327*62c56f98SSadaf Ebrahimi if ((key_usage & usage) != usage) {
328*62c56f98SSadaf Ebrahimi return 0;
329*62c56f98SSadaf Ebrahimi }
330*62c56f98SSadaf Ebrahimi
331*62c56f98SSadaf Ebrahimi /*
332*62c56f98SSadaf Ebrahimi * Common case: the key alg or alg2 only allows alg.
333*62c56f98SSadaf Ebrahimi * This will match PSA_ALG_RSA_PKCS1V15_CRYPT & PSA_ALG_IS_ECDH
334*62c56f98SSadaf Ebrahimi * directly.
335*62c56f98SSadaf Ebrahimi * This would also match ECDSA/RSA_PKCS1V15_SIGN/RSA_PSS with
336*62c56f98SSadaf Ebrahimi * a fixed hash on key_alg/key_alg2.
337*62c56f98SSadaf Ebrahimi */
338*62c56f98SSadaf Ebrahimi if (alg == key_alg || alg == key_alg2) {
339*62c56f98SSadaf Ebrahimi return 1;
340*62c56f98SSadaf Ebrahimi }
341*62c56f98SSadaf Ebrahimi
342*62c56f98SSadaf Ebrahimi /*
343*62c56f98SSadaf Ebrahimi * If key_alg or key_alg2 is a hash-and-sign with a wildcard for the hash,
344*62c56f98SSadaf Ebrahimi * and alg is the same hash-and-sign family with any hash,
345*62c56f98SSadaf Ebrahimi * then alg is compliant with this key alg
346*62c56f98SSadaf Ebrahimi */
347*62c56f98SSadaf Ebrahimi if (PSA_ALG_IS_SIGN_HASH(alg)) {
348*62c56f98SSadaf Ebrahimi
349*62c56f98SSadaf Ebrahimi if (PSA_ALG_IS_SIGN_HASH(key_alg) &&
350*62c56f98SSadaf Ebrahimi PSA_ALG_SIGN_GET_HASH(key_alg) == PSA_ALG_ANY_HASH &&
351*62c56f98SSadaf Ebrahimi (alg & ~PSA_ALG_HASH_MASK) == (key_alg & ~PSA_ALG_HASH_MASK)) {
352*62c56f98SSadaf Ebrahimi return 1;
353*62c56f98SSadaf Ebrahimi }
354*62c56f98SSadaf Ebrahimi
355*62c56f98SSadaf Ebrahimi if (PSA_ALG_IS_SIGN_HASH(key_alg2) &&
356*62c56f98SSadaf Ebrahimi PSA_ALG_SIGN_GET_HASH(key_alg2) == PSA_ALG_ANY_HASH &&
357*62c56f98SSadaf Ebrahimi (alg & ~PSA_ALG_HASH_MASK) == (key_alg2 & ~PSA_ALG_HASH_MASK)) {
358*62c56f98SSadaf Ebrahimi return 1;
359*62c56f98SSadaf Ebrahimi }
360*62c56f98SSadaf Ebrahimi }
361*62c56f98SSadaf Ebrahimi
362*62c56f98SSadaf Ebrahimi return 0;
363*62c56f98SSadaf Ebrahimi }
364*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_USE_PSA_CRYPTO */
365*62c56f98SSadaf Ebrahimi
366*62c56f98SSadaf Ebrahimi /*
367*62c56f98SSadaf Ebrahimi * Helper for mbedtls_pk_sign and mbedtls_pk_verify
368*62c56f98SSadaf Ebrahimi */
pk_hashlen_helper(mbedtls_md_type_t md_alg,size_t * hash_len)369*62c56f98SSadaf Ebrahimi static inline int pk_hashlen_helper(mbedtls_md_type_t md_alg, size_t *hash_len)
370*62c56f98SSadaf Ebrahimi {
371*62c56f98SSadaf Ebrahimi if (*hash_len != 0) {
372*62c56f98SSadaf Ebrahimi return 0;
373*62c56f98SSadaf Ebrahimi }
374*62c56f98SSadaf Ebrahimi
375*62c56f98SSadaf Ebrahimi *hash_len = mbedtls_md_get_size_from_type(md_alg);
376*62c56f98SSadaf Ebrahimi
377*62c56f98SSadaf Ebrahimi if (*hash_len == 0) {
378*62c56f98SSadaf Ebrahimi return -1;
379*62c56f98SSadaf Ebrahimi }
380*62c56f98SSadaf Ebrahimi
381*62c56f98SSadaf Ebrahimi return 0;
382*62c56f98SSadaf Ebrahimi }
383*62c56f98SSadaf Ebrahimi
384*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
385*62c56f98SSadaf Ebrahimi /*
386*62c56f98SSadaf Ebrahimi * Helper to set up a restart context if needed
387*62c56f98SSadaf Ebrahimi */
pk_restart_setup(mbedtls_pk_restart_ctx * ctx,const mbedtls_pk_info_t * info)388*62c56f98SSadaf Ebrahimi static int pk_restart_setup(mbedtls_pk_restart_ctx *ctx,
389*62c56f98SSadaf Ebrahimi const mbedtls_pk_info_t *info)
390*62c56f98SSadaf Ebrahimi {
391*62c56f98SSadaf Ebrahimi /* Don't do anything if already set up or invalid */
392*62c56f98SSadaf Ebrahimi if (ctx == NULL || ctx->pk_info != NULL) {
393*62c56f98SSadaf Ebrahimi return 0;
394*62c56f98SSadaf Ebrahimi }
395*62c56f98SSadaf Ebrahimi
396*62c56f98SSadaf Ebrahimi /* Should never happen when we're called */
397*62c56f98SSadaf Ebrahimi if (info->rs_alloc_func == NULL || info->rs_free_func == NULL) {
398*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
399*62c56f98SSadaf Ebrahimi }
400*62c56f98SSadaf Ebrahimi
401*62c56f98SSadaf Ebrahimi if ((ctx->rs_ctx = info->rs_alloc_func()) == NULL) {
402*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_ALLOC_FAILED;
403*62c56f98SSadaf Ebrahimi }
404*62c56f98SSadaf Ebrahimi
405*62c56f98SSadaf Ebrahimi ctx->pk_info = info;
406*62c56f98SSadaf Ebrahimi
407*62c56f98SSadaf Ebrahimi return 0;
408*62c56f98SSadaf Ebrahimi }
409*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
410*62c56f98SSadaf Ebrahimi
411*62c56f98SSadaf Ebrahimi /*
412*62c56f98SSadaf Ebrahimi * Verify a signature (restartable)
413*62c56f98SSadaf Ebrahimi */
mbedtls_pk_verify_restartable(mbedtls_pk_context * ctx,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hash_len,const unsigned char * sig,size_t sig_len,mbedtls_pk_restart_ctx * rs_ctx)414*62c56f98SSadaf Ebrahimi int mbedtls_pk_verify_restartable(mbedtls_pk_context *ctx,
415*62c56f98SSadaf Ebrahimi mbedtls_md_type_t md_alg,
416*62c56f98SSadaf Ebrahimi const unsigned char *hash, size_t hash_len,
417*62c56f98SSadaf Ebrahimi const unsigned char *sig, size_t sig_len,
418*62c56f98SSadaf Ebrahimi mbedtls_pk_restart_ctx *rs_ctx)
419*62c56f98SSadaf Ebrahimi {
420*62c56f98SSadaf Ebrahimi if ((md_alg != MBEDTLS_MD_NONE || hash_len != 0) && hash == NULL) {
421*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
422*62c56f98SSadaf Ebrahimi }
423*62c56f98SSadaf Ebrahimi
424*62c56f98SSadaf Ebrahimi if (ctx->pk_info == NULL ||
425*62c56f98SSadaf Ebrahimi pk_hashlen_helper(md_alg, &hash_len) != 0) {
426*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
427*62c56f98SSadaf Ebrahimi }
428*62c56f98SSadaf Ebrahimi
429*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
430*62c56f98SSadaf Ebrahimi /* optimization: use non-restartable version if restart disabled */
431*62c56f98SSadaf Ebrahimi if (rs_ctx != NULL &&
432*62c56f98SSadaf Ebrahimi mbedtls_ecp_restart_is_enabled() &&
433*62c56f98SSadaf Ebrahimi ctx->pk_info->verify_rs_func != NULL) {
434*62c56f98SSadaf Ebrahimi int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
435*62c56f98SSadaf Ebrahimi
436*62c56f98SSadaf Ebrahimi if ((ret = pk_restart_setup(rs_ctx, ctx->pk_info)) != 0) {
437*62c56f98SSadaf Ebrahimi return ret;
438*62c56f98SSadaf Ebrahimi }
439*62c56f98SSadaf Ebrahimi
440*62c56f98SSadaf Ebrahimi ret = ctx->pk_info->verify_rs_func(ctx,
441*62c56f98SSadaf Ebrahimi md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx);
442*62c56f98SSadaf Ebrahimi
443*62c56f98SSadaf Ebrahimi if (ret != MBEDTLS_ERR_ECP_IN_PROGRESS) {
444*62c56f98SSadaf Ebrahimi mbedtls_pk_restart_free(rs_ctx);
445*62c56f98SSadaf Ebrahimi }
446*62c56f98SSadaf Ebrahimi
447*62c56f98SSadaf Ebrahimi return ret;
448*62c56f98SSadaf Ebrahimi }
449*62c56f98SSadaf Ebrahimi #else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
450*62c56f98SSadaf Ebrahimi (void) rs_ctx;
451*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
452*62c56f98SSadaf Ebrahimi
453*62c56f98SSadaf Ebrahimi if (ctx->pk_info->verify_func == NULL) {
454*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_TYPE_MISMATCH;
455*62c56f98SSadaf Ebrahimi }
456*62c56f98SSadaf Ebrahimi
457*62c56f98SSadaf Ebrahimi return ctx->pk_info->verify_func(ctx, md_alg, hash, hash_len,
458*62c56f98SSadaf Ebrahimi sig, sig_len);
459*62c56f98SSadaf Ebrahimi }
460*62c56f98SSadaf Ebrahimi
461*62c56f98SSadaf Ebrahimi /*
462*62c56f98SSadaf Ebrahimi * Verify a signature
463*62c56f98SSadaf Ebrahimi */
mbedtls_pk_verify(mbedtls_pk_context * ctx,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hash_len,const unsigned char * sig,size_t sig_len)464*62c56f98SSadaf Ebrahimi int mbedtls_pk_verify(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
465*62c56f98SSadaf Ebrahimi const unsigned char *hash, size_t hash_len,
466*62c56f98SSadaf Ebrahimi const unsigned char *sig, size_t sig_len)
467*62c56f98SSadaf Ebrahimi {
468*62c56f98SSadaf Ebrahimi return mbedtls_pk_verify_restartable(ctx, md_alg, hash, hash_len,
469*62c56f98SSadaf Ebrahimi sig, sig_len, NULL);
470*62c56f98SSadaf Ebrahimi }
471*62c56f98SSadaf Ebrahimi
472*62c56f98SSadaf Ebrahimi /*
473*62c56f98SSadaf Ebrahimi * Verify a signature with options
474*62c56f98SSadaf Ebrahimi */
mbedtls_pk_verify_ext(mbedtls_pk_type_t type,const void * options,mbedtls_pk_context * ctx,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hash_len,const unsigned char * sig,size_t sig_len)475*62c56f98SSadaf Ebrahimi int mbedtls_pk_verify_ext(mbedtls_pk_type_t type, const void *options,
476*62c56f98SSadaf Ebrahimi mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
477*62c56f98SSadaf Ebrahimi const unsigned char *hash, size_t hash_len,
478*62c56f98SSadaf Ebrahimi const unsigned char *sig, size_t sig_len)
479*62c56f98SSadaf Ebrahimi {
480*62c56f98SSadaf Ebrahimi if ((md_alg != MBEDTLS_MD_NONE || hash_len != 0) && hash == NULL) {
481*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
482*62c56f98SSadaf Ebrahimi }
483*62c56f98SSadaf Ebrahimi
484*62c56f98SSadaf Ebrahimi if (ctx->pk_info == NULL) {
485*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
486*62c56f98SSadaf Ebrahimi }
487*62c56f98SSadaf Ebrahimi
488*62c56f98SSadaf Ebrahimi if (!mbedtls_pk_can_do(ctx, type)) {
489*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_TYPE_MISMATCH;
490*62c56f98SSadaf Ebrahimi }
491*62c56f98SSadaf Ebrahimi
492*62c56f98SSadaf Ebrahimi if (type != MBEDTLS_PK_RSASSA_PSS) {
493*62c56f98SSadaf Ebrahimi /* General case: no options */
494*62c56f98SSadaf Ebrahimi if (options != NULL) {
495*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
496*62c56f98SSadaf Ebrahimi }
497*62c56f98SSadaf Ebrahimi
498*62c56f98SSadaf Ebrahimi return mbedtls_pk_verify(ctx, md_alg, hash, hash_len, sig, sig_len);
499*62c56f98SSadaf Ebrahimi }
500*62c56f98SSadaf Ebrahimi
501*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
502*62c56f98SSadaf Ebrahimi int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
503*62c56f98SSadaf Ebrahimi const mbedtls_pk_rsassa_pss_options *pss_opts;
504*62c56f98SSadaf Ebrahimi
505*62c56f98SSadaf Ebrahimi #if SIZE_MAX > UINT_MAX
506*62c56f98SSadaf Ebrahimi if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) {
507*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
508*62c56f98SSadaf Ebrahimi }
509*62c56f98SSadaf Ebrahimi #endif
510*62c56f98SSadaf Ebrahimi
511*62c56f98SSadaf Ebrahimi if (options == NULL) {
512*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
513*62c56f98SSadaf Ebrahimi }
514*62c56f98SSadaf Ebrahimi
515*62c56f98SSadaf Ebrahimi pss_opts = (const mbedtls_pk_rsassa_pss_options *) options;
516*62c56f98SSadaf Ebrahimi
517*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_USE_PSA_CRYPTO)
518*62c56f98SSadaf Ebrahimi if (pss_opts->mgf1_hash_id == md_alg) {
519*62c56f98SSadaf Ebrahimi unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES];
520*62c56f98SSadaf Ebrahimi unsigned char *p;
521*62c56f98SSadaf Ebrahimi int key_len;
522*62c56f98SSadaf Ebrahimi size_t signature_length;
523*62c56f98SSadaf Ebrahimi psa_status_t status = PSA_ERROR_DATA_CORRUPT;
524*62c56f98SSadaf Ebrahimi psa_status_t destruction_status = PSA_ERROR_DATA_CORRUPT;
525*62c56f98SSadaf Ebrahimi
526*62c56f98SSadaf Ebrahimi psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
527*62c56f98SSadaf Ebrahimi mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
528*62c56f98SSadaf Ebrahimi psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
529*62c56f98SSadaf Ebrahimi psa_algorithm_t psa_sig_alg = PSA_ALG_RSA_PSS_ANY_SALT(psa_md_alg);
530*62c56f98SSadaf Ebrahimi p = buf + sizeof(buf);
531*62c56f98SSadaf Ebrahimi key_len = mbedtls_pk_write_pubkey(&p, buf, ctx);
532*62c56f98SSadaf Ebrahimi
533*62c56f98SSadaf Ebrahimi if (key_len < 0) {
534*62c56f98SSadaf Ebrahimi return key_len;
535*62c56f98SSadaf Ebrahimi }
536*62c56f98SSadaf Ebrahimi
537*62c56f98SSadaf Ebrahimi psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY);
538*62c56f98SSadaf Ebrahimi psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH);
539*62c56f98SSadaf Ebrahimi psa_set_key_algorithm(&attributes, psa_sig_alg);
540*62c56f98SSadaf Ebrahimi
541*62c56f98SSadaf Ebrahimi status = psa_import_key(&attributes,
542*62c56f98SSadaf Ebrahimi buf + sizeof(buf) - key_len, key_len,
543*62c56f98SSadaf Ebrahimi &key_id);
544*62c56f98SSadaf Ebrahimi if (status != PSA_SUCCESS) {
545*62c56f98SSadaf Ebrahimi psa_destroy_key(key_id);
546*62c56f98SSadaf Ebrahimi return PSA_PK_TO_MBEDTLS_ERR(status);
547*62c56f98SSadaf Ebrahimi }
548*62c56f98SSadaf Ebrahimi
549*62c56f98SSadaf Ebrahimi /* This function requires returning MBEDTLS_ERR_PK_SIG_LEN_MISMATCH
550*62c56f98SSadaf Ebrahimi * on a valid signature with trailing data in a buffer, but
551*62c56f98SSadaf Ebrahimi * mbedtls_psa_rsa_verify_hash requires the sig_len to be exact,
552*62c56f98SSadaf Ebrahimi * so for this reason the passed sig_len is overwritten. Smaller
553*62c56f98SSadaf Ebrahimi * signature lengths should not be accepted for verification. */
554*62c56f98SSadaf Ebrahimi signature_length = sig_len > mbedtls_pk_get_len(ctx) ?
555*62c56f98SSadaf Ebrahimi mbedtls_pk_get_len(ctx) : sig_len;
556*62c56f98SSadaf Ebrahimi status = psa_verify_hash(key_id, psa_sig_alg, hash,
557*62c56f98SSadaf Ebrahimi hash_len, sig, signature_length);
558*62c56f98SSadaf Ebrahimi destruction_status = psa_destroy_key(key_id);
559*62c56f98SSadaf Ebrahimi
560*62c56f98SSadaf Ebrahimi if (status == PSA_SUCCESS && sig_len > mbedtls_pk_get_len(ctx)) {
561*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
562*62c56f98SSadaf Ebrahimi }
563*62c56f98SSadaf Ebrahimi
564*62c56f98SSadaf Ebrahimi if (status == PSA_SUCCESS) {
565*62c56f98SSadaf Ebrahimi status = destruction_status;
566*62c56f98SSadaf Ebrahimi }
567*62c56f98SSadaf Ebrahimi
568*62c56f98SSadaf Ebrahimi return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
569*62c56f98SSadaf Ebrahimi } else
570*62c56f98SSadaf Ebrahimi #endif
571*62c56f98SSadaf Ebrahimi {
572*62c56f98SSadaf Ebrahimi if (sig_len < mbedtls_pk_get_len(ctx)) {
573*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_RSA_VERIFY_FAILED;
574*62c56f98SSadaf Ebrahimi }
575*62c56f98SSadaf Ebrahimi
576*62c56f98SSadaf Ebrahimi ret = mbedtls_rsa_rsassa_pss_verify_ext(mbedtls_pk_rsa(*ctx),
577*62c56f98SSadaf Ebrahimi md_alg, (unsigned int) hash_len, hash,
578*62c56f98SSadaf Ebrahimi pss_opts->mgf1_hash_id,
579*62c56f98SSadaf Ebrahimi pss_opts->expected_salt_len,
580*62c56f98SSadaf Ebrahimi sig);
581*62c56f98SSadaf Ebrahimi if (ret != 0) {
582*62c56f98SSadaf Ebrahimi return ret;
583*62c56f98SSadaf Ebrahimi }
584*62c56f98SSadaf Ebrahimi
585*62c56f98SSadaf Ebrahimi if (sig_len > mbedtls_pk_get_len(ctx)) {
586*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
587*62c56f98SSadaf Ebrahimi }
588*62c56f98SSadaf Ebrahimi
589*62c56f98SSadaf Ebrahimi return 0;
590*62c56f98SSadaf Ebrahimi }
591*62c56f98SSadaf Ebrahimi #else
592*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
593*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */
594*62c56f98SSadaf Ebrahimi }
595*62c56f98SSadaf Ebrahimi
596*62c56f98SSadaf Ebrahimi /*
597*62c56f98SSadaf Ebrahimi * Make a signature (restartable)
598*62c56f98SSadaf Ebrahimi */
mbedtls_pk_sign_restartable(mbedtls_pk_context * ctx,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,mbedtls_pk_restart_ctx * rs_ctx)599*62c56f98SSadaf Ebrahimi int mbedtls_pk_sign_restartable(mbedtls_pk_context *ctx,
600*62c56f98SSadaf Ebrahimi mbedtls_md_type_t md_alg,
601*62c56f98SSadaf Ebrahimi const unsigned char *hash, size_t hash_len,
602*62c56f98SSadaf Ebrahimi unsigned char *sig, size_t sig_size, size_t *sig_len,
603*62c56f98SSadaf Ebrahimi int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
604*62c56f98SSadaf Ebrahimi mbedtls_pk_restart_ctx *rs_ctx)
605*62c56f98SSadaf Ebrahimi {
606*62c56f98SSadaf Ebrahimi if ((md_alg != MBEDTLS_MD_NONE || hash_len != 0) && hash == NULL) {
607*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
608*62c56f98SSadaf Ebrahimi }
609*62c56f98SSadaf Ebrahimi
610*62c56f98SSadaf Ebrahimi if (ctx->pk_info == NULL || pk_hashlen_helper(md_alg, &hash_len) != 0) {
611*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
612*62c56f98SSadaf Ebrahimi }
613*62c56f98SSadaf Ebrahimi
614*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
615*62c56f98SSadaf Ebrahimi /* optimization: use non-restartable version if restart disabled */
616*62c56f98SSadaf Ebrahimi if (rs_ctx != NULL &&
617*62c56f98SSadaf Ebrahimi mbedtls_ecp_restart_is_enabled() &&
618*62c56f98SSadaf Ebrahimi ctx->pk_info->sign_rs_func != NULL) {
619*62c56f98SSadaf Ebrahimi int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
620*62c56f98SSadaf Ebrahimi
621*62c56f98SSadaf Ebrahimi if ((ret = pk_restart_setup(rs_ctx, ctx->pk_info)) != 0) {
622*62c56f98SSadaf Ebrahimi return ret;
623*62c56f98SSadaf Ebrahimi }
624*62c56f98SSadaf Ebrahimi
625*62c56f98SSadaf Ebrahimi ret = ctx->pk_info->sign_rs_func(ctx, md_alg,
626*62c56f98SSadaf Ebrahimi hash, hash_len,
627*62c56f98SSadaf Ebrahimi sig, sig_size, sig_len,
628*62c56f98SSadaf Ebrahimi f_rng, p_rng, rs_ctx->rs_ctx);
629*62c56f98SSadaf Ebrahimi
630*62c56f98SSadaf Ebrahimi if (ret != MBEDTLS_ERR_ECP_IN_PROGRESS) {
631*62c56f98SSadaf Ebrahimi mbedtls_pk_restart_free(rs_ctx);
632*62c56f98SSadaf Ebrahimi }
633*62c56f98SSadaf Ebrahimi
634*62c56f98SSadaf Ebrahimi return ret;
635*62c56f98SSadaf Ebrahimi }
636*62c56f98SSadaf Ebrahimi #else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
637*62c56f98SSadaf Ebrahimi (void) rs_ctx;
638*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
639*62c56f98SSadaf Ebrahimi
640*62c56f98SSadaf Ebrahimi if (ctx->pk_info->sign_func == NULL) {
641*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_TYPE_MISMATCH;
642*62c56f98SSadaf Ebrahimi }
643*62c56f98SSadaf Ebrahimi
644*62c56f98SSadaf Ebrahimi return ctx->pk_info->sign_func(ctx, md_alg,
645*62c56f98SSadaf Ebrahimi hash, hash_len,
646*62c56f98SSadaf Ebrahimi sig, sig_size, sig_len,
647*62c56f98SSadaf Ebrahimi f_rng, p_rng);
648*62c56f98SSadaf Ebrahimi }
649*62c56f98SSadaf Ebrahimi
650*62c56f98SSadaf Ebrahimi /*
651*62c56f98SSadaf Ebrahimi * Make a signature
652*62c56f98SSadaf Ebrahimi */
mbedtls_pk_sign(mbedtls_pk_context * ctx,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)653*62c56f98SSadaf Ebrahimi int mbedtls_pk_sign(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
654*62c56f98SSadaf Ebrahimi const unsigned char *hash, size_t hash_len,
655*62c56f98SSadaf Ebrahimi unsigned char *sig, size_t sig_size, size_t *sig_len,
656*62c56f98SSadaf Ebrahimi int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
657*62c56f98SSadaf Ebrahimi {
658*62c56f98SSadaf Ebrahimi return mbedtls_pk_sign_restartable(ctx, md_alg, hash, hash_len,
659*62c56f98SSadaf Ebrahimi sig, sig_size, sig_len,
660*62c56f98SSadaf Ebrahimi f_rng, p_rng, NULL);
661*62c56f98SSadaf Ebrahimi }
662*62c56f98SSadaf Ebrahimi
663*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_CRYPTO_C)
664*62c56f98SSadaf Ebrahimi /*
665*62c56f98SSadaf Ebrahimi * Make a signature given a signature type.
666*62c56f98SSadaf Ebrahimi */
mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type,mbedtls_pk_context * ctx,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)667*62c56f98SSadaf Ebrahimi int mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type,
668*62c56f98SSadaf Ebrahimi mbedtls_pk_context *ctx,
669*62c56f98SSadaf Ebrahimi mbedtls_md_type_t md_alg,
670*62c56f98SSadaf Ebrahimi const unsigned char *hash, size_t hash_len,
671*62c56f98SSadaf Ebrahimi unsigned char *sig, size_t sig_size, size_t *sig_len,
672*62c56f98SSadaf Ebrahimi int (*f_rng)(void *, unsigned char *, size_t),
673*62c56f98SSadaf Ebrahimi void *p_rng)
674*62c56f98SSadaf Ebrahimi {
675*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_RSA_C)
676*62c56f98SSadaf Ebrahimi psa_algorithm_t psa_md_alg;
677*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_RSA_C */
678*62c56f98SSadaf Ebrahimi *sig_len = 0;
679*62c56f98SSadaf Ebrahimi
680*62c56f98SSadaf Ebrahimi if (ctx->pk_info == NULL) {
681*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
682*62c56f98SSadaf Ebrahimi }
683*62c56f98SSadaf Ebrahimi
684*62c56f98SSadaf Ebrahimi if (!mbedtls_pk_can_do(ctx, pk_type)) {
685*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_TYPE_MISMATCH;
686*62c56f98SSadaf Ebrahimi }
687*62c56f98SSadaf Ebrahimi
688*62c56f98SSadaf Ebrahimi if (pk_type != MBEDTLS_PK_RSASSA_PSS) {
689*62c56f98SSadaf Ebrahimi return mbedtls_pk_sign(ctx, md_alg, hash, hash_len,
690*62c56f98SSadaf Ebrahimi sig, sig_size, sig_len, f_rng, p_rng);
691*62c56f98SSadaf Ebrahimi }
692*62c56f98SSadaf Ebrahimi
693*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_RSA_C)
694*62c56f98SSadaf Ebrahimi psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
695*62c56f98SSadaf Ebrahimi if (psa_md_alg == 0) {
696*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
697*62c56f98SSadaf Ebrahimi }
698*62c56f98SSadaf Ebrahimi
699*62c56f98SSadaf Ebrahimi if (mbedtls_pk_get_type(ctx) == MBEDTLS_PK_OPAQUE) {
700*62c56f98SSadaf Ebrahimi psa_status_t status;
701*62c56f98SSadaf Ebrahimi
702*62c56f98SSadaf Ebrahimi status = psa_sign_hash(ctx->priv_id, PSA_ALG_RSA_PSS(psa_md_alg),
703*62c56f98SSadaf Ebrahimi hash, hash_len,
704*62c56f98SSadaf Ebrahimi sig, sig_size, sig_len);
705*62c56f98SSadaf Ebrahimi return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
706*62c56f98SSadaf Ebrahimi }
707*62c56f98SSadaf Ebrahimi
708*62c56f98SSadaf Ebrahimi return mbedtls_pk_psa_rsa_sign_ext(PSA_ALG_RSA_PSS(psa_md_alg),
709*62c56f98SSadaf Ebrahimi ctx->pk_ctx, hash, hash_len,
710*62c56f98SSadaf Ebrahimi sig, sig_size, sig_len);
711*62c56f98SSadaf Ebrahimi #else /* MBEDTLS_RSA_C */
712*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
713*62c56f98SSadaf Ebrahimi #endif /* !MBEDTLS_RSA_C */
714*62c56f98SSadaf Ebrahimi
715*62c56f98SSadaf Ebrahimi }
716*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PSA_CRYPTO_C */
717*62c56f98SSadaf Ebrahimi
718*62c56f98SSadaf Ebrahimi /*
719*62c56f98SSadaf Ebrahimi * Decrypt message
720*62c56f98SSadaf Ebrahimi */
mbedtls_pk_decrypt(mbedtls_pk_context * ctx,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)721*62c56f98SSadaf Ebrahimi int mbedtls_pk_decrypt(mbedtls_pk_context *ctx,
722*62c56f98SSadaf Ebrahimi const unsigned char *input, size_t ilen,
723*62c56f98SSadaf Ebrahimi unsigned char *output, size_t *olen, size_t osize,
724*62c56f98SSadaf Ebrahimi int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
725*62c56f98SSadaf Ebrahimi {
726*62c56f98SSadaf Ebrahimi if (ctx->pk_info == NULL) {
727*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
728*62c56f98SSadaf Ebrahimi }
729*62c56f98SSadaf Ebrahimi
730*62c56f98SSadaf Ebrahimi if (ctx->pk_info->decrypt_func == NULL) {
731*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_TYPE_MISMATCH;
732*62c56f98SSadaf Ebrahimi }
733*62c56f98SSadaf Ebrahimi
734*62c56f98SSadaf Ebrahimi return ctx->pk_info->decrypt_func(ctx, input, ilen,
735*62c56f98SSadaf Ebrahimi output, olen, osize, f_rng, p_rng);
736*62c56f98SSadaf Ebrahimi }
737*62c56f98SSadaf Ebrahimi
738*62c56f98SSadaf Ebrahimi /*
739*62c56f98SSadaf Ebrahimi * Encrypt message
740*62c56f98SSadaf Ebrahimi */
mbedtls_pk_encrypt(mbedtls_pk_context * ctx,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)741*62c56f98SSadaf Ebrahimi int mbedtls_pk_encrypt(mbedtls_pk_context *ctx,
742*62c56f98SSadaf Ebrahimi const unsigned char *input, size_t ilen,
743*62c56f98SSadaf Ebrahimi unsigned char *output, size_t *olen, size_t osize,
744*62c56f98SSadaf Ebrahimi int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
745*62c56f98SSadaf Ebrahimi {
746*62c56f98SSadaf Ebrahimi if (ctx->pk_info == NULL) {
747*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
748*62c56f98SSadaf Ebrahimi }
749*62c56f98SSadaf Ebrahimi
750*62c56f98SSadaf Ebrahimi if (ctx->pk_info->encrypt_func == NULL) {
751*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_TYPE_MISMATCH;
752*62c56f98SSadaf Ebrahimi }
753*62c56f98SSadaf Ebrahimi
754*62c56f98SSadaf Ebrahimi return ctx->pk_info->encrypt_func(ctx, input, ilen,
755*62c56f98SSadaf Ebrahimi output, olen, osize, f_rng, p_rng);
756*62c56f98SSadaf Ebrahimi }
757*62c56f98SSadaf Ebrahimi
758*62c56f98SSadaf Ebrahimi /*
759*62c56f98SSadaf Ebrahimi * Check public-private key pair
760*62c56f98SSadaf Ebrahimi */
mbedtls_pk_check_pair(const mbedtls_pk_context * pub,const mbedtls_pk_context * prv,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)761*62c56f98SSadaf Ebrahimi int mbedtls_pk_check_pair(const mbedtls_pk_context *pub,
762*62c56f98SSadaf Ebrahimi const mbedtls_pk_context *prv,
763*62c56f98SSadaf Ebrahimi int (*f_rng)(void *, unsigned char *, size_t),
764*62c56f98SSadaf Ebrahimi void *p_rng)
765*62c56f98SSadaf Ebrahimi {
766*62c56f98SSadaf Ebrahimi if (pub->pk_info == NULL ||
767*62c56f98SSadaf Ebrahimi prv->pk_info == NULL) {
768*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
769*62c56f98SSadaf Ebrahimi }
770*62c56f98SSadaf Ebrahimi
771*62c56f98SSadaf Ebrahimi if (f_rng == NULL) {
772*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
773*62c56f98SSadaf Ebrahimi }
774*62c56f98SSadaf Ebrahimi
775*62c56f98SSadaf Ebrahimi if (prv->pk_info->check_pair_func == NULL) {
776*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
777*62c56f98SSadaf Ebrahimi }
778*62c56f98SSadaf Ebrahimi
779*62c56f98SSadaf Ebrahimi if (prv->pk_info->type == MBEDTLS_PK_RSA_ALT) {
780*62c56f98SSadaf Ebrahimi if (pub->pk_info->type != MBEDTLS_PK_RSA) {
781*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_TYPE_MISMATCH;
782*62c56f98SSadaf Ebrahimi }
783*62c56f98SSadaf Ebrahimi } else {
784*62c56f98SSadaf Ebrahimi if ((prv->pk_info->type != MBEDTLS_PK_OPAQUE) &&
785*62c56f98SSadaf Ebrahimi (pub->pk_info != prv->pk_info)) {
786*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_TYPE_MISMATCH;
787*62c56f98SSadaf Ebrahimi }
788*62c56f98SSadaf Ebrahimi }
789*62c56f98SSadaf Ebrahimi
790*62c56f98SSadaf Ebrahimi return prv->pk_info->check_pair_func((mbedtls_pk_context *) pub,
791*62c56f98SSadaf Ebrahimi (mbedtls_pk_context *) prv,
792*62c56f98SSadaf Ebrahimi f_rng, p_rng);
793*62c56f98SSadaf Ebrahimi }
794*62c56f98SSadaf Ebrahimi
795*62c56f98SSadaf Ebrahimi /*
796*62c56f98SSadaf Ebrahimi * Get key size in bits
797*62c56f98SSadaf Ebrahimi */
mbedtls_pk_get_bitlen(const mbedtls_pk_context * ctx)798*62c56f98SSadaf Ebrahimi size_t mbedtls_pk_get_bitlen(const mbedtls_pk_context *ctx)
799*62c56f98SSadaf Ebrahimi {
800*62c56f98SSadaf Ebrahimi /* For backward compatibility, accept NULL or a context that
801*62c56f98SSadaf Ebrahimi * isn't set up yet, and return a fake value that should be safe. */
802*62c56f98SSadaf Ebrahimi if (ctx == NULL || ctx->pk_info == NULL) {
803*62c56f98SSadaf Ebrahimi return 0;
804*62c56f98SSadaf Ebrahimi }
805*62c56f98SSadaf Ebrahimi
806*62c56f98SSadaf Ebrahimi return ctx->pk_info->get_bitlen((mbedtls_pk_context *) ctx);
807*62c56f98SSadaf Ebrahimi }
808*62c56f98SSadaf Ebrahimi
809*62c56f98SSadaf Ebrahimi /*
810*62c56f98SSadaf Ebrahimi * Export debug information
811*62c56f98SSadaf Ebrahimi */
mbedtls_pk_debug(const mbedtls_pk_context * ctx,mbedtls_pk_debug_item * items)812*62c56f98SSadaf Ebrahimi int mbedtls_pk_debug(const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items)
813*62c56f98SSadaf Ebrahimi {
814*62c56f98SSadaf Ebrahimi if (ctx->pk_info == NULL) {
815*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
816*62c56f98SSadaf Ebrahimi }
817*62c56f98SSadaf Ebrahimi
818*62c56f98SSadaf Ebrahimi if (ctx->pk_info->debug_func == NULL) {
819*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_TYPE_MISMATCH;
820*62c56f98SSadaf Ebrahimi }
821*62c56f98SSadaf Ebrahimi
822*62c56f98SSadaf Ebrahimi ctx->pk_info->debug_func((mbedtls_pk_context *) ctx, items);
823*62c56f98SSadaf Ebrahimi return 0;
824*62c56f98SSadaf Ebrahimi }
825*62c56f98SSadaf Ebrahimi
826*62c56f98SSadaf Ebrahimi /*
827*62c56f98SSadaf Ebrahimi * Access the PK type name
828*62c56f98SSadaf Ebrahimi */
mbedtls_pk_get_name(const mbedtls_pk_context * ctx)829*62c56f98SSadaf Ebrahimi const char *mbedtls_pk_get_name(const mbedtls_pk_context *ctx)
830*62c56f98SSadaf Ebrahimi {
831*62c56f98SSadaf Ebrahimi if (ctx == NULL || ctx->pk_info == NULL) {
832*62c56f98SSadaf Ebrahimi return "invalid PK";
833*62c56f98SSadaf Ebrahimi }
834*62c56f98SSadaf Ebrahimi
835*62c56f98SSadaf Ebrahimi return ctx->pk_info->name;
836*62c56f98SSadaf Ebrahimi }
837*62c56f98SSadaf Ebrahimi
838*62c56f98SSadaf Ebrahimi /*
839*62c56f98SSadaf Ebrahimi * Access the PK type
840*62c56f98SSadaf Ebrahimi */
mbedtls_pk_get_type(const mbedtls_pk_context * ctx)841*62c56f98SSadaf Ebrahimi mbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx)
842*62c56f98SSadaf Ebrahimi {
843*62c56f98SSadaf Ebrahimi if (ctx == NULL || ctx->pk_info == NULL) {
844*62c56f98SSadaf Ebrahimi return MBEDTLS_PK_NONE;
845*62c56f98SSadaf Ebrahimi }
846*62c56f98SSadaf Ebrahimi
847*62c56f98SSadaf Ebrahimi return ctx->pk_info->type;
848*62c56f98SSadaf Ebrahimi }
849*62c56f98SSadaf Ebrahimi
850*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_USE_PSA_CRYPTO)
851*62c56f98SSadaf Ebrahimi /*
852*62c56f98SSadaf Ebrahimi * Load the key to a PSA key slot,
853*62c56f98SSadaf Ebrahimi * then turn the PK context into a wrapper for that key slot.
854*62c56f98SSadaf Ebrahimi *
855*62c56f98SSadaf Ebrahimi * Currently only works for EC & RSA private keys.
856*62c56f98SSadaf Ebrahimi */
mbedtls_pk_wrap_as_opaque(mbedtls_pk_context * pk,mbedtls_svc_key_id_t * key,psa_algorithm_t alg,psa_key_usage_t usage,psa_algorithm_t alg2)857*62c56f98SSadaf Ebrahimi int mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk,
858*62c56f98SSadaf Ebrahimi mbedtls_svc_key_id_t *key,
859*62c56f98SSadaf Ebrahimi psa_algorithm_t alg,
860*62c56f98SSadaf Ebrahimi psa_key_usage_t usage,
861*62c56f98SSadaf Ebrahimi psa_algorithm_t alg2)
862*62c56f98SSadaf Ebrahimi {
863*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_RSA_C)
864*62c56f98SSadaf Ebrahimi ((void) pk);
865*62c56f98SSadaf Ebrahimi ((void) key);
866*62c56f98SSadaf Ebrahimi ((void) alg);
867*62c56f98SSadaf Ebrahimi ((void) usage);
868*62c56f98SSadaf Ebrahimi ((void) alg2);
869*62c56f98SSadaf Ebrahimi #else /* !MBEDTLS_PK_HAVE_ECC_KEYS && !MBEDTLS_RSA_C */
870*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
871*62c56f98SSadaf Ebrahimi if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_ECKEY) {
872*62c56f98SSadaf Ebrahimi size_t d_len;
873*62c56f98SSadaf Ebrahimi psa_ecc_family_t curve_id;
874*62c56f98SSadaf Ebrahimi psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
875*62c56f98SSadaf Ebrahimi psa_key_type_t key_type;
876*62c56f98SSadaf Ebrahimi size_t bits;
877*62c56f98SSadaf Ebrahimi psa_status_t status;
878*62c56f98SSadaf Ebrahimi
879*62c56f98SSadaf Ebrahimi /* export the private key material in the format PSA wants */
880*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
881*62c56f98SSadaf Ebrahimi unsigned char d[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH];
882*62c56f98SSadaf Ebrahimi status = psa_export_key(pk->priv_id, d, sizeof(d), &d_len);
883*62c56f98SSadaf Ebrahimi if (status != PSA_SUCCESS) {
884*62c56f98SSadaf Ebrahimi return psa_pk_status_to_mbedtls(status);
885*62c56f98SSadaf Ebrahimi }
886*62c56f98SSadaf Ebrahimi
887*62c56f98SSadaf Ebrahimi curve_id = pk->ec_family;
888*62c56f98SSadaf Ebrahimi bits = pk->ec_bits;
889*62c56f98SSadaf Ebrahimi #else /* MBEDTLS_PK_USE_PSA_EC_DATA */
890*62c56f98SSadaf Ebrahimi unsigned char d[MBEDTLS_ECP_MAX_BYTES];
891*62c56f98SSadaf Ebrahimi mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*pk);
892*62c56f98SSadaf Ebrahimi int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
893*62c56f98SSadaf Ebrahimi
894*62c56f98SSadaf Ebrahimi d_len = PSA_BITS_TO_BYTES(ec->grp.nbits);
895*62c56f98SSadaf Ebrahimi if ((ret = mbedtls_ecp_write_key(ec, d, d_len)) != 0) {
896*62c56f98SSadaf Ebrahimi return ret;
897*62c56f98SSadaf Ebrahimi }
898*62c56f98SSadaf Ebrahimi
899*62c56f98SSadaf Ebrahimi curve_id = mbedtls_ecc_group_to_psa(ec->grp.id, &bits);
900*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
901*62c56f98SSadaf Ebrahimi key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(curve_id);
902*62c56f98SSadaf Ebrahimi
903*62c56f98SSadaf Ebrahimi /* prepare the key attributes */
904*62c56f98SSadaf Ebrahimi psa_set_key_type(&attributes, key_type);
905*62c56f98SSadaf Ebrahimi psa_set_key_bits(&attributes, bits);
906*62c56f98SSadaf Ebrahimi psa_set_key_usage_flags(&attributes, usage);
907*62c56f98SSadaf Ebrahimi psa_set_key_algorithm(&attributes, alg);
908*62c56f98SSadaf Ebrahimi if (alg2 != PSA_ALG_NONE) {
909*62c56f98SSadaf Ebrahimi psa_set_key_enrollment_algorithm(&attributes, alg2);
910*62c56f98SSadaf Ebrahimi }
911*62c56f98SSadaf Ebrahimi
912*62c56f98SSadaf Ebrahimi /* import private key into PSA */
913*62c56f98SSadaf Ebrahimi status = psa_import_key(&attributes, d, d_len, key);
914*62c56f98SSadaf Ebrahimi mbedtls_platform_zeroize(d, sizeof(d));
915*62c56f98SSadaf Ebrahimi if (status != PSA_SUCCESS) {
916*62c56f98SSadaf Ebrahimi return PSA_PK_TO_MBEDTLS_ERR(status);
917*62c56f98SSadaf Ebrahimi }
918*62c56f98SSadaf Ebrahimi
919*62c56f98SSadaf Ebrahimi /* make PK context wrap the key slot */
920*62c56f98SSadaf Ebrahimi mbedtls_pk_free(pk);
921*62c56f98SSadaf Ebrahimi mbedtls_pk_init(pk);
922*62c56f98SSadaf Ebrahimi
923*62c56f98SSadaf Ebrahimi return mbedtls_pk_setup_opaque(pk, *key);
924*62c56f98SSadaf Ebrahimi } else
925*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
926*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_RSA_C)
927*62c56f98SSadaf Ebrahimi if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_RSA) {
928*62c56f98SSadaf Ebrahimi unsigned char buf[MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES];
929*62c56f98SSadaf Ebrahimi psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
930*62c56f98SSadaf Ebrahimi int key_len;
931*62c56f98SSadaf Ebrahimi psa_status_t status;
932*62c56f98SSadaf Ebrahimi
933*62c56f98SSadaf Ebrahimi /* export the private key material in the format PSA wants */
934*62c56f98SSadaf Ebrahimi key_len = mbedtls_pk_write_key_der(pk, buf, sizeof(buf));
935*62c56f98SSadaf Ebrahimi if (key_len <= 0) {
936*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
937*62c56f98SSadaf Ebrahimi }
938*62c56f98SSadaf Ebrahimi
939*62c56f98SSadaf Ebrahimi /* prepare the key attributes */
940*62c56f98SSadaf Ebrahimi psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
941*62c56f98SSadaf Ebrahimi psa_set_key_bits(&attributes, mbedtls_pk_get_bitlen(pk));
942*62c56f98SSadaf Ebrahimi psa_set_key_usage_flags(&attributes, usage);
943*62c56f98SSadaf Ebrahimi psa_set_key_algorithm(&attributes, alg);
944*62c56f98SSadaf Ebrahimi if (alg2 != PSA_ALG_NONE) {
945*62c56f98SSadaf Ebrahimi psa_set_key_enrollment_algorithm(&attributes, alg2);
946*62c56f98SSadaf Ebrahimi }
947*62c56f98SSadaf Ebrahimi
948*62c56f98SSadaf Ebrahimi /* import private key into PSA */
949*62c56f98SSadaf Ebrahimi status = psa_import_key(&attributes,
950*62c56f98SSadaf Ebrahimi buf + sizeof(buf) - key_len,
951*62c56f98SSadaf Ebrahimi key_len, key);
952*62c56f98SSadaf Ebrahimi
953*62c56f98SSadaf Ebrahimi mbedtls_platform_zeroize(buf, sizeof(buf));
954*62c56f98SSadaf Ebrahimi
955*62c56f98SSadaf Ebrahimi if (status != PSA_SUCCESS) {
956*62c56f98SSadaf Ebrahimi return PSA_PK_TO_MBEDTLS_ERR(status);
957*62c56f98SSadaf Ebrahimi }
958*62c56f98SSadaf Ebrahimi
959*62c56f98SSadaf Ebrahimi /* make PK context wrap the key slot */
960*62c56f98SSadaf Ebrahimi mbedtls_pk_free(pk);
961*62c56f98SSadaf Ebrahimi mbedtls_pk_init(pk);
962*62c56f98SSadaf Ebrahimi
963*62c56f98SSadaf Ebrahimi return mbedtls_pk_setup_opaque(pk, *key);
964*62c56f98SSadaf Ebrahimi } else
965*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_RSA_C */
966*62c56f98SSadaf Ebrahimi #endif /* !MBEDTLS_PK_HAVE_ECC_KEYS && !MBEDTLS_RSA_C */
967*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_PK_TYPE_MISMATCH;
968*62c56f98SSadaf Ebrahimi }
969*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_USE_PSA_CRYPTO */
970*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PK_C */
971