blob: 2519d8765a4b76f7c5a6e1255ba89a7cfd361967 [file] [log] [blame]
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +02001/*
2 * Public Key abstraction layer
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * 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.
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020020 */
21
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020022#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000023#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020024#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020025#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020026#endif
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_PK_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/pk.h"
Manuel Pégourié-Gonnard50518f42015-05-26 11:04:15 +020030#include "mbedtls/pk_internal.h"
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020031
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050032#include "mbedtls/platform_util.h"
Andres AG72849872017-01-19 11:24:33 +000033
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020034#if defined(MBEDTLS_RSA_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000035#include "mbedtls/rsa.h"
Manuel Pégourié-Gonnard81c313c2013-07-09 10:35:54 +020036#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020037#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000038#include "mbedtls/ecp.h"
Manuel Pégourié-Gonnard81c313c2013-07-09 10:35:54 +020039#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020040#if defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000041#include "mbedtls/ecdsa.h"
Manuel Pégourié-Gonnard7c5819e2013-07-10 12:29:57 +020042#endif
Manuel Pégourié-Gonnard81c313c2013-07-09 10:35:54 +020043
Andres AG72849872017-01-19 11:24:33 +000044#include <limits.h>
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +010045#include <stdint.h>
Paul Bakker34617722014-06-13 17:20:13 +020046
Gilles Peskinee97dc602018-12-19 00:51:38 +010047/* 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
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +020053/*
Manuel Pégourié-Gonnardc10f0922019-09-19 10:45:14 +020054 * Access to members of the pk_info structure. These are meant to be replaced
55 * by zero-runtime-cost accessors when a single PK type is hardcoded.
56 *
57 * For function members, don't make a getter, but a function that directly
58 * calls the method, so that we can entirely get rid of function pointers
59 * when hardcoding a single PK - some compilers optimize better that way.
60 *
61 * Not implemented for members that are only present in builds with
62 * MBEDTLS_ECP_RESTARTABLE for now, as the main target for hardcoded is builds
63 * with MBEDTLS_USE_TINYCRYPT, which don't have MBEDTLS_ECP_RESTARTABLE.
64 */
65
66MBEDTLS_ALWAYS_INLINE static inline mbedtls_pk_type_t pk_info_type(
67 const mbedtls_pk_info_t *info )
68{
69 return( info->type );
70}
71
72MBEDTLS_ALWAYS_INLINE static inline const char * pk_info_name(
73 const mbedtls_pk_info_t *info )
74{
75 return( info->name );
76}
77
78MBEDTLS_ALWAYS_INLINE static inline size_t pk_info_get_bitlen(
79 const mbedtls_pk_info_t *info, const void *ctx )
80{
81 return( info->get_bitlen( ctx ) );
82}
83
84MBEDTLS_ALWAYS_INLINE static inline int pk_info_can_do(
85 const mbedtls_pk_info_t *info, mbedtls_pk_type_t type )
86{
87 return( info->can_do( type ) );
88}
89
90MBEDTLS_ALWAYS_INLINE static inline int pk_info_verify_func(
91 const mbedtls_pk_info_t *info, void *ctx, mbedtls_md_type_t md_alg,
92 const unsigned char *hash, size_t hash_len,
93 const unsigned char *sig, size_t sig_len )
94{
95 return( info->verify_func( ctx, md_alg, hash, hash_len, sig, sig_len ) );
96}
97
98MBEDTLS_ALWAYS_INLINE static inline int pk_info_sign_func(
99 const mbedtls_pk_info_t *info, void *ctx, mbedtls_md_type_t md_alg,
100 const unsigned char *hash, size_t hash_len,
101 unsigned char *sig, size_t *sig_len,
102 int (*f_rng)(void *, unsigned char *, size_t),
103 void *p_rng )
104{
105 return( info->sign_func( ctx, md_alg, hash, hash_len, sig, sig_len,
106 f_rng, p_rng ) );
107}
108
109MBEDTLS_ALWAYS_INLINE static inline int pk_info_decrypt_func(
110 const mbedtls_pk_info_t *info, void *ctx,
111 const unsigned char *input, size_t ilen,
112 unsigned char *output, size_t *olen, size_t osize,
113 int (*f_rng)(void *, unsigned char *, size_t),
114 void *p_rng )
115{
116 return( info->decrypt_func( ctx, input, ilen, output, olen, osize,
117 f_rng, p_rng ) );
118}
119
120MBEDTLS_ALWAYS_INLINE static inline int pk_info_encrypt_func(
121 const mbedtls_pk_info_t *info, void *ctx,
122 const unsigned char *input, size_t ilen,
123 unsigned char *output, size_t *olen, size_t osize,
124 int (*f_rng)(void *, unsigned char *, size_t),
125 void *p_rng )
126{
127 return( info->encrypt_func( ctx, input, ilen, output, olen, osize,
128 f_rng, p_rng ) );
129}
130
131MBEDTLS_ALWAYS_INLINE static inline int pk_info_check_pair_func(
132 const mbedtls_pk_info_t *info, const void *pub, const void *prv )
133{
134 return( info->check_pair_func( pub, prv ) );
135}
136
137MBEDTLS_ALWAYS_INLINE static inline void *pk_info_ctx_alloc_func(
138 const mbedtls_pk_info_t *info )
139{
140 return( info->ctx_alloc_func( ) );
141}
142
143MBEDTLS_ALWAYS_INLINE static inline void pk_info_ctx_free_func(
144 const mbedtls_pk_info_t *info, void *ctx )
145{
146 info->ctx_free_func( ctx );
147}
148
149MBEDTLS_ALWAYS_INLINE static inline void pk_info_debug_func(
150 const mbedtls_pk_info_t *info,
151 const void *ctx, mbedtls_pk_debug_item *items )
152{
153 info->debug_func( ctx, items );
154}
155
156/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200157 * Initialise a mbedtls_pk_context
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200158 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200159void mbedtls_pk_init( mbedtls_pk_context *ctx )
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200160{
Gilles Peskinee97dc602018-12-19 00:51:38 +0100161 PK_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200162
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200163 ctx->pk_info = NULL;
164 ctx->pk_ctx = NULL;
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200165}
166
167/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200168 * Free (the components of) a mbedtls_pk_context
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200169 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200170void mbedtls_pk_free( mbedtls_pk_context *ctx )
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200171{
irwir2239a862018-06-12 18:25:09 +0300172 if( ctx == NULL )
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200173 return;
174
irwir2239a862018-06-12 18:25:09 +0300175 if ( ctx->pk_info != NULL )
Manuel Pégourié-Gonnardc10f0922019-09-19 10:45:14 +0200176 pk_info_ctx_free_func( ctx->pk_info, ctx->pk_ctx );
Manuel Pégourié-Gonnard1f73a652013-07-09 10:26:41 +0200177
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500178 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pk_context ) );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200179}
180
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200181#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +0200182/*
183 * Initialize a restart context
184 */
185void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx )
186{
Gilles Peskinee97dc602018-12-19 00:51:38 +0100187 PK_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200188 ctx->pk_info = NULL;
189 ctx->rs_ctx = NULL;
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +0200190}
191
192/*
193 * Free the components of a restart context
194 */
195void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx )
196{
Gilles Peskine1f19fa62018-12-19 14:18:39 +0100197 if( ctx == NULL || ctx->pk_info == NULL ||
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200198 ctx->pk_info->rs_free_func == NULL )
199 {
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +0200200 return;
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200201 }
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +0200202
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200203 ctx->pk_info->rs_free_func( ctx->rs_ctx );
204
205 ctx->pk_info = NULL;
206 ctx->rs_ctx = NULL;
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +0200207}
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200208#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +0200209
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200210/*
211 * Get pk_info structure from type
212 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200213const mbedtls_pk_info_t * mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type )
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200214{
215 switch( pk_type ) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200216#if defined(MBEDTLS_RSA_C)
217 case MBEDTLS_PK_RSA:
218 return( &mbedtls_rsa_info );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200219#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200220#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200221 case MBEDTLS_PK_ECKEY_DH:
222 return( &mbedtls_eckeydh_info );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200223#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200224#if defined(MBEDTLS_ECDSA_C)
225 case MBEDTLS_PK_ECDSA:
226 return( &mbedtls_ecdsa_info );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200227#endif
Hanno Beckeradf11e12019-08-21 13:03:44 +0100228#if defined(MBEDTLS_USE_TINYCRYPT)
229 case MBEDTLS_PK_ECKEY:
230 return( &mbedtls_uecc_eckey_info );
231#else /* MBEDTLS_USE_TINYCRYPT */
232#if defined(MBEDTLS_ECP_C)
233 case MBEDTLS_PK_ECKEY:
234 return( &mbedtls_eckey_info );
235#endif
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300236#endif /* MBEDTLS_USE_TINYCRYPT */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200237 /* MBEDTLS_PK_RSA_ALT omitted on purpose */
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200238 default:
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200239 return( NULL );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200240 }
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200241}
242
243/*
Manuel Pégourié-Gonnardab466942013-08-15 11:30:27 +0200244 * Initialise context
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200245 */
Manuel Pégourié-Gonnardd9e6a3a2015-05-14 19:41:36 +0200246int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info )
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200247{
Gilles Peskinee97dc602018-12-19 00:51:38 +0100248 PK_VALIDATE_RET( ctx != NULL );
249 if( info == NULL || ctx->pk_info != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200250 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200251
Manuel Pégourié-Gonnardc10f0922019-09-19 10:45:14 +0200252 if( ( ctx->pk_ctx = pk_info_ctx_alloc_func( info ) ) == NULL )
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +0200253 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200254
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200255 ctx->pk_info = info;
Manuel Pégourié-Gonnard12e0ed92013-07-04 13:31:32 +0200256
257 return( 0 );
258}
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200259
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200260#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
Manuel Pégourié-Gonnardb4fae572014-01-20 11:22:25 +0100261/*
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200262 * Initialize an RSA-alt context
263 */
Manuel Pégourié-Gonnardd9e6a3a2015-05-14 19:41:36 +0200264int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200265 mbedtls_pk_rsa_alt_decrypt_func decrypt_func,
266 mbedtls_pk_rsa_alt_sign_func sign_func,
267 mbedtls_pk_rsa_alt_key_len_func key_len_func )
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200268{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200269 mbedtls_rsa_alt_context *rsa_alt;
270 const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200271
Gilles Peskinee97dc602018-12-19 00:51:38 +0100272 PK_VALIDATE_RET( ctx != NULL );
273 if( ctx->pk_info != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200274 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200275
276 if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +0200277 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200278
279 ctx->pk_info = info;
280
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200281 rsa_alt = (mbedtls_rsa_alt_context *) ctx->pk_ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200282
283 rsa_alt->key = key;
284 rsa_alt->decrypt_func = decrypt_func;
285 rsa_alt->sign_func = sign_func;
286 rsa_alt->key_len_func = key_len_func;
287
288 return( 0 );
289}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200290#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200291
292/*
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200293 * Tell if a PK can do the operations of the given type
294 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200295int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type )
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200296{
Gilles Peskine6af45ec2018-12-19 17:52:05 +0100297 /* A context with null pk_info is not set up yet and can't do anything.
298 * For backward compatibility, also accept NULL instead of a context
299 * pointer. */
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200300 if( ctx == NULL || ctx->pk_info == NULL )
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200301 return( 0 );
302
Manuel Pégourié-Gonnardc10f0922019-09-19 10:45:14 +0200303 return( pk_info_can_do( ctx->pk_info, type ) );
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200304}
305
306/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200307 * Helper for mbedtls_pk_sign and mbedtls_pk_verify
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200308 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200309static inline int pk_hashlen_helper( mbedtls_md_type_t md_alg, size_t *hash_len )
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200310{
Hanno Beckera5cedbc2019-07-17 11:21:02 +0100311 mbedtls_md_handle_t md_info;
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200312
313 if( *hash_len != 0 )
314 return( 0 );
315
Hanno Beckera5cedbc2019-07-17 11:21:02 +0100316 if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) ==
317 MBEDTLS_MD_INVALID_HANDLE )
318 {
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200319 return( -1 );
Hanno Beckera5cedbc2019-07-17 11:21:02 +0100320 }
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200321
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200322 *hash_len = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200323 return( 0 );
324}
325
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200326#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200327/*
328 * Helper to set up a restart context if needed
329 */
330static int pk_restart_setup( mbedtls_pk_restart_ctx *ctx,
Manuel Pégourié-Gonnardee68cff2018-10-15 15:27:49 +0200331 const mbedtls_pk_info_t *info )
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200332{
Manuel Pégourié-Gonnardc8c12b62018-07-02 13:09:39 +0200333 /* Don't do anything if already set up or invalid */
334 if( ctx == NULL || ctx->pk_info != NULL )
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200335 return( 0 );
336
337 /* Should never happen when we're called */
338 if( info->rs_alloc_func == NULL || info->rs_free_func == NULL )
339 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
340
341 if( ( ctx->rs_ctx = info->rs_alloc_func() ) == NULL )
342 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
343
344 ctx->pk_info = info;
345
346 return( 0 );
347}
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200348#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200349
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200350/*
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200351 * Verify a signature (restartable)
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200352 */
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200353int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx,
354 mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200355 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200356 const unsigned char *sig, size_t sig_len,
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +0200357 mbedtls_pk_restart_ctx *rs_ctx )
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200358{
Gilles Peskinee97dc602018-12-19 00:51:38 +0100359 PK_VALIDATE_RET( ctx != NULL );
Gilles Peskineee3cfec2018-12-19 17:10:02 +0100360 PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
361 hash != NULL );
Gilles Peskinee97dc602018-12-19 00:51:38 +0100362 PK_VALIDATE_RET( sig != NULL );
363
364 if( ctx->pk_info == NULL ||
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200365 pk_hashlen_helper( md_alg, &hash_len ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200366 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200367
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200368#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnardd55f7762017-08-18 17:40:15 +0200369 /* optimization: use non-restartable version if restart disabled */
370 if( rs_ctx != NULL &&
Manuel Pégourié-Gonnardb843b152018-10-16 10:41:31 +0200371 mbedtls_ecp_restart_is_enabled() &&
Manuel Pégourié-Gonnardd55f7762017-08-18 17:40:15 +0200372 ctx->pk_info->verify_rs_func != NULL )
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200373 {
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200374 int ret;
375
376 if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
377 return( ret );
378
379 ret = ctx->pk_info->verify_rs_func( ctx->pk_ctx,
380 md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx );
381
382 if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
383 mbedtls_pk_restart_free( rs_ctx );
384
385 return( ret );
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200386 }
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200387#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200388 (void) rs_ctx;
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200389#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200390
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200391 if( ctx->pk_info->verify_func == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200392 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200393
Manuel Pégourié-Gonnardc10f0922019-09-19 10:45:14 +0200394 return( pk_info_verify_func( ctx->pk_info, ctx->pk_ctx, md_alg, hash, hash_len,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200395 sig, sig_len ) );
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200396}
397
398/*
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200399 * Verify a signature
400 */
401int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
402 const unsigned char *hash, size_t hash_len,
403 const unsigned char *sig, size_t sig_len )
404{
405 return( mbedtls_pk_verify_restartable( ctx, md_alg, hash, hash_len,
406 sig, sig_len, NULL ) );
407}
408
409/*
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200410 * Verify a signature with options
411 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200412int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
413 mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200414 const unsigned char *hash, size_t hash_len,
415 const unsigned char *sig, size_t sig_len )
416{
Gilles Peskinee97dc602018-12-19 00:51:38 +0100417 PK_VALIDATE_RET( ctx != NULL );
Gilles Peskineee3cfec2018-12-19 17:10:02 +0100418 PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
419 hash != NULL );
Gilles Peskinee97dc602018-12-19 00:51:38 +0100420 PK_VALIDATE_RET( sig != NULL );
421
422 if( ctx->pk_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200423 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200424
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200425 if( ! mbedtls_pk_can_do( ctx, type ) )
426 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200427
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200428 if( type == MBEDTLS_PK_RSASSA_PSS )
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200429 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200430#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200431 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200432 const mbedtls_pk_rsassa_pss_options *pss_opts;
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200433
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100434#if SIZE_MAX > UINT_MAX
Andres AG72849872017-01-19 11:24:33 +0000435 if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
436 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100437#endif /* SIZE_MAX > UINT_MAX */
Andres AG72849872017-01-19 11:24:33 +0000438
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200439 if( options == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200440 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200441
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200442 pss_opts = (const mbedtls_pk_rsassa_pss_options *) options;
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200443
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200444 if( sig_len < mbedtls_pk_get_len( ctx ) )
445 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200446
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200447 ret = mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_pk_rsa( *ctx ),
448 NULL, NULL, MBEDTLS_RSA_PUBLIC,
Sander Niemeijeref5087d2014-08-16 12:45:52 +0200449 md_alg, (unsigned int) hash_len, hash,
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200450 pss_opts->mgf1_hash_id,
451 pss_opts->expected_salt_len,
452 sig );
453 if( ret != 0 )
454 return( ret );
455
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200456 if( sig_len > mbedtls_pk_get_len( ctx ) )
457 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200458
459 return( 0 );
460#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200461 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
Andres AG72849872017-01-19 11:24:33 +0000462#endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200463 }
464
465 /* General case: no options */
466 if( options != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200467 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200468
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200469 return( mbedtls_pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) );
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200470}
471
472/*
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200473 * Make a signature (restartable)
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200474 */
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200475int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx,
476 mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200477 const unsigned char *hash, size_t hash_len,
478 unsigned char *sig, size_t *sig_len,
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200479 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
Manuel Pégourié-Gonnard15d7df22017-08-17 14:33:31 +0200480 mbedtls_pk_restart_ctx *rs_ctx )
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200481{
Gilles Peskinee97dc602018-12-19 00:51:38 +0100482 PK_VALIDATE_RET( ctx != NULL );
Gilles Peskineee3cfec2018-12-19 17:10:02 +0100483 PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
484 hash != NULL );
Gilles Peskinee97dc602018-12-19 00:51:38 +0100485 PK_VALIDATE_RET( sig != NULL );
486
487 if( ctx->pk_info == NULL ||
Manuel Pégourié-Gonnardbfe32ef2013-08-22 14:55:30 +0200488 pk_hashlen_helper( md_alg, &hash_len ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200489 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200490
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200491#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnardd55f7762017-08-18 17:40:15 +0200492 /* optimization: use non-restartable version if restart disabled */
493 if( rs_ctx != NULL &&
Manuel Pégourié-Gonnardb843b152018-10-16 10:41:31 +0200494 mbedtls_ecp_restart_is_enabled() &&
Manuel Pégourié-Gonnardd55f7762017-08-18 17:40:15 +0200495 ctx->pk_info->sign_rs_func != NULL )
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200496 {
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200497 int ret;
498
499 if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
500 return( ret );
501
502 ret = ctx->pk_info->sign_rs_func( ctx->pk_ctx, md_alg,
503 hash, hash_len, sig, sig_len, f_rng, p_rng, rs_ctx->rs_ctx );
504
505 if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
506 mbedtls_pk_restart_free( rs_ctx );
507
508 return( ret );
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200509 }
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200510#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200511 (void) rs_ctx;
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200512#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200513
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200514 if( ctx->pk_info->sign_func == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200515 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200516
Manuel Pégourié-Gonnardc10f0922019-09-19 10:45:14 +0200517 return( pk_info_sign_func( ctx->pk_info, ctx->pk_ctx, md_alg, hash, hash_len,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200518 sig, sig_len, f_rng, p_rng ) );
519}
520
521/*
Manuel Pégourié-Gonnard82cb27b2017-05-03 10:59:45 +0200522 * Make a signature
523 */
524int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
525 const unsigned char *hash, size_t hash_len,
526 unsigned char *sig, size_t *sig_len,
527 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
528{
529 return( mbedtls_pk_sign_restartable( ctx, md_alg, hash, hash_len,
530 sig, sig_len, f_rng, p_rng, NULL ) );
531}
532
533/*
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200534 * Decrypt message
535 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200536int mbedtls_pk_decrypt( mbedtls_pk_context *ctx,
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200537 const unsigned char *input, size_t ilen,
538 unsigned char *output, size_t *olen, size_t osize,
539 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
540{
Gilles Peskinee97dc602018-12-19 00:51:38 +0100541 PK_VALIDATE_RET( ctx != NULL );
542 PK_VALIDATE_RET( input != NULL || ilen == 0 );
543 PK_VALIDATE_RET( output != NULL || osize == 0 );
544 PK_VALIDATE_RET( olen != NULL );
545
546 if( ctx->pk_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200547 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200548
549 if( ctx->pk_info->decrypt_func == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200550 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200551
Manuel Pégourié-Gonnardc10f0922019-09-19 10:45:14 +0200552 return( pk_info_decrypt_func( ctx->pk_info, ctx->pk_ctx, input, ilen,
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200553 output, olen, osize, f_rng, p_rng ) );
554}
555
556/*
557 * Encrypt message
558 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200559int mbedtls_pk_encrypt( mbedtls_pk_context *ctx,
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200560 const unsigned char *input, size_t ilen,
561 unsigned char *output, size_t *olen, size_t osize,
562 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
563{
Gilles Peskinee97dc602018-12-19 00:51:38 +0100564 PK_VALIDATE_RET( ctx != NULL );
565 PK_VALIDATE_RET( input != NULL || ilen == 0 );
566 PK_VALIDATE_RET( output != NULL || osize == 0 );
567 PK_VALIDATE_RET( olen != NULL );
568
569 if( ctx->pk_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200570 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200571
572 if( ctx->pk_info->encrypt_func == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200573 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200574
Manuel Pégourié-Gonnardc10f0922019-09-19 10:45:14 +0200575 return( pk_info_encrypt_func( ctx->pk_info, ctx->pk_ctx, input, ilen,
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200576 output, olen, osize, f_rng, p_rng ) );
577}
578
579/*
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100580 * Check public-private key pair
581 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200582int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv )
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100583{
Gilles Peskinee97dc602018-12-19 00:51:38 +0100584 PK_VALIDATE_RET( pub != NULL );
585 PK_VALIDATE_RET( prv != NULL );
586
Manuel Pégourié-Gonnard2d9466f2019-09-19 10:45:14 +0200587 if( pub->pk_info == NULL || prv->pk_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200588 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100589
Manuel Pégourié-Gonnard2d9466f2019-09-19 10:45:14 +0200590#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
Manuel Pégourié-Gonnardc10f0922019-09-19 10:45:14 +0200591 if( pk_info_type( prv->pk_info ) == MBEDTLS_PK_RSA_ALT )
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100592 {
Manuel Pégourié-Gonnardc10f0922019-09-19 10:45:14 +0200593 if( pk_info_type( pub->pk_info ) != MBEDTLS_PK_RSA )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200594 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100595 }
596 else
Manuel Pégourié-Gonnard2d9466f2019-09-19 10:45:14 +0200597#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100598 {
599 if( pub->pk_info != prv->pk_info )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200600 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100601 }
602
Manuel Pégourié-Gonnard2d9466f2019-09-19 10:45:14 +0200603 if( prv->pk_info->check_pair_func == NULL )
604 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
605
Manuel Pégourié-Gonnardc10f0922019-09-19 10:45:14 +0200606 return( pk_info_check_pair_func( prv->pk_info, pub->pk_ctx, prv->pk_ctx ) );
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100607}
608
609/*
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200610 * Get key size in bits
611 */
Manuel Pégourié-Gonnard097c7bb2015-06-18 16:43:38 +0200612size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx )
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200613{
Gilles Peskine6af45ec2018-12-19 17:52:05 +0100614 /* For backward compatibility, accept NULL or a context that
615 * isn't set up yet, and return a fake value that should be safe. */
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200616 if( ctx == NULL || ctx->pk_info == NULL )
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200617 return( 0 );
618
Manuel Pégourié-Gonnardc10f0922019-09-19 10:45:14 +0200619 return( pk_info_get_bitlen( ctx->pk_info, ctx->pk_ctx ) );
Manuel Pégourié-Gonnardb3d91872013-08-14 15:56:19 +0200620}
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200621
622/*
623 * Export debug information
624 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200625int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items )
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200626{
Gilles Peskinee97dc602018-12-19 00:51:38 +0100627 PK_VALIDATE_RET( ctx != NULL );
628 if( ctx->pk_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200629 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200630
Manuel Pégourié-Gonnard01488752014-04-03 22:09:18 +0200631 if( ctx->pk_info->debug_func == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200632 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
Manuel Pégourié-Gonnard01488752014-04-03 22:09:18 +0200633
Manuel Pégourié-Gonnardc10f0922019-09-19 10:45:14 +0200634 pk_info_debug_func( ctx->pk_info, ctx->pk_ctx, items );
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200635 return( 0 );
636}
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200637
638/*
639 * Access the PK type name
640 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200641const char *mbedtls_pk_get_name( const mbedtls_pk_context *ctx )
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200642{
643 if( ctx == NULL || ctx->pk_info == NULL )
644 return( "invalid PK" );
645
Manuel Pégourié-Gonnardc10f0922019-09-19 10:45:14 +0200646 return( pk_info_name( ctx->pk_info ) );
Manuel Pégourié-Gonnard3fb5c5e2013-08-14 18:26:41 +0200647}
Manuel Pégourié-Gonnardc40b4c32013-08-22 13:29:31 +0200648
Manuel Pégourié-Gonnard8053da42013-09-11 22:28:30 +0200649/*
650 * Access the PK type
651 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200652mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx )
Manuel Pégourié-Gonnard8053da42013-09-11 22:28:30 +0200653{
654 if( ctx == NULL || ctx->pk_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200655 return( MBEDTLS_PK_NONE );
Manuel Pégourié-Gonnard8053da42013-09-11 22:28:30 +0200656
Manuel Pégourié-Gonnardc10f0922019-09-19 10:45:14 +0200657 return( pk_info_type( ctx->pk_info ) );
Manuel Pégourié-Gonnard8053da42013-09-11 22:28:30 +0200658}
659
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200660#endif /* MBEDTLS_PK_C */