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