Coverage Report

Created: 2025-07-01 06:54

/work/mbedtls-2.28.8/library/pk.c
Line
Count
Source (jump to first uncovered line)
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 "mbedtls/pk_internal.h"
13
14
#include "mbedtls/platform_util.h"
15
#include "mbedtls/error.h"
16
17
#if defined(MBEDTLS_RSA_C)
18
#include "mbedtls/rsa.h"
19
#endif
20
#if defined(MBEDTLS_ECP_C)
21
#include "mbedtls/ecp.h"
22
#endif
23
#if defined(MBEDTLS_ECDSA_C)
24
#include "mbedtls/ecdsa.h"
25
#endif
26
27
#if defined(MBEDTLS_USE_PSA_CRYPTO)
28
#include "mbedtls/psa_util.h"
29
#endif
30
31
#include <limits.h>
32
#include <stdint.h>
33
34
/* Parameter validation macros based on platform_util.h */
35
#define PK_VALIDATE_RET(cond)    \
36
0
    MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA)
37
#define PK_VALIDATE(cond)        \
38
0
    MBEDTLS_INTERNAL_VALIDATE(cond)
39
40
/*
41
 * Initialise a mbedtls_pk_context
42
 */
43
void mbedtls_pk_init(mbedtls_pk_context *ctx)
44
0
{
45
0
    PK_VALIDATE(ctx != NULL);
46
47
0
    ctx->pk_info = NULL;
48
0
    ctx->pk_ctx = NULL;
49
0
}
50
51
/*
52
 * Free (the components of) a mbedtls_pk_context
53
 */
54
void mbedtls_pk_free(mbedtls_pk_context *ctx)
55
0
{
56
0
    if (ctx == NULL) {
57
0
        return;
58
0
    }
59
60
0
    if (ctx->pk_info != NULL) {
61
0
        ctx->pk_info->ctx_free_func(ctx->pk_ctx);
62
0
    }
63
64
0
    mbedtls_platform_zeroize(ctx, sizeof(mbedtls_pk_context));
65
0
}
66
67
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
68
/*
69
 * Initialize a restart context
70
 */
71
void mbedtls_pk_restart_init(mbedtls_pk_restart_ctx *ctx)
72
{
73
    PK_VALIDATE(ctx != NULL);
74
    ctx->pk_info = NULL;
75
    ctx->rs_ctx = NULL;
76
}
77
78
/*
79
 * Free the components of a restart context
80
 */
81
void mbedtls_pk_restart_free(mbedtls_pk_restart_ctx *ctx)
82
{
83
    if (ctx == NULL || ctx->pk_info == NULL ||
84
        ctx->pk_info->rs_free_func == NULL) {
85
        return;
86
    }
87
88
    ctx->pk_info->rs_free_func(ctx->rs_ctx);
89
90
    ctx->pk_info = NULL;
91
    ctx->rs_ctx = NULL;
92
}
93
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
94
95
/*
96
 * Get pk_info structure from type
97
 */
98
const mbedtls_pk_info_t *mbedtls_pk_info_from_type(mbedtls_pk_type_t pk_type)
99
0
{
100
0
    switch (pk_type) {
101
0
#if defined(MBEDTLS_RSA_C)
102
0
        case MBEDTLS_PK_RSA:
103
0
            return &mbedtls_rsa_info;
104
0
#endif
105
0
#if defined(MBEDTLS_ECP_C)
106
0
        case MBEDTLS_PK_ECKEY:
107
0
            return &mbedtls_eckey_info;
108
0
        case MBEDTLS_PK_ECKEY_DH:
109
0
            return &mbedtls_eckeydh_info;
110
0
#endif
111
0
#if defined(MBEDTLS_ECDSA_C)
112
0
        case MBEDTLS_PK_ECDSA:
113
0
            return &mbedtls_ecdsa_info;
114
0
#endif
115
        /* MBEDTLS_PK_RSA_ALT omitted on purpose */
116
0
        default:
117
0
            return NULL;
118
0
    }
119
0
}
120
121
/*
122
 * Initialise context
123
 */
124
int mbedtls_pk_setup(mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info)
125
0
{
126
0
    PK_VALIDATE_RET(ctx != NULL);
127
0
    if (info == NULL || ctx->pk_info != NULL) {
128
0
        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
129
0
    }
130
131
0
    if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL) {
132
0
        return MBEDTLS_ERR_PK_ALLOC_FAILED;
133
0
    }
134
135
0
    ctx->pk_info = info;
136
137
0
    return 0;
138
0
}
139
140
#if defined(MBEDTLS_USE_PSA_CRYPTO)
141
/*
142
 * Initialise a PSA-wrapping context
143
 */
144
int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx,
145
                            const psa_key_id_t key)
146
{
147
    const mbedtls_pk_info_t * const info = &mbedtls_pk_opaque_info;
148
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
149
    psa_key_id_t *pk_ctx;
150
    psa_key_type_t type;
151
152
    if (ctx == NULL || ctx->pk_info != NULL) {
153
        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
154
    }
155
156
    if (PSA_SUCCESS != psa_get_key_attributes(key, &attributes)) {
157
        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
158
    }
159
    type = psa_get_key_type(&attributes);
160
    psa_reset_key_attributes(&attributes);
161
162
    /* Current implementation of can_do() relies on this. */
163
    if (!PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
164
        return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
165
    }
166
167
    if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL) {
168
        return MBEDTLS_ERR_PK_ALLOC_FAILED;
169
    }
170
171
    ctx->pk_info = info;
172
173
    pk_ctx = (psa_key_id_t *) ctx->pk_ctx;
174
    *pk_ctx = key;
175
176
    return 0;
177
}
178
#endif /* MBEDTLS_USE_PSA_CRYPTO */
179
180
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
181
/*
182
 * Initialize an RSA-alt context
183
 */
184
int mbedtls_pk_setup_rsa_alt(mbedtls_pk_context *ctx, void *key,
185
                             mbedtls_pk_rsa_alt_decrypt_func decrypt_func,
186
                             mbedtls_pk_rsa_alt_sign_func sign_func,
187
                             mbedtls_pk_rsa_alt_key_len_func key_len_func)
188
0
{
189
0
    mbedtls_rsa_alt_context *rsa_alt;
190
0
    const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info;
191
192
0
    PK_VALIDATE_RET(ctx != NULL);
193
0
    if (ctx->pk_info != NULL) {
194
0
        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
195
0
    }
196
197
0
    if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL) {
198
0
        return MBEDTLS_ERR_PK_ALLOC_FAILED;
199
0
    }
200
201
0
    ctx->pk_info = info;
202
203
0
    rsa_alt = (mbedtls_rsa_alt_context *) ctx->pk_ctx;
204
205
0
    rsa_alt->key = key;
206
0
    rsa_alt->decrypt_func = decrypt_func;
207
0
    rsa_alt->sign_func = sign_func;
208
0
    rsa_alt->key_len_func = key_len_func;
209
210
0
    return 0;
211
0
}
212
#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
213
214
/*
215
 * Tell if a PK can do the operations of the given type
216
 */
217
int mbedtls_pk_can_do(const mbedtls_pk_context *ctx, mbedtls_pk_type_t type)
218
0
{
219
    /* A context with null pk_info is not set up yet and can't do anything.
220
     * For backward compatibility, also accept NULL instead of a context
221
     * pointer. */
222
0
    if (ctx == NULL || ctx->pk_info == NULL) {
223
0
        return 0;
224
0
    }
225
226
0
    return ctx->pk_info->can_do(type);
227
0
}
228
229
/*
230
 * Helper for mbedtls_pk_sign and mbedtls_pk_verify
231
 */
232
static inline int pk_hashlen_helper(mbedtls_md_type_t md_alg, size_t *hash_len)
233
0
{
234
0
    const mbedtls_md_info_t *md_info;
235
236
0
    if (*hash_len != 0 && md_alg == MBEDTLS_MD_NONE) {
237
0
        return 0;
238
0
    }
239
240
0
    if ((md_info = mbedtls_md_info_from_type(md_alg)) == NULL) {
241
0
        return -1;
242
0
    }
243
244
0
    if (*hash_len != 0 && *hash_len != mbedtls_md_get_size(md_info)) {
245
0
        return -1;
246
0
    }
247
248
0
    *hash_len = mbedtls_md_get_size(md_info);
249
0
    return 0;
250
0
}
251
252
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
253
/*
254
 * Helper to set up a restart context if needed
255
 */
256
static int pk_restart_setup(mbedtls_pk_restart_ctx *ctx,
257
                            const mbedtls_pk_info_t *info)
258
{
259
    /* Don't do anything if already set up or invalid */
260
    if (ctx == NULL || ctx->pk_info != NULL) {
261
        return 0;
262
    }
263
264
    /* Should never happen when we're called */
265
    if (info->rs_alloc_func == NULL || info->rs_free_func == NULL) {
266
        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
267
    }
268
269
    if ((ctx->rs_ctx = info->rs_alloc_func()) == NULL) {
270
        return MBEDTLS_ERR_PK_ALLOC_FAILED;
271
    }
272
273
    ctx->pk_info = info;
274
275
    return 0;
276
}
277
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
278
279
/*
280
 * Verify a signature (restartable)
281
 */
282
int mbedtls_pk_verify_restartable(mbedtls_pk_context *ctx,
283
                                  mbedtls_md_type_t md_alg,
284
                                  const unsigned char *hash, size_t hash_len,
285
                                  const unsigned char *sig, size_t sig_len,
286
                                  mbedtls_pk_restart_ctx *rs_ctx)
287
0
{
288
0
    PK_VALIDATE_RET(ctx != NULL);
289
0
    PK_VALIDATE_RET((md_alg == MBEDTLS_MD_NONE && hash_len == 0) ||
290
0
                    hash != NULL);
291
0
    PK_VALIDATE_RET(sig != NULL);
292
293
0
    if (ctx->pk_info == NULL ||
294
0
        pk_hashlen_helper(md_alg, &hash_len) != 0) {
295
0
        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
296
0
    }
297
298
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
299
    /* optimization: use non-restartable version if restart disabled */
300
    if (rs_ctx != NULL &&
301
        mbedtls_ecp_restart_is_enabled() &&
302
        ctx->pk_info->verify_rs_func != NULL) {
303
        int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
304
305
        if ((ret = pk_restart_setup(rs_ctx, ctx->pk_info)) != 0) {
306
            return ret;
307
        }
308
309
        ret = ctx->pk_info->verify_rs_func(ctx->pk_ctx,
310
                                           md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx);
311
312
        if (ret != MBEDTLS_ERR_ECP_IN_PROGRESS) {
313
            mbedtls_pk_restart_free(rs_ctx);
314
        }
315
316
        return ret;
317
    }
318
#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
319
0
    (void) rs_ctx;
320
0
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
321
322
0
    if (ctx->pk_info->verify_func == NULL) {
323
0
        return MBEDTLS_ERR_PK_TYPE_MISMATCH;
324
0
    }
325
326
0
    return ctx->pk_info->verify_func(ctx->pk_ctx, md_alg, hash, hash_len,
327
0
                                     sig, sig_len);
328
0
}
329
330
/*
331
 * Verify a signature
332
 */
333
int mbedtls_pk_verify(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
334
                      const unsigned char *hash, size_t hash_len,
335
                      const unsigned char *sig, size_t sig_len)
336
0
{
337
0
    return mbedtls_pk_verify_restartable(ctx, md_alg, hash, hash_len,
338
0
                                         sig, sig_len, NULL);
339
0
}
340
341
/*
342
 * Verify a signature with options
343
 */
344
int mbedtls_pk_verify_ext(mbedtls_pk_type_t type, const void *options,
345
                          mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
346
                          const unsigned char *hash, size_t hash_len,
347
                          const unsigned char *sig, size_t sig_len)
348
0
{
349
0
    PK_VALIDATE_RET(ctx != NULL);
350
0
    PK_VALIDATE_RET((md_alg == MBEDTLS_MD_NONE && hash_len == 0) ||
351
0
                    hash != NULL);
352
0
    PK_VALIDATE_RET(sig != NULL);
353
354
0
    if (ctx->pk_info == NULL) {
355
0
        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
356
0
    }
357
358
0
    if (!mbedtls_pk_can_do(ctx, type)) {
359
0
        return MBEDTLS_ERR_PK_TYPE_MISMATCH;
360
0
    }
361
362
0
    if (type == MBEDTLS_PK_RSASSA_PSS) {
363
0
#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
364
0
        int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
365
0
        const mbedtls_pk_rsassa_pss_options *pss_opts;
366
367
0
#if SIZE_MAX > UINT_MAX
368
0
        if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) {
369
0
            return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
370
0
        }
371
0
#endif /* SIZE_MAX > UINT_MAX */
372
373
0
        if (options == NULL) {
374
0
            return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
375
0
        }
376
377
0
        pss_opts = (const mbedtls_pk_rsassa_pss_options *) options;
378
379
0
        if (sig_len < mbedtls_pk_get_len(ctx)) {
380
0
            return MBEDTLS_ERR_RSA_VERIFY_FAILED;
381
0
        }
382
383
0
        ret = mbedtls_rsa_rsassa_pss_verify_ext(mbedtls_pk_rsa(*ctx),
384
0
                                                NULL, NULL, MBEDTLS_RSA_PUBLIC,
385
0
                                                md_alg, (unsigned int) hash_len, hash,
386
0
                                                pss_opts->mgf1_hash_id,
387
0
                                                pss_opts->expected_salt_len,
388
0
                                                sig);
389
0
        if (ret != 0) {
390
0
            return ret;
391
0
        }
392
393
0
        if (sig_len > mbedtls_pk_get_len(ctx)) {
394
0
            return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
395
0
        }
396
397
0
        return 0;
398
#else
399
        return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
400
#endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */
401
0
    }
402
403
    /* General case: no options */
404
0
    if (options != NULL) {
405
0
        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
406
0
    }
407
408
0
    return mbedtls_pk_verify(ctx, md_alg, hash, hash_len, sig, sig_len);
409
0
}
410
411
/*
412
 * Make a signature (restartable)
413
 */
414
int mbedtls_pk_sign_restartable(mbedtls_pk_context *ctx,
415
                                mbedtls_md_type_t md_alg,
416
                                const unsigned char *hash, size_t hash_len,
417
                                unsigned char *sig, size_t *sig_len,
418
                                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
419
                                mbedtls_pk_restart_ctx *rs_ctx)
420
0
{
421
0
    PK_VALIDATE_RET(ctx != NULL);
422
0
    PK_VALIDATE_RET((md_alg == MBEDTLS_MD_NONE && hash_len == 0) ||
423
0
                    hash != NULL);
424
0
    PK_VALIDATE_RET(sig != NULL);
425
426
0
    if (ctx->pk_info == NULL ||
427
0
        pk_hashlen_helper(md_alg, &hash_len) != 0) {
428
0
        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
429
0
    }
430
431
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
432
    /* optimization: use non-restartable version if restart disabled */
433
    if (rs_ctx != NULL &&
434
        mbedtls_ecp_restart_is_enabled() &&
435
        ctx->pk_info->sign_rs_func != NULL) {
436
        int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
437
438
        if ((ret = pk_restart_setup(rs_ctx, ctx->pk_info)) != 0) {
439
            return ret;
440
        }
441
442
        ret = ctx->pk_info->sign_rs_func(ctx->pk_ctx, md_alg,
443
                                         hash, hash_len, sig, sig_len, f_rng, p_rng,
444
                                         rs_ctx->rs_ctx);
445
446
        if (ret != MBEDTLS_ERR_ECP_IN_PROGRESS) {
447
            mbedtls_pk_restart_free(rs_ctx);
448
        }
449
450
        return ret;
451
    }
452
#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
453
0
    (void) rs_ctx;
454
0
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
455
456
0
    if (ctx->pk_info->sign_func == NULL) {
457
0
        return MBEDTLS_ERR_PK_TYPE_MISMATCH;
458
0
    }
459
460
0
    return ctx->pk_info->sign_func(ctx->pk_ctx, md_alg, hash, hash_len,
461
0
                                   sig, sig_len, f_rng, p_rng);
462
0
}
463
464
/*
465
 * Make a signature
466
 */
467
int mbedtls_pk_sign(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
468
                    const unsigned char *hash, size_t hash_len,
469
                    unsigned char *sig, size_t *sig_len,
470
                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
471
0
{
472
0
    return mbedtls_pk_sign_restartable(ctx, md_alg, hash, hash_len,
473
0
                                       sig, sig_len, f_rng, p_rng, NULL);
474
0
}
475
476
/*
477
 * Decrypt message
478
 */
479
int mbedtls_pk_decrypt(mbedtls_pk_context *ctx,
480
                       const unsigned char *input, size_t ilen,
481
                       unsigned char *output, size_t *olen, size_t osize,
482
                       int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
483
0
{
484
0
    PK_VALIDATE_RET(ctx != NULL);
485
0
    PK_VALIDATE_RET(input != NULL || ilen == 0);
486
0
    PK_VALIDATE_RET(output != NULL || osize == 0);
487
0
    PK_VALIDATE_RET(olen != NULL);
488
489
0
    if (ctx->pk_info == NULL) {
490
0
        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
491
0
    }
492
493
0
    if (ctx->pk_info->decrypt_func == NULL) {
494
0
        return MBEDTLS_ERR_PK_TYPE_MISMATCH;
495
0
    }
496
497
0
    return ctx->pk_info->decrypt_func(ctx->pk_ctx, input, ilen,
498
0
                                      output, olen, osize, f_rng, p_rng);
499
0
}
500
501
/*
502
 * Encrypt message
503
 */
504
int mbedtls_pk_encrypt(mbedtls_pk_context *ctx,
505
                       const unsigned char *input, size_t ilen,
506
                       unsigned char *output, size_t *olen, size_t osize,
507
                       int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
508
0
{
509
0
    PK_VALIDATE_RET(ctx != NULL);
510
0
    PK_VALIDATE_RET(input != NULL || ilen == 0);
511
0
    PK_VALIDATE_RET(output != NULL || osize == 0);
512
0
    PK_VALIDATE_RET(olen != NULL);
513
514
0
    if (ctx->pk_info == NULL) {
515
0
        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
516
0
    }
517
518
0
    if (ctx->pk_info->encrypt_func == NULL) {
519
0
        return MBEDTLS_ERR_PK_TYPE_MISMATCH;
520
0
    }
521
522
0
    return ctx->pk_info->encrypt_func(ctx->pk_ctx, input, ilen,
523
0
                                      output, olen, osize, f_rng, p_rng);
524
0
}
525
526
/*
527
 * Check public-private key pair
528
 */
529
int mbedtls_pk_check_pair(const mbedtls_pk_context *pub, const mbedtls_pk_context *prv)
530
0
{
531
0
    PK_VALIDATE_RET(pub != NULL);
532
0
    PK_VALIDATE_RET(prv != NULL);
533
534
0
    if (pub->pk_info == NULL ||
535
0
        prv->pk_info == NULL) {
536
0
        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
537
0
    }
538
539
0
    if (prv->pk_info->check_pair_func == NULL) {
540
0
        return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
541
0
    }
542
543
0
    if (prv->pk_info->type == MBEDTLS_PK_RSA_ALT) {
544
0
        if (pub->pk_info->type != MBEDTLS_PK_RSA) {
545
0
            return MBEDTLS_ERR_PK_TYPE_MISMATCH;
546
0
        }
547
0
    } else {
548
0
        if (pub->pk_info != prv->pk_info) {
549
0
            return MBEDTLS_ERR_PK_TYPE_MISMATCH;
550
0
        }
551
0
    }
552
553
0
    return prv->pk_info->check_pair_func(pub->pk_ctx, prv->pk_ctx);
554
0
}
555
556
/*
557
 * Get key size in bits
558
 */
559
size_t mbedtls_pk_get_bitlen(const mbedtls_pk_context *ctx)
560
0
{
561
    /* For backward compatibility, accept NULL or a context that
562
     * isn't set up yet, and return a fake value that should be safe. */
563
0
    if (ctx == NULL || ctx->pk_info == NULL) {
564
0
        return 0;
565
0
    }
566
567
0
    return ctx->pk_info->get_bitlen(ctx->pk_ctx);
568
0
}
569
570
/*
571
 * Export debug information
572
 */
573
int mbedtls_pk_debug(const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items)
574
0
{
575
0
    PK_VALIDATE_RET(ctx != NULL);
576
0
    if (ctx->pk_info == NULL) {
577
0
        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
578
0
    }
579
580
0
    if (ctx->pk_info->debug_func == NULL) {
581
0
        return MBEDTLS_ERR_PK_TYPE_MISMATCH;
582
0
    }
583
584
0
    ctx->pk_info->debug_func(ctx->pk_ctx, items);
585
0
    return 0;
586
0
}
587
588
/*
589
 * Access the PK type name
590
 */
591
const char *mbedtls_pk_get_name(const mbedtls_pk_context *ctx)
592
0
{
593
0
    if (ctx == NULL || ctx->pk_info == NULL) {
594
0
        return "invalid PK";
595
0
    }
596
597
0
    return ctx->pk_info->name;
598
0
}
599
600
/*
601
 * Access the PK type
602
 */
603
mbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx)
604
0
{
605
0
    if (ctx == NULL || ctx->pk_info == NULL) {
606
0
        return MBEDTLS_PK_NONE;
607
0
    }
608
609
0
    return ctx->pk_info->type;
610
0
}
611
612
#if defined(MBEDTLS_USE_PSA_CRYPTO)
613
/*
614
 * Load the key to a PSA key slot,
615
 * then turn the PK context into a wrapper for that key slot.
616
 *
617
 * Currently only works for EC private keys.
618
 */
619
int mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk,
620
                              psa_key_id_t *key,
621
                              psa_algorithm_t hash_alg)
622
{
623
#if !defined(MBEDTLS_ECP_C)
624
    ((void) pk);
625
    ((void) key);
626
    ((void) hash_alg);
627
    return MBEDTLS_ERR_PK_TYPE_MISMATCH;
628
#else
629
    const mbedtls_ecp_keypair *ec;
630
    unsigned char d[MBEDTLS_ECP_MAX_BYTES];
631
    size_t d_len;
632
    psa_ecc_family_t curve_id;
633
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
634
    psa_key_type_t key_type;
635
    size_t bits;
636
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
637
    psa_status_t status;
638
639
    /* export the private key material in the format PSA wants */
640
    if (mbedtls_pk_get_type(pk) != MBEDTLS_PK_ECKEY) {
641
        return MBEDTLS_ERR_PK_TYPE_MISMATCH;
642
    }
643
644
    ec = mbedtls_pk_ec(*pk);
645
    d_len = (ec->grp.nbits + 7) / 8;
646
    if ((ret = mbedtls_mpi_write_binary(&ec->d, d, d_len)) != 0) {
647
        return ret;
648
    }
649
650
    curve_id = mbedtls_ecc_group_to_psa(ec->grp.id, &bits);
651
    key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(curve_id);
652
653
    /* prepare the key attributes */
654
    psa_set_key_type(&attributes, key_type);
655
    psa_set_key_bits(&attributes, bits);
656
    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
657
    psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(hash_alg));
658
659
    /* import private key into PSA */
660
    status = psa_import_key(&attributes, d, d_len, key);
661
    mbedtls_platform_zeroize(d, sizeof(d));
662
    if (status != PSA_SUCCESS) {
663
        return MBEDTLS_ERR_PK_HW_ACCEL_FAILED;
664
    }
665
666
    /* make PK context wrap the key slot */
667
    mbedtls_pk_free(pk);
668
    mbedtls_pk_init(pk);
669
670
    return mbedtls_pk_setup_opaque(pk, *key);
671
#endif /* MBEDTLS_ECP_C */
672
}
673
#endif /* MBEDTLS_USE_PSA_CRYPTO */
674
#endif /* MBEDTLS_PK_C */