blob: c2326502292ee95e66dacfdef72b9557b66eb28f [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 Rodgman16799db2023-11-02 19:47:20 +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
Gilles Peskine8a6022e2022-10-04 23:01:59 +020010#include "mbedtls/platform_util.h"
11
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020012#if defined(MBEDTLS_PK_C)
Chris Jonesdaacb592021-03-09 17:03:29 +000013#include "pk_wrap.h"
Valerio Settia1b8af62023-05-17 15:34:57 +020014#include "pk_internal.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000015#include "mbedtls/error.h"
Valerio Setti384fbde2024-01-02 13:26:40 +010016#include "mbedtls/psa_util.h"
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020017
Manuel Pégourié-Gonnarde511ffc2013-08-22 17:33:21 +020018/* Even if RSA not activated, for the sake of RSA-alt */
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000019#include "mbedtls/rsa.h"
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020020
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020021#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000022#include "mbedtls/ecp.h"
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020023#endif
24
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020025#if defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000026#include "mbedtls/ecdsa.h"
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020027#endif
28
Manuel Pégourié-Gonnard36867712018-10-31 16:22:49 +010029#if defined(MBEDTLS_USE_PSA_CRYPTO)
Tomi Fontanilles1941af02023-12-14 21:48:52 +020030#include "psa_util_internal.h"
Andrzej Kurek8b036a62018-10-31 05:16:46 -040031#include "psa/crypto.h"
Gilles Peskine8a6022e2022-10-04 23:01:59 +020032
Tomi Fontanilles9f417702023-12-16 15:28:51 +020033#if defined(MBEDTLS_RSA_C)
34#include "pkwrite.h"
35#endif
36
Valerio Setti80d07982023-02-08 13:49:17 +010037#if defined(MBEDTLS_PK_CAN_ECDSA_SOME)
Gilles Peskine8a6022e2022-10-04 23:01:59 +020038#include "mbedtls/asn1write.h"
39#include "mbedtls/asn1.h"
Manuel Pégourié-Gonnard36867712018-10-31 16:22:49 +010040#endif
Gilles Peskine8a6022e2022-10-04 23:01:59 +020041#endif /* MBEDTLS_USE_PSA_CRYPTO */
Manuel Pégourié-Gonnard36867712018-10-31 16:22:49 +010042
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000043#include "mbedtls/platform.h"
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +020044
Andres AG72849872017-01-19 11:24:33 +000045#include <limits.h>
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +010046#include <stdint.h>
Gilles Peskine8a6022e2022-10-04 23:01:59 +020047#include <string.h>
Paul Bakker34617722014-06-13 17:20:13 +020048
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020049#if defined(MBEDTLS_RSA_C)
Gilles Peskine449bd832023-01-11 14:50:10 +010050static int rsa_can_do(mbedtls_pk_type_t type)
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +020051{
Gilles Peskine449bd832023-01-11 14:50:10 +010052 return type == MBEDTLS_PK_RSA ||
53 type == MBEDTLS_PK_RSASSA_PSS;
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +020054}
55
valerio38992cb2023-04-20 09:56:30 +020056static size_t rsa_get_bitlen(mbedtls_pk_context *pk)
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +020057{
valerio38992cb2023-04-20 09:56:30 +020058 const mbedtls_rsa_context *rsa = (const mbedtls_rsa_context *) pk->pk_ctx;
Gilles Peskine449bd832023-01-11 14:50:10 +010059 return 8 * mbedtls_rsa_get_len(rsa);
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +020060}
61
Neil Armstrong52f41f82022-02-22 15:30:24 +010062#if defined(MBEDTLS_USE_PSA_CRYPTO)
valerio38992cb2023-04-20 09:56:30 +020063static int rsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
Gilles Peskine449bd832023-01-11 14:50:10 +010064 const unsigned char *hash, size_t hash_len,
65 const unsigned char *sig, size_t sig_len)
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020066{
valerio38992cb2023-04-20 09:56:30 +020067 mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
Neil Armstrong52f41f82022-02-22 15:30:24 +010068 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
69 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
70 mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
71 psa_status_t status;
72 mbedtls_pk_context key;
73 int key_len;
Neil Armstrong6baea782022-03-01 13:52:02 +010074 unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES];
Neil Armstrong82cf8042022-03-03 12:30:59 +010075 psa_algorithm_t psa_alg_md =
Manuel Pégourié-Gonnard2d6d9932023-03-28 11:38:08 +020076 PSA_ALG_RSA_PKCS1V15_SIGN(mbedtls_md_psa_alg_from_type(md_alg));
Gilles Peskine449bd832023-01-11 14:50:10 +010077 size_t rsa_len = mbedtls_rsa_get_len(rsa);
Neil Armstrong52f41f82022-02-22 15:30:24 +010078
Dave Rodgman2eab4622023-10-05 13:30:37 +010079#if SIZE_MAX > UINT_MAX
Gilles Peskine449bd832023-01-11 14:50:10 +010080 if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) {
81 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
82 }
Dave Rodgman2eab4622023-10-05 13:30:37 +010083#endif
Neil Armstrong52f41f82022-02-22 15:30:24 +010084
Gilles Peskine449bd832023-01-11 14:50:10 +010085 if (sig_len < rsa_len) {
86 return MBEDTLS_ERR_RSA_VERIFY_FAILED;
87 }
Neil Armstrong52f41f82022-02-22 15:30:24 +010088
Neil Armstrongea54dbe2022-03-14 09:26:48 +010089 /* mbedtls_pk_write_pubkey_der() expects a full PK context;
Neil Armstrong52f41f82022-02-22 15:30:24 +010090 * re-construct one to make it happy */
Neil Armstrong253e9e72022-03-16 15:32:23 +010091 key.pk_info = &mbedtls_rsa_info;
valerio38992cb2023-04-20 09:56:30 +020092 key.pk_ctx = rsa;
Gilles Peskine449bd832023-01-11 14:50:10 +010093 key_len = mbedtls_pk_write_pubkey_der(&key, buf, sizeof(buf));
94 if (key_len <= 0) {
95 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
96 }
Neil Armstrong52f41f82022-02-22 15:30:24 +010097
Gilles Peskine449bd832023-01-11 14:50:10 +010098 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH);
99 psa_set_key_algorithm(&attributes, psa_alg_md);
100 psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY);
Neil Armstrong52f41f82022-02-22 15:30:24 +0100101
Gilles Peskine449bd832023-01-11 14:50:10 +0100102 status = psa_import_key(&attributes,
103 buf + sizeof(buf) - key_len, key_len,
104 &key_id);
105 if (status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500106 ret = PSA_PK_TO_MBEDTLS_ERR(status);
Neil Armstrong52f41f82022-02-22 15:30:24 +0100107 goto cleanup;
108 }
109
Gilles Peskine449bd832023-01-11 14:50:10 +0100110 status = psa_verify_hash(key_id, psa_alg_md, hash, hash_len,
111 sig, sig_len);
112 if (status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500113 ret = PSA_PK_RSA_TO_MBEDTLS_ERR(status);
Neil Armstrong52f41f82022-02-22 15:30:24 +0100114 goto cleanup;
115 }
116 ret = 0;
117
118cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100119 status = psa_destroy_key(key_id);
120 if (ret == 0 && status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500121 ret = PSA_PK_TO_MBEDTLS_ERR(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100122 }
Neil Armstronga33280a2022-02-24 15:17:47 +0100123
Gilles Peskine449bd832023-01-11 14:50:10 +0100124 return ret;
Neil Armstrong52f41f82022-02-22 15:30:24 +0100125}
Valerio Setti5c26b302023-06-21 19:47:01 +0200126#else /* MBEDTLS_USE_PSA_CRYPTO */
valerio38992cb2023-04-20 09:56:30 +0200127static int rsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100128 const unsigned char *hash, size_t hash_len,
129 const unsigned char *sig, size_t sig_len)
Neil Armstrong52f41f82022-02-22 15:30:24 +0100130{
Janos Follath24eed8d2019-11-22 13:21:35 +0000131 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
valerio38992cb2023-04-20 09:56:30 +0200132 mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
Gilles Peskine449bd832023-01-11 14:50:10 +0100133 size_t rsa_len = mbedtls_rsa_get_len(rsa);
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200134
Dave Rodgman02a53d72023-09-28 17:17:07 +0100135#if SIZE_MAX > UINT_MAX
Gilles Peskine449bd832023-01-11 14:50:10 +0100136 if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) {
137 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
138 }
Dave Rodgman02a53d72023-09-28 17:17:07 +0100139#endif
Andres AG72849872017-01-19 11:24:33 +0000140
Gilles Peskine449bd832023-01-11 14:50:10 +0100141 if (sig_len < rsa_len) {
142 return MBEDTLS_ERR_RSA_VERIFY_FAILED;
143 }
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200144
Gilles Peskine449bd832023-01-11 14:50:10 +0100145 if ((ret = mbedtls_rsa_pkcs1_verify(rsa, md_alg,
146 (unsigned int) hash_len,
147 hash, sig)) != 0) {
148 return ret;
149 }
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200150
Gilles Peskine5114d3e2018-03-30 07:12:15 +0200151 /* The buffer contains a valid signature followed by extra data.
152 * We have a special error code for that so that so that callers can
153 * use mbedtls_pk_verify() to check "Does the buffer start with a
154 * valid signature?" and not just "Does the buffer contain a valid
155 * signature?". */
Gilles Peskine449bd832023-01-11 14:50:10 +0100156 if (sig_len > rsa_len) {
157 return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
158 }
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200159
Gilles Peskine449bd832023-01-11 14:50:10 +0100160 return 0;
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200161}
Valerio Setti5c26b302023-06-21 19:47:01 +0200162#endif /* MBEDTLS_USE_PSA_CRYPTO */
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200163
Tomi Fontanilles81746622023-07-16 13:06:06 +0300164#if defined(MBEDTLS_USE_PSA_CRYPTO)
Gilles Peskine449bd832023-01-11 14:50:10 +0100165int mbedtls_pk_psa_rsa_sign_ext(psa_algorithm_t alg,
166 mbedtls_rsa_context *rsa_ctx,
167 const unsigned char *hash, size_t hash_len,
168 unsigned char *sig, size_t sig_size,
169 size_t *sig_len)
Neil Armstrong98545682022-02-22 16:12:51 +0100170{
Neil Armstrong98545682022-02-22 16:12:51 +0100171 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
172 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
173 mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
174 psa_status_t status;
175 mbedtls_pk_context key;
176 int key_len;
Sarvesh Bodakhe430a4f32023-07-27 14:51:25 +0530177 unsigned char *buf = NULL;
178 buf = mbedtls_calloc(1, MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES);
179 if (buf == NULL) {
180 return MBEDTLS_ERR_PK_ALLOC_FAILED;
181 }
Neil Armstrong98545682022-02-22 16:12:51 +0100182 mbedtls_pk_info_t pk_info = mbedtls_rsa_info;
Neil Armstrong98545682022-02-22 16:12:51 +0100183
Gilles Peskine449bd832023-01-11 14:50:10 +0100184 *sig_len = mbedtls_rsa_get_len(rsa_ctx);
185 if (sig_size < *sig_len) {
Sarvesh Bodakhe430a4f32023-07-27 14:51:25 +0530186 mbedtls_free(buf);
Gilles Peskine449bd832023-01-11 14:50:10 +0100187 return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
188 }
Neil Armstrong98545682022-02-22 16:12:51 +0100189
Neil Armstronge4f28682022-02-24 15:41:39 +0100190 /* mbedtls_pk_write_key_der() expects a full PK context;
Neil Armstrong98545682022-02-22 16:12:51 +0100191 * re-construct one to make it happy */
192 key.pk_info = &pk_info;
Jerry Yue010de42022-03-23 11:45:55 +0800193 key.pk_ctx = rsa_ctx;
Sarvesh Bodakhe430a4f32023-07-27 14:51:25 +0530194 key_len = mbedtls_pk_write_key_der(&key, buf, MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES);
Gilles Peskine449bd832023-01-11 14:50:10 +0100195 if (key_len <= 0) {
Sarvesh Bodakhe430a4f32023-07-27 14:51:25 +0530196 mbedtls_free(buf);
Gilles Peskine449bd832023-01-11 14:50:10 +0100197 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
198 }
199 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
200 psa_set_key_algorithm(&attributes, alg);
201 psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
Neil Armstrong98545682022-02-22 16:12:51 +0100202
Gilles Peskine449bd832023-01-11 14:50:10 +0100203 status = psa_import_key(&attributes,
Sarvesh Bodakhe430a4f32023-07-27 14:51:25 +0530204 buf + MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES - key_len, key_len,
Gilles Peskine449bd832023-01-11 14:50:10 +0100205 &key_id);
206 if (status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500207 ret = PSA_PK_TO_MBEDTLS_ERR(status);
Neil Armstrong98545682022-02-22 16:12:51 +0100208 goto cleanup;
209 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100210 status = psa_sign_hash(key_id, alg, hash, hash_len,
211 sig, sig_size, sig_len);
212 if (status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500213 ret = PSA_PK_RSA_TO_MBEDTLS_ERR(status);
Neil Armstrong98545682022-02-22 16:12:51 +0100214 goto cleanup;
215 }
216
217 ret = 0;
218
219cleanup:
Sarvesh Bodakhe430a4f32023-07-27 14:51:25 +0530220 mbedtls_free(buf);
Gilles Peskine449bd832023-01-11 14:50:10 +0100221 status = psa_destroy_key(key_id);
222 if (ret == 0 && status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500223 ret = PSA_PK_TO_MBEDTLS_ERR(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100224 }
225 return ret;
Neil Armstrong98545682022-02-22 16:12:51 +0100226}
Tomi Fontanilles81746622023-07-16 13:06:06 +0300227#endif /* MBEDTLS_USE_PSA_CRYPTO */
Jerry Yu1d172a32022-03-12 19:12:05 +0800228
229#if defined(MBEDTLS_USE_PSA_CRYPTO)
valerio38992cb2023-04-20 09:56:30 +0200230static int rsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100231 const unsigned char *hash, size_t hash_len,
232 unsigned char *sig, size_t sig_size, size_t *sig_len,
233 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Jerry Yu1d172a32022-03-12 19:12:05 +0800234{
Jerry Yu1d172a32022-03-12 19:12:05 +0800235 ((void) f_rng);
236 ((void) p_rng);
Jerry Yu1d172a32022-03-12 19:12:05 +0800237
Jerry Yubd1b3272022-03-24 13:05:20 +0800238 psa_algorithm_t psa_md_alg;
Manuel Pégourié-Gonnard2d6d9932023-03-28 11:38:08 +0200239 psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
Gilles Peskine449bd832023-01-11 14:50:10 +0100240 if (psa_md_alg == 0) {
241 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
242 }
Jerry Yu1d172a32022-03-12 19:12:05 +0800243
Gilles Peskine449bd832023-01-11 14:50:10 +0100244 return mbedtls_pk_psa_rsa_sign_ext(PSA_ALG_RSA_PKCS1V15_SIGN(
245 psa_md_alg),
valerio38992cb2023-04-20 09:56:30 +0200246 pk->pk_ctx, hash, hash_len,
Gilles Peskine449bd832023-01-11 14:50:10 +0100247 sig, sig_size, sig_len);
Jerry Yu1d172a32022-03-12 19:12:05 +0800248}
Valerio Setti5c26b302023-06-21 19:47:01 +0200249#else /* MBEDTLS_USE_PSA_CRYPTO */
valerio38992cb2023-04-20 09:56:30 +0200250static int rsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100251 const unsigned char *hash, size_t hash_len,
252 unsigned char *sig, size_t sig_size, 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{
valerio38992cb2023-04-20 09:56:30 +0200255 mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100256
Dave Rodgman02a53d72023-09-28 17:17:07 +0100257#if SIZE_MAX > UINT_MAX
Gilles Peskine449bd832023-01-11 14:50:10 +0100258 if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) {
259 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
260 }
Dave Rodgman02a53d72023-09-28 17:17:07 +0100261#endif
Andres AG72849872017-01-19 11:24:33 +0000262
Gilles Peskine449bd832023-01-11 14:50:10 +0100263 *sig_len = mbedtls_rsa_get_len(rsa);
264 if (sig_size < *sig_len) {
265 return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
266 }
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200267
Gilles Peskine449bd832023-01-11 14:50:10 +0100268 return mbedtls_rsa_pkcs1_sign(rsa, f_rng, p_rng,
269 md_alg, (unsigned int) hash_len,
270 hash, sig);
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200271}
Valerio Setti5c26b302023-06-21 19:47:01 +0200272#endif /* MBEDTLS_USE_PSA_CRYPTO */
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200273
Neil Armstrong18f43c72022-02-09 15:32:45 +0100274#if defined(MBEDTLS_USE_PSA_CRYPTO)
valerio38992cb2023-04-20 09:56:30 +0200275static int rsa_decrypt_wrap(mbedtls_pk_context *pk,
Gilles Peskine449bd832023-01-11 14:50:10 +0100276 const unsigned char *input, size_t ilen,
277 unsigned char *output, size_t *olen, size_t osize,
278 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Neil Armstrong18f43c72022-02-09 15:32:45 +0100279{
valerio38992cb2023-04-20 09:56:30 +0200280 mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
Neil Armstrong18f43c72022-02-09 15:32:45 +0100281 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
282 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
283 mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
284 psa_status_t status;
285 mbedtls_pk_context key;
286 int key_len;
Neil Armstrongb556a422022-02-25 08:58:12 +0100287 unsigned char buf[MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES];
Neil Armstrong18f43c72022-02-09 15:32:45 +0100288
289 ((void) f_rng);
290 ((void) p_rng);
291
292#if !defined(MBEDTLS_RSA_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100293 if (rsa->padding != MBEDTLS_RSA_PKCS_V15) {
294 return MBEDTLS_ERR_RSA_INVALID_PADDING;
295 }
Neil Armstrong8e805042022-03-16 15:30:31 +0100296#endif /* !MBEDTLS_RSA_ALT */
Neil Armstrong18f43c72022-02-09 15:32:45 +0100297
Gilles Peskine449bd832023-01-11 14:50:10 +0100298 if (ilen != mbedtls_rsa_get_len(rsa)) {
299 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
300 }
Neil Armstrong18f43c72022-02-09 15:32:45 +0100301
302 /* mbedtls_pk_write_key_der() expects a full PK context;
303 * re-construct one to make it happy */
Neil Armstrong6b03a3d2022-03-16 15:31:07 +0100304 key.pk_info = &mbedtls_rsa_info;
valerio38992cb2023-04-20 09:56:30 +0200305 key.pk_ctx = rsa;
Gilles Peskine449bd832023-01-11 14:50:10 +0100306 key_len = mbedtls_pk_write_key_der(&key, buf, sizeof(buf));
307 if (key_len <= 0) {
308 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
309 }
Neil Armstrong18f43c72022-02-09 15:32:45 +0100310
Gilles Peskine449bd832023-01-11 14:50:10 +0100311 psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
312 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT);
313 psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_CRYPT);
Neil Armstrong18f43c72022-02-09 15:32:45 +0100314
Gilles Peskine449bd832023-01-11 14:50:10 +0100315 status = psa_import_key(&attributes,
316 buf + sizeof(buf) - key_len, key_len,
317 &key_id);
318 if (status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500319 ret = PSA_PK_TO_MBEDTLS_ERR(status);
Neil Armstrong18f43c72022-02-09 15:32:45 +0100320 goto cleanup;
321 }
322
Gilles Peskine449bd832023-01-11 14:50:10 +0100323 status = psa_asymmetric_decrypt(key_id, PSA_ALG_RSA_PKCS1V15_CRYPT,
324 input, ilen,
325 NULL, 0,
326 output, osize, olen);
327 if (status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500328 ret = PSA_PK_RSA_TO_MBEDTLS_ERR(status);
Neil Armstrong18f43c72022-02-09 15:32:45 +0100329 goto cleanup;
330 }
331
332 ret = 0;
333
334cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100335 mbedtls_platform_zeroize(buf, sizeof(buf));
336 status = psa_destroy_key(key_id);
337 if (ret == 0 && status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500338 ret = PSA_PK_TO_MBEDTLS_ERR(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100339 }
Neil Armstrongf1b564b2022-02-24 15:17:47 +0100340
Gilles Peskine449bd832023-01-11 14:50:10 +0100341 return ret;
Neil Armstrong18f43c72022-02-09 15:32:45 +0100342}
Valerio Setti5c26b302023-06-21 19:47:01 +0200343#else /* MBEDTLS_USE_PSA_CRYPTO */
valerio38992cb2023-04-20 09:56:30 +0200344static int rsa_decrypt_wrap(mbedtls_pk_context *pk,
Gilles Peskine449bd832023-01-11 14:50:10 +0100345 const unsigned char *input, size_t ilen,
346 unsigned char *output, size_t *olen, size_t osize,
347 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200348{
valerio38992cb2023-04-20 09:56:30 +0200349 mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100350
Gilles Peskine449bd832023-01-11 14:50:10 +0100351 if (ilen != mbedtls_rsa_get_len(rsa)) {
352 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
353 }
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200354
Gilles Peskine449bd832023-01-11 14:50:10 +0100355 return mbedtls_rsa_pkcs1_decrypt(rsa, f_rng, p_rng,
356 olen, input, output, osize);
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200357}
Valerio Setti5c26b302023-06-21 19:47:01 +0200358#endif /* MBEDTLS_USE_PSA_CRYPTO */
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200359
Neil Armstrong96a16a42022-02-10 10:40:11 +0100360#if defined(MBEDTLS_USE_PSA_CRYPTO)
valerio38992cb2023-04-20 09:56:30 +0200361static int rsa_encrypt_wrap(mbedtls_pk_context *pk,
Gilles Peskine449bd832023-01-11 14:50:10 +0100362 const unsigned char *input, size_t ilen,
363 unsigned char *output, size_t *olen, size_t osize,
364 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Neil Armstrong96a16a42022-02-10 10:40:11 +0100365{
valerio38992cb2023-04-20 09:56:30 +0200366 mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
Neil Armstrong96a16a42022-02-10 10:40:11 +0100367 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
368 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
369 mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
370 psa_status_t status;
371 mbedtls_pk_context key;
372 int key_len;
Neil Armstrongdeb4bfb2022-02-25 08:58:12 +0100373 unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES];
Neil Armstrong96a16a42022-02-10 10:40:11 +0100374
375 ((void) f_rng);
376 ((void) p_rng);
377
378#if !defined(MBEDTLS_RSA_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100379 if (rsa->padding != MBEDTLS_RSA_PKCS_V15) {
380 return MBEDTLS_ERR_RSA_INVALID_PADDING;
381 }
Neil Armstrong96a16a42022-02-10 10:40:11 +0100382#endif
383
Gilles Peskine449bd832023-01-11 14:50:10 +0100384 if (mbedtls_rsa_get_len(rsa) > osize) {
385 return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
386 }
Neil Armstrong96a16a42022-02-10 10:40:11 +0100387
Neil Armstrongac014ca2022-02-24 15:27:54 +0100388 /* mbedtls_pk_write_pubkey_der() expects a full PK context;
Neil Armstrong96a16a42022-02-10 10:40:11 +0100389 * re-construct one to make it happy */
Neil Armstrongda1d80d2022-03-16 15:36:32 +0100390 key.pk_info = &mbedtls_rsa_info;
valerio38992cb2023-04-20 09:56:30 +0200391 key.pk_ctx = rsa;
Gilles Peskine449bd832023-01-11 14:50:10 +0100392 key_len = mbedtls_pk_write_pubkey_der(&key, buf, sizeof(buf));
393 if (key_len <= 0) {
394 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
395 }
Neil Armstrong96a16a42022-02-10 10:40:11 +0100396
Gilles Peskine449bd832023-01-11 14:50:10 +0100397 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT);
398 psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_CRYPT);
399 psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY);
Neil Armstrong96a16a42022-02-10 10:40:11 +0100400
Gilles Peskine449bd832023-01-11 14:50:10 +0100401 status = psa_import_key(&attributes,
402 buf + sizeof(buf) - key_len, key_len,
403 &key_id);
404 if (status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500405 ret = PSA_PK_TO_MBEDTLS_ERR(status);
Neil Armstrong96a16a42022-02-10 10:40:11 +0100406 goto cleanup;
407 }
408
Gilles Peskine449bd832023-01-11 14:50:10 +0100409 status = psa_asymmetric_encrypt(key_id, PSA_ALG_RSA_PKCS1V15_CRYPT,
410 input, ilen,
411 NULL, 0,
412 output, osize, olen);
413 if (status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500414 ret = PSA_PK_RSA_TO_MBEDTLS_ERR(status);
Neil Armstrong96a16a42022-02-10 10:40:11 +0100415 goto cleanup;
416 }
417
418 ret = 0;
419
420cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100421 status = psa_destroy_key(key_id);
422 if (ret == 0 && status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500423 ret = PSA_PK_TO_MBEDTLS_ERR(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100424 }
Neil Armstrong7dd3b202022-02-24 15:29:18 +0100425
Gilles Peskine449bd832023-01-11 14:50:10 +0100426 return ret;
Neil Armstrong96a16a42022-02-10 10:40:11 +0100427}
Valerio Setti5c26b302023-06-21 19:47:01 +0200428#else /* MBEDTLS_USE_PSA_CRYPTO */
valerio38992cb2023-04-20 09:56:30 +0200429static int rsa_encrypt_wrap(mbedtls_pk_context *pk,
Gilles Peskine449bd832023-01-11 14:50:10 +0100430 const unsigned char *input, size_t ilen,
431 unsigned char *output, size_t *olen, size_t osize,
432 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200433{
valerio38992cb2023-04-20 09:56:30 +0200434 mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
Gilles Peskine449bd832023-01-11 14:50:10 +0100435 *olen = mbedtls_rsa_get_len(rsa);
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200436
Gilles Peskine449bd832023-01-11 14:50:10 +0100437 if (*olen > osize) {
438 return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
439 }
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100440
Gilles Peskine449bd832023-01-11 14:50:10 +0100441 return mbedtls_rsa_pkcs1_encrypt(rsa, f_rng, p_rng,
442 ilen, input, output);
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200443}
Valerio Setti5c26b302023-06-21 19:47:01 +0200444#endif /* MBEDTLS_USE_PSA_CRYPTO */
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200445
valerio38992cb2023-04-20 09:56:30 +0200446static int rsa_check_pair_wrap(mbedtls_pk_context *pub, mbedtls_pk_context *prv,
Gilles Peskine449bd832023-01-11 14:50:10 +0100447 int (*f_rng)(void *, unsigned char *, size_t),
448 void *p_rng)
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100449{
Manuel Pégourié-Gonnard39be1412021-06-15 11:29:26 +0200450 (void) f_rng;
451 (void) p_rng;
valerio38992cb2023-04-20 09:56:30 +0200452 return mbedtls_rsa_check_pub_priv((const mbedtls_rsa_context *) pub->pk_ctx,
453 (const mbedtls_rsa_context *) prv->pk_ctx);
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100454}
455
Gilles Peskine449bd832023-01-11 14:50:10 +0100456static void *rsa_alloc_wrap(void)
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200457{
Gilles Peskine449bd832023-01-11 14:50:10 +0100458 void *ctx = mbedtls_calloc(1, sizeof(mbedtls_rsa_context));
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200459
Gilles Peskine449bd832023-01-11 14:50:10 +0100460 if (ctx != NULL) {
461 mbedtls_rsa_init((mbedtls_rsa_context *) ctx);
462 }
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200463
Gilles Peskine449bd832023-01-11 14:50:10 +0100464 return ctx;
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200465}
466
Gilles Peskine449bd832023-01-11 14:50:10 +0100467static void rsa_free_wrap(void *ctx)
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200468{
Gilles Peskine449bd832023-01-11 14:50:10 +0100469 mbedtls_rsa_free((mbedtls_rsa_context *) ctx);
470 mbedtls_free(ctx);
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200471}
472
valerio38992cb2023-04-20 09:56:30 +0200473static void rsa_debug(mbedtls_pk_context *pk, mbedtls_pk_debug_item *items)
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200474{
Gilles Peskine85b1bc62021-05-25 09:20:26 +0200475#if defined(MBEDTLS_RSA_ALT)
476 /* Not supported */
valerio38992cb2023-04-20 09:56:30 +0200477 (void) pk;
Gilles Peskine85b1bc62021-05-25 09:20:26 +0200478 (void) items;
479#else
valerio38992cb2023-04-20 09:56:30 +0200480 mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx;
481
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200482 items->type = MBEDTLS_PK_DEBUG_MPI;
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200483 items->name = "rsa.N";
valerio38992cb2023-04-20 09:56:30 +0200484 items->value = &(rsa->N);
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200485
486 items++;
487
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200488 items->type = MBEDTLS_PK_DEBUG_MPI;
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200489 items->name = "rsa.E";
valerio38992cb2023-04-20 09:56:30 +0200490 items->value = &(rsa->E);
Gilles Peskine85b1bc62021-05-25 09:20:26 +0200491#endif
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200492}
493
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494const mbedtls_pk_info_t mbedtls_rsa_info = {
Valerio Settif69514a2023-06-21 18:16:49 +0200495 .type = MBEDTLS_PK_RSA,
496 .name = "RSA",
497 .get_bitlen = rsa_get_bitlen,
498 .can_do = rsa_can_do,
499 .verify_func = rsa_verify_wrap,
500 .sign_func = rsa_sign_wrap,
Valerio Setti97976e32023-06-23 14:08:26 +0200501#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
502 .verify_rs_func = NULL,
503 .sign_rs_func = NULL,
504 .rs_alloc_func = NULL,
505 .rs_free_func = NULL,
506#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Valerio Settif69514a2023-06-21 18:16:49 +0200507 .decrypt_func = rsa_decrypt_wrap,
508 .encrypt_func = rsa_encrypt_wrap,
509 .check_pair_func = rsa_check_pair_wrap,
510 .ctx_alloc_func = rsa_alloc_wrap,
511 .ctx_free_func = rsa_free_wrap,
512 .debug_func = rsa_debug,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200513};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200514#endif /* MBEDTLS_RSA_C */
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200515
Valerio Setti81d75122023-06-14 14:49:33 +0200516#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200517/*
518 * Generic EC key
519 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100520static int eckey_can_do(mbedtls_pk_type_t type)
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200521{
Gilles Peskine449bd832023-01-11 14:50:10 +0100522 return type == MBEDTLS_PK_ECKEY ||
523 type == MBEDTLS_PK_ECKEY_DH ||
524 type == MBEDTLS_PK_ECDSA;
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200525}
526
valerio38992cb2023-04-20 09:56:30 +0200527static size_t eckey_get_bitlen(mbedtls_pk_context *pk)
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200528{
Valerio Settia1b8af62023-05-17 15:34:57 +0200529#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
530 return pk->ec_bits;
Valerio Setti5c26b302023-06-21 19:47:01 +0200531#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
valerio38992cb2023-04-20 09:56:30 +0200532 mbedtls_ecp_keypair *ecp = (mbedtls_ecp_keypair *) pk->pk_ctx;
533 return ecp->grp.pbits;
Valerio Setti5c26b302023-06-21 19:47:01 +0200534#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200535}
536
Valerio Setti1cdddac2023-02-02 13:55:57 +0100537#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY)
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400538#if defined(MBEDTLS_USE_PSA_CRYPTO)
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400539/*
Andrzej Kurek9241d182018-11-20 05:04:35 -0500540 * An ASN.1 encoded signature is a sequence of two ASN.1 integers. Parse one of
541 * those integers and convert it to the fixed-length encoding expected by PSA.
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500542 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100543static int extract_ecdsa_sig_int(unsigned char **from, const unsigned char *end,
544 unsigned char *to, size_t to_len)
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500545{
Janos Follath24eed8d2019-11-22 13:21:35 +0000546 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurek9241d182018-11-20 05:04:35 -0500547 size_t unpadded_len, padding_len;
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500548
Gilles Peskine449bd832023-01-11 14:50:10 +0100549 if ((ret = mbedtls_asn1_get_tag(from, end, &unpadded_len,
550 MBEDTLS_ASN1_INTEGER)) != 0) {
551 return ret;
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500552 }
553
Gilles Peskine449bd832023-01-11 14:50:10 +0100554 while (unpadded_len > 0 && **from == 0x00) {
555 (*from)++;
Andrzej Kurek9241d182018-11-20 05:04:35 -0500556 unpadded_len--;
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500557 }
558
Gilles Peskine449bd832023-01-11 14:50:10 +0100559 if (unpadded_len > to_len || unpadded_len == 0) {
560 return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
561 }
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500562
Andrzej Kurek9241d182018-11-20 05:04:35 -0500563 padding_len = to_len - unpadded_len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100564 memset(to, 0x00, padding_len);
565 memcpy(to + padding_len, *from, unpadded_len);
566 (*from) += unpadded_len;
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500567
Gilles Peskine449bd832023-01-11 14:50:10 +0100568 return 0;
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500569}
570
571/*
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400572 * Convert a signature from an ASN.1 sequence of two integers
Andrzej Kurek9241d182018-11-20 05:04:35 -0500573 * to a raw {r,s} buffer. Note: the provided sig buffer must be at least
Andrzej Kurekb6016c52018-11-19 17:41:58 -0500574 * twice as big as int_size.
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400575 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100576static int extract_ecdsa_sig(unsigned char **p, const unsigned char *end,
577 unsigned char *sig, size_t int_size)
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400578{
Janos Follath24eed8d2019-11-22 13:21:35 +0000579 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurek9241d182018-11-20 05:04:35 -0500580 size_t tmp_size;
Andrzej Kurek3f864c22018-11-07 09:30:50 -0500581
Gilles Peskine449bd832023-01-11 14:50:10 +0100582 if ((ret = mbedtls_asn1_get_tag(p, end, &tmp_size,
583 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
584 return ret;
585 }
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400586
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500587 /* Extract r */
Gilles Peskine449bd832023-01-11 14:50:10 +0100588 if ((ret = extract_ecdsa_sig_int(p, end, sig, int_size)) != 0) {
589 return ret;
590 }
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500591 /* Extract s */
Gilles Peskine449bd832023-01-11 14:50:10 +0100592 if ((ret = extract_ecdsa_sig_int(p, end, sig + int_size, int_size)) != 0) {
593 return ret;
594 }
Andrzej Kurek3f864c22018-11-07 09:30:50 -0500595
Gilles Peskine449bd832023-01-11 14:50:10 +0100596 return 0;
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400597}
598
Valerio Setti76d0f962023-06-23 13:32:54 +0200599/* Common helper for ECDSA verify using PSA functions. */
Valerio Settied7d6af2023-06-21 15:42:21 +0200600static int ecdsa_verify_psa(unsigned char *key, size_t key_len,
601 psa_ecc_family_t curve, size_t curve_bits,
602 const unsigned char *hash, size_t hash_len,
603 const unsigned char *sig, size_t sig_len)
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400604{
Janos Follath24eed8d2019-11-22 13:21:35 +0000605 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskined2d45c12019-05-27 14:53:13 +0200606 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Andrzej Kurek03e01462022-01-03 12:53:24 +0100607 mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
Valerio Settia1b8af62023-05-17 15:34:57 +0200608 psa_algorithm_t psa_sig_md = PSA_ALG_ECDSA_ANY;
Valerio Settied7d6af2023-06-21 15:42:21 +0200609 size_t signature_len = PSA_ECDSA_SIGNATURE_SIZE(curve_bits);
610 unsigned char extracted_sig[PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE];
611 unsigned char *p;
612 psa_status_t status;
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400613
Gilles Peskine449bd832023-01-11 14:50:10 +0100614 if (curve == 0) {
615 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
616 }
Andrzej Kurekb3d1b122018-11-07 08:18:52 -0500617
Gilles Peskine449bd832023-01-11 14:50:10 +0100618 psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve));
619 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH);
620 psa_set_key_algorithm(&attributes, psa_sig_md);
Andrzej Kurek2349c4d2019-01-08 09:36:01 -0500621
Valerio Settied7d6af2023-06-21 15:42:21 +0200622 status = psa_import_key(&attributes, key, key_len, &key_id);
Gilles Peskine449bd832023-01-11 14:50:10 +0100623 if (status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500624 ret = PSA_PK_TO_MBEDTLS_ERR(status);
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400625 goto cleanup;
626 }
627
Valerio Settied7d6af2023-06-21 15:42:21 +0200628 if (signature_len > sizeof(extracted_sig)) {
Andrzej Kurekb6016c52018-11-19 17:41:58 -0500629 ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;
630 goto cleanup;
631 }
Andrzej Kurekb6016c52018-11-19 17:41:58 -0500632
Gilles Peskine449bd832023-01-11 14:50:10 +0100633 p = (unsigned char *) sig;
Valerio Settia1b8af62023-05-17 15:34:57 +0200634 /* extract_ecdsa_sig's last parameter is the size
Valerio Settif57007d2023-05-19 13:54:39 +0200635 * of each integer to be parsed, so it's actually half
Valerio Settia1b8af62023-05-17 15:34:57 +0200636 * the size of the signature. */
Valerio Settied7d6af2023-06-21 15:42:21 +0200637 if ((ret = extract_ecdsa_sig(&p, sig + sig_len, extracted_sig,
Valerio Settia1b8af62023-05-17 15:34:57 +0200638 signature_len/2)) != 0) {
Andrzej Kurekb6016c52018-11-19 17:41:58 -0500639 goto cleanup;
640 }
641
Valerio Settied7d6af2023-06-21 15:42:21 +0200642 status = psa_verify_hash(key_id, psa_sig_md, hash, hash_len,
643 extracted_sig, signature_len);
Gilles Peskine449bd832023-01-11 14:50:10 +0100644 if (status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500645 ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100646 goto cleanup;
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400647 }
Andrzej Kurekad5d5812018-11-20 07:59:18 -0500648
Gilles Peskine449bd832023-01-11 14:50:10 +0100649 if (p != sig + sig_len) {
Andrzej Kurekad5d5812018-11-20 07:59:18 -0500650 ret = MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
651 goto cleanup;
652 }
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400653 ret = 0;
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400654
Andrzej Kurekb7b04782018-11-19 17:01:16 -0500655cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100656 status = psa_destroy_key(key_id);
657 if (ret == 0 && status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500658 ret = PSA_PK_TO_MBEDTLS_ERR(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100659 }
Neil Armstrong9dccd862022-02-24 15:33:13 +0100660
Gilles Peskine449bd832023-01-11 14:50:10 +0100661 return ret;
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400662}
Valerio Settied7d6af2023-06-21 15:42:21 +0200663
Valerio Setti76d0f962023-06-23 13:32:54 +0200664static int ecdsa_opaque_verify_wrap(mbedtls_pk_context *pk,
665 mbedtls_md_type_t md_alg,
666 const unsigned char *hash, size_t hash_len,
667 const unsigned char *sig, size_t sig_len)
Valerio Settie7730772023-06-21 16:58:40 +0200668{
669 (void) md_alg;
670 unsigned char key[MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN];
671 size_t key_len;
672 psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
673 psa_ecc_family_t curve;
674 size_t curve_bits;
675 psa_status_t status;
676
677 status = psa_get_key_attributes(pk->priv_id, &key_attr);
678 if (status != PSA_SUCCESS) {
679 return PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
680 }
681 curve = PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(&key_attr));
682 curve_bits = psa_get_key_bits(&key_attr);
683 psa_reset_key_attributes(&key_attr);
684
685 status = psa_export_public_key(pk->priv_id, key, sizeof(key), &key_len);
686 if (status != PSA_SUCCESS) {
687 return PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
688 }
689
690 return ecdsa_verify_psa(key, key_len, curve, curve_bits,
691 hash, hash_len, sig, sig_len);
692}
693
Valerio Settied7d6af2023-06-21 15:42:21 +0200694#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
695static int ecdsa_verify_wrap(mbedtls_pk_context *pk,
696 mbedtls_md_type_t md_alg,
697 const unsigned char *hash, size_t hash_len,
698 const unsigned char *sig, size_t sig_len)
699{
700 (void) md_alg;
701 psa_ecc_family_t curve = pk->ec_family;
702 size_t curve_bits = pk->ec_bits;
703
704 return ecdsa_verify_psa(pk->pub_raw, pk->pub_raw_len, curve, curve_bits,
705 hash, hash_len, sig, sig_len);
706}
707#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
708static int ecdsa_verify_wrap(mbedtls_pk_context *pk,
709 mbedtls_md_type_t md_alg,
710 const unsigned char *hash, size_t hash_len,
711 const unsigned char *sig, size_t sig_len)
712{
713 (void) md_alg;
714 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
715 mbedtls_ecp_keypair *ctx = pk->pk_ctx;
716 unsigned char key[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
717 size_t key_len;
718 size_t curve_bits;
719 psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(ctx->grp.id, &curve_bits);
720
721 ret = mbedtls_ecp_point_write_binary(&ctx->grp, &ctx->Q,
722 MBEDTLS_ECP_PF_UNCOMPRESSED,
723 &key_len, key, sizeof(key));
724 if (ret != 0) {
725 return ret;
726 }
727
728 return ecdsa_verify_psa(key, key_len, curve, curve_bits,
729 hash, hash_len, sig, sig_len);
730}
731#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400732#else /* MBEDTLS_USE_PSA_CRYPTO */
valerio38992cb2023-04-20 09:56:30 +0200733static int ecdsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100734 const unsigned char *hash, size_t hash_len,
735 const unsigned char *sig, size_t sig_len)
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200736{
Janos Follath24eed8d2019-11-22 13:21:35 +0000737 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200738 ((void) md_alg);
739
valerio38992cb2023-04-20 09:56:30 +0200740 ret = mbedtls_ecdsa_read_signature((mbedtls_ecdsa_context *) pk->pk_ctx,
Gilles Peskine449bd832023-01-11 14:50:10 +0100741 hash, hash_len, sig, sig_len);
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200742
Gilles Peskine449bd832023-01-11 14:50:10 +0100743 if (ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) {
744 return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
745 }
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200746
Gilles Peskine449bd832023-01-11 14:50:10 +0100747 return ret;
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200748}
Andrzej Kurek8b036a62018-10-31 05:16:46 -0400749#endif /* MBEDTLS_USE_PSA_CRYPTO */
Valerio Setti1cdddac2023-02-02 13:55:57 +0100750#endif /* MBEDTLS_PK_CAN_ECDSA_VERIFY */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200751
Valerio Setti1cdddac2023-02-02 13:55:57 +0100752#if defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
Neil Armstronge9606902022-02-09 14:23:00 +0100753#if defined(MBEDTLS_USE_PSA_CRYPTO)
Neil Armstrong15021652022-03-01 10:14:17 +0100754/*
755 * Simultaneously convert and move raw MPI from the beginning of a buffer
756 * to an ASN.1 MPI at the end of the buffer.
757 * See also mbedtls_asn1_write_mpi().
758 *
759 * p: pointer to the end of the output buffer
760 * start: start of the output buffer, and also of the mpi to write at the end
761 * n_len: length of the mpi to read from start
762 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100763static int asn1_write_mpibuf(unsigned char **p, unsigned char *start,
764 size_t n_len)
Neil Armstrong15021652022-03-01 10:14:17 +0100765{
766 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
767 size_t len = 0;
768
Gilles Peskine449bd832023-01-11 14:50:10 +0100769 if ((size_t) (*p - start) < n_len) {
770 return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
771 }
Neil Armstrong15021652022-03-01 10:14:17 +0100772
773 len = n_len;
774 *p -= len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100775 memmove(*p, start, len);
Neil Armstrong15021652022-03-01 10:14:17 +0100776
777 /* ASN.1 DER encoding requires minimal length, so skip leading 0s.
778 * Neither r nor s should be 0, but as a failsafe measure, still detect
779 * that rather than overflowing the buffer in case of a PSA error. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100780 while (len > 0 && **p == 0x00) {
Neil Armstrong15021652022-03-01 10:14:17 +0100781 ++(*p);
782 --len;
783 }
784
785 /* this is only reached if the signature was invalid */
Gilles Peskine449bd832023-01-11 14:50:10 +0100786 if (len == 0) {
787 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
788 }
Neil Armstrong15021652022-03-01 10:14:17 +0100789
790 /* if the msb is 1, ASN.1 requires that we prepend a 0.
791 * Neither r nor s can be 0, so we can assume len > 0 at all times. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100792 if (**p & 0x80) {
793 if (*p - start < 1) {
794 return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
795 }
Neil Armstrong15021652022-03-01 10:14:17 +0100796
797 *--(*p) = 0x00;
798 len += 1;
799 }
800
Gilles Peskine449bd832023-01-11 14:50:10 +0100801 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len));
802 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start,
803 MBEDTLS_ASN1_INTEGER));
Neil Armstrong15021652022-03-01 10:14:17 +0100804
Gilles Peskine449bd832023-01-11 14:50:10 +0100805 return (int) len;
Neil Armstrong15021652022-03-01 10:14:17 +0100806}
807
808/* Transcode signature from PSA format to ASN.1 sequence.
809 * See ecdsa_signature_to_asn1 in ecdsa.c, but with byte buffers instead of
810 * MPIs, and in-place.
811 *
812 * [in/out] sig: the signature pre- and post-transcoding
813 * [in/out] sig_len: signature length pre- and post-transcoding
814 * [int] buf_len: the available size the in/out buffer
815 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100816static int pk_ecdsa_sig_asn1_from_psa(unsigned char *sig, size_t *sig_len,
817 size_t buf_len)
Neil Armstrong15021652022-03-01 10:14:17 +0100818{
819 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
820 size_t len = 0;
821 const size_t rs_len = *sig_len / 2;
822 unsigned char *p = sig + buf_len;
823
Gilles Peskine449bd832023-01-11 14:50:10 +0100824 MBEDTLS_ASN1_CHK_ADD(len, asn1_write_mpibuf(&p, sig + rs_len, rs_len));
825 MBEDTLS_ASN1_CHK_ADD(len, asn1_write_mpibuf(&p, sig, rs_len));
Neil Armstrong15021652022-03-01 10:14:17 +0100826
Gilles Peskine449bd832023-01-11 14:50:10 +0100827 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, sig, len));
828 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, sig,
829 MBEDTLS_ASN1_CONSTRUCTED |
830 MBEDTLS_ASN1_SEQUENCE));
Neil Armstrong15021652022-03-01 10:14:17 +0100831
Gilles Peskine449bd832023-01-11 14:50:10 +0100832 memmove(sig, p, len);
Neil Armstrong15021652022-03-01 10:14:17 +0100833 *sig_len = len;
834
Gilles Peskine449bd832023-01-11 14:50:10 +0100835 return 0;
Neil Armstrong15021652022-03-01 10:14:17 +0100836}
Neil Armstronge9606902022-02-09 14:23:00 +0100837
Valerio Setti4ac2c182023-12-05 07:59:01 +0100838/* Common helper for ECDSA sign using PSA functions.
839 * Instead of extracting key's properties in order to check which kind of ECDSA
840 * signature it supports, we try both deterministic and non-deterministic.
841 */
Valerio Setti884c1ec2023-06-23 12:09:13 +0200842static int ecdsa_sign_psa(mbedtls_svc_key_id_t key_id, mbedtls_md_type_t md_alg,
Valerio Setti4657f102023-06-21 13:55:16 +0200843 const unsigned char *hash, size_t hash_len,
844 unsigned char *sig, size_t sig_size, size_t *sig_len)
845{
846 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
847 psa_status_t status;
Valerio Setti884c1ec2023-06-23 12:09:13 +0200848
Valerio Setti4ac2c182023-12-05 07:59:01 +0100849 status = psa_sign_hash(key_id,
850 PSA_ALG_DETERMINISTIC_ECDSA(mbedtls_md_psa_alg_from_type(md_alg)),
851 hash, hash_len, sig, sig_size, sig_len);
852 if (status == PSA_SUCCESS) {
853 goto done;
854 } else if (status != PSA_ERROR_NOT_PERMITTED) {
Valerio Setti884c1ec2023-06-23 12:09:13 +0200855 return PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
856 }
Valerio Setti884c1ec2023-06-23 12:09:13 +0200857
Valerio Setti4ac2c182023-12-05 07:59:01 +0100858 status = psa_sign_hash(key_id,
859 PSA_ALG_ECDSA(mbedtls_md_psa_alg_from_type(md_alg)),
860 hash, hash_len, sig, sig_size, sig_len);
Valerio Setti4657f102023-06-21 13:55:16 +0200861 if (status != PSA_SUCCESS) {
862 return PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
863 }
864
Valerio Setti4ac2c182023-12-05 07:59:01 +0100865done:
Valerio Setti4657f102023-06-21 13:55:16 +0200866 ret = pk_ecdsa_sig_asn1_from_psa(sig, sig_len, sig_size);
867
868 return ret;
869}
870
Valerio Setti76d0f962023-06-23 13:32:54 +0200871static int ecdsa_opaque_sign_wrap(mbedtls_pk_context *pk,
872 mbedtls_md_type_t md_alg,
873 const unsigned char *hash, size_t hash_len,
874 unsigned char *sig, size_t sig_size,
875 size_t *sig_len,
876 int (*f_rng)(void *, unsigned char *, size_t),
877 void *p_rng)
Valerio Setti4657f102023-06-21 13:55:16 +0200878{
879 ((void) f_rng);
880 ((void) p_rng);
Valerio Setti4657f102023-06-21 13:55:16 +0200881
Valerio Setti884c1ec2023-06-23 12:09:13 +0200882 return ecdsa_sign_psa(pk->priv_id, md_alg, hash, hash_len, sig, sig_size,
Valerio Setti4657f102023-06-21 13:55:16 +0200883 sig_len);
884}
885
886#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
Valerio Setti76d0f962023-06-23 13:32:54 +0200887/* When PK_USE_PSA_EC_DATA is defined opaque and non-opaque keys end up
888 * using the same function. */
889#define ecdsa_sign_wrap ecdsa_opaque_sign_wrap
Valerio Setti4657f102023-06-21 13:55:16 +0200890#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
valerio38992cb2023-04-20 09:56:30 +0200891static int ecdsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100892 const unsigned char *hash, size_t hash_len,
893 unsigned char *sig, size_t sig_size, size_t *sig_len,
894 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Neil Armstronge9606902022-02-09 14:23:00 +0100895{
Neil Armstronge9606902022-02-09 14:23:00 +0100896 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Neil Armstronge9606902022-02-09 14:23:00 +0100897 mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
898 psa_status_t status;
Valerio Settiae8c6282023-05-18 18:57:57 +0200899 mbedtls_ecp_keypair *ctx = pk->pk_ctx;
900 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
901 unsigned char buf[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH];
Neil Armstronge9606902022-02-09 14:23:00 +0100902 size_t curve_bits;
903 psa_ecc_family_t curve =
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 mbedtls_ecc_group_to_psa(ctx->grp.id, &curve_bits);
Gilles Peskine13caa942022-10-04 22:59:26 +0200905 size_t key_len = PSA_BITS_TO_BYTES(curve_bits);
Manuel Pégourié-Gonnard116175c2023-07-25 12:06:55 +0200906 psa_algorithm_t psa_hash = mbedtls_md_psa_alg_from_type(md_alg);
907 psa_algorithm_t psa_sig_md = MBEDTLS_PK_PSA_ALG_ECDSA_MAYBE_DET(psa_hash);
Neil Armstronge9606902022-02-09 14:23:00 +0100908 ((void) f_rng);
909 ((void) p_rng);
910
Gilles Peskine449bd832023-01-11 14:50:10 +0100911 if (curve == 0) {
912 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
913 }
Neil Armstronge9606902022-02-09 14:23:00 +0100914
Gilles Peskine13caa942022-10-04 22:59:26 +0200915 if (key_len > sizeof(buf)) {
Valerio Settib761b152023-01-31 14:56:04 +0100916 return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine449bd832023-01-11 14:50:10 +0100917 }
Gilles Peskine13caa942022-10-04 22:59:26 +0200918 ret = mbedtls_mpi_write_binary(&ctx->d, buf, key_len);
Gilles Peskine449bd832023-01-11 14:50:10 +0100919 if (ret != 0) {
Neil Armstronge9606902022-02-09 14:23:00 +0100920 goto cleanup;
921 }
922
Gilles Peskine449bd832023-01-11 14:50:10 +0100923 psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
924 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
925 psa_set_key_algorithm(&attributes, psa_sig_md);
926
Valerio Setti4657f102023-06-21 13:55:16 +0200927 status = psa_import_key(&attributes, buf, key_len, &key_id);
Gilles Peskine449bd832023-01-11 14:50:10 +0100928 if (status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500929 ret = PSA_PK_TO_MBEDTLS_ERR(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100930 goto cleanup;
Neil Armstronge9606902022-02-09 14:23:00 +0100931 }
932
Valerio Setti884c1ec2023-06-23 12:09:13 +0200933 ret = ecdsa_sign_psa(key_id, md_alg, hash, hash_len, sig, sig_size, sig_len);
Neil Armstronge9606902022-02-09 14:23:00 +0100934
935cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100936 mbedtls_platform_zeroize(buf, sizeof(buf));
937 status = psa_destroy_key(key_id);
938 if (ret == 0 && status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500939 ret = PSA_PK_TO_MBEDTLS_ERR(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100940 }
Neil Armstrongff70f0b2022-03-03 14:31:17 +0100941
Gilles Peskine449bd832023-01-11 14:50:10 +0100942 return ret;
Neil Armstronge9606902022-02-09 14:23:00 +0100943}
Valerio Setti4657f102023-06-21 13:55:16 +0200944#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
Valerio Setti1cdddac2023-02-02 13:55:57 +0100945#else /* MBEDTLS_USE_PSA_CRYPTO */
valerio38992cb2023-04-20 09:56:30 +0200946static int ecdsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100947 const unsigned char *hash, size_t hash_len,
948 unsigned char *sig, size_t sig_size, size_t *sig_len,
949 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200950{
valerio38992cb2023-04-20 09:56:30 +0200951 return mbedtls_ecdsa_write_signature((mbedtls_ecdsa_context *) pk->pk_ctx,
Gilles Peskine449bd832023-01-11 14:50:10 +0100952 md_alg, hash, hash_len,
953 sig, sig_size, sig_len,
954 f_rng, p_rng);
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200955}
Valerio Setti1cdddac2023-02-02 13:55:57 +0100956#endif /* MBEDTLS_USE_PSA_CRYPTO */
957#endif /* MBEDTLS_PK_CAN_ECDSA_SIGN */
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200958
Valerio Setti80d07982023-02-08 13:49:17 +0100959#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Valerio Setti1cdddac2023-02-02 13:55:57 +0100960/* Forward declarations */
valerio38992cb2023-04-20 09:56:30 +0200961static int ecdsa_verify_rs_wrap(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
Valerio Setti1cdddac2023-02-02 13:55:57 +0100962 const unsigned char *hash, size_t hash_len,
963 const unsigned char *sig, size_t sig_len,
964 void *rs_ctx);
965
valerio38992cb2023-04-20 09:56:30 +0200966static int ecdsa_sign_rs_wrap(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
Valerio Setti1cdddac2023-02-02 13:55:57 +0100967 const unsigned char *hash, size_t hash_len,
968 unsigned char *sig, size_t sig_size, size_t *sig_len,
969 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
970 void *rs_ctx);
971
972/*
973 * Restart context for ECDSA operations with ECKEY context
974 *
975 * We need to store an actual ECDSA context, as we need to pass the same to
976 * the underlying ecdsa function, so we can't create it on the fly every time.
977 */
978typedef struct {
979 mbedtls_ecdsa_restart_ctx ecdsa_rs;
980 mbedtls_ecdsa_context ecdsa_ctx;
981} eckey_restart_ctx;
982
983static void *eckey_rs_alloc(void)
984{
985 eckey_restart_ctx *rs_ctx;
986
987 void *ctx = mbedtls_calloc(1, sizeof(eckey_restart_ctx));
988
989 if (ctx != NULL) {
990 rs_ctx = ctx;
991 mbedtls_ecdsa_restart_init(&rs_ctx->ecdsa_rs);
992 mbedtls_ecdsa_init(&rs_ctx->ecdsa_ctx);
993 }
994
995 return ctx;
996}
997
998static void eckey_rs_free(void *ctx)
999{
1000 eckey_restart_ctx *rs_ctx;
1001
1002 if (ctx == NULL) {
1003 return;
1004 }
1005
1006 rs_ctx = ctx;
1007 mbedtls_ecdsa_restart_free(&rs_ctx->ecdsa_rs);
1008 mbedtls_ecdsa_free(&rs_ctx->ecdsa_ctx);
1009
1010 mbedtls_free(ctx);
1011}
1012
valerio38992cb2023-04-20 09:56:30 +02001013static int eckey_verify_rs_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
Valerio Setti1cdddac2023-02-02 13:55:57 +01001014 const unsigned char *hash, size_t hash_len,
1015 const unsigned char *sig, size_t sig_len,
1016 void *rs_ctx)
1017{
1018 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1019 eckey_restart_ctx *rs = rs_ctx;
1020
1021 /* Should never happen */
1022 if (rs == NULL) {
1023 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1024 }
1025
1026 /* set up our own sub-context if needed (that is, on first run) */
1027 if (rs->ecdsa_ctx.grp.pbits == 0) {
valerio38992cb2023-04-20 09:56:30 +02001028 MBEDTLS_MPI_CHK(mbedtls_ecdsa_from_keypair(&rs->ecdsa_ctx, pk->pk_ctx));
Valerio Setti1cdddac2023-02-02 13:55:57 +01001029 }
1030
valerio38992cb2023-04-20 09:56:30 +02001031 MBEDTLS_MPI_CHK(ecdsa_verify_rs_wrap(pk,
Valerio Setti1cdddac2023-02-02 13:55:57 +01001032 md_alg, hash, hash_len,
1033 sig, sig_len, &rs->ecdsa_rs));
1034
1035cleanup:
1036 return ret;
1037}
1038
valerio38992cb2023-04-20 09:56:30 +02001039static int eckey_sign_rs_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
Valerio Setti1cdddac2023-02-02 13:55:57 +01001040 const unsigned char *hash, size_t hash_len,
1041 unsigned char *sig, size_t sig_size, size_t *sig_len,
1042 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
1043 void *rs_ctx)
1044{
1045 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1046 eckey_restart_ctx *rs = rs_ctx;
1047
1048 /* Should never happen */
1049 if (rs == NULL) {
1050 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1051 }
1052
1053 /* set up our own sub-context if needed (that is, on first run) */
1054 if (rs->ecdsa_ctx.grp.pbits == 0) {
valerio38992cb2023-04-20 09:56:30 +02001055 MBEDTLS_MPI_CHK(mbedtls_ecdsa_from_keypair(&rs->ecdsa_ctx, pk->pk_ctx));
Valerio Setti1cdddac2023-02-02 13:55:57 +01001056 }
1057
valerio38992cb2023-04-20 09:56:30 +02001058 MBEDTLS_MPI_CHK(ecdsa_sign_rs_wrap(pk, md_alg,
Valerio Setti1cdddac2023-02-02 13:55:57 +01001059 hash, hash_len, sig, sig_size, sig_len,
1060 f_rng, p_rng, &rs->ecdsa_rs));
1061
1062cleanup:
1063 return ret;
1064}
Valerio Setti80d07982023-02-08 13:49:17 +01001065#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Valerio Setti1cdddac2023-02-02 13:55:57 +01001066
Valerio Setti0fe1ee22023-04-03 14:42:22 +02001067#if defined(MBEDTLS_USE_PSA_CRYPTO)
Valerio Settibb7603a2023-06-21 18:34:54 +02001068#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
valerio38992cb2023-04-20 09:56:30 +02001069static int eckey_check_pair_psa(mbedtls_pk_context *pub, mbedtls_pk_context *prv)
Valerio Setti0fe1ee22023-04-03 14:42:22 +02001070{
Valerio Setti9efa8c42023-05-19 13:27:30 +02001071 psa_status_t status;
Valerio Setti0fe1ee22023-04-03 14:42:22 +02001072 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Valerio Setti8eb55262023-04-04 10:20:53 +02001073 uint8_t prv_key_buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
Valerio Setti0fe1ee22023-04-03 14:42:22 +02001074 size_t prv_key_len;
Valerio Settiae8c6282023-05-18 18:57:57 +02001075 mbedtls_svc_key_id_t key_id = prv->priv_id;
Valerio Setti9efa8c42023-05-19 13:27:30 +02001076
1077 status = psa_export_public_key(key_id, prv_key_buf, sizeof(prv_key_buf),
1078 &prv_key_len);
1079 ret = PSA_PK_TO_MBEDTLS_ERR(status);
1080 if (ret != 0) {
1081 return ret;
1082 }
1083
1084 if (memcmp(prv_key_buf, pub->pub_raw, pub->pub_raw_len) != 0) {
1085 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1086 }
Valerio Settibb7603a2023-06-21 18:34:54 +02001087
1088 return 0;
1089}
1090#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
1091static int eckey_check_pair_psa(mbedtls_pk_context *pub, mbedtls_pk_context *prv)
1092{
1093 psa_status_t status;
1094 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1095 uint8_t prv_key_buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
1096 size_t prv_key_len;
Valerio Setti9efa8c42023-05-19 13:27:30 +02001097 psa_status_t destruction_status;
Valerio Settiae8c6282023-05-18 18:57:57 +02001098 mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
1099 psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
Valerio Setti0fe1ee22023-04-03 14:42:22 +02001100 uint8_t pub_key_buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
1101 size_t pub_key_len;
Valerio Setti0fe1ee22023-04-03 14:42:22 +02001102 size_t curve_bits;
Valerio Settif2866642023-04-06 16:49:54 +02001103 const psa_ecc_family_t curve =
Valerio Settia1b8af62023-05-17 15:34:57 +02001104 mbedtls_ecc_group_to_psa(mbedtls_pk_ec_ro(*prv)->grp.id, &curve_bits);
Valerio Settic1541cb2023-05-17 15:49:55 +02001105 const size_t curve_bytes = PSA_BITS_TO_BYTES(curve_bits);
Valerio Setti0fe1ee22023-04-03 14:42:22 +02001106
Valerio Settia7cb8452023-05-22 18:39:43 +02001107 if (curve == 0) {
1108 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1109 }
1110
Valerio Setti0fe1ee22023-04-03 14:42:22 +02001111 psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
1112 psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT);
1113
Valerio Settia1b8af62023-05-17 15:34:57 +02001114 ret = mbedtls_mpi_write_binary(&mbedtls_pk_ec_ro(*prv)->d,
1115 prv_key_buf, curve_bytes);
Valerio Setti0fe1ee22023-04-03 14:42:22 +02001116 if (ret != 0) {
Valerio Setti35d1dac2023-06-30 18:04:16 +02001117 mbedtls_platform_zeroize(prv_key_buf, sizeof(prv_key_buf));
Valerio Setti0fe1ee22023-04-03 14:42:22 +02001118 return ret;
1119 }
1120
1121 status = psa_import_key(&key_attr, prv_key_buf, curve_bytes, &key_id);
Valerio Setti35d1dac2023-06-30 18:04:16 +02001122 mbedtls_platform_zeroize(prv_key_buf, sizeof(prv_key_buf));
Valerio Setti1df94f82023-04-07 08:59:24 +02001123 ret = PSA_PK_TO_MBEDTLS_ERR(status);
1124 if (ret != 0) {
Valerio Setti0fe1ee22023-04-03 14:42:22 +02001125 return ret;
1126 }
1127
Valerio Setti35d1dac2023-06-30 18:04:16 +02001128 // From now on prv_key_buf is used to store the public key of prv.
Valerio Setti1df94f82023-04-07 08:59:24 +02001129 status = psa_export_public_key(key_id, prv_key_buf, sizeof(prv_key_buf),
1130 &prv_key_len);
1131 ret = PSA_PK_TO_MBEDTLS_ERR(status);
1132 destruction_status = psa_destroy_key(key_id);
1133 if (ret != 0) {
1134 return ret;
1135 } else if (destruction_status != PSA_SUCCESS) {
1136 return PSA_PK_TO_MBEDTLS_ERR(destruction_status);
Valerio Setti0fe1ee22023-04-03 14:42:22 +02001137 }
1138
Valerio Settia1b8af62023-05-17 15:34:57 +02001139 ret = mbedtls_ecp_point_write_binary(&mbedtls_pk_ec_rw(*pub)->grp,
1140 &mbedtls_pk_ec_rw(*pub)->Q,
Valerio Setti0fe1ee22023-04-03 14:42:22 +02001141 MBEDTLS_ECP_PF_UNCOMPRESSED,
1142 &pub_key_len, pub_key_buf,
1143 sizeof(pub_key_buf));
1144 if (ret != 0) {
1145 return ret;
1146 }
1147
1148 if (memcmp(prv_key_buf, pub_key_buf, curve_bytes) != 0) {
1149 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1150 }
1151
1152 return 0;
1153}
Valerio Settibb7603a2023-06-21 18:34:54 +02001154#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
Valerio Setti0fe1ee22023-04-03 14:42:22 +02001155
Valerio Settibb7603a2023-06-21 18:34:54 +02001156static int eckey_check_pair_wrap(mbedtls_pk_context *pub, mbedtls_pk_context *prv,
1157 int (*f_rng)(void *, unsigned char *, size_t),
1158 void *p_rng)
Valerio Setti1cdddac2023-02-02 13:55:57 +01001159{
Valerio Setti0fe1ee22023-04-03 14:42:22 +02001160 (void) f_rng;
1161 (void) p_rng;
Valerio Setti9d65f0e2023-04-07 08:53:17 +02001162 return eckey_check_pair_psa(pub, prv);
Valerio Settibb7603a2023-06-21 18:34:54 +02001163}
1164#else /* MBEDTLS_USE_PSA_CRYPTO */
1165static int eckey_check_pair_wrap(mbedtls_pk_context *pub, mbedtls_pk_context *prv,
1166 int (*f_rng)(void *, unsigned char *, size_t),
1167 void *p_rng)
1168{
valerio38992cb2023-04-20 09:56:30 +02001169 return mbedtls_ecp_check_pub_priv((const mbedtls_ecp_keypair *) pub->pk_ctx,
1170 (const mbedtls_ecp_keypair *) prv->pk_ctx,
Valerio Setti1cdddac2023-02-02 13:55:57 +01001171 f_rng, p_rng);
1172}
Valerio Settibb7603a2023-06-21 18:34:54 +02001173#endif /* MBEDTLS_USE_PSA_CRYPTO */
Valerio Setti1cdddac2023-02-02 13:55:57 +01001174
Valerio Setti88a3aee2023-06-29 15:01:10 +02001175#if defined(MBEDTLS_USE_PSA_CRYPTO)
1176#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1177/* When PK_USE_PSA_EC_DATA is defined opaque and non-opaque keys end up
1178 * using the same function. */
1179#define ecdsa_opaque_check_pair_wrap eckey_check_pair_wrap
1180#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
1181static int ecdsa_opaque_check_pair_wrap(mbedtls_pk_context *pub,
1182 mbedtls_pk_context *prv,
1183 int (*f_rng)(void *, unsigned char *, size_t),
1184 void *p_rng)
1185{
1186 psa_status_t status;
1187 uint8_t exp_pub_key[MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN];
1188 size_t exp_pub_key_len = 0;
1189 uint8_t pub_key[MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN];
1190 size_t pub_key_len = 0;
1191 int ret;
1192 (void) f_rng;
1193 (void) p_rng;
1194
1195 status = psa_export_public_key(prv->priv_id, exp_pub_key, sizeof(exp_pub_key),
1196 &exp_pub_key_len);
1197 if (status != PSA_SUCCESS) {
1198 ret = psa_pk_status_to_mbedtls(status);
1199 return ret;
1200 }
1201 ret = mbedtls_ecp_point_write_binary(&(mbedtls_pk_ec_ro(*pub)->grp),
1202 &(mbedtls_pk_ec_ro(*pub)->Q),
1203 MBEDTLS_ECP_PF_UNCOMPRESSED,
1204 &pub_key_len, pub_key, sizeof(pub_key));
1205 if (ret != 0) {
1206 return ret;
1207 }
1208 if ((exp_pub_key_len != pub_key_len) ||
1209 memcmp(exp_pub_key, pub_key, exp_pub_key_len)) {
1210 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1211 }
1212 return 0;
1213}
1214#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1215#endif /* MBEDTLS_USE_PSA_CRYPTO */
1216
Valerio Settib5361262023-05-18 18:51:58 +02001217#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
Valerio Setti1cdddac2023-02-02 13:55:57 +01001218static void *eckey_alloc_wrap(void)
1219{
1220 void *ctx = mbedtls_calloc(1, sizeof(mbedtls_ecp_keypair));
1221
1222 if (ctx != NULL) {
1223 mbedtls_ecp_keypair_init(ctx);
1224 }
1225
1226 return ctx;
1227}
1228
1229static void eckey_free_wrap(void *ctx)
1230{
1231 mbedtls_ecp_keypair_free((mbedtls_ecp_keypair *) ctx);
1232 mbedtls_free(ctx);
1233}
Valerio Settib5361262023-05-18 18:51:58 +02001234#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
Valerio Setti1cdddac2023-02-02 13:55:57 +01001235
valerio38992cb2023-04-20 09:56:30 +02001236static void eckey_debug(mbedtls_pk_context *pk, mbedtls_pk_debug_item *items)
Valerio Setti1cdddac2023-02-02 13:55:57 +01001237{
Valerio Settia1b8af62023-05-17 15:34:57 +02001238#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1239 items->type = MBEDTLS_PK_DEBUG_PSA_EC;
1240 items->name = "eckey.Q";
1241 items->value = pk;
Valerio Setti5c26b302023-06-21 19:47:01 +02001242#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
valerio38992cb2023-04-20 09:56:30 +02001243 mbedtls_ecp_keypair *ecp = (mbedtls_ecp_keypair *) pk->pk_ctx;
Valerio Setti1cdddac2023-02-02 13:55:57 +01001244 items->type = MBEDTLS_PK_DEBUG_ECP;
1245 items->name = "eckey.Q";
valerio38992cb2023-04-20 09:56:30 +02001246 items->value = &(ecp->Q);
Valerio Setti5c26b302023-06-21 19:47:01 +02001247#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
Valerio Setti1cdddac2023-02-02 13:55:57 +01001248}
1249
1250const mbedtls_pk_info_t mbedtls_eckey_info = {
Valerio Settif69514a2023-06-21 18:16:49 +02001251 .type = MBEDTLS_PK_ECKEY,
1252 .name = "EC",
1253 .get_bitlen = eckey_get_bitlen,
1254 .can_do = eckey_can_do,
Valerio Setti1cdddac2023-02-02 13:55:57 +01001255#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY)
Valerio Settif69514a2023-06-21 18:16:49 +02001256 .verify_func = ecdsa_verify_wrap, /* Compatible key structures */
Valerio Setti97976e32023-06-23 14:08:26 +02001257#else /* MBEDTLS_PK_CAN_ECDSA_VERIFY */
1258 .verify_func = NULL,
1259#endif /* MBEDTLS_PK_CAN_ECDSA_VERIFY */
Valerio Setti1cdddac2023-02-02 13:55:57 +01001260#if defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
Valerio Settif69514a2023-06-21 18:16:49 +02001261 .sign_func = ecdsa_sign_wrap, /* Compatible key structures */
Valerio Setti97976e32023-06-23 14:08:26 +02001262#else /* MBEDTLS_PK_CAN_ECDSA_VERIFY */
1263 .sign_func = NULL,
1264#endif /* MBEDTLS_PK_CAN_ECDSA_VERIFY */
Valerio Setti5b16e9e2023-02-07 08:08:53 +01001265#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Valerio Settif69514a2023-06-21 18:16:49 +02001266 .verify_rs_func = eckey_verify_rs_wrap,
1267 .sign_rs_func = eckey_sign_rs_wrap,
Valerio Setti97976e32023-06-23 14:08:26 +02001268 .rs_alloc_func = eckey_rs_alloc,
1269 .rs_free_func = eckey_rs_free,
1270#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
1271 .decrypt_func = NULL,
1272 .encrypt_func = NULL,
Valerio Settibb7603a2023-06-21 18:34:54 +02001273 .check_pair_func = eckey_check_pair_wrap,
Valerio Setti97976e32023-06-23 14:08:26 +02001274#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1275 .ctx_alloc_func = NULL,
1276 .ctx_free_func = NULL,
1277#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
Valerio Settif69514a2023-06-21 18:16:49 +02001278 .ctx_alloc_func = eckey_alloc_wrap,
1279 .ctx_free_func = eckey_free_wrap,
Valerio Settib5361262023-05-18 18:51:58 +02001280#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
Valerio Settif69514a2023-06-21 18:16:49 +02001281 .debug_func = eckey_debug,
Valerio Setti1cdddac2023-02-02 13:55:57 +01001282};
1283
1284/*
1285 * EC key restricted to ECDH
1286 */
1287static int eckeydh_can_do(mbedtls_pk_type_t type)
1288{
1289 return type == MBEDTLS_PK_ECKEY ||
1290 type == MBEDTLS_PK_ECKEY_DH;
1291}
1292
1293const mbedtls_pk_info_t mbedtls_eckeydh_info = {
Valerio Settif69514a2023-06-21 18:16:49 +02001294 .type = MBEDTLS_PK_ECKEY_DH,
1295 .name = "EC_DH",
1296 .get_bitlen = eckey_get_bitlen, /* Same underlying key structure */
1297 .can_do = eckeydh_can_do,
Valerio Setti97976e32023-06-23 14:08:26 +02001298 .verify_func = NULL,
1299 .sign_func = NULL,
1300#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
1301 .verify_rs_func = NULL,
1302 .sign_rs_func = NULL,
1303#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
1304 .decrypt_func = NULL,
1305 .encrypt_func = NULL,
Valerio Settibb7603a2023-06-21 18:34:54 +02001306 .check_pair_func = eckey_check_pair_wrap,
Valerio Setti97976e32023-06-23 14:08:26 +02001307#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1308 .ctx_alloc_func = NULL,
1309 .ctx_free_func = NULL,
1310#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
Valerio Settif69514a2023-06-21 18:16:49 +02001311 .ctx_alloc_func = eckey_alloc_wrap, /* Same underlying key structure */
1312 .ctx_free_func = eckey_free_wrap, /* Same underlying key structure */
Valerio Settib5361262023-05-18 18:51:58 +02001313#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
Valerio Settif69514a2023-06-21 18:16:49 +02001314 .debug_func = eckey_debug, /* Same underlying key structure */
Valerio Setti1cdddac2023-02-02 13:55:57 +01001315};
Valerio Setti1cdddac2023-02-02 13:55:57 +01001316
1317#if defined(MBEDTLS_PK_CAN_ECDSA_SOME)
1318static int ecdsa_can_do(mbedtls_pk_type_t type)
1319{
1320 return type == MBEDTLS_PK_ECDSA;
1321}
1322
Valerio Setti5b16e9e2023-02-07 08:08:53 +01001323#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
valerio38992cb2023-04-20 09:56:30 +02001324static int ecdsa_verify_rs_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
Gilles Peskine449bd832023-01-11 14:50:10 +01001325 const unsigned char *hash, size_t hash_len,
1326 const unsigned char *sig, size_t sig_len,
1327 void *rs_ctx)
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +02001328{
Janos Follath24eed8d2019-11-22 13:21:35 +00001329 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +02001330 ((void) md_alg);
1331
1332 ret = mbedtls_ecdsa_read_signature_restartable(
valerio38992cb2023-04-20 09:56:30 +02001333 (mbedtls_ecdsa_context *) pk->pk_ctx,
Gilles Peskine449bd832023-01-11 14:50:10 +01001334 hash, hash_len, sig, sig_len,
1335 (mbedtls_ecdsa_restart_ctx *) rs_ctx);
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +02001336
Gilles Peskine449bd832023-01-11 14:50:10 +01001337 if (ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) {
1338 return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
1339 }
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +02001340
Gilles Peskine449bd832023-01-11 14:50:10 +01001341 return ret;
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +02001342}
1343
valerio38992cb2023-04-20 09:56:30 +02001344static int ecdsa_sign_rs_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
Gilles Peskine449bd832023-01-11 14:50:10 +01001345 const unsigned char *hash, size_t hash_len,
1346 unsigned char *sig, size_t sig_size, size_t *sig_len,
1347 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
1348 void *rs_ctx)
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +02001349{
Gilles Peskine449bd832023-01-11 14:50:10 +01001350 return mbedtls_ecdsa_write_signature_restartable(
valerio38992cb2023-04-20 09:56:30 +02001351 (mbedtls_ecdsa_context *) pk->pk_ctx,
Gilles Peskine449bd832023-01-11 14:50:10 +01001352 md_alg, hash, hash_len, sig, sig_size, sig_len, f_rng, p_rng,
1353 (mbedtls_ecdsa_restart_ctx *) rs_ctx);
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +02001354
1355}
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +02001356
Gilles Peskine449bd832023-01-11 14:50:10 +01001357static void *ecdsa_rs_alloc(void)
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +02001358{
Gilles Peskine449bd832023-01-11 14:50:10 +01001359 void *ctx = mbedtls_calloc(1, sizeof(mbedtls_ecdsa_restart_ctx));
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +02001360
Gilles Peskine449bd832023-01-11 14:50:10 +01001361 if (ctx != NULL) {
1362 mbedtls_ecdsa_restart_init(ctx);
1363 }
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +02001364
Gilles Peskine449bd832023-01-11 14:50:10 +01001365 return ctx;
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +02001366}
1367
Gilles Peskine449bd832023-01-11 14:50:10 +01001368static void ecdsa_rs_free(void *ctx)
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +02001369{
Gilles Peskine449bd832023-01-11 14:50:10 +01001370 mbedtls_ecdsa_restart_free(ctx);
1371 mbedtls_free(ctx);
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +02001372}
Valerio Setti5b16e9e2023-02-07 08:08:53 +01001373#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +02001374
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001375const mbedtls_pk_info_t mbedtls_ecdsa_info = {
Valerio Settif69514a2023-06-21 18:16:49 +02001376 .type = MBEDTLS_PK_ECDSA,
1377 .name = "ECDSA",
1378 .get_bitlen = eckey_get_bitlen, /* Compatible key structures */
1379 .can_do = ecdsa_can_do,
Valerio Setti1cdddac2023-02-02 13:55:57 +01001380#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY)
Valerio Settif69514a2023-06-21 18:16:49 +02001381 .verify_func = ecdsa_verify_wrap, /* Compatible key structures */
Valerio Setti97976e32023-06-23 14:08:26 +02001382#else /* MBEDTLS_PK_CAN_ECDSA_VERIFY */
1383 .verify_func = NULL,
1384#endif /* MBEDTLS_PK_CAN_ECDSA_VERIFY */
Valerio Setti1cdddac2023-02-02 13:55:57 +01001385#if defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
Valerio Settif69514a2023-06-21 18:16:49 +02001386 .sign_func = ecdsa_sign_wrap, /* Compatible key structures */
Valerio Setti97976e32023-06-23 14:08:26 +02001387#else /* MBEDTLS_PK_CAN_ECDSA_SIGN */
1388 .sign_func = NULL,
1389#endif /* MBEDTLS_PK_CAN_ECDSA_SIGN */
Valerio Setti5b16e9e2023-02-07 08:08:53 +01001390#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Valerio Settif69514a2023-06-21 18:16:49 +02001391 .verify_rs_func = ecdsa_verify_rs_wrap,
1392 .sign_rs_func = ecdsa_sign_rs_wrap,
Valerio Setti97976e32023-06-23 14:08:26 +02001393 .rs_alloc_func = ecdsa_rs_alloc,
1394 .rs_free_func = ecdsa_rs_free,
1395#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
1396 .decrypt_func = NULL,
1397 .encrypt_func = NULL,
Valerio Settibb7603a2023-06-21 18:34:54 +02001398 .check_pair_func = eckey_check_pair_wrap, /* Compatible key structures */
Valerio Setti97976e32023-06-23 14:08:26 +02001399#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1400 .ctx_alloc_func = NULL,
1401 .ctx_free_func = NULL,
1402#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
Valerio Settif69514a2023-06-21 18:16:49 +02001403 .ctx_alloc_func = eckey_alloc_wrap, /* Compatible key structures */
1404 .ctx_free_func = eckey_free_wrap, /* Compatible key structures */
Valerio Settib5361262023-05-18 18:51:58 +02001405#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
Valerio Settif69514a2023-06-21 18:16:49 +02001406 .debug_func = eckey_debug, /* Compatible key structures */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +02001407};
Valerio Setti7ca13182023-01-27 13:22:42 +01001408#endif /* MBEDTLS_PK_CAN_ECDSA_SOME */
Valerio Settid9d74c22023-06-29 15:00:02 +02001409#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +02001410
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001411#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +02001412/*
1413 * Support for alternative RSA-private implementations
1414 */
1415
Gilles Peskine449bd832023-01-11 14:50:10 +01001416static int rsa_alt_can_do(mbedtls_pk_type_t type)
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +02001417{
Gilles Peskine449bd832023-01-11 14:50:10 +01001418 return type == MBEDTLS_PK_RSA;
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +02001419}
1420
valerio38992cb2023-04-20 09:56:30 +02001421static size_t rsa_alt_get_bitlen(mbedtls_pk_context *pk)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +02001422{
valerio38992cb2023-04-20 09:56:30 +02001423 const mbedtls_rsa_alt_context *rsa_alt = pk->pk_ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +02001424
Gilles Peskine449bd832023-01-11 14:50:10 +01001425 return 8 * rsa_alt->key_len_func(rsa_alt->key);
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +02001426}
1427
valerio38992cb2023-04-20 09:56:30 +02001428static int rsa_alt_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
Gilles Peskine449bd832023-01-11 14:50:10 +01001429 const unsigned char *hash, size_t hash_len,
1430 unsigned char *sig, size_t sig_size, size_t *sig_len,
1431 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +02001432{
valerio38992cb2023-04-20 09:56:30 +02001433 mbedtls_rsa_alt_context *rsa_alt = pk->pk_ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +02001434
Dave Rodgman02a53d72023-09-28 17:17:07 +01001435#if SIZE_MAX > UINT_MAX
Gilles Peskine449bd832023-01-11 14:50:10 +01001436 if (UINT_MAX < hash_len) {
1437 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1438 }
Dave Rodgman02a53d72023-09-28 17:17:07 +01001439#endif
Andres AG72849872017-01-19 11:24:33 +00001440
Gilles Peskine449bd832023-01-11 14:50:10 +01001441 *sig_len = rsa_alt->key_len_func(rsa_alt->key);
1442 if (*sig_len > MBEDTLS_PK_SIGNATURE_MAX_SIZE) {
1443 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
1444 }
1445 if (*sig_len > sig_size) {
1446 return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
1447 }
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +02001448
Gilles Peskine449bd832023-01-11 14:50:10 +01001449 return rsa_alt->sign_func(rsa_alt->key, f_rng, p_rng,
1450 md_alg, (unsigned int) hash_len, hash, sig);
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +02001451}
1452
valerio38992cb2023-04-20 09:56:30 +02001453static int rsa_alt_decrypt_wrap(mbedtls_pk_context *pk,
Gilles Peskine449bd832023-01-11 14:50:10 +01001454 const unsigned char *input, size_t ilen,
1455 unsigned char *output, size_t *olen, size_t osize,
1456 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +02001457{
valerio38992cb2023-04-20 09:56:30 +02001458 mbedtls_rsa_alt_context *rsa_alt = pk->pk_ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +02001459
1460 ((void) f_rng);
1461 ((void) p_rng);
1462
Gilles Peskine449bd832023-01-11 14:50:10 +01001463 if (ilen != rsa_alt->key_len_func(rsa_alt->key)) {
1464 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1465 }
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +02001466
Gilles Peskine449bd832023-01-11 14:50:10 +01001467 return rsa_alt->decrypt_func(rsa_alt->key,
1468 olen, input, output, osize);
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +02001469}
1470
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001471#if defined(MBEDTLS_RSA_C)
valerio38992cb2023-04-20 09:56:30 +02001472static int rsa_alt_check_pair(mbedtls_pk_context *pub, mbedtls_pk_context *prv,
Gilles Peskine449bd832023-01-11 14:50:10 +01001473 int (*f_rng)(void *, unsigned char *, size_t),
1474 void *p_rng)
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +01001475{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001476 unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +01001477 unsigned char hash[32];
1478 size_t sig_len = 0;
Janos Follath24eed8d2019-11-22 13:21:35 +00001479 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +01001480
Gilles Peskine449bd832023-01-11 14:50:10 +01001481 if (rsa_alt_get_bitlen(prv) != rsa_get_bitlen(pub)) {
1482 return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +01001483 }
1484
Gilles Peskine449bd832023-01-11 14:50:10 +01001485 memset(hash, 0x2a, sizeof(hash));
1486
valerio38992cb2023-04-20 09:56:30 +02001487 if ((ret = rsa_alt_sign_wrap(prv, MBEDTLS_MD_NONE,
Gilles Peskine449bd832023-01-11 14:50:10 +01001488 hash, sizeof(hash),
1489 sig, sizeof(sig), &sig_len,
1490 f_rng, p_rng)) != 0) {
1491 return ret;
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +01001492 }
1493
valerio38992cb2023-04-20 09:56:30 +02001494 if (rsa_verify_wrap(pub, MBEDTLS_MD_NONE,
Gilles Peskine449bd832023-01-11 14:50:10 +01001495 hash, sizeof(hash), sig, sig_len) != 0) {
1496 return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
1497 }
1498
1499 return 0;
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +01001500}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001501#endif /* MBEDTLS_RSA_C */
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +01001502
Gilles Peskine449bd832023-01-11 14:50:10 +01001503static void *rsa_alt_alloc_wrap(void)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +02001504{
Gilles Peskine449bd832023-01-11 14:50:10 +01001505 void *ctx = mbedtls_calloc(1, sizeof(mbedtls_rsa_alt_context));
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +02001506
Gilles Peskine449bd832023-01-11 14:50:10 +01001507 if (ctx != NULL) {
1508 memset(ctx, 0, sizeof(mbedtls_rsa_alt_context));
1509 }
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +02001510
Gilles Peskine449bd832023-01-11 14:50:10 +01001511 return ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +02001512}
1513
Gilles Peskine449bd832023-01-11 14:50:10 +01001514static void rsa_alt_free_wrap(void *ctx)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +02001515{
Tom Cosgroveca8c61b2023-07-17 15:17:40 +01001516 mbedtls_zeroize_and_free(ctx, sizeof(mbedtls_rsa_alt_context));
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +02001517}
1518
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001519const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
Valerio Settif69514a2023-06-21 18:16:49 +02001520 .type = MBEDTLS_PK_RSA_ALT,
1521 .name = "RSA-alt",
1522 .get_bitlen = rsa_alt_get_bitlen,
1523 .can_do = rsa_alt_can_do,
Valerio Setti97976e32023-06-23 14:08:26 +02001524 .verify_func = NULL,
Valerio Settif69514a2023-06-21 18:16:49 +02001525 .sign_func = rsa_alt_sign_wrap,
Valerio Setti97976e32023-06-23 14:08:26 +02001526#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
1527 .verify_rs_func = NULL,
1528 .sign_rs_func = NULL,
1529 .rs_alloc_func = NULL,
1530 .rs_free_func = NULL,
1531#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Valerio Settif69514a2023-06-21 18:16:49 +02001532 .decrypt_func = rsa_alt_decrypt_wrap,
Valerio Setti97976e32023-06-23 14:08:26 +02001533 .encrypt_func = NULL,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001534#if defined(MBEDTLS_RSA_C)
Valerio Settif69514a2023-06-21 18:16:49 +02001535 .check_pair_func = rsa_alt_check_pair,
Valerio Setti97976e32023-06-23 14:08:26 +02001536#else
1537 .check_pair_func = NULL,
Manuel Pégourié-Gonnard7c13d692014-11-12 00:01:34 +01001538#endif
Valerio Settif69514a2023-06-21 18:16:49 +02001539 .ctx_alloc_func = rsa_alt_alloc_wrap,
1540 .ctx_free_func = rsa_alt_free_wrap,
Valerio Setti97976e32023-06-23 14:08:26 +02001541 .debug_func = NULL,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +02001542};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001543#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
Manuel Pégourié-Gonnard348bcb32015-03-31 14:01:33 +02001544
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +02001545#if defined(MBEDTLS_USE_PSA_CRYPTO)
Valerio Setti76d0f962023-06-23 13:32:54 +02001546static size_t opaque_get_bitlen(mbedtls_pk_context *pk)
Manuel Pégourié-Gonnard0184b3c2018-10-31 10:36:51 +01001547{
Manuel Pégourié-Gonnard0184b3c2018-10-31 10:36:51 +01001548 size_t bits;
Gilles Peskined2d45c12019-05-27 14:53:13 +02001549 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Manuel Pégourié-Gonnard0184b3c2018-10-31 10:36:51 +01001550
Valerio Setti4f387ef2023-05-02 14:15:59 +02001551 if (PSA_SUCCESS != psa_get_key_attributes(pk->priv_id, &attributes)) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001552 return 0;
1553 }
Manuel Pégourié-Gonnard0184b3c2018-10-31 10:36:51 +01001554
Gilles Peskine449bd832023-01-11 14:50:10 +01001555 bits = psa_get_key_bits(&attributes);
1556 psa_reset_key_attributes(&attributes);
1557 return bits;
Manuel Pégourié-Gonnard0184b3c2018-10-31 10:36:51 +01001558}
1559
Valerio Setti38913c12023-06-30 16:18:33 +02001560#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
Valerio Setti76d0f962023-06-23 13:32:54 +02001561static int ecdsa_opaque_can_do(mbedtls_pk_type_t type)
Manuel Pégourié-Gonnard920c0632018-10-31 10:57:29 +01001562{
Gilles Peskine449bd832023-01-11 14:50:10 +01001563 return type == MBEDTLS_PK_ECKEY ||
1564 type == MBEDTLS_PK_ECDSA;
Manuel Pégourié-Gonnard920c0632018-10-31 10:57:29 +01001565}
1566
Valerio Setti76d0f962023-06-23 13:32:54 +02001567const mbedtls_pk_info_t mbedtls_ecdsa_opaque_info = {
Valerio Setti574a00b2023-06-21 19:47:37 +02001568 .type = MBEDTLS_PK_OPAQUE,
1569 .name = "Opaque",
Valerio Setti76d0f962023-06-23 13:32:54 +02001570 .get_bitlen = opaque_get_bitlen,
1571 .can_do = ecdsa_opaque_can_do,
Valerio Setti4d1daf82023-06-26 13:31:18 +02001572#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY)
Valerio Setti76d0f962023-06-23 13:32:54 +02001573 .verify_func = ecdsa_opaque_verify_wrap,
Valerio Setti4d1daf82023-06-26 13:31:18 +02001574#else /* MBEDTLS_PK_CAN_ECDSA_VERIFY */
1575 .verify_func = NULL,
1576#endif /* MBEDTLS_PK_CAN_ECDSA_VERIFY */
1577#if defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
Valerio Setti76d0f962023-06-23 13:32:54 +02001578 .sign_func = ecdsa_opaque_sign_wrap,
Valerio Setti4d1daf82023-06-26 13:31:18 +02001579#else /* MBEDTLS_PK_CAN_ECDSA_SIGN */
1580 .sign_func = NULL,
1581#endif /* MBEDTLS_PK_CAN_ECDSA_SIGN */
Valerio Setti97976e32023-06-23 14:08:26 +02001582#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
1583 .verify_rs_func = NULL,
1584 .sign_rs_func = NULL,
1585 .rs_alloc_func = NULL,
1586 .rs_free_func = NULL,
1587#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
1588 .decrypt_func = NULL,
1589 .encrypt_func = NULL,
Valerio Setti76d0f962023-06-23 13:32:54 +02001590 .check_pair_func = ecdsa_opaque_check_pair_wrap,
Valerio Setti97976e32023-06-23 14:08:26 +02001591 .ctx_alloc_func = NULL,
1592 .ctx_free_func = NULL,
1593 .debug_func = NULL,
Valerio Setti574a00b2023-06-21 19:47:37 +02001594};
Valerio Setti38913c12023-06-30 16:18:33 +02001595#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
Valerio Setti574a00b2023-06-21 19:47:37 +02001596
Valerio Setti76d0f962023-06-23 13:32:54 +02001597static int rsa_opaque_can_do(mbedtls_pk_type_t type)
Neil Armstrongeabbf9d2022-03-15 12:01:26 +01001598{
Gilles Peskine449bd832023-01-11 14:50:10 +01001599 return type == MBEDTLS_PK_RSA ||
1600 type == MBEDTLS_PK_RSASSA_PSS;
Neil Armstrongeabbf9d2022-03-15 12:01:26 +01001601}
1602
Valerio Settif6d4dfb2023-07-10 10:55:12 +02001603#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
Valerio Setti76d0f962023-06-23 13:32:54 +02001604static int rsa_opaque_decrypt(mbedtls_pk_context *pk,
1605 const unsigned char *input, size_t ilen,
1606 unsigned char *output, size_t *olen, size_t osize,
1607 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +01001608{
Valerio Setti574a00b2023-06-21 19:47:37 +02001609 psa_status_t status;
1610
1611 /* PSA has its own RNG */
1612 (void) f_rng;
1613 (void) p_rng;
1614
1615 status = psa_asymmetric_decrypt(pk->priv_id, PSA_ALG_RSA_PKCS1V15_CRYPT,
1616 input, ilen,
1617 NULL, 0,
1618 output, osize, olen);
1619 if (status != PSA_SUCCESS) {
1620 return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
1621 }
1622
1623 return 0;
1624}
Valerio Settif6d4dfb2023-07-10 10:55:12 +02001625#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC */
Valerio Setti574a00b2023-06-21 19:47:37 +02001626
Valerio Setti76d0f962023-06-23 13:32:54 +02001627static int rsa_opaque_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
1628 const unsigned char *hash, size_t hash_len,
1629 unsigned char *sig, size_t sig_size, size_t *sig_len,
1630 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Valerio Setti574a00b2023-06-21 19:47:37 +02001631{
1632#if defined(MBEDTLS_RSA_C)
Neil Armstrongeabbf9d2022-03-15 12:01:26 +01001633 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Neil Armstrongb980c9b2022-03-15 16:19:16 +01001634 psa_algorithm_t alg;
Neil Armstrongeabbf9d2022-03-15 12:01:26 +01001635 psa_key_type_t type;
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +01001636 psa_status_t status;
1637
1638 /* PSA has its own RNG */
1639 (void) f_rng;
1640 (void) p_rng;
1641
Valerio Setti4f387ef2023-05-02 14:15:59 +02001642 status = psa_get_key_attributes(pk->priv_id, &attributes);
Gilles Peskine449bd832023-01-11 14:50:10 +01001643 if (status != PSA_SUCCESS) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -05001644 return PSA_PK_TO_MBEDTLS_ERR(status);
Gilles Peskine449bd832023-01-11 14:50:10 +01001645 }
Neil Armstrongb980c9b2022-03-15 16:19:16 +01001646
Gilles Peskine449bd832023-01-11 14:50:10 +01001647 type = psa_get_key_type(&attributes);
1648 psa_reset_key_attributes(&attributes);
Neil Armstrongb980c9b2022-03-15 16:19:16 +01001649
Gilles Peskine449bd832023-01-11 14:50:10 +01001650 if (PSA_KEY_TYPE_IS_RSA(type)) {
Manuel Pégourié-Gonnard2d6d9932023-03-28 11:38:08 +02001651 alg = PSA_ALG_RSA_PKCS1V15_SIGN(mbedtls_md_psa_alg_from_type(md_alg));
Valerio Setti4657f102023-06-21 13:55:16 +02001652 } else {
1653 return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
1654 }
Neil Armstrongb980c9b2022-03-15 16:19:16 +01001655
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +01001656 /* make the signature */
Valerio Setti4f387ef2023-05-02 14:15:59 +02001657 status = psa_sign_hash(pk->priv_id, alg, hash, hash_len,
Gilles Peskine449bd832023-01-11 14:50:10 +01001658 sig, sig_size, sig_len);
1659 if (status != PSA_SUCCESS) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001660 if (PSA_KEY_TYPE_IS_RSA(type)) {
Andrzej Kurek8a045ce2022-12-23 11:00:06 -05001661 return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
Valerio Setti4657f102023-06-21 13:55:16 +02001662 } else {
1663 return PSA_PK_TO_MBEDTLS_ERR(status);
1664 }
Neil Armstrongb980c9b2022-03-15 16:19:16 +01001665 }
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +01001666
Neil Armstrongb980c9b2022-03-15 16:19:16 +01001667 return 0;
Valerio Setti574a00b2023-06-21 19:47:37 +02001668#else /* !MBEDTLS_RSA_C */
1669 ((void) pk);
1670 ((void) md_alg);
1671 ((void) hash);
1672 ((void) hash_len);
1673 ((void) sig);
1674 ((void) sig_size);
1675 ((void) sig_len);
1676 ((void) f_rng);
1677 ((void) p_rng);
1678 return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
Valerio Setti4657f102023-06-21 13:55:16 +02001679#endif /* !MBEDTLS_RSA_C */
Manuel Pégourié-Gonnardd8454bc2018-11-13 10:32:00 +01001680}
1681
Valerio Setti76d0f962023-06-23 13:32:54 +02001682const mbedtls_pk_info_t mbedtls_rsa_opaque_info = {
Valerio Settif69514a2023-06-21 18:16:49 +02001683 .type = MBEDTLS_PK_OPAQUE,
1684 .name = "Opaque",
Valerio Setti76d0f962023-06-23 13:32:54 +02001685 .get_bitlen = opaque_get_bitlen,
1686 .can_do = rsa_opaque_can_do,
Valerio Setti97976e32023-06-23 14:08:26 +02001687 .verify_func = NULL,
Valerio Setti76d0f962023-06-23 13:32:54 +02001688 .sign_func = rsa_opaque_sign_wrap,
Valerio Setti97976e32023-06-23 14:08:26 +02001689#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
1690 .verify_rs_func = NULL,
1691 .sign_rs_func = NULL,
1692 .rs_alloc_func = NULL,
1693 .rs_free_func = NULL,
1694#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Valerio Settif6d4dfb2023-07-10 10:55:12 +02001695#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
Valerio Setti76d0f962023-06-23 13:32:54 +02001696 .decrypt_func = rsa_opaque_decrypt,
Valerio Settif6d4dfb2023-07-10 10:55:12 +02001697#else /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC */
Valerio Setti97976e32023-06-23 14:08:26 +02001698 .decrypt_func = NULL,
Valerio Settif6d4dfb2023-07-10 10:55:12 +02001699#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC */
Valerio Setti97976e32023-06-23 14:08:26 +02001700 .encrypt_func = NULL,
1701 .check_pair_func = NULL,
1702 .ctx_alloc_func = NULL,
1703 .ctx_free_func = NULL,
1704 .debug_func = NULL,
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +02001705};
1706
1707#endif /* MBEDTLS_USE_PSA_CRYPTO */
1708
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001709#endif /* MBEDTLS_PK_C */