blob: d46a93461aaa49b73bf92c5ccef5c4db4fb60a54 [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
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020018 */
19
Gilles Peskinedb09ef62020-06-03 01:43:33 +020020#include "common.h"
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020021
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020022#if defined(MBEDTLS_PK_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000023#include "mbedtls/pk.h"
Manuel Pégourié-Gonnard50518f42015-05-26 11:04:15 +020024#include "mbedtls/pk_internal.h"
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020025
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050026#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000027#include "mbedtls/error.h"
Andres AG72849872017-01-19 11:24:33 +000028
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020029#if defined(MBEDTLS_RSA_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000030#include "mbedtls/rsa.h"
Manuel Pégourié-Gonnard81c313c2013-07-09 10:35:54 +020031#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020032#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000033#include "mbedtls/ecp.h"
Manuel Pégourié-Gonnard81c313c2013-07-09 10:35:54 +020034#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020035#if defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000036#include "mbedtls/ecdsa.h"
Manuel Pégourié-Gonnard7c5819e2013-07-10 12:29:57 +020037#endif
Manuel Pégourié-Gonnard81c313c2013-07-09 10:35:54 +020038
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +010039#if defined(MBEDTLS_USE_PSA_CRYPTO)
40#include "mbedtls/psa_util.h"
41#endif
42
Andres AG72849872017-01-19 11:24:33 +000043#include <limits.h>
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +010044#include <stdint.h>
Paul Bakker34617722014-06-13 17:20:13 +020045
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050046/* Parameter validation macros based on platform_util.h */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010047#define PK_VALIDATE_RET(cond) \
48 MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA)
49#define PK_VALIDATE(cond) \
50 MBEDTLS_INTERNAL_VALIDATE(cond)
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050051
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020052/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053 * Initialise a mbedtls_pk_context
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020054 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010055void mbedtls_pk_init(mbedtls_pk_context *ctx)
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020056{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010057 PK_VALIDATE(ctx != NULL);
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020058
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +020059 ctx->pk_info = NULL;
60 ctx->pk_ctx = NULL;
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020061}
62
63/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020064 * Free (the components of) a mbedtls_pk_context
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020065 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010066void mbedtls_pk_free(mbedtls_pk_context *ctx)
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020067{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010068 if (ctx == NULL) {
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020069 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010070 }
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020071
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010072 if (ctx->pk_info != NULL) {
73 ctx->pk_info->ctx_free_func(ctx->pk_ctx);
74 }
Manuel Pégourié-Gonnard1f73a652013-07-09 10:26:41 +020075
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010076 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_pk_context));
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +020077}
78
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +020079#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020080/*
81 * Initialize a restart context
82 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010083void mbedtls_pk_restart_init(mbedtls_pk_restart_ctx *ctx)
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020084{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010085 PK_VALIDATE(ctx != NULL);
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +020086 ctx->pk_info = NULL;
87 ctx->rs_ctx = NULL;
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020088}
89
90/*
91 * Free the components of a restart context
92 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010093void mbedtls_pk_restart_free(mbedtls_pk_restart_ctx *ctx)
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020094{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010095 if (ctx == NULL || ctx->pk_info == NULL ||
96 ctx->pk_info->rs_free_func == NULL) {
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020097 return;
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +020098 }
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020099
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100100 ctx->pk_info->rs_free_func(ctx->rs_ctx);
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200101
102 ctx->pk_info = NULL;
103 ctx->rs_ctx = NULL;
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +0200104}
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200105#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +0200106
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200107/*
108 * Get pk_info structure from type
109 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100110const mbedtls_pk_info_t *mbedtls_pk_info_from_type(mbedtls_pk_type_t pk_type)
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200111{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100112 switch (pk_type) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200113#if defined(MBEDTLS_RSA_C)
114 case MBEDTLS_PK_RSA:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100115 return &mbedtls_rsa_info;
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200116#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200117#if defined(MBEDTLS_ECP_C)
118 case MBEDTLS_PK_ECKEY:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100119 return &mbedtls_eckey_info;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200120 case MBEDTLS_PK_ECKEY_DH:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100121 return &mbedtls_eckeydh_info;
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200122#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200123#if defined(MBEDTLS_ECDSA_C)
124 case MBEDTLS_PK_ECDSA:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100125 return &mbedtls_ecdsa_info;
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200126#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200127 /* MBEDTLS_PK_RSA_ALT omitted on purpose */
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200128 default:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100129 return NULL;
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200130 }
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200131}
132
133/*
Manuel Pégourié-Gonnardab466942013-08-15 11:30:27 +0200134 * Initialise context
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200135 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100136int mbedtls_pk_setup(mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info)
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200137{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100138 PK_VALIDATE_RET(ctx != NULL);
139 if (info == NULL || ctx->pk_info != NULL) {
140 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
141 }
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200142
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100143 if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL) {
144 return MBEDTLS_ERR_PK_ALLOC_FAILED;
145 }
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200146
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200147 ctx->pk_info = info;
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200148
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100149 return 0;
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200150}
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200151
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200152#if defined(MBEDTLS_USE_PSA_CRYPTO)
153/*
154 * Initialise a PSA-wrapping context
155 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100156int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx,
157 const psa_key_id_t key)
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200158{
Manuel Pégourié-Gonnard69baf702018-11-06 09:34:30 +0100159 const mbedtls_pk_info_t * const info = &mbedtls_pk_opaque_info;
Gilles Peskined2d45c12019-05-27 14:53:13 +0200160 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Ronald Croncf56a0a2020-08-04 09:51:30 +0200161 psa_key_id_t *pk_ctx;
Manuel Pégourié-Gonnard920c0632018-10-31 10:57:29 +0100162 psa_key_type_t type;
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200163
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100164 if (ctx == NULL || ctx->pk_info != NULL) {
165 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
166 }
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200167
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100168 if (PSA_SUCCESS != psa_get_key_attributes(key, &attributes)) {
169 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
170 }
171 type = psa_get_key_type(&attributes);
172 psa_reset_key_attributes(&attributes);
Manuel Pégourié-Gonnard920c0632018-10-31 10:57:29 +0100173
174 /* Current implementation of can_do() relies on this. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100175 if (!PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
176 return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
177 }
Manuel Pégourié-Gonnard920c0632018-10-31 10:57:29 +0100178
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100179 if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL) {
180 return MBEDTLS_ERR_PK_ALLOC_FAILED;
181 }
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200182
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200183 ctx->pk_info = info;
184
Ronald Croncf56a0a2020-08-04 09:51:30 +0200185 pk_ctx = (psa_key_id_t *) ctx->pk_ctx;
Manuel Pégourié-Gonnard7b5fe042018-10-31 09:57:45 +0100186 *pk_ctx = key;
187
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100188 return 0;
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200189}
190#endif /* MBEDTLS_USE_PSA_CRYPTO */
191
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200192#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
Manuel Pégourié-Gonnardb4fae572014-01-20 11:22:25 +0100193/*
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200194 * Initialize an RSA-alt context
195 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100196int mbedtls_pk_setup_rsa_alt(mbedtls_pk_context *ctx, void *key,
197 mbedtls_pk_rsa_alt_decrypt_func decrypt_func,
198 mbedtls_pk_rsa_alt_sign_func sign_func,
199 mbedtls_pk_rsa_alt_key_len_func key_len_func)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200200{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200201 mbedtls_rsa_alt_context *rsa_alt;
202 const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200203
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100204 PK_VALIDATE_RET(ctx != NULL);
205 if (ctx->pk_info != NULL) {
206 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
207 }
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200208
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100209 if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL) {
210 return MBEDTLS_ERR_PK_ALLOC_FAILED;
211 }
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200212
213 ctx->pk_info = info;
214
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200215 rsa_alt = (mbedtls_rsa_alt_context *) ctx->pk_ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200216
217 rsa_alt->key = key;
218 rsa_alt->decrypt_func = decrypt_func;
219 rsa_alt->sign_func = sign_func;
220 rsa_alt->key_len_func = key_len_func;
221
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100222 return 0;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200223}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200224#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200225
226/*
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200227 * Tell if a PK can do the operations of the given type
228 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100229int mbedtls_pk_can_do(const mbedtls_pk_context *ctx, mbedtls_pk_type_t type)
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200230{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500231 /* A context with null pk_info is not set up yet and can't do anything.
232 * For backward compatibility, also accept NULL instead of a context
233 * pointer. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100234 if (ctx == NULL || ctx->pk_info == NULL) {
235 return 0;
236 }
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200237
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100238 return ctx->pk_info->can_do(type);
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200239}
240
241/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200242 * Helper for mbedtls_pk_sign and mbedtls_pk_verify
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200243 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100244static inline int pk_hashlen_helper(mbedtls_md_type_t md_alg, size_t *hash_len)
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200245{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200246 const mbedtls_md_info_t *md_info;
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200247
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100248 if (*hash_len != 0 && md_alg == MBEDTLS_MD_NONE) {
249 return 0;
250 }
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200251
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100252 if ((md_info = mbedtls_md_info_from_type(md_alg)) == NULL) {
253 return -1;
254 }
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200255
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100256 if (*hash_len != 0 && *hash_len != mbedtls_md_get_size(md_info)) {
257 return -1;
258 }
Nick Childb6d56932021-05-25 15:31:21 -0400259
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100260 *hash_len = mbedtls_md_get_size(md_info);
261 return 0;
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200262}
263
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200264#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200265/*
266 * Helper to set up a restart context if needed
267 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100268static int pk_restart_setup(mbedtls_pk_restart_ctx *ctx,
269 const mbedtls_pk_info_t *info)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200270{
Manuel Pégourié-Gonnardc8c12b62018-07-02 13:09:39 +0200271 /* Don't do anything if already set up or invalid */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100272 if (ctx == NULL || ctx->pk_info != NULL) {
273 return 0;
274 }
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200275
276 /* Should never happen when we're called */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100277 if (info->rs_alloc_func == NULL || info->rs_free_func == NULL) {
278 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
279 }
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200280
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100281 if ((ctx->rs_ctx = info->rs_alloc_func()) == NULL) {
282 return MBEDTLS_ERR_PK_ALLOC_FAILED;
283 }
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200284
285 ctx->pk_info = info;
286
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100287 return 0;
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200288}
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200289#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200290
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200291/*
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200292 * Verify a signature (restartable)
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200293 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100294int mbedtls_pk_verify_restartable(mbedtls_pk_context *ctx,
295 mbedtls_md_type_t md_alg,
296 const unsigned char *hash, size_t hash_len,
297 const unsigned char *sig, size_t sig_len,
298 mbedtls_pk_restart_ctx *rs_ctx)
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200299{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100300 PK_VALIDATE_RET(ctx != NULL);
301 PK_VALIDATE_RET((md_alg == MBEDTLS_MD_NONE && hash_len == 0) ||
302 hash != NULL);
303 PK_VALIDATE_RET(sig != NULL);
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500304
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100305 if (ctx->pk_info == NULL ||
306 pk_hashlen_helper(md_alg, &hash_len) != 0) {
307 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
308 }
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200309
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200310#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnardd55f7762017-08-18 17:40:15 +0200311 /* optimization: use non-restartable version if restart disabled */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100312 if (rs_ctx != NULL &&
Manuel Pégourié-Gonnardb843b152018-10-16 10:41:31 +0200313 mbedtls_ecp_restart_is_enabled() &&
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100314 ctx->pk_info->verify_rs_func != NULL) {
Janos Follath24eed8d2019-11-22 13:21:35 +0000315 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200316
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100317 if ((ret = pk_restart_setup(rs_ctx, ctx->pk_info)) != 0) {
318 return ret;
319 }
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200320
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100321 ret = ctx->pk_info->verify_rs_func(ctx->pk_ctx,
322 md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx);
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200323
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100324 if (ret != MBEDTLS_ERR_ECP_IN_PROGRESS) {
325 mbedtls_pk_restart_free(rs_ctx);
326 }
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200327
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100328 return ret;
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200329 }
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200330#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200331 (void) rs_ctx;
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200332#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200333
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100334 if (ctx->pk_info->verify_func == NULL) {
335 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
336 }
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200337
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100338 return ctx->pk_info->verify_func(ctx->pk_ctx, md_alg, hash, hash_len,
339 sig, sig_len);
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200340}
341
342/*
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200343 * Verify a signature
344 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100345int mbedtls_pk_verify(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é-Gonnard82cb27b2017-05-03 10:59:45 +0200348{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100349 return mbedtls_pk_verify_restartable(ctx, md_alg, hash, hash_len,
350 sig, sig_len, NULL);
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200351}
352
353/*
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200354 * Verify a signature with options
355 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100356int mbedtls_pk_verify_ext(mbedtls_pk_type_t type, const void *options,
357 mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
358 const unsigned char *hash, size_t hash_len,
359 const unsigned char *sig, size_t sig_len)
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200360{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100361 PK_VALIDATE_RET(ctx != NULL);
362 PK_VALIDATE_RET((md_alg == MBEDTLS_MD_NONE && hash_len == 0) ||
363 hash != NULL);
364 PK_VALIDATE_RET(sig != NULL);
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500365
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100366 if (ctx->pk_info == NULL) {
367 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
368 }
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200369
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100370 if (!mbedtls_pk_can_do(ctx, type)) {
371 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
372 }
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200373
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100374 if (type == MBEDTLS_PK_RSASSA_PSS) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200375#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
Janos Follath24eed8d2019-11-22 13:21:35 +0000376 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200377 const mbedtls_pk_rsassa_pss_options *pss_opts;
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200378
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100379#if SIZE_MAX > UINT_MAX
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100380 if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) {
381 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
382 }
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100383#endif /* SIZE_MAX > UINT_MAX */
Andres AG72849872017-01-19 11:24:33 +0000384
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100385 if (options == NULL) {
386 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
387 }
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200388
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200389 pss_opts = (const mbedtls_pk_rsassa_pss_options *) options;
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200390
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100391 if (sig_len < mbedtls_pk_get_len(ctx)) {
392 return MBEDTLS_ERR_RSA_VERIFY_FAILED;
393 }
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200394
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100395 ret = mbedtls_rsa_rsassa_pss_verify_ext(mbedtls_pk_rsa(*ctx),
396 NULL, NULL, MBEDTLS_RSA_PUBLIC,
397 md_alg, (unsigned int) hash_len, hash,
398 pss_opts->mgf1_hash_id,
399 pss_opts->expected_salt_len,
400 sig);
401 if (ret != 0) {
402 return ret;
403 }
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200404
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100405 if (sig_len > mbedtls_pk_get_len(ctx)) {
406 return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
407 }
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200408
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100409 return 0;
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200410#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100411 return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
Andres AG72849872017-01-19 11:24:33 +0000412#endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200413 }
414
415 /* General case: no options */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100416 if (options != NULL) {
417 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
418 }
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200419
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100420 return mbedtls_pk_verify(ctx, md_alg, hash, hash_len, sig, sig_len);
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200421}
422
423/*
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200424 * Make a signature (restartable)
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200425 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100426int mbedtls_pk_sign_restartable(mbedtls_pk_context *ctx,
427 mbedtls_md_type_t md_alg,
428 const unsigned char *hash, size_t hash_len,
429 unsigned char *sig, size_t *sig_len,
430 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
431 mbedtls_pk_restart_ctx *rs_ctx)
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200432{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100433 PK_VALIDATE_RET(ctx != NULL);
434 PK_VALIDATE_RET((md_alg == MBEDTLS_MD_NONE && hash_len == 0) ||
435 hash != NULL);
436 PK_VALIDATE_RET(sig != NULL);
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500437
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100438 if (ctx->pk_info == NULL ||
439 pk_hashlen_helper(md_alg, &hash_len) != 0) {
440 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
441 }
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200442
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200443#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnardd55f7762017-08-18 17:40:15 +0200444 /* optimization: use non-restartable version if restart disabled */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100445 if (rs_ctx != NULL &&
Manuel Pégourié-Gonnardb843b152018-10-16 10:41:31 +0200446 mbedtls_ecp_restart_is_enabled() &&
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100447 ctx->pk_info->sign_rs_func != NULL) {
Janos Follath24eed8d2019-11-22 13:21:35 +0000448 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200449
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100450 if ((ret = pk_restart_setup(rs_ctx, ctx->pk_info)) != 0) {
451 return ret;
452 }
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200453
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100454 ret = ctx->pk_info->sign_rs_func(ctx->pk_ctx, md_alg,
455 hash, hash_len, sig, sig_len, f_rng, p_rng,
456 rs_ctx->rs_ctx);
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200457
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100458 if (ret != MBEDTLS_ERR_ECP_IN_PROGRESS) {
459 mbedtls_pk_restart_free(rs_ctx);
460 }
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200461
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100462 return ret;
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200463 }
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200464#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200465 (void) rs_ctx;
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200466#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200467
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100468 if (ctx->pk_info->sign_func == NULL) {
469 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
470 }
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200471
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100472 return ctx->pk_info->sign_func(ctx->pk_ctx, md_alg, hash, hash_len,
473 sig, sig_len, f_rng, p_rng);
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200474}
475
476/*
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200477 * Make a signature
478 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100479int mbedtls_pk_sign(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
480 const unsigned char *hash, size_t hash_len,
481 unsigned char *sig, size_t *sig_len,
482 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200483{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100484 return mbedtls_pk_sign_restartable(ctx, md_alg, hash, hash_len,
485 sig, sig_len, f_rng, p_rng, NULL);
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200486}
487
488/*
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200489 * Decrypt message
490 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100491int mbedtls_pk_decrypt(mbedtls_pk_context *ctx,
492 const unsigned char *input, size_t ilen,
493 unsigned char *output, size_t *olen, size_t osize,
494 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200495{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100496 PK_VALIDATE_RET(ctx != NULL);
497 PK_VALIDATE_RET(input != NULL || ilen == 0);
498 PK_VALIDATE_RET(output != NULL || osize == 0);
499 PK_VALIDATE_RET(olen != NULL);
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500500
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100501 if (ctx->pk_info == NULL) {
502 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
503 }
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200504
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100505 if (ctx->pk_info->decrypt_func == NULL) {
506 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
507 }
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200508
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100509 return ctx->pk_info->decrypt_func(ctx->pk_ctx, input, ilen,
510 output, olen, osize, f_rng, p_rng);
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200511}
512
513/*
514 * Encrypt message
515 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100516int mbedtls_pk_encrypt(mbedtls_pk_context *ctx,
517 const unsigned char *input, size_t ilen,
518 unsigned char *output, size_t *olen, size_t osize,
519 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200520{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100521 PK_VALIDATE_RET(ctx != NULL);
522 PK_VALIDATE_RET(input != NULL || ilen == 0);
523 PK_VALIDATE_RET(output != NULL || osize == 0);
524 PK_VALIDATE_RET(olen != NULL);
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500525
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100526 if (ctx->pk_info == NULL) {
527 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
528 }
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200529
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100530 if (ctx->pk_info->encrypt_func == NULL) {
531 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
532 }
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200533
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100534 return ctx->pk_info->encrypt_func(ctx->pk_ctx, input, ilen,
535 output, olen, osize, f_rng, p_rng);
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200536}
537
538/*
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100539 * Check public-private key pair
540 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100541int mbedtls_pk_check_pair(const mbedtls_pk_context *pub, const mbedtls_pk_context *prv)
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100542{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100543 PK_VALIDATE_RET(pub != NULL);
544 PK_VALIDATE_RET(prv != NULL);
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500545
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100546 if (pub->pk_info == NULL ||
547 prv->pk_info == NULL) {
548 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100549 }
550
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100551 if (prv->pk_info->check_pair_func == NULL) {
552 return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100553 }
554
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100555 if (prv->pk_info->type == MBEDTLS_PK_RSA_ALT) {
556 if (pub->pk_info->type != MBEDTLS_PK_RSA) {
557 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
558 }
559 } else {
560 if (pub->pk_info != prv->pk_info) {
561 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
562 }
563 }
564
565 return prv->pk_info->check_pair_func(pub->pk_ctx, prv->pk_ctx);
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100566}
567
568/*
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200569 * Get key size in bits
570 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100571size_t mbedtls_pk_get_bitlen(const mbedtls_pk_context *ctx)
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200572{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500573 /* For backward compatibility, accept NULL or a context that
574 * isn't set up yet, and return a fake value that should be safe. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100575 if (ctx == NULL || ctx->pk_info == NULL) {
576 return 0;
577 }
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200578
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100579 return ctx->pk_info->get_bitlen(ctx->pk_ctx);
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200580}
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200581
582/*
583 * Export debug information
584 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100585int mbedtls_pk_debug(const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items)
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200586{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100587 PK_VALIDATE_RET(ctx != NULL);
588 if (ctx->pk_info == NULL) {
589 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
590 }
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200591
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100592 if (ctx->pk_info->debug_func == NULL) {
593 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
594 }
Manuel Pégourié-Gonnard01488752014-04-03 22:09:18 +0200595
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100596 ctx->pk_info->debug_func(ctx->pk_ctx, items);
597 return 0;
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200598}
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200599
600/*
601 * Access the PK type name
602 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100603const char *mbedtls_pk_get_name(const mbedtls_pk_context *ctx)
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200604{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100605 if (ctx == NULL || ctx->pk_info == NULL) {
606 return "invalid PK";
607 }
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200608
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100609 return ctx->pk_info->name;
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200610}
Manuel Pégourié-Gonnardc40b4c32013-08-22 13:29:31 +0200611
Manuel Pégourié-Gonnard8053da42013-09-11 22:28:30 +0200612/*
613 * Access the PK type
614 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100615mbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx)
Manuel Pégourié-Gonnard8053da42013-09-11 22:28:30 +0200616{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100617 if (ctx == NULL || ctx->pk_info == NULL) {
618 return MBEDTLS_PK_NONE;
619 }
Manuel Pégourié-Gonnard8053da42013-09-11 22:28:30 +0200620
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100621 return ctx->pk_info->type;
Manuel Pégourié-Gonnard8053da42013-09-11 22:28:30 +0200622}
623
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100624#if defined(MBEDTLS_USE_PSA_CRYPTO)
625/*
626 * Load the key to a PSA key slot,
627 * then turn the PK context into a wrapper for that key slot.
628 *
629 * Currently only works for EC private keys.
630 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100631int mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk,
632 psa_key_id_t *key,
633 psa_algorithm_t hash_alg)
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100634{
635#if !defined(MBEDTLS_ECP_C)
John Durkopf35069a2020-08-17 22:05:14 -0700636 ((void) pk);
Ronald Croncf56a0a2020-08-04 09:51:30 +0200637 ((void) key);
John Durkopf35069a2020-08-17 22:05:14 -0700638 ((void) hash_alg);
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100639 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100640#else
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100641 const mbedtls_ecp_keypair *ec;
642 unsigned char d[MBEDTLS_ECP_MAX_BYTES];
643 size_t d_len;
Paul Elliott8ff510a2020-06-02 17:19:28 +0100644 psa_ecc_family_t curve_id;
Gilles Peskined2d45c12019-05-27 14:53:13 +0200645 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100646 psa_key_type_t key_type;
Gilles Peskine4080c912019-12-18 20:43:03 +0100647 size_t bits;
Janos Follath24eed8d2019-11-22 13:21:35 +0000648 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100649
650 /* export the private key material in the format PSA wants */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100651 if (mbedtls_pk_get_type(pk) != MBEDTLS_PK_ECKEY) {
652 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
653 }
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100654
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100655 ec = mbedtls_pk_ec(*pk);
656 d_len = (ec->grp.nbits + 7) / 8;
657 if ((ret = mbedtls_mpi_write_binary(&ec->d, d, d_len)) != 0) {
658 return ret;
659 }
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100660
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100661 curve_id = mbedtls_ecc_group_to_psa(ec->grp.id, &bits);
662 key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(curve_id);
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100663
Gilles Peskined2d45c12019-05-27 14:53:13 +0200664 /* prepare the key attributes */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100665 psa_set_key_type(&attributes, key_type);
666 psa_set_key_bits(&attributes, bits);
667 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
668 psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(hash_alg));
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100669
Gilles Peskined2d45c12019-05-27 14:53:13 +0200670 /* import private key into PSA */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100671 if (PSA_SUCCESS != psa_import_key(&attributes, d, d_len, key)) {
672 return MBEDTLS_ERR_PK_HW_ACCEL_FAILED;
673 }
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100674
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100675 /* make PK context wrap the key slot */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100676 mbedtls_pk_free(pk);
677 mbedtls_pk_init(pk);
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100678
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100679 return mbedtls_pk_setup_opaque(pk, *key);
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100680#endif /* MBEDTLS_ECP_C */
681}
682#endif /* MBEDTLS_USE_PSA_CRYPTO */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200683#endif /* MBEDTLS_PK_C */