1 /*
2 * Public Key abstraction layer
3 *
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
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 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22 #if !defined(MBEDTLS_CONFIG_FILE)
23 #include "mbedtls/config.h"
24 #else
25 #include MBEDTLS_CONFIG_FILE
26 #endif
27
28 #if defined(MBEDTLS_PK_C)
29 #include "mbedtls/pk.h"
30 #include "mbedtls/pk_internal.h"
31
32 #include "mbedtls/platform_util.h"
33
34 #if defined(MBEDTLS_RSA_C)
35 #include "mbedtls/rsa.h"
36 #endif
37 #if defined(MBEDTLS_ECP_C)
38 #include "mbedtls/ecp.h"
39 #endif
40 #if defined(MBEDTLS_ECDSA_C)
41 #include "mbedtls/ecdsa.h"
42 #endif
43
44 #include <limits.h>
45 #include <stdint.h>
46
47 /* Parameter validation macros based on platform_util.h */
48 #define PK_VALIDATE_RET( cond ) \
49 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA )
50 #define PK_VALIDATE( cond ) \
51 MBEDTLS_INTERNAL_VALIDATE( cond )
52
53 /*
54 * Initialise a mbedtls_pk_context
55 */
mbedtls_pk_init(mbedtls_pk_context * ctx)56 void mbedtls_pk_init( mbedtls_pk_context *ctx )
57 {
58 PK_VALIDATE( ctx != NULL );
59
60 ctx->pk_info = NULL;
61 ctx->pk_ctx = NULL;
62 }
63
64 /*
65 * Free (the components of) a mbedtls_pk_context
66 */
mbedtls_pk_free(mbedtls_pk_context * ctx)67 void mbedtls_pk_free( mbedtls_pk_context *ctx )
68 {
69 if( ctx == NULL )
70 return;
71
72 if ( ctx->pk_info != NULL )
73 ctx->pk_info->ctx_free_func( ctx->pk_ctx );
74
75 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pk_context ) );
76 }
77
78 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
79 /*
80 * Initialize a restart context
81 */
mbedtls_pk_restart_init(mbedtls_pk_restart_ctx * ctx)82 void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx )
83 {
84 PK_VALIDATE( ctx != NULL );
85 ctx->pk_info = NULL;
86 ctx->rs_ctx = NULL;
87 }
88
89 /*
90 * Free the components of a restart context
91 */
mbedtls_pk_restart_free(mbedtls_pk_restart_ctx * ctx)92 void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx )
93 {
94 if( ctx == NULL || ctx->pk_info == NULL ||
95 ctx->pk_info->rs_free_func == NULL )
96 {
97 return;
98 }
99
100 ctx->pk_info->rs_free_func( ctx->rs_ctx );
101
102 ctx->pk_info = NULL;
103 ctx->rs_ctx = NULL;
104 }
105 #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
106
107 /*
108 * Get pk_info structure from type
109 */
mbedtls_pk_info_from_type(mbedtls_pk_type_t pk_type)110 const mbedtls_pk_info_t * mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type )
111 {
112 switch( pk_type ) {
113 #if defined(MBEDTLS_RSA_C)
114 case MBEDTLS_PK_RSA:
115 return( &mbedtls_rsa_info );
116 #endif
117 #if defined(MBEDTLS_ECP_C)
118 case MBEDTLS_PK_ECKEY:
119 return( &mbedtls_eckey_info );
120 case MBEDTLS_PK_ECKEY_DH:
121 return( &mbedtls_eckeydh_info );
122 #endif
123 #if defined(MBEDTLS_ECDSA_C)
124 case MBEDTLS_PK_ECDSA:
125 return( &mbedtls_ecdsa_info );
126 #endif
127 /* MBEDTLS_PK_RSA_ALT omitted on purpose */
128 default:
129 return( NULL );
130 }
131 }
132
133 /*
134 * Initialise context
135 */
mbedtls_pk_setup(mbedtls_pk_context * ctx,const mbedtls_pk_info_t * info)136 int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info )
137 {
138 PK_VALIDATE_RET( ctx != NULL );
139 if( info == NULL || ctx->pk_info != NULL )
140 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
141
142 if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
143 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
144
145 ctx->pk_info = info;
146
147 return( 0 );
148 }
149
150 #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
151 /*
152 * Initialize an RSA-alt context
153 */
mbedtls_pk_setup_rsa_alt(mbedtls_pk_context * ctx,void * key,mbedtls_pk_rsa_alt_decrypt_func decrypt_func,mbedtls_pk_rsa_alt_sign_func sign_func,mbedtls_pk_rsa_alt_key_len_func key_len_func)154 int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key,
155 mbedtls_pk_rsa_alt_decrypt_func decrypt_func,
156 mbedtls_pk_rsa_alt_sign_func sign_func,
157 mbedtls_pk_rsa_alt_key_len_func key_len_func )
158 {
159 mbedtls_rsa_alt_context *rsa_alt;
160 const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info;
161
162 PK_VALIDATE_RET( ctx != NULL );
163 if( ctx->pk_info != NULL )
164 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
165
166 if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
167 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
168
169 ctx->pk_info = info;
170
171 rsa_alt = (mbedtls_rsa_alt_context *) ctx->pk_ctx;
172
173 rsa_alt->key = key;
174 rsa_alt->decrypt_func = decrypt_func;
175 rsa_alt->sign_func = sign_func;
176 rsa_alt->key_len_func = key_len_func;
177
178 return( 0 );
179 }
180 #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
181
182 /*
183 * Tell if a PK can do the operations of the given type
184 */
mbedtls_pk_can_do(const mbedtls_pk_context * ctx,mbedtls_pk_type_t type)185 int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type )
186 {
187 /* A context with null pk_info is not set up yet and can't do anything.
188 * For backward compatibility, also accept NULL instead of a context
189 * pointer. */
190 if( ctx == NULL || ctx->pk_info == NULL )
191 return( 0 );
192
193 return( ctx->pk_info->can_do( type ) );
194 }
195
196 /*
197 * Helper for mbedtls_pk_sign and mbedtls_pk_verify
198 */
pk_hashlen_helper(mbedtls_md_type_t md_alg,size_t * hash_len)199 static inline int pk_hashlen_helper( mbedtls_md_type_t md_alg, size_t *hash_len )
200 {
201 const mbedtls_md_info_t *md_info;
202
203 if( *hash_len != 0 )
204 return( 0 );
205
206 if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL )
207 return( -1 );
208
209 *hash_len = mbedtls_md_get_size( md_info );
210 return( 0 );
211 }
212
213 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
214 /*
215 * Helper to set up a restart context if needed
216 */
pk_restart_setup(mbedtls_pk_restart_ctx * ctx,const mbedtls_pk_info_t * info)217 static int pk_restart_setup( mbedtls_pk_restart_ctx *ctx,
218 const mbedtls_pk_info_t *info )
219 {
220 /* Don't do anything if already set up or invalid */
221 if( ctx == NULL || ctx->pk_info != NULL )
222 return( 0 );
223
224 /* Should never happen when we're called */
225 if( info->rs_alloc_func == NULL || info->rs_free_func == NULL )
226 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
227
228 if( ( ctx->rs_ctx = info->rs_alloc_func() ) == NULL )
229 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
230
231 ctx->pk_info = info;
232
233 return( 0 );
234 }
235 #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
236
237 /*
238 * Verify a signature (restartable)
239 */
mbedtls_pk_verify_restartable(mbedtls_pk_context * ctx,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hash_len,const unsigned char * sig,size_t sig_len,mbedtls_pk_restart_ctx * rs_ctx)240 int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx,
241 mbedtls_md_type_t md_alg,
242 const unsigned char *hash, size_t hash_len,
243 const unsigned char *sig, size_t sig_len,
244 mbedtls_pk_restart_ctx *rs_ctx )
245 {
246 PK_VALIDATE_RET( ctx != NULL );
247 PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
248 hash != NULL );
249 PK_VALIDATE_RET( sig != NULL );
250
251 if( ctx->pk_info == NULL ||
252 pk_hashlen_helper( md_alg, &hash_len ) != 0 )
253 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
254
255 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
256 /* optimization: use non-restartable version if restart disabled */
257 if( rs_ctx != NULL &&
258 mbedtls_ecp_restart_is_enabled() &&
259 ctx->pk_info->verify_rs_func != NULL )
260 {
261 int ret;
262
263 if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
264 return( ret );
265
266 ret = ctx->pk_info->verify_rs_func( ctx->pk_ctx,
267 md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx );
268
269 if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
270 mbedtls_pk_restart_free( rs_ctx );
271
272 return( ret );
273 }
274 #else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
275 (void) rs_ctx;
276 #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
277
278 if( ctx->pk_info->verify_func == NULL )
279 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
280
281 return( ctx->pk_info->verify_func( ctx->pk_ctx, md_alg, hash, hash_len,
282 sig, sig_len ) );
283 }
284
285 /*
286 * Verify a signature
287 */
mbedtls_pk_verify(mbedtls_pk_context * ctx,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hash_len,const unsigned char * sig,size_t sig_len)288 int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
289 const unsigned char *hash, size_t hash_len,
290 const unsigned char *sig, size_t sig_len )
291 {
292 return( mbedtls_pk_verify_restartable( ctx, md_alg, hash, hash_len,
293 sig, sig_len, NULL ) );
294 }
295
296 /*
297 * Verify a signature with options
298 */
mbedtls_pk_verify_ext(mbedtls_pk_type_t type,const void * options,mbedtls_pk_context * ctx,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hash_len,const unsigned char * sig,size_t sig_len)299 int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
300 mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
301 const unsigned char *hash, size_t hash_len,
302 const unsigned char *sig, size_t sig_len )
303 {
304 PK_VALIDATE_RET( ctx != NULL );
305 PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
306 hash != NULL );
307 PK_VALIDATE_RET( sig != NULL );
308
309 if( ctx->pk_info == NULL )
310 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
311
312 if( ! mbedtls_pk_can_do( ctx, type ) )
313 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
314
315 if( type == MBEDTLS_PK_RSASSA_PSS )
316 {
317 #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
318 int ret;
319 const mbedtls_pk_rsassa_pss_options *pss_opts;
320
321 #if SIZE_MAX > UINT_MAX
322 if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
323 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
324 #endif /* SIZE_MAX > UINT_MAX */
325
326 if( options == NULL )
327 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
328
329 pss_opts = (const mbedtls_pk_rsassa_pss_options *) options;
330
331 if( sig_len < mbedtls_pk_get_len( ctx ) )
332 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
333
334 ret = mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_pk_rsa( *ctx ),
335 NULL, NULL, MBEDTLS_RSA_PUBLIC,
336 md_alg, (unsigned int) hash_len, hash,
337 pss_opts->mgf1_hash_id,
338 pss_opts->expected_salt_len,
339 sig );
340 if( ret != 0 )
341 return( ret );
342
343 if( sig_len > mbedtls_pk_get_len( ctx ) )
344 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
345
346 return( 0 );
347 #else
348 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
349 #endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */
350 }
351
352 /* General case: no options */
353 if( options != NULL )
354 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
355
356 return( mbedtls_pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) );
357 }
358
359 /*
360 * Make a signature (restartable)
361 */
mbedtls_pk_sign_restartable(mbedtls_pk_context * ctx,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hash_len,unsigned char * sig,size_t * sig_len,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,mbedtls_pk_restart_ctx * rs_ctx)362 int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx,
363 mbedtls_md_type_t md_alg,
364 const unsigned char *hash, size_t hash_len,
365 unsigned char *sig, size_t *sig_len,
366 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
367 mbedtls_pk_restart_ctx *rs_ctx )
368 {
369 PK_VALIDATE_RET( ctx != NULL );
370 PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
371 hash != NULL );
372 PK_VALIDATE_RET( sig != NULL );
373
374 if( ctx->pk_info == NULL ||
375 pk_hashlen_helper( md_alg, &hash_len ) != 0 )
376 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
377
378 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
379 /* optimization: use non-restartable version if restart disabled */
380 if( rs_ctx != NULL &&
381 mbedtls_ecp_restart_is_enabled() &&
382 ctx->pk_info->sign_rs_func != NULL )
383 {
384 int ret;
385
386 if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
387 return( ret );
388
389 ret = ctx->pk_info->sign_rs_func( ctx->pk_ctx, md_alg,
390 hash, hash_len, sig, sig_len, f_rng, p_rng, rs_ctx->rs_ctx );
391
392 if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
393 mbedtls_pk_restart_free( rs_ctx );
394
395 return( ret );
396 }
397 #else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
398 (void) rs_ctx;
399 #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
400
401 if( ctx->pk_info->sign_func == NULL )
402 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
403
404 return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg, hash, hash_len,
405 sig, sig_len, f_rng, p_rng ) );
406 }
407
408 /*
409 * Make a signature
410 */
mbedtls_pk_sign(mbedtls_pk_context * ctx,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hash_len,unsigned char * sig,size_t * sig_len,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)411 int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
412 const unsigned char *hash, size_t hash_len,
413 unsigned char *sig, size_t *sig_len,
414 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
415 {
416 return( mbedtls_pk_sign_restartable( ctx, md_alg, hash, hash_len,
417 sig, sig_len, f_rng, p_rng, NULL ) );
418 }
419
420 /*
421 * Decrypt message
422 */
mbedtls_pk_decrypt(mbedtls_pk_context * ctx,const unsigned char * input,size_t ilen,unsigned char * output,size_t * olen,size_t osize,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)423 int mbedtls_pk_decrypt( mbedtls_pk_context *ctx,
424 const unsigned char *input, size_t ilen,
425 unsigned char *output, size_t *olen, size_t osize,
426 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
427 {
428 PK_VALIDATE_RET( ctx != NULL );
429 PK_VALIDATE_RET( input != NULL || ilen == 0 );
430 PK_VALIDATE_RET( output != NULL || osize == 0 );
431 PK_VALIDATE_RET( olen != NULL );
432
433 if( ctx->pk_info == NULL )
434 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
435
436 if( ctx->pk_info->decrypt_func == NULL )
437 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
438
439 return( ctx->pk_info->decrypt_func( ctx->pk_ctx, input, ilen,
440 output, olen, osize, f_rng, p_rng ) );
441 }
442
443 /*
444 * Encrypt message
445 */
mbedtls_pk_encrypt(mbedtls_pk_context * ctx,const unsigned char * input,size_t ilen,unsigned char * output,size_t * olen,size_t osize,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)446 int mbedtls_pk_encrypt( mbedtls_pk_context *ctx,
447 const unsigned char *input, size_t ilen,
448 unsigned char *output, size_t *olen, size_t osize,
449 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
450 {
451 PK_VALIDATE_RET( ctx != NULL );
452 PK_VALIDATE_RET( input != NULL || ilen == 0 );
453 PK_VALIDATE_RET( output != NULL || osize == 0 );
454 PK_VALIDATE_RET( olen != NULL );
455
456 if( ctx->pk_info == NULL )
457 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
458
459 if( ctx->pk_info->encrypt_func == NULL )
460 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
461
462 return( ctx->pk_info->encrypt_func( ctx->pk_ctx, input, ilen,
463 output, olen, osize, f_rng, p_rng ) );
464 }
465
466 /*
467 * Check public-private key pair
468 */
mbedtls_pk_check_pair(const mbedtls_pk_context * pub,const mbedtls_pk_context * prv)469 int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv )
470 {
471 PK_VALIDATE_RET( pub != NULL );
472 PK_VALIDATE_RET( prv != NULL );
473
474 if( pub->pk_info == NULL ||
475 prv->pk_info == NULL ||
476 prv->pk_info->check_pair_func == NULL )
477 {
478 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
479 }
480
481 if( prv->pk_info->type == MBEDTLS_PK_RSA_ALT )
482 {
483 if( pub->pk_info->type != MBEDTLS_PK_RSA )
484 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
485 }
486 else
487 {
488 if( pub->pk_info != prv->pk_info )
489 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
490 }
491
492 return( prv->pk_info->check_pair_func( pub->pk_ctx, prv->pk_ctx ) );
493 }
494
495 /*
496 * Get key size in bits
497 */
mbedtls_pk_get_bitlen(const mbedtls_pk_context * ctx)498 size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx )
499 {
500 /* For backward compatibility, accept NULL or a context that
501 * isn't set up yet, and return a fake value that should be safe. */
502 if( ctx == NULL || ctx->pk_info == NULL )
503 return( 0 );
504
505 return( ctx->pk_info->get_bitlen( ctx->pk_ctx ) );
506 }
507
508 /*
509 * Export debug information
510 */
mbedtls_pk_debug(const mbedtls_pk_context * ctx,mbedtls_pk_debug_item * items)511 int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items )
512 {
513 PK_VALIDATE_RET( ctx != NULL );
514 if( ctx->pk_info == NULL )
515 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
516
517 if( ctx->pk_info->debug_func == NULL )
518 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
519
520 ctx->pk_info->debug_func( ctx->pk_ctx, items );
521 return( 0 );
522 }
523
524 /*
525 * Access the PK type name
526 */
mbedtls_pk_get_name(const mbedtls_pk_context * ctx)527 const char *mbedtls_pk_get_name( const mbedtls_pk_context *ctx )
528 {
529 if( ctx == NULL || ctx->pk_info == NULL )
530 return( "invalid PK" );
531
532 return( ctx->pk_info->name );
533 }
534
535 /*
536 * Access the PK type
537 */
mbedtls_pk_get_type(const mbedtls_pk_context * ctx)538 mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx )
539 {
540 if( ctx == NULL || ctx->pk_info == NULL )
541 return( MBEDTLS_PK_NONE );
542
543 return( ctx->pk_info->type );
544 }
545
546 #endif /* MBEDTLS_PK_C */
547