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