blob: a751cf1d8d34587b77b8106c9cec7d26650932ba [file] [log] [blame]
Ronald Cron00b7bfc2020-11-25 15:25:26 +01001/*
2 * PSA ECP layer on top of Mbed TLS crypto
3 */
4/*
5 * Copyright The Mbed TLS Contributors
6 * SPDX-License-Identifier: Apache-2.0
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License"); you may
9 * not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21#include "common.h"
22
23#if defined(MBEDTLS_PSA_CRYPTO_C)
24
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020025# include <psa/crypto.h>
26# include "psa_crypto_core.h"
27# include "psa_crypto_ecp.h"
28# include "psa_crypto_random_impl.h"
29# include "psa_crypto_hash.h"
Ronald Cron00b7bfc2020-11-25 15:25:26 +010030
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020031# include <stdlib.h>
32# include <string.h>
33# include "mbedtls/platform.h"
34# if !defined(MBEDTLS_PLATFORM_C)
35# define mbedtls_calloc calloc
36# define mbedtls_free free
37# endif
Ronald Cron00b7bfc2020-11-25 15:25:26 +010038
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020039# include <mbedtls/ecdsa.h>
40# include <mbedtls/ecp.h>
41# include <mbedtls/error.h>
Ronald Cron00b7bfc2020-11-25 15:25:26 +010042
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020043# if (defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
44 (defined(PSA_CRYPTO_DRIVER_TEST) && \
45 defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR)))
46# define BUILTIN_KEY_TYPE_ECC_KEY_PAIR 1
47# endif
Ronald Cronf1057d32020-11-26 19:19:10 +010048
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020049# if (defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || \
50 (defined(PSA_CRYPTO_DRIVER_TEST) && \
51 defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY)))
52# define BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY 1
53# endif
Ronald Cronf1057d32020-11-26 19:19:10 +010054
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020055# if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
56 (defined(PSA_CRYPTO_DRIVER_TEST) && \
57 defined(MBEDTLS_PSA_ACCEL_ALG_ECDSA) && defined(MBEDTLS_ECDSA_C)))
58# define BUILTIN_ALG_ECDSA 1
59# endif
Ronald Cronb5399a82020-12-10 09:35:33 +010060
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020061# if (defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) || \
62 (defined(PSA_CRYPTO_DRIVER_TEST) && \
63 defined(MBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA) && \
64 defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECDSA_DETERMINISTIC)))
65# define BUILTIN_ALG_DETERMINISTIC_ECDSA 1
66# endif
Ronald Cronb5399a82020-12-10 09:35:33 +010067
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020068# if defined(BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
69 defined(BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || \
70 defined(BUILTIN_ALG_ECDSA) || \
71 defined(BUILTIN_ALG_DETERMINISTIC_ECDSA) || \
72 defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
73psa_status_t mbedtls_psa_ecp_load_representation(psa_key_type_t type,
74 size_t curve_bits,
75 const uint8_t *data,
76 size_t data_length,
77 mbedtls_ecp_keypair **p_ecp)
Ronald Cron00b7bfc2020-11-25 15:25:26 +010078{
79 mbedtls_ecp_group_id grp_id = MBEDTLS_ECP_DP_NONE;
80 psa_status_t status;
81 mbedtls_ecp_keypair *ecp = NULL;
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +010082 size_t curve_bytes = data_length;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020083 int explicit_bits = (curve_bits != 0);
Ronald Cron00b7bfc2020-11-25 15:25:26 +010084
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020085 if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type) &&
86 PSA_KEY_TYPE_ECC_GET_FAMILY(type) != PSA_ECC_FAMILY_MONTGOMERY) {
Ronald Cron00b7bfc2020-11-25 15:25:26 +010087 /* A Weierstrass public key is represented as:
88 * - The byte 0x04;
89 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
90 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian.
91 * So its data length is 2m+1 where m is the curve size in bits.
92 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020093 if ((data_length & 1) == 0)
94 return PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +010095 curve_bytes = data_length / 2;
Ronald Cron00b7bfc2020-11-25 15:25:26 +010096
97 /* Montgomery public keys are represented in compressed format, meaning
Gilles Peskined88ccae2021-02-08 18:39:18 +010098 * their curve_bytes is equal to the amount of input. */
Ronald Cron00b7bfc2020-11-25 15:25:26 +010099
100 /* Private keys are represented in uncompressed private random integer
Gilles Peskined88ccae2021-02-08 18:39:18 +0100101 * format, meaning their curve_bytes is equal to the amount of input. */
Ronald Cron00b7bfc2020-11-25 15:25:26 +0100102 }
103
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200104 if (explicit_bits) {
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100105 /* With an explicit bit-size, the data must have the matching length. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200106 if (curve_bytes != PSA_BITS_TO_BYTES(curve_bits))
107 return PSA_ERROR_INVALID_ARGUMENT;
108 } else {
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100109 /* We need to infer the bit-size from the data. Since the only
110 * information we have is the length in bytes, the value of curve_bits
111 * at this stage is rounded up to the nearest multiple of 8. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200112 curve_bits = PSA_BYTES_TO_BITS(curve_bytes);
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100113 }
114
Ronald Cron00b7bfc2020-11-25 15:25:26 +0100115 /* Allocate and initialize a key representation. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200116 ecp = mbedtls_calloc(1, sizeof(mbedtls_ecp_keypair));
117 if (ecp == NULL)
118 return PSA_ERROR_INSUFFICIENT_MEMORY;
119 mbedtls_ecp_keypair_init(ecp);
Ronald Cron00b7bfc2020-11-25 15:25:26 +0100120
121 /* Load the group. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200122 grp_id = mbedtls_ecc_group_of_psa(PSA_KEY_TYPE_ECC_GET_FAMILY(type),
123 curve_bits, !explicit_bits);
124 if (grp_id == MBEDTLS_ECP_DP_NONE) {
Gilles Peskine2fa6b5f2021-01-27 15:44:45 +0100125 /* We can't distinguish between a nonsensical family/size combination
126 * (which would warrant PSA_ERROR_INVALID_ARGUMENT) and a
127 * well-regarded curve that Mbed TLS just doesn't know about (which
128 * would warrant PSA_ERROR_NOT_SUPPORTED). For uniformity with how
129 * curves that Mbed TLS knows about but for which support is disabled
130 * at build time, return NOT_SUPPORTED. */
131 status = PSA_ERROR_NOT_SUPPORTED;
Ronald Cron00b7bfc2020-11-25 15:25:26 +0100132 goto exit;
133 }
134
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200135 status = mbedtls_to_psa_error(mbedtls_ecp_group_load(&ecp->grp, grp_id));
136 if (status != PSA_SUCCESS)
Ronald Cron00b7bfc2020-11-25 15:25:26 +0100137 goto exit;
138
139 /* Load the key material. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200140 if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type)) {
Ronald Cron00b7bfc2020-11-25 15:25:26 +0100141 /* Load the public value. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200142 status = mbedtls_to_psa_error(mbedtls_ecp_point_read_binary(
143 &ecp->grp, &ecp->Q, data, data_length));
144 if (status != PSA_SUCCESS)
Ronald Cron00b7bfc2020-11-25 15:25:26 +0100145 goto exit;
146
147 /* Check that the point is on the curve. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200148 status =
149 mbedtls_to_psa_error(mbedtls_ecp_check_pubkey(&ecp->grp, &ecp->Q));
150 if (status != PSA_SUCCESS)
Ronald Cron00b7bfc2020-11-25 15:25:26 +0100151 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200152 } else {
Ronald Cron00b7bfc2020-11-25 15:25:26 +0100153 /* Load and validate the secret value. */
154 status = mbedtls_to_psa_error(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200155 mbedtls_ecp_read_key(ecp->grp.id, ecp, data, data_length));
156 if (status != PSA_SUCCESS)
Ronald Cron00b7bfc2020-11-25 15:25:26 +0100157 goto exit;
158 }
159
160 *p_ecp = ecp;
161exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200162 if (status != PSA_SUCCESS) {
163 mbedtls_ecp_keypair_free(ecp);
164 mbedtls_free(ecp);
Ronald Cron00b7bfc2020-11-25 15:25:26 +0100165 }
166
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200167 return status;
Ronald Cron00b7bfc2020-11-25 15:25:26 +0100168}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200169# endif /* defined(BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
170 * defined(BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || \
171 * defined(BUILTIN_ALG_ECDSA) || \
172 * defined(BUILTIN_ALG_DETERMINISTIC_ECDSA) || \
173 * defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) */
Ronald Cron00b7bfc2020-11-25 15:25:26 +0100174
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200175# if defined(BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
176 defined(BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
Ronald Crond6ec3032020-11-27 18:54:57 +0100177
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200178static psa_status_t ecp_import_key(const psa_key_attributes_t *attributes,
179 const uint8_t *data,
180 size_t data_length,
181 uint8_t *key_buffer,
182 size_t key_buffer_size,
183 size_t *key_buffer_length,
184 size_t *bits)
Ronald Crond6ec3032020-11-27 18:54:57 +0100185{
186 psa_status_t status;
187 mbedtls_ecp_keypair *ecp = NULL;
188
189 /* Parse input */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200190 status = mbedtls_psa_ecp_load_representation(
191 attributes->core.type, attributes->core.bits, data, data_length, &ecp);
192 if (status != PSA_SUCCESS)
Ronald Crond6ec3032020-11-27 18:54:57 +0100193 goto exit;
194
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200195 if (PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type) ==
196 PSA_ECC_FAMILY_MONTGOMERY)
Ronald Crond6ec3032020-11-27 18:54:57 +0100197 *bits = ecp->grp.nbits + 1;
198 else
199 *bits = ecp->grp.nbits;
200
201 /* Re-export the data to PSA export format. There is currently no support
202 * for other input formats then the export format, so this is a 1-1
203 * copy operation. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200204 status = mbedtls_psa_ecp_export_key(attributes->core.type, ecp, key_buffer,
205 key_buffer_size, key_buffer_length);
Ronald Crond6ec3032020-11-27 18:54:57 +0100206exit:
207 /* Always free the PK object (will also free contained ECP context) */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200208 mbedtls_ecp_keypair_free(ecp);
209 mbedtls_free(ecp);
Ronald Crond6ec3032020-11-27 18:54:57 +0100210
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200211 return status;
Ronald Crond6ec3032020-11-27 18:54:57 +0100212}
213
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200214psa_status_t mbedtls_psa_ecp_export_key(psa_key_type_t type,
215 mbedtls_ecp_keypair *ecp,
216 uint8_t *data,
217 size_t data_size,
218 size_t *data_length)
Ronald Crone5ca3d82020-11-26 16:36:16 +0100219{
220 psa_status_t status;
221
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200222 if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type)) {
Ronald Crone5ca3d82020-11-26 16:36:16 +0100223 /* Check whether the public part is loaded */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200224 if (mbedtls_ecp_is_zero(&ecp->Q)) {
Ronald Crone5ca3d82020-11-26 16:36:16 +0100225 /* Calculate the public key */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200226 status = mbedtls_to_psa_error(mbedtls_ecp_mul(
227 &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
228 mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE));
229 if (status != PSA_SUCCESS)
230 return status;
Ronald Crone5ca3d82020-11-26 16:36:16 +0100231 }
232
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200233 status = mbedtls_to_psa_error(mbedtls_ecp_point_write_binary(
234 &ecp->grp, &ecp->Q, MBEDTLS_ECP_PF_UNCOMPRESSED, data_length, data,
235 data_size));
236 if (status != PSA_SUCCESS)
237 memset(data, 0, data_size);
Ronald Crone5ca3d82020-11-26 16:36:16 +0100238
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200239 return status;
240 } else {
241 if (data_size < PSA_BITS_TO_BYTES(ecp->grp.nbits))
242 return PSA_ERROR_BUFFER_TOO_SMALL;
Ronald Crone5ca3d82020-11-26 16:36:16 +0100243
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200244 status = mbedtls_to_psa_error(mbedtls_ecp_write_key(
245 ecp, data, PSA_BITS_TO_BYTES(ecp->grp.nbits)));
246 if (status == PSA_SUCCESS)
247 *data_length = PSA_BITS_TO_BYTES(ecp->grp.nbits);
Ronald Crone5ca3d82020-11-26 16:36:16 +0100248 else
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200249 memset(data, 0, data_size);
Ronald Crone5ca3d82020-11-26 16:36:16 +0100250
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200251 return status;
Ronald Crone5ca3d82020-11-26 16:36:16 +0100252 }
253}
254
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200255static psa_status_t
256ecp_export_public_key(const psa_key_attributes_t *attributes,
257 const uint8_t *key_buffer,
258 size_t key_buffer_size,
259 uint8_t *data,
260 size_t data_size,
261 size_t *data_length)
Ronald Crone5ca3d82020-11-26 16:36:16 +0100262{
263 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
264 mbedtls_ecp_keypair *ecp = NULL;
265
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200266 status = mbedtls_psa_ecp_load_representation(attributes->core.type,
267 attributes->core.bits,
268 key_buffer, key_buffer_size,
269 &ecp);
270 if (status != PSA_SUCCESS)
271 return status;
Ronald Crone5ca3d82020-11-26 16:36:16 +0100272
273 status = mbedtls_psa_ecp_export_key(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200274 PSA_KEY_TYPE_ECC_PUBLIC_KEY(
275 PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type)),
276 ecp, data, data_size, data_length);
Ronald Crone5ca3d82020-11-26 16:36:16 +0100277
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200278 mbedtls_ecp_keypair_free(ecp);
279 mbedtls_free(ecp);
Ronald Crone5ca3d82020-11-26 16:36:16 +0100280
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200281 return status;
Ronald Crone5ca3d82020-11-26 16:36:16 +0100282}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200283# endif /* defined(BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
284 * defined(BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
Ronald Cronf1057d32020-11-26 19:19:10 +0100285
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200286# if defined(BUILTIN_KEY_TYPE_ECC_KEY_PAIR)
287static psa_status_t ecp_generate_key(const psa_key_attributes_t *attributes,
288 uint8_t *key_buffer,
289 size_t key_buffer_size,
290 size_t *key_buffer_length)
Ronald Cron7023db52020-11-20 18:17:42 +0100291{
292 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
293 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
294
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200295 psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type);
Ronald Cron7023db52020-11-20 18:17:42 +0100296 mbedtls_ecp_group_id grp_id =
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200297 mbedtls_ecc_group_of_psa(curve, attributes->core.bits, 0);
Ronald Cron7023db52020-11-20 18:17:42 +0100298
299 const mbedtls_ecp_curve_info *curve_info =
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200300 mbedtls_ecp_curve_info_from_grp_id(grp_id);
Ronald Cron7023db52020-11-20 18:17:42 +0100301 mbedtls_ecp_keypair ecp;
302
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200303 if (attributes->domain_parameters_size != 0)
304 return PSA_ERROR_NOT_SUPPORTED;
Ronald Cron7023db52020-11-20 18:17:42 +0100305
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200306 if (grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL)
307 return PSA_ERROR_NOT_SUPPORTED;
Ronald Cron7023db52020-11-20 18:17:42 +0100308
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200309 mbedtls_ecp_keypair_init(&ecp);
310 ret = mbedtls_ecp_gen_key(grp_id, &ecp, mbedtls_psa_get_random,
311 MBEDTLS_PSA_RANDOM_STATE);
312 if (ret != 0) {
313 mbedtls_ecp_keypair_free(&ecp);
314 return mbedtls_to_psa_error(ret);
Ronald Cron7023db52020-11-20 18:17:42 +0100315 }
316
317 status = mbedtls_to_psa_error(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200318 mbedtls_ecp_write_key(&ecp, key_buffer, key_buffer_size));
Ronald Cron7023db52020-11-20 18:17:42 +0100319
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200320 mbedtls_ecp_keypair_free(&ecp);
Ronald Cron7023db52020-11-20 18:17:42 +0100321
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200322 if (status == PSA_SUCCESS)
Ronald Cron7023db52020-11-20 18:17:42 +0100323 *key_buffer_length = key_buffer_size;
324
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200325 return status;
Ronald Cron7023db52020-11-20 18:17:42 +0100326}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200327# endif /* defined(BUILTIN_KEY_TYPE_ECC_KEY_PAIR) */
Ronald Cron7023db52020-11-20 18:17:42 +0100328
Ronald Cron072722c2020-12-09 16:36:19 +0100329/****************************************************************/
330/* ECDSA sign/verify */
331/****************************************************************/
332
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200333# if defined(BUILTIN_ALG_ECDSA) || defined(BUILTIN_ALG_DETERMINISTIC_ECDSA)
334static psa_status_t ecdsa_sign_hash(const psa_key_attributes_t *attributes,
335 const uint8_t *key_buffer,
336 size_t key_buffer_size,
337 psa_algorithm_t alg,
338 const uint8_t *hash,
339 size_t hash_length,
340 uint8_t *signature,
341 size_t signature_size,
342 size_t *signature_length)
Ronald Cron072722c2020-12-09 16:36:19 +0100343{
344 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
345 mbedtls_ecp_keypair *ecp = NULL;
346 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
347 size_t curve_bytes;
348 mbedtls_mpi r, s;
349
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200350 status = mbedtls_psa_ecp_load_representation(attributes->core.type,
351 attributes->core.bits,
352 key_buffer, key_buffer_size,
353 &ecp);
354 if (status != PSA_SUCCESS)
355 return status;
Ronald Cron072722c2020-12-09 16:36:19 +0100356
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200357 curve_bytes = PSA_BITS_TO_BYTES(ecp->grp.pbits);
358 mbedtls_mpi_init(&r);
359 mbedtls_mpi_init(&s);
Ronald Cron072722c2020-12-09 16:36:19 +0100360
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200361 if (signature_size < 2 * curve_bytes) {
Ronald Cron072722c2020-12-09 16:36:19 +0100362 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
363 goto cleanup;
364 }
365
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200366 if (PSA_ALG_ECDSA_IS_DETERMINISTIC(alg)) {
367# if defined(BUILTIN_ALG_DETERMINISTIC_ECDSA)
368 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
369 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa(hash_alg);
370 mbedtls_md_type_t md_alg = mbedtls_md_get_type(md_info);
371 MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign_det_ext(
372 &ecp->grp, &r, &s, &ecp->d, hash, hash_length, md_alg,
373 mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE));
374# else
375 ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
376 goto cleanup;
377# endif /* defined(BUILTIN_ALG_DETERMINISTIC_ECDSA) */
378 } else {
379 (void)alg;
380 MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign(&ecp->grp, &r, &s, &ecp->d, hash,
381 hash_length, mbedtls_psa_get_random,
382 MBEDTLS_PSA_RANDOM_STATE));
Ronald Cron072722c2020-12-09 16:36:19 +0100383 }
384
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200385 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&r, signature, curve_bytes));
386 MBEDTLS_MPI_CHK(
387 mbedtls_mpi_write_binary(&s, signature + curve_bytes, curve_bytes));
Ronald Cron072722c2020-12-09 16:36:19 +0100388cleanup:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200389 mbedtls_mpi_free(&r);
390 mbedtls_mpi_free(&s);
391 if (ret == 0)
Ronald Cron072722c2020-12-09 16:36:19 +0100392 *signature_length = 2 * curve_bytes;
393
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200394 mbedtls_ecp_keypair_free(ecp);
395 mbedtls_free(ecp);
Ronald Cron072722c2020-12-09 16:36:19 +0100396
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200397 return mbedtls_to_psa_error(ret);
Ronald Cron072722c2020-12-09 16:36:19 +0100398}
399
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200400static psa_status_t ecdsa_verify_hash(const psa_key_attributes_t *attributes,
401 const uint8_t *key_buffer,
402 size_t key_buffer_size,
403 psa_algorithm_t alg,
404 const uint8_t *hash,
405 size_t hash_length,
406 const uint8_t *signature,
407 size_t signature_length)
Ronald Cron072722c2020-12-09 16:36:19 +0100408{
409 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
410 mbedtls_ecp_keypair *ecp = NULL;
411 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
412 size_t curve_bytes;
413 mbedtls_mpi r, s;
414
415 (void)alg;
416
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200417 status = mbedtls_psa_ecp_load_representation(attributes->core.type,
418 attributes->core.bits,
419 key_buffer, key_buffer_size,
420 &ecp);
421 if (status != PSA_SUCCESS)
422 return status;
Ronald Cron072722c2020-12-09 16:36:19 +0100423
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200424 curve_bytes = PSA_BITS_TO_BYTES(ecp->grp.pbits);
425 mbedtls_mpi_init(&r);
426 mbedtls_mpi_init(&s);
Ronald Cron072722c2020-12-09 16:36:19 +0100427
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200428 if (signature_length != 2 * curve_bytes) {
Ronald Cron072722c2020-12-09 16:36:19 +0100429 ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
430 goto cleanup;
431 }
432
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200433 MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&r, signature, curve_bytes));
434 MBEDTLS_MPI_CHK(
435 mbedtls_mpi_read_binary(&s, signature + curve_bytes, curve_bytes));
Ronald Cron072722c2020-12-09 16:36:19 +0100436
437 /* Check whether the public part is loaded. If not, load it. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200438 if (mbedtls_ecp_is_zero(&ecp->Q)) {
439 MBEDTLS_MPI_CHK(mbedtls_ecp_mul(&ecp->grp, &ecp->Q, &ecp->d,
440 &ecp->grp.G, mbedtls_psa_get_random,
441 MBEDTLS_PSA_RANDOM_STATE));
Ronald Cron072722c2020-12-09 16:36:19 +0100442 }
443
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200444 ret = mbedtls_ecdsa_verify(&ecp->grp, hash, hash_length, &ecp->Q, &r, &s);
Ronald Cron072722c2020-12-09 16:36:19 +0100445
446cleanup:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200447 mbedtls_mpi_free(&r);
448 mbedtls_mpi_free(&s);
449 mbedtls_ecp_keypair_free(ecp);
450 mbedtls_free(ecp);
Ronald Cron072722c2020-12-09 16:36:19 +0100451
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200452 return mbedtls_to_psa_error(ret);
Ronald Cron072722c2020-12-09 16:36:19 +0100453}
454
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200455# endif /* defined(BUILTIN_ALG_ECDSA) || \
456 * defined(BUILTIN_ALG_DETERMINISTIC_ECDSA) */
Ronald Cron072722c2020-12-09 16:36:19 +0100457
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200458# if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
459 defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
Ronald Cronf1057d32020-11-26 19:19:10 +0100460
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200461psa_status_t mbedtls_psa_ecp_import_key(const psa_key_attributes_t *attributes,
462 const uint8_t *data,
463 size_t data_length,
464 uint8_t *key_buffer,
465 size_t key_buffer_size,
466 size_t *key_buffer_length,
467 size_t *bits)
Ronald Cron784fb322020-11-30 13:55:05 +0100468{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200469 return (ecp_import_key(attributes, data, data_length, key_buffer,
470 key_buffer_size, key_buffer_length, bits));
Ronald Cron784fb322020-11-30 13:55:05 +0100471}
472
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200473psa_status_t
474mbedtls_psa_ecp_export_public_key(const psa_key_attributes_t *attributes,
475 const uint8_t *key_buffer,
476 size_t key_buffer_size,
477 uint8_t *data,
478 size_t data_size,
479 size_t *data_length)
Ronald Cronf1057d32020-11-26 19:19:10 +0100480{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200481 return (ecp_export_public_key(attributes, key_buffer, key_buffer_size, data,
482 data_size, data_length));
Ronald Cronf1057d32020-11-26 19:19:10 +0100483}
484
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200485# endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
486 * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
Ronald Crone5ca3d82020-11-26 16:36:16 +0100487
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200488# if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR)
489psa_status_t
490mbedtls_psa_ecp_generate_key(const psa_key_attributes_t *attributes,
491 uint8_t *key_buffer,
492 size_t key_buffer_size,
493 size_t *key_buffer_length)
Ronald Cronbbe5cbb2020-11-20 19:42:24 +0100494{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200495 return (ecp_generate_key(attributes, key_buffer, key_buffer_size,
496 key_buffer_length));
Ronald Cronbbe5cbb2020-11-20 19:42:24 +0100497}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200498# endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) */
Ronald Cronbbe5cbb2020-11-20 19:42:24 +0100499
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200500# if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
501 defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
Ronald Cronb5399a82020-12-10 09:35:33 +0100502
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200503psa_status_t mbedtls_psa_ecdsa_sign_hash(const psa_key_attributes_t *attributes,
504 const uint8_t *key_buffer,
505 size_t key_buffer_size,
506 psa_algorithm_t alg,
507 const uint8_t *hash,
508 size_t hash_length,
509 uint8_t *signature,
510 size_t signature_size,
511 size_t *signature_length)
Ronald Cronb5399a82020-12-10 09:35:33 +0100512{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200513 return (ecdsa_sign_hash(attributes, key_buffer, key_buffer_size, alg, hash,
514 hash_length, signature, signature_size,
515 signature_length));
Ronald Cronb5399a82020-12-10 09:35:33 +0100516}
517
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200518psa_status_t
519mbedtls_psa_ecdsa_verify_hash(const psa_key_attributes_t *attributes,
520 const uint8_t *key_buffer,
521 size_t key_buffer_size,
522 psa_algorithm_t alg,
523 const uint8_t *hash,
524 size_t hash_length,
525 const uint8_t *signature,
526 size_t signature_length)
Ronald Cronb5399a82020-12-10 09:35:33 +0100527{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200528 return (ecdsa_verify_hash(attributes, key_buffer, key_buffer_size, alg,
529 hash, hash_length, signature, signature_length));
Ronald Cronb5399a82020-12-10 09:35:33 +0100530}
531
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200532# endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
533 * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
Ronald Cronb5399a82020-12-10 09:35:33 +0100534
Ronald Cronf1057d32020-11-26 19:19:10 +0100535/*
536 * BEYOND THIS POINT, TEST DRIVER ENTRY POINTS ONLY.
537 */
538
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200539# if defined(PSA_CRYPTO_DRIVER_TEST)
Ronald Cronf1057d32020-11-26 19:19:10 +0100540
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200541# if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) || \
542 defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY)
Ronald Cron784fb322020-11-30 13:55:05 +0100543
544psa_status_t mbedtls_transparent_test_driver_ecp_import_key(
545 const psa_key_attributes_t *attributes,
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200546 const uint8_t *data,
547 size_t data_length,
548 uint8_t *key_buffer,
549 size_t key_buffer_size,
550 size_t *key_buffer_length,
551 size_t *bits)
Ronald Cron784fb322020-11-30 13:55:05 +0100552{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200553 return (ecp_import_key(attributes, data, data_length, key_buffer,
554 key_buffer_size, key_buffer_length, bits));
Ronald Cron784fb322020-11-30 13:55:05 +0100555}
556
Ronald Cronf1057d32020-11-26 19:19:10 +0100557psa_status_t mbedtls_transparent_test_driver_ecp_export_public_key(
558 const psa_key_attributes_t *attributes,
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200559 const uint8_t *key_buffer,
560 size_t key_buffer_size,
561 uint8_t *data,
562 size_t data_size,
563 size_t *data_length)
Ronald Cronf1057d32020-11-26 19:19:10 +0100564{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200565 return (ecp_export_public_key(attributes, key_buffer, key_buffer_size, data,
566 data_size, data_length));
Ronald Cronf1057d32020-11-26 19:19:10 +0100567}
Ronald Cron784fb322020-11-30 13:55:05 +0100568
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200569# endif /* defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) || \
570 defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) */
Ronald Cronf1057d32020-11-26 19:19:10 +0100571
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200572# if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) && \
573 defined(MBEDTLS_GENPRIME)
Ronald Cronbbe5cbb2020-11-20 19:42:24 +0100574psa_status_t mbedtls_transparent_test_driver_ecp_generate_key(
575 const psa_key_attributes_t *attributes,
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200576 uint8_t *key_buffer,
577 size_t key_buffer_size,
578 size_t *key_buffer_length)
Ronald Cronbbe5cbb2020-11-20 19:42:24 +0100579{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200580 return (ecp_generate_key(attributes, key_buffer, key_buffer_size,
581 key_buffer_length));
Ronald Cronbbe5cbb2020-11-20 19:42:24 +0100582}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200583# endif /* defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) && \
584 defined(MBEDTLS_GENPRIME) */
Ronald Cronbbe5cbb2020-11-20 19:42:24 +0100585
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200586# if defined(MBEDTLS_PSA_ACCEL_ALG_ECDSA) || \
587 defined(MBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA)
Ronald Cronb5399a82020-12-10 09:35:33 +0100588
589psa_status_t mbedtls_transparent_test_driver_ecdsa_sign_hash(
590 const psa_key_attributes_t *attributes,
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200591 const uint8_t *key_buffer,
592 size_t key_buffer_size,
593 psa_algorithm_t alg,
594 const uint8_t *hash,
595 size_t hash_length,
596 uint8_t *signature,
597 size_t signature_size,
598 size_t *signature_length)
Ronald Cronb5399a82020-12-10 09:35:33 +0100599{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200600# if defined(MBEDTLS_ECDSA_C)
601 return (ecdsa_sign_hash(attributes, key_buffer, key_buffer_size, alg, hash,
602 hash_length, signature, signature_size,
603 signature_length));
604# else
Ronald Cronb5399a82020-12-10 09:35:33 +0100605 (void)attributes;
606 (void)key_buffer;
607 (void)key_buffer_size;
608 (void)alg;
609 (void)hash;
610 (void)hash_length;
611 (void)signature;
612 (void)signature_size;
613 (void)signature_length;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200614 return PSA_ERROR_NOT_SUPPORTED;
615# endif
Ronald Cronb5399a82020-12-10 09:35:33 +0100616}
617
618psa_status_t mbedtls_transparent_test_driver_ecdsa_verify_hash(
619 const psa_key_attributes_t *attributes,
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200620 const uint8_t *key_buffer,
621 size_t key_buffer_size,
622 psa_algorithm_t alg,
623 const uint8_t *hash,
624 size_t hash_length,
625 const uint8_t *signature,
626 size_t signature_length)
Ronald Cronb5399a82020-12-10 09:35:33 +0100627{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200628# if defined(MBEDTLS_ECDSA_C)
629 return (ecdsa_verify_hash(attributes, key_buffer, key_buffer_size, alg,
630 hash, hash_length, signature, signature_length));
631# else
Ronald Cronb5399a82020-12-10 09:35:33 +0100632 (void)attributes;
633 (void)key_buffer;
634 (void)key_buffer_size;
635 (void)alg;
636 (void)hash;
637 (void)hash_length;
638 (void)signature;
639 (void)signature_length;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200640 return PSA_ERROR_NOT_SUPPORTED;
641# endif
Ronald Cronb5399a82020-12-10 09:35:33 +0100642}
643
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200644# endif /* defined(MBEDTLS_PSA_ACCEL_ALG_ECDSA) || \
645 * defined(MBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA) */
Ronald Cronb5399a82020-12-10 09:35:33 +0100646
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200647# endif /* PSA_CRYPTO_DRIVER_TEST */
Ronald Cronf1057d32020-11-26 19:19:10 +0100648
Ronald Cron00b7bfc2020-11-25 15:25:26 +0100649#endif /* MBEDTLS_PSA_CRYPTO_C */