blob: 838360405a3a3b97d8d774342a0bcf11e99593ec [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)
478static int extract_ecdsa_sig_int( unsigned char **from, const unsigned char *end,
479 unsigned char *to, size_t to_len )
480{
481 int ret;
482 size_t unpadded_len, padding_len;
483
484 if( ( ret = mbedtls_asn1_get_tag( from, end, &unpadded_len,
485 MBEDTLS_ASN1_INTEGER ) ) != 0 )
486 {
487 return( ret );
488 }
489
490 while( unpadded_len > 0 && **from == 0x00 )
491 {
492 ( *from )++;
493 unpadded_len--;
494 }
495
496 if( unpadded_len > to_len || unpadded_len == 0 )
497 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
498
499 padding_len = to_len - unpadded_len;
500 memset( to, 0x00, padding_len );
501 memcpy( to + padding_len, *from, unpadded_len );
502 ( *from ) += unpadded_len;
503
504 return( 0 );
505}
506
507/*
508 * Convert a signature from an ASN.1 sequence of two integers
509 * to a raw {r,s} buffer. Note: the provided sig buffer must be at least
510 * twice as big as int_size.
511 */
512static int extract_ecdsa_sig( unsigned char **p, const unsigned char *end,
513 unsigned char *sig, size_t int_size )
514{
515 int ret;
516 size_t tmp_size;
517
518 if( ( ret = mbedtls_asn1_get_tag( p, end, &tmp_size,
519 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
520 return( ret );
521
522 /* Extract r */
523 if( ( ret = extract_ecdsa_sig_int( p, end, sig, int_size ) ) != 0 )
524 return( ret );
525 /* Extract s */
526 if( ( ret = extract_ecdsa_sig_int( p, end, sig + int_size, int_size ) ) != 0 )
527 return( ret );
528
529 return( 0 );
530}
531
Hanno Beckeradf11e12019-08-21 13:03:44 +0100532static size_t uecc_eckey_get_bitlen( const void *ctx )
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300533{
534 (void) ctx;
Hanno Becker9a62f2d2019-08-20 14:57:37 +0100535 return( (size_t) ( NUM_ECC_BYTES * 8 ) );
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300536}
537
Hanno Beckeradf11e12019-08-21 13:03:44 +0100538static int uecc_eckey_can_do( mbedtls_pk_type_t type )
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300539{
Hanno Beckeradf11e12019-08-21 13:03:44 +0100540 return( type == MBEDTLS_PK_ECDSA ||
541 type == MBEDTLS_PK_ECKEY );
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300542}
543
Hanno Beckeradf11e12019-08-21 13:03:44 +0100544static int uecc_eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300545 const unsigned char *hash, size_t hash_len,
546 const unsigned char *sig, size_t sig_len )
547{
548 int ret;
549 uint8_t signature[2*NUM_ECC_BYTES];
550 unsigned char *p;
551 const struct uECC_Curve_t * uecc_curve = uECC_secp256r1();
Hanno Becker8ea35452019-08-20 15:39:13 +0100552 const mbedtls_uecc_keypair *keypair = (const mbedtls_uecc_keypair *) ctx;
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300553
554 ((void) md_alg);
555 p = (unsigned char*) sig;
556
Hanno Beckerad353f22019-08-20 13:04:30 +0100557 ret = extract_ecdsa_sig( &p, sig + sig_len, signature, NUM_ECC_BYTES );
558 if( ret != 0 )
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300559 return( ret );
560
Hanno Becker8ea35452019-08-20 15:39:13 +0100561 ret = uECC_verify( keypair->public_key, hash,
Hanno Beckerad353f22019-08-20 13:04:30 +0100562 (unsigned) hash_len, signature, uecc_curve );
Hanno Becker8ea35452019-08-20 15:39:13 +0100563 if( ret == 0 )
564 return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300565
Hanno Becker8ea35452019-08-20 15:39:13 +0100566 return( 0 );
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300567}
568
569/*
570 * Simultaneously convert and move raw MPI from the beginning of a buffer
571 * to an ASN.1 MPI at the end of the buffer.
572 * See also mbedtls_asn1_write_mpi().
573 *
574 * p: pointer to the end of the output buffer
575 * start: start of the output buffer, and also of the mpi to write at the end
576 * n_len: length of the mpi to read from start
577 */
578static int asn1_write_mpibuf( unsigned char **p, unsigned char *start,
579 size_t n_len )
580{
581 int ret;
582 size_t len = 0;
583
584 if( (size_t)( *p - start ) < n_len )
585 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
586
587 len = n_len;
588 *p -= len;
589 memmove( *p, start, len );
590
591 /* ASN.1 DER encoding requires minimal length, so skip leading 0s.
592 * Neither r nor s should be 0, but as a failsafe measure, still detect
Hanno Beckere8f14482019-08-20 13:28:59 +0100593 * that rather than overflowing the buffer in case of an error. */
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300594 while( len > 0 && **p == 0x00 )
595 {
596 ++(*p);
597 --len;
598 }
599
600 /* this is only reached if the signature was invalid */
601 if( len == 0 )
602 return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
603
604 /* if the msb is 1, ASN.1 requires that we prepend a 0.
605 * Neither r nor s can be 0, so we can assume len > 0 at all times. */
606 if( **p & 0x80 )
607 {
608 if( *p - start < 1 )
609 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
610
611 *--(*p) = 0x00;
612 len += 1;
613 }
614
615 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
616 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
617 MBEDTLS_ASN1_INTEGER ) );
618
619 return( (int) len );
620}
621
Jarno Lamsaad789312019-04-23 09:15:54 +0300622/* Transcode signature from uECC format to ASN.1 sequence.
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300623 * See ecdsa_signature_to_asn1 in ecdsa.c, but with byte buffers instead of
624 * MPIs, and in-place.
625 *
626 * [in/out] sig: the signature pre- and post-transcoding
627 * [in/out] sig_len: signature length pre- and post-transcoding
628 * [int] buf_len: the available size the in/out buffer
629 */
Hanno Beckere8f14482019-08-20 13:28:59 +0100630static int pk_ecdsa_sig_asn1_from_uecc( unsigned char *sig, size_t *sig_len,
631 size_t buf_len )
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300632{
633 int ret;
634 size_t len = 0;
635 const size_t rs_len = *sig_len / 2;
636 unsigned char *p = sig + buf_len;
637
638 MBEDTLS_ASN1_CHK_ADD( len, asn1_write_mpibuf( &p, sig + rs_len, rs_len ) );
639 MBEDTLS_ASN1_CHK_ADD( len, asn1_write_mpibuf( &p, sig, rs_len ) );
640
641 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &p, sig, len ) );
642 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, sig,
643 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
644
645 memmove( sig, p, len );
646 *sig_len = len;
647
648 return( 0 );
649}
650
Hanno Beckeradf11e12019-08-21 13:03:44 +0100651static int uecc_eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300652 const unsigned char *hash, size_t hash_len,
653 unsigned char *sig, size_t *sig_len,
654 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
655{
Jarno Lamsaad789312019-04-23 09:15:54 +0300656 const mbedtls_uecc_keypair *keypair = (const mbedtls_uecc_keypair *) ctx;
657 const struct uECC_Curve_t * uecc_curve = uECC_secp256r1();
Hanno Becker9c7a3592019-08-20 15:37:17 +0100658
659 /*
660 * RFC-4492 page 20:
661 *
662 * Ecdsa-Sig-Value ::= SEQUENCE {
663 * r INTEGER,
664 * s INTEGER
665 * }
666 *
667 * Size is at most
668 * 1 (tag) + 1 (len) + 1 (initial 0) + NUM_ECC_BYTES for each of r and s,
669 * twice that + 1 (tag) + 2 (len) for the sequence
670 * (assuming NUM_ECC_BYTES is less than 126 for r and s,
671 * and less than 124 (total len <= 255) for the sequence)
672 */
673 const size_t max_secp256r1_ecdsa_sig_len = 3 + 2 * ( 3 + NUM_ECC_BYTES );
674
675 uECC_sign( keypair->private_key, hash, hash_len, sig, uecc_curve );
676 *sig_len = 2 * NUM_ECC_BYTES;
Jarno Lamsaad789312019-04-23 09:15:54 +0300677
678 /* uECC owns its rng function pointer */
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300679 (void) f_rng;
680 (void) p_rng;
Jarno Lamsaad789312019-04-23 09:15:54 +0300681 (void) md_alg;
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300682
Hanno Becker9c7a3592019-08-20 15:37:17 +0100683 return( pk_ecdsa_sig_asn1_from_uecc( sig, sig_len, max_secp256r1_ecdsa_sig_len ) );
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300684}
685
Hanno Beckeradf11e12019-08-21 13:03:44 +0100686static void *uecc_eckey_alloc_wrap( void )
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300687{
Hanno Becker41029722019-08-20 13:18:56 +0100688 return( mbedtls_calloc( 1, sizeof( mbedtls_uecc_keypair ) ) );
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300689}
690
Hanno Beckeradf11e12019-08-21 13:03:44 +0100691static void uecc_eckey_free_wrap( void *ctx )
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300692{
Hanno Becker41029722019-08-20 13:18:56 +0100693 if( ctx == NULL )
694 return;
695
696 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_uecc_keypair ) );
697 mbedtls_free( ctx );
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300698}
699
Hanno Beckeradf11e12019-08-21 13:03:44 +0100700const mbedtls_pk_info_t mbedtls_uecc_eckey_info = {
701 MBEDTLS_PK_ECKEY,
702 "EC",
703 uecc_eckey_get_bitlen,
704 uecc_eckey_can_do,
705 uecc_eckey_verify_wrap,
706 uecc_eckey_sign_wrap,
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300707 NULL,
708 NULL,
709 NULL,
Hanno Beckeradf11e12019-08-21 13:03:44 +0100710 uecc_eckey_alloc_wrap,
711 uecc_eckey_free_wrap,
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300712 NULL,
713};
Hanno Becker11cb2632019-09-02 11:55:45 +0100714#endif /* MBEDTLS_USE_TINYCRYPT */
715
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200716#if defined(MBEDTLS_ECDSA_C)
717static int ecdsa_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200718{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200719 return( type == MBEDTLS_PK_ECDSA );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200720}
721
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200722static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200723 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200724 const unsigned char *sig, size_t sig_len )
725{
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200726 int ret;
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200727 ((void) md_alg);
728
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200729 ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx,
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200730 hash, hash_len, sig, sig_len );
731
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200732 if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )
733 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200734
735 return( ret );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200736}
737
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200738static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200739 const unsigned char *hash, size_t hash_len,
740 unsigned char *sig, size_t *sig_len,
741 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
742{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200743 return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx,
Manuel Pégourié-Gonnarddfdcac92015-03-31 11:41:42 +0200744 md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200745}
746
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200747#if defined(MBEDTLS_ECP_RESTARTABLE)
748static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
749 const unsigned char *hash, size_t hash_len,
750 const unsigned char *sig, size_t sig_len,
751 void *rs_ctx )
752{
753 int ret;
754 ((void) md_alg);
755
756 ret = mbedtls_ecdsa_read_signature_restartable(
757 (mbedtls_ecdsa_context *) ctx,
758 hash, hash_len, sig, sig_len,
759 (mbedtls_ecdsa_restart_ctx *) rs_ctx );
760
761 if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )
762 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
763
764 return( ret );
765}
766
767static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
768 const unsigned char *hash, size_t hash_len,
769 unsigned char *sig, size_t *sig_len,
770 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
771 void *rs_ctx )
772{
773 return( mbedtls_ecdsa_write_signature_restartable(
774 (mbedtls_ecdsa_context *) ctx,
775 md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng,
776 (mbedtls_ecdsa_restart_ctx *) rs_ctx ) );
777
778}
779#endif /* MBEDTLS_ECP_RESTARTABLE */
780
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200781static void *ecdsa_alloc_wrap( void )
782{
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200783 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200784
785 if( ctx != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200786 mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200787
788 return( ctx );
789}
790
791static void ecdsa_free_wrap( void *ctx )
792{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200793 mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx );
794 mbedtls_free( ctx );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200795}
796
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200797#if defined(MBEDTLS_ECP_RESTARTABLE)
798static void *ecdsa_rs_alloc( void )
799{
800 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_restart_ctx ) );
801
802 if( ctx != NULL )
803 mbedtls_ecdsa_restart_init( ctx );
804
805 return( ctx );
806}
807
808static void ecdsa_rs_free( void *ctx )
809{
810 mbedtls_ecdsa_restart_free( ctx );
811 mbedtls_free( ctx );
812}
813#endif /* MBEDTLS_ECP_RESTARTABLE */
814
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200815const mbedtls_pk_info_t mbedtls_ecdsa_info = {
816 MBEDTLS_PK_ECDSA,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200817 "ECDSA",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200818 eckey_get_bitlen, /* Compatible key structures */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200819 ecdsa_can_do,
820 ecdsa_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200821 ecdsa_sign_wrap,
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200822#if defined(MBEDTLS_ECP_RESTARTABLE)
823 ecdsa_verify_rs_wrap,
824 ecdsa_sign_rs_wrap,
825#endif
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200826 NULL,
827 NULL,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100828 eckey_check_pair, /* Compatible key structures */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200829 ecdsa_alloc_wrap,
830 ecdsa_free_wrap,
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200831#if defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200832 ecdsa_rs_alloc,
833 ecdsa_rs_free,
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200834#endif
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200835 eckey_debug, /* Compatible key structures */
836};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200837#endif /* MBEDTLS_ECDSA_C */
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200838
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200839#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200840/*
841 * Support for alternative RSA-private implementations
842 */
843
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200844static int rsa_alt_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200845{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200846 return( type == MBEDTLS_PK_RSA );
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200847}
848
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200849static size_t rsa_alt_get_bitlen( const void *ctx )
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200850{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200851 const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200852
Manuel Pégourié-Gonnard01488752014-04-03 22:09:18 +0200853 return( 8 * rsa_alt->key_len_func( rsa_alt->key ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200854}
855
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200856static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200857 const unsigned char *hash, size_t hash_len,
858 unsigned char *sig, size_t *sig_len,
859 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
860{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200861 mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200862
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100863#if SIZE_MAX > UINT_MAX
Andres AG72849872017-01-19 11:24:33 +0000864 if( UINT_MAX < hash_len )
865 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100866#endif /* SIZE_MAX > UINT_MAX */
Andres AG72849872017-01-19 11:24:33 +0000867
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200868 *sig_len = rsa_alt->key_len_func( rsa_alt->key );
869
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200870 return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200871 md_alg, (unsigned int) hash_len, hash, sig ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200872}
873
874static int rsa_alt_decrypt_wrap( void *ctx,
875 const unsigned char *input, size_t ilen,
876 unsigned char *output, size_t *olen, size_t osize,
877 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
878{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200879 mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200880
881 ((void) f_rng);
882 ((void) p_rng);
883
884 if( ilen != rsa_alt->key_len_func( rsa_alt->key ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200885 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200886
887 return( rsa_alt->decrypt_func( rsa_alt->key,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200888 MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200889}
890
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200891#if defined(MBEDTLS_RSA_C)
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100892static int rsa_alt_check_pair( const void *pub, const void *prv )
893{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200894 unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100895 unsigned char hash[32];
896 size_t sig_len = 0;
897 int ret;
898
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200899 if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200900 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100901
902 memset( hash, 0x2a, sizeof( hash ) );
903
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200904 if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE,
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100905 hash, sizeof( hash ),
906 sig, &sig_len, NULL, NULL ) ) != 0 )
907 {
908 return( ret );
909 }
910
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200911 if( rsa_verify_wrap( (void *) pub, MBEDTLS_MD_NONE,
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100912 hash, sizeof( hash ), sig, sig_len ) != 0 )
913 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200914 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100915 }
916
917 return( 0 );
918}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200919#endif /* MBEDTLS_RSA_C */
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100920
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200921static void *rsa_alt_alloc_wrap( void )
922{
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200923 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200924
925 if( ctx != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200926 memset( ctx, 0, sizeof( mbedtls_rsa_alt_context ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200927
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200928 return( ctx );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200929}
930
931static void rsa_alt_free_wrap( void *ctx )
932{
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500933 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200934 mbedtls_free( ctx );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200935}
936
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200937const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
938 MBEDTLS_PK_RSA_ALT,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200939 "RSA-alt",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200940 rsa_alt_get_bitlen,
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200941 rsa_alt_can_do,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200942 NULL,
943 rsa_alt_sign_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200944#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200945 NULL,
946 NULL,
947#endif
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200948 rsa_alt_decrypt_wrap,
949 NULL,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200950#if defined(MBEDTLS_RSA_C)
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100951 rsa_alt_check_pair,
Manuel Pégourié-Gonnard7c13d692014-11-12 00:01:34 +0100952#else
953 NULL,
954#endif
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200955 rsa_alt_alloc_wrap,
956 rsa_alt_free_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200957#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200958 NULL,
959 NULL,
960#endif
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200961 NULL,
962};
Manuel Pégourié-Gonnardc40b4c32013-08-22 13:29:31 +0200963
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200964#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
Manuel Pégourié-Gonnard348bcb32015-03-31 14:01:33 +0200965
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200966#endif /* MBEDTLS_PK_C */