Branch data Line data Source code
1 : : /*
2 : : * Public Key abstraction layer
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 "mbedtls/pk.h"
24 : : #include "pk_wrap.h"
25 : :
26 : : #include "mbedtls/platform_util.h"
27 : : #include "mbedtls/error.h"
28 : :
29 : : #if defined(MBEDTLS_RSA_C)
30 : : #include "mbedtls/rsa.h"
31 : : #endif
32 : : #if defined(MBEDTLS_ECP_C)
33 : : #include "mbedtls/ecp.h"
34 : : #endif
35 : : #if defined(MBEDTLS_ECDSA_C)
36 : : #include "mbedtls/ecdsa.h"
37 : : #endif
38 : :
39 : : #if defined(MBEDTLS_USE_PSA_CRYPTO)
40 : : #include "mbedtls/psa_util.h"
41 : : #endif
42 : :
43 : : #include <limits.h>
44 : : #include <stdint.h>
45 : :
46 : : /* Parameter validation macros based on platform_util.h */
47 : : #define PK_VALIDATE_RET( cond ) \
48 : : MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA )
49 : : #define PK_VALIDATE( cond ) \
50 : : MBEDTLS_INTERNAL_VALIDATE( cond )
51 : :
52 : : /*
53 : : * Initialise a mbedtls_pk_context
54 : : */
55 : 4 : void mbedtls_pk_init( mbedtls_pk_context *ctx )
56 : : {
57 : 4 : PK_VALIDATE( ctx != NULL );
58 : :
59 : 4 : ctx->pk_info = NULL;
60 : 4 : ctx->pk_ctx = NULL;
61 : 4 : }
62 : :
63 : : /*
64 : : * Free (the components of) a mbedtls_pk_context
65 : : */
66 : 8 : void mbedtls_pk_free( mbedtls_pk_context *ctx )
67 : : {
68 [ + - ]: 8 : if( ctx == NULL )
69 : : return;
70 : :
71 [ + - ]: 8 : if ( ctx->pk_info != NULL )
72 : 8 : ctx->pk_info->ctx_free_func( ctx->pk_ctx );
73 : :
74 : 8 : mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pk_context ) );
75 : : }
76 : :
77 : : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
78 : : /*
79 : : * Initialize a restart context
80 : : */
81 : : void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx )
82 : : {
83 : : PK_VALIDATE( ctx != NULL );
84 : : ctx->pk_info = NULL;
85 : : ctx->rs_ctx = NULL;
86 : : }
87 : :
88 : : /*
89 : : * Free the components of a restart context
90 : : */
91 : : void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx )
92 : : {
93 : : if( ctx == NULL || ctx->pk_info == NULL ||
94 : : ctx->pk_info->rs_free_func == NULL )
95 : : {
96 : : return;
97 : : }
98 : :
99 : : ctx->pk_info->rs_free_func( ctx->rs_ctx );
100 : :
101 : : ctx->pk_info = NULL;
102 : : ctx->rs_ctx = NULL;
103 : : }
104 : : #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
105 : :
106 : : /*
107 : : * Get pk_info structure from type
108 : : */
109 : 8 : const mbedtls_pk_info_t * mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type )
110 : : {
111 [ - + ]: 8 : switch( pk_type ) {
112 : : #if defined(MBEDTLS_RSA_C)
113 : : case MBEDTLS_PK_RSA:
114 : : return( &mbedtls_rsa_info );
115 : : #endif
116 : : #if defined(MBEDTLS_ECP_C)
117 : : case MBEDTLS_PK_ECKEY:
118 : : return( &mbedtls_eckey_info );
119 : : case MBEDTLS_PK_ECKEY_DH:
120 : : return( &mbedtls_eckeydh_info );
121 : : #endif
122 : : #if defined(MBEDTLS_ECDSA_C)
123 : : case MBEDTLS_PK_ECDSA:
124 : : return( &mbedtls_ecdsa_info );
125 : : #endif
126 : : /* MBEDTLS_PK_RSA_ALT omitted on purpose */
127 : : default:
128 : : return( NULL );
129 : : }
130 : : }
131 : :
132 : : /*
133 : : * Initialise context
134 : : */
135 : 8 : int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info )
136 : : {
137 : 8 : PK_VALIDATE_RET( ctx != NULL );
138 [ + - + - ]: 8 : if( info == NULL || ctx->pk_info != NULL )
139 : : return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
140 : :
141 [ + - ]: 8 : if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
142 : : return( MBEDTLS_ERR_PK_ALLOC_FAILED );
143 : :
144 : 8 : ctx->pk_info = info;
145 : :
146 : 8 : return( 0 );
147 : : }
148 : :
149 : : #if defined(MBEDTLS_USE_PSA_CRYPTO)
150 : : /*
151 : : * Initialise a PSA-wrapping context
152 : : */
153 : : int mbedtls_pk_setup_opaque( mbedtls_pk_context *ctx,
154 : : const psa_key_id_t key )
155 : : {
156 : : const mbedtls_pk_info_t * const info = &mbedtls_pk_opaque_info;
157 : : psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
158 : : psa_key_id_t *pk_ctx;
159 : : psa_key_type_t type;
160 : :
161 : : if( ctx == NULL || ctx->pk_info != NULL )
162 : : return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
163 : :
164 : : if( PSA_SUCCESS != psa_get_key_attributes( key, &attributes ) )
165 : : return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
166 : : type = psa_get_key_type( &attributes );
167 : : psa_reset_key_attributes( &attributes );
168 : :
169 : : /* Current implementation of can_do() relies on this. */
170 : : if( ! PSA_KEY_TYPE_IS_ECC_KEY_PAIR( type ) )
171 : : return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE) ;
172 : :
173 : : if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
174 : : return( MBEDTLS_ERR_PK_ALLOC_FAILED );
175 : :
176 : : ctx->pk_info = info;
177 : :
178 : : pk_ctx = (psa_key_id_t *) ctx->pk_ctx;
179 : : *pk_ctx = key;
180 : :
181 : : return( 0 );
182 : : }
183 : : #endif /* MBEDTLS_USE_PSA_CRYPTO */
184 : :
185 : : #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
186 : : /*
187 : : * Initialize an RSA-alt context
188 : : */
189 : : int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key,
190 : : mbedtls_pk_rsa_alt_decrypt_func decrypt_func,
191 : : mbedtls_pk_rsa_alt_sign_func sign_func,
192 : : mbedtls_pk_rsa_alt_key_len_func key_len_func )
193 : : {
194 : : mbedtls_rsa_alt_context *rsa_alt;
195 : : const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info;
196 : :
197 : : PK_VALIDATE_RET( ctx != NULL );
198 : : if( ctx->pk_info != NULL )
199 : : return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
200 : :
201 : : if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
202 : : return( MBEDTLS_ERR_PK_ALLOC_FAILED );
203 : :
204 : : ctx->pk_info = info;
205 : :
206 : : rsa_alt = (mbedtls_rsa_alt_context *) ctx->pk_ctx;
207 : :
208 : : rsa_alt->key = key;
209 : : rsa_alt->decrypt_func = decrypt_func;
210 : : rsa_alt->sign_func = sign_func;
211 : : rsa_alt->key_len_func = key_len_func;
212 : :
213 : : return( 0 );
214 : : }
215 : : #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
216 : :
217 : : /*
218 : : * Tell if a PK can do the operations of the given type
219 : : */
220 : 0 : int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type )
221 : : {
222 : : /* A context with null pk_info is not set up yet and can't do anything.
223 : : * For backward compatibility, also accept NULL instead of a context
224 : : * pointer. */
225 [ # # # # ]: 0 : if( ctx == NULL || ctx->pk_info == NULL )
226 : : return( 0 );
227 : :
228 : 0 : return( ctx->pk_info->can_do( type ) );
229 : : }
230 : :
231 : : /*
232 : : * Helper for mbedtls_pk_sign and mbedtls_pk_verify
233 : : */
234 : 0 : static inline int pk_hashlen_helper( mbedtls_md_type_t md_alg, size_t *hash_len )
235 : : {
236 : 0 : const mbedtls_md_info_t *md_info;
237 : :
238 [ # # ]: 0 : if( *hash_len != 0 )
239 : : return( 0 );
240 : :
241 [ # # ]: 0 : if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL )
242 : : return( -1 );
243 : :
244 : 0 : *hash_len = mbedtls_md_get_size( md_info );
245 : 0 : return( 0 );
246 : : }
247 : :
248 : : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
249 : : /*
250 : : * Helper to set up a restart context if needed
251 : : */
252 : : static int pk_restart_setup( mbedtls_pk_restart_ctx *ctx,
253 : : const mbedtls_pk_info_t *info )
254 : : {
255 : : /* Don't do anything if already set up or invalid */
256 : : if( ctx == NULL || ctx->pk_info != NULL )
257 : : return( 0 );
258 : :
259 : : /* Should never happen when we're called */
260 : : if( info->rs_alloc_func == NULL || info->rs_free_func == NULL )
261 : : return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
262 : :
263 : : if( ( ctx->rs_ctx = info->rs_alloc_func() ) == NULL )
264 : : return( MBEDTLS_ERR_PK_ALLOC_FAILED );
265 : :
266 : : ctx->pk_info = info;
267 : :
268 : : return( 0 );
269 : : }
270 : : #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
271 : :
272 : : /*
273 : : * Verify a signature (restartable)
274 : : */
275 : 0 : int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx,
276 : : mbedtls_md_type_t md_alg,
277 : : const unsigned char *hash, size_t hash_len,
278 : : const unsigned char *sig, size_t sig_len,
279 : : mbedtls_pk_restart_ctx *rs_ctx )
280 : : {
281 : 0 : PK_VALIDATE_RET( ctx != NULL );
282 : 0 : PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
283 : : hash != NULL );
284 : 0 : PK_VALIDATE_RET( sig != NULL );
285 : :
286 [ # # # # ]: 0 : if( ctx->pk_info == NULL ||
287 : 0 : pk_hashlen_helper( md_alg, &hash_len ) != 0 )
288 : 0 : return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
289 : :
290 : : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
291 : : /* optimization: use non-restartable version if restart disabled */
292 : : if( rs_ctx != NULL &&
293 : : mbedtls_ecp_restart_is_enabled() &&
294 : : ctx->pk_info->verify_rs_func != NULL )
295 : : {
296 : : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
297 : :
298 : : if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
299 : : return( ret );
300 : :
301 : : ret = ctx->pk_info->verify_rs_func( ctx->pk_ctx,
302 : : md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx );
303 : :
304 : : if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
305 : : mbedtls_pk_restart_free( rs_ctx );
306 : :
307 : : return( ret );
308 : : }
309 : : #else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
310 : 0 : (void) rs_ctx;
311 : : #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
312 : :
313 [ # # ]: 0 : if( ctx->pk_info->verify_func == NULL )
314 : : return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
315 : :
316 : 0 : return( ctx->pk_info->verify_func( ctx->pk_ctx, md_alg, hash, hash_len,
317 : : sig, sig_len ) );
318 : : }
319 : :
320 : : /*
321 : : * Verify a signature
322 : : */
323 : 0 : int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
324 : : const unsigned char *hash, size_t hash_len,
325 : : const unsigned char *sig, size_t sig_len )
326 : : {
327 : 0 : return( mbedtls_pk_verify_restartable( ctx, md_alg, hash, hash_len,
328 : : sig, sig_len, NULL ) );
329 : : }
330 : :
331 : : /*
332 : : * Verify a signature with options
333 : : */
334 : 0 : int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
335 : : mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
336 : : const unsigned char *hash, size_t hash_len,
337 : : const unsigned char *sig, size_t sig_len )
338 : : {
339 : 0 : PK_VALIDATE_RET( ctx != NULL );
340 : 0 : PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
341 : : hash != NULL );
342 : 0 : PK_VALIDATE_RET( sig != NULL );
343 : :
344 [ # # ]: 0 : if( ctx->pk_info == NULL )
345 : : return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
346 : :
347 [ # # ]: 0 : if( ! mbedtls_pk_can_do( ctx, type ) )
348 : : return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
349 : :
350 [ # # ]: 0 : if( type == MBEDTLS_PK_RSASSA_PSS )
351 : : {
352 : : #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
353 : : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
354 : : const mbedtls_pk_rsassa_pss_options *pss_opts;
355 : :
356 : : #if SIZE_MAX > UINT_MAX
357 : : if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
358 : : return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
359 : : #endif /* SIZE_MAX > UINT_MAX */
360 : :
361 : : if( options == NULL )
362 : : return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
363 : :
364 : : pss_opts = (const mbedtls_pk_rsassa_pss_options *) options;
365 : :
366 : : if( sig_len < mbedtls_pk_get_len( ctx ) )
367 : : return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
368 : :
369 : : ret = mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_pk_rsa( *ctx ),
370 : : md_alg, (unsigned int) hash_len, hash,
371 : : pss_opts->mgf1_hash_id,
372 : : pss_opts->expected_salt_len,
373 : : sig );
374 : : if( ret != 0 )
375 : : return( ret );
376 : :
377 : : if( sig_len > mbedtls_pk_get_len( ctx ) )
378 : : return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
379 : :
380 : : return( 0 );
381 : : #else
382 : : return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
383 : : #endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */
384 : : }
385 : :
386 : : /* General case: no options */
387 [ # # ]: 0 : if( options != NULL )
388 : : return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
389 : :
390 : 0 : return( mbedtls_pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) );
391 : : }
392 : :
393 : : /*
394 : : * Make a signature (restartable)
395 : : */
396 : 0 : int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx,
397 : : mbedtls_md_type_t md_alg,
398 : : const unsigned char *hash, size_t hash_len,
399 : : unsigned char *sig, size_t sig_size, size_t *sig_len,
400 : : int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
401 : : mbedtls_pk_restart_ctx *rs_ctx )
402 : : {
403 : 0 : PK_VALIDATE_RET( ctx != NULL );
404 : 0 : PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
405 : : hash != NULL );
406 : 0 : PK_VALIDATE_RET( sig != NULL );
407 : :
408 [ # # # # ]: 0 : if( ctx->pk_info == NULL ||
409 : 0 : pk_hashlen_helper( md_alg, &hash_len ) != 0 )
410 : 0 : return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
411 : :
412 : : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
413 : : /* optimization: use non-restartable version if restart disabled */
414 : : if( rs_ctx != NULL &&
415 : : mbedtls_ecp_restart_is_enabled() &&
416 : : ctx->pk_info->sign_rs_func != NULL )
417 : : {
418 : : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
419 : :
420 : : if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
421 : : return( ret );
422 : :
423 : : ret = ctx->pk_info->sign_rs_func( ctx->pk_ctx, md_alg,
424 : : hash, hash_len,
425 : : sig, sig_size, sig_len,
426 : : f_rng, p_rng, rs_ctx->rs_ctx );
427 : :
428 : : if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
429 : : mbedtls_pk_restart_free( rs_ctx );
430 : :
431 : : return( ret );
432 : : }
433 : : #else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
434 : 0 : (void) rs_ctx;
435 : : #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
436 : :
437 [ # # ]: 0 : if( ctx->pk_info->sign_func == NULL )
438 : : return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
439 : :
440 : 0 : return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg,
441 : : hash, hash_len,
442 : : sig, sig_size, sig_len,
443 : : f_rng, p_rng ) );
444 : : }
445 : :
446 : : /*
447 : : * Make a signature
448 : : */
449 : 0 : int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
450 : : const unsigned char *hash, size_t hash_len,
451 : : unsigned char *sig, size_t sig_size, size_t *sig_len,
452 : : int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
453 : : {
454 : 0 : return( mbedtls_pk_sign_restartable( ctx, md_alg, hash, hash_len,
455 : : sig, sig_size, sig_len,
456 : : f_rng, p_rng, NULL ) );
457 : : }
458 : :
459 : : /*
460 : : * Decrypt message
461 : : */
462 : 0 : int mbedtls_pk_decrypt( mbedtls_pk_context *ctx,
463 : : const unsigned char *input, size_t ilen,
464 : : unsigned char *output, size_t *olen, size_t osize,
465 : : int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
466 : : {
467 : 0 : PK_VALIDATE_RET( ctx != NULL );
468 : 0 : PK_VALIDATE_RET( input != NULL || ilen == 0 );
469 : 0 : PK_VALIDATE_RET( output != NULL || osize == 0 );
470 : 0 : PK_VALIDATE_RET( olen != NULL );
471 : :
472 [ # # ]: 0 : if( ctx->pk_info == NULL )
473 : : return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
474 : :
475 [ # # ]: 0 : if( ctx->pk_info->decrypt_func == NULL )
476 : : return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
477 : :
478 : 0 : return( ctx->pk_info->decrypt_func( ctx->pk_ctx, input, ilen,
479 : : output, olen, osize, f_rng, p_rng ) );
480 : : }
481 : :
482 : : /*
483 : : * Encrypt message
484 : : */
485 : 0 : int mbedtls_pk_encrypt( mbedtls_pk_context *ctx,
486 : : const unsigned char *input, size_t ilen,
487 : : unsigned char *output, size_t *olen, size_t osize,
488 : : int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
489 : : {
490 : 0 : PK_VALIDATE_RET( ctx != NULL );
491 : 0 : PK_VALIDATE_RET( input != NULL || ilen == 0 );
492 : 0 : PK_VALIDATE_RET( output != NULL || osize == 0 );
493 : 0 : PK_VALIDATE_RET( olen != NULL );
494 : :
495 [ # # ]: 0 : if( ctx->pk_info == NULL )
496 : : return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
497 : :
498 [ # # ]: 0 : if( ctx->pk_info->encrypt_func == NULL )
499 : : return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
500 : :
501 : 0 : return( ctx->pk_info->encrypt_func( ctx->pk_ctx, input, ilen,
502 : : output, olen, osize, f_rng, p_rng ) );
503 : : }
504 : :
505 : : /*
506 : : * Check public-private key pair
507 : : */
508 : 0 : int mbedtls_pk_check_pair( const mbedtls_pk_context *pub,
509 : : const mbedtls_pk_context *prv,
510 : : int (*f_rng)(void *, unsigned char *, size_t),
511 : : void *p_rng )
512 : : {
513 : 0 : PK_VALIDATE_RET( pub != NULL );
514 : 0 : PK_VALIDATE_RET( prv != NULL );
515 : :
516 [ # # ]: 0 : if( pub->pk_info == NULL ||
517 [ # # ]: 0 : prv->pk_info == NULL )
518 : : {
519 : : return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
520 : : }
521 : :
522 [ # # ]: 0 : if( f_rng == NULL )
523 : : return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
524 : :
525 [ # # ]: 0 : if( prv->pk_info->check_pair_func == NULL )
526 : : return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
527 : :
528 [ # # ]: 0 : if( prv->pk_info->type == MBEDTLS_PK_RSA_ALT )
529 : : {
530 [ # # ]: 0 : if( pub->pk_info->type != MBEDTLS_PK_RSA )
531 : : return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
532 : : }
533 : : else
534 : : {
535 [ # # ]: 0 : if( pub->pk_info != prv->pk_info )
536 : : return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
537 : : }
538 : :
539 : 0 : return( prv->pk_info->check_pair_func( pub->pk_ctx, prv->pk_ctx, f_rng, p_rng ) );
540 : : }
541 : :
542 : : /*
543 : : * Get key size in bits
544 : : */
545 : 0 : size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx )
546 : : {
547 : : /* For backward compatibility, accept NULL or a context that
548 : : * isn't set up yet, and return a fake value that should be safe. */
549 [ # # # # ]: 0 : if( ctx == NULL || ctx->pk_info == NULL )
550 : : return( 0 );
551 : :
552 : 0 : return( ctx->pk_info->get_bitlen( ctx->pk_ctx ) );
553 : : }
554 : :
555 : : /*
556 : : * Export debug information
557 : : */
558 : 0 : int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items )
559 : : {
560 : 0 : PK_VALIDATE_RET( ctx != NULL );
561 [ # # ]: 0 : if( ctx->pk_info == NULL )
562 : : return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
563 : :
564 [ # # ]: 0 : if( ctx->pk_info->debug_func == NULL )
565 : : return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
566 : :
567 : 0 : ctx->pk_info->debug_func( ctx->pk_ctx, items );
568 : 0 : return( 0 );
569 : : }
570 : :
571 : : /*
572 : : * Access the PK type name
573 : : */
574 : 0 : const char *mbedtls_pk_get_name( const mbedtls_pk_context *ctx )
575 : : {
576 [ # # # # ]: 0 : if( ctx == NULL || ctx->pk_info == NULL )
577 : : return( "invalid PK" );
578 : :
579 : 0 : return( ctx->pk_info->name );
580 : : }
581 : :
582 : : /*
583 : : * Access the PK type
584 : : */
585 : 0 : mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx )
586 : : {
587 [ # # # # ]: 0 : if( ctx == NULL || ctx->pk_info == NULL )
588 : : return( MBEDTLS_PK_NONE );
589 : :
590 : 0 : return( ctx->pk_info->type );
591 : : }
592 : :
593 : : #if defined(MBEDTLS_USE_PSA_CRYPTO)
594 : : /*
595 : : * Load the key to a PSA key slot,
596 : : * then turn the PK context into a wrapper for that key slot.
597 : : *
598 : : * Currently only works for EC private keys.
599 : : */
600 : : int mbedtls_pk_wrap_as_opaque( mbedtls_pk_context *pk,
601 : : psa_key_id_t *key,
602 : : psa_algorithm_t hash_alg )
603 : : {
604 : : #if !defined(MBEDTLS_ECP_C)
605 : : ((void) pk);
606 : : ((void) key);
607 : : ((void) hash_alg);
608 : : return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
609 : : #else
610 : : const mbedtls_ecp_keypair *ec;
611 : : unsigned char d[MBEDTLS_ECP_MAX_BYTES];
612 : : size_t d_len;
613 : : psa_ecc_family_t curve_id;
614 : : psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
615 : : psa_key_type_t key_type;
616 : : size_t bits;
617 : : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
618 : :
619 : : /* export the private key material in the format PSA wants */
620 : : if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_ECKEY )
621 : : return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
622 : :
623 : : ec = mbedtls_pk_ec( *pk );
624 : : d_len = ( ec->grp.nbits + 7 ) / 8;
625 : : if( ( ret = mbedtls_mpi_write_binary( &ec->d, d, d_len ) ) != 0 )
626 : : return( ret );
627 : :
628 : : curve_id = mbedtls_ecc_group_to_psa( ec->grp.id, &bits );
629 : : key_type = PSA_KEY_TYPE_ECC_KEY_PAIR( curve_id );
630 : :
631 : : /* prepare the key attributes */
632 : : psa_set_key_type( &attributes, key_type );
633 : : psa_set_key_bits( &attributes, bits );
634 : : psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH );
635 : : psa_set_key_algorithm( &attributes, PSA_ALG_ECDSA(hash_alg) );
636 : :
637 : : /* import private key into PSA */
638 : : if( PSA_SUCCESS != psa_import_key( &attributes, d, d_len, key ) )
639 : : return( MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED );
640 : :
641 : : /* make PK context wrap the key slot */
642 : : mbedtls_pk_free( pk );
643 : : mbedtls_pk_init( pk );
644 : :
645 : : return( mbedtls_pk_setup_opaque( pk, *key ) );
646 : : #endif /* MBEDTLS_ECP_C */
647 : : }
648 : : #endif /* MBEDTLS_USE_PSA_CRYPTO */
649 : : #endif /* MBEDTLS_PK_C */
|