blob: f3fcd1d8cc4bfe47cdfc41d3e35f15fbea5b3f3b [file] [log] [blame]
Andrzej Kurek8a045ce2022-12-23 11:00:06 -05001/*
2 * PSA hashing layer on top of Mbed TLS software crypto
3 */
4/*
5 * Copyright The Mbed TLS Contributors
Dave Rodgman16799db2023-11-02 19:47:20 +00006 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Andrzej Kurek8a045ce2022-12-23 11:00:06 -05007 */
8
9#include "common.h"
10
Valerio Settic22e3ce2024-01-10 08:46:59 +010011/* This is needed for MBEDTLS_ERR_XXX macros */
12#include <mbedtls/error.h>
13
14#if defined(MBEDTLS_ASN1_WRITE_C)
15#include <mbedtls/asn1write.h>
16#include <psa/crypto_sizes.h>
17#endif
18
19#include "psa_util_internal.h"
20
Andrzej Kurek8a045ce2022-12-23 11:00:06 -050021#if defined(MBEDTLS_PSA_CRYPTO_C)
22
23#include <psa/crypto.h>
24
Manuel Pégourié-Gonnardabfe6402023-06-20 09:59:13 +020025#if defined(MBEDTLS_MD_LIGHT)
26#include <mbedtls/md.h>
27#endif
28#if defined(MBEDTLS_LMS_C)
Andrzej Kurek8a045ce2022-12-23 11:00:06 -050029#include <mbedtls/lms.h>
Manuel Pégourié-Gonnardabfe6402023-06-20 09:59:13 +020030#endif
31#if defined(MBEDTLS_SSL_TLS_C) && \
32 (defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3))
Andrzej Kurek8a045ce2022-12-23 11:00:06 -050033#include <mbedtls/ssl.h>
Manuel Pégourié-Gonnardabfe6402023-06-20 09:59:13 +020034#endif
35#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) || \
Valerio Setti7e6aaa12023-07-11 16:59:21 +020036 defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
Andrzej Kurek8a045ce2022-12-23 11:00:06 -050037#include <mbedtls/rsa.h>
Manuel Pégourié-Gonnardabfe6402023-06-20 09:59:13 +020038#endif
39#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
40 defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
41#include <mbedtls/ecp.h>
42#endif
43#if defined(MBEDTLS_PK_C)
44#include <mbedtls/pk.h>
45#endif
Valerio Setti8ceaa752023-12-12 11:20:18 +010046#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
47#include <mbedtls/cipher.h>
48#endif
Andrzej Kurek8a045ce2022-12-23 11:00:06 -050049
50/* PSA_SUCCESS is kept at the top of each error table since
51 * it's the most common status when everything functions properly. */
Manuel Pégourié-Gonnard725d2e22023-03-29 12:38:37 +020052#if defined(MBEDTLS_MD_LIGHT)
Andrzej Kurek270b3f92023-03-03 05:54:13 -050053const mbedtls_error_pair_t psa_to_md_errors[] =
Andrzej Kurek8a045ce2022-12-23 11:00:06 -050054{
Andrzej Kurek747ab4e2023-02-28 10:32:47 -050055 { PSA_SUCCESS, 0 },
56 { PSA_ERROR_NOT_SUPPORTED, MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE },
57 { PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_MD_BAD_INPUT_DATA },
58 { PSA_ERROR_INSUFFICIENT_MEMORY, MBEDTLS_ERR_MD_ALLOC_FAILED }
Andrzej Kurek8a045ce2022-12-23 11:00:06 -050059};
60#endif
Valerio Setti8ceaa752023-12-12 11:20:18 +010061
62#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
63const mbedtls_error_pair_t psa_to_cipher_errors[] =
64{
65 { PSA_SUCCESS, 0 },
66 { PSA_ERROR_NOT_SUPPORTED, MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE },
67 { PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA },
68 { PSA_ERROR_INSUFFICIENT_MEMORY, MBEDTLS_ERR_CIPHER_ALLOC_FAILED }
69};
70#endif
71
Andrzej Kurek8a045ce2022-12-23 11:00:06 -050072#if defined(MBEDTLS_LMS_C)
Andrzej Kurek270b3f92023-03-03 05:54:13 -050073const mbedtls_error_pair_t psa_to_lms_errors[] =
Andrzej Kurek8a045ce2022-12-23 11:00:06 -050074{
Andrzej Kurek747ab4e2023-02-28 10:32:47 -050075 { PSA_SUCCESS, 0 },
76 { PSA_ERROR_BUFFER_TOO_SMALL, MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL },
77 { PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_LMS_BAD_INPUT_DATA }
Andrzej Kurek8a045ce2022-12-23 11:00:06 -050078};
79#endif
Valerio Setti8ceaa752023-12-12 11:20:18 +010080
Manuel Pégourié-Gonnardabfe6402023-06-20 09:59:13 +020081#if defined(MBEDTLS_SSL_TLS_C) && \
82 (defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3))
Andrzej Kurek270b3f92023-03-03 05:54:13 -050083const mbedtls_error_pair_t psa_to_ssl_errors[] =
Andrzej Kurek8a045ce2022-12-23 11:00:06 -050084{
Andrzej Kurek747ab4e2023-02-28 10:32:47 -050085 { PSA_SUCCESS, 0 },
86 { PSA_ERROR_INSUFFICIENT_MEMORY, MBEDTLS_ERR_SSL_ALLOC_FAILED },
87 { PSA_ERROR_NOT_SUPPORTED, MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE },
88 { PSA_ERROR_INVALID_SIGNATURE, MBEDTLS_ERR_SSL_INVALID_MAC },
89 { PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_SSL_BAD_INPUT_DATA },
90 { PSA_ERROR_BAD_STATE, MBEDTLS_ERR_SSL_INTERNAL_ERROR },
91 { PSA_ERROR_BUFFER_TOO_SMALL, MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL }
Andrzej Kurek8a045ce2022-12-23 11:00:06 -050092};
93#endif
94
95#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) || \
Valerio Settif6d4dfb2023-07-10 10:55:12 +020096 defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
Andrzej Kurek270b3f92023-03-03 05:54:13 -050097const mbedtls_error_pair_t psa_to_pk_rsa_errors[] =
Andrzej Kurek8a045ce2022-12-23 11:00:06 -050098{
Andrzej Kurek747ab4e2023-02-28 10:32:47 -050099 { PSA_SUCCESS, 0 },
100 { PSA_ERROR_NOT_PERMITTED, MBEDTLS_ERR_RSA_BAD_INPUT_DATA },
101 { PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_RSA_BAD_INPUT_DATA },
102 { PSA_ERROR_INVALID_HANDLE, MBEDTLS_ERR_RSA_BAD_INPUT_DATA },
103 { PSA_ERROR_BUFFER_TOO_SMALL, MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE },
104 { PSA_ERROR_INSUFFICIENT_ENTROPY, MBEDTLS_ERR_RSA_RNG_FAILED },
105 { PSA_ERROR_INVALID_SIGNATURE, MBEDTLS_ERR_RSA_VERIFY_FAILED },
106 { PSA_ERROR_INVALID_PADDING, MBEDTLS_ERR_RSA_INVALID_PADDING }
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500107};
108#endif
109
110#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
111 defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
Andrzej Kurek270b3f92023-03-03 05:54:13 -0500112const mbedtls_error_pair_t psa_to_pk_ecdsa_errors[] =
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500113{
Andrzej Kurek747ab4e2023-02-28 10:32:47 -0500114 { PSA_SUCCESS, 0 },
115 { PSA_ERROR_NOT_PERMITTED, MBEDTLS_ERR_ECP_BAD_INPUT_DATA },
116 { PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_ECP_BAD_INPUT_DATA },
117 { PSA_ERROR_INVALID_HANDLE, MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE },
118 { PSA_ERROR_BUFFER_TOO_SMALL, MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL },
119 { PSA_ERROR_INSUFFICIENT_ENTROPY, MBEDTLS_ERR_ECP_RANDOM_FAILED },
120 { PSA_ERROR_INVALID_SIGNATURE, MBEDTLS_ERR_ECP_VERIFY_FAILED }
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500121};
122#endif
123
124int psa_generic_status_to_mbedtls(psa_status_t status)
125{
126 switch (status) {
127 case PSA_SUCCESS:
128 return 0;
129 case PSA_ERROR_NOT_SUPPORTED:
130 return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
131 case PSA_ERROR_CORRUPTION_DETECTED:
132 return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
133 case PSA_ERROR_COMMUNICATION_FAILURE:
134 case PSA_ERROR_HARDWARE_FAILURE:
135 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
136 case PSA_ERROR_NOT_PERMITTED:
137 default:
138 return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
139 }
140}
141
142int psa_status_to_mbedtls(psa_status_t status,
Andrzej Kurek270b3f92023-03-03 05:54:13 -0500143 const mbedtls_error_pair_t *local_translations,
Valerio Settiab9dc662023-03-27 14:02:08 +0200144 size_t local_errors_num,
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500145 int (*fallback_f)(psa_status_t))
146{
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500147 for (size_t i = 0; i < local_errors_num; i++) {
Andrzej Kurek747ab4e2023-02-28 10:32:47 -0500148 if (status == local_translations[i].psa_status) {
149 return local_translations[i].mbedtls_error;
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500150 }
151 }
152 return fallback_f(status);
153}
154
Manuel Pégourié-Gonnardabfe6402023-06-20 09:59:13 +0200155#if defined(MBEDTLS_PK_C)
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500156int psa_pk_status_to_mbedtls(psa_status_t status)
157{
158 switch (status) {
159 case PSA_ERROR_INVALID_HANDLE:
160 return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
161 case PSA_ERROR_BUFFER_TOO_SMALL:
162 return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
163 case PSA_ERROR_NOT_SUPPORTED:
164 return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
165 case PSA_ERROR_INVALID_ARGUMENT:
166 return MBEDTLS_ERR_PK_INVALID_ALG;
167 case PSA_ERROR_INSUFFICIENT_MEMORY:
168 return MBEDTLS_ERR_PK_ALLOC_FAILED;
169 case PSA_ERROR_BAD_STATE:
170 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
171 case PSA_ERROR_DATA_CORRUPT:
172 case PSA_ERROR_DATA_INVALID:
173 case PSA_ERROR_STORAGE_FAILURE:
174 return MBEDTLS_ERR_PK_FILE_IO_ERROR;
175 default:
176 return psa_generic_status_to_mbedtls(status);
177 }
178}
Manuel Pégourié-Gonnardabfe6402023-06-20 09:59:13 +0200179#endif /* MBEDTLS_PK_C */
Joakim Anderssonb3491082023-12-11 21:29:19 +0100180
181/****************************************************************/
182/* Key management */
183/****************************************************************/
184
185#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
186psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid,
187 size_t *bits)
188{
189 switch (grpid) {
190#if defined(MBEDTLS_ECP_HAVE_SECP192R1)
191 case MBEDTLS_ECP_DP_SECP192R1:
192 *bits = 192;
193 return PSA_ECC_FAMILY_SECP_R1;
194#endif
195#if defined(MBEDTLS_ECP_HAVE_SECP224R1)
196 case MBEDTLS_ECP_DP_SECP224R1:
197 *bits = 224;
198 return PSA_ECC_FAMILY_SECP_R1;
199#endif
200#if defined(MBEDTLS_ECP_HAVE_SECP256R1)
201 case MBEDTLS_ECP_DP_SECP256R1:
202 *bits = 256;
203 return PSA_ECC_FAMILY_SECP_R1;
204#endif
205#if defined(MBEDTLS_ECP_HAVE_SECP384R1)
206 case MBEDTLS_ECP_DP_SECP384R1:
207 *bits = 384;
208 return PSA_ECC_FAMILY_SECP_R1;
209#endif
210#if defined(MBEDTLS_ECP_HAVE_SECP521R1)
211 case MBEDTLS_ECP_DP_SECP521R1:
212 *bits = 521;
213 return PSA_ECC_FAMILY_SECP_R1;
214#endif
215#if defined(MBEDTLS_ECP_HAVE_BP256R1)
216 case MBEDTLS_ECP_DP_BP256R1:
217 *bits = 256;
218 return PSA_ECC_FAMILY_BRAINPOOL_P_R1;
219#endif
220#if defined(MBEDTLS_ECP_HAVE_BP384R1)
221 case MBEDTLS_ECP_DP_BP384R1:
222 *bits = 384;
223 return PSA_ECC_FAMILY_BRAINPOOL_P_R1;
224#endif
225#if defined(MBEDTLS_ECP_HAVE_BP512R1)
226 case MBEDTLS_ECP_DP_BP512R1:
227 *bits = 512;
228 return PSA_ECC_FAMILY_BRAINPOOL_P_R1;
229#endif
230#if defined(MBEDTLS_ECP_HAVE_CURVE25519)
231 case MBEDTLS_ECP_DP_CURVE25519:
232 *bits = 255;
233 return PSA_ECC_FAMILY_MONTGOMERY;
234#endif
235#if defined(MBEDTLS_ECP_HAVE_SECP192K1)
236 case MBEDTLS_ECP_DP_SECP192K1:
237 *bits = 192;
238 return PSA_ECC_FAMILY_SECP_K1;
239#endif
240#if defined(MBEDTLS_ECP_HAVE_SECP224K1)
Valerio Setti78636272024-01-04 13:17:04 +0100241 /* secp224k1 is not and will not be supported in PSA (#3541). */
Joakim Anderssonb3491082023-12-11 21:29:19 +0100242#endif
243#if defined(MBEDTLS_ECP_HAVE_SECP256K1)
244 case MBEDTLS_ECP_DP_SECP256K1:
245 *bits = 256;
246 return PSA_ECC_FAMILY_SECP_K1;
247#endif
248#if defined(MBEDTLS_ECP_HAVE_CURVE448)
249 case MBEDTLS_ECP_DP_CURVE448:
250 *bits = 448;
251 return PSA_ECC_FAMILY_MONTGOMERY;
252#endif
253 default:
254 *bits = 0;
255 return 0;
256 }
257}
258
Valerio Setti39faa9c2024-01-09 09:11:22 +0100259mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t family,
Valerio Settid36c3132023-12-21 14:03:51 +0100260 size_t bits)
Joakim Anderssonb3491082023-12-11 21:29:19 +0100261{
Valerio Setti39faa9c2024-01-09 09:11:22 +0100262 switch (family) {
Joakim Anderssonb3491082023-12-11 21:29:19 +0100263 case PSA_ECC_FAMILY_SECP_R1:
264 switch (bits) {
265#if defined(PSA_WANT_ECC_SECP_R1_192)
266 case 192:
267 return MBEDTLS_ECP_DP_SECP192R1;
268#endif
269#if defined(PSA_WANT_ECC_SECP_R1_224)
270 case 224:
271 return MBEDTLS_ECP_DP_SECP224R1;
272#endif
273#if defined(PSA_WANT_ECC_SECP_R1_256)
274 case 256:
275 return MBEDTLS_ECP_DP_SECP256R1;
276#endif
277#if defined(PSA_WANT_ECC_SECP_R1_384)
278 case 384:
279 return MBEDTLS_ECP_DP_SECP384R1;
280#endif
281#if defined(PSA_WANT_ECC_SECP_R1_521)
282 case 521:
Valerio Settid36c3132023-12-21 14:03:51 +0100283 return MBEDTLS_ECP_DP_SECP521R1;
Joakim Anderssonb3491082023-12-11 21:29:19 +0100284#endif
285 }
286 break;
287
288 case PSA_ECC_FAMILY_BRAINPOOL_P_R1:
289 switch (bits) {
290#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256)
291 case 256:
292 return MBEDTLS_ECP_DP_BP256R1;
293#endif
294#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384)
295 case 384:
296 return MBEDTLS_ECP_DP_BP384R1;
297#endif
298#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512)
299 case 512:
300 return MBEDTLS_ECP_DP_BP512R1;
301#endif
302 }
303 break;
304
305 case PSA_ECC_FAMILY_MONTGOMERY:
306 switch (bits) {
307#if defined(PSA_WANT_ECC_MONTGOMERY_255)
308 case 255:
Valerio Settid36c3132023-12-21 14:03:51 +0100309 return MBEDTLS_ECP_DP_CURVE25519;
Joakim Anderssonb3491082023-12-11 21:29:19 +0100310#endif
311#if defined(PSA_WANT_ECC_MONTGOMERY_448)
312 case 448:
313 return MBEDTLS_ECP_DP_CURVE448;
314#endif
315 }
316 break;
317
318 case PSA_ECC_FAMILY_SECP_K1:
319 switch (bits) {
320#if defined(PSA_WANT_ECC_SECP_K1_192)
321 case 192:
322 return MBEDTLS_ECP_DP_SECP192K1;
323#endif
324#if defined(PSA_WANT_ECC_SECP_K1_224)
Valerio Setti78636272024-01-04 13:17:04 +0100325 /* secp224k1 is not and will not be supported in PSA (#3541). */
Joakim Anderssonb3491082023-12-11 21:29:19 +0100326#endif
327#if defined(PSA_WANT_ECC_SECP_K1_256)
328 case 256:
329 return MBEDTLS_ECP_DP_SECP256K1;
330#endif
331 }
332 break;
333 }
334
Joakim Anderssonb3491082023-12-11 21:29:19 +0100335 return MBEDTLS_ECP_DP_NONE;
336}
337#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */
338
Valerio Settic22e3ce2024-01-10 08:46:59 +0100339#endif /* MBEDTLS_PSA_CRYPTO_C */
340
Valerio Settif4d2dc22024-01-16 10:57:48 +0100341#if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
342
Valerio Setti84890c92024-01-09 14:20:23 +0100343/**
344 * \brief Convert a single raw coordinate to DER ASN.1 format. The output der
345 * buffer is filled backward (i.e. starting from its end).
346 *
347 * \param raw_buf Buffer containing the raw coordinate to be
348 * converted.
Valerio Setti2bd0ecd2024-02-05 15:25:15 +0100349 * \param raw_len Length of raw_buf in bytes. This must be > 0.
Valerio Setti84890c92024-01-09 14:20:23 +0100350 * \param der_buf_start Pointer to the beginning of the buffer which
351 * will be filled with the DER converted data.
352 * \param der_buf_end End of the buffer used to store the DER output.
353 *
354 * \return On success, the amount of data (in bytes) written to
355 * the DER buffer.
356 * \return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL if the provided der
357 * buffer is too small to contain all the converted data.
358 * \return MBEDTLS_ERR_ASN1_INVALID_DATA if the input raw
359 * coordinate is null (i.e. all zeros).
360 *
361 * \warning Raw and der buffer must not be overlapping.
Valerio Setti75501f52024-01-08 16:49:17 +0100362 */
363static int convert_raw_to_der_single_int(const unsigned char *raw_buf, size_t raw_len,
364 unsigned char *der_buf_start,
365 unsigned char *der_buf_end)
366{
367 unsigned char *p = der_buf_end;
Valerio Setti954ef4b2024-02-05 12:06:46 +0100368 int len;
Valerio Setti75501f52024-01-08 16:49:17 +0100369 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
370
Valerio Setti954ef4b2024-02-05 12:06:46 +0100371 /* ASN.1 DER encoding requires minimal length, so skip leading 0s.
372 * Provided input MPIs should not be 0, but as a failsafe measure, still
373 * detect that and return error in case. */
374 while (*raw_buf == 0x00) {
375 ++raw_buf;
376 --raw_len;
377 if (raw_len == 0) {
378 return MBEDTLS_ERR_ASN1_INVALID_DATA;
379 }
380 }
381 len = (int) raw_len;
382
Valerio Setti75501f52024-01-08 16:49:17 +0100383 /* Copy the raw coordinate to the end of der_buf. */
384 if ((p - der_buf_start) < len) {
385 return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
386 }
387 p -= len;
388 memcpy(p, raw_buf, len);
389
Valerio Setti75501f52024-01-08 16:49:17 +0100390 /* If MSb is 1, ASN.1 requires that we prepend a 0. */
391 if (*p & 0x80) {
392 if ((p - der_buf_start) < 1) {
393 return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
394 }
395 --p;
396 *p = 0x00;
397 ++len;
398 }
399
400 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, der_buf_start, len));
401 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, der_buf_start, MBEDTLS_ASN1_INTEGER));
402
403 return len;
404}
405
Valerio Setti315e4af2024-02-05 10:09:15 +0100406int mbedtls_ecdsa_raw_to_der(size_t bits, const unsigned char *raw, size_t raw_len,
407 unsigned char *der, size_t der_size, size_t *der_len)
Valerio Setti75501f52024-01-08 16:49:17 +0100408{
409 unsigned char r[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
410 unsigned char s[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
411 const size_t coordinate_len = PSA_BITS_TO_BYTES(bits);
412 size_t len = 0;
413 unsigned char *p = der + der_size;
414 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
415
Valerio Setti8334d002024-02-05 15:35:26 +0100416 if ((raw_len < 2 * coordinate_len) || (raw_len > 2 * coordinate_len)) {
Valerio Setti75501f52024-01-08 16:49:17 +0100417 return MBEDTLS_ERR_ASN1_INVALID_DATA;
418 }
419
420 /* Since raw and der buffers might overlap, dump r and s before starting
421 * the conversion. */
Valerio Setti75501f52024-01-08 16:49:17 +0100422 memcpy(r, raw, coordinate_len);
Valerio Setti75501f52024-01-08 16:49:17 +0100423 memcpy(s, raw + coordinate_len, coordinate_len);
424
425 /* der buffer will initially be written starting from its end so we pick s
426 * first and then r. */
427 ret = convert_raw_to_der_single_int(s, coordinate_len, der, p);
428 if (ret < 0) {
429 return ret;
430 }
431 p -= ret;
432 len += ret;
433
434 ret = convert_raw_to_der_single_int(r, coordinate_len, der, p);
435 if (ret < 0) {
436 return ret;
437 }
438 p -= ret;
439 len += ret;
440
441 /* Add ASN.1 header (len + tag). */
442 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, der, len));
443 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, der,
444 MBEDTLS_ASN1_CONSTRUCTED |
445 MBEDTLS_ASN1_SEQUENCE));
446
447 /* memmove the content of der buffer to its beginnig. */
448 memmove(der, p, len);
449 *der_len = len;
450
451 return 0;
452}
Valerio Setti75501f52024-01-08 16:49:17 +0100453
Valerio Setti84890c92024-01-09 14:20:23 +0100454/**
455 * \brief Convert a single integer from ASN.1 DER format to raw.
456 *
457 * \param der Buffer containing the DER integer value to be
458 * converted.
459 * \param der_len Length of the der buffer in bytes.
460 * \param raw Output buffer that will be filled with the
461 * converted data. This should be at least
Valerio Setti78da7462024-01-30 15:08:40 +0100462 * coordinate_size bytes and it must be zeroed before
463 * calling this function.
Valerio Setti84890c92024-01-09 14:20:23 +0100464 * \param coordinate_size Size (in bytes) of a single coordinate in raw
465 * format.
466 *
467 * \return On success, the amount of DER data parsed from the
468 * provided der buffer.
469 * \return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the integer tag
470 * is missing in the der buffer.
471 * \return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the integer
472 * is null (i.e. all zeros) or if the output raw buffer
473 * is too small to contain the converted raw value.
474 *
475 * \warning Der and raw buffers must not be overlapping.
Valerio Setti75501f52024-01-08 16:49:17 +0100476 */
477static int convert_der_to_raw_single_int(unsigned char *der, size_t der_len,
Valerio Setti122c94f2024-01-29 18:02:03 +0100478 unsigned char *raw, size_t coordinate_size)
Valerio Setti75501f52024-01-08 16:49:17 +0100479{
480 unsigned char *p = der;
481 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
482 size_t unpadded_len, padding_len = 0;
483
484 /* Get the length of ASN.1 element (i.e. the integer we need to parse). */
485 ret = mbedtls_asn1_get_tag(&p, p + der_len, &unpadded_len,
486 MBEDTLS_ASN1_INTEGER);
487 if (ret != 0) {
488 return ret;
489 }
490
Valerio Setti86bae522024-01-10 11:12:31 +0100491 /* Skip possible leading zero */
Valerio Setti3122f4d2024-01-31 11:16:46 +0100492 if ((unpadded_len > 0) && (*p == 0x00)) {
Valerio Setti75501f52024-01-08 16:49:17 +0100493 p++;
494 unpadded_len--;
Valerio Setti2d73baf2024-02-01 15:25:17 +0100495 }
496 /* It should never happen that the input number has 0 length. */
497 if (unpadded_len == 0) {
498 return MBEDTLS_ERR_ASN1_INVALID_DATA;
Valerio Setti75501f52024-01-08 16:49:17 +0100499 }
500
Valerio Setti9b9b5a52024-01-29 16:53:03 +0100501 if (unpadded_len > coordinate_size) {
502 /* Parsed number is longer than the maximum expected value. */
503 return MBEDTLS_ERR_ASN1_INVALID_DATA;
Valerio Setti75501f52024-01-08 16:49:17 +0100504 }
Valerio Setti78da7462024-01-30 15:08:40 +0100505 padding_len = coordinate_size - unpadded_len;
506 /* raw buffer was already zeroed by the calling function so zero-padding
507 * operation is skipped here. */
Valerio Setti75501f52024-01-08 16:49:17 +0100508 memcpy(raw + padding_len, p, unpadded_len);
509 p += unpadded_len;
510
511 return (int) (p - der);
512}
513
Valerio Setti315e4af2024-02-05 10:09:15 +0100514int mbedtls_ecdsa_der_to_raw(size_t bits, const unsigned char *der, size_t der_len,
515 unsigned char *raw, size_t raw_size, size_t *raw_len)
Valerio Setti75501f52024-01-08 16:49:17 +0100516{
517 unsigned char raw_tmp[PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE];
518 unsigned char *p = (unsigned char *) der;
519 size_t data_len;
520 size_t coordinate_size = PSA_BITS_TO_BYTES(bits);
521 int ret;
522
523 /* The output raw buffer should be at least twice the size of a raw
524 * coordinate in order to store r and s. */
525 if (raw_size < coordinate_size * 2) {
526 return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
527 }
528
529 /* Check that the provided input DER buffer has the right header. */
530 ret = mbedtls_asn1_get_tag(&p, der + der_len, &data_len,
531 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
532 if (ret != 0) {
533 return ret;
534 }
535
536 memset(raw_tmp, 0, sizeof(raw_tmp));
537
538 /* Extract r */
Valerio Setti122c94f2024-01-29 18:02:03 +0100539 ret = convert_der_to_raw_single_int(p, data_len, raw_tmp, coordinate_size);
Valerio Setti75501f52024-01-08 16:49:17 +0100540 if (ret < 0) {
541 return ret;
542 }
543 p += ret;
544 data_len -= ret;
545
546 /* Extract s */
547 ret = convert_der_to_raw_single_int(p, data_len, raw_tmp + coordinate_size,
Valerio Setti75501f52024-01-08 16:49:17 +0100548 coordinate_size);
549 if (ret < 0) {
550 return ret;
551 }
552 p += ret;
553 data_len -= ret;
554
555 /* Check that we consumed all the input der data. */
Valerio Setti5713c8a2024-01-09 15:48:37 +0100556 if ((size_t) (p - der) != der_len) {
Valerio Setti75501f52024-01-08 16:49:17 +0100557 return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
558 }
559
560 memcpy(raw, raw_tmp, 2 * coordinate_size);
561 *raw_len = 2 * coordinate_size;
562
563 return 0;
564}
Valerio Settif4d2dc22024-01-16 10:57:48 +0100565
566#endif /* MBEDTLS_PSA_UTIL_HAVE_ECDSA */