blob: 918665157e26b494893b7da2d9a89586521eef29 [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)
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020023# include "mbedtls/pk.h"
24# include "pk_wrap.h"
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020025
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020026# include "mbedtls/platform_util.h"
27# include "mbedtls/error.h"
Andres AG72849872017-01-19 11:24:33 +000028
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020029# if defined(MBEDTLS_RSA_C)
30# include "mbedtls/rsa.h"
31# endif
32# if defined(MBEDTLS_ECP_C)
33# include "mbedtls/ecp.h"
34# endif
35# if defined(MBEDTLS_ECDSA_C)
36# include "mbedtls/ecdsa.h"
37# endif
Manuel Pégourié-Gonnard81c313c2013-07-09 10:35:54 +020038
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020039# if defined(MBEDTLS_USE_PSA_CRYPTO)
40# include "mbedtls/psa_util.h"
41# endif
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +010042
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020043# include <limits.h>
44# 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 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020047# define PK_VALIDATE_RET(cond) \
48 MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA)
49# define PK_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE(cond)
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050050
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020051/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020052 * Initialise a mbedtls_pk_context
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020053 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020054void mbedtls_pk_init(mbedtls_pk_context *ctx)
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020055{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020056 PK_VALIDATE(ctx != NULL);
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020057
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +020058 ctx->pk_info = NULL;
59 ctx->pk_ctx = NULL;
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020060}
61
62/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020063 * Free (the components of) a mbedtls_pk_context
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020064 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020065void mbedtls_pk_free(mbedtls_pk_context *ctx)
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020066{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020067 if (ctx == NULL)
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020068 return;
69
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020070 if (ctx->pk_info != NULL)
71 ctx->pk_info->ctx_free_func(ctx->pk_ctx);
Manuel Pégourié-Gonnard1f73a652013-07-09 10:26:41 +020072
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020073 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_pk_context));
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +020074}
75
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020076# if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020077/*
78 * Initialize a restart context
79 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020080void mbedtls_pk_restart_init(mbedtls_pk_restart_ctx *ctx)
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020081{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020082 PK_VALIDATE(ctx != NULL);
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +020083 ctx->pk_info = NULL;
84 ctx->rs_ctx = NULL;
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020085}
86
87/*
88 * Free the components of a restart context
89 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020090void mbedtls_pk_restart_free(mbedtls_pk_restart_ctx *ctx)
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020091{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020092 if (ctx == NULL || ctx->pk_info == NULL ||
93 ctx->pk_info->rs_free_func == NULL) {
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020094 return;
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +020095 }
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +020096
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020097 ctx->pk_info->rs_free_func(ctx->rs_ctx);
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +020098
99 ctx->pk_info = NULL;
100 ctx->rs_ctx = NULL;
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +0200101}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200102# endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +0200103
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200104/*
105 * Get pk_info structure from type
106 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200107const mbedtls_pk_info_t *mbedtls_pk_info_from_type(mbedtls_pk_type_t pk_type)
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200108{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200109 switch (pk_type) {
110# if defined(MBEDTLS_RSA_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200111 case MBEDTLS_PK_RSA:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200112 return &mbedtls_rsa_info;
113# endif
114# if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200115 case MBEDTLS_PK_ECKEY:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200116 return &mbedtls_eckey_info;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200117 case MBEDTLS_PK_ECKEY_DH:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200118 return &mbedtls_eckeydh_info;
119# endif
120# if defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200121 case MBEDTLS_PK_ECDSA:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200122 return &mbedtls_ecdsa_info;
123# endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200124 /* MBEDTLS_PK_RSA_ALT omitted on purpose */
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200125 default:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200126 return NULL;
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200127 }
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200128}
129
130/*
Manuel Pégourié-Gonnardab466942013-08-15 11:30:27 +0200131 * Initialise context
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200132 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200133int mbedtls_pk_setup(mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info)
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200134{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200135 PK_VALIDATE_RET(ctx != NULL);
136 if (info == NULL || ctx->pk_info != NULL)
137 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200138
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200139 if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL)
140 return MBEDTLS_ERR_PK_ALLOC_FAILED;
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200141
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200142 ctx->pk_info = info;
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200143
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200144 return 0;
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200145}
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200146
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200147# if defined(MBEDTLS_USE_PSA_CRYPTO)
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200148/*
149 * Initialise a PSA-wrapping context
150 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200151int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx, const psa_key_id_t key)
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200152{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200153 const mbedtls_pk_info_t *const info = &mbedtls_pk_opaque_info;
Gilles Peskined2d45c12019-05-27 14:53:13 +0200154 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Ronald Croncf56a0a2020-08-04 09:51:30 +0200155 psa_key_id_t *pk_ctx;
Manuel Pégourié-Gonnard920c0632018-10-31 10:57:29 +0100156 psa_key_type_t type;
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200157
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200158 if (ctx == NULL || ctx->pk_info != NULL)
159 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200160
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200161 if (PSA_SUCCESS != psa_get_key_attributes(key, &attributes))
162 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
163 type = psa_get_key_type(&attributes);
164 psa_reset_key_attributes(&attributes);
Manuel Pégourié-Gonnard920c0632018-10-31 10:57:29 +0100165
166 /* Current implementation of can_do() relies on this. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200167 if (!PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type))
168 return (MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE);
Manuel Pégourié-Gonnard920c0632018-10-31 10:57:29 +0100169
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200170 if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL)
171 return MBEDTLS_ERR_PK_ALLOC_FAILED;
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200172
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200173 ctx->pk_info = info;
174
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200175 pk_ctx = (psa_key_id_t *)ctx->pk_ctx;
Manuel Pégourié-Gonnard7b5fe042018-10-31 09:57:45 +0100176 *pk_ctx = key;
177
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200178 return 0;
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200179}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200180# endif /* MBEDTLS_USE_PSA_CRYPTO */
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200181
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200182# if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
Manuel Pégourié-Gonnardb4fae572014-01-20 11:22:25 +0100183/*
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200184 * Initialize an RSA-alt context
185 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200186int mbedtls_pk_setup_rsa_alt(mbedtls_pk_context *ctx,
187 void *key,
188 mbedtls_pk_rsa_alt_decrypt_func decrypt_func,
189 mbedtls_pk_rsa_alt_sign_func sign_func,
190 mbedtls_pk_rsa_alt_key_len_func key_len_func)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200191{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200192 mbedtls_rsa_alt_context *rsa_alt;
193 const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200194
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200195 PK_VALIDATE_RET(ctx != NULL);
196 if (ctx->pk_info != NULL)
197 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200198
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200199 if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL)
200 return MBEDTLS_ERR_PK_ALLOC_FAILED;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200201
202 ctx->pk_info = info;
203
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200204 rsa_alt = (mbedtls_rsa_alt_context *)ctx->pk_ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200205
206 rsa_alt->key = key;
207 rsa_alt->decrypt_func = decrypt_func;
208 rsa_alt->sign_func = sign_func;
209 rsa_alt->key_len_func = key_len_func;
210
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200211 return 0;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200212}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200213# endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200214
215/*
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200216 * Tell if a PK can do the operations of the given type
217 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200218int mbedtls_pk_can_do(const mbedtls_pk_context *ctx, mbedtls_pk_type_t type)
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200219{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500220 /* A context with null pk_info is not set up yet and can't do anything.
221 * For backward compatibility, also accept NULL instead of a context
222 * pointer. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200223 if (ctx == NULL || ctx->pk_info == NULL)
224 return 0;
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200225
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200226 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 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200232static 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
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200236 if (*hash_len != 0)
237 return 0;
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200238
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200239 if ((md_info = mbedtls_md_info_from_type(md_alg)) == NULL)
240 return -1;
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200241
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200242 *hash_len = mbedtls_md_get_size(md_info);
243 return 0;
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200244}
245
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200246# if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200247/*
248 * Helper to set up a restart context if needed
249 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200250static int pk_restart_setup(mbedtls_pk_restart_ctx *ctx,
251 const mbedtls_pk_info_t *info)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200252{
Manuel Pégourié-Gonnardc8c12b62018-07-02 13:09:39 +0200253 /* Don't do anything if already set up or invalid */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200254 if (ctx == NULL || ctx->pk_info != NULL)
255 return 0;
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200256
257 /* Should never happen when we're called */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200258 if (info->rs_alloc_func == NULL || info->rs_free_func == NULL)
259 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200260
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200261 if ((ctx->rs_ctx = info->rs_alloc_func()) == NULL)
262 return MBEDTLS_ERR_PK_ALLOC_FAILED;
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200263
264 ctx->pk_info = info;
265
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200266 return 0;
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200267}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200268# endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200269
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200270/*
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200271 * Verify a signature (restartable)
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200272 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200273int mbedtls_pk_verify_restartable(mbedtls_pk_context *ctx,
274 mbedtls_md_type_t md_alg,
275 const unsigned char *hash,
276 size_t hash_len,
277 const unsigned char *sig,
278 size_t sig_len,
279 mbedtls_pk_restart_ctx *rs_ctx)
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200280{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200281 PK_VALIDATE_RET(ctx != NULL);
282 PK_VALIDATE_RET((md_alg == MBEDTLS_MD_NONE && hash_len == 0) ||
283 hash != NULL);
284 PK_VALIDATE_RET(sig != NULL);
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500285
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200286 if (ctx->pk_info == NULL || pk_hashlen_helper(md_alg, &hash_len) != 0)
287 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200288
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200289# if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnardd55f7762017-08-18 17:40:15 +0200290 /* optimization: use non-restartable version if restart disabled */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200291 if (rs_ctx != NULL && mbedtls_ecp_restart_is_enabled() &&
292 ctx->pk_info->verify_rs_func != NULL) {
Janos Follath24eed8d2019-11-22 13:21:35 +0000293 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200294
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200295 if ((ret = pk_restart_setup(rs_ctx, ctx->pk_info)) != 0)
296 return ret;
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200297
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200298 ret = ctx->pk_info->verify_rs_func(ctx->pk_ctx, md_alg, hash, hash_len,
299 sig, sig_len, rs_ctx->rs_ctx);
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200300
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200301 if (ret != MBEDTLS_ERR_ECP_IN_PROGRESS)
302 mbedtls_pk_restart_free(rs_ctx);
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200303
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200304 return ret;
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200305 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200306# else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
307 (void)rs_ctx;
308# endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200309
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200310 if (ctx->pk_info->verify_func == NULL)
311 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200312
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200313 return (ctx->pk_info->verify_func(ctx->pk_ctx, md_alg, hash, hash_len, sig,
314 sig_len));
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200315}
316
317/*
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200318 * Verify a signature
319 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200320int mbedtls_pk_verify(mbedtls_pk_context *ctx,
321 mbedtls_md_type_t md_alg,
322 const unsigned char *hash,
323 size_t hash_len,
324 const unsigned char *sig,
325 size_t sig_len)
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200326{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200327 return (mbedtls_pk_verify_restartable(ctx, md_alg, hash, hash_len, sig,
328 sig_len, NULL));
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200329}
330
331/*
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200332 * Verify a signature with options
333 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200334int mbedtls_pk_verify_ext(mbedtls_pk_type_t type,
335 const void *options,
336 mbedtls_pk_context *ctx,
337 mbedtls_md_type_t md_alg,
338 const unsigned char *hash,
339 size_t hash_len,
340 const unsigned char *sig,
341 size_t sig_len)
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200342{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200343 PK_VALIDATE_RET(ctx != NULL);
344 PK_VALIDATE_RET((md_alg == MBEDTLS_MD_NONE && hash_len == 0) ||
345 hash != NULL);
346 PK_VALIDATE_RET(sig != NULL);
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500347
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200348 if (ctx->pk_info == NULL)
349 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200350
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200351 if (!mbedtls_pk_can_do(ctx, type))
352 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200353
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200354 if (type == MBEDTLS_PK_RSASSA_PSS) {
355# if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
Janos Follath24eed8d2019-11-22 13:21:35 +0000356 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200357 const mbedtls_pk_rsassa_pss_options *pss_opts;
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200358
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200359# if SIZE_MAX > UINT_MAX
360 if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len)
361 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
362# endif /* SIZE_MAX > UINT_MAX */
Andres AG72849872017-01-19 11:24:33 +0000363
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200364 if (options == NULL)
365 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200366
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200367 pss_opts = (const mbedtls_pk_rsassa_pss_options *)options;
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200368
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200369 if (sig_len < mbedtls_pk_get_len(ctx))
370 return MBEDTLS_ERR_RSA_VERIFY_FAILED;
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200371
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200372 ret = mbedtls_rsa_rsassa_pss_verify_ext(
373 mbedtls_pk_rsa(*ctx), md_alg, (unsigned int)hash_len, hash,
374 pss_opts->mgf1_hash_id, pss_opts->expected_salt_len, sig);
375 if (ret != 0)
376 return ret;
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200377
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200378 if (sig_len > mbedtls_pk_get_len(ctx))
379 return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200380
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200381 return 0;
382# else
383 return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
384# endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200385 }
386
387 /* General case: no options */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200388 if (options != NULL)
389 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200390
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200391 return mbedtls_pk_verify(ctx, md_alg, hash, hash_len, sig, sig_len);
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200392}
393
394/*
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200395 * Make a signature (restartable)
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200396 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200397int mbedtls_pk_sign_restartable(mbedtls_pk_context *ctx,
398 mbedtls_md_type_t md_alg,
399 const unsigned char *hash,
400 size_t hash_len,
401 unsigned char *sig,
402 size_t sig_size,
403 size_t *sig_len,
404 int (*f_rng)(void *, unsigned char *, size_t),
405 void *p_rng,
406 mbedtls_pk_restart_ctx *rs_ctx)
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200407{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200408 PK_VALIDATE_RET(ctx != NULL);
409 PK_VALIDATE_RET((md_alg == MBEDTLS_MD_NONE && hash_len == 0) ||
410 hash != NULL);
411 PK_VALIDATE_RET(sig != NULL);
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500412
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200413 if (ctx->pk_info == NULL || pk_hashlen_helper(md_alg, &hash_len) != 0)
414 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200415
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200416# if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnardd55f7762017-08-18 17:40:15 +0200417 /* optimization: use non-restartable version if restart disabled */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200418 if (rs_ctx != NULL && mbedtls_ecp_restart_is_enabled() &&
419 ctx->pk_info->sign_rs_func != NULL) {
Janos Follath24eed8d2019-11-22 13:21:35 +0000420 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200421
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200422 if ((ret = pk_restart_setup(rs_ctx, ctx->pk_info)) != 0)
423 return ret;
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200424
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200425 ret = ctx->pk_info->sign_rs_func(ctx->pk_ctx, md_alg, hash, hash_len,
426 sig, sig_size, sig_len, f_rng, p_rng,
427 rs_ctx->rs_ctx);
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200428
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200429 if (ret != MBEDTLS_ERR_ECP_IN_PROGRESS)
430 mbedtls_pk_restart_free(rs_ctx);
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200431
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200432 return ret;
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200433 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200434# else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
435 (void)rs_ctx;
436# endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200437
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200438 if (ctx->pk_info->sign_func == NULL)
439 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200440
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200441 return (ctx->pk_info->sign_func(ctx->pk_ctx, md_alg, hash, hash_len, sig,
442 sig_size, sig_len, f_rng, p_rng));
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200443}
444
445/*
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200446 * Make a signature
447 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200448int mbedtls_pk_sign(mbedtls_pk_context *ctx,
449 mbedtls_md_type_t md_alg,
450 const unsigned char *hash,
451 size_t hash_len,
452 unsigned char *sig,
453 size_t sig_size,
454 size_t *sig_len,
455 int (*f_rng)(void *, unsigned char *, size_t),
456 void *p_rng)
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200457{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200458 return (mbedtls_pk_sign_restartable(ctx, md_alg, hash, hash_len, sig,
459 sig_size, sig_len, f_rng, p_rng, NULL));
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200460}
461
462/*
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200463 * Decrypt message
464 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200465int mbedtls_pk_decrypt(mbedtls_pk_context *ctx,
466 const unsigned char *input,
467 size_t ilen,
468 unsigned char *output,
469 size_t *olen,
470 size_t osize,
471 int (*f_rng)(void *, unsigned char *, size_t),
472 void *p_rng)
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200473{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200474 PK_VALIDATE_RET(ctx != NULL);
475 PK_VALIDATE_RET(input != NULL || ilen == 0);
476 PK_VALIDATE_RET(output != NULL || osize == 0);
477 PK_VALIDATE_RET(olen != NULL);
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500478
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200479 if (ctx->pk_info == NULL)
480 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200481
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200482 if (ctx->pk_info->decrypt_func == NULL)
483 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200484
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200485 return (ctx->pk_info->decrypt_func(ctx->pk_ctx, input, ilen, output, olen,
486 osize, f_rng, p_rng));
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200487}
488
489/*
490 * Encrypt message
491 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200492int mbedtls_pk_encrypt(mbedtls_pk_context *ctx,
493 const unsigned char *input,
494 size_t ilen,
495 unsigned char *output,
496 size_t *olen,
497 size_t osize,
498 int (*f_rng)(void *, unsigned char *, size_t),
499 void *p_rng)
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200500{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200501 PK_VALIDATE_RET(ctx != NULL);
502 PK_VALIDATE_RET(input != NULL || ilen == 0);
503 PK_VALIDATE_RET(output != NULL || osize == 0);
504 PK_VALIDATE_RET(olen != NULL);
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500505
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200506 if (ctx->pk_info == NULL)
507 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200508
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200509 if (ctx->pk_info->encrypt_func == NULL)
510 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200511
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200512 return (ctx->pk_info->encrypt_func(ctx->pk_ctx, input, ilen, output, olen,
513 osize, f_rng, p_rng));
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200514}
515
516/*
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100517 * Check public-private key pair
518 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200519int mbedtls_pk_check_pair(const mbedtls_pk_context *pub,
520 const mbedtls_pk_context *prv,
521 int (*f_rng)(void *, unsigned char *, size_t),
522 void *p_rng)
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100523{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200524 PK_VALIDATE_RET(pub != NULL);
525 PK_VALIDATE_RET(prv != NULL);
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500526
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200527 if (pub->pk_info == NULL || prv->pk_info == NULL) {
528 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100529 }
530
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200531 if (f_rng == NULL)
532 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard39be1412021-06-15 11:29:26 +0200533
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200534 if (prv->pk_info->check_pair_func == NULL)
535 return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
Manuel Pégourié-Gonnardeaeb7b22018-10-24 12:37:44 +0200536
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200537 if (prv->pk_info->type == MBEDTLS_PK_RSA_ALT) {
538 if (pub->pk_info->type != MBEDTLS_PK_RSA)
539 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
540 } else {
541 if (pub->pk_info != prv->pk_info)
542 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100543 }
544
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200545 return prv->pk_info->check_pair_func(pub->pk_ctx, prv->pk_ctx, f_rng,
546 p_rng);
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100547}
548
549/*
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200550 * Get key size in bits
551 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200552size_t mbedtls_pk_get_bitlen(const mbedtls_pk_context *ctx)
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200553{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500554 /* For backward compatibility, accept NULL or a context that
555 * isn't set up yet, and return a fake value that should be safe. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200556 if (ctx == NULL || ctx->pk_info == NULL)
557 return 0;
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200558
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200559 return ctx->pk_info->get_bitlen(ctx->pk_ctx);
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200560}
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200561
562/*
563 * Export debug information
564 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200565int mbedtls_pk_debug(const mbedtls_pk_context *ctx,
566 mbedtls_pk_debug_item *items)
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200567{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200568 PK_VALIDATE_RET(ctx != NULL);
569 if (ctx->pk_info == NULL)
570 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200571
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200572 if (ctx->pk_info->debug_func == NULL)
573 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
Manuel Pégourié-Gonnard01488752014-04-03 22:09:18 +0200574
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200575 ctx->pk_info->debug_func(ctx->pk_ctx, items);
576 return 0;
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200577}
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200578
579/*
580 * Access the PK type name
581 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200582const char *mbedtls_pk_get_name(const mbedtls_pk_context *ctx)
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200583{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200584 if (ctx == NULL || ctx->pk_info == NULL)
585 return "invalid PK";
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200586
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200587 return ctx->pk_info->name;
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200588}
Manuel Pégourié-Gonnardc40b4c32013-08-22 13:29:31 +0200589
Manuel Pégourié-Gonnard8053da42013-09-11 22:28:30 +0200590/*
591 * Access the PK type
592 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200593mbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx)
Manuel Pégourié-Gonnard8053da42013-09-11 22:28:30 +0200594{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200595 if (ctx == NULL || ctx->pk_info == NULL)
596 return MBEDTLS_PK_NONE;
Manuel Pégourié-Gonnard8053da42013-09-11 22:28:30 +0200597
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200598 return ctx->pk_info->type;
Manuel Pégourié-Gonnard8053da42013-09-11 22:28:30 +0200599}
600
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200601# if defined(MBEDTLS_USE_PSA_CRYPTO)
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100602/*
603 * Load the key to a PSA key slot,
604 * then turn the PK context into a wrapper for that key slot.
605 *
606 * Currently only works for EC private keys.
607 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200608int mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk,
609 psa_key_id_t *key,
610 psa_algorithm_t hash_alg)
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100611{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200612# if !defined(MBEDTLS_ECP_C)
613 ((void)pk);
614 ((void)key);
615 ((void)hash_alg);
616 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
617# else
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100618 const mbedtls_ecp_keypair *ec;
619 unsigned char d[MBEDTLS_ECP_MAX_BYTES];
620 size_t d_len;
Paul Elliott8ff510a2020-06-02 17:19:28 +0100621 psa_ecc_family_t curve_id;
Gilles Peskined2d45c12019-05-27 14:53:13 +0200622 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100623 psa_key_type_t key_type;
Gilles Peskine4080c912019-12-18 20:43:03 +0100624 size_t bits;
Janos Follath24eed8d2019-11-22 13:21:35 +0000625 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100626
627 /* export the private key material in the format PSA wants */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200628 if (mbedtls_pk_get_type(pk) != MBEDTLS_PK_ECKEY)
629 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100630
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200631 ec = mbedtls_pk_ec(*pk);
632 d_len = (ec->grp.nbits + 7) / 8;
633 if ((ret = mbedtls_mpi_write_binary(&ec->d, d, d_len)) != 0)
634 return ret;
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100635
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200636 curve_id = mbedtls_ecc_group_to_psa(ec->grp.id, &bits);
637 key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(curve_id);
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100638
Gilles Peskined2d45c12019-05-27 14:53:13 +0200639 /* prepare the key attributes */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200640 psa_set_key_type(&attributes, key_type);
641 psa_set_key_bits(&attributes, bits);
642 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
643 psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(hash_alg));
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100644
Gilles Peskined2d45c12019-05-27 14:53:13 +0200645 /* import private key into PSA */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200646 if (PSA_SUCCESS != psa_import_key(&attributes, d, d_len, key))
647 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100648
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100649 /* make PK context wrap the key slot */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200650 mbedtls_pk_free(pk);
651 mbedtls_pk_init(pk);
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100652
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200653 return mbedtls_pk_setup_opaque(pk, *key);
654# endif /* MBEDTLS_ECP_C */
Manuel Pégourié-Gonnard347a00e2018-11-19 12:25:37 +0100655}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200656# endif /* MBEDTLS_USE_PSA_CRYPTO */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200657#endif /* MBEDTLS_PK_C */