blob: dd460a6a0c838f049e9b940ac7488858a6538fb2 [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;
Gilles Peskine0196f482024-02-01 22:33:06 +010056 /* Unfortunately, the rsa.h interface does not have a direct way
57 * to access the bit-length that works with MBEDTLS_RSA_ALT.
58 * So we have to do a little work here.
59 */
60 mbedtls_mpi N;
61 mbedtls_mpi_init(&N);
62 int ret = mbedtls_rsa_export(rsa, &N, NULL, NULL, NULL, NULL);
63 /* If the export fails for some reason (e.g. the RSA_ALT implementation
64 * does not support export, or there is not enough memory),
65 * we have no way of returning an error from this function.
66 * As a fallback, return the byte-length converted in bits, which is
67 * the correct value if the modulus size is a multiple of 8 bits, which
68 * is very often the case in practice. */
69 size_t bitlen = (ret == 0 ? mbedtls_mpi_bitlen(&N) :
70 8 * mbedtls_rsa_get_len(rsa));
71 mbedtls_mpi_free(&N);
72 return bitlen;
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +020073}
74
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010075static int rsa_verify_wrap(void *ctx, mbedtls_md_type_t md_alg,
76 const unsigned char *hash, size_t hash_len,
77 const unsigned char *sig, size_t sig_len)
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020078{
Janos Follath24eed8d2019-11-22 13:21:35 +000079 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010080 mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) ctx;
81 size_t rsa_len = mbedtls_rsa_get_len(rsa);
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +020082
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +010083#if SIZE_MAX > UINT_MAX
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010084 if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) {
85 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
86 }
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +010087#endif /* SIZE_MAX > UINT_MAX */
Andres AG72849872017-01-19 11:24:33 +000088
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010089 if (sig_len < rsa_len) {
90 return MBEDTLS_ERR_RSA_VERIFY_FAILED;
91 }
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020092
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010093 if ((ret = mbedtls_rsa_pkcs1_verify(rsa, NULL, NULL,
94 MBEDTLS_RSA_PUBLIC, md_alg,
95 (unsigned int) hash_len, hash, sig)) != 0) {
96 return ret;
97 }
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +020098
Gilles Peskine5114d3e2018-03-30 07:12:15 +020099 /* The buffer contains a valid signature followed by extra data.
100 * We have a special error code for that so that so that callers can
101 * use mbedtls_pk_verify() to check "Does the buffer start with a
102 * valid signature?" and not just "Does the buffer contain a valid
103 * signature?". */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100104 if (sig_len > rsa_len) {
105 return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
106 }
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200107
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100108 return 0;
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200109}
110
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100111static int rsa_sign_wrap(void *ctx, mbedtls_md_type_t md_alg,
112 const unsigned char *hash, size_t hash_len,
113 unsigned char *sig, size_t *sig_len,
114 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200115{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100116 mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) ctx;
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100117
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100118#if SIZE_MAX > UINT_MAX
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100119 if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) {
120 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
121 }
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100122#endif /* SIZE_MAX > UINT_MAX */
Andres AG72849872017-01-19 11:24:33 +0000123
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100124 *sig_len = mbedtls_rsa_get_len(rsa);
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200125
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100126 return mbedtls_rsa_pkcs1_sign(rsa, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
127 md_alg, (unsigned int) hash_len, hash, sig);
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200128}
129
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100130static int rsa_decrypt_wrap(void *ctx,
131 const unsigned char *input, size_t ilen,
132 unsigned char *output, size_t *olen, size_t osize,
133 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200134{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100135 mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) ctx;
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100136
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100137 if (ilen != mbedtls_rsa_get_len(rsa)) {
138 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
139 }
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200140
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100141 return mbedtls_rsa_pkcs1_decrypt(rsa, f_rng, p_rng,
142 MBEDTLS_RSA_PRIVATE, olen, input, output, osize);
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200143}
144
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100145static int rsa_encrypt_wrap(void *ctx,
146 const unsigned char *input, size_t ilen,
147 unsigned char *output, size_t *olen, size_t osize,
148 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200149{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100150 mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) ctx;
151 *olen = mbedtls_rsa_get_len(rsa);
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200152
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100153 if (*olen > osize) {
154 return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
155 }
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100156
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100157 return mbedtls_rsa_pkcs1_encrypt(rsa, f_rng, p_rng, MBEDTLS_RSA_PUBLIC,
158 ilen, input, output);
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200159}
160
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100161static int rsa_check_pair_wrap(const void *pub, const void *prv)
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100162{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100163 return mbedtls_rsa_check_pub_priv((const mbedtls_rsa_context *) pub,
164 (const mbedtls_rsa_context *) prv);
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100165}
166
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100167static void *rsa_alloc_wrap(void)
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200168{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100169 void *ctx = mbedtls_calloc(1, sizeof(mbedtls_rsa_context));
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200170
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100171 if (ctx != NULL) {
172 mbedtls_rsa_init((mbedtls_rsa_context *) ctx, 0, 0);
173 }
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200174
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100175 return ctx;
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200176}
177
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100178static void rsa_free_wrap(void *ctx)
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200179{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100180 mbedtls_rsa_free((mbedtls_rsa_context *) ctx);
181 mbedtls_free(ctx);
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200182}
183
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100184static void rsa_debug(const void *ctx, mbedtls_pk_debug_item *items)
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200185{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200186 items->type = MBEDTLS_PK_DEBUG_MPI;
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200187 items->name = "rsa.N";
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100188 items->value = &(((mbedtls_rsa_context *) ctx)->N);
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200189
190 items++;
191
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200192 items->type = MBEDTLS_PK_DEBUG_MPI;
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200193 items->name = "rsa.E";
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100194 items->value = &(((mbedtls_rsa_context *) ctx)->E);
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200195}
196
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200197const mbedtls_pk_info_t mbedtls_rsa_info = {
198 MBEDTLS_PK_RSA,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200199 "RSA",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200200 rsa_get_bitlen,
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200201 rsa_can_do,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200202 rsa_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200203 rsa_sign_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200204#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200205 NULL,
206 NULL,
207#endif
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200208 rsa_decrypt_wrap,
209 rsa_encrypt_wrap,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100210 rsa_check_pair_wrap,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200211 rsa_alloc_wrap,
212 rsa_free_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200213#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200214 NULL,
215 NULL,
216#endif
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200217 rsa_debug,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200218};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200219#endif /* MBEDTLS_RSA_C */
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200220
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200221#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200222/*
223 * Generic EC key
224 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100225static int eckey_can_do(mbedtls_pk_type_t type)
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200226{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100227 return type == MBEDTLS_PK_ECKEY ||
228 type == MBEDTLS_PK_ECKEY_DH ||
229 type == MBEDTLS_PK_ECDSA;
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200230}
231
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100232static size_t eckey_get_bitlen(const void *ctx)
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200233{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100234 return ((mbedtls_ecp_keypair *) ctx)->grp.pbits;
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200235}
236
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200237#if defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200238/* Forward declarations */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100239static int ecdsa_verify_wrap(void *ctx, mbedtls_md_type_t md_alg,
240 const unsigned char *hash, size_t hash_len,
241 const unsigned char *sig, size_t sig_len);
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200242
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100243static int ecdsa_sign_wrap(void *ctx, mbedtls_md_type_t md_alg,
244 const unsigned char *hash, size_t hash_len,
245 unsigned char *sig, size_t *sig_len,
246 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200247
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100248static int eckey_verify_wrap(void *ctx, mbedtls_md_type_t md_alg,
249 const unsigned char *hash, size_t hash_len,
250 const unsigned char *sig, size_t sig_len)
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200251{
Janos Follath24eed8d2019-11-22 13:21:35 +0000252 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200253 mbedtls_ecdsa_context ecdsa;
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200254
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100255 mbedtls_ecdsa_init(&ecdsa);
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200256
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100257 if ((ret = mbedtls_ecdsa_from_keypair(&ecdsa, ctx)) == 0) {
258 ret = ecdsa_verify_wrap(&ecdsa, md_alg, hash, hash_len, sig, sig_len);
259 }
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200260
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100261 mbedtls_ecdsa_free(&ecdsa);
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200262
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100263 return ret;
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200264}
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200265
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100266static int eckey_sign_wrap(void *ctx, mbedtls_md_type_t md_alg,
267 const unsigned char *hash, size_t hash_len,
268 unsigned char *sig, size_t *sig_len,
269 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200270{
Janos Follath24eed8d2019-11-22 13:21:35 +0000271 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200272 mbedtls_ecdsa_context ecdsa;
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200273
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100274 mbedtls_ecdsa_init(&ecdsa);
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200275
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100276 if ((ret = mbedtls_ecdsa_from_keypair(&ecdsa, ctx)) == 0) {
277 ret = ecdsa_sign_wrap(&ecdsa, md_alg, hash, hash_len, sig, sig_len,
278 f_rng, p_rng);
279 }
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200280
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100281 mbedtls_ecdsa_free(&ecdsa);
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200282
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100283 return ret;
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200284}
285
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200286#if defined(MBEDTLS_ECP_RESTARTABLE)
287/* Forward declarations */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100288static int ecdsa_verify_rs_wrap(void *ctx, mbedtls_md_type_t md_alg,
289 const unsigned char *hash, size_t hash_len,
290 const unsigned char *sig, size_t sig_len,
291 void *rs_ctx);
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200292
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100293static int ecdsa_sign_rs_wrap(void *ctx, mbedtls_md_type_t md_alg,
294 const unsigned char *hash, size_t hash_len,
295 unsigned char *sig, size_t *sig_len,
296 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
297 void *rs_ctx);
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200298
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200299/*
300 * Restart context for ECDSA operations with ECKEY context
301 *
302 * We need to store an actual ECDSA context, as we need to pass the same to
303 * the underlying ecdsa function, so we can't create it on the fly every time.
304 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100305typedef struct {
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200306 mbedtls_ecdsa_restart_ctx ecdsa_rs;
307 mbedtls_ecdsa_context ecdsa_ctx;
308} eckey_restart_ctx;
309
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100310static void *eckey_rs_alloc(void)
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200311{
312 eckey_restart_ctx *rs_ctx;
313
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100314 void *ctx = mbedtls_calloc(1, sizeof(eckey_restart_ctx));
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200315
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100316 if (ctx != NULL) {
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200317 rs_ctx = ctx;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100318 mbedtls_ecdsa_restart_init(&rs_ctx->ecdsa_rs);
319 mbedtls_ecdsa_init(&rs_ctx->ecdsa_ctx);
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200320 }
321
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100322 return ctx;
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200323}
324
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100325static void eckey_rs_free(void *ctx)
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200326{
327 eckey_restart_ctx *rs_ctx;
328
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100329 if (ctx == NULL) {
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200330 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100331 }
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200332
333 rs_ctx = ctx;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100334 mbedtls_ecdsa_restart_free(&rs_ctx->ecdsa_rs);
335 mbedtls_ecdsa_free(&rs_ctx->ecdsa_ctx);
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200336
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100337 mbedtls_free(ctx);
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200338}
339
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100340static int eckey_verify_rs_wrap(void *ctx, mbedtls_md_type_t md_alg,
341 const unsigned char *hash, size_t hash_len,
342 const unsigned char *sig, size_t sig_len,
343 void *rs_ctx)
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200344{
Janos Follath24eed8d2019-11-22 13:21:35 +0000345 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200346 eckey_restart_ctx *rs = rs_ctx;
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200347
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200348 /* Should never happen */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100349 if (rs == NULL) {
350 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
351 }
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200352
Manuel Pégourié-Gonnardee68cff2018-10-15 15:27:49 +0200353 /* set up our own sub-context if needed (that is, on first run) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100354 if (rs->ecdsa_ctx.grp.pbits == 0) {
355 MBEDTLS_MPI_CHK(mbedtls_ecdsa_from_keypair(&rs->ecdsa_ctx, ctx));
356 }
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200357
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100358 MBEDTLS_MPI_CHK(ecdsa_verify_rs_wrap(&rs->ecdsa_ctx,
359 md_alg, hash, hash_len,
360 sig, sig_len, &rs->ecdsa_rs));
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200361
362cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100363 return ret;
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200364}
365
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100366static int eckey_sign_rs_wrap(void *ctx, mbedtls_md_type_t md_alg,
367 const unsigned char *hash, size_t hash_len,
368 unsigned char *sig, size_t *sig_len,
369 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
370 void *rs_ctx)
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200371{
Janos Follath24eed8d2019-11-22 13:21:35 +0000372 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200373 eckey_restart_ctx *rs = rs_ctx;
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200374
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200375 /* Should never happen */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100376 if (rs == NULL) {
377 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
378 }
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200379
Manuel Pégourié-Gonnardee68cff2018-10-15 15:27:49 +0200380 /* set up our own sub-context if needed (that is, on first run) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100381 if (rs->ecdsa_ctx.grp.pbits == 0) {
382 MBEDTLS_MPI_CHK(mbedtls_ecdsa_from_keypair(&rs->ecdsa_ctx, ctx));
383 }
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200384
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100385 MBEDTLS_MPI_CHK(ecdsa_sign_rs_wrap(&rs->ecdsa_ctx, md_alg,
386 hash, hash_len, sig, sig_len,
387 f_rng, p_rng, &rs->ecdsa_rs));
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200388
389cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100390 return ret;
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200391}
392#endif /* MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200393#endif /* MBEDTLS_ECDSA_C */
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200394
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100395static int eckey_check_pair(const void *pub, const void *prv)
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100396{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100397 return mbedtls_ecp_check_pub_priv((const mbedtls_ecp_keypair *) pub,
398 (const mbedtls_ecp_keypair *) prv);
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100399}
400
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100401static void *eckey_alloc_wrap(void)
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200402{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100403 void *ctx = mbedtls_calloc(1, sizeof(mbedtls_ecp_keypair));
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200404
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100405 if (ctx != NULL) {
406 mbedtls_ecp_keypair_init(ctx);
407 }
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200408
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100409 return ctx;
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200410}
411
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100412static void eckey_free_wrap(void *ctx)
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200413{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100414 mbedtls_ecp_keypair_free((mbedtls_ecp_keypair *) ctx);
415 mbedtls_free(ctx);
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200416}
417
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100418static void eckey_debug(const void *ctx, mbedtls_pk_debug_item *items)
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200419{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200420 items->type = MBEDTLS_PK_DEBUG_ECP;
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200421 items->name = "eckey.Q";
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100422 items->value = &(((mbedtls_ecp_keypair *) ctx)->Q);
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200423}
424
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200425const mbedtls_pk_info_t mbedtls_eckey_info = {
426 MBEDTLS_PK_ECKEY,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200427 "EC",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200428 eckey_get_bitlen,
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200429 eckey_can_do,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200430#if defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200431 eckey_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200432 eckey_sign_wrap,
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200433#if defined(MBEDTLS_ECP_RESTARTABLE)
434 eckey_verify_rs_wrap,
435 eckey_sign_rs_wrap,
436#endif
437#else /* MBEDTLS_ECDSA_C */
438 NULL,
439 NULL,
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200440#endif /* MBEDTLS_ECDSA_C */
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200441 NULL,
442 NULL,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100443 eckey_check_pair,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200444 eckey_alloc_wrap,
445 eckey_free_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200446#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200447 eckey_rs_alloc,
448 eckey_rs_free,
449#endif
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200450 eckey_debug,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200451};
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200452
453/*
Paul Bakker75342a62014-04-08 17:35:40 +0200454 * EC key restricted to ECDH
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200455 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100456static int eckeydh_can_do(mbedtls_pk_type_t type)
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200457{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100458 return type == MBEDTLS_PK_ECKEY ||
459 type == MBEDTLS_PK_ECKEY_DH;
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200460}
461
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200462const mbedtls_pk_info_t mbedtls_eckeydh_info = {
463 MBEDTLS_PK_ECKEY_DH,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200464 "EC_DH",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200465 eckey_get_bitlen, /* Same underlying key structure */
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200466 eckeydh_can_do,
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200467 NULL,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200468 NULL,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200469#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200470 NULL,
471 NULL,
472#endif
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200473 NULL,
474 NULL,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100475 eckey_check_pair,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200476 eckey_alloc_wrap, /* Same underlying key structure */
477 eckey_free_wrap, /* Same underlying key structure */
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200478#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200479 NULL,
480 NULL,
481#endif
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200482 eckey_debug, /* Same underlying key structure */
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200483};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200484#endif /* MBEDTLS_ECP_C */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200485
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200486#if defined(MBEDTLS_ECDSA_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100487static int ecdsa_can_do(mbedtls_pk_type_t type)
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200488{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100489 return type == MBEDTLS_PK_ECDSA;
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200490}
491
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400492#if defined(MBEDTLS_USE_PSA_CRYPTO)
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400493/*
Andrzej Kurek9241d182018-11-20 05:04:35 -0500494 * An ASN.1 encoded signature is a sequence of two ASN.1 integers. Parse one of
495 * those integers and convert it to the fixed-length encoding expected by PSA.
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500496 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100497static int extract_ecdsa_sig_int(unsigned char **from, const unsigned char *end,
498 unsigned char *to, size_t to_len)
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500499{
Janos Follath24eed8d2019-11-22 13:21:35 +0000500 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurek9241d182018-11-20 05:04:35 -0500501 size_t unpadded_len, padding_len;
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500502
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100503 if ((ret = mbedtls_asn1_get_tag(from, end, &unpadded_len,
504 MBEDTLS_ASN1_INTEGER)) != 0) {
505 return ret;
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500506 }
507
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100508 while (unpadded_len > 0 && **from == 0x00) {
509 (*from)++;
Andrzej Kurek9241d182018-11-20 05:04:35 -0500510 unpadded_len--;
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500511 }
512
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100513 if (unpadded_len > to_len || unpadded_len == 0) {
514 return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
515 }
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500516
Andrzej Kurek9241d182018-11-20 05:04:35 -0500517 padding_len = to_len - unpadded_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100518 memset(to, 0x00, padding_len);
519 memcpy(to + padding_len, *from, unpadded_len);
520 (*from) += unpadded_len;
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500521
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100522 return 0;
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500523}
524
525/*
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400526 * Convert a signature from an ASN.1 sequence of two integers
Andrzej Kurek9241d182018-11-20 05:04:35 -0500527 * to a raw {r,s} buffer. Note: the provided sig buffer must be at least
Andrzej Kurekb6016c52018-11-19 17:41:58 -0500528 * twice as big as int_size.
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400529 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100530static int extract_ecdsa_sig(unsigned char **p, const unsigned char *end,
531 unsigned char *sig, size_t int_size)
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400532{
Janos Follath24eed8d2019-11-22 13:21:35 +0000533 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurek9241d182018-11-20 05:04:35 -0500534 size_t tmp_size;
Andrzej Kurek3f864c22018-11-07 09:30:50 -0500535
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100536 if ((ret = mbedtls_asn1_get_tag(p, end, &tmp_size,
537 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
538 return ret;
539 }
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400540
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500541 /* Extract r */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100542 if ((ret = extract_ecdsa_sig_int(p, end, sig, int_size)) != 0) {
543 return ret;
544 }
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500545 /* Extract s */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100546 if ((ret = extract_ecdsa_sig_int(p, end, sig + int_size, int_size)) != 0) {
547 return ret;
548 }
Andrzej Kurek3f864c22018-11-07 09:30:50 -0500549
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100550 return 0;
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400551}
552
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100553static int ecdsa_verify_wrap(void *ctx_arg, mbedtls_md_type_t md_alg,
554 const unsigned char *hash, size_t hash_len,
555 const unsigned char *sig, size_t sig_len)
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400556{
Gilles Peskinefc2459d2019-12-12 17:50:44 +0100557 mbedtls_ecdsa_context *ctx = ctx_arg;
Janos Follath24eed8d2019-11-22 13:21:35 +0000558 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskined2d45c12019-05-27 14:53:13 +0200559 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Ronald Croncf56a0a2020-08-04 09:51:30 +0200560 psa_key_id_t key_id = 0;
Gilles Peskined2d45c12019-05-27 14:53:13 +0200561 psa_status_t status;
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400562 mbedtls_pk_context key;
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400563 int key_len;
Andrzej Kurek9241d182018-11-20 05:04:35 -0500564 /* see ECP_PUB_DER_MAX_BYTES in pkwrite.c */
565 unsigned char buf[30 + 2 * MBEDTLS_ECP_MAX_BYTES];
Hanno Beckera9851112019-01-25 16:37:10 +0000566 unsigned char *p;
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400567 mbedtls_pk_info_t pk_info = mbedtls_eckey_info;
John Durkop2ec2eaa2020-08-24 18:29:15 -0700568 psa_algorithm_t psa_sig_md = PSA_ALG_ECDSA_ANY;
Gilles Peskinefc2459d2019-12-12 17:50:44 +0100569 size_t curve_bits;
Paul Elliott8ff510a2020-06-02 17:19:28 +0100570 psa_ecc_family_t curve =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100571 mbedtls_ecc_group_to_psa(ctx->grp.id, &curve_bits);
572 const size_t signature_part_size = (ctx->grp.nbits + 7) / 8;
John Durkop2ec2eaa2020-08-24 18:29:15 -0700573 ((void) md_alg);
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400574
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100575 if (curve == 0) {
576 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
577 }
Andrzej Kurekb3d1b122018-11-07 08:18:52 -0500578
Hanno Beckerccf574e2019-01-29 08:26:15 +0000579 /* mbedtls_pk_write_pubkey() expects a full PK context;
Andrzej Kurek9241d182018-11-20 05:04:35 -0500580 * re-construct one to make it happy */
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400581 key.pk_info = &pk_info;
582 key.pk_ctx = ctx;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100583 p = buf + sizeof(buf);
584 key_len = mbedtls_pk_write_pubkey(&p, buf, &key);
585 if (key_len <= 0) {
586 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
587 }
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400588
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100589 psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve));
590 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH);
591 psa_set_key_algorithm(&attributes, psa_sig_md);
Andrzej Kurek2349c4d2019-01-08 09:36:01 -0500592
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100593 status = psa_import_key(&attributes,
594 buf + sizeof(buf) - key_len, key_len,
595 &key_id);
596 if (status != PSA_SUCCESS) {
597 ret = mbedtls_psa_err_translate_pk(status);
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400598 goto cleanup;
599 }
600
Andrzej Kurekeeac03b2018-11-20 06:39:06 -0500601 /* We don't need the exported key anymore and can
602 * reuse its buffer for signature extraction. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100603 if (2 * signature_part_size > sizeof(buf)) {
Andrzej Kurekb6016c52018-11-19 17:41:58 -0500604 ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;
605 goto cleanup;
606 }
Andrzej Kurekb6016c52018-11-19 17:41:58 -0500607
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100608 p = (unsigned char *) sig;
609 if ((ret = extract_ecdsa_sig(&p, sig + sig_len, buf,
610 signature_part_size)) != 0) {
Andrzej Kurekb6016c52018-11-19 17:41:58 -0500611 goto cleanup;
612 }
613
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100614 if (psa_verify_hash(key_id, psa_sig_md,
615 hash, hash_len,
616 buf, 2 * signature_part_size)
617 != PSA_SUCCESS) {
618 ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
619 goto cleanup;
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400620 }
Andrzej Kurekad5d5812018-11-20 07:59:18 -0500621
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100622 if (p != sig + sig_len) {
Andrzej Kurekad5d5812018-11-20 07:59:18 -0500623 ret = MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
624 goto cleanup;
625 }
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400626 ret = 0;
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400627
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500628cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100629 psa_destroy_key(key_id);
630 return ret;
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400631}
632#else /* MBEDTLS_USE_PSA_CRYPTO */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100633static int ecdsa_verify_wrap(void *ctx, mbedtls_md_type_t md_alg,
634 const unsigned char *hash, size_t hash_len,
635 const unsigned char *sig, size_t sig_len)
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200636{
Janos Follath24eed8d2019-11-22 13:21:35 +0000637 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200638 ((void) md_alg);
639
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100640 ret = mbedtls_ecdsa_read_signature((mbedtls_ecdsa_context *) ctx,
641 hash, hash_len, sig, sig_len);
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200642
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100643 if (ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) {
644 return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
645 }
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200646
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100647 return ret;
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200648}
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400649#endif /* MBEDTLS_USE_PSA_CRYPTO */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200650
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100651static int ecdsa_sign_wrap(void *ctx, mbedtls_md_type_t md_alg,
652 const unsigned char *hash, size_t hash_len,
653 unsigned char *sig, size_t *sig_len,
654 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200655{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100656 return mbedtls_ecdsa_write_signature((mbedtls_ecdsa_context *) ctx,
657 md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng);
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200658}
659
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200660#if defined(MBEDTLS_ECP_RESTARTABLE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100661static int ecdsa_verify_rs_wrap(void *ctx, mbedtls_md_type_t md_alg,
662 const unsigned char *hash, size_t hash_len,
663 const unsigned char *sig, size_t sig_len,
664 void *rs_ctx)
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200665{
Janos Follath24eed8d2019-11-22 13:21:35 +0000666 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200667 ((void) md_alg);
668
669 ret = mbedtls_ecdsa_read_signature_restartable(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100670 (mbedtls_ecdsa_context *) ctx,
671 hash, hash_len, sig, sig_len,
672 (mbedtls_ecdsa_restart_ctx *) rs_ctx);
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200673
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100674 if (ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) {
675 return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
676 }
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200677
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100678 return ret;
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200679}
680
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100681static int ecdsa_sign_rs_wrap(void *ctx, mbedtls_md_type_t md_alg,
682 const unsigned char *hash, size_t hash_len,
683 unsigned char *sig, size_t *sig_len,
684 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
685 void *rs_ctx)
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200686{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100687 return mbedtls_ecdsa_write_signature_restartable(
688 (mbedtls_ecdsa_context *) ctx,
689 md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng,
690 (mbedtls_ecdsa_restart_ctx *) rs_ctx);
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200691
692}
693#endif /* MBEDTLS_ECP_RESTARTABLE */
694
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100695static void *ecdsa_alloc_wrap(void)
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200696{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100697 void *ctx = mbedtls_calloc(1, sizeof(mbedtls_ecdsa_context));
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200698
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100699 if (ctx != NULL) {
700 mbedtls_ecdsa_init((mbedtls_ecdsa_context *) ctx);
701 }
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200702
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100703 return ctx;
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200704}
705
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100706static void ecdsa_free_wrap(void *ctx)
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200707{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100708 mbedtls_ecdsa_free((mbedtls_ecdsa_context *) ctx);
709 mbedtls_free(ctx);
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200710}
711
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200712#if defined(MBEDTLS_ECP_RESTARTABLE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100713static void *ecdsa_rs_alloc(void)
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200714{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100715 void *ctx = mbedtls_calloc(1, sizeof(mbedtls_ecdsa_restart_ctx));
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200716
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100717 if (ctx != NULL) {
718 mbedtls_ecdsa_restart_init(ctx);
719 }
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200720
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100721 return ctx;
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200722}
723
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100724static void ecdsa_rs_free(void *ctx)
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200725{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100726 mbedtls_ecdsa_restart_free(ctx);
727 mbedtls_free(ctx);
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200728}
729#endif /* MBEDTLS_ECP_RESTARTABLE */
730
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200731const mbedtls_pk_info_t mbedtls_ecdsa_info = {
732 MBEDTLS_PK_ECDSA,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200733 "ECDSA",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200734 eckey_get_bitlen, /* Compatible key structures */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200735 ecdsa_can_do,
736 ecdsa_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200737 ecdsa_sign_wrap,
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200738#if defined(MBEDTLS_ECP_RESTARTABLE)
739 ecdsa_verify_rs_wrap,
740 ecdsa_sign_rs_wrap,
741#endif
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200742 NULL,
743 NULL,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100744 eckey_check_pair, /* Compatible key structures */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200745 ecdsa_alloc_wrap,
746 ecdsa_free_wrap,
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200747#if defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200748 ecdsa_rs_alloc,
749 ecdsa_rs_free,
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200750#endif
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200751 eckey_debug, /* Compatible key structures */
752};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200753#endif /* MBEDTLS_ECDSA_C */
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200754
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200755#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200756/*
757 * Support for alternative RSA-private implementations
758 */
759
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100760static int rsa_alt_can_do(mbedtls_pk_type_t type)
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200761{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100762 return type == MBEDTLS_PK_RSA;
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200763}
764
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100765static size_t rsa_alt_get_bitlen(const void *ctx)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200766{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200767 const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200768
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100769 return 8 * rsa_alt->key_len_func(rsa_alt->key);
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200770}
771
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100772static int rsa_alt_sign_wrap(void *ctx, mbedtls_md_type_t md_alg,
773 const unsigned char *hash, size_t hash_len,
774 unsigned char *sig, size_t *sig_len,
775 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200776{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200777 mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200778
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100779#if SIZE_MAX > UINT_MAX
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100780 if (UINT_MAX < hash_len) {
781 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
782 }
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100783#endif /* SIZE_MAX > UINT_MAX */
Andres AG72849872017-01-19 11:24:33 +0000784
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100785 *sig_len = rsa_alt->key_len_func(rsa_alt->key);
786 if (*sig_len > MBEDTLS_PK_SIGNATURE_MAX_SIZE) {
787 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
788 }
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200789
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100790 return rsa_alt->sign_func(rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
791 md_alg, (unsigned int) hash_len, hash, sig);
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200792}
793
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100794static int rsa_alt_decrypt_wrap(void *ctx,
795 const unsigned char *input, size_t ilen,
796 unsigned char *output, size_t *olen, size_t osize,
797 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200798{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200799 mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200800
801 ((void) f_rng);
802 ((void) p_rng);
803
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100804 if (ilen != rsa_alt->key_len_func(rsa_alt->key)) {
805 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
806 }
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200807
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100808 return rsa_alt->decrypt_func(rsa_alt->key,
809 MBEDTLS_RSA_PRIVATE, olen, input, output, osize);
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200810}
811
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200812#if defined(MBEDTLS_RSA_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100813static int rsa_alt_check_pair(const void *pub, const void *prv)
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100814{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200815 unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100816 unsigned char hash[32];
817 size_t sig_len = 0;
Janos Follath24eed8d2019-11-22 13:21:35 +0000818 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100819
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100820 if (rsa_alt_get_bitlen(prv) != rsa_get_bitlen(pub)) {
821 return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100822 }
823
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100824 memset(hash, 0x2a, sizeof(hash));
825
826 if ((ret = rsa_alt_sign_wrap((void *) prv, MBEDTLS_MD_NONE,
827 hash, sizeof(hash),
828 sig, &sig_len, NULL, NULL)) != 0) {
829 return ret;
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100830 }
831
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100832 if (rsa_verify_wrap((void *) pub, MBEDTLS_MD_NONE,
833 hash, sizeof(hash), sig, sig_len) != 0) {
834 return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
835 }
836
837 return 0;
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100838}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200839#endif /* MBEDTLS_RSA_C */
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100840
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100841static void *rsa_alt_alloc_wrap(void)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200842{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100843 void *ctx = mbedtls_calloc(1, sizeof(mbedtls_rsa_alt_context));
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200844
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100845 if (ctx != NULL) {
846 memset(ctx, 0, sizeof(mbedtls_rsa_alt_context));
847 }
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200848
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100849 return ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200850}
851
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100852static void rsa_alt_free_wrap(void *ctx)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200853{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100854 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_rsa_alt_context));
855 mbedtls_free(ctx);
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200856}
857
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200858const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
859 MBEDTLS_PK_RSA_ALT,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200860 "RSA-alt",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200861 rsa_alt_get_bitlen,
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200862 rsa_alt_can_do,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200863 NULL,
864 rsa_alt_sign_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200865#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200866 NULL,
867 NULL,
868#endif
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200869 rsa_alt_decrypt_wrap,
870 NULL,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200871#if defined(MBEDTLS_RSA_C)
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100872 rsa_alt_check_pair,
Manuel Pégourié-Gonnard7c13d692014-11-12 00:01:34 +0100873#else
874 NULL,
875#endif
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200876 rsa_alt_alloc_wrap,
877 rsa_alt_free_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200878#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200879 NULL,
880 NULL,
881#endif
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200882 NULL,
883};
Manuel Pégourié-Gonnardc40b4c32013-08-22 13:29:31 +0200884
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200885#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
Manuel Pégourié-Gonnard348bcb32015-03-31 14:01:33 +0200886
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200887#if defined(MBEDTLS_USE_PSA_CRYPTO)
888
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100889static void *pk_opaque_alloc_wrap(void)
Manuel Pégourié-Gonnard7b5fe042018-10-31 09:57:45 +0100890{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100891 void *ctx = mbedtls_calloc(1, sizeof(psa_key_id_t));
Manuel Pégourié-Gonnard7b5fe042018-10-31 09:57:45 +0100892
Tom Cosgrove5205c972022-07-28 06:12:08 +0100893 /* no _init() function to call, as calloc() already zeroized */
Manuel Pégourié-Gonnard7b5fe042018-10-31 09:57:45 +0100894
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100895 return ctx;
Manuel Pégourié-Gonnard7b5fe042018-10-31 09:57:45 +0100896}
897
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100898static void pk_opaque_free_wrap(void *ctx)
Manuel Pégourié-Gonnard7b5fe042018-10-31 09:57:45 +0100899{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100900 mbedtls_platform_zeroize(ctx, sizeof(psa_key_id_t));
901 mbedtls_free(ctx);
Manuel Pégourié-Gonnard7b5fe042018-10-31 09:57:45 +0100902}
903
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100904static size_t pk_opaque_get_bitlen(const void *ctx)
Manuel Pégourié-Gonnard0184b3c2018-10-31 10:36:51 +0100905{
Ronald Croncf56a0a2020-08-04 09:51:30 +0200906 const psa_key_id_t *key = (const psa_key_id_t *) ctx;
Manuel Pégourié-Gonnard0184b3c2018-10-31 10:36:51 +0100907 size_t bits;
Gilles Peskined2d45c12019-05-27 14:53:13 +0200908 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Manuel Pégourié-Gonnard0184b3c2018-10-31 10:36:51 +0100909
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100910 if (PSA_SUCCESS != psa_get_key_attributes(*key, &attributes)) {
911 return 0;
912 }
Manuel Pégourié-Gonnard0184b3c2018-10-31 10:36:51 +0100913
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100914 bits = psa_get_key_bits(&attributes);
915 psa_reset_key_attributes(&attributes);
916 return bits;
Manuel Pégourié-Gonnard0184b3c2018-10-31 10:36:51 +0100917}
918
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100919static int pk_opaque_can_do(mbedtls_pk_type_t type)
Manuel Pégourié-Gonnard920c0632018-10-31 10:57:29 +0100920{
921 /* For now opaque PSA keys can only wrap ECC keypairs,
922 * as checked by setup_psa().
923 * Also, ECKEY_DH does not really make sense with the current API. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100924 return type == MBEDTLS_PK_ECKEY ||
925 type == MBEDTLS_PK_ECDSA;
Manuel Pégourié-Gonnard920c0632018-10-31 10:57:29 +0100926}
927
John Durkopf35069a2020-08-17 22:05:14 -0700928#if defined(MBEDTLS_ECDSA_C)
929
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100930/*
Manuel Pégourié-Gonnard509aff12018-11-15 12:17:38 +0100931 * Simultaneously convert and move raw MPI from the beginning of a buffer
932 * to an ASN.1 MPI at the end of the buffer.
933 * See also mbedtls_asn1_write_mpi().
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100934 *
935 * p: pointer to the end of the output buffer
936 * 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 +0100937 * n_len: length of the mpi to read from start
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100938 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100939static int asn1_write_mpibuf(unsigned char **p, unsigned char *start,
940 size_t n_len)
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100941{
Janos Follath24eed8d2019-11-22 13:21:35 +0000942 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100943 size_t len = 0;
944
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100945 if ((size_t) (*p - start) < n_len) {
946 return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
947 }
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100948
949 len = n_len;
950 *p -= len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100951 memmove(*p, start, len);
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100952
Manuel Pégourié-Gonnard45013a12018-11-16 10:09:11 +0100953 /* ASN.1 DER encoding requires minimal length, so skip leading 0s.
Manuel Pégourié-Gonnard59eecb02018-11-16 10:54:54 +0100954 * Neither r nor s should be 0, but as a failsafe measure, still detect
955 * that rather than overflowing the buffer in case of a PSA error. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100956 while (len > 0 && **p == 0x00) {
Manuel Pégourié-Gonnard45013a12018-11-16 10:09:11 +0100957 ++(*p);
958 --len;
959 }
960
Manuel Pégourié-Gonnard59eecb02018-11-16 10:54:54 +0100961 /* this is only reached if the signature was invalid */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100962 if (len == 0) {
963 return MBEDTLS_ERR_PK_HW_ACCEL_FAILED;
964 }
Manuel Pégourié-Gonnard59eecb02018-11-16 10:54:54 +0100965
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100966 /* if the msb is 1, ASN.1 requires that we prepend a 0.
Manuel Pégourié-Gonnard45013a12018-11-16 10:09:11 +0100967 * Neither r nor s can be 0, so we can assume len > 0 at all times. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100968 if (**p & 0x80) {
969 if (*p - start < 1) {
970 return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
971 }
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100972
973 *--(*p) = 0x00;
974 len += 1;
975 }
976
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100977 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len));
978 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start,
979 MBEDTLS_ASN1_INTEGER));
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100980
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100981 return (int) len;
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100982}
983
984/* Transcode signature from PSA format to ASN.1 sequence.
985 * See ecdsa_signature_to_asn1 in ecdsa.c, but with byte buffers instead of
986 * MPIs, and in-place.
987 *
988 * [in/out] sig: the signature pre- and post-transcoding
989 * [in/out] sig_len: signature length pre- and post-transcoding
990 * [int] buf_len: the available size the in/out buffer
991 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100992static int pk_ecdsa_sig_asn1_from_psa(unsigned char *sig, size_t *sig_len,
993 size_t buf_len)
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100994{
Janos Follath24eed8d2019-11-22 13:21:35 +0000995 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +0100996 size_t len = 0;
997 const size_t rs_len = *sig_len / 2;
998 unsigned char *p = sig + buf_len;
999
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001000 MBEDTLS_ASN1_CHK_ADD(len, asn1_write_mpibuf(&p, sig + rs_len, rs_len));
1001 MBEDTLS_ASN1_CHK_ADD(len, asn1_write_mpibuf(&p, sig, rs_len));
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +01001002
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001003 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, sig, len));
1004 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, sig,
1005 MBEDTLS_ASN1_CONSTRUCTED |
1006 MBEDTLS_ASN1_SEQUENCE));
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +01001007
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001008 memmove(sig, p, len);
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +01001009 *sig_len = len;
Manuel Pégourié-Gonnard36867712018-10-31 16:22:49 +01001010
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001011 return 0;
Manuel Pégourié-Gonnard36867712018-10-31 16:22:49 +01001012}
1013
John Durkopd46ede02020-08-24 09:51:00 -07001014#endif /* MBEDTLS_ECDSA_C */
John Durkopf35069a2020-08-17 22:05:14 -07001015
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001016static int pk_opaque_sign_wrap(void *ctx, mbedtls_md_type_t md_alg,
1017 const unsigned char *hash, size_t hash_len,
1018 unsigned char *sig, size_t *sig_len,
1019 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +01001020{
John Durkopf35069a2020-08-17 22:05:14 -07001021#if !defined(MBEDTLS_ECDSA_C)
1022 ((void) ctx);
1023 ((void) md_alg);
1024 ((void) hash);
1025 ((void) hash_len);
1026 ((void) sig);
1027 ((void) sig_len);
1028 ((void) f_rng);
1029 ((void) p_rng);
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001030 return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
John Durkopaf5363c2020-08-24 08:29:39 -07001031#else /* !MBEDTLS_ECDSA_C */
Ronald Croncf56a0a2020-08-04 09:51:30 +02001032 const psa_key_id_t *key = (const psa_key_id_t *) ctx;
Gilles Peskined2d45c12019-05-27 14:53:13 +02001033 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001034 psa_algorithm_t alg = PSA_ALG_ECDSA(mbedtls_psa_translate_md(md_alg));
Gilles Peskined2d45c12019-05-27 14:53:13 +02001035 size_t buf_len;
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +01001036 psa_status_t status;
1037
1038 /* PSA has its own RNG */
1039 (void) f_rng;
1040 (void) p_rng;
1041
1042 /* PSA needs an output buffer of known size, but our API doesn't provide
1043 * that information. Assume that the buffer is large enough for a
1044 * maximal-length signature with that key (otherwise the application is
1045 * buggy anyway). */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001046 status = psa_get_key_attributes(*key, &attributes);
1047 if (status != PSA_SUCCESS) {
1048 return mbedtls_psa_err_translate_pk(status);
1049 }
1050 buf_len = MBEDTLS_ECDSA_MAX_SIG_LEN(psa_get_key_bits(&attributes));
1051 psa_reset_key_attributes(&attributes);
1052 if (buf_len > MBEDTLS_PK_SIGNATURE_MAX_SIZE) {
1053 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1054 }
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +01001055
1056 /* make the signature */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001057 status = psa_sign_hash(*key, alg, hash, hash_len,
1058 sig, buf_len, sig_len);
1059 if (status != PSA_SUCCESS) {
1060 return mbedtls_psa_err_translate_pk(status);
1061 }
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +01001062
1063 /* transcode it to ASN.1 sequence */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001064 return pk_ecdsa_sig_asn1_from_psa(sig, sig_len, buf_len);
John Durkopaf5363c2020-08-24 08:29:39 -07001065#endif /* !MBEDTLS_ECDSA_C */
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +01001066}
1067
Manuel Pégourié-Gonnard69baf702018-11-06 09:34:30 +01001068const mbedtls_pk_info_t mbedtls_pk_opaque_info = {
1069 MBEDTLS_PK_OPAQUE,
1070 "Opaque",
1071 pk_opaque_get_bitlen,
1072 pk_opaque_can_do,
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +02001073 NULL, /* verify - will be done later */
Manuel Pégourié-Gonnard69baf702018-11-06 09:34:30 +01001074 pk_opaque_sign_wrap,
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +02001075#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
1076 NULL, /* restartable verify - not relevant */
1077 NULL, /* restartable sign - not relevant */
1078#endif
1079 NULL, /* decrypt - will be done later */
1080 NULL, /* encrypt - will be done later */
1081 NULL, /* check_pair - could be done later or left NULL */
Manuel Pégourié-Gonnard69baf702018-11-06 09:34:30 +01001082 pk_opaque_alloc_wrap,
1083 pk_opaque_free_wrap,
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +02001084#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
1085 NULL, /* restart alloc - not relevant */
1086 NULL, /* restart free - not relevant */
1087#endif
1088 NULL, /* debug - could be done later, or even left NULL */
1089};
1090
1091#endif /* MBEDTLS_USE_PSA_CRYPTO */
1092
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001093#endif /* MBEDTLS_PK_C */