blob: 2bcc947f7bfcc68f595b019fd88f92d096283058 [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"
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020033
Rich Evans00ab4702015-02-06 13:43:58 +000034#include <string.h>
35
Jarno Lamsa42b83db2019-04-16 16:48:22 +030036#if defined(MBEDTLS_USE_TINYCRYPT)
Hanno Becker496b83f2019-08-20 13:33:49 +010037#include "tinycrypt/ecc.h"
38#include "tinycrypt/ecc_dsa.h"
Jarno Lamsa42b83db2019-04-16 16:48:22 +030039#include "mbedtls/asn1.h"
40#include "mbedtls/asn1write.h"
Hanno Becker11cb2632019-09-02 11:55:45 +010041#endif /* MBEDTLS_USE_TINYCRYPT */
42
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020043#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000044#include "mbedtls/ecp.h"
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020045#endif
46
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020047#if defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000048#include "mbedtls/ecdsa.h"
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020049#endif
50
Hanno Becker41029722019-08-20 13:18:56 +010051#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) || \
52 defined(MBEDTLS_USE_TINYCRYPT)
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050053#include "mbedtls/platform_util.h"
Andres Amaya Garciae32df082017-10-25 09:37:04 +010054#endif
55
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020056#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000057#include "mbedtls/platform.h"
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +020058#else
59#include <stdlib.h>
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +020060#define mbedtls_calloc calloc
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020061#define mbedtls_free free
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +020062#endif
63
Andres AG72849872017-01-19 11:24:33 +000064#include <limits.h>
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +010065#include <stdint.h>
Paul Bakker34617722014-06-13 17:20:13 +020066
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020067#if defined(MBEDTLS_RSA_C)
68static int rsa_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +020069{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020070 return( type == MBEDTLS_PK_RSA ||
71 type == MBEDTLS_PK_RSASSA_PSS );
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +020072}
73
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +020074static size_t rsa_get_bitlen( const void *ctx )
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +020075{
Hanno Becker6a1e7e52017-08-22 13:55:00 +010076 const mbedtls_rsa_context * rsa = (const mbedtls_rsa_context *) ctx;
77 return( 8 * mbedtls_rsa_get_len( rsa ) );
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +020078}
79
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020080static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +020081 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020082 const unsigned char *sig, size_t sig_len )
83{
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +020084 int ret;
Hanno Becker6a1e7e52017-08-22 13:55:00 +010085 mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
86 size_t rsa_len = mbedtls_rsa_get_len( rsa );
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +020087
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +010088#if SIZE_MAX > UINT_MAX
Andres AG72849872017-01-19 11:24:33 +000089 if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
90 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +010091#endif /* SIZE_MAX > UINT_MAX */
Andres AG72849872017-01-19 11:24:33 +000092
Hanno Becker6a1e7e52017-08-22 13:55:00 +010093 if( sig_len < rsa_len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020094 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020095
Hanno Becker6a1e7e52017-08-22 13:55:00 +010096 if( ( ret = mbedtls_rsa_pkcs1_verify( rsa, NULL, NULL,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020097 MBEDTLS_RSA_PUBLIC, md_alg,
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +020098 (unsigned int) hash_len, hash, sig ) ) != 0 )
99 return( ret );
100
Gilles Peskine5114d3e2018-03-30 07:12:15 +0200101 /* The buffer contains a valid signature followed by extra data.
102 * We have a special error code for that so that so that callers can
103 * use mbedtls_pk_verify() to check "Does the buffer start with a
104 * valid signature?" and not just "Does the buffer contain a valid
105 * signature?". */
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100106 if( sig_len > rsa_len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200107 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200108
109 return( 0 );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200110}
111
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200112static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200113 const unsigned char *hash, size_t hash_len,
114 unsigned char *sig, size_t *sig_len,
115 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
116{
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100117 mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
118
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100119#if SIZE_MAX > UINT_MAX
Andres AG72849872017-01-19 11:24:33 +0000120 if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
121 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100122#endif /* SIZE_MAX > UINT_MAX */
Andres AG72849872017-01-19 11:24:33 +0000123
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100124 *sig_len = mbedtls_rsa_get_len( rsa );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200125
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100126 return( mbedtls_rsa_pkcs1_sign( rsa, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200127 md_alg, (unsigned int) hash_len, hash, sig ) );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200128}
129
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200130static int rsa_decrypt_wrap( void *ctx,
131 const unsigned char *input, size_t ilen,
132 unsigned char *output, size_t *olen, size_t osize,
133 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
134{
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100135 mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
136
137 if( ilen != mbedtls_rsa_get_len( rsa ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200138 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200139
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100140 return( mbedtls_rsa_pkcs1_decrypt( rsa, f_rng, p_rng,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200141 MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200142}
143
144static int rsa_encrypt_wrap( void *ctx,
145 const unsigned char *input, size_t ilen,
146 unsigned char *output, size_t *olen, size_t osize,
147 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
148{
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100149 mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
150 *olen = mbedtls_rsa_get_len( rsa );
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200151
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100152 if( *olen > osize )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200153 return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE );
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100154
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100155 return( mbedtls_rsa_pkcs1_encrypt( rsa, f_rng, p_rng, MBEDTLS_RSA_PUBLIC,
156 ilen, input, output ) );
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200157}
158
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100159static int rsa_check_pair_wrap( const void *pub, const void *prv )
160{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200161 return( mbedtls_rsa_check_pub_priv( (const mbedtls_rsa_context *) pub,
162 (const mbedtls_rsa_context *) prv ) );
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100163}
164
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200165static void *rsa_alloc_wrap( void )
166{
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200167 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_context ) );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200168
169 if( ctx != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200170 mbedtls_rsa_init( (mbedtls_rsa_context *) ctx, 0, 0 );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200171
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200172 return( ctx );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200173}
174
175static void rsa_free_wrap( void *ctx )
176{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200177 mbedtls_rsa_free( (mbedtls_rsa_context *) ctx );
178 mbedtls_free( ctx );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200179}
180
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200181static void rsa_debug( const void *ctx, mbedtls_pk_debug_item *items )
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200182{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200183 items->type = MBEDTLS_PK_DEBUG_MPI;
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200184 items->name = "rsa.N";
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200185 items->value = &( ((mbedtls_rsa_context *) ctx)->N );
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200186
187 items++;
188
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200189 items->type = MBEDTLS_PK_DEBUG_MPI;
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200190 items->name = "rsa.E";
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200191 items->value = &( ((mbedtls_rsa_context *) ctx)->E );
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200192}
193
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200194const mbedtls_pk_info_t mbedtls_rsa_info = {
195 MBEDTLS_PK_RSA,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200196 "RSA",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200197 rsa_get_bitlen,
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200198 rsa_can_do,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200199 rsa_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200200 rsa_sign_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200201#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200202 NULL,
203 NULL,
204#endif
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200205 rsa_decrypt_wrap,
206 rsa_encrypt_wrap,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100207 rsa_check_pair_wrap,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200208 rsa_alloc_wrap,
209 rsa_free_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200210#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200211 NULL,
212 NULL,
213#endif
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200214 rsa_debug,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200215};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200216#endif /* MBEDTLS_RSA_C */
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200217
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200218#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200219/*
220 * Generic EC key
221 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200222static int eckey_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200223{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200224 return( type == MBEDTLS_PK_ECKEY ||
225 type == MBEDTLS_PK_ECKEY_DH ||
226 type == MBEDTLS_PK_ECDSA );
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200227}
228
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200229static size_t eckey_get_bitlen( const void *ctx )
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200230{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200231 return( ((mbedtls_ecp_keypair *) ctx)->grp.pbits );
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200232}
233
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200234#if defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200235/* Forward declarations */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200236static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200237 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200238 const unsigned char *sig, size_t sig_len );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200239
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200240static int ecdsa_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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200245static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200246 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200247 const unsigned char *sig, size_t sig_len )
248{
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200249 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200250 mbedtls_ecdsa_context ecdsa;
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200251
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200252 mbedtls_ecdsa_init( &ecdsa );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200253
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200254 if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
Manuel Pégourié-Gonnard583b6082013-08-20 16:58:13 +0200255 ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200256
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200257 mbedtls_ecdsa_free( &ecdsa );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200258
259 return( ret );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200260}
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200261
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200262static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200263 const unsigned char *hash, size_t hash_len,
264 unsigned char *sig, size_t *sig_len,
265 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
266{
267 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200268 mbedtls_ecdsa_context ecdsa;
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200269
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200270 mbedtls_ecdsa_init( &ecdsa );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200271
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200272 if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200273 ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len,
274 f_rng, p_rng );
275
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200276 mbedtls_ecdsa_free( &ecdsa );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200277
278 return( ret );
279}
280
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200281#if defined(MBEDTLS_ECP_RESTARTABLE)
282/* Forward declarations */
283static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
284 const unsigned char *hash, size_t hash_len,
285 const unsigned char *sig, size_t sig_len,
286 void *rs_ctx );
287
288static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
289 const unsigned char *hash, size_t hash_len,
290 unsigned char *sig, size_t *sig_len,
291 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
292 void *rs_ctx );
293
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200294/*
295 * Restart context for ECDSA operations with ECKEY context
296 *
297 * We need to store an actual ECDSA context, as we need to pass the same to
298 * the underlying ecdsa function, so we can't create it on the fly every time.
299 */
300typedef struct
301{
302 mbedtls_ecdsa_restart_ctx ecdsa_rs;
303 mbedtls_ecdsa_context ecdsa_ctx;
304} eckey_restart_ctx;
305
306static void *eckey_rs_alloc( void )
307{
308 eckey_restart_ctx *rs_ctx;
309
310 void *ctx = mbedtls_calloc( 1, sizeof( eckey_restart_ctx ) );
311
312 if( ctx != NULL )
313 {
314 rs_ctx = ctx;
315 mbedtls_ecdsa_restart_init( &rs_ctx->ecdsa_rs );
316 mbedtls_ecdsa_init( &rs_ctx->ecdsa_ctx );
317 }
318
319 return( ctx );
320}
321
322static void eckey_rs_free( void *ctx )
323{
324 eckey_restart_ctx *rs_ctx;
325
326 if( ctx == NULL)
327 return;
328
329 rs_ctx = ctx;
330 mbedtls_ecdsa_restart_free( &rs_ctx->ecdsa_rs );
331 mbedtls_ecdsa_free( &rs_ctx->ecdsa_ctx );
332
333 mbedtls_free( ctx );
334}
335
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200336static int eckey_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
337 const unsigned char *hash, size_t hash_len,
338 const unsigned char *sig, size_t sig_len,
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200339 void *rs_ctx )
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200340{
341 int ret;
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200342 eckey_restart_ctx *rs = rs_ctx;
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200343
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200344 /* Should never happen */
345 if( rs == NULL )
346 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200347
Manuel Pégourié-Gonnardee68cff2018-10-15 15:27:49 +0200348 /* set up our own sub-context if needed (that is, on first run) */
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200349 if( rs->ecdsa_ctx.grp.pbits == 0 )
350 MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) );
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200351
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200352 MBEDTLS_MPI_CHK( ecdsa_verify_rs_wrap( &rs->ecdsa_ctx,
353 md_alg, hash, hash_len,
354 sig, sig_len, &rs->ecdsa_rs ) );
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200355
356cleanup:
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200357 return( ret );
358}
359
360static int eckey_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
361 const unsigned char *hash, size_t hash_len,
362 unsigned char *sig, size_t *sig_len,
363 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200364 void *rs_ctx )
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200365{
366 int ret;
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200367 eckey_restart_ctx *rs = rs_ctx;
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200368
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200369 /* Should never happen */
370 if( rs == NULL )
371 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200372
Manuel Pégourié-Gonnardee68cff2018-10-15 15:27:49 +0200373 /* set up our own sub-context if needed (that is, on first run) */
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200374 if( rs->ecdsa_ctx.grp.pbits == 0 )
375 MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) );
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200376
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200377 MBEDTLS_MPI_CHK( ecdsa_sign_rs_wrap( &rs->ecdsa_ctx, md_alg,
378 hash, hash_len, sig, sig_len,
379 f_rng, p_rng, &rs->ecdsa_rs ) );
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200380
381cleanup:
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200382 return( ret );
383}
384#endif /* MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200385#endif /* MBEDTLS_ECDSA_C */
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200386
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100387static int eckey_check_pair( const void *pub, const void *prv )
388{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200389 return( mbedtls_ecp_check_pub_priv( (const mbedtls_ecp_keypair *) pub,
390 (const mbedtls_ecp_keypair *) prv ) );
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100391}
392
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200393static void *eckey_alloc_wrap( void )
394{
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200395 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200396
397 if( ctx != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200398 mbedtls_ecp_keypair_init( ctx );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200399
400 return( ctx );
401}
402
403static void eckey_free_wrap( void *ctx )
404{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200405 mbedtls_ecp_keypair_free( (mbedtls_ecp_keypair *) ctx );
406 mbedtls_free( ctx );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200407}
408
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200409static void eckey_debug( const void *ctx, mbedtls_pk_debug_item *items )
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200410{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200411 items->type = MBEDTLS_PK_DEBUG_ECP;
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200412 items->name = "eckey.Q";
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200413 items->value = &( ((mbedtls_ecp_keypair *) ctx)->Q );
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200414}
415
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200416const mbedtls_pk_info_t mbedtls_eckey_info = {
417 MBEDTLS_PK_ECKEY,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200418 "EC",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200419 eckey_get_bitlen,
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200420 eckey_can_do,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200421#if defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200422 eckey_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200423 eckey_sign_wrap,
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200424#if defined(MBEDTLS_ECP_RESTARTABLE)
425 eckey_verify_rs_wrap,
426 eckey_sign_rs_wrap,
427#endif
428#else /* MBEDTLS_ECDSA_C */
429 NULL,
430 NULL,
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200431#endif /* MBEDTLS_ECDSA_C */
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200432 NULL,
433 NULL,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100434 eckey_check_pair,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200435 eckey_alloc_wrap,
436 eckey_free_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200437#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200438 eckey_rs_alloc,
439 eckey_rs_free,
440#endif
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200441 eckey_debug,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200442};
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200443
444/*
Paul Bakker75342a62014-04-08 17:35:40 +0200445 * EC key restricted to ECDH
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200446 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200447static int eckeydh_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200448{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200449 return( type == MBEDTLS_PK_ECKEY ||
450 type == MBEDTLS_PK_ECKEY_DH );
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200451}
452
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200453const mbedtls_pk_info_t mbedtls_eckeydh_info = {
454 MBEDTLS_PK_ECKEY_DH,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200455 "EC_DH",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200456 eckey_get_bitlen, /* Same underlying key structure */
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200457 eckeydh_can_do,
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200458 NULL,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200459 NULL,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200460#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200461 NULL,
462 NULL,
463#endif
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200464 NULL,
465 NULL,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100466 eckey_check_pair,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200467 eckey_alloc_wrap, /* Same underlying key structure */
468 eckey_free_wrap, /* Same underlying key structure */
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200469#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200470 NULL,
471 NULL,
472#endif
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200473 eckey_debug, /* Same underlying key structure */
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200474};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200475#endif /* MBEDTLS_ECP_C */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200476
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300477#if defined(MBEDTLS_USE_TINYCRYPT)
Hanno Beckerd7e0cd02019-08-20 13:03:11 +0100478
479/*
480 * An ASN.1 encoded signature is a sequence of two ASN.1 integers. Parse one of
481 * those integers and convert it to the fixed-length encoding.
482 */
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300483static int extract_ecdsa_sig_int( unsigned char **from, const unsigned char *end,
484 unsigned char *to, size_t to_len )
485{
486 int ret;
487 size_t unpadded_len, padding_len;
488
489 if( ( ret = mbedtls_asn1_get_tag( from, end, &unpadded_len,
490 MBEDTLS_ASN1_INTEGER ) ) != 0 )
491 {
492 return( ret );
493 }
494
495 while( unpadded_len > 0 && **from == 0x00 )
496 {
497 ( *from )++;
498 unpadded_len--;
499 }
500
501 if( unpadded_len > to_len || unpadded_len == 0 )
502 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
503
504 padding_len = to_len - unpadded_len;
505 memset( to, 0x00, padding_len );
506 memcpy( to + padding_len, *from, unpadded_len );
507 ( *from ) += unpadded_len;
508
509 return( 0 );
510}
511
512/*
513 * Convert a signature from an ASN.1 sequence of two integers
514 * to a raw {r,s} buffer. Note: the provided sig buffer must be at least
515 * twice as big as int_size.
516 */
517static int extract_ecdsa_sig( unsigned char **p, const unsigned char *end,
518 unsigned char *sig, size_t int_size )
519{
520 int ret;
521 size_t tmp_size;
522
523 if( ( ret = mbedtls_asn1_get_tag( p, end, &tmp_size,
524 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
525 return( ret );
526
527 /* Extract r */
528 if( ( ret = extract_ecdsa_sig_int( p, end, sig, int_size ) ) != 0 )
529 return( ret );
530 /* Extract s */
531 if( ( ret = extract_ecdsa_sig_int( p, end, sig + int_size, int_size ) ) != 0 )
532 return( ret );
533
534 return( 0 );
535}
536
Hanno Beckeradf11e12019-08-21 13:03:44 +0100537static size_t uecc_eckey_get_bitlen( const void *ctx )
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300538{
539 (void) ctx;
Hanno Becker9a62f2d2019-08-20 14:57:37 +0100540 return( (size_t) ( NUM_ECC_BYTES * 8 ) );
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300541}
542
Hanno Becker9653d802019-08-21 13:49:13 +0100543static int uecc_eckey_check_pair( const void *pub, const void *prv )
544{
545 const mbedtls_uecc_keypair *uecc_pub =
546 (const mbedtls_uecc_keypair *) pub;
547 const mbedtls_uecc_keypair *uecc_prv =
548 (const mbedtls_uecc_keypair *) prv;
549
550 if( memcmp( uecc_pub->public_key,
551 uecc_prv->public_key,
552 2 * NUM_ECC_BYTES ) == 0 )
553 {
554 return( 0 );
555 }
556
Hanno Beckerc64d5af2019-08-23 13:14:36 +0100557 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Hanno Becker9653d802019-08-21 13:49:13 +0100558}
559
Hanno Beckeradf11e12019-08-21 13:03:44 +0100560static int uecc_eckey_can_do( mbedtls_pk_type_t type )
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300561{
Hanno Beckeradf11e12019-08-21 13:03:44 +0100562 return( type == MBEDTLS_PK_ECDSA ||
563 type == MBEDTLS_PK_ECKEY );
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300564}
565
Hanno Beckeradf11e12019-08-21 13:03:44 +0100566static int uecc_eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300567 const unsigned char *hash, size_t hash_len,
568 const unsigned char *sig, size_t sig_len )
569{
570 int ret;
571 uint8_t signature[2*NUM_ECC_BYTES];
572 unsigned char *p;
573 const struct uECC_Curve_t * uecc_curve = uECC_secp256r1();
Hanno Becker8ea35452019-08-20 15:39:13 +0100574 const mbedtls_uecc_keypair *keypair = (const mbedtls_uecc_keypair *) ctx;
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300575
576 ((void) md_alg);
577 p = (unsigned char*) sig;
578
Hanno Beckerad353f22019-08-20 13:04:30 +0100579 ret = extract_ecdsa_sig( &p, sig + sig_len, signature, NUM_ECC_BYTES );
580 if( ret != 0 )
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300581 return( ret );
582
Hanno Becker8ea35452019-08-20 15:39:13 +0100583 ret = uECC_verify( keypair->public_key, hash,
Hanno Beckerad353f22019-08-20 13:04:30 +0100584 (unsigned) hash_len, signature, uecc_curve );
Hanno Becker8ea35452019-08-20 15:39:13 +0100585 if( ret == 0 )
586 return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300587
Hanno Becker8ea35452019-08-20 15:39:13 +0100588 return( 0 );
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300589}
590
591/*
592 * Simultaneously convert and move raw MPI from the beginning of a buffer
593 * to an ASN.1 MPI at the end of the buffer.
594 * See also mbedtls_asn1_write_mpi().
595 *
596 * p: pointer to the end of the output buffer
597 * start: start of the output buffer, and also of the mpi to write at the end
598 * n_len: length of the mpi to read from start
Hanno Becker96d34d52019-09-03 10:01:26 +0100599 *
600 * Warning:
601 * The total length of the output buffer must be smaller than 128 Bytes.
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300602 */
603static int asn1_write_mpibuf( unsigned char **p, unsigned char *start,
604 size_t n_len )
605{
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300606 size_t len = 0;
607
608 if( (size_t)( *p - start ) < n_len )
609 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
610
611 len = n_len;
612 *p -= len;
613 memmove( *p, start, len );
614
615 /* ASN.1 DER encoding requires minimal length, so skip leading 0s.
616 * Neither r nor s should be 0, but as a failsafe measure, still detect
Hanno Beckere8f14482019-08-20 13:28:59 +0100617 * that rather than overflowing the buffer in case of an error. */
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300618 while( len > 0 && **p == 0x00 )
619 {
620 ++(*p);
621 --len;
622 }
623
624 /* this is only reached if the signature was invalid */
625 if( len == 0 )
626 return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
627
628 /* if the msb is 1, ASN.1 requires that we prepend a 0.
629 * Neither r nor s can be 0, so we can assume len > 0 at all times. */
630 if( **p & 0x80 )
631 {
632 if( *p - start < 1 )
633 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
634
635 *--(*p) = 0x00;
636 len += 1;
637 }
638
Hanno Becker96d34d52019-09-03 10:01:26 +0100639 /* The ASN.1 length encoding is just a single Byte containing the length,
640 * as we assume that the total buffer length is smaller than 128 Bytes. */
641 *--(*p) = len;
642 *--(*p) = MBEDTLS_ASN1_INTEGER;
643 len += 2;
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300644
645 return( (int) len );
646}
647
Jarno Lamsaad789312019-04-23 09:15:54 +0300648/* Transcode signature from uECC format to ASN.1 sequence.
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300649 * See ecdsa_signature_to_asn1 in ecdsa.c, but with byte buffers instead of
650 * MPIs, and in-place.
651 *
652 * [in/out] sig: the signature pre- and post-transcoding
653 * [in/out] sig_len: signature length pre- and post-transcoding
654 * [int] buf_len: the available size the in/out buffer
Hanno Becker96d34d52019-09-03 10:01:26 +0100655 *
656 * Warning: buf_len must be smaller than 128 Bytes.
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300657 */
Hanno Beckere8f14482019-08-20 13:28:59 +0100658static int pk_ecdsa_sig_asn1_from_uecc( unsigned char *sig, size_t *sig_len,
659 size_t buf_len )
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300660{
661 int ret;
662 size_t len = 0;
663 const size_t rs_len = *sig_len / 2;
664 unsigned char *p = sig + buf_len;
665
666 MBEDTLS_ASN1_CHK_ADD( len, asn1_write_mpibuf( &p, sig + rs_len, rs_len ) );
667 MBEDTLS_ASN1_CHK_ADD( len, asn1_write_mpibuf( &p, sig, rs_len ) );
668
Hanno Becker96d34d52019-09-03 10:01:26 +0100669 /* The ASN.1 length encoding is just a single Byte containing the length,
670 * as we assume that the total buffer length is smaller than 128 Bytes. */
671 *--p = len;
672 *--p = MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE;
673 len += 2;
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300674
675 memmove( sig, p, len );
676 *sig_len = len;
677
678 return( 0 );
679}
680
Hanno Beckeradf11e12019-08-21 13:03:44 +0100681static int uecc_eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300682 const unsigned char *hash, size_t hash_len,
683 unsigned char *sig, size_t *sig_len,
684 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
685{
Jarno Lamsaad789312019-04-23 09:15:54 +0300686 const mbedtls_uecc_keypair *keypair = (const mbedtls_uecc_keypair *) ctx;
687 const struct uECC_Curve_t * uecc_curve = uECC_secp256r1();
Hanno Beckerd2929b52019-09-04 16:07:52 +0100688 int ret;
Hanno Becker9c7a3592019-08-20 15:37:17 +0100689
690 /*
691 * RFC-4492 page 20:
692 *
693 * Ecdsa-Sig-Value ::= SEQUENCE {
694 * r INTEGER,
695 * s INTEGER
696 * }
697 *
698 * Size is at most
699 * 1 (tag) + 1 (len) + 1 (initial 0) + NUM_ECC_BYTES for each of r and s,
700 * twice that + 1 (tag) + 2 (len) for the sequence
Hanno Becker96d34d52019-09-03 10:01:26 +0100701 *
702 * (The ASN.1 length encodings are all 1-Byte encodings because
703 * the total size is smaller than 128 Bytes).
Hanno Becker9c7a3592019-08-20 15:37:17 +0100704 */
Hanno Becker96d34d52019-09-03 10:01:26 +0100705 #define MAX_SECP256R1_ECDSA_SIG_LEN ( 3 + 2 * ( 3 + NUM_ECC_BYTES ) )
Hanno Becker9c7a3592019-08-20 15:37:17 +0100706
Hanno Beckerd2929b52019-09-04 16:07:52 +0100707 ret = uECC_sign( keypair->private_key, hash, hash_len, sig, uecc_curve );
708 /* TinyCrypt uses 0 to signal errors. */
709 if( ret == 0 )
710 return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
711
Hanno Becker9c7a3592019-08-20 15:37:17 +0100712 *sig_len = 2 * NUM_ECC_BYTES;
Jarno Lamsaad789312019-04-23 09:15:54 +0300713
714 /* uECC owns its rng function pointer */
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300715 (void) f_rng;
716 (void) p_rng;
Jarno Lamsaad789312019-04-23 09:15:54 +0300717 (void) md_alg;
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300718
Hanno Becker96d34d52019-09-03 10:01:26 +0100719 return( pk_ecdsa_sig_asn1_from_uecc( sig, sig_len,
720 MAX_SECP256R1_ECDSA_SIG_LEN ) );
721
722 #undef MAX_SECP256R1_ECDSA_SIG_LEN
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300723}
724
Hanno Beckeradf11e12019-08-21 13:03:44 +0100725static void *uecc_eckey_alloc_wrap( void )
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300726{
Hanno Becker41029722019-08-20 13:18:56 +0100727 return( mbedtls_calloc( 1, sizeof( mbedtls_uecc_keypair ) ) );
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300728}
729
Hanno Beckeradf11e12019-08-21 13:03:44 +0100730static void uecc_eckey_free_wrap( void *ctx )
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300731{
Hanno Becker41029722019-08-20 13:18:56 +0100732 if( ctx == NULL )
733 return;
734
735 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_uecc_keypair ) );
736 mbedtls_free( ctx );
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300737}
738
Hanno Beckeradf11e12019-08-21 13:03:44 +0100739const mbedtls_pk_info_t mbedtls_uecc_eckey_info = {
740 MBEDTLS_PK_ECKEY,
741 "EC",
742 uecc_eckey_get_bitlen,
743 uecc_eckey_can_do,
744 uecc_eckey_verify_wrap,
745 uecc_eckey_sign_wrap,
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300746 NULL,
747 NULL,
Hanno Becker9653d802019-08-21 13:49:13 +0100748 uecc_eckey_check_pair,
Hanno Beckeradf11e12019-08-21 13:03:44 +0100749 uecc_eckey_alloc_wrap,
750 uecc_eckey_free_wrap,
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300751 NULL,
752};
Hanno Becker11cb2632019-09-02 11:55:45 +0100753#endif /* MBEDTLS_USE_TINYCRYPT */
754
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200755#if defined(MBEDTLS_ECDSA_C)
756static int ecdsa_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200757{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200758 return( type == MBEDTLS_PK_ECDSA );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200759}
760
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200761static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200762 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200763 const unsigned char *sig, size_t sig_len )
764{
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200765 int ret;
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200766 ((void) md_alg);
767
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200768 ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx,
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200769 hash, hash_len, sig, sig_len );
770
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200771 if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )
772 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200773
774 return( ret );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200775}
776
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200777static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200778 const unsigned char *hash, size_t hash_len,
779 unsigned char *sig, size_t *sig_len,
780 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
781{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200782 return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx,
Manuel Pégourié-Gonnarddfdcac92015-03-31 11:41:42 +0200783 md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200784}
785
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200786#if defined(MBEDTLS_ECP_RESTARTABLE)
787static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
788 const unsigned char *hash, size_t hash_len,
789 const unsigned char *sig, size_t sig_len,
790 void *rs_ctx )
791{
792 int ret;
793 ((void) md_alg);
794
795 ret = mbedtls_ecdsa_read_signature_restartable(
796 (mbedtls_ecdsa_context *) ctx,
797 hash, hash_len, sig, sig_len,
798 (mbedtls_ecdsa_restart_ctx *) rs_ctx );
799
800 if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )
801 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
802
803 return( ret );
804}
805
806static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
807 const unsigned char *hash, size_t hash_len,
808 unsigned char *sig, size_t *sig_len,
809 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
810 void *rs_ctx )
811{
812 return( mbedtls_ecdsa_write_signature_restartable(
813 (mbedtls_ecdsa_context *) ctx,
814 md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng,
815 (mbedtls_ecdsa_restart_ctx *) rs_ctx ) );
816
817}
818#endif /* MBEDTLS_ECP_RESTARTABLE */
819
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200820static void *ecdsa_alloc_wrap( void )
821{
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200822 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200823
824 if( ctx != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200825 mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200826
827 return( ctx );
828}
829
830static void ecdsa_free_wrap( void *ctx )
831{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200832 mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx );
833 mbedtls_free( ctx );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200834}
835
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200836#if defined(MBEDTLS_ECP_RESTARTABLE)
837static void *ecdsa_rs_alloc( void )
838{
839 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_restart_ctx ) );
840
841 if( ctx != NULL )
842 mbedtls_ecdsa_restart_init( ctx );
843
844 return( ctx );
845}
846
847static void ecdsa_rs_free( void *ctx )
848{
849 mbedtls_ecdsa_restart_free( ctx );
850 mbedtls_free( ctx );
851}
852#endif /* MBEDTLS_ECP_RESTARTABLE */
853
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200854const mbedtls_pk_info_t mbedtls_ecdsa_info = {
855 MBEDTLS_PK_ECDSA,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200856 "ECDSA",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200857 eckey_get_bitlen, /* Compatible key structures */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200858 ecdsa_can_do,
859 ecdsa_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200860 ecdsa_sign_wrap,
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200861#if defined(MBEDTLS_ECP_RESTARTABLE)
862 ecdsa_verify_rs_wrap,
863 ecdsa_sign_rs_wrap,
864#endif
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200865 NULL,
866 NULL,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100867 eckey_check_pair, /* Compatible key structures */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200868 ecdsa_alloc_wrap,
869 ecdsa_free_wrap,
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200870#if defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200871 ecdsa_rs_alloc,
872 ecdsa_rs_free,
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200873#endif
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200874 eckey_debug, /* Compatible key structures */
875};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200876#endif /* MBEDTLS_ECDSA_C */
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200877
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200878#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200879/*
880 * Support for alternative RSA-private implementations
881 */
882
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200883static int rsa_alt_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200884{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200885 return( type == MBEDTLS_PK_RSA );
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200886}
887
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200888static size_t rsa_alt_get_bitlen( const void *ctx )
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200889{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200890 const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200891
Manuel Pégourié-Gonnard01488752014-04-03 22:09:18 +0200892 return( 8 * rsa_alt->key_len_func( rsa_alt->key ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200893}
894
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200895static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200896 const unsigned char *hash, size_t hash_len,
897 unsigned char *sig, size_t *sig_len,
898 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
899{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200900 mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200901
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100902#if SIZE_MAX > UINT_MAX
Andres AG72849872017-01-19 11:24:33 +0000903 if( UINT_MAX < hash_len )
904 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100905#endif /* SIZE_MAX > UINT_MAX */
Andres AG72849872017-01-19 11:24:33 +0000906
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200907 *sig_len = rsa_alt->key_len_func( rsa_alt->key );
908
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200909 return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200910 md_alg, (unsigned int) hash_len, hash, sig ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200911}
912
913static int rsa_alt_decrypt_wrap( void *ctx,
914 const unsigned char *input, size_t ilen,
915 unsigned char *output, size_t *olen, size_t osize,
916 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
917{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200918 mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200919
920 ((void) f_rng);
921 ((void) p_rng);
922
923 if( ilen != rsa_alt->key_len_func( rsa_alt->key ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200924 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200925
926 return( rsa_alt->decrypt_func( rsa_alt->key,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200927 MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200928}
929
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200930#if defined(MBEDTLS_RSA_C)
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100931static int rsa_alt_check_pair( const void *pub, const void *prv )
932{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200933 unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100934 unsigned char hash[32];
935 size_t sig_len = 0;
936 int ret;
937
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200938 if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200939 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100940
941 memset( hash, 0x2a, sizeof( hash ) );
942
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200943 if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE,
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100944 hash, sizeof( hash ),
945 sig, &sig_len, NULL, NULL ) ) != 0 )
946 {
947 return( ret );
948 }
949
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200950 if( rsa_verify_wrap( (void *) pub, MBEDTLS_MD_NONE,
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100951 hash, sizeof( hash ), sig, sig_len ) != 0 )
952 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200953 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100954 }
955
956 return( 0 );
957}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200958#endif /* MBEDTLS_RSA_C */
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100959
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200960static void *rsa_alt_alloc_wrap( void )
961{
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200962 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200963
964 if( ctx != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200965 memset( ctx, 0, sizeof( mbedtls_rsa_alt_context ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200966
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200967 return( ctx );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200968}
969
970static void rsa_alt_free_wrap( void *ctx )
971{
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500972 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200973 mbedtls_free( ctx );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200974}
975
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200976const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
977 MBEDTLS_PK_RSA_ALT,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200978 "RSA-alt",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200979 rsa_alt_get_bitlen,
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200980 rsa_alt_can_do,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200981 NULL,
982 rsa_alt_sign_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200983#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200984 NULL,
985 NULL,
986#endif
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200987 rsa_alt_decrypt_wrap,
988 NULL,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200989#if defined(MBEDTLS_RSA_C)
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100990 rsa_alt_check_pair,
Manuel Pégourié-Gonnard7c13d692014-11-12 00:01:34 +0100991#else
992 NULL,
993#endif
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200994 rsa_alt_alloc_wrap,
995 rsa_alt_free_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200996#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200997 NULL,
998 NULL,
999#endif
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +02001000 NULL,
1001};
Manuel Pégourié-Gonnardc40b4c32013-08-22 13:29:31 +02001002
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001003#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
Manuel Pégourié-Gonnard348bcb32015-03-31 14:01:33 +02001004
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001005#endif /* MBEDTLS_PK_C */