Branch data Line data Source code
1 : : /*
2 : : * PSA hashing layer on top of Mbed TLS software crypto
3 : : */
4 : : /*
5 : : * Copyright The Mbed TLS Contributors
6 : : * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
7 : : */
8 : :
9 : : #include "common.h"
10 : :
11 : : /* 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 : :
21 : : #if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
22 : :
23 : : #include <psa/crypto.h>
24 : :
25 : : #if defined(MBEDTLS_MD_LIGHT)
26 : : #include <mbedtls/md.h>
27 : : #endif
28 : : #if defined(MBEDTLS_LMS_C)
29 : : #include <mbedtls/lms.h>
30 : : #endif
31 : : #if defined(MBEDTLS_SSL_TLS_C) && \
32 : : (defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3))
33 : : #include <mbedtls/ssl.h>
34 : : #endif
35 : : #if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) || \
36 : : defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
37 : : #include <mbedtls/rsa.h>
38 : : #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
46 : : #if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
47 : : #include <mbedtls/cipher.h>
48 : : #endif
49 : : #include <mbedtls/entropy.h>
50 : :
51 : : /* PSA_SUCCESS is kept at the top of each error table since
52 : : * it's the most common status when everything functions properly. */
53 : : #if defined(MBEDTLS_MD_LIGHT)
54 : : const mbedtls_error_pair_t psa_to_md_errors[] =
55 : : {
56 : : { PSA_SUCCESS, 0 },
57 : : { PSA_ERROR_NOT_SUPPORTED, MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE },
58 : : { PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_MD_BAD_INPUT_DATA },
59 : : { PSA_ERROR_INSUFFICIENT_MEMORY, MBEDTLS_ERR_MD_ALLOC_FAILED }
60 : : };
61 : : #endif
62 : :
63 : : #if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
64 : : const mbedtls_error_pair_t psa_to_cipher_errors[] =
65 : : {
66 : : { PSA_SUCCESS, 0 },
67 : : { PSA_ERROR_NOT_SUPPORTED, MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE },
68 : : { PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA },
69 : : { PSA_ERROR_INSUFFICIENT_MEMORY, MBEDTLS_ERR_CIPHER_ALLOC_FAILED }
70 : : };
71 : : #endif
72 : :
73 : : #if defined(MBEDTLS_LMS_C)
74 : : const mbedtls_error_pair_t psa_to_lms_errors[] =
75 : : {
76 : : { PSA_SUCCESS, 0 },
77 : : { PSA_ERROR_BUFFER_TOO_SMALL, MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL },
78 : : { PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_LMS_BAD_INPUT_DATA }
79 : : };
80 : : #endif
81 : :
82 : : #if defined(MBEDTLS_SSL_TLS_C) && \
83 : : (defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3))
84 : : const mbedtls_error_pair_t psa_to_ssl_errors[] =
85 : : {
86 : : { PSA_SUCCESS, 0 },
87 : : { PSA_ERROR_INSUFFICIENT_MEMORY, MBEDTLS_ERR_SSL_ALLOC_FAILED },
88 : : { PSA_ERROR_NOT_SUPPORTED, MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE },
89 : : { PSA_ERROR_INVALID_SIGNATURE, MBEDTLS_ERR_SSL_INVALID_MAC },
90 : : { PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_SSL_BAD_INPUT_DATA },
91 : : { PSA_ERROR_BAD_STATE, MBEDTLS_ERR_SSL_INTERNAL_ERROR },
92 : : { PSA_ERROR_BUFFER_TOO_SMALL, MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL }
93 : : };
94 : : #endif
95 : :
96 : : #if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) || \
97 : : defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
98 : : const mbedtls_error_pair_t psa_to_pk_rsa_errors[] =
99 : : {
100 : : { PSA_SUCCESS, 0 },
101 : : { PSA_ERROR_NOT_PERMITTED, MBEDTLS_ERR_RSA_BAD_INPUT_DATA },
102 : : { PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_RSA_BAD_INPUT_DATA },
103 : : { PSA_ERROR_INVALID_HANDLE, MBEDTLS_ERR_RSA_BAD_INPUT_DATA },
104 : : { PSA_ERROR_BUFFER_TOO_SMALL, MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE },
105 : : { PSA_ERROR_INSUFFICIENT_ENTROPY, MBEDTLS_ERR_RSA_RNG_FAILED },
106 : : { PSA_ERROR_INVALID_SIGNATURE, MBEDTLS_ERR_RSA_VERIFY_FAILED },
107 : : { PSA_ERROR_INVALID_PADDING, MBEDTLS_ERR_RSA_INVALID_PADDING }
108 : : };
109 : : #endif
110 : :
111 : : #if defined(MBEDTLS_USE_PSA_CRYPTO) && \
112 : : defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
113 : : const mbedtls_error_pair_t psa_to_pk_ecdsa_errors[] =
114 : : {
115 : : { PSA_SUCCESS, 0 },
116 : : { PSA_ERROR_NOT_PERMITTED, MBEDTLS_ERR_ECP_BAD_INPUT_DATA },
117 : : { PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_ECP_BAD_INPUT_DATA },
118 : : { PSA_ERROR_INVALID_HANDLE, MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE },
119 : : { PSA_ERROR_BUFFER_TOO_SMALL, MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL },
120 : : { PSA_ERROR_INSUFFICIENT_ENTROPY, MBEDTLS_ERR_ECP_RANDOM_FAILED },
121 : : { PSA_ERROR_INVALID_SIGNATURE, MBEDTLS_ERR_ECP_VERIFY_FAILED }
122 : : };
123 : : #endif
124 : :
125 : 0 : int psa_generic_status_to_mbedtls(psa_status_t status)
126 : : {
127 [ # # # # : 0 : switch (status) {
# ]
128 : : case PSA_SUCCESS:
129 : : return 0;
130 : 0 : case PSA_ERROR_NOT_SUPPORTED:
131 : 0 : return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
132 : 0 : case PSA_ERROR_CORRUPTION_DETECTED:
133 : 0 : return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
134 : 0 : case PSA_ERROR_COMMUNICATION_FAILURE:
135 : : case PSA_ERROR_HARDWARE_FAILURE:
136 : 0 : return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
137 : 0 : case PSA_ERROR_NOT_PERMITTED:
138 : : default:
139 : 0 : return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
140 : : }
141 : : }
142 : :
143 : 0 : int psa_status_to_mbedtls(psa_status_t status,
144 : : const mbedtls_error_pair_t *local_translations,
145 : : size_t local_errors_num,
146 : : int (*fallback_f)(psa_status_t))
147 : : {
148 [ # # ]: 0 : for (size_t i = 0; i < local_errors_num; i++) {
149 [ # # ]: 0 : if (status == local_translations[i].psa_status) {
150 : 0 : return local_translations[i].mbedtls_error;
151 : : }
152 : : }
153 : 0 : return fallback_f(status);
154 : : }
155 : :
156 : : #if defined(MBEDTLS_PK_C)
157 : 0 : int psa_pk_status_to_mbedtls(psa_status_t status)
158 : : {
159 [ # # # # : 0 : switch (status) {
# # # #
# ]
160 : : case PSA_ERROR_INVALID_HANDLE:
161 : : return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
162 : 0 : case PSA_ERROR_BUFFER_TOO_SMALL:
163 : 0 : return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
164 : 0 : case PSA_ERROR_NOT_SUPPORTED:
165 : 0 : return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
166 : 0 : case PSA_ERROR_INVALID_ARGUMENT:
167 : 0 : return MBEDTLS_ERR_PK_INVALID_ALG;
168 : 0 : case PSA_ERROR_NOT_PERMITTED:
169 : 0 : return MBEDTLS_ERR_PK_TYPE_MISMATCH;
170 : 0 : case PSA_ERROR_INSUFFICIENT_MEMORY:
171 : 0 : return MBEDTLS_ERR_PK_ALLOC_FAILED;
172 : 0 : case PSA_ERROR_BAD_STATE:
173 : 0 : return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
174 : 0 : case PSA_ERROR_DATA_CORRUPT:
175 : : case PSA_ERROR_DATA_INVALID:
176 : : case PSA_ERROR_STORAGE_FAILURE:
177 : 0 : return MBEDTLS_ERR_PK_FILE_IO_ERROR;
178 : 0 : default:
179 : 0 : return psa_generic_status_to_mbedtls(status);
180 : : }
181 : : }
182 : : #endif /* MBEDTLS_PK_C */
183 : :
184 : : /****************************************************************/
185 : : /* Key management */
186 : : /****************************************************************/
187 : :
188 : : #if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
189 : 4 : psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid,
190 : : size_t *bits)
191 : : {
192 [ + - ]: 4 : switch (grpid) {
193 : : #if defined(MBEDTLS_ECP_HAVE_SECP192R1)
194 : : case MBEDTLS_ECP_DP_SECP192R1:
195 : : *bits = 192;
196 : : return PSA_ECC_FAMILY_SECP_R1;
197 : : #endif
198 : : #if defined(MBEDTLS_ECP_HAVE_SECP224R1)
199 : : case MBEDTLS_ECP_DP_SECP224R1:
200 : : *bits = 224;
201 : : return PSA_ECC_FAMILY_SECP_R1;
202 : : #endif
203 : : #if defined(MBEDTLS_ECP_HAVE_SECP256R1)
204 : 4 : case MBEDTLS_ECP_DP_SECP256R1:
205 : 4 : *bits = 256;
206 : 4 : return PSA_ECC_FAMILY_SECP_R1;
207 : : #endif
208 : : #if defined(MBEDTLS_ECP_HAVE_SECP384R1)
209 : : case MBEDTLS_ECP_DP_SECP384R1:
210 : : *bits = 384;
211 : : return PSA_ECC_FAMILY_SECP_R1;
212 : : #endif
213 : : #if defined(MBEDTLS_ECP_HAVE_SECP521R1)
214 : : case MBEDTLS_ECP_DP_SECP521R1:
215 : : *bits = 521;
216 : : return PSA_ECC_FAMILY_SECP_R1;
217 : : #endif
218 : : #if defined(MBEDTLS_ECP_HAVE_BP256R1)
219 : : case MBEDTLS_ECP_DP_BP256R1:
220 : : *bits = 256;
221 : : return PSA_ECC_FAMILY_BRAINPOOL_P_R1;
222 : : #endif
223 : : #if defined(MBEDTLS_ECP_HAVE_BP384R1)
224 : : case MBEDTLS_ECP_DP_BP384R1:
225 : : *bits = 384;
226 : : return PSA_ECC_FAMILY_BRAINPOOL_P_R1;
227 : : #endif
228 : : #if defined(MBEDTLS_ECP_HAVE_BP512R1)
229 : : case MBEDTLS_ECP_DP_BP512R1:
230 : : *bits = 512;
231 : : return PSA_ECC_FAMILY_BRAINPOOL_P_R1;
232 : : #endif
233 : : #if defined(MBEDTLS_ECP_HAVE_CURVE25519)
234 : : case MBEDTLS_ECP_DP_CURVE25519:
235 : : *bits = 255;
236 : : return PSA_ECC_FAMILY_MONTGOMERY;
237 : : #endif
238 : : #if defined(MBEDTLS_ECP_HAVE_SECP192K1)
239 : : case MBEDTLS_ECP_DP_SECP192K1:
240 : : *bits = 192;
241 : : return PSA_ECC_FAMILY_SECP_K1;
242 : : #endif
243 : : #if defined(MBEDTLS_ECP_HAVE_SECP224K1)
244 : : /* secp224k1 is not and will not be supported in PSA (#3541). */
245 : : #endif
246 : : #if defined(MBEDTLS_ECP_HAVE_SECP256K1)
247 : : case MBEDTLS_ECP_DP_SECP256K1:
248 : : *bits = 256;
249 : : return PSA_ECC_FAMILY_SECP_K1;
250 : : #endif
251 : : #if defined(MBEDTLS_ECP_HAVE_CURVE448)
252 : : case MBEDTLS_ECP_DP_CURVE448:
253 : : *bits = 448;
254 : : return PSA_ECC_FAMILY_MONTGOMERY;
255 : : #endif
256 : 0 : default:
257 : 0 : *bits = 0;
258 : 0 : return 0;
259 : : }
260 : : }
261 : :
262 : 32 : mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t family,
263 : : size_t bits)
264 : : {
265 [ + - ]: 32 : switch (family) {
266 : 32 : case PSA_ECC_FAMILY_SECP_R1:
267 [ - + ]: 32 : switch (bits) {
268 : : #if defined(PSA_WANT_ECC_SECP_R1_192)
269 : : case 192:
270 : : return MBEDTLS_ECP_DP_SECP192R1;
271 : : #endif
272 : : #if defined(PSA_WANT_ECC_SECP_R1_224)
273 : : case 224:
274 : : return MBEDTLS_ECP_DP_SECP224R1;
275 : : #endif
276 : : #if defined(PSA_WANT_ECC_SECP_R1_256)
277 : : case 256:
278 : : return MBEDTLS_ECP_DP_SECP256R1;
279 : : #endif
280 : : #if defined(PSA_WANT_ECC_SECP_R1_384)
281 : : case 384:
282 : : return MBEDTLS_ECP_DP_SECP384R1;
283 : : #endif
284 : : #if defined(PSA_WANT_ECC_SECP_R1_521)
285 : : case 521:
286 : : return MBEDTLS_ECP_DP_SECP521R1;
287 : : #endif
288 : : }
289 : : break;
290 : :
291 : : case PSA_ECC_FAMILY_BRAINPOOL_P_R1:
292 : : switch (bits) {
293 : : #if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256)
294 : : case 256:
295 : : return MBEDTLS_ECP_DP_BP256R1;
296 : : #endif
297 : : #if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384)
298 : : case 384:
299 : : return MBEDTLS_ECP_DP_BP384R1;
300 : : #endif
301 : : #if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512)
302 : : case 512:
303 : : return MBEDTLS_ECP_DP_BP512R1;
304 : : #endif
305 : : }
306 : : break;
307 : :
308 : : case PSA_ECC_FAMILY_MONTGOMERY:
309 : : switch (bits) {
310 : : #if defined(PSA_WANT_ECC_MONTGOMERY_255)
311 : : case 255:
312 : : return MBEDTLS_ECP_DP_CURVE25519;
313 : : #endif
314 : : #if defined(PSA_WANT_ECC_MONTGOMERY_448)
315 : : case 448:
316 : : return MBEDTLS_ECP_DP_CURVE448;
317 : : #endif
318 : : }
319 : : break;
320 : :
321 : : case PSA_ECC_FAMILY_SECP_K1:
322 : : switch (bits) {
323 : : #if defined(PSA_WANT_ECC_SECP_K1_192)
324 : : case 192:
325 : : return MBEDTLS_ECP_DP_SECP192K1;
326 : : #endif
327 : : #if defined(PSA_WANT_ECC_SECP_K1_224)
328 : : /* secp224k1 is not and will not be supported in PSA (#3541). */
329 : : #endif
330 : : #if defined(PSA_WANT_ECC_SECP_K1_256)
331 : : case 256:
332 : : return MBEDTLS_ECP_DP_SECP256K1;
333 : : #endif
334 : : }
335 : : break;
336 : : }
337 : :
338 : 0 : return MBEDTLS_ECP_DP_NONE;
339 : : }
340 : : #endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */
341 : :
342 : : /* Wrapper function allowing the classic API to use the PSA RNG.
343 : : *
344 : : * `mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE, ...)` calls
345 : : * `psa_generate_random(...)`. The state parameter is ignored since the
346 : : * PSA API doesn't support passing an explicit state.
347 : : */
348 : 12 : int mbedtls_psa_get_random(void *p_rng,
349 : : unsigned char *output,
350 : : size_t output_size)
351 : : {
352 : : /* This function takes a pointer to the RNG state because that's what
353 : : * classic mbedtls functions using an RNG expect. The PSA RNG manages
354 : : * its own state internally and doesn't let the caller access that state.
355 : : * So we just ignore the state parameter, and in practice we'll pass
356 : : * NULL. */
357 : 12 : (void) p_rng;
358 : 12 : psa_status_t status = psa_generate_random(output, output_size);
359 [ - + ]: 12 : if (status == PSA_SUCCESS) {
360 : : return 0;
361 : : } else {
362 : 0 : return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
363 : : }
364 : : }
365 : :
366 : : #endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
367 : :
368 : : #if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
369 : :
370 : : /**
371 : : * \brief Convert a single raw coordinate to DER ASN.1 format. The output der
372 : : * buffer is filled backward (i.e. starting from its end).
373 : : *
374 : : * \param raw_buf Buffer containing the raw coordinate to be
375 : : * converted.
376 : : * \param raw_len Length of raw_buf in bytes. This must be > 0.
377 : : * \param der_buf_start Pointer to the beginning of the buffer which
378 : : * will be filled with the DER converted data.
379 : : * \param der_buf_end End of the buffer used to store the DER output.
380 : : *
381 : : * \return On success, the amount of data (in bytes) written to
382 : : * the DER buffer.
383 : : * \return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL if the provided der
384 : : * buffer is too small to contain all the converted data.
385 : : * \return MBEDTLS_ERR_ASN1_INVALID_DATA if the input raw
386 : : * coordinate is null (i.e. all zeros).
387 : : *
388 : : * \warning Raw and der buffer must not be overlapping.
389 : : */
390 : 0 : static int convert_raw_to_der_single_int(const unsigned char *raw_buf, size_t raw_len,
391 : : unsigned char *der_buf_start,
392 : : unsigned char *der_buf_end)
393 : : {
394 : 0 : unsigned char *p = der_buf_end;
395 : 0 : int len;
396 : 0 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
397 : :
398 : : /* ASN.1 DER encoding requires minimal length, so skip leading 0s.
399 : : * Provided input MPIs should not be 0, but as a failsafe measure, still
400 : : * detect that and return error in case. */
401 [ # # ]: 0 : while (*raw_buf == 0x00) {
402 : 0 : ++raw_buf;
403 : 0 : --raw_len;
404 [ # # ]: 0 : if (raw_len == 0) {
405 : : return MBEDTLS_ERR_ASN1_INVALID_DATA;
406 : : }
407 : : }
408 : 0 : len = (int) raw_len;
409 : :
410 : : /* Copy the raw coordinate to the end of der_buf. */
411 [ # # ]: 0 : if ((p - der_buf_start) < len) {
412 : : return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
413 : : }
414 : 0 : p -= len;
415 [ # # ]: 0 : memcpy(p, raw_buf, len);
416 : :
417 : : /* If MSb is 1, ASN.1 requires that we prepend a 0. */
418 [ # # ]: 0 : if (*p & 0x80) {
419 [ # # ]: 0 : if ((p - der_buf_start) < 1) {
420 : : return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
421 : : }
422 : 0 : --p;
423 : 0 : *p = 0x00;
424 : 0 : ++len;
425 : : }
426 : :
427 [ # # ]: 0 : MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, der_buf_start, len));
428 [ # # ]: 0 : MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, der_buf_start, MBEDTLS_ASN1_INTEGER));
429 : :
430 : 0 : return len;
431 : : }
432 : :
433 : 0 : int mbedtls_ecdsa_raw_to_der(size_t bits, const unsigned char *raw, size_t raw_len,
434 : : unsigned char *der, size_t der_size, size_t *der_len)
435 : : {
436 : 0 : unsigned char r[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
437 : 0 : unsigned char s[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
438 : 0 : const size_t coordinate_len = PSA_BITS_TO_BYTES(bits);
439 : 0 : size_t len = 0;
440 : 0 : unsigned char *p = der + der_size;
441 : 0 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
442 : :
443 [ # # ]: 0 : if (bits == 0) {
444 : : return MBEDTLS_ERR_ASN1_INVALID_DATA;
445 : : }
446 [ # # ]: 0 : if (raw_len != (2 * coordinate_len)) {
447 : : return MBEDTLS_ERR_ASN1_INVALID_DATA;
448 : : }
449 [ # # ]: 0 : if (coordinate_len > sizeof(r)) {
450 : : return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
451 : : }
452 : :
453 : : /* Since raw and der buffers might overlap, dump r and s before starting
454 : : * the conversion. */
455 : 0 : memcpy(r, raw, coordinate_len);
456 : 0 : memcpy(s, raw + coordinate_len, coordinate_len);
457 : :
458 : : /* der buffer will initially be written starting from its end so we pick s
459 : : * first and then r. */
460 : 0 : ret = convert_raw_to_der_single_int(s, coordinate_len, der, p);
461 [ # # ]: 0 : if (ret < 0) {
462 : : return ret;
463 : : }
464 : 0 : p -= ret;
465 : 0 : len += ret;
466 : :
467 : 0 : ret = convert_raw_to_der_single_int(r, coordinate_len, der, p);
468 [ # # ]: 0 : if (ret < 0) {
469 : : return ret;
470 : : }
471 : 0 : p -= ret;
472 : 0 : len += ret;
473 : :
474 : : /* Add ASN.1 header (len + tag). */
475 [ # # ]: 0 : MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, der, len));
476 [ # # ]: 0 : MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, der,
477 : : MBEDTLS_ASN1_CONSTRUCTED |
478 : : MBEDTLS_ASN1_SEQUENCE));
479 : :
480 : : /* memmove the content of der buffer to its beginnig. */
481 : 0 : memmove(der, p, len);
482 : 0 : *der_len = len;
483 : :
484 : 0 : return 0;
485 : : }
486 : :
487 : : /**
488 : : * \brief Convert a single integer from ASN.1 DER format to raw.
489 : : *
490 : : * \param der Buffer containing the DER integer value to be
491 : : * converted.
492 : : * \param der_len Length of the der buffer in bytes.
493 : : * \param raw Output buffer that will be filled with the
494 : : * converted data. This should be at least
495 : : * coordinate_size bytes and it must be zeroed before
496 : : * calling this function.
497 : : * \param coordinate_size Size (in bytes) of a single coordinate in raw
498 : : * format.
499 : : *
500 : : * \return On success, the amount of DER data parsed from the
501 : : * provided der buffer.
502 : : * \return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the integer tag
503 : : * is missing in the der buffer.
504 : : * \return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the integer
505 : : * is null (i.e. all zeros) or if the output raw buffer
506 : : * is too small to contain the converted raw value.
507 : : *
508 : : * \warning Der and raw buffers must not be overlapping.
509 : : */
510 : 0 : static int convert_der_to_raw_single_int(unsigned char *der, size_t der_len,
511 : : unsigned char *raw, size_t coordinate_size)
512 : : {
513 : 0 : unsigned char *p = der;
514 : 0 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
515 : 0 : size_t unpadded_len, padding_len = 0;
516 : :
517 : : /* Get the length of ASN.1 element (i.e. the integer we need to parse). */
518 : 0 : ret = mbedtls_asn1_get_tag(&p, p + der_len, &unpadded_len,
519 : : MBEDTLS_ASN1_INTEGER);
520 [ # # ]: 0 : if (ret != 0) {
521 : : return ret;
522 : : }
523 : :
524 : : /* It's invalid to have:
525 : : * - unpadded_len == 0.
526 : : * - MSb set without a leading 0x00 (leading 0x00 is checked below). */
527 [ # # # # ]: 0 : if (((unpadded_len == 0) || (*p & 0x80) != 0)) {
528 : : return MBEDTLS_ERR_ASN1_INVALID_DATA;
529 : : }
530 : :
531 : : /* Skip possible leading zero */
532 [ # # ]: 0 : if (*p == 0x00) {
533 : 0 : p++;
534 : 0 : unpadded_len--;
535 : : /* It is not allowed to have more than 1 leading zero.
536 : : * Ignore the case in which unpadded_len = 0 because that's a 0 encoded
537 : : * in ASN.1 format (i.e. 020100). */
538 [ # # # # ]: 0 : if ((unpadded_len > 0) && (*p == 0x00)) {
539 : : return MBEDTLS_ERR_ASN1_INVALID_DATA;
540 : : }
541 : : }
542 : :
543 [ # # ]: 0 : if (unpadded_len > coordinate_size) {
544 : : /* Parsed number is longer than the maximum expected value. */
545 : : return MBEDTLS_ERR_ASN1_INVALID_DATA;
546 : : }
547 : 0 : padding_len = coordinate_size - unpadded_len;
548 : : /* raw buffer was already zeroed by the calling function so zero-padding
549 : : * operation is skipped here. */
550 : 0 : memcpy(raw + padding_len, p, unpadded_len);
551 : 0 : p += unpadded_len;
552 : :
553 : 0 : return (int) (p - der);
554 : : }
555 : :
556 : 0 : int mbedtls_ecdsa_der_to_raw(size_t bits, const unsigned char *der, size_t der_len,
557 : : unsigned char *raw, size_t raw_size, size_t *raw_len)
558 : : {
559 : 0 : unsigned char raw_tmp[PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE];
560 : 0 : unsigned char *p = (unsigned char *) der;
561 : 0 : size_t data_len;
562 : 0 : size_t coordinate_size = PSA_BITS_TO_BYTES(bits);
563 : 0 : int ret;
564 : :
565 [ # # ]: 0 : if (bits == 0) {
566 : : return MBEDTLS_ERR_ASN1_INVALID_DATA;
567 : : }
568 : : /* The output raw buffer should be at least twice the size of a raw
569 : : * coordinate in order to store r and s. */
570 [ # # ]: 0 : if (raw_size < coordinate_size * 2) {
571 : : return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
572 : : }
573 [ # # ]: 0 : if (2 * coordinate_size > sizeof(raw_tmp)) {
574 : : return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
575 : : }
576 : :
577 : : /* Check that the provided input DER buffer has the right header. */
578 : 0 : ret = mbedtls_asn1_get_tag(&p, der + der_len, &data_len,
579 : : MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
580 [ # # ]: 0 : if (ret != 0) {
581 : : return ret;
582 : : }
583 : :
584 : 0 : memset(raw_tmp, 0, 2 * coordinate_size);
585 : :
586 : : /* Extract r */
587 : 0 : ret = convert_der_to_raw_single_int(p, data_len, raw_tmp, coordinate_size);
588 [ # # ]: 0 : if (ret < 0) {
589 : : return ret;
590 : : }
591 : 0 : p += ret;
592 : 0 : data_len -= ret;
593 : :
594 : : /* Extract s */
595 : 0 : ret = convert_der_to_raw_single_int(p, data_len, raw_tmp + coordinate_size,
596 : : coordinate_size);
597 [ # # ]: 0 : if (ret < 0) {
598 : : return ret;
599 : : }
600 : 0 : p += ret;
601 : 0 : data_len -= ret;
602 : :
603 : : /* Check that we consumed all the input der data. */
604 [ # # ]: 0 : if ((size_t) (p - der) != der_len) {
605 : : return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
606 : : }
607 : :
608 : 0 : memcpy(raw, raw_tmp, 2 * coordinate_size);
609 : 0 : *raw_len = 2 * coordinate_size;
610 : :
611 : 0 : return 0;
612 : : }
613 : :
614 : : #endif /* MBEDTLS_PSA_UTIL_HAVE_ECDSA */
|