blob: 14c6d3f99cdbb9a6b5ce95c383d42d13fae653d4 [file] [log] [blame]
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +02001/*
2 * Public Key abstraction layer: wrapper functions
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é-Gonnardd73b3c12013-08-12 17:06:05 +02006 */
7
Gilles Peskinedb09ef62020-06-03 01:43:33 +02008#include "common.h"
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +02009
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020010#if defined(MBEDTLS_PK_C)
Manuel Pégourié-Gonnard50518f42015-05-26 11:04:15 +020011#include "mbedtls/pk_internal.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000012#include "mbedtls/error.h"
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020013
Manuel Pégourié-Gonnarde511ffc2013-08-22 17:33:21 +020014/* Even if RSA not activated, for the sake of RSA-alt */
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000015#include "mbedtls/rsa.h"
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020016
Rich Evans00ab4702015-02-06 13:43:58 +000017#include <string.h>
18
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020019#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000020#include "mbedtls/ecp.h"
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020021#endif
22
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é-Gonnardd73b3c12013-08-12 17:06:05 +020025#endif
26
Manuel Pégourié-Gonnard36867712018-10-31 16:22:49 +010027#if defined(MBEDTLS_USE_PSA_CRYPTO)
28#include "mbedtls/asn1write.h"
29#endif
30
Andres Amaya Garciae32df082017-10-25 09:37:04 +010031#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050032#include "mbedtls/platform_util.h"
Andres Amaya Garciae32df082017-10-25 09:37:04 +010033#endif
34
Manuel Pégourié-Gonnard36867712018-10-31 16:22:49 +010035#if defined(MBEDTLS_USE_PSA_CRYPTO)
Andrzej Kurek8b036a62018-10-31 05:16:46 -040036#include "psa/crypto.h"
Manuel Pégourié-Gonnard36867712018-10-31 16:22:49 +010037#include "mbedtls/psa_util.h"
Andrzej Kurek8b036a62018-10-31 05:16:46 -040038#include "mbedtls/asn1.h"
Manuel Pégourié-Gonnard36867712018-10-31 16:22:49 +010039#endif
40
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000041#include "mbedtls/platform.h"
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +020042
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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020046#if defined(MBEDTLS_RSA_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010047static int rsa_can_do(mbedtls_pk_type_t type)
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +020048{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010049 return type == MBEDTLS_PK_RSA ||
50 type == MBEDTLS_PK_RSASSA_PSS;
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +020051}
52
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010053static size_t rsa_get_bitlen(const void *ctx)
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +020054{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010055 const mbedtls_rsa_context *rsa = (const mbedtls_rsa_context *) ctx;
56 return 8 * mbedtls_rsa_get_len(rsa);
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +020057}
58
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010059static int rsa_verify_wrap(void *ctx, mbedtls_md_type_t md_alg,
60 const unsigned char *hash, size_t hash_len,
61 const unsigned char *sig, size_t sig_len)
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020062{
Janos Follath24eed8d2019-11-22 13:21:35 +000063 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010064 mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) ctx;
65 size_t rsa_len = mbedtls_rsa_get_len(rsa);
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +020066
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +010067#if SIZE_MAX > UINT_MAX
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010068 if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) {
69 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
70 }
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +010071#endif /* SIZE_MAX > UINT_MAX */
Andres AG72849872017-01-19 11:24:33 +000072
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010073 if (sig_len < rsa_len) {
74 return MBEDTLS_ERR_RSA_VERIFY_FAILED;
75 }
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020076
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010077 if ((ret = mbedtls_rsa_pkcs1_verify(rsa, NULL, NULL,
78 MBEDTLS_RSA_PUBLIC, md_alg,
79 (unsigned int) hash_len, hash, sig)) != 0) {
80 return ret;
81 }
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +020082
Gilles Peskine5114d3e2018-03-30 07:12:15 +020083 /* The buffer contains a valid signature followed by extra data.
84 * We have a special error code for that so that so that callers can
85 * use mbedtls_pk_verify() to check "Does the buffer start with a
86 * valid signature?" and not just "Does the buffer contain a valid
87 * signature?". */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010088 if (sig_len > rsa_len) {
89 return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
90 }
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +020091
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010092 return 0;
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020093}
94
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010095static int rsa_sign_wrap(void *ctx, mbedtls_md_type_t md_alg,
96 const unsigned char *hash, size_t hash_len,
97 unsigned char *sig, size_t *sig_len,
98 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +020099{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100100 mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) ctx;
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100101
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100102#if SIZE_MAX > UINT_MAX
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100103 if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) {
104 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
105 }
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100106#endif /* SIZE_MAX > UINT_MAX */
Andres AG72849872017-01-19 11:24:33 +0000107
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100108 *sig_len = mbedtls_rsa_get_len(rsa);
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200109
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100110 return mbedtls_rsa_pkcs1_sign(rsa, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
111 md_alg, (unsigned int) hash_len, hash, sig);
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200112}
113
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100114static int rsa_decrypt_wrap(void *ctx,
115 const unsigned char *input, size_t ilen,
116 unsigned char *output, size_t *olen, size_t osize,
117 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200118{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100119 mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) ctx;
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100120
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100121 if (ilen != mbedtls_rsa_get_len(rsa)) {
122 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
123 }
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200124
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100125 return mbedtls_rsa_pkcs1_decrypt(rsa, f_rng, p_rng,
126 MBEDTLS_RSA_PRIVATE, olen, input, output, osize);
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200127}
128
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100129static int rsa_encrypt_wrap(void *ctx,
130 const unsigned char *input, size_t ilen,
131 unsigned char *output, size_t *olen, size_t osize,
132 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200133{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100134 mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) ctx;
135 *olen = mbedtls_rsa_get_len(rsa);
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200136
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100137 if (*olen > osize) {
138 return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
139 }
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100140
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100141 return mbedtls_rsa_pkcs1_encrypt(rsa, f_rng, p_rng, MBEDTLS_RSA_PUBLIC,
142 ilen, input, output);
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200143}
144
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100145static int rsa_check_pair_wrap(const void *pub, const void *prv)
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100146{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100147 return mbedtls_rsa_check_pub_priv((const mbedtls_rsa_context *) pub,
148 (const mbedtls_rsa_context *) prv);
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100149}
150
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100151static void *rsa_alloc_wrap(void)
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200152{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100153 void *ctx = mbedtls_calloc(1, sizeof(mbedtls_rsa_context));
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200154
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100155 if (ctx != NULL) {
156 mbedtls_rsa_init((mbedtls_rsa_context *) ctx, 0, 0);
157 }
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200158
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100159 return ctx;
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200160}
161
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100162static void rsa_free_wrap(void *ctx)
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200163{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100164 mbedtls_rsa_free((mbedtls_rsa_context *) ctx);
165 mbedtls_free(ctx);
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200166}
167
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100168static void rsa_debug(const void *ctx, mbedtls_pk_debug_item *items)
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200169{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200170 items->type = MBEDTLS_PK_DEBUG_MPI;
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200171 items->name = "rsa.N";
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100172 items->value = &(((mbedtls_rsa_context *) ctx)->N);
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200173
174 items++;
175
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200176 items->type = MBEDTLS_PK_DEBUG_MPI;
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200177 items->name = "rsa.E";
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100178 items->value = &(((mbedtls_rsa_context *) ctx)->E);
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200179}
180
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200181const mbedtls_pk_info_t mbedtls_rsa_info = {
182 MBEDTLS_PK_RSA,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200183 "RSA",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200184 rsa_get_bitlen,
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200185 rsa_can_do,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200186 rsa_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200187 rsa_sign_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200188#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200189 NULL,
190 NULL,
191#endif
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200192 rsa_decrypt_wrap,
193 rsa_encrypt_wrap,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100194 rsa_check_pair_wrap,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200195 rsa_alloc_wrap,
196 rsa_free_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200197#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200198 NULL,
199 NULL,
200#endif
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200201 rsa_debug,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200202};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200203#endif /* MBEDTLS_RSA_C */
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200204
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200205#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200206/*
207 * Generic EC key
208 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100209static int eckey_can_do(mbedtls_pk_type_t type)
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200210{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100211 return type == MBEDTLS_PK_ECKEY ||
212 type == MBEDTLS_PK_ECKEY_DH ||
213 type == MBEDTLS_PK_ECDSA;
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200214}
215
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100216static size_t eckey_get_bitlen(const void *ctx)
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200217{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100218 return ((mbedtls_ecp_keypair *) ctx)->grp.pbits;
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200219}
220
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200221#if defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200222/* Forward declarations */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100223static int ecdsa_verify_wrap(void *ctx, mbedtls_md_type_t md_alg,
224 const unsigned char *hash, size_t hash_len,
225 const unsigned char *sig, size_t sig_len);
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200226
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100227static int ecdsa_sign_wrap(void *ctx, mbedtls_md_type_t md_alg,
228 const unsigned char *hash, size_t hash_len,
229 unsigned char *sig, size_t *sig_len,
230 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200231
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100232static int eckey_verify_wrap(void *ctx, mbedtls_md_type_t md_alg,
233 const unsigned char *hash, size_t hash_len,
234 const unsigned char *sig, size_t sig_len)
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200235{
Janos Follath24eed8d2019-11-22 13:21:35 +0000236 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200237 mbedtls_ecdsa_context ecdsa;
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200238
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100239 mbedtls_ecdsa_init(&ecdsa);
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200240
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100241 if ((ret = mbedtls_ecdsa_from_keypair(&ecdsa, ctx)) == 0) {
242 ret = ecdsa_verify_wrap(&ecdsa, md_alg, hash, hash_len, sig, sig_len);
243 }
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200244
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100245 mbedtls_ecdsa_free(&ecdsa);
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200246
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100247 return ret;
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200248}
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200249
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100250static int eckey_sign_wrap(void *ctx, mbedtls_md_type_t md_alg,
251 const unsigned char *hash, size_t hash_len,
252 unsigned char *sig, size_t *sig_len,
253 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200254{
Janos Follath24eed8d2019-11-22 13:21:35 +0000255 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200256 mbedtls_ecdsa_context ecdsa;
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200257
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100258 mbedtls_ecdsa_init(&ecdsa);
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200259
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100260 if ((ret = mbedtls_ecdsa_from_keypair(&ecdsa, ctx)) == 0) {
261 ret = ecdsa_sign_wrap(&ecdsa, md_alg, hash, hash_len, sig, sig_len,
262 f_rng, p_rng);
263 }
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200264
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100265 mbedtls_ecdsa_free(&ecdsa);
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200266
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100267 return ret;
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200268}
269
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200270#if defined(MBEDTLS_ECP_RESTARTABLE)
271/* Forward declarations */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100272static int ecdsa_verify_rs_wrap(void *ctx, mbedtls_md_type_t md_alg,
273 const unsigned char *hash, size_t hash_len,
274 const unsigned char *sig, size_t sig_len,
275 void *rs_ctx);
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200276
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100277static int ecdsa_sign_rs_wrap(void *ctx, mbedtls_md_type_t md_alg,
278 const unsigned char *hash, size_t hash_len,
279 unsigned char *sig, size_t *sig_len,
280 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
281 void *rs_ctx);
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200282
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200283/*
284 * Restart context for ECDSA operations with ECKEY context
285 *
286 * We need to store an actual ECDSA context, as we need to pass the same to
287 * the underlying ecdsa function, so we can't create it on the fly every time.
288 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100289typedef struct {
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200290 mbedtls_ecdsa_restart_ctx ecdsa_rs;
291 mbedtls_ecdsa_context ecdsa_ctx;
292} eckey_restart_ctx;
293
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100294static void *eckey_rs_alloc(void)
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200295{
296 eckey_restart_ctx *rs_ctx;
297
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100298 void *ctx = mbedtls_calloc(1, sizeof(eckey_restart_ctx));
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200299
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100300 if (ctx != NULL) {
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200301 rs_ctx = ctx;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100302 mbedtls_ecdsa_restart_init(&rs_ctx->ecdsa_rs);
303 mbedtls_ecdsa_init(&rs_ctx->ecdsa_ctx);
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200304 }
305
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100306 return ctx;
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200307}
308
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100309static void eckey_rs_free(void *ctx)
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200310{
311 eckey_restart_ctx *rs_ctx;
312
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100313 if (ctx == NULL) {
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200314 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100315 }
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200316
317 rs_ctx = ctx;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100318 mbedtls_ecdsa_restart_free(&rs_ctx->ecdsa_rs);
319 mbedtls_ecdsa_free(&rs_ctx->ecdsa_ctx);
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200320
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100321 mbedtls_free(ctx);
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200322}
323
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100324static int eckey_verify_rs_wrap(void *ctx, mbedtls_md_type_t md_alg,
325 const unsigned char *hash, size_t hash_len,
326 const unsigned char *sig, size_t sig_len,
327 void *rs_ctx)
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200328{
Janos Follath24eed8d2019-11-22 13:21:35 +0000329 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200330 eckey_restart_ctx *rs = rs_ctx;
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200331
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200332 /* Should never happen */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100333 if (rs == NULL) {
334 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
335 }
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200336
Manuel Pégourié-Gonnardee68cff2018-10-15 15:27:49 +0200337 /* set up our own sub-context if needed (that is, on first run) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100338 if (rs->ecdsa_ctx.grp.pbits == 0) {
339 MBEDTLS_MPI_CHK(mbedtls_ecdsa_from_keypair(&rs->ecdsa_ctx, ctx));
340 }
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200341
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100342 MBEDTLS_MPI_CHK(ecdsa_verify_rs_wrap(&rs->ecdsa_ctx,
343 md_alg, hash, hash_len,
344 sig, sig_len, &rs->ecdsa_rs));
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200345
346cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100347 return ret;
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200348}
349
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100350static int eckey_sign_rs_wrap(void *ctx, mbedtls_md_type_t md_alg,
351 const unsigned char *hash, size_t hash_len,
352 unsigned char *sig, size_t *sig_len,
353 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
354 void *rs_ctx)
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200355{
Janos Follath24eed8d2019-11-22 13:21:35 +0000356 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200357 eckey_restart_ctx *rs = rs_ctx;
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200358
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200359 /* Should never happen */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100360 if (rs == NULL) {
361 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
362 }
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200363
Manuel Pégourié-Gonnardee68cff2018-10-15 15:27:49 +0200364 /* set up our own sub-context if needed (that is, on first run) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100365 if (rs->ecdsa_ctx.grp.pbits == 0) {
366 MBEDTLS_MPI_CHK(mbedtls_ecdsa_from_keypair(&rs->ecdsa_ctx, ctx));
367 }
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200368
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100369 MBEDTLS_MPI_CHK(ecdsa_sign_rs_wrap(&rs->ecdsa_ctx, md_alg,
370 hash, hash_len, sig, sig_len,
371 f_rng, p_rng, &rs->ecdsa_rs));
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200372
373cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100374 return ret;
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200375}
376#endif /* MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200377#endif /* MBEDTLS_ECDSA_C */
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200378
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100379static int eckey_check_pair(const void *pub, const void *prv)
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100380{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100381 return mbedtls_ecp_check_pub_priv((const mbedtls_ecp_keypair *) pub,
382 (const mbedtls_ecp_keypair *) prv);
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100383}
384
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100385static void *eckey_alloc_wrap(void)
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200386{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100387 void *ctx = mbedtls_calloc(1, sizeof(mbedtls_ecp_keypair));
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200388
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100389 if (ctx != NULL) {
390 mbedtls_ecp_keypair_init(ctx);
391 }
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200392
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100393 return ctx;
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200394}
395
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100396static void eckey_free_wrap(void *ctx)
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200397{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100398 mbedtls_ecp_keypair_free((mbedtls_ecp_keypair *) ctx);
399 mbedtls_free(ctx);
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200400}
401
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100402static void eckey_debug(const void *ctx, mbedtls_pk_debug_item *items)
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200403{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200404 items->type = MBEDTLS_PK_DEBUG_ECP;
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200405 items->name = "eckey.Q";
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100406 items->value = &(((mbedtls_ecp_keypair *) ctx)->Q);
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200407}
408
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200409const mbedtls_pk_info_t mbedtls_eckey_info = {
410 MBEDTLS_PK_ECKEY,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200411 "EC",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200412 eckey_get_bitlen,
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200413 eckey_can_do,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200414#if defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200415 eckey_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200416 eckey_sign_wrap,
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200417#if defined(MBEDTLS_ECP_RESTARTABLE)
418 eckey_verify_rs_wrap,
419 eckey_sign_rs_wrap,
420#endif
421#else /* MBEDTLS_ECDSA_C */
422 NULL,
423 NULL,
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200424#endif /* MBEDTLS_ECDSA_C */
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200425 NULL,
426 NULL,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100427 eckey_check_pair,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200428 eckey_alloc_wrap,
429 eckey_free_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200430#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200431 eckey_rs_alloc,
432 eckey_rs_free,
433#endif
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200434 eckey_debug,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200435};
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200436
437/*
Paul Bakker75342a62014-04-08 17:35:40 +0200438 * EC key restricted to ECDH
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200439 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100440static int eckeydh_can_do(mbedtls_pk_type_t type)
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200441{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100442 return type == MBEDTLS_PK_ECKEY ||
443 type == MBEDTLS_PK_ECKEY_DH;
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200444}
445
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200446const mbedtls_pk_info_t mbedtls_eckeydh_info = {
447 MBEDTLS_PK_ECKEY_DH,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200448 "EC_DH",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200449 eckey_get_bitlen, /* Same underlying key structure */
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200450 eckeydh_can_do,
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200451 NULL,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200452 NULL,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200453#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200454 NULL,
455 NULL,
456#endif
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200457 NULL,
458 NULL,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100459 eckey_check_pair,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200460 eckey_alloc_wrap, /* Same underlying key structure */
461 eckey_free_wrap, /* Same underlying key structure */
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200462#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200463 NULL,
464 NULL,
465#endif
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200466 eckey_debug, /* Same underlying key structure */
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200467};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200468#endif /* MBEDTLS_ECP_C */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200469
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200470#if defined(MBEDTLS_ECDSA_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100471static int ecdsa_can_do(mbedtls_pk_type_t type)
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200472{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100473 return type == MBEDTLS_PK_ECDSA;
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200474}
475
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400476#if defined(MBEDTLS_USE_PSA_CRYPTO)
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400477/*
Andrzej Kurek9241d182018-11-20 05:04:35 -0500478 * An ASN.1 encoded signature is a sequence of two ASN.1 integers. Parse one of
479 * those integers and convert it to the fixed-length encoding expected by PSA.
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500480 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100481static int extract_ecdsa_sig_int(unsigned char **from, const unsigned char *end,
482 unsigned char *to, size_t to_len)
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500483{
Janos Follath24eed8d2019-11-22 13:21:35 +0000484 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurek9241d182018-11-20 05:04:35 -0500485 size_t unpadded_len, padding_len;
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500486
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100487 if ((ret = mbedtls_asn1_get_tag(from, end, &unpadded_len,
488 MBEDTLS_ASN1_INTEGER)) != 0) {
489 return ret;
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500490 }
491
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100492 while (unpadded_len > 0 && **from == 0x00) {
493 (*from)++;
Andrzej Kurek9241d182018-11-20 05:04:35 -0500494 unpadded_len--;
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500495 }
496
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100497 if (unpadded_len > to_len || unpadded_len == 0) {
498 return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
499 }
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500500
Andrzej Kurek9241d182018-11-20 05:04:35 -0500501 padding_len = to_len - unpadded_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100502 memset(to, 0x00, padding_len);
503 memcpy(to + padding_len, *from, unpadded_len);
504 (*from) += unpadded_len;
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500505
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100506 return 0;
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500507}
508
509/*
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400510 * Convert a signature from an ASN.1 sequence of two integers
Andrzej Kurek9241d182018-11-20 05:04:35 -0500511 * to a raw {r,s} buffer. Note: the provided sig buffer must be at least
Andrzej Kurekb6016c52018-11-19 17:41:58 -0500512 * twice as big as int_size.
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400513 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100514static int extract_ecdsa_sig(unsigned char **p, const unsigned char *end,
515 unsigned char *sig, size_t int_size)
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400516{
Janos Follath24eed8d2019-11-22 13:21:35 +0000517 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurek9241d182018-11-20 05:04:35 -0500518 size_t tmp_size;
Andrzej Kurek3f864c22018-11-07 09:30:50 -0500519
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100520 if ((ret = mbedtls_asn1_get_tag(p, end, &tmp_size,
521 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
522 return ret;
523 }
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400524
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500525 /* Extract r */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100526 if ((ret = extract_ecdsa_sig_int(p, end, sig, int_size)) != 0) {
527 return ret;
528 }
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500529 /* Extract s */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100530 if ((ret = extract_ecdsa_sig_int(p, end, sig + int_size, int_size)) != 0) {
531 return ret;
532 }
Andrzej Kurek3f864c22018-11-07 09:30:50 -0500533
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100534 return 0;
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400535}
536
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100537static int ecdsa_verify_wrap(void *ctx_arg, mbedtls_md_type_t md_alg,
538 const unsigned char *hash, size_t hash_len,
539 const unsigned char *sig, size_t sig_len)
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400540{
Gilles Peskinefc2459d2019-12-12 17:50:44 +0100541 mbedtls_ecdsa_context *ctx = ctx_arg;
Janos Follath24eed8d2019-11-22 13:21:35 +0000542 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskined2d45c12019-05-27 14:53:13 +0200543 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Ronald Croncf56a0a2020-08-04 09:51:30 +0200544 psa_key_id_t key_id = 0;
Gilles Peskined2d45c12019-05-27 14:53:13 +0200545 psa_status_t status;
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400546 mbedtls_pk_context key;
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400547 int key_len;
Andrzej Kurek9241d182018-11-20 05:04:35 -0500548 /* see ECP_PUB_DER_MAX_BYTES in pkwrite.c */
549 unsigned char buf[30 + 2 * MBEDTLS_ECP_MAX_BYTES];
Hanno Beckera9851112019-01-25 16:37:10 +0000550 unsigned char *p;
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400551 mbedtls_pk_info_t pk_info = mbedtls_eckey_info;
John Durkop2ec2eaa2020-08-24 18:29:15 -0700552 psa_algorithm_t psa_sig_md = PSA_ALG_ECDSA_ANY;
Gilles Peskinefc2459d2019-12-12 17:50:44 +0100553 size_t curve_bits;
Paul Elliott8ff510a2020-06-02 17:19:28 +0100554 psa_ecc_family_t curve =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100555 mbedtls_ecc_group_to_psa(ctx->grp.id, &curve_bits);
556 const size_t signature_part_size = (ctx->grp.nbits + 7) / 8;
John Durkop2ec2eaa2020-08-24 18:29:15 -0700557 ((void) md_alg);
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400558
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100559 if (curve == 0) {
560 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
561 }
Andrzej Kurekb3d1b122018-11-07 08:18:52 -0500562
Hanno Beckerccf574e2019-01-29 08:26:15 +0000563 /* mbedtls_pk_write_pubkey() expects a full PK context;
Andrzej Kurek9241d182018-11-20 05:04:35 -0500564 * re-construct one to make it happy */
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400565 key.pk_info = &pk_info;
566 key.pk_ctx = ctx;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100567 p = buf + sizeof(buf);
568 key_len = mbedtls_pk_write_pubkey(&p, buf, &key);
569 if (key_len <= 0) {
570 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
571 }
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400572
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100573 psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve));
574 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH);
575 psa_set_key_algorithm(&attributes, psa_sig_md);
Andrzej Kurek2349c4d2019-01-08 09:36:01 -0500576
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100577 status = psa_import_key(&attributes,
578 buf + sizeof(buf) - key_len, key_len,
579 &key_id);
580 if (status != PSA_SUCCESS) {
581 ret = mbedtls_psa_err_translate_pk(status);
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400582 goto cleanup;
583 }
584
Andrzej Kurekeeac03b2018-11-20 06:39:06 -0500585 /* We don't need the exported key anymore and can
586 * reuse its buffer for signature extraction. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100587 if (2 * signature_part_size > sizeof(buf)) {
Andrzej Kurekb6016c52018-11-19 17:41:58 -0500588 ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;
589 goto cleanup;
590 }
Andrzej Kurekb6016c52018-11-19 17:41:58 -0500591
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100592 p = (unsigned char *) sig;
593 if ((ret = extract_ecdsa_sig(&p, sig + sig_len, buf,
594 signature_part_size)) != 0) {
Andrzej Kurekb6016c52018-11-19 17:41:58 -0500595 goto cleanup;
596 }
597
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100598 if (psa_verify_hash(key_id, psa_sig_md,
599 hash, hash_len,
600 buf, 2 * signature_part_size)
601 != PSA_SUCCESS) {
602 ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
603 goto cleanup;
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400604 }
Andrzej Kurekad5d5812018-11-20 07:59:18 -0500605
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100606 if (p != sig + sig_len) {
Andrzej Kurekad5d5812018-11-20 07:59:18 -0500607 ret = MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
608 goto cleanup;
609 }
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400610 ret = 0;
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400611
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500612cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100613 psa_destroy_key(key_id);
614 return ret;
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400615}
616#else /* MBEDTLS_USE_PSA_CRYPTO */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100617static int ecdsa_verify_wrap(void *ctx, mbedtls_md_type_t md_alg,
618 const unsigned char *hash, size_t hash_len,
619 const unsigned char *sig, size_t sig_len)
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200620{
Janos Follath24eed8d2019-11-22 13:21:35 +0000621 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200622 ((void) md_alg);
623
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100624 ret = mbedtls_ecdsa_read_signature((mbedtls_ecdsa_context *) ctx,
625 hash, hash_len, sig, sig_len);
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200626
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100627 if (ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) {
628 return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
629 }
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200630
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100631 return ret;
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200632}
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400633#endif /* MBEDTLS_USE_PSA_CRYPTO */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200634
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100635static int ecdsa_sign_wrap(void *ctx, mbedtls_md_type_t md_alg,
636 const unsigned char *hash, size_t hash_len,
637 unsigned char *sig, size_t *sig_len,
638 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200639{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100640 return mbedtls_ecdsa_write_signature((mbedtls_ecdsa_context *) ctx,
641 md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng);
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200642}
643
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200644#if defined(MBEDTLS_ECP_RESTARTABLE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100645static int ecdsa_verify_rs_wrap(void *ctx, mbedtls_md_type_t md_alg,
646 const unsigned char *hash, size_t hash_len,
647 const unsigned char *sig, size_t sig_len,
648 void *rs_ctx)
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200649{
Janos Follath24eed8d2019-11-22 13:21:35 +0000650 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200651 ((void) md_alg);
652
653 ret = mbedtls_ecdsa_read_signature_restartable(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100654 (mbedtls_ecdsa_context *) ctx,
655 hash, hash_len, sig, sig_len,
656 (mbedtls_ecdsa_restart_ctx *) rs_ctx);
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200657
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100658 if (ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) {
659 return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
660 }
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200661
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100662 return ret;
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200663}
664
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100665static int ecdsa_sign_rs_wrap(void *ctx, mbedtls_md_type_t md_alg,
666 const unsigned char *hash, size_t hash_len,
667 unsigned char *sig, size_t *sig_len,
668 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
669 void *rs_ctx)
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200670{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100671 return mbedtls_ecdsa_write_signature_restartable(
672 (mbedtls_ecdsa_context *) ctx,
673 md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng,
674 (mbedtls_ecdsa_restart_ctx *) rs_ctx);
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200675
676}
677#endif /* MBEDTLS_ECP_RESTARTABLE */
678
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100679static void *ecdsa_alloc_wrap(void)
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200680{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100681 void *ctx = mbedtls_calloc(1, sizeof(mbedtls_ecdsa_context));
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200682
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100683 if (ctx != NULL) {
684 mbedtls_ecdsa_init((mbedtls_ecdsa_context *) ctx);
685 }
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200686
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100687 return ctx;
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200688}
689
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100690static void ecdsa_free_wrap(void *ctx)
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200691{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100692 mbedtls_ecdsa_free((mbedtls_ecdsa_context *) ctx);
693 mbedtls_free(ctx);
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200694}
695
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200696#if defined(MBEDTLS_ECP_RESTARTABLE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100697static void *ecdsa_rs_alloc(void)
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200698{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100699 void *ctx = mbedtls_calloc(1, sizeof(mbedtls_ecdsa_restart_ctx));
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200700
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100701 if (ctx != NULL) {
702 mbedtls_ecdsa_restart_init(ctx);
703 }
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200704
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100705 return ctx;
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200706}
707
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100708static void ecdsa_rs_free(void *ctx)
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200709{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100710 mbedtls_ecdsa_restart_free(ctx);
711 mbedtls_free(ctx);
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200712}
713#endif /* MBEDTLS_ECP_RESTARTABLE */
714
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200715const mbedtls_pk_info_t mbedtls_ecdsa_info = {
716 MBEDTLS_PK_ECDSA,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200717 "ECDSA",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200718 eckey_get_bitlen, /* Compatible key structures */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200719 ecdsa_can_do,
720 ecdsa_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200721 ecdsa_sign_wrap,
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200722#if defined(MBEDTLS_ECP_RESTARTABLE)
723 ecdsa_verify_rs_wrap,
724 ecdsa_sign_rs_wrap,
725#endif
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200726 NULL,
727 NULL,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100728 eckey_check_pair, /* Compatible key structures */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200729 ecdsa_alloc_wrap,
730 ecdsa_free_wrap,
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200731#if defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200732 ecdsa_rs_alloc,
733 ecdsa_rs_free,
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200734#endif
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200735 eckey_debug, /* Compatible key structures */
736};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200737#endif /* MBEDTLS_ECDSA_C */
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200738
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200739#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200740/*
741 * Support for alternative RSA-private implementations
742 */
743
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100744static int rsa_alt_can_do(mbedtls_pk_type_t type)
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200745{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100746 return type == MBEDTLS_PK_RSA;
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200747}
748
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100749static size_t rsa_alt_get_bitlen(const void *ctx)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200750{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200751 const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200752
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100753 return 8 * rsa_alt->key_len_func(rsa_alt->key);
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200754}
755
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100756static int rsa_alt_sign_wrap(void *ctx, mbedtls_md_type_t md_alg,
757 const unsigned char *hash, size_t hash_len,
758 unsigned char *sig, size_t *sig_len,
759 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200760{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200761 mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200762
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100763#if SIZE_MAX > UINT_MAX
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100764 if (UINT_MAX < hash_len) {
765 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
766 }
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100767#endif /* SIZE_MAX > UINT_MAX */
Andres AG72849872017-01-19 11:24:33 +0000768
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100769 *sig_len = rsa_alt->key_len_func(rsa_alt->key);
770 if (*sig_len > MBEDTLS_PK_SIGNATURE_MAX_SIZE) {
771 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
772 }
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200773
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100774 return rsa_alt->sign_func(rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
775 md_alg, (unsigned int) hash_len, hash, sig);
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200776}
777
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100778static int rsa_alt_decrypt_wrap(void *ctx,
779 const unsigned char *input, size_t ilen,
780 unsigned char *output, size_t *olen, size_t osize,
781 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200782{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200783 mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200784
785 ((void) f_rng);
786 ((void) p_rng);
787
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100788 if (ilen != rsa_alt->key_len_func(rsa_alt->key)) {
789 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
790 }
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200791
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100792 return rsa_alt->decrypt_func(rsa_alt->key,
793 MBEDTLS_RSA_PRIVATE, olen, input, output, osize);
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200794}
795
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200796#if defined(MBEDTLS_RSA_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100797static int rsa_alt_check_pair(const void *pub, const void *prv)
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100798{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200799 unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100800 unsigned char hash[32];
801 size_t sig_len = 0;
Janos Follath24eed8d2019-11-22 13:21:35 +0000802 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100803
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100804 if (rsa_alt_get_bitlen(prv) != rsa_get_bitlen(pub)) {
805 return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100806 }
807
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100808 memset(hash, 0x2a, sizeof(hash));
809
810 if ((ret = rsa_alt_sign_wrap((void *) prv, MBEDTLS_MD_NONE,
811 hash, sizeof(hash),
812 sig, &sig_len, NULL, NULL)) != 0) {
813 return ret;
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100814 }
815
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100816 if (rsa_verify_wrap((void *) pub, MBEDTLS_MD_NONE,
817 hash, sizeof(hash), sig, sig_len) != 0) {
818 return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
819 }
820
821 return 0;
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100822}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200823#endif /* MBEDTLS_RSA_C */
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100824
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100825static void *rsa_alt_alloc_wrap(void)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200826{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100827 void *ctx = mbedtls_calloc(1, sizeof(mbedtls_rsa_alt_context));
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200828
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100829 if (ctx != NULL) {
830 memset(ctx, 0, sizeof(mbedtls_rsa_alt_context));
831 }
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200832
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100833 return ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200834}
835
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100836static void rsa_alt_free_wrap(void *ctx)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200837{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100838 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_rsa_alt_context));
839 mbedtls_free(ctx);
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200840}
841
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200842const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
843 MBEDTLS_PK_RSA_ALT,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200844 "RSA-alt",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200845 rsa_alt_get_bitlen,
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200846 rsa_alt_can_do,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200847 NULL,
848 rsa_alt_sign_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200849#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200850 NULL,
851 NULL,
852#endif
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200853 rsa_alt_decrypt_wrap,
854 NULL,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200855#if defined(MBEDTLS_RSA_C)
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100856 rsa_alt_check_pair,
Manuel Pégourié-Gonnard7c13d692014-11-12 00:01:34 +0100857#else
858 NULL,
859#endif
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200860 rsa_alt_alloc_wrap,
861 rsa_alt_free_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200862#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200863 NULL,
864 NULL,
865#endif
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200866 NULL,
867};
Manuel Pégourié-Gonnardc40b4c32013-08-22 13:29:31 +0200868
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200869#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
Manuel Pégourié-Gonnard348bcb32015-03-31 14:01:33 +0200870
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200871#if defined(MBEDTLS_USE_PSA_CRYPTO)
872
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100873static void *pk_opaque_alloc_wrap(void)
Manuel Pégourié-Gonnard7b5fe042018-10-31 09:57:45 +0100874{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100875 void *ctx = mbedtls_calloc(1, sizeof(psa_key_id_t));
Manuel Pégourié-Gonnard7b5fe042018-10-31 09:57:45 +0100876
Tom Cosgrove5205c972022-07-28 06:12:08 +0100877 /* no _init() function to call, as calloc() already zeroized */
Manuel Pégourié-Gonnard7b5fe042018-10-31 09:57:45 +0100878
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100879 return ctx;
Manuel Pégourié-Gonnard7b5fe042018-10-31 09:57:45 +0100880}
881
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100882static void pk_opaque_free_wrap(void *ctx)
Manuel Pégourié-Gonnard7b5fe042018-10-31 09:57:45 +0100883{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100884 mbedtls_platform_zeroize(ctx, sizeof(psa_key_id_t));
885 mbedtls_free(ctx);
Manuel Pégourié-Gonnard7b5fe042018-10-31 09:57:45 +0100886}
887
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100888static size_t pk_opaque_get_bitlen(const void *ctx)
Manuel Pégourié-Gonnard0184b3c2018-10-31 10:36:51 +0100889{
Ronald Croncf56a0a2020-08-04 09:51:30 +0200890 const psa_key_id_t *key = (const psa_key_id_t *) ctx;
Manuel Pégourié-Gonnard0184b3c2018-10-31 10:36:51 +0100891 size_t bits;
Gilles Peskined2d45c12019-05-27 14:53:13 +0200892 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Manuel Pégourié-Gonnard0184b3c2018-10-31 10:36:51 +0100893
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100894 if (PSA_SUCCESS != psa_get_key_attributes(*key, &attributes)) {
895 return 0;
896 }
Manuel Pégourié-Gonnard0184b3c2018-10-31 10:36:51 +0100897
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100898 bits = psa_get_key_bits(&attributes);
899 psa_reset_key_attributes(&attributes);
900 return bits;
Manuel Pégourié-Gonnard0184b3c2018-10-31 10:36:51 +0100901}
902
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100903static int pk_opaque_can_do(mbedtls_pk_type_t type)
Manuel Pégourié-Gonnard920c0632018-10-31 10:57:29 +0100904{
905 /* For now opaque PSA keys can only wrap ECC keypairs,
906 * as checked by setup_psa().
907 * Also, ECKEY_DH does not really make sense with the current API. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100908 return type == MBEDTLS_PK_ECKEY ||
909 type == MBEDTLS_PK_ECDSA;
Manuel Pégourié-Gonnard920c0632018-10-31 10:57:29 +0100910}
911
John Durkopf35069a2020-08-17 22:05:14 -0700912#if defined(MBEDTLS_ECDSA_C)
913
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100914/*
Manuel Pégourié-Gonnard509aff12018-11-15 12:17:38 +0100915 * Simultaneously convert and move raw MPI from the beginning of a buffer
916 * to an ASN.1 MPI at the end of the buffer.
917 * See also mbedtls_asn1_write_mpi().
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100918 *
919 * p: pointer to the end of the output buffer
920 * start: start of the output buffer, and also of the mpi to write at the end
Manuel Pégourié-Gonnard509aff12018-11-15 12:17:38 +0100921 * n_len: length of the mpi to read from start
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100922 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100923static int asn1_write_mpibuf(unsigned char **p, unsigned char *start,
924 size_t n_len)
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100925{
Janos Follath24eed8d2019-11-22 13:21:35 +0000926 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100927 size_t len = 0;
928
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100929 if ((size_t) (*p - start) < n_len) {
930 return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
931 }
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100932
933 len = n_len;
934 *p -= len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100935 memmove(*p, start, len);
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100936
Manuel Pégourié-Gonnard45013a12018-11-16 10:09:11 +0100937 /* ASN.1 DER encoding requires minimal length, so skip leading 0s.
Manuel Pégourié-Gonnard59eecb02018-11-16 10:54:54 +0100938 * Neither r nor s should be 0, but as a failsafe measure, still detect
939 * that rather than overflowing the buffer in case of a PSA error. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100940 while (len > 0 && **p == 0x00) {
Manuel Pégourié-Gonnard45013a12018-11-16 10:09:11 +0100941 ++(*p);
942 --len;
943 }
944
Manuel Pégourié-Gonnard59eecb02018-11-16 10:54:54 +0100945 /* this is only reached if the signature was invalid */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100946 if (len == 0) {
947 return MBEDTLS_ERR_PK_HW_ACCEL_FAILED;
948 }
Manuel Pégourié-Gonnard59eecb02018-11-16 10:54:54 +0100949
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100950 /* if the msb is 1, ASN.1 requires that we prepend a 0.
Manuel Pégourié-Gonnard45013a12018-11-16 10:09:11 +0100951 * Neither r nor s can be 0, so we can assume len > 0 at all times. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100952 if (**p & 0x80) {
953 if (*p - start < 1) {
954 return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
955 }
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100956
957 *--(*p) = 0x00;
958 len += 1;
959 }
960
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100961 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len));
962 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start,
963 MBEDTLS_ASN1_INTEGER));
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100964
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100965 return (int) len;
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100966}
967
968/* Transcode signature from PSA format to ASN.1 sequence.
969 * See ecdsa_signature_to_asn1 in ecdsa.c, but with byte buffers instead of
970 * MPIs, and in-place.
971 *
972 * [in/out] sig: the signature pre- and post-transcoding
973 * [in/out] sig_len: signature length pre- and post-transcoding
974 * [int] buf_len: the available size the in/out buffer
975 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100976static int pk_ecdsa_sig_asn1_from_psa(unsigned char *sig, size_t *sig_len,
977 size_t buf_len)
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100978{
Janos Follath24eed8d2019-11-22 13:21:35 +0000979 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100980 size_t len = 0;
981 const size_t rs_len = *sig_len / 2;
982 unsigned char *p = sig + buf_len;
983
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100984 MBEDTLS_ASN1_CHK_ADD(len, asn1_write_mpibuf(&p, sig + rs_len, rs_len));
985 MBEDTLS_ASN1_CHK_ADD(len, asn1_write_mpibuf(&p, sig, rs_len));
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100986
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100987 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, sig, len));
988 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, sig,
989 MBEDTLS_ASN1_CONSTRUCTED |
990 MBEDTLS_ASN1_SEQUENCE));
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100991
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100992 memmove(sig, p, len);
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100993 *sig_len = len;
Manuel Pégourié-Gonnard36867712018-10-31 16:22:49 +0100994
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100995 return 0;
Manuel Pégourié-Gonnard36867712018-10-31 16:22:49 +0100996}
997
John Durkopd46ede02020-08-24 09:51:00 -0700998#endif /* MBEDTLS_ECDSA_C */
John Durkopf35069a2020-08-17 22:05:14 -0700999
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001000static int pk_opaque_sign_wrap(void *ctx, mbedtls_md_type_t md_alg,
1001 const unsigned char *hash, size_t hash_len,
1002 unsigned char *sig, size_t *sig_len,
1003 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +01001004{
John Durkopf35069a2020-08-17 22:05:14 -07001005#if !defined(MBEDTLS_ECDSA_C)
1006 ((void) ctx);
1007 ((void) md_alg);
1008 ((void) hash);
1009 ((void) hash_len);
1010 ((void) sig);
1011 ((void) sig_len);
1012 ((void) f_rng);
1013 ((void) p_rng);
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001014 return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
John Durkopaf5363c2020-08-24 08:29:39 -07001015#else /* !MBEDTLS_ECDSA_C */
Ronald Croncf56a0a2020-08-04 09:51:30 +02001016 const psa_key_id_t *key = (const psa_key_id_t *) ctx;
Gilles Peskined2d45c12019-05-27 14:53:13 +02001017 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001018 psa_algorithm_t alg = PSA_ALG_ECDSA(mbedtls_psa_translate_md(md_alg));
Gilles Peskined2d45c12019-05-27 14:53:13 +02001019 size_t buf_len;
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +01001020 psa_status_t status;
1021
1022 /* PSA has its own RNG */
1023 (void) f_rng;
1024 (void) p_rng;
1025
1026 /* PSA needs an output buffer of known size, but our API doesn't provide
1027 * that information. Assume that the buffer is large enough for a
1028 * maximal-length signature with that key (otherwise the application is
1029 * buggy anyway). */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001030 status = psa_get_key_attributes(*key, &attributes);
1031 if (status != PSA_SUCCESS) {
1032 return mbedtls_psa_err_translate_pk(status);
1033 }
1034 buf_len = MBEDTLS_ECDSA_MAX_SIG_LEN(psa_get_key_bits(&attributes));
1035 psa_reset_key_attributes(&attributes);
1036 if (buf_len > MBEDTLS_PK_SIGNATURE_MAX_SIZE) {
1037 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1038 }
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +01001039
1040 /* make the signature */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001041 status = psa_sign_hash(*key, alg, hash, hash_len,
1042 sig, buf_len, sig_len);
1043 if (status != PSA_SUCCESS) {
1044 return mbedtls_psa_err_translate_pk(status);
1045 }
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +01001046
1047 /* transcode it to ASN.1 sequence */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001048 return pk_ecdsa_sig_asn1_from_psa(sig, sig_len, buf_len);
John Durkopaf5363c2020-08-24 08:29:39 -07001049#endif /* !MBEDTLS_ECDSA_C */
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +01001050}
1051
Manuel Pégourié-Gonnard69baf702018-11-06 09:34:30 +01001052const mbedtls_pk_info_t mbedtls_pk_opaque_info = {
1053 MBEDTLS_PK_OPAQUE,
1054 "Opaque",
1055 pk_opaque_get_bitlen,
1056 pk_opaque_can_do,
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +02001057 NULL, /* verify - will be done later */
Manuel Pégourié-Gonnard69baf702018-11-06 09:34:30 +01001058 pk_opaque_sign_wrap,
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +02001059#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
1060 NULL, /* restartable verify - not relevant */
1061 NULL, /* restartable sign - not relevant */
1062#endif
1063 NULL, /* decrypt - will be done later */
1064 NULL, /* encrypt - will be done later */
1065 NULL, /* check_pair - could be done later or left NULL */
Manuel Pégourié-Gonnard69baf702018-11-06 09:34:30 +01001066 pk_opaque_alloc_wrap,
1067 pk_opaque_free_wrap,
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +02001068#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
1069 NULL, /* restart alloc - not relevant */
1070 NULL, /* restart free - not relevant */
1071#endif
1072 NULL, /* debug - could be done later, or even left NULL */
1073};
1074
1075#endif /* MBEDTLS_USE_PSA_CRYPTO */
1076
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001077#endif /* MBEDTLS_PK_C */