blob: eda6ca87814389c03b3f9ed66eb41cdce3bb9971 [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;
Gilles Peskinefc3d8662024-02-09 19:26:37 +0100167 case PSA_ERROR_NOT_PERMITTED:
168 return MBEDTLS_ERR_PK_TYPE_MISMATCH;
Andrzej Kurek8a045ce2022-12-23 11:00:06 -0500169 case PSA_ERROR_INSUFFICIENT_MEMORY:
170 return MBEDTLS_ERR_PK_ALLOC_FAILED;
171 case PSA_ERROR_BAD_STATE:
172 return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
173 case PSA_ERROR_DATA_CORRUPT:
174 case PSA_ERROR_DATA_INVALID:
175 case PSA_ERROR_STORAGE_FAILURE:
176 return MBEDTLS_ERR_PK_FILE_IO_ERROR;
177 default:
178 return psa_generic_status_to_mbedtls(status);
179 }
180}
Manuel Pégourié-Gonnardabfe6402023-06-20 09:59:13 +0200181#endif /* MBEDTLS_PK_C */
Joakim Anderssonb3491082023-12-11 21:29:19 +0100182
183/****************************************************************/
184/* Key management */
185/****************************************************************/
186
187#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
188psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid,
189 size_t *bits)
190{
191 switch (grpid) {
192#if defined(MBEDTLS_ECP_HAVE_SECP192R1)
193 case MBEDTLS_ECP_DP_SECP192R1:
194 *bits = 192;
195 return PSA_ECC_FAMILY_SECP_R1;
196#endif
197#if defined(MBEDTLS_ECP_HAVE_SECP224R1)
198 case MBEDTLS_ECP_DP_SECP224R1:
199 *bits = 224;
200 return PSA_ECC_FAMILY_SECP_R1;
201#endif
202#if defined(MBEDTLS_ECP_HAVE_SECP256R1)
203 case MBEDTLS_ECP_DP_SECP256R1:
204 *bits = 256;
205 return PSA_ECC_FAMILY_SECP_R1;
206#endif
207#if defined(MBEDTLS_ECP_HAVE_SECP384R1)
208 case MBEDTLS_ECP_DP_SECP384R1:
209 *bits = 384;
210 return PSA_ECC_FAMILY_SECP_R1;
211#endif
212#if defined(MBEDTLS_ECP_HAVE_SECP521R1)
213 case MBEDTLS_ECP_DP_SECP521R1:
214 *bits = 521;
215 return PSA_ECC_FAMILY_SECP_R1;
216#endif
217#if defined(MBEDTLS_ECP_HAVE_BP256R1)
218 case MBEDTLS_ECP_DP_BP256R1:
219 *bits = 256;
220 return PSA_ECC_FAMILY_BRAINPOOL_P_R1;
221#endif
222#if defined(MBEDTLS_ECP_HAVE_BP384R1)
223 case MBEDTLS_ECP_DP_BP384R1:
224 *bits = 384;
225 return PSA_ECC_FAMILY_BRAINPOOL_P_R1;
226#endif
227#if defined(MBEDTLS_ECP_HAVE_BP512R1)
228 case MBEDTLS_ECP_DP_BP512R1:
229 *bits = 512;
230 return PSA_ECC_FAMILY_BRAINPOOL_P_R1;
231#endif
232#if defined(MBEDTLS_ECP_HAVE_CURVE25519)
233 case MBEDTLS_ECP_DP_CURVE25519:
234 *bits = 255;
235 return PSA_ECC_FAMILY_MONTGOMERY;
236#endif
237#if defined(MBEDTLS_ECP_HAVE_SECP192K1)
238 case MBEDTLS_ECP_DP_SECP192K1:
239 *bits = 192;
240 return PSA_ECC_FAMILY_SECP_K1;
241#endif
242#if defined(MBEDTLS_ECP_HAVE_SECP224K1)
Valerio Setti78636272024-01-04 13:17:04 +0100243 /* secp224k1 is not and will not be supported in PSA (#3541). */
Joakim Anderssonb3491082023-12-11 21:29:19 +0100244#endif
245#if defined(MBEDTLS_ECP_HAVE_SECP256K1)
246 case MBEDTLS_ECP_DP_SECP256K1:
247 *bits = 256;
248 return PSA_ECC_FAMILY_SECP_K1;
249#endif
250#if defined(MBEDTLS_ECP_HAVE_CURVE448)
251 case MBEDTLS_ECP_DP_CURVE448:
252 *bits = 448;
253 return PSA_ECC_FAMILY_MONTGOMERY;
254#endif
255 default:
256 *bits = 0;
257 return 0;
258 }
259}
260
Valerio Setti39faa9c2024-01-09 09:11:22 +0100261mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t family,
Valerio Settid36c3132023-12-21 14:03:51 +0100262 size_t bits)
Joakim Anderssonb3491082023-12-11 21:29:19 +0100263{
Valerio Setti39faa9c2024-01-09 09:11:22 +0100264 switch (family) {
Joakim Anderssonb3491082023-12-11 21:29:19 +0100265 case PSA_ECC_FAMILY_SECP_R1:
266 switch (bits) {
267#if defined(PSA_WANT_ECC_SECP_R1_192)
268 case 192:
269 return MBEDTLS_ECP_DP_SECP192R1;
270#endif
271#if defined(PSA_WANT_ECC_SECP_R1_224)
272 case 224:
273 return MBEDTLS_ECP_DP_SECP224R1;
274#endif
275#if defined(PSA_WANT_ECC_SECP_R1_256)
276 case 256:
277 return MBEDTLS_ECP_DP_SECP256R1;
278#endif
279#if defined(PSA_WANT_ECC_SECP_R1_384)
280 case 384:
281 return MBEDTLS_ECP_DP_SECP384R1;
282#endif
283#if defined(PSA_WANT_ECC_SECP_R1_521)
284 case 521:
Valerio Settid36c3132023-12-21 14:03:51 +0100285 return MBEDTLS_ECP_DP_SECP521R1;
Joakim Anderssonb3491082023-12-11 21:29:19 +0100286#endif
287 }
288 break;
289
290 case PSA_ECC_FAMILY_BRAINPOOL_P_R1:
291 switch (bits) {
292#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256)
293 case 256:
294 return MBEDTLS_ECP_DP_BP256R1;
295#endif
296#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384)
297 case 384:
298 return MBEDTLS_ECP_DP_BP384R1;
299#endif
300#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512)
301 case 512:
302 return MBEDTLS_ECP_DP_BP512R1;
303#endif
304 }
305 break;
306
307 case PSA_ECC_FAMILY_MONTGOMERY:
308 switch (bits) {
309#if defined(PSA_WANT_ECC_MONTGOMERY_255)
310 case 255:
Valerio Settid36c3132023-12-21 14:03:51 +0100311 return MBEDTLS_ECP_DP_CURVE25519;
Joakim Anderssonb3491082023-12-11 21:29:19 +0100312#endif
313#if defined(PSA_WANT_ECC_MONTGOMERY_448)
314 case 448:
315 return MBEDTLS_ECP_DP_CURVE448;
316#endif
317 }
318 break;
319
320 case PSA_ECC_FAMILY_SECP_K1:
321 switch (bits) {
322#if defined(PSA_WANT_ECC_SECP_K1_192)
323 case 192:
324 return MBEDTLS_ECP_DP_SECP192K1;
325#endif
326#if defined(PSA_WANT_ECC_SECP_K1_224)
Valerio Setti78636272024-01-04 13:17:04 +0100327 /* secp224k1 is not and will not be supported in PSA (#3541). */
Joakim Anderssonb3491082023-12-11 21:29:19 +0100328#endif
329#if defined(PSA_WANT_ECC_SECP_K1_256)
330 case 256:
331 return MBEDTLS_ECP_DP_SECP256K1;
332#endif
333 }
334 break;
335 }
336
Joakim Anderssonb3491082023-12-11 21:29:19 +0100337 return MBEDTLS_ECP_DP_NONE;
338}
339#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */
340
Valerio Settibb91bcd2024-02-26 08:41:33 +0100341/* Wrapper function allowing the classic API to use the PSA RNG.
342 *
343 * `mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE, ...)` calls
344 * `psa_generate_random(...)`. The state parameter is ignored since the
345 * PSA API doesn't support passing an explicit state.
346 *
347 * In the non-external case, psa_generate_random() calls an
348 * `mbedtls_xxx_drbg_random` function which has exactly the same signature
349 * and semantics as mbedtls_psa_get_random(). As an optimization,
350 * instead of doing this back-and-forth between the PSA API and the
351 * classic API, psa_crypto_random_impl.h defines `mbedtls_psa_get_random`
352 * as a constant function pointer to `mbedtls_xxx_drbg_random`.
353 */
354#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
355int mbedtls_psa_get_random(void *p_rng,
356 unsigned char *output,
357 size_t output_size)
358{
359 /* This function takes a pointer to the RNG state because that's what
360 * classic mbedtls functions using an RNG expect. The PSA RNG manages
361 * its own state internally and doesn't let the caller access that state.
362 * So we just ignore the state parameter, and in practice we'll pass
363 * NULL. */
364 (void) p_rng;
365 psa_status_t status = psa_generate_random(output, output_size);
366 if (status == PSA_SUCCESS) {
367 return 0;
368 } else {
369 return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
370 }
371}
372#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
373
Valerio Settic22e3ce2024-01-10 08:46:59 +0100374#endif /* MBEDTLS_PSA_CRYPTO_C */
375
Valerio Settif4d2dc22024-01-16 10:57:48 +0100376#if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
377
Valerio Setti84890c92024-01-09 14:20:23 +0100378/**
379 * \brief Convert a single raw coordinate to DER ASN.1 format. The output der
380 * buffer is filled backward (i.e. starting from its end).
381 *
382 * \param raw_buf Buffer containing the raw coordinate to be
383 * converted.
Valerio Setti2bd0ecd2024-02-05 15:25:15 +0100384 * \param raw_len Length of raw_buf in bytes. This must be > 0.
Valerio Setti84890c92024-01-09 14:20:23 +0100385 * \param der_buf_start Pointer to the beginning of the buffer which
386 * will be filled with the DER converted data.
387 * \param der_buf_end End of the buffer used to store the DER output.
388 *
389 * \return On success, the amount of data (in bytes) written to
390 * the DER buffer.
391 * \return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL if the provided der
392 * buffer is too small to contain all the converted data.
393 * \return MBEDTLS_ERR_ASN1_INVALID_DATA if the input raw
394 * coordinate is null (i.e. all zeros).
395 *
396 * \warning Raw and der buffer must not be overlapping.
Valerio Setti75501f52024-01-08 16:49:17 +0100397 */
398static int convert_raw_to_der_single_int(const unsigned char *raw_buf, size_t raw_len,
399 unsigned char *der_buf_start,
400 unsigned char *der_buf_end)
401{
402 unsigned char *p = der_buf_end;
Valerio Setti954ef4b2024-02-05 12:06:46 +0100403 int len;
Valerio Setti75501f52024-01-08 16:49:17 +0100404 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
405
Valerio Setti954ef4b2024-02-05 12:06:46 +0100406 /* ASN.1 DER encoding requires minimal length, so skip leading 0s.
407 * Provided input MPIs should not be 0, but as a failsafe measure, still
408 * detect that and return error in case. */
409 while (*raw_buf == 0x00) {
410 ++raw_buf;
411 --raw_len;
412 if (raw_len == 0) {
413 return MBEDTLS_ERR_ASN1_INVALID_DATA;
414 }
415 }
416 len = (int) raw_len;
417
Valerio Setti75501f52024-01-08 16:49:17 +0100418 /* Copy the raw coordinate to the end of der_buf. */
419 if ((p - der_buf_start) < len) {
420 return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
421 }
422 p -= len;
423 memcpy(p, raw_buf, len);
424
Valerio Setti75501f52024-01-08 16:49:17 +0100425 /* If MSb is 1, ASN.1 requires that we prepend a 0. */
426 if (*p & 0x80) {
427 if ((p - der_buf_start) < 1) {
428 return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
429 }
430 --p;
431 *p = 0x00;
432 ++len;
433 }
434
435 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, der_buf_start, len));
436 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, der_buf_start, MBEDTLS_ASN1_INTEGER));
437
438 return len;
439}
440
Valerio Setti315e4af2024-02-05 10:09:15 +0100441int mbedtls_ecdsa_raw_to_der(size_t bits, const unsigned char *raw, size_t raw_len,
442 unsigned char *der, size_t der_size, size_t *der_len)
Valerio Setti75501f52024-01-08 16:49:17 +0100443{
444 unsigned char r[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
445 unsigned char s[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
446 const size_t coordinate_len = PSA_BITS_TO_BYTES(bits);
447 size_t len = 0;
448 unsigned char *p = der + der_size;
449 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
450
Valerio Setticf81f692024-02-06 16:57:12 +0100451 if (raw_len != (2 * coordinate_len)) {
Valerio Setti75501f52024-01-08 16:49:17 +0100452 return MBEDTLS_ERR_ASN1_INVALID_DATA;
453 }
454
455 /* Since raw and der buffers might overlap, dump r and s before starting
456 * the conversion. */
Valerio Setti75501f52024-01-08 16:49:17 +0100457 memcpy(r, raw, coordinate_len);
Valerio Setti75501f52024-01-08 16:49:17 +0100458 memcpy(s, raw + coordinate_len, coordinate_len);
459
460 /* der buffer will initially be written starting from its end so we pick s
461 * first and then r. */
462 ret = convert_raw_to_der_single_int(s, coordinate_len, der, p);
463 if (ret < 0) {
464 return ret;
465 }
466 p -= ret;
467 len += ret;
468
469 ret = convert_raw_to_der_single_int(r, coordinate_len, der, p);
470 if (ret < 0) {
471 return ret;
472 }
473 p -= ret;
474 len += ret;
475
476 /* Add ASN.1 header (len + tag). */
477 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, der, len));
478 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, der,
479 MBEDTLS_ASN1_CONSTRUCTED |
480 MBEDTLS_ASN1_SEQUENCE));
481
482 /* memmove the content of der buffer to its beginnig. */
483 memmove(der, p, len);
484 *der_len = len;
485
486 return 0;
487}
Valerio Setti75501f52024-01-08 16:49:17 +0100488
Valerio Setti84890c92024-01-09 14:20:23 +0100489/**
490 * \brief Convert a single integer from ASN.1 DER format to raw.
491 *
492 * \param der Buffer containing the DER integer value to be
493 * converted.
494 * \param der_len Length of the der buffer in bytes.
495 * \param raw Output buffer that will be filled with the
496 * converted data. This should be at least
Valerio Setti78da7462024-01-30 15:08:40 +0100497 * coordinate_size bytes and it must be zeroed before
498 * calling this function.
Valerio Setti84890c92024-01-09 14:20:23 +0100499 * \param coordinate_size Size (in bytes) of a single coordinate in raw
500 * format.
501 *
502 * \return On success, the amount of DER data parsed from the
503 * provided der buffer.
504 * \return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the integer tag
505 * is missing in the der buffer.
506 * \return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the integer
507 * is null (i.e. all zeros) or if the output raw buffer
508 * is too small to contain the converted raw value.
509 *
510 * \warning Der and raw buffers must not be overlapping.
Valerio Setti75501f52024-01-08 16:49:17 +0100511 */
512static int convert_der_to_raw_single_int(unsigned char *der, size_t der_len,
Valerio Setti122c94f2024-01-29 18:02:03 +0100513 unsigned char *raw, size_t coordinate_size)
Valerio Setti75501f52024-01-08 16:49:17 +0100514{
515 unsigned char *p = der;
516 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
517 size_t unpadded_len, padding_len = 0;
518
519 /* Get the length of ASN.1 element (i.e. the integer we need to parse). */
520 ret = mbedtls_asn1_get_tag(&p, p + der_len, &unpadded_len,
521 MBEDTLS_ASN1_INTEGER);
522 if (ret != 0) {
523 return ret;
524 }
525
Valerio Setti19103902024-02-07 16:16:58 +0100526 /* It's invalid to have:
527 * - unpadded_len == 0.
528 * - MSb set without a leading 0x00 (leading 0x00 is checked below). */
529 if (((unpadded_len == 0) || (*p & 0x80) != 0)) {
Valerio Setti091bdc42024-02-05 16:17:44 +0100530 return MBEDTLS_ERR_ASN1_INVALID_DATA;
531 }
532
Valerio Setti86bae522024-01-10 11:12:31 +0100533 /* Skip possible leading zero */
Valerio Setti19103902024-02-07 16:16:58 +0100534 if (*p == 0x00) {
Valerio Setti75501f52024-01-08 16:49:17 +0100535 p++;
536 unpadded_len--;
Valerio Setti19103902024-02-07 16:16:58 +0100537 /* It is not allowed to have more than 1 leading zero.
538 * Ignore the case in which unpadded_len = 0 because that's a 0 encoded
539 * in ASN.1 format (i.e. 020100). */
540 if ((unpadded_len > 0) && (*p == 0x00)) {
Valerio Setti091bdc42024-02-05 16:17:44 +0100541 return MBEDTLS_ERR_ASN1_INVALID_DATA;
542 }
Valerio Setti2d73baf2024-02-01 15:25:17 +0100543 }
Valerio Setti75501f52024-01-08 16:49:17 +0100544
Valerio Setti9b9b5a52024-01-29 16:53:03 +0100545 if (unpadded_len > coordinate_size) {
546 /* Parsed number is longer than the maximum expected value. */
547 return MBEDTLS_ERR_ASN1_INVALID_DATA;
Valerio Setti75501f52024-01-08 16:49:17 +0100548 }
Valerio Setti78da7462024-01-30 15:08:40 +0100549 padding_len = coordinate_size - unpadded_len;
550 /* raw buffer was already zeroed by the calling function so zero-padding
551 * operation is skipped here. */
Valerio Setti75501f52024-01-08 16:49:17 +0100552 memcpy(raw + padding_len, p, unpadded_len);
553 p += unpadded_len;
554
555 return (int) (p - der);
556}
557
Valerio Setti315e4af2024-02-05 10:09:15 +0100558int mbedtls_ecdsa_der_to_raw(size_t bits, const unsigned char *der, size_t der_len,
559 unsigned char *raw, size_t raw_size, size_t *raw_len)
Valerio Setti75501f52024-01-08 16:49:17 +0100560{
561 unsigned char raw_tmp[PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE];
562 unsigned char *p = (unsigned char *) der;
563 size_t data_len;
564 size_t coordinate_size = PSA_BITS_TO_BYTES(bits);
565 int ret;
566
567 /* The output raw buffer should be at least twice the size of a raw
568 * coordinate in order to store r and s. */
569 if (raw_size < coordinate_size * 2) {
570 return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
571 }
572
573 /* Check that the provided input DER buffer has the right header. */
574 ret = mbedtls_asn1_get_tag(&p, der + der_len, &data_len,
575 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
576 if (ret != 0) {
577 return ret;
578 }
579
Valerio Setti05c256f2024-02-05 16:02:11 +0100580 memset(raw_tmp, 0, 2 * coordinate_size);
Valerio Setti75501f52024-01-08 16:49:17 +0100581
582 /* Extract r */
Valerio Setti122c94f2024-01-29 18:02:03 +0100583 ret = convert_der_to_raw_single_int(p, data_len, raw_tmp, coordinate_size);
Valerio Setti75501f52024-01-08 16:49:17 +0100584 if (ret < 0) {
585 return ret;
586 }
587 p += ret;
588 data_len -= ret;
589
590 /* Extract s */
591 ret = convert_der_to_raw_single_int(p, data_len, raw_tmp + coordinate_size,
Valerio Setti75501f52024-01-08 16:49:17 +0100592 coordinate_size);
593 if (ret < 0) {
594 return ret;
595 }
596 p += ret;
597 data_len -= ret;
598
599 /* Check that we consumed all the input der data. */
Valerio Setti5713c8a2024-01-09 15:48:37 +0100600 if ((size_t) (p - der) != der_len) {
Valerio Setti75501f52024-01-08 16:49:17 +0100601 return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
602 }
603
604 memcpy(raw, raw_tmp, 2 * coordinate_size);
605 *raw_len = 2 * coordinate_size;
606
607 return 0;
608}
Valerio Settif4d2dc22024-01-16 10:57:48 +0100609
610#endif /* MBEDTLS_PSA_UTIL_HAVE_ECDSA */