blob: 6b5008df2aabe6ab8dade153a08647d9a015ac79 [file] [log] [blame]
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +02001/*
2 * Public Key abstraction layer
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Dave Rodgman7ff79652023-11-03 12:04:52 +00005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +02006 */
7
Gilles Peskinedb09ef62020-06-03 01:43:33 +02008#include "common.h"
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +02009
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020010#if defined(MBEDTLS_PK_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000011#include "mbedtls/pk.h"
Manuel Pégourié-Gonnard50518f42015-05-26 11:04:15 +020012#include "mbedtls/pk_internal.h"
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020013
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050014#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000015#include "mbedtls/error.h"
Andres AG72849872017-01-19 11:24:33 +000016
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020017#if defined(MBEDTLS_RSA_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000018#include "mbedtls/rsa.h"
Manuel Pégourié-Gonnard81c313c2013-07-09 10:35:54 +020019#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020020#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000021#include "mbedtls/ecp.h"
Manuel Pégourié-Gonnard81c313c2013-07-09 10:35:54 +020022#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020023#if defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000024#include "mbedtls/ecdsa.h"
Manuel Pégourié-Gonnard7c5819e2013-07-10 12:29:57 +020025#endif
Manuel Pégourié-Gonnard81c313c2013-07-09 10:35:54 +020026
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +010027#if defined(MBEDTLS_USE_PSA_CRYPTO)
28#include "mbedtls/psa_util.h"
29#endif
30
Andres AG72849872017-01-19 11:24:33 +000031#include <limits.h>
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +010032#include <stdint.h>
Paul Bakker34617722014-06-13 17:20:13 +020033
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050034/* Parameter validation macros based on platform_util.h */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010035#define PK_VALIDATE_RET(cond) \
36 MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA)
37#define PK_VALIDATE(cond) \
38 MBEDTLS_INTERNAL_VALIDATE(cond)
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050039
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020040/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041 * Initialise a mbedtls_pk_context
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020042 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010043void mbedtls_pk_init(mbedtls_pk_context *ctx)
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020044{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010045 PK_VALIDATE(ctx != NULL);
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020046
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +020047 ctx->pk_info = NULL;
48 ctx->pk_ctx = NULL;
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020049}
50
51/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020052 * Free (the components of) a mbedtls_pk_context
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020053 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010054void mbedtls_pk_free(mbedtls_pk_context *ctx)
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020055{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010056 if (ctx == NULL) {
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020057 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010058 }
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020059
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010060 if (ctx->pk_info != NULL) {
61 ctx->pk_info->ctx_free_func(ctx->pk_ctx);
62 }
Manuel Pégourié-Gonnard1f73a652013-07-09 10:26:41 +020063
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010064 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_pk_context));
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +020065}
66
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +020067#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020068/*
69 * Initialize a restart context
70 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010071void mbedtls_pk_restart_init(mbedtls_pk_restart_ctx *ctx)
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020072{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010073 PK_VALIDATE(ctx != NULL);
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +020074 ctx->pk_info = NULL;
75 ctx->rs_ctx = NULL;
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020076}
77
78/*
79 * Free the components of a restart context
80 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010081void mbedtls_pk_restart_free(mbedtls_pk_restart_ctx *ctx)
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020082{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010083 if (ctx == NULL || ctx->pk_info == NULL ||
84 ctx->pk_info->rs_free_func == NULL) {
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020085 return;
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +020086 }
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020087
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010088 ctx->pk_info->rs_free_func(ctx->rs_ctx);
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +020089
90 ctx->pk_info = NULL;
91 ctx->rs_ctx = NULL;
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020092}
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +020093#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020094
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +020095/*
96 * Get pk_info structure from type
97 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010098const mbedtls_pk_info_t *mbedtls_pk_info_from_type(mbedtls_pk_type_t pk_type)
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +020099{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100100 switch (pk_type) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200101#if defined(MBEDTLS_RSA_C)
102 case MBEDTLS_PK_RSA:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100103 return &mbedtls_rsa_info;
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200104#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200105#if defined(MBEDTLS_ECP_C)
106 case MBEDTLS_PK_ECKEY:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100107 return &mbedtls_eckey_info;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200108 case MBEDTLS_PK_ECKEY_DH:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100109 return &mbedtls_eckeydh_info;
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200110#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200111#if defined(MBEDTLS_ECDSA_C)
112 case MBEDTLS_PK_ECDSA:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100113 return &mbedtls_ecdsa_info;
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200114#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200115 /* MBEDTLS_PK_RSA_ALT omitted on purpose */
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200116 default:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100117 return NULL;
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200118 }
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200119}
120
121/*
Manuel Pégourié-Gonnardab466942013-08-15 11:30:27 +0200122 * Initialise context
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200123 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100124int mbedtls_pk_setup(mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info)
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200125{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100126 PK_VALIDATE_RET(ctx != NULL);
127 if (info == NULL || ctx->pk_info != NULL) {
128 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
129 }
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200130
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100131 if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL) {
132 return MBEDTLS_ERR_PK_ALLOC_FAILED;
133 }
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200134
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200135 ctx->pk_info = info;
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200136
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100137 return 0;
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200138}
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200139
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200140#if defined(MBEDTLS_USE_PSA_CRYPTO)
141/*
142 * Initialise a PSA-wrapping context
143 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100144int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx,
145 const psa_key_id_t key)
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200146{
Manuel Pégourié-Gonnard69baf702018-11-06 09:34:30 +0100147 const mbedtls_pk_info_t * const info = &mbedtls_pk_opaque_info;
Gilles Peskined2d45c12019-05-27 14:53:13 +0200148 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Ronald Croncf56a0a2020-08-04 09:51:30 +0200149 psa_key_id_t *pk_ctx;
Manuel Pégourié-Gonnard920c0632018-10-31 10:57:29 +0100150 psa_key_type_t type;
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200151
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100152 if (ctx == NULL || ctx->pk_info != NULL) {
153 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
154 }
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200155
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100156 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);
Manuel Pégourié-Gonnard920c0632018-10-31 10:57:29 +0100161
162 /* Current implementation of can_do() relies on this. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100163 if (!PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
164 return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
165 }
Manuel Pégourié-Gonnard920c0632018-10-31 10:57:29 +0100166
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100167 if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL) {
168 return MBEDTLS_ERR_PK_ALLOC_FAILED;
169 }
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200170
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200171 ctx->pk_info = info;
172
Ronald Croncf56a0a2020-08-04 09:51:30 +0200173 pk_ctx = (psa_key_id_t *) ctx->pk_ctx;
Manuel Pégourié-Gonnard7b5fe042018-10-31 09:57:45 +0100174 *pk_ctx = key;
175
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100176 return 0;
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200177}
178#endif /* MBEDTLS_USE_PSA_CRYPTO */
179
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200180#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
Manuel Pégourié-Gonnardb4fae572014-01-20 11:22:25 +0100181/*
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200182 * Initialize an RSA-alt context
183 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100184int 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)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200188{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200189 mbedtls_rsa_alt_context *rsa_alt;
190 const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200191
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100192 PK_VALIDATE_RET(ctx != NULL);
193 if (ctx->pk_info != NULL) {
194 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
195 }
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200196
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100197 if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL) {
198 return MBEDTLS_ERR_PK_ALLOC_FAILED;
199 }
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200200
201 ctx->pk_info = info;
202
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200203 rsa_alt = (mbedtls_rsa_alt_context *) ctx->pk_ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200204
205 rsa_alt->key = key;
206 rsa_alt->decrypt_func = decrypt_func;
207 rsa_alt->sign_func = sign_func;
208 rsa_alt->key_len_func = key_len_func;
209
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100210 return 0;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200211}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200212#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200213
214/*
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200215 * Tell if a PK can do the operations of the given type
216 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100217int mbedtls_pk_can_do(const mbedtls_pk_context *ctx, mbedtls_pk_type_t type)
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200218{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500219 /* 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. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100222 if (ctx == NULL || ctx->pk_info == NULL) {
223 return 0;
224 }
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200225
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100226 return ctx->pk_info->can_do(type);
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200227}
228
229/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200230 * Helper for mbedtls_pk_sign and mbedtls_pk_verify
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200231 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100232static inline int pk_hashlen_helper(mbedtls_md_type_t md_alg, size_t *hash_len)
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200233{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200234 const mbedtls_md_info_t *md_info;
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200235
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100236 if (*hash_len != 0 && md_alg == MBEDTLS_MD_NONE) {
237 return 0;
238 }
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200239
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100240 if ((md_info = mbedtls_md_info_from_type(md_alg)) == NULL) {
241 return -1;
242 }
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200243
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100244 if (*hash_len != 0 && *hash_len != mbedtls_md_get_size(md_info)) {
245 return -1;
246 }
Nick Childb6d56932021-05-25 15:31:21 -0400247
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100248 *hash_len = mbedtls_md_get_size(md_info);
249 return 0;
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200250}
251
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200252#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200253/*
254 * Helper to set up a restart context if needed
255 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100256static int pk_restart_setup(mbedtls_pk_restart_ctx *ctx,
257 const mbedtls_pk_info_t *info)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200258{
Manuel Pégourié-Gonnardc8c12b62018-07-02 13:09:39 +0200259 /* Don't do anything if already set up or invalid */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100260 if (ctx == NULL || ctx->pk_info != NULL) {
261 return 0;
262 }
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200263
264 /* Should never happen when we're called */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100265 if (info->rs_alloc_func == NULL || info->rs_free_func == NULL) {
266 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
267 }
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200268
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100269 if ((ctx->rs_ctx = info->rs_alloc_func()) == NULL) {
270 return MBEDTLS_ERR_PK_ALLOC_FAILED;
271 }
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200272
273 ctx->pk_info = info;
274
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100275 return 0;
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200276}
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200277#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200278
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200279/*
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200280 * Verify a signature (restartable)
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200281 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100282int 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)
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200287{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100288 PK_VALIDATE_RET(ctx != NULL);
289 PK_VALIDATE_RET((md_alg == MBEDTLS_MD_NONE && hash_len == 0) ||
290 hash != NULL);
291 PK_VALIDATE_RET(sig != NULL);
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500292
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100293 if (ctx->pk_info == NULL ||
294 pk_hashlen_helper(md_alg, &hash_len) != 0) {
295 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
296 }
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200297
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200298#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnardd55f7762017-08-18 17:40:15 +0200299 /* optimization: use non-restartable version if restart disabled */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100300 if (rs_ctx != NULL &&
Manuel Pégourié-Gonnardb843b152018-10-16 10:41:31 +0200301 mbedtls_ecp_restart_is_enabled() &&
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100302 ctx->pk_info->verify_rs_func != NULL) {
Janos Follath24eed8d2019-11-22 13:21:35 +0000303 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200304
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100305 if ((ret = pk_restart_setup(rs_ctx, ctx->pk_info)) != 0) {
306 return ret;
307 }
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200308
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100309 ret = ctx->pk_info->verify_rs_func(ctx->pk_ctx,
310 md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx);
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200311
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100312 if (ret != MBEDTLS_ERR_ECP_IN_PROGRESS) {
313 mbedtls_pk_restart_free(rs_ctx);
314 }
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200315
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100316 return ret;
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200317 }
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200318#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200319 (void) rs_ctx;
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200320#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200321
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100322 if (ctx->pk_info->verify_func == NULL) {
323 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
324 }
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200325
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100326 return ctx->pk_info->verify_func(ctx->pk_ctx, md_alg, hash, hash_len,
327 sig, sig_len);
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200328}
329
330/*
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200331 * Verify a signature
332 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100333int 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)
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200336{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100337 return mbedtls_pk_verify_restartable(ctx, md_alg, hash, hash_len,
338 sig, sig_len, NULL);
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200339}
340
341/*
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200342 * Verify a signature with options
343 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100344int 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)
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200348{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100349 PK_VALIDATE_RET(ctx != NULL);
350 PK_VALIDATE_RET((md_alg == MBEDTLS_MD_NONE && hash_len == 0) ||
351 hash != NULL);
352 PK_VALIDATE_RET(sig != NULL);
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500353
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100354 if (ctx->pk_info == NULL) {
355 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
356 }
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200357
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100358 if (!mbedtls_pk_can_do(ctx, type)) {
359 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
360 }
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200361
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100362 if (type == MBEDTLS_PK_RSASSA_PSS) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200363#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
Janos Follath24eed8d2019-11-22 13:21:35 +0000364 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200365 const mbedtls_pk_rsassa_pss_options *pss_opts;
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200366
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100367#if SIZE_MAX > UINT_MAX
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100368 if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) {
369 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
370 }
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100371#endif /* SIZE_MAX > UINT_MAX */
Andres AG72849872017-01-19 11:24:33 +0000372
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100373 if (options == NULL) {
374 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
375 }
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200376
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200377 pss_opts = (const mbedtls_pk_rsassa_pss_options *) options;
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200378
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100379 if (sig_len < mbedtls_pk_get_len(ctx)) {
380 return MBEDTLS_ERR_RSA_VERIFY_FAILED;
381 }
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200382
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100383 ret = mbedtls_rsa_rsassa_pss_verify_ext(mbedtls_pk_rsa(*ctx),
384 NULL, NULL, MBEDTLS_RSA_PUBLIC,
385 md_alg, (unsigned int) hash_len, hash,
386 pss_opts->mgf1_hash_id,
387 pss_opts->expected_salt_len,
388 sig);
389 if (ret != 0) {
390 return ret;
391 }
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200392
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100393 if (sig_len > mbedtls_pk_get_len(ctx)) {
394 return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
395 }
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200396
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100397 return 0;
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200398#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100399 return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
Andres AG72849872017-01-19 11:24:33 +0000400#endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200401 }
402
403 /* General case: no options */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100404 if (options != NULL) {
405 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
406 }
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200407
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100408 return mbedtls_pk_verify(ctx, md_alg, hash, hash_len, sig, sig_len);
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200409}
410
411/*
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200412 * Make a signature (restartable)
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200413 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100414int 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)
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200420{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100421 PK_VALIDATE_RET(ctx != NULL);
422 PK_VALIDATE_RET((md_alg == MBEDTLS_MD_NONE && hash_len == 0) ||
423 hash != NULL);
424 PK_VALIDATE_RET(sig != NULL);
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500425
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100426 if (ctx->pk_info == NULL ||
427 pk_hashlen_helper(md_alg, &hash_len) != 0) {
428 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
429 }
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200430
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200431#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnardd55f7762017-08-18 17:40:15 +0200432 /* optimization: use non-restartable version if restart disabled */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100433 if (rs_ctx != NULL &&
Manuel Pégourié-Gonnardb843b152018-10-16 10:41:31 +0200434 mbedtls_ecp_restart_is_enabled() &&
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100435 ctx->pk_info->sign_rs_func != NULL) {
Janos Follath24eed8d2019-11-22 13:21:35 +0000436 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200437
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100438 if ((ret = pk_restart_setup(rs_ctx, ctx->pk_info)) != 0) {
439 return ret;
440 }
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200441
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100442 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);
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200445
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100446 if (ret != MBEDTLS_ERR_ECP_IN_PROGRESS) {
447 mbedtls_pk_restart_free(rs_ctx);
448 }
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200449
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100450 return ret;
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200451 }
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200452#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200453 (void) rs_ctx;
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200454#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200455
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100456 if (ctx->pk_info->sign_func == NULL) {
457 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
458 }
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200459
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100460 return ctx->pk_info->sign_func(ctx->pk_ctx, md_alg, hash, hash_len,
461 sig, sig_len, f_rng, p_rng);
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200462}
463
464/*
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200465 * Make a signature
466 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100467int 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)
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200471{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100472 return mbedtls_pk_sign_restartable(ctx, md_alg, hash, hash_len,
473 sig, sig_len, f_rng, p_rng, NULL);
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200474}
475
476/*
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200477 * Decrypt message
478 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100479int 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)
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200483{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100484 PK_VALIDATE_RET(ctx != NULL);
485 PK_VALIDATE_RET(input != NULL || ilen == 0);
486 PK_VALIDATE_RET(output != NULL || osize == 0);
487 PK_VALIDATE_RET(olen != NULL);
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500488
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100489 if (ctx->pk_info == NULL) {
490 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
491 }
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200492
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100493 if (ctx->pk_info->decrypt_func == NULL) {
494 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
495 }
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200496
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100497 return ctx->pk_info->decrypt_func(ctx->pk_ctx, input, ilen,
498 output, olen, osize, f_rng, p_rng);
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200499}
500
501/*
502 * Encrypt message
503 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100504int 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)
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200508{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100509 PK_VALIDATE_RET(ctx != NULL);
510 PK_VALIDATE_RET(input != NULL || ilen == 0);
511 PK_VALIDATE_RET(output != NULL || osize == 0);
512 PK_VALIDATE_RET(olen != NULL);
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500513
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100514 if (ctx->pk_info == NULL) {
515 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
516 }
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200517
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100518 if (ctx->pk_info->encrypt_func == NULL) {
519 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
520 }
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200521
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100522 return ctx->pk_info->encrypt_func(ctx->pk_ctx, input, ilen,
523 output, olen, osize, f_rng, p_rng);
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200524}
525
526/*
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100527 * Check public-private key pair
528 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100529int mbedtls_pk_check_pair(const mbedtls_pk_context *pub, const mbedtls_pk_context *prv)
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100530{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100531 PK_VALIDATE_RET(pub != NULL);
532 PK_VALIDATE_RET(prv != NULL);
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500533
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100534 if (pub->pk_info == NULL ||
535 prv->pk_info == NULL) {
536 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100537 }
538
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100539 if (prv->pk_info->check_pair_func == NULL) {
540 return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100541 }
542
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100543 if (prv->pk_info->type == MBEDTLS_PK_RSA_ALT) {
544 if (pub->pk_info->type != MBEDTLS_PK_RSA) {
545 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
546 }
547 } else {
548 if (pub->pk_info != prv->pk_info) {
549 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
550 }
551 }
552
553 return prv->pk_info->check_pair_func(pub->pk_ctx, prv->pk_ctx);
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100554}
555
556/*
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200557 * Get key size in bits
558 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100559size_t mbedtls_pk_get_bitlen(const mbedtls_pk_context *ctx)
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200560{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500561 /* For backward compatibility, accept NULL or a context that
562 * isn't set up yet, and return a fake value that should be safe. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100563 if (ctx == NULL || ctx->pk_info == NULL) {
564 return 0;
565 }
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200566
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100567 return ctx->pk_info->get_bitlen(ctx->pk_ctx);
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200568}
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200569
570/*
571 * Export debug information
572 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100573int mbedtls_pk_debug(const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items)
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200574{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100575 PK_VALIDATE_RET(ctx != NULL);
576 if (ctx->pk_info == NULL) {
577 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
578 }
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200579
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100580 if (ctx->pk_info->debug_func == NULL) {
581 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
582 }
Manuel Pégourié-Gonnard01488752014-04-03 22:09:18 +0200583
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100584 ctx->pk_info->debug_func(ctx->pk_ctx, items);
585 return 0;
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200586}
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200587
588/*
589 * Access the PK type name
590 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100591const char *mbedtls_pk_get_name(const mbedtls_pk_context *ctx)
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200592{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100593 if (ctx == NULL || ctx->pk_info == NULL) {
594 return "invalid PK";
595 }
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200596
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100597 return ctx->pk_info->name;
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200598}
Manuel Pégourié-Gonnardc40b4c32013-08-22 13:29:31 +0200599
Manuel Pégourié-Gonnard8053da42013-09-11 22:28:30 +0200600/*
601 * Access the PK type
602 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100603mbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx)
Manuel Pégourié-Gonnard8053da42013-09-11 22:28:30 +0200604{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100605 if (ctx == NULL || ctx->pk_info == NULL) {
606 return MBEDTLS_PK_NONE;
607 }
Manuel Pégourié-Gonnard8053da42013-09-11 22:28:30 +0200608
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100609 return ctx->pk_info->type;
Manuel Pégourié-Gonnard8053da42013-09-11 22:28:30 +0200610}
611
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100612#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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100619int mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk,
620 psa_key_id_t *key,
621 psa_algorithm_t hash_alg)
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100622{
623#if !defined(MBEDTLS_ECP_C)
John Durkopf35069a2020-08-17 22:05:14 -0700624 ((void) pk);
Ronald Croncf56a0a2020-08-04 09:51:30 +0200625 ((void) key);
John Durkopf35069a2020-08-17 22:05:14 -0700626 ((void) hash_alg);
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100627 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100628#else
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100629 const mbedtls_ecp_keypair *ec;
630 unsigned char d[MBEDTLS_ECP_MAX_BYTES];
631 size_t d_len;
Paul Elliott8ff510a2020-06-02 17:19:28 +0100632 psa_ecc_family_t curve_id;
Gilles Peskined2d45c12019-05-27 14:53:13 +0200633 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100634 psa_key_type_t key_type;
Gilles Peskine4080c912019-12-18 20:43:03 +0100635 size_t bits;
Janos Follath24eed8d2019-11-22 13:21:35 +0000636 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Valerio Setti5e7494e2023-04-27 10:05:03 +0200637 psa_status_t status;
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100638
639 /* export the private key material in the format PSA wants */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100640 if (mbedtls_pk_get_type(pk) != MBEDTLS_PK_ECKEY) {
641 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
642 }
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100643
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100644 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 }
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100649
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100650 curve_id = mbedtls_ecc_group_to_psa(ec->grp.id, &bits);
651 key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(curve_id);
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100652
Gilles Peskined2d45c12019-05-27 14:53:13 +0200653 /* prepare the key attributes */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100654 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));
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100658
Gilles Peskined2d45c12019-05-27 14:53:13 +0200659 /* import private key into PSA */
Valerio Setti5e7494e2023-04-27 10:05:03 +0200660 status = psa_import_key(&attributes, d, d_len, key);
Valerio Settiaae96c92023-04-26 13:08:56 +0200661 mbedtls_platform_zeroize(d, sizeof(d));
Valerio Setti5e7494e2023-04-27 10:05:03 +0200662 if (status != PSA_SUCCESS) {
Valerio Setti0eace412023-05-02 16:38:57 +0200663 return MBEDTLS_ERR_PK_HW_ACCEL_FAILED;
Valerio Setti5e7494e2023-04-27 10:05:03 +0200664 }
Valerio Settiaae96c92023-04-26 13:08:56 +0200665
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100666 /* make PK context wrap the key slot */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100667 mbedtls_pk_free(pk);
668 mbedtls_pk_init(pk);
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100669
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100670 return mbedtls_pk_setup_opaque(pk, *key);
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100671#endif /* MBEDTLS_ECP_C */
672}
673#endif /* MBEDTLS_USE_PSA_CRYPTO */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200674#endif /* MBEDTLS_PK_C */