]> git.sur5r.net Git - freertos/blob - FreeRTOS-Labs/Source/mbedtls/library/pk_wrap.c
Add the Labs projects provided in the V10.2.1_191129 zip file.
[freertos] / FreeRTOS-Labs / Source / mbedtls / library / pk_wrap.c
1 /*\r
2  *  Public Key abstraction layer: wrapper functions\r
3  *\r
4  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved\r
5  *  SPDX-License-Identifier: Apache-2.0\r
6  *\r
7  *  Licensed under the Apache License, Version 2.0 (the "License"); you may\r
8  *  not use this file except in compliance with the License.\r
9  *  You may obtain a copy of the License at\r
10  *\r
11  *  http://www.apache.org/licenses/LICENSE-2.0\r
12  *\r
13  *  Unless required by applicable law or agreed to in writing, software\r
14  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
15  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16  *  See the License for the specific language governing permissions and\r
17  *  limitations under the License.\r
18  *\r
19  *  This file is part of mbed TLS (https://tls.mbed.org)\r
20  */\r
21 \r
22 #if !defined(MBEDTLS_CONFIG_FILE)\r
23 #include "mbedtls/config.h"\r
24 #else\r
25 #include MBEDTLS_CONFIG_FILE\r
26 #endif\r
27 \r
28 #if defined(MBEDTLS_PK_C)\r
29 #include "mbedtls/pk_internal.h"\r
30 \r
31 /* Even if RSA not activated, for the sake of RSA-alt */\r
32 #include "mbedtls/rsa.h"\r
33 \r
34 #include <string.h>\r
35 \r
36 #if defined(MBEDTLS_ECP_C)\r
37 #include "mbedtls/ecp.h"\r
38 #endif\r
39 \r
40 #if defined(MBEDTLS_ECDSA_C)\r
41 #include "mbedtls/ecdsa.h"\r
42 #endif\r
43 \r
44 #if defined(MBEDTLS_USE_PSA_CRYPTO)\r
45 #include "mbedtls/asn1write.h"\r
46 #endif\r
47 \r
48 #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)\r
49 #include "mbedtls/platform_util.h"\r
50 #endif\r
51 \r
52 #if defined(MBEDTLS_USE_PSA_CRYPTO)\r
53 #include "psa/crypto.h"\r
54 #include "mbedtls/psa_util.h"\r
55 #include "mbedtls/asn1.h"\r
56 #endif\r
57 \r
58 #if defined(MBEDTLS_PLATFORM_C)\r
59 #include "mbedtls/platform.h"\r
60 #else\r
61 #include <stdlib.h>\r
62 #define mbedtls_calloc    calloc\r
63 #define mbedtls_free       free\r
64 #endif\r
65 \r
66 #include <limits.h>\r
67 #include <stdint.h>\r
68 \r
69 #if defined(MBEDTLS_RSA_C)\r
70 static int rsa_can_do( mbedtls_pk_type_t type )\r
71 {\r
72     return( type == MBEDTLS_PK_RSA ||\r
73             type == MBEDTLS_PK_RSASSA_PSS );\r
74 }\r
75 \r
76 static size_t rsa_get_bitlen( const void *ctx )\r
77 {\r
78     const mbedtls_rsa_context * rsa = (const mbedtls_rsa_context *) ctx;\r
79     return( 8 * mbedtls_rsa_get_len( rsa ) );\r
80 }\r
81 \r
82 static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,\r
83                    const unsigned char *hash, size_t hash_len,\r
84                    const unsigned char *sig, size_t sig_len )\r
85 {\r
86     int ret;\r
87     mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;\r
88     size_t rsa_len = mbedtls_rsa_get_len( rsa );\r
89 \r
90 #if SIZE_MAX > UINT_MAX\r
91     if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )\r
92         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );\r
93 #endif /* SIZE_MAX > UINT_MAX */\r
94 \r
95     if( sig_len < rsa_len )\r
96         return( MBEDTLS_ERR_RSA_VERIFY_FAILED );\r
97 \r
98     if( ( ret = mbedtls_rsa_pkcs1_verify( rsa, NULL, NULL,\r
99                                   MBEDTLS_RSA_PUBLIC, md_alg,\r
100                                   (unsigned int) hash_len, hash, sig ) ) != 0 )\r
101         return( ret );\r
102 \r
103     /* The buffer contains a valid signature followed by extra data.\r
104      * We have a special error code for that so that so that callers can\r
105      * use mbedtls_pk_verify() to check "Does the buffer start with a\r
106      * valid signature?" and not just "Does the buffer contain a valid\r
107      * signature?". */\r
108     if( sig_len > rsa_len )\r
109         return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );\r
110 \r
111     return( 0 );\r
112 }\r
113 \r
114 static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,\r
115                    const unsigned char *hash, size_t hash_len,\r
116                    unsigned char *sig, size_t *sig_len,\r
117                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )\r
118 {\r
119     mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;\r
120 \r
121 #if SIZE_MAX > UINT_MAX\r
122     if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )\r
123         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );\r
124 #endif /* SIZE_MAX > UINT_MAX */\r
125 \r
126     *sig_len = mbedtls_rsa_get_len( rsa );\r
127 \r
128     return( mbedtls_rsa_pkcs1_sign( rsa, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,\r
129                 md_alg, (unsigned int) hash_len, hash, sig ) );\r
130 }\r
131 \r
132 static int rsa_decrypt_wrap( void *ctx,\r
133                     const unsigned char *input, size_t ilen,\r
134                     unsigned char *output, size_t *olen, size_t osize,\r
135                     int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )\r
136 {\r
137     mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;\r
138 \r
139     if( ilen != mbedtls_rsa_get_len( rsa ) )\r
140         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );\r
141 \r
142     return( mbedtls_rsa_pkcs1_decrypt( rsa, f_rng, p_rng,\r
143                 MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );\r
144 }\r
145 \r
146 static int rsa_encrypt_wrap( void *ctx,\r
147                     const unsigned char *input, size_t ilen,\r
148                     unsigned char *output, size_t *olen, size_t osize,\r
149                     int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )\r
150 {\r
151     mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;\r
152     *olen = mbedtls_rsa_get_len( rsa );\r
153 \r
154     if( *olen > osize )\r
155         return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE );\r
156 \r
157     return( mbedtls_rsa_pkcs1_encrypt( rsa, f_rng, p_rng, MBEDTLS_RSA_PUBLIC,\r
158                                        ilen, input, output ) );\r
159 }\r
160 \r
161 static int rsa_check_pair_wrap( const void *pub, const void *prv )\r
162 {\r
163     return( mbedtls_rsa_check_pub_priv( (const mbedtls_rsa_context *) pub,\r
164                                 (const mbedtls_rsa_context *) prv ) );\r
165 }\r
166 \r
167 static void *rsa_alloc_wrap( void )\r
168 {\r
169     void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_context ) );\r
170 \r
171     if( ctx != NULL )\r
172         mbedtls_rsa_init( (mbedtls_rsa_context *) ctx, 0, 0 );\r
173 \r
174     return( ctx );\r
175 }\r
176 \r
177 static void rsa_free_wrap( void *ctx )\r
178 {\r
179     mbedtls_rsa_free( (mbedtls_rsa_context *) ctx );\r
180     mbedtls_free( ctx );\r
181 }\r
182 \r
183 static void rsa_debug( const void *ctx, mbedtls_pk_debug_item *items )\r
184 {\r
185     items->type = MBEDTLS_PK_DEBUG_MPI;\r
186     items->name = "rsa.N";\r
187     items->value = &( ((mbedtls_rsa_context *) ctx)->N );\r
188 \r
189     items++;\r
190 \r
191     items->type = MBEDTLS_PK_DEBUG_MPI;\r
192     items->name = "rsa.E";\r
193     items->value = &( ((mbedtls_rsa_context *) ctx)->E );\r
194 }\r
195 \r
196 const mbedtls_pk_info_t mbedtls_rsa_info = {\r
197     MBEDTLS_PK_RSA,\r
198     "RSA",\r
199     rsa_get_bitlen,\r
200     rsa_can_do,\r
201     rsa_verify_wrap,\r
202     rsa_sign_wrap,\r
203 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)\r
204     NULL,\r
205     NULL,\r
206 #endif\r
207     rsa_decrypt_wrap,\r
208     rsa_encrypt_wrap,\r
209     rsa_check_pair_wrap,\r
210     rsa_alloc_wrap,\r
211     rsa_free_wrap,\r
212 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)\r
213     NULL,\r
214     NULL,\r
215 #endif\r
216     rsa_debug,\r
217 };\r
218 #endif /* MBEDTLS_RSA_C */\r
219 \r
220 #if defined(MBEDTLS_ECP_C)\r
221 /*\r
222  * Generic EC key\r
223  */\r
224 static int eckey_can_do( mbedtls_pk_type_t type )\r
225 {\r
226     return( type == MBEDTLS_PK_ECKEY ||\r
227             type == MBEDTLS_PK_ECKEY_DH ||\r
228             type == MBEDTLS_PK_ECDSA );\r
229 }\r
230 \r
231 static size_t eckey_get_bitlen( const void *ctx )\r
232 {\r
233     return( ((mbedtls_ecp_keypair *) ctx)->grp.pbits );\r
234 }\r
235 \r
236 #if defined(MBEDTLS_ECDSA_C)\r
237 /* Forward declarations */\r
238 static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,\r
239                        const unsigned char *hash, size_t hash_len,\r
240                        const unsigned char *sig, size_t sig_len );\r
241 \r
242 static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,\r
243                    const unsigned char *hash, size_t hash_len,\r
244                    unsigned char *sig, size_t *sig_len,\r
245                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );\r
246 \r
247 static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,\r
248                        const unsigned char *hash, size_t hash_len,\r
249                        const unsigned char *sig, size_t sig_len )\r
250 {\r
251     int ret;\r
252     mbedtls_ecdsa_context ecdsa;\r
253 \r
254     mbedtls_ecdsa_init( &ecdsa );\r
255 \r
256     if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )\r
257         ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len );\r
258 \r
259     mbedtls_ecdsa_free( &ecdsa );\r
260 \r
261     return( ret );\r
262 }\r
263 \r
264 static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,\r
265                    const unsigned char *hash, size_t hash_len,\r
266                    unsigned char *sig, size_t *sig_len,\r
267                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )\r
268 {\r
269     int ret;\r
270     mbedtls_ecdsa_context ecdsa;\r
271 \r
272     mbedtls_ecdsa_init( &ecdsa );\r
273 \r
274     if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )\r
275         ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len,\r
276                                f_rng, p_rng );\r
277 \r
278     mbedtls_ecdsa_free( &ecdsa );\r
279 \r
280     return( ret );\r
281 }\r
282 \r
283 #if defined(MBEDTLS_ECP_RESTARTABLE)\r
284 /* Forward declarations */\r
285 static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,\r
286                        const unsigned char *hash, size_t hash_len,\r
287                        const unsigned char *sig, size_t sig_len,\r
288                        void *rs_ctx );\r
289 \r
290 static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,\r
291                    const unsigned char *hash, size_t hash_len,\r
292                    unsigned char *sig, size_t *sig_len,\r
293                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,\r
294                    void *rs_ctx );\r
295 \r
296 /*\r
297  * Restart context for ECDSA operations with ECKEY context\r
298  *\r
299  * We need to store an actual ECDSA context, as we need to pass the same to\r
300  * the underlying ecdsa function, so we can't create it on the fly every time.\r
301  */\r
302 typedef struct\r
303 {\r
304     mbedtls_ecdsa_restart_ctx ecdsa_rs;\r
305     mbedtls_ecdsa_context ecdsa_ctx;\r
306 } eckey_restart_ctx;\r
307 \r
308 static void *eckey_rs_alloc( void )\r
309 {\r
310     eckey_restart_ctx *rs_ctx;\r
311 \r
312     void *ctx = mbedtls_calloc( 1, sizeof( eckey_restart_ctx ) );\r
313 \r
314     if( ctx != NULL )\r
315     {\r
316         rs_ctx = ctx;\r
317         mbedtls_ecdsa_restart_init( &rs_ctx->ecdsa_rs );\r
318         mbedtls_ecdsa_init( &rs_ctx->ecdsa_ctx );\r
319     }\r
320 \r
321     return( ctx );\r
322 }\r
323 \r
324 static void eckey_rs_free( void *ctx )\r
325 {\r
326     eckey_restart_ctx *rs_ctx;\r
327 \r
328     if( ctx == NULL)\r
329         return;\r
330 \r
331     rs_ctx = ctx;\r
332     mbedtls_ecdsa_restart_free( &rs_ctx->ecdsa_rs );\r
333     mbedtls_ecdsa_free( &rs_ctx->ecdsa_ctx );\r
334 \r
335     mbedtls_free( ctx );\r
336 }\r
337 \r
338 static int eckey_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,\r
339                        const unsigned char *hash, size_t hash_len,\r
340                        const unsigned char *sig, size_t sig_len,\r
341                        void *rs_ctx )\r
342 {\r
343     int ret;\r
344     eckey_restart_ctx *rs = rs_ctx;\r
345 \r
346     /* Should never happen */\r
347     if( rs == NULL )\r
348         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );\r
349 \r
350     /* set up our own sub-context if needed (that is, on first run) */\r
351     if( rs->ecdsa_ctx.grp.pbits == 0 )\r
352         MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) );\r
353 \r
354     MBEDTLS_MPI_CHK( ecdsa_verify_rs_wrap( &rs->ecdsa_ctx,\r
355                                            md_alg, hash, hash_len,\r
356                                            sig, sig_len, &rs->ecdsa_rs ) );\r
357 \r
358 cleanup:\r
359     return( ret );\r
360 }\r
361 \r
362 static int eckey_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,\r
363                    const unsigned char *hash, size_t hash_len,\r
364                    unsigned char *sig, size_t *sig_len,\r
365                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,\r
366                        void *rs_ctx )\r
367 {\r
368     int ret;\r
369     eckey_restart_ctx *rs = rs_ctx;\r
370 \r
371     /* Should never happen */\r
372     if( rs == NULL )\r
373         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );\r
374 \r
375     /* set up our own sub-context if needed (that is, on first run) */\r
376     if( rs->ecdsa_ctx.grp.pbits == 0 )\r
377         MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) );\r
378 \r
379     MBEDTLS_MPI_CHK( ecdsa_sign_rs_wrap( &rs->ecdsa_ctx, md_alg,\r
380                                          hash, hash_len, sig, sig_len,\r
381                                          f_rng, p_rng, &rs->ecdsa_rs ) );\r
382 \r
383 cleanup:\r
384     return( ret );\r
385 }\r
386 #endif /* MBEDTLS_ECP_RESTARTABLE */\r
387 #endif /* MBEDTLS_ECDSA_C */\r
388 \r
389 static int eckey_check_pair( const void *pub, const void *prv )\r
390 {\r
391     return( mbedtls_ecp_check_pub_priv( (const mbedtls_ecp_keypair *) pub,\r
392                                 (const mbedtls_ecp_keypair *) prv ) );\r
393 }\r
394 \r
395 static void *eckey_alloc_wrap( void )\r
396 {\r
397     void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );\r
398 \r
399     if( ctx != NULL )\r
400         mbedtls_ecp_keypair_init( ctx );\r
401 \r
402     return( ctx );\r
403 }\r
404 \r
405 static void eckey_free_wrap( void *ctx )\r
406 {\r
407     mbedtls_ecp_keypair_free( (mbedtls_ecp_keypair *) ctx );\r
408     mbedtls_free( ctx );\r
409 }\r
410 \r
411 static void eckey_debug( const void *ctx, mbedtls_pk_debug_item *items )\r
412 {\r
413     items->type = MBEDTLS_PK_DEBUG_ECP;\r
414     items->name = "eckey.Q";\r
415     items->value = &( ((mbedtls_ecp_keypair *) ctx)->Q );\r
416 }\r
417 \r
418 const mbedtls_pk_info_t mbedtls_eckey_info = {\r
419     MBEDTLS_PK_ECKEY,\r
420     "EC",\r
421     eckey_get_bitlen,\r
422     eckey_can_do,\r
423 #if defined(MBEDTLS_ECDSA_C)\r
424     eckey_verify_wrap,\r
425     eckey_sign_wrap,\r
426 #if defined(MBEDTLS_ECP_RESTARTABLE)\r
427     eckey_verify_rs_wrap,\r
428     eckey_sign_rs_wrap,\r
429 #endif\r
430 #else /* MBEDTLS_ECDSA_C */\r
431     NULL,\r
432     NULL,\r
433 #endif /* MBEDTLS_ECDSA_C */\r
434     NULL,\r
435     NULL,\r
436     eckey_check_pair,\r
437     eckey_alloc_wrap,\r
438     eckey_free_wrap,\r
439 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)\r
440     eckey_rs_alloc,\r
441     eckey_rs_free,\r
442 #endif\r
443     eckey_debug,\r
444 };\r
445 \r
446 /*\r
447  * EC key restricted to ECDH\r
448  */\r
449 static int eckeydh_can_do( mbedtls_pk_type_t type )\r
450 {\r
451     return( type == MBEDTLS_PK_ECKEY ||\r
452             type == MBEDTLS_PK_ECKEY_DH );\r
453 }\r
454 \r
455 const mbedtls_pk_info_t mbedtls_eckeydh_info = {\r
456     MBEDTLS_PK_ECKEY_DH,\r
457     "EC_DH",\r
458     eckey_get_bitlen,         /* Same underlying key structure */\r
459     eckeydh_can_do,\r
460     NULL,\r
461     NULL,\r
462 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)\r
463     NULL,\r
464     NULL,\r
465 #endif\r
466     NULL,\r
467     NULL,\r
468     eckey_check_pair,\r
469     eckey_alloc_wrap,       /* Same underlying key structure */\r
470     eckey_free_wrap,        /* Same underlying key structure */\r
471 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)\r
472     NULL,\r
473     NULL,\r
474 #endif\r
475     eckey_debug,            /* Same underlying key structure */\r
476 };\r
477 #endif /* MBEDTLS_ECP_C */\r
478 \r
479 #if defined(MBEDTLS_ECDSA_C)\r
480 static int ecdsa_can_do( mbedtls_pk_type_t type )\r
481 {\r
482     return( type == MBEDTLS_PK_ECDSA );\r
483 }\r
484 \r
485 #if defined(MBEDTLS_USE_PSA_CRYPTO)\r
486 /*\r
487  * An ASN.1 encoded signature is a sequence of two ASN.1 integers. Parse one of\r
488  * those integers and convert it to the fixed-length encoding expected by PSA.\r
489  */\r
490 static int extract_ecdsa_sig_int( unsigned char **from, const unsigned char *end,\r
491                                   unsigned char *to, size_t to_len )\r
492 {\r
493     int ret;\r
494     size_t unpadded_len, padding_len;\r
495 \r
496     if( ( ret = mbedtls_asn1_get_tag( from, end, &unpadded_len,\r
497                                       MBEDTLS_ASN1_INTEGER ) ) != 0 )\r
498     {\r
499         return( ret );\r
500     }\r
501 \r
502     while( unpadded_len > 0 && **from == 0x00 )\r
503     {\r
504         ( *from )++;\r
505         unpadded_len--;\r
506     }\r
507 \r
508     if( unpadded_len > to_len || unpadded_len == 0 )\r
509         return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );\r
510 \r
511     padding_len = to_len - unpadded_len;\r
512     memset( to, 0x00, padding_len );\r
513     memcpy( to + padding_len, *from, unpadded_len );\r
514     ( *from ) += unpadded_len;\r
515 \r
516     return( 0 );\r
517 }\r
518 \r
519 /*\r
520  * Convert a signature from an ASN.1 sequence of two integers\r
521  * to a raw {r,s} buffer. Note: the provided sig buffer must be at least\r
522  * twice as big as int_size.\r
523  */\r
524 static int extract_ecdsa_sig( unsigned char **p, const unsigned char *end,\r
525                               unsigned char *sig, size_t int_size )\r
526 {\r
527     int ret;\r
528     size_t tmp_size;\r
529 \r
530     if( ( ret = mbedtls_asn1_get_tag( p, end, &tmp_size,\r
531                 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )\r
532         return( ret );\r
533 \r
534     /* Extract r */\r
535     if( ( ret = extract_ecdsa_sig_int( p, end, sig, int_size ) ) != 0 )\r
536         return( ret );\r
537     /* Extract s */\r
538     if( ( ret = extract_ecdsa_sig_int( p, end, sig + int_size, int_size ) ) != 0 )\r
539         return( ret );\r
540 \r
541     return( 0 );\r
542 }\r
543 \r
544 static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,\r
545                        const unsigned char *hash, size_t hash_len,\r
546                        const unsigned char *sig, size_t sig_len )\r
547 {\r
548     int ret;\r
549     psa_key_handle_t key_slot;\r
550     psa_key_policy_t policy;\r
551     psa_key_type_t psa_type;\r
552     mbedtls_pk_context key;\r
553     int key_len;\r
554     /* see ECP_PUB_DER_MAX_BYTES in pkwrite.c */\r
555     unsigned char buf[30 + 2 * MBEDTLS_ECP_MAX_BYTES];\r
556     unsigned char *p;\r
557     mbedtls_pk_info_t pk_info = mbedtls_eckey_info;\r
558     psa_algorithm_t psa_sig_md, psa_md;\r
559     psa_ecc_curve_t curve = mbedtls_psa_translate_ecc_group(\r
560                             ( (mbedtls_ecdsa_context *) ctx )->grp.id );\r
561     const size_t signature_part_size = ( ( (mbedtls_ecdsa_context *) ctx )->grp.nbits + 7 ) / 8;\r
562 \r
563     if( curve == 0 )\r
564         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );\r
565 \r
566     /* mbedtls_pk_write_pubkey() expects a full PK context;\r
567      * re-construct one to make it happy */\r
568     key.pk_info = &pk_info;\r
569     key.pk_ctx = ctx;\r
570     p = buf + sizeof( buf );\r
571     key_len = mbedtls_pk_write_pubkey( &p, buf, &key );\r
572     if( key_len <= 0 )\r
573         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );\r
574 \r
575     psa_md = mbedtls_psa_translate_md( md_alg );\r
576     if( psa_md == 0 )\r
577         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );\r
578     psa_sig_md = PSA_ALG_ECDSA( psa_md );\r
579     psa_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY( curve );\r
580 \r
581     if( ( ret = psa_allocate_key( &key_slot ) ) != PSA_SUCCESS )\r
582           return( mbedtls_psa_err_translate_pk( ret ) );\r
583 \r
584     policy = psa_key_policy_init();\r
585     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, psa_sig_md );\r
586     if( ( ret = psa_set_key_policy( key_slot, &policy ) ) != PSA_SUCCESS )\r
587     {\r
588         ret = mbedtls_psa_err_translate_pk( ret );\r
589         goto cleanup;\r
590     }\r
591 \r
592     if( psa_import_key( key_slot, psa_type, buf + sizeof( buf ) - key_len, key_len )\r
593          != PSA_SUCCESS )\r
594     {\r
595         ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;\r
596         goto cleanup;\r
597     }\r
598 \r
599     /* We don't need the exported key anymore and can\r
600      * reuse its buffer for signature extraction. */\r
601     if( 2 * signature_part_size > sizeof( buf ) )\r
602     {\r
603         ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;\r
604         goto cleanup;\r
605     }\r
606 \r
607     p = (unsigned char*) sig;\r
608     if( ( ret = extract_ecdsa_sig( &p, sig + sig_len, buf,\r
609                                    signature_part_size ) ) != 0 )\r
610     {\r
611         goto cleanup;\r
612     }\r
613 \r
614     if( psa_asymmetric_verify( key_slot, psa_sig_md,\r
615                                hash, hash_len,\r
616                                buf, 2 * signature_part_size )\r
617          != PSA_SUCCESS )\r
618     {\r
619          ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;\r
620          goto cleanup;\r
621     }\r
622 \r
623     if( p != sig + sig_len )\r
624     {\r
625         ret = MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;\r
626         goto cleanup;\r
627     }\r
628     ret = 0;\r
629 \r
630 cleanup:\r
631     psa_destroy_key( key_slot );\r
632     return( ret );\r
633 }\r
634 #else /* MBEDTLS_USE_PSA_CRYPTO */\r
635 static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,\r
636                        const unsigned char *hash, size_t hash_len,\r
637                        const unsigned char *sig, size_t sig_len )\r
638 {\r
639     int ret;\r
640     ((void) md_alg);\r
641 \r
642     ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx,\r
643                                 hash, hash_len, sig, sig_len );\r
644 \r
645     if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )\r
646         return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );\r
647 \r
648     return( ret );\r
649 }\r
650 #endif /* MBEDTLS_USE_PSA_CRYPTO */\r
651 \r
652 static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,\r
653                    const unsigned char *hash, size_t hash_len,\r
654                    unsigned char *sig, size_t *sig_len,\r
655                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )\r
656 {\r
657     return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx,\r
658                 md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) );\r
659 }\r
660 \r
661 #if defined(MBEDTLS_ECP_RESTARTABLE)\r
662 static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,\r
663                        const unsigned char *hash, size_t hash_len,\r
664                        const unsigned char *sig, size_t sig_len,\r
665                        void *rs_ctx )\r
666 {\r
667     int ret;\r
668     ((void) md_alg);\r
669 \r
670     ret = mbedtls_ecdsa_read_signature_restartable(\r
671             (mbedtls_ecdsa_context *) ctx,\r
672             hash, hash_len, sig, sig_len,\r
673             (mbedtls_ecdsa_restart_ctx *) rs_ctx );\r
674 \r
675     if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )\r
676         return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );\r
677 \r
678     return( ret );\r
679 }\r
680 \r
681 static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,\r
682                    const unsigned char *hash, size_t hash_len,\r
683                    unsigned char *sig, size_t *sig_len,\r
684                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,\r
685                    void *rs_ctx )\r
686 {\r
687     return( mbedtls_ecdsa_write_signature_restartable(\r
688                 (mbedtls_ecdsa_context *) ctx,\r
689                 md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng,\r
690                 (mbedtls_ecdsa_restart_ctx *) rs_ctx ) );\r
691 \r
692 }\r
693 #endif /* MBEDTLS_ECP_RESTARTABLE */\r
694 \r
695 static void *ecdsa_alloc_wrap( void )\r
696 {\r
697     void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) );\r
698 \r
699     if( ctx != NULL )\r
700         mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx );\r
701 \r
702     return( ctx );\r
703 }\r
704 \r
705 static void ecdsa_free_wrap( void *ctx )\r
706 {\r
707     mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx );\r
708     mbedtls_free( ctx );\r
709 }\r
710 \r
711 #if defined(MBEDTLS_ECP_RESTARTABLE)\r
712 static void *ecdsa_rs_alloc( void )\r
713 {\r
714     void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_restart_ctx ) );\r
715 \r
716     if( ctx != NULL )\r
717         mbedtls_ecdsa_restart_init( ctx );\r
718 \r
719     return( ctx );\r
720 }\r
721 \r
722 static void ecdsa_rs_free( void *ctx )\r
723 {\r
724     mbedtls_ecdsa_restart_free( ctx );\r
725     mbedtls_free( ctx );\r
726 }\r
727 #endif /* MBEDTLS_ECP_RESTARTABLE */\r
728 \r
729 const mbedtls_pk_info_t mbedtls_ecdsa_info = {\r
730     MBEDTLS_PK_ECDSA,\r
731     "ECDSA",\r
732     eckey_get_bitlen,     /* Compatible key structures */\r
733     ecdsa_can_do,\r
734     ecdsa_verify_wrap,\r
735     ecdsa_sign_wrap,\r
736 #if defined(MBEDTLS_ECP_RESTARTABLE)\r
737     ecdsa_verify_rs_wrap,\r
738     ecdsa_sign_rs_wrap,\r
739 #endif\r
740     NULL,\r
741     NULL,\r
742     eckey_check_pair,   /* Compatible key structures */\r
743     ecdsa_alloc_wrap,\r
744     ecdsa_free_wrap,\r
745 #if defined(MBEDTLS_ECP_RESTARTABLE)\r
746     ecdsa_rs_alloc,\r
747     ecdsa_rs_free,\r
748 #endif\r
749     eckey_debug,        /* Compatible key structures */\r
750 };\r
751 #endif /* MBEDTLS_ECDSA_C */\r
752 \r
753 #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)\r
754 /*\r
755  * Support for alternative RSA-private implementations\r
756  */\r
757 \r
758 static int rsa_alt_can_do( mbedtls_pk_type_t type )\r
759 {\r
760     return( type == MBEDTLS_PK_RSA );\r
761 }\r
762 \r
763 static size_t rsa_alt_get_bitlen( const void *ctx )\r
764 {\r
765     const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx;\r
766 \r
767     return( 8 * rsa_alt->key_len_func( rsa_alt->key ) );\r
768 }\r
769 \r
770 static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,\r
771                    const unsigned char *hash, size_t hash_len,\r
772                    unsigned char *sig, size_t *sig_len,\r
773                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )\r
774 {\r
775     mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;\r
776 \r
777 #if SIZE_MAX > UINT_MAX\r
778     if( UINT_MAX < hash_len )\r
779         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );\r
780 #endif /* SIZE_MAX > UINT_MAX */\r
781 \r
782     *sig_len = rsa_alt->key_len_func( rsa_alt->key );\r
783 \r
784     return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,\r
785                 md_alg, (unsigned int) hash_len, hash, sig ) );\r
786 }\r
787 \r
788 static int rsa_alt_decrypt_wrap( void *ctx,\r
789                     const unsigned char *input, size_t ilen,\r
790                     unsigned char *output, size_t *olen, size_t osize,\r
791                     int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )\r
792 {\r
793     mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;\r
794 \r
795     ((void) f_rng);\r
796     ((void) p_rng);\r
797 \r
798     if( ilen != rsa_alt->key_len_func( rsa_alt->key ) )\r
799         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );\r
800 \r
801     return( rsa_alt->decrypt_func( rsa_alt->key,\r
802                 MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );\r
803 }\r
804 \r
805 #if defined(MBEDTLS_RSA_C)\r
806 static int rsa_alt_check_pair( const void *pub, const void *prv )\r
807 {\r
808     unsigned char sig[MBEDTLS_MPI_MAX_SIZE];\r
809     unsigned char hash[32];\r
810     size_t sig_len = 0;\r
811     int ret;\r
812 \r
813     if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) )\r
814         return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );\r
815 \r
816     memset( hash, 0x2a, sizeof( hash ) );\r
817 \r
818     if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE,\r
819                                    hash, sizeof( hash ),\r
820                                    sig, &sig_len, NULL, NULL ) ) != 0 )\r
821     {\r
822         return( ret );\r
823     }\r
824 \r
825     if( rsa_verify_wrap( (void *) pub, MBEDTLS_MD_NONE,\r
826                          hash, sizeof( hash ), sig, sig_len ) != 0 )\r
827     {\r
828         return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );\r
829     }\r
830 \r
831     return( 0 );\r
832 }\r
833 #endif /* MBEDTLS_RSA_C */\r
834 \r
835 static void *rsa_alt_alloc_wrap( void )\r
836 {\r
837     void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context ) );\r
838 \r
839     if( ctx != NULL )\r
840         memset( ctx, 0, sizeof( mbedtls_rsa_alt_context ) );\r
841 \r
842     return( ctx );\r
843 }\r
844 \r
845 static void rsa_alt_free_wrap( void *ctx )\r
846 {\r
847     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) );\r
848     mbedtls_free( ctx );\r
849 }\r
850 \r
851 const mbedtls_pk_info_t mbedtls_rsa_alt_info = {\r
852     MBEDTLS_PK_RSA_ALT,\r
853     "RSA-alt",\r
854     rsa_alt_get_bitlen,\r
855     rsa_alt_can_do,\r
856     NULL,\r
857     rsa_alt_sign_wrap,\r
858 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)\r
859     NULL,\r
860     NULL,\r
861 #endif\r
862     rsa_alt_decrypt_wrap,\r
863     NULL,\r
864 #if defined(MBEDTLS_RSA_C)\r
865     rsa_alt_check_pair,\r
866 #else\r
867     NULL,\r
868 #endif\r
869     rsa_alt_alloc_wrap,\r
870     rsa_alt_free_wrap,\r
871 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)\r
872     NULL,\r
873     NULL,\r
874 #endif\r
875     NULL,\r
876 };\r
877 \r
878 #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */\r
879 \r
880 #if defined(MBEDTLS_USE_PSA_CRYPTO)\r
881 \r
882 static void *pk_opaque_alloc_wrap( void )\r
883 {\r
884     void *ctx = mbedtls_calloc( 1, sizeof( psa_key_handle_t ) );\r
885 \r
886     /* no _init() function to call, an calloc() already zeroized */\r
887 \r
888     return( ctx );\r
889 }\r
890 \r
891 static void pk_opaque_free_wrap( void *ctx )\r
892 {\r
893     mbedtls_platform_zeroize( ctx, sizeof( psa_key_handle_t ) );\r
894     mbedtls_free( ctx );\r
895 }\r
896 \r
897 static size_t pk_opaque_get_bitlen( const void *ctx )\r
898 {\r
899     const psa_key_handle_t *key = (const psa_key_handle_t *) ctx;\r
900     size_t bits;\r
901 \r
902     if( PSA_SUCCESS != psa_get_key_information( *key, NULL, &bits ) )\r
903         return( 0 );\r
904 \r
905     return( bits );\r
906 }\r
907 \r
908 static int pk_opaque_can_do( mbedtls_pk_type_t type )\r
909 {\r
910     /* For now opaque PSA keys can only wrap ECC keypairs,\r
911      * as checked by setup_psa().\r
912      * Also, ECKEY_DH does not really make sense with the current API. */\r
913     return( type == MBEDTLS_PK_ECKEY ||\r
914             type == MBEDTLS_PK_ECDSA );\r
915 }\r
916 \r
917 /*\r
918  * Simultaneously convert and move raw MPI from the beginning of a buffer\r
919  * to an ASN.1 MPI at the end of the buffer.\r
920  * See also mbedtls_asn1_write_mpi().\r
921  *\r
922  * p: pointer to the end of the output buffer\r
923  * start: start of the output buffer, and also of the mpi to write at the end\r
924  * n_len: length of the mpi to read from start\r
925  */\r
926 static int asn1_write_mpibuf( unsigned char **p, unsigned char *start,\r
927                               size_t n_len )\r
928 {\r
929     int ret;\r
930     size_t len = 0;\r
931 \r
932     if( (size_t)( *p - start ) < n_len )\r
933         return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );\r
934 \r
935     len = n_len;\r
936     *p -= len;\r
937     memmove( *p, start, len );\r
938 \r
939     /* ASN.1 DER encoding requires minimal length, so skip leading 0s.\r
940      * Neither r nor s should be 0, but as a failsafe measure, still detect\r
941      * that rather than overflowing the buffer in case of a PSA error. */\r
942     while( len > 0 && **p == 0x00 )\r
943     {\r
944         ++(*p);\r
945         --len;\r
946     }\r
947 \r
948     /* this is only reached if the signature was invalid */\r
949     if( len == 0 )\r
950         return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );\r
951 \r
952     /* if the msb is 1, ASN.1 requires that we prepend a 0.\r
953      * Neither r nor s can be 0, so we can assume len > 0 at all times. */\r
954     if( **p & 0x80 )\r
955     {\r
956         if( *p - start < 1 )\r
957             return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );\r
958 \r
959         *--(*p) = 0x00;\r
960         len += 1;\r
961     }\r
962 \r
963     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );\r
964     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,\r
965                                                 MBEDTLS_ASN1_INTEGER ) );\r
966 \r
967     return( (int) len );\r
968 }\r
969 \r
970 /* Transcode signature from PSA format to ASN.1 sequence.\r
971  * See ecdsa_signature_to_asn1 in ecdsa.c, but with byte buffers instead of\r
972  * MPIs, and in-place.\r
973  *\r
974  * [in/out] sig: the signature pre- and post-transcoding\r
975  * [in/out] sig_len: signature length pre- and post-transcoding\r
976  * [int] buf_len: the available size the in/out buffer\r
977  */\r
978 static int pk_ecdsa_sig_asn1_from_psa( unsigned char *sig, size_t *sig_len,\r
979                                        size_t buf_len )\r
980 {\r
981     int ret;\r
982     size_t len = 0;\r
983     const size_t rs_len = *sig_len / 2;\r
984     unsigned char *p = sig + buf_len;\r
985 \r
986     MBEDTLS_ASN1_CHK_ADD( len, asn1_write_mpibuf( &p, sig + rs_len, rs_len ) );\r
987     MBEDTLS_ASN1_CHK_ADD( len, asn1_write_mpibuf( &p, sig, rs_len ) );\r
988 \r
989     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &p, sig, len ) );\r
990     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, sig,\r
991                           MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );\r
992 \r
993     memmove( sig, p, len );\r
994     *sig_len = len;\r
995 \r
996     return( 0 );\r
997 }\r
998 \r
999 static int pk_opaque_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,\r
1000                    const unsigned char *hash, size_t hash_len,\r
1001                    unsigned char *sig, size_t *sig_len,\r
1002                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )\r
1003 {\r
1004     const psa_key_handle_t *key = (const psa_key_handle_t *) ctx;\r
1005     psa_algorithm_t alg = PSA_ALG_ECDSA( mbedtls_psa_translate_md( md_alg ) );\r
1006     size_t bits, buf_len;\r
1007     psa_status_t status;\r
1008 \r
1009     /* PSA has its own RNG */\r
1010     (void) f_rng;\r
1011     (void) p_rng;\r
1012 \r
1013     /* PSA needs an output buffer of known size, but our API doesn't provide\r
1014      * that information. Assume that the buffer is large enough for a\r
1015      * maximal-length signature with that key (otherwise the application is\r
1016      * buggy anyway). */\r
1017     status = psa_get_key_information( *key, NULL, &bits );\r
1018     if( status != PSA_SUCCESS )\r
1019         return( mbedtls_psa_err_translate_pk( status ) );\r
1020 \r
1021     buf_len = MBEDTLS_ECDSA_MAX_SIG_LEN( bits );\r
1022 \r
1023     /* make the signature */\r
1024     status = psa_asymmetric_sign( *key, alg, hash, hash_len,\r
1025                                         sig, buf_len, sig_len );\r
1026     if( status != PSA_SUCCESS )\r
1027         return( mbedtls_psa_err_translate_pk( status ) );\r
1028 \r
1029     /* transcode it to ASN.1 sequence */\r
1030     return( pk_ecdsa_sig_asn1_from_psa( sig, sig_len, buf_len ) );\r
1031 }\r
1032 \r
1033 const mbedtls_pk_info_t mbedtls_pk_opaque_info = {\r
1034     MBEDTLS_PK_OPAQUE,\r
1035     "Opaque",\r
1036     pk_opaque_get_bitlen,\r
1037     pk_opaque_can_do,\r
1038     NULL, /* verify - will be done later */\r
1039     pk_opaque_sign_wrap,\r
1040 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)\r
1041     NULL, /* restartable verify - not relevant */\r
1042     NULL, /* restartable sign - not relevant */\r
1043 #endif\r
1044     NULL, /* decrypt - will be done later */\r
1045     NULL, /* encrypt - will be done later */\r
1046     NULL, /* check_pair - could be done later or left NULL */\r
1047     pk_opaque_alloc_wrap,\r
1048     pk_opaque_free_wrap,\r
1049 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)\r
1050     NULL, /* restart alloc - not relevant */\r
1051     NULL, /* restart free - not relevant */\r
1052 #endif\r
1053     NULL, /* debug - could be done later, or even left NULL */\r
1054 };\r
1055 \r
1056 #endif /* MBEDTLS_USE_PSA_CRYPTO */\r
1057 \r
1058 #endif /* MBEDTLS_PK_C */\r