2 * Public Key abstraction layer: wrapper functions
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: GPL-2.0
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 * This file is part of mbed TLS (https://tls.mbed.org)
24 #if !defined(MBEDTLS_CONFIG_FILE)
25 #include "mbedtls/config.h"
27 #include MBEDTLS_CONFIG_FILE
30 #if defined(MBEDTLS_PK_C)
31 #include "mbedtls/pk_internal.h"
33 /* Even if RSA not activated, for the sake of RSA-alt */
34 #include "mbedtls/rsa.h"
38 #if defined(MBEDTLS_ECP_C)
39 #include "mbedtls/ecp.h"
42 #if defined(MBEDTLS_ECDSA_C)
43 #include "mbedtls/ecdsa.h"
46 #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
47 #include "mbedtls/platform_util.h"
50 #if defined(MBEDTLS_PLATFORM_C)
51 #include "mbedtls/platform.h"
54 #define mbedtls_calloc calloc
55 #define mbedtls_free free
61 #if defined(MBEDTLS_RSA_C)
62 static int rsa_can_do( mbedtls_pk_type_t type
)
64 return( type
== MBEDTLS_PK_RSA
||
65 type
== MBEDTLS_PK_RSASSA_PSS
);
68 static size_t rsa_get_bitlen( const void *ctx
)
70 const mbedtls_rsa_context
* rsa
= (const mbedtls_rsa_context
*) ctx
;
71 return( 8 * mbedtls_rsa_get_len( rsa
) );
74 static int rsa_verify_wrap( void *ctx
, mbedtls_md_type_t md_alg
,
75 const unsigned char *hash
, size_t hash_len
,
76 const unsigned char *sig
, size_t sig_len
)
79 mbedtls_rsa_context
* rsa
= (mbedtls_rsa_context
*) ctx
;
80 size_t rsa_len
= mbedtls_rsa_get_len( rsa
);
82 #if SIZE_MAX > UINT_MAX
83 if( md_alg
== MBEDTLS_MD_NONE
&& UINT_MAX
< hash_len
)
84 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA
);
85 #endif /* SIZE_MAX > UINT_MAX */
87 if( sig_len
< rsa_len
)
88 return( MBEDTLS_ERR_RSA_VERIFY_FAILED
);
90 if( ( ret
= mbedtls_rsa_pkcs1_verify( rsa
, NULL
, NULL
,
91 MBEDTLS_RSA_PUBLIC
, md_alg
,
92 (unsigned int) hash_len
, hash
, sig
) ) != 0 )
95 /* The buffer contains a valid signature followed by extra data.
96 * We have a special error code for that so that so that callers can
97 * use mbedtls_pk_verify() to check "Does the buffer start with a
98 * valid signature?" and not just "Does the buffer contain a valid
100 if( sig_len
> rsa_len
)
101 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH
);
106 static int rsa_sign_wrap( void *ctx
, mbedtls_md_type_t md_alg
,
107 const unsigned char *hash
, size_t hash_len
,
108 unsigned char *sig
, size_t *sig_len
,
109 int (*f_rng
)(void *, unsigned char *, size_t), void *p_rng
)
111 mbedtls_rsa_context
* rsa
= (mbedtls_rsa_context
*) ctx
;
113 #if SIZE_MAX > UINT_MAX
114 if( md_alg
== MBEDTLS_MD_NONE
&& UINT_MAX
< hash_len
)
115 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA
);
116 #endif /* SIZE_MAX > UINT_MAX */
118 *sig_len
= mbedtls_rsa_get_len( rsa
);
120 return( mbedtls_rsa_pkcs1_sign( rsa
, f_rng
, p_rng
, MBEDTLS_RSA_PRIVATE
,
121 md_alg
, (unsigned int) hash_len
, hash
, sig
) );
124 static int rsa_decrypt_wrap( void *ctx
,
125 const unsigned char *input
, size_t ilen
,
126 unsigned char *output
, size_t *olen
, size_t osize
,
127 int (*f_rng
)(void *, unsigned char *, size_t), void *p_rng
)
129 mbedtls_rsa_context
* rsa
= (mbedtls_rsa_context
*) ctx
;
131 if( ilen
!= mbedtls_rsa_get_len( rsa
) )
132 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA
);
134 return( mbedtls_rsa_pkcs1_decrypt( rsa
, f_rng
, p_rng
,
135 MBEDTLS_RSA_PRIVATE
, olen
, input
, output
, osize
) );
138 static int rsa_encrypt_wrap( void *ctx
,
139 const unsigned char *input
, size_t ilen
,
140 unsigned char *output
, size_t *olen
, size_t osize
,
141 int (*f_rng
)(void *, unsigned char *, size_t), void *p_rng
)
143 mbedtls_rsa_context
* rsa
= (mbedtls_rsa_context
*) ctx
;
144 *olen
= mbedtls_rsa_get_len( rsa
);
147 return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE
);
149 return( mbedtls_rsa_pkcs1_encrypt( rsa
, f_rng
, p_rng
, MBEDTLS_RSA_PUBLIC
,
150 ilen
, input
, output
) );
153 static int rsa_check_pair_wrap( const void *pub
, const void *prv
)
155 return( mbedtls_rsa_check_pub_priv( (const mbedtls_rsa_context
*) pub
,
156 (const mbedtls_rsa_context
*) prv
) );
159 static void *rsa_alloc_wrap( void )
161 void *ctx
= mbedtls_calloc( 1, sizeof( mbedtls_rsa_context
) );
164 mbedtls_rsa_init( (mbedtls_rsa_context
*) ctx
, 0, 0 );
169 static void rsa_free_wrap( void *ctx
)
171 mbedtls_rsa_free( (mbedtls_rsa_context
*) ctx
);
175 static void rsa_debug( const void *ctx
, mbedtls_pk_debug_item
*items
)
177 items
->type
= MBEDTLS_PK_DEBUG_MPI
;
178 items
->name
= "rsa.N";
179 items
->value
= &( ((mbedtls_rsa_context
*) ctx
)->N
);
183 items
->type
= MBEDTLS_PK_DEBUG_MPI
;
184 items
->name
= "rsa.E";
185 items
->value
= &( ((mbedtls_rsa_context
*) ctx
)->E
);
188 const mbedtls_pk_info_t mbedtls_rsa_info
= {
202 #endif /* MBEDTLS_RSA_C */
204 #if defined(MBEDTLS_ECP_C)
208 static int eckey_can_do( mbedtls_pk_type_t type
)
210 return( type
== MBEDTLS_PK_ECKEY
||
211 type
== MBEDTLS_PK_ECKEY_DH
||
212 type
== MBEDTLS_PK_ECDSA
);
215 static size_t eckey_get_bitlen( const void *ctx
)
217 return( ((mbedtls_ecp_keypair
*) ctx
)->grp
.pbits
);
220 #if defined(MBEDTLS_ECDSA_C)
221 /* Forward declarations */
222 static int ecdsa_verify_wrap( void *ctx
, mbedtls_md_type_t md_alg
,
223 const unsigned char *hash
, size_t hash_len
,
224 const unsigned char *sig
, size_t sig_len
);
226 static int ecdsa_sign_wrap( void *ctx
, mbedtls_md_type_t md_alg
,
227 const unsigned char *hash
, size_t hash_len
,
228 unsigned char *sig
, size_t *sig_len
,
229 int (*f_rng
)(void *, unsigned char *, size_t), void *p_rng
);
231 static int eckey_verify_wrap( void *ctx
, mbedtls_md_type_t md_alg
,
232 const unsigned char *hash
, size_t hash_len
,
233 const unsigned char *sig
, size_t sig_len
)
236 mbedtls_ecdsa_context ecdsa
;
238 mbedtls_ecdsa_init( &ecdsa
);
240 if( ( ret
= mbedtls_ecdsa_from_keypair( &ecdsa
, ctx
) ) == 0 )
241 ret
= ecdsa_verify_wrap( &ecdsa
, md_alg
, hash
, hash_len
, sig
, sig_len
);
243 mbedtls_ecdsa_free( &ecdsa
);
248 static int eckey_sign_wrap( void *ctx
, mbedtls_md_type_t md_alg
,
249 const unsigned char *hash
, size_t hash_len
,
250 unsigned char *sig
, size_t *sig_len
,
251 int (*f_rng
)(void *, unsigned char *, size_t), void *p_rng
)
254 mbedtls_ecdsa_context ecdsa
;
256 mbedtls_ecdsa_init( &ecdsa
);
258 if( ( ret
= mbedtls_ecdsa_from_keypair( &ecdsa
, ctx
) ) == 0 )
259 ret
= ecdsa_sign_wrap( &ecdsa
, md_alg
, hash
, hash_len
, sig
, sig_len
,
262 mbedtls_ecdsa_free( &ecdsa
);
267 #endif /* MBEDTLS_ECDSA_C */
269 static int eckey_check_pair( const void *pub
, const void *prv
)
271 return( mbedtls_ecp_check_pub_priv( (const mbedtls_ecp_keypair
*) pub
,
272 (const mbedtls_ecp_keypair
*) prv
) );
275 static void *eckey_alloc_wrap( void )
277 void *ctx
= mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair
) );
280 mbedtls_ecp_keypair_init( ctx
);
285 static void eckey_free_wrap( void *ctx
)
287 mbedtls_ecp_keypair_free( (mbedtls_ecp_keypair
*) ctx
);
291 static void eckey_debug( const void *ctx
, mbedtls_pk_debug_item
*items
)
293 items
->type
= MBEDTLS_PK_DEBUG_ECP
;
294 items
->name
= "eckey.Q";
295 items
->value
= &( ((mbedtls_ecp_keypair
*) ctx
)->Q
);
298 const mbedtls_pk_info_t mbedtls_eckey_info
= {
303 #if defined(MBEDTLS_ECDSA_C)
319 * EC key restricted to ECDH
321 static int eckeydh_can_do( mbedtls_pk_type_t type
)
323 return( type
== MBEDTLS_PK_ECKEY
||
324 type
== MBEDTLS_PK_ECKEY_DH
);
327 const mbedtls_pk_info_t mbedtls_eckeydh_info
= {
330 eckey_get_bitlen
, /* Same underlying key structure */
337 eckey_alloc_wrap
, /* Same underlying key structure */
338 eckey_free_wrap
, /* Same underlying key structure */
339 eckey_debug
, /* Same underlying key structure */
341 #endif /* MBEDTLS_ECP_C */
343 #if defined(MBEDTLS_ECDSA_C)
344 static int ecdsa_can_do( mbedtls_pk_type_t type
)
346 return( type
== MBEDTLS_PK_ECDSA
);
349 static int ecdsa_verify_wrap( void *ctx
, mbedtls_md_type_t md_alg
,
350 const unsigned char *hash
, size_t hash_len
,
351 const unsigned char *sig
, size_t sig_len
)
356 ret
= mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context
*) ctx
,
357 hash
, hash_len
, sig
, sig_len
);
359 if( ret
== MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH
)
360 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH
);
365 static int ecdsa_sign_wrap( void *ctx
, mbedtls_md_type_t md_alg
,
366 const unsigned char *hash
, size_t hash_len
,
367 unsigned char *sig
, size_t *sig_len
,
368 int (*f_rng
)(void *, unsigned char *, size_t), void *p_rng
)
370 return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context
*) ctx
,
371 md_alg
, hash
, hash_len
, sig
, sig_len
, f_rng
, p_rng
) );
374 static void *ecdsa_alloc_wrap( void )
376 void *ctx
= mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context
) );
379 mbedtls_ecdsa_init( (mbedtls_ecdsa_context
*) ctx
);
384 static void ecdsa_free_wrap( void *ctx
)
386 mbedtls_ecdsa_free( (mbedtls_ecdsa_context
*) ctx
);
390 const mbedtls_pk_info_t mbedtls_ecdsa_info
= {
393 eckey_get_bitlen
, /* Compatible key structures */
399 eckey_check_pair
, /* Compatible key structures */
402 eckey_debug
, /* Compatible key structures */
404 #endif /* MBEDTLS_ECDSA_C */
406 #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
408 * Support for alternative RSA-private implementations
411 static int rsa_alt_can_do( mbedtls_pk_type_t type
)
413 return( type
== MBEDTLS_PK_RSA
);
416 static size_t rsa_alt_get_bitlen( const void *ctx
)
418 const mbedtls_rsa_alt_context
*rsa_alt
= (const mbedtls_rsa_alt_context
*) ctx
;
420 return( 8 * rsa_alt
->key_len_func( rsa_alt
->key
) );
423 static int rsa_alt_sign_wrap( void *ctx
, mbedtls_md_type_t md_alg
,
424 const unsigned char *hash
, size_t hash_len
,
425 unsigned char *sig
, size_t *sig_len
,
426 int (*f_rng
)(void *, unsigned char *, size_t), void *p_rng
)
428 mbedtls_rsa_alt_context
*rsa_alt
= (mbedtls_rsa_alt_context
*) ctx
;
430 #if SIZE_MAX > UINT_MAX
431 if( UINT_MAX
< hash_len
)
432 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA
);
433 #endif /* SIZE_MAX > UINT_MAX */
435 *sig_len
= rsa_alt
->key_len_func( rsa_alt
->key
);
437 return( rsa_alt
->sign_func( rsa_alt
->key
, f_rng
, p_rng
, MBEDTLS_RSA_PRIVATE
,
438 md_alg
, (unsigned int) hash_len
, hash
, sig
) );
441 static int rsa_alt_decrypt_wrap( void *ctx
,
442 const unsigned char *input
, size_t ilen
,
443 unsigned char *output
, size_t *olen
, size_t osize
,
444 int (*f_rng
)(void *, unsigned char *, size_t), void *p_rng
)
446 mbedtls_rsa_alt_context
*rsa_alt
= (mbedtls_rsa_alt_context
*) ctx
;
451 if( ilen
!= rsa_alt
->key_len_func( rsa_alt
->key
) )
452 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA
);
454 return( rsa_alt
->decrypt_func( rsa_alt
->key
,
455 MBEDTLS_RSA_PRIVATE
, olen
, input
, output
, osize
) );
458 #if defined(MBEDTLS_RSA_C)
459 static int rsa_alt_check_pair( const void *pub
, const void *prv
)
461 unsigned char sig
[MBEDTLS_MPI_MAX_SIZE
];
462 unsigned char hash
[32];
466 if( rsa_alt_get_bitlen( prv
) != rsa_get_bitlen( pub
) )
467 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED
);
469 memset( hash
, 0x2a, sizeof( hash
) );
471 if( ( ret
= rsa_alt_sign_wrap( (void *) prv
, MBEDTLS_MD_NONE
,
472 hash
, sizeof( hash
),
473 sig
, &sig_len
, NULL
, NULL
) ) != 0 )
478 if( rsa_verify_wrap( (void *) pub
, MBEDTLS_MD_NONE
,
479 hash
, sizeof( hash
), sig
, sig_len
) != 0 )
481 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED
);
486 #endif /* MBEDTLS_RSA_C */
488 static void *rsa_alt_alloc_wrap( void )
490 void *ctx
= mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context
) );
493 memset( ctx
, 0, sizeof( mbedtls_rsa_alt_context
) );
498 static void rsa_alt_free_wrap( void *ctx
)
500 mbedtls_platform_zeroize( ctx
, sizeof( mbedtls_rsa_alt_context
) );
504 const mbedtls_pk_info_t mbedtls_rsa_alt_info
= {
511 rsa_alt_decrypt_wrap
,
513 #if defined(MBEDTLS_RSA_C)
523 #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
525 #endif /* MBEDTLS_PK_C */