blob: 8b94d8129ada634cc465ede53f965f1c09cd68ac [file] [log] [blame]
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +02001/*
2 * Public Key abstraction layer: wrapper functions
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é-Gonnardd73b3c12013-08-12 17:06:05 +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é-Gonnardd73b3c12013-08-12 17:06:05 +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é-Gonnardd73b3c12013-08-12 17:06:05 +020027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_PK_C)
Manuel Pégourié-Gonnard50518f42015-05-26 11:04:15 +020029#include "mbedtls/pk_internal.h"
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020030
Manuel Pégourié-Gonnarde511ffc2013-08-22 17:33:21 +020031/* Even if RSA not activated, for the sake of RSA-alt */
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/rsa.h"
Andres AG72849872017-01-19 11:24:33 +000033#include "mbedtls/bignum.h"
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020034
Rich Evans00ab4702015-02-06 13:43:58 +000035#include <string.h>
36
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é-Gonnardd73b3c12013-08-12 17:06:05 +020039#endif
40
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#if defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000042#include "mbedtls/ecdsa.h"
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020043#endif
44
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000046#include "mbedtls/platform.h"
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +020047#else
48#include <stdlib.h>
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +020049#define mbedtls_calloc calloc
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050#define mbedtls_free free
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +020051#endif
52
Andres AG72849872017-01-19 11:24:33 +000053#include <limits.h>
54
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020055#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
Paul Bakker34617722014-06-13 17:20:13 +020056/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020057static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020058 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
59}
Manuel Pégourié-Gonnard348bcb32015-03-31 14:01:33 +020060#endif
Paul Bakker34617722014-06-13 17:20:13 +020061
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020062#if defined(MBEDTLS_RSA_C)
63static int rsa_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +020064{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020065 return( type == MBEDTLS_PK_RSA ||
66 type == MBEDTLS_PK_RSASSA_PSS );
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +020067}
68
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +020069static size_t rsa_get_bitlen( const void *ctx )
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +020070{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020071 return( 8 * ((const mbedtls_rsa_context *) ctx)->len );
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +020072}
73
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020074static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +020075 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020076 const unsigned char *sig, size_t sig_len )
77{
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +020078 int ret;
79
Andres AG72849872017-01-19 11:24:33 +000080#if defined(MBEDTLS_HAVE_INT64)
81 if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
82 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
83#endif /* MBEDTLS_HAVE_INT64 */
84
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020085 if( sig_len < ((mbedtls_rsa_context *) ctx)->len )
86 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020087
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020088 if( ( ret = mbedtls_rsa_pkcs1_verify( (mbedtls_rsa_context *) ctx, NULL, NULL,
89 MBEDTLS_RSA_PUBLIC, md_alg,
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +020090 (unsigned int) hash_len, hash, sig ) ) != 0 )
91 return( ret );
92
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020093 if( sig_len > ((mbedtls_rsa_context *) ctx)->len )
94 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +020095
96 return( 0 );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020097}
98
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020099static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200100 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), void *p_rng )
103{
Andres AG72849872017-01-19 11:24:33 +0000104#if defined(MBEDTLS_HAVE_INT64)
105 if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
106 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
107#endif /* MBEDTLS_HAVE_INT64 */
108
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200109 *sig_len = ((mbedtls_rsa_context *) ctx)->len;
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200110
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200111 return( mbedtls_rsa_pkcs1_sign( (mbedtls_rsa_context *) ctx, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200112 md_alg, (unsigned int) hash_len, hash, sig ) );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200113}
114
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200115static int rsa_decrypt_wrap( void *ctx,
116 const unsigned char *input, size_t ilen,
117 unsigned char *output, size_t *olen, size_t osize,
118 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
119{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200120 if( ilen != ((mbedtls_rsa_context *) ctx)->len )
121 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200122
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200123 return( mbedtls_rsa_pkcs1_decrypt( (mbedtls_rsa_context *) ctx, f_rng, p_rng,
124 MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200125}
126
127static int rsa_encrypt_wrap( void *ctx,
128 const unsigned char *input, size_t ilen,
129 unsigned char *output, size_t *olen, size_t osize,
130 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
131{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200132 *olen = ((mbedtls_rsa_context *) ctx)->len;
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200133
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100134 if( *olen > osize )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200135 return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE );
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100136
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200137 return( mbedtls_rsa_pkcs1_encrypt( (mbedtls_rsa_context *) ctx,
138 f_rng, p_rng, MBEDTLS_RSA_PUBLIC, ilen, input, output ) );
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200139}
140
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100141static int rsa_check_pair_wrap( const void *pub, const void *prv )
142{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200143 return( mbedtls_rsa_check_pub_priv( (const mbedtls_rsa_context *) pub,
144 (const mbedtls_rsa_context *) prv ) );
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100145}
146
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200147static void *rsa_alloc_wrap( void )
148{
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200149 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_context ) );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200150
151 if( ctx != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200152 mbedtls_rsa_init( (mbedtls_rsa_context *) ctx, 0, 0 );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200153
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200154 return( ctx );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200155}
156
157static void rsa_free_wrap( void *ctx )
158{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200159 mbedtls_rsa_free( (mbedtls_rsa_context *) ctx );
160 mbedtls_free( ctx );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200161}
162
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200163static void rsa_debug( const void *ctx, mbedtls_pk_debug_item *items )
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200164{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200165 items->type = MBEDTLS_PK_DEBUG_MPI;
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200166 items->name = "rsa.N";
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200167 items->value = &( ((mbedtls_rsa_context *) ctx)->N );
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200168
169 items++;
170
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200171 items->type = MBEDTLS_PK_DEBUG_MPI;
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200172 items->name = "rsa.E";
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200173 items->value = &( ((mbedtls_rsa_context *) ctx)->E );
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200174}
175
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200176const mbedtls_pk_info_t mbedtls_rsa_info = {
177 MBEDTLS_PK_RSA,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200178 "RSA",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200179 rsa_get_bitlen,
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200180 rsa_can_do,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200181 rsa_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200182 rsa_sign_wrap,
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200183#if defined(MBEDTLS_ECP_RESTARTABLE)
184 NULL,
185 NULL,
186#endif
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200187 rsa_decrypt_wrap,
188 rsa_encrypt_wrap,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100189 rsa_check_pair_wrap,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200190 rsa_alloc_wrap,
191 rsa_free_wrap,
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200192 rsa_debug,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200193};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200194#endif /* MBEDTLS_RSA_C */
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200195
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200196#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200197/*
198 * Generic EC key
199 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200200static int eckey_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200201{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200202 return( type == MBEDTLS_PK_ECKEY ||
203 type == MBEDTLS_PK_ECKEY_DH ||
204 type == MBEDTLS_PK_ECDSA );
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200205}
206
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200207static size_t eckey_get_bitlen( const void *ctx )
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200208{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200209 return( ((mbedtls_ecp_keypair *) ctx)->grp.pbits );
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200210}
211
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200212#if defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200213/* Forward declarations */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200214static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200215 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200216 const unsigned char *sig, size_t sig_len );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200217
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200218static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200219 const unsigned char *hash, size_t hash_len,
220 unsigned char *sig, size_t *sig_len,
221 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
222
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200223static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200224 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200225 const unsigned char *sig, size_t sig_len )
226{
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200227 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200228 mbedtls_ecdsa_context ecdsa;
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200229
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200230 mbedtls_ecdsa_init( &ecdsa );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200231
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200232 if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
Manuel Pégourié-Gonnard583b6082013-08-20 16:58:13 +0200233 ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200234
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200235 mbedtls_ecdsa_free( &ecdsa );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200236
237 return( ret );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200238}
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200239
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200240static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200241 const unsigned char *hash, size_t hash_len,
242 unsigned char *sig, size_t *sig_len,
243 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
244{
245 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200246 mbedtls_ecdsa_context ecdsa;
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200247
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200248 mbedtls_ecdsa_init( &ecdsa );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200249
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200250 if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200251 ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len,
252 f_rng, p_rng );
253
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200254 mbedtls_ecdsa_free( &ecdsa );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200255
256 return( ret );
257}
258
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200259#if defined(MBEDTLS_ECP_RESTARTABLE)
260/* Forward declarations */
261static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
262 const unsigned char *hash, size_t hash_len,
263 const unsigned char *sig, size_t sig_len,
264 void *rs_ctx );
265
266static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
267 const unsigned char *hash, size_t hash_len,
268 unsigned char *sig, size_t *sig_len,
269 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
270 void *rs_ctx );
271
272static int eckey_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
273 const unsigned char *hash, size_t hash_len,
274 const unsigned char *sig, size_t sig_len,
275 void *p_rs_ctx )
276{
277 int ret;
278 mbedtls_ecdsa_context ecdsa, *p_ecdsa = &ecdsa;
279 mbedtls_ecdsa_restart_ctx *rs_ctx = p_rs_ctx;
280
281 mbedtls_ecdsa_init( &ecdsa );
282
283 /* set up our own sub-context if needed */
284 if( mbedtls_ecp_restart_enabled() &&
285 rs_ctx != NULL && rs_ctx->ecdsa == NULL )
286 {
287 rs_ctx->ecdsa = mbedtls_calloc( 1, sizeof( *rs_ctx->ecdsa ) );
288 if( rs_ctx->ecdsa == NULL )
289 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
290
291 mbedtls_ecdsa_init( rs_ctx->ecdsa );
292 MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( rs_ctx->ecdsa, ctx ) );
293 }
294
295 if( rs_ctx != NULL && rs_ctx->ecdsa != NULL )
296 {
297 /* redirect to our context */
298 p_ecdsa = rs_ctx->ecdsa;
299 }
300 else
301 {
302 MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( p_ecdsa, ctx ) );
303 }
304
305 MBEDTLS_MPI_CHK( ecdsa_verify_rs_wrap( p_ecdsa, md_alg, hash, hash_len,
306 sig, sig_len, rs_ctx ) );
307
308cleanup:
309 /* clear our sub-context when not in progress (done or error) */
Manuel Pégourié-Gonnard31f0ef72017-05-17 10:05:58 +0200310 if( rs_ctx != NULL && ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
311 {
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200312 mbedtls_ecdsa_free( rs_ctx->ecdsa );
313 mbedtls_free( rs_ctx->ecdsa );
314 rs_ctx->ecdsa = NULL;
315 }
316
317 mbedtls_ecdsa_free( &ecdsa );
318
319 return( ret );
320}
321
322static int eckey_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
323 const unsigned char *hash, size_t hash_len,
324 unsigned char *sig, size_t *sig_len,
325 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
326 void *p_rs_ctx )
327{
328 int ret;
329 mbedtls_ecdsa_context ecdsa, *p_ecdsa = &ecdsa;
330 mbedtls_ecdsa_restart_ctx *rs_ctx = p_rs_ctx;
331
332 mbedtls_ecdsa_init( &ecdsa );
333
334 /* set up our own sub-context if needed */
335 if( mbedtls_ecp_restart_enabled() &&
336 rs_ctx != NULL && rs_ctx->ecdsa == NULL )
337 {
338 rs_ctx->ecdsa = mbedtls_calloc( 1, sizeof( *rs_ctx->ecdsa ) );
339 if( rs_ctx->ecdsa == NULL )
340 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
341
342 mbedtls_ecdsa_init( rs_ctx->ecdsa );
343 MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( rs_ctx->ecdsa, ctx ) );
344 }
345
346 if( rs_ctx != NULL && rs_ctx->ecdsa != NULL )
347 {
348 /* redirect to our context */
349 p_ecdsa = rs_ctx->ecdsa;
350 }
351 else
352 {
353 MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( p_ecdsa, ctx ) );
354 }
355
356 MBEDTLS_MPI_CHK( ecdsa_sign_rs_wrap( p_ecdsa, md_alg, hash, hash_len,
357 sig, sig_len, f_rng, p_rng, rs_ctx ) );
358
359cleanup:
360 /* clear our sub-context when not in progress (done or error) */
Manuel Pégourié-Gonnard31f0ef72017-05-17 10:05:58 +0200361 if( rs_ctx != NULL && ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
362 {
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200363 mbedtls_ecdsa_free( rs_ctx->ecdsa );
364 mbedtls_free( rs_ctx->ecdsa );
365 rs_ctx->ecdsa = NULL;
366 }
367
368 mbedtls_ecdsa_free( &ecdsa );
369
370 return( ret );
371}
372#endif /* MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200373#endif /* MBEDTLS_ECDSA_C */
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200374
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100375static int eckey_check_pair( const void *pub, const void *prv )
376{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200377 return( mbedtls_ecp_check_pub_priv( (const mbedtls_ecp_keypair *) pub,
378 (const mbedtls_ecp_keypair *) prv ) );
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100379}
380
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200381static void *eckey_alloc_wrap( void )
382{
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200383 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200384
385 if( ctx != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200386 mbedtls_ecp_keypair_init( ctx );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200387
388 return( ctx );
389}
390
391static void eckey_free_wrap( void *ctx )
392{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200393 mbedtls_ecp_keypair_free( (mbedtls_ecp_keypair *) ctx );
394 mbedtls_free( ctx );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200395}
396
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200397static void eckey_debug( const void *ctx, mbedtls_pk_debug_item *items )
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200398{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200399 items->type = MBEDTLS_PK_DEBUG_ECP;
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200400 items->name = "eckey.Q";
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200401 items->value = &( ((mbedtls_ecp_keypair *) ctx)->Q );
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200402}
403
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200404const mbedtls_pk_info_t mbedtls_eckey_info = {
405 MBEDTLS_PK_ECKEY,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200406 "EC",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200407 eckey_get_bitlen,
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200408 eckey_can_do,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200409#if defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200410 eckey_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200411 eckey_sign_wrap,
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200412#if defined(MBEDTLS_ECP_RESTARTABLE)
413 eckey_verify_rs_wrap,
414 eckey_sign_rs_wrap,
415#endif
416#else /* MBEDTLS_ECDSA_C */
417 NULL,
418 NULL,
419#if defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200420 NULL,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200421 NULL,
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200422#endif
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200423#endif /* MBEDTLS_ECDSA_C */
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200424 NULL,
425 NULL,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100426 eckey_check_pair,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200427 eckey_alloc_wrap,
428 eckey_free_wrap,
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200429 eckey_debug,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200430};
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200431
432/*
Paul Bakker75342a62014-04-08 17:35:40 +0200433 * EC key restricted to ECDH
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200434 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200435static int eckeydh_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200436{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200437 return( type == MBEDTLS_PK_ECKEY ||
438 type == MBEDTLS_PK_ECKEY_DH );
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200439}
440
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200441const mbedtls_pk_info_t mbedtls_eckeydh_info = {
442 MBEDTLS_PK_ECKEY_DH,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200443 "EC_DH",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200444 eckey_get_bitlen, /* Same underlying key structure */
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200445 eckeydh_can_do,
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200446 NULL,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200447 NULL,
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200448#if defined(MBEDTLS_ECP_RESTARTABLE)
449 NULL,
450 NULL,
451#endif
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200452 NULL,
453 NULL,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100454 eckey_check_pair,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200455 eckey_alloc_wrap, /* Same underlying key structure */
456 eckey_free_wrap, /* Same underlying key structure */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200457 eckey_debug, /* Same underlying key structure */
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200458};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200459#endif /* MBEDTLS_ECP_C */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200460
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200461#if defined(MBEDTLS_ECDSA_C)
462static int ecdsa_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200463{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200464 return( type == MBEDTLS_PK_ECDSA );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200465}
466
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200467static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200468 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200469 const unsigned char *sig, size_t sig_len )
470{
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200471 int ret;
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200472 ((void) md_alg);
473
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200474 ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx,
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200475 hash, hash_len, sig, sig_len );
476
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200477 if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )
478 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200479
480 return( ret );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200481}
482
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200483static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200484 const unsigned char *hash, size_t hash_len,
485 unsigned char *sig, size_t *sig_len,
486 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
487{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200488 return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx,
Manuel Pégourié-Gonnarddfdcac92015-03-31 11:41:42 +0200489 md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200490}
491
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200492#if defined(MBEDTLS_ECP_RESTARTABLE)
493static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
494 const unsigned char *hash, size_t hash_len,
495 const unsigned char *sig, size_t sig_len,
496 void *rs_ctx )
497{
498 int ret;
499 ((void) md_alg);
500
501 ret = mbedtls_ecdsa_read_signature_restartable(
502 (mbedtls_ecdsa_context *) ctx,
503 hash, hash_len, sig, sig_len,
504 (mbedtls_ecdsa_restart_ctx *) rs_ctx );
505
506 if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )
507 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
508
509 return( ret );
510}
511
512static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
513 const unsigned char *hash, size_t hash_len,
514 unsigned char *sig, size_t *sig_len,
515 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
516 void *rs_ctx )
517{
518 return( mbedtls_ecdsa_write_signature_restartable(
519 (mbedtls_ecdsa_context *) ctx,
520 md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng,
521 (mbedtls_ecdsa_restart_ctx *) rs_ctx ) );
522
523}
524#endif /* MBEDTLS_ECP_RESTARTABLE */
525
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200526static void *ecdsa_alloc_wrap( void )
527{
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200528 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200529
530 if( ctx != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200531 mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200532
533 return( ctx );
534}
535
536static void ecdsa_free_wrap( void *ctx )
537{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200538 mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx );
539 mbedtls_free( ctx );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200540}
541
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200542const mbedtls_pk_info_t mbedtls_ecdsa_info = {
543 MBEDTLS_PK_ECDSA,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200544 "ECDSA",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200545 eckey_get_bitlen, /* Compatible key structures */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200546 ecdsa_can_do,
547 ecdsa_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200548 ecdsa_sign_wrap,
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200549#if defined(MBEDTLS_ECP_RESTARTABLE)
550 ecdsa_verify_rs_wrap,
551 ecdsa_sign_rs_wrap,
552#endif
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200553 NULL,
554 NULL,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100555 eckey_check_pair, /* Compatible key structures */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200556 ecdsa_alloc_wrap,
557 ecdsa_free_wrap,
558 eckey_debug, /* Compatible key structures */
559};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200560#endif /* MBEDTLS_ECDSA_C */
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200561
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200562#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200563/*
564 * Support for alternative RSA-private implementations
565 */
566
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200567static int rsa_alt_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200568{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200569 return( type == MBEDTLS_PK_RSA );
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200570}
571
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200572static size_t rsa_alt_get_bitlen( const void *ctx )
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200573{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200574 const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200575
Manuel Pégourié-Gonnard01488752014-04-03 22:09:18 +0200576 return( 8 * rsa_alt->key_len_func( rsa_alt->key ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200577}
578
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200579static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200580 const unsigned char *hash, size_t hash_len,
581 unsigned char *sig, size_t *sig_len,
582 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
583{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200584 mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200585
Andres AG72849872017-01-19 11:24:33 +0000586#if defined(MBEDTLS_HAVE_INT64)
587 if( UINT_MAX < hash_len )
588 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
589#endif /* MBEDTLS_HAVE_INT64 */
590
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200591 *sig_len = rsa_alt->key_len_func( rsa_alt->key );
592
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200593 return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200594 md_alg, (unsigned int) hash_len, hash, sig ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200595}
596
597static int rsa_alt_decrypt_wrap( void *ctx,
598 const unsigned char *input, size_t ilen,
599 unsigned char *output, size_t *olen, size_t osize,
600 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
601{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200602 mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200603
604 ((void) f_rng);
605 ((void) p_rng);
606
607 if( ilen != rsa_alt->key_len_func( rsa_alt->key ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200608 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200609
610 return( rsa_alt->decrypt_func( rsa_alt->key,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200611 MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200612}
613
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200614#if defined(MBEDTLS_RSA_C)
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100615static int rsa_alt_check_pair( const void *pub, const void *prv )
616{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200617 unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100618 unsigned char hash[32];
619 size_t sig_len = 0;
620 int ret;
621
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200622 if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200623 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100624
625 memset( hash, 0x2a, sizeof( hash ) );
626
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200627 if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE,
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100628 hash, sizeof( hash ),
629 sig, &sig_len, NULL, NULL ) ) != 0 )
630 {
631 return( ret );
632 }
633
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200634 if( rsa_verify_wrap( (void *) pub, MBEDTLS_MD_NONE,
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100635 hash, sizeof( hash ), sig, sig_len ) != 0 )
636 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200637 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100638 }
639
640 return( 0 );
641}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200642#endif /* MBEDTLS_RSA_C */
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100643
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200644static void *rsa_alt_alloc_wrap( void )
645{
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200646 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200647
648 if( ctx != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200649 memset( ctx, 0, sizeof( mbedtls_rsa_alt_context ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200650
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200651 return( ctx );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200652}
653
654static void rsa_alt_free_wrap( void *ctx )
655{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200656 mbedtls_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) );
657 mbedtls_free( ctx );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200658}
659
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200660const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
661 MBEDTLS_PK_RSA_ALT,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200662 "RSA-alt",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200663 rsa_alt_get_bitlen,
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200664 rsa_alt_can_do,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200665 NULL,
666 rsa_alt_sign_wrap,
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200667#if defined(MBEDTLS_ECP_RESTARTABLE)
668 NULL,
669 NULL,
670#endif
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200671 rsa_alt_decrypt_wrap,
672 NULL,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200673#if defined(MBEDTLS_RSA_C)
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100674 rsa_alt_check_pair,
Manuel Pégourié-Gonnard7c13d692014-11-12 00:01:34 +0100675#else
676 NULL,
677#endif
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200678 rsa_alt_alloc_wrap,
679 rsa_alt_free_wrap,
680 NULL,
681};
Manuel Pégourié-Gonnardc40b4c32013-08-22 13:29:31 +0200682
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200683#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
Manuel Pégourié-Gonnard348bcb32015-03-31 14:01:33 +0200684
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200685#endif /* MBEDTLS_PK_C */