blob: 78318cb998901d5ff18c7e8086f0a1f0b39521fb [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
599 */
600static int asn1_write_mpibuf( unsigned char **p, unsigned char *start,
601 size_t n_len )
602{
603 int ret;
604 size_t len = 0;
605
606 if( (size_t)( *p - start ) < n_len )
607 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
608
609 len = n_len;
610 *p -= len;
611 memmove( *p, start, len );
612
613 /* ASN.1 DER encoding requires minimal length, so skip leading 0s.
614 * Neither r nor s should be 0, but as a failsafe measure, still detect
Hanno Beckere8f14482019-08-20 13:28:59 +0100615 * that rather than overflowing the buffer in case of an error. */
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300616 while( len > 0 && **p == 0x00 )
617 {
618 ++(*p);
619 --len;
620 }
621
622 /* this is only reached if the signature was invalid */
623 if( len == 0 )
624 return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
625
626 /* if the msb is 1, ASN.1 requires that we prepend a 0.
627 * Neither r nor s can be 0, so we can assume len > 0 at all times. */
628 if( **p & 0x80 )
629 {
630 if( *p - start < 1 )
631 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
632
633 *--(*p) = 0x00;
634 len += 1;
635 }
636
637 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
638 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
639 MBEDTLS_ASN1_INTEGER ) );
640
641 return( (int) len );
642}
643
Jarno Lamsaad789312019-04-23 09:15:54 +0300644/* Transcode signature from uECC format to ASN.1 sequence.
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300645 * See ecdsa_signature_to_asn1 in ecdsa.c, but with byte buffers instead of
646 * MPIs, and in-place.
647 *
648 * [in/out] sig: the signature pre- and post-transcoding
649 * [in/out] sig_len: signature length pre- and post-transcoding
650 * [int] buf_len: the available size the in/out buffer
651 */
Hanno Beckere8f14482019-08-20 13:28:59 +0100652static int pk_ecdsa_sig_asn1_from_uecc( unsigned char *sig, size_t *sig_len,
653 size_t buf_len )
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300654{
655 int ret;
656 size_t len = 0;
657 const size_t rs_len = *sig_len / 2;
658 unsigned char *p = sig + buf_len;
659
660 MBEDTLS_ASN1_CHK_ADD( len, asn1_write_mpibuf( &p, sig + rs_len, rs_len ) );
661 MBEDTLS_ASN1_CHK_ADD( len, asn1_write_mpibuf( &p, sig, rs_len ) );
662
663 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &p, sig, len ) );
664 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, sig,
665 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
666
667 memmove( sig, p, len );
668 *sig_len = len;
669
670 return( 0 );
671}
672
Hanno Beckeradf11e12019-08-21 13:03:44 +0100673static int uecc_eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300674 const unsigned char *hash, size_t hash_len,
675 unsigned char *sig, size_t *sig_len,
676 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
677{
Jarno Lamsaad789312019-04-23 09:15:54 +0300678 const mbedtls_uecc_keypair *keypair = (const mbedtls_uecc_keypair *) ctx;
679 const struct uECC_Curve_t * uecc_curve = uECC_secp256r1();
Hanno Becker9c7a3592019-08-20 15:37:17 +0100680
681 /*
682 * RFC-4492 page 20:
683 *
684 * Ecdsa-Sig-Value ::= SEQUENCE {
685 * r INTEGER,
686 * s INTEGER
687 * }
688 *
689 * Size is at most
690 * 1 (tag) + 1 (len) + 1 (initial 0) + NUM_ECC_BYTES for each of r and s,
691 * twice that + 1 (tag) + 2 (len) for the sequence
692 * (assuming NUM_ECC_BYTES is less than 126 for r and s,
693 * and less than 124 (total len <= 255) for the sequence)
694 */
695 const size_t max_secp256r1_ecdsa_sig_len = 3 + 2 * ( 3 + NUM_ECC_BYTES );
696
697 uECC_sign( keypair->private_key, hash, hash_len, sig, uecc_curve );
698 *sig_len = 2 * NUM_ECC_BYTES;
Jarno Lamsaad789312019-04-23 09:15:54 +0300699
700 /* uECC owns its rng function pointer */
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300701 (void) f_rng;
702 (void) p_rng;
Jarno Lamsaad789312019-04-23 09:15:54 +0300703 (void) md_alg;
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300704
Hanno Becker9c7a3592019-08-20 15:37:17 +0100705 return( pk_ecdsa_sig_asn1_from_uecc( sig, sig_len, max_secp256r1_ecdsa_sig_len ) );
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300706}
707
Hanno Beckeradf11e12019-08-21 13:03:44 +0100708static void *uecc_eckey_alloc_wrap( void )
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300709{
Hanno Becker41029722019-08-20 13:18:56 +0100710 return( mbedtls_calloc( 1, sizeof( mbedtls_uecc_keypair ) ) );
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300711}
712
Hanno Beckeradf11e12019-08-21 13:03:44 +0100713static void uecc_eckey_free_wrap( void *ctx )
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300714{
Hanno Becker41029722019-08-20 13:18:56 +0100715 if( ctx == NULL )
716 return;
717
718 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_uecc_keypair ) );
719 mbedtls_free( ctx );
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300720}
721
Hanno Beckeradf11e12019-08-21 13:03:44 +0100722const mbedtls_pk_info_t mbedtls_uecc_eckey_info = {
723 MBEDTLS_PK_ECKEY,
724 "EC",
725 uecc_eckey_get_bitlen,
726 uecc_eckey_can_do,
727 uecc_eckey_verify_wrap,
728 uecc_eckey_sign_wrap,
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300729 NULL,
730 NULL,
Hanno Becker9653d802019-08-21 13:49:13 +0100731 uecc_eckey_check_pair,
Hanno Beckeradf11e12019-08-21 13:03:44 +0100732 uecc_eckey_alloc_wrap,
733 uecc_eckey_free_wrap,
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300734 NULL,
735};
Hanno Becker11cb2632019-09-02 11:55:45 +0100736#endif /* MBEDTLS_USE_TINYCRYPT */
737
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200738#if defined(MBEDTLS_ECDSA_C)
739static int ecdsa_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200740{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200741 return( type == MBEDTLS_PK_ECDSA );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200742}
743
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200744static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200745 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200746 const unsigned char *sig, size_t sig_len )
747{
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200748 int ret;
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200749 ((void) md_alg);
750
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200751 ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx,
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200752 hash, hash_len, sig, sig_len );
753
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200754 if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )
755 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200756
757 return( ret );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200758}
759
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200760static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200761 const unsigned char *hash, size_t hash_len,
762 unsigned char *sig, size_t *sig_len,
763 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
764{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200765 return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx,
Manuel Pégourié-Gonnarddfdcac92015-03-31 11:41:42 +0200766 md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200767}
768
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200769#if defined(MBEDTLS_ECP_RESTARTABLE)
770static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
771 const unsigned char *hash, size_t hash_len,
772 const unsigned char *sig, size_t sig_len,
773 void *rs_ctx )
774{
775 int ret;
776 ((void) md_alg);
777
778 ret = mbedtls_ecdsa_read_signature_restartable(
779 (mbedtls_ecdsa_context *) ctx,
780 hash, hash_len, sig, sig_len,
781 (mbedtls_ecdsa_restart_ctx *) rs_ctx );
782
783 if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )
784 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
785
786 return( ret );
787}
788
789static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
790 const unsigned char *hash, size_t hash_len,
791 unsigned char *sig, size_t *sig_len,
792 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
793 void *rs_ctx )
794{
795 return( mbedtls_ecdsa_write_signature_restartable(
796 (mbedtls_ecdsa_context *) ctx,
797 md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng,
798 (mbedtls_ecdsa_restart_ctx *) rs_ctx ) );
799
800}
801#endif /* MBEDTLS_ECP_RESTARTABLE */
802
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200803static void *ecdsa_alloc_wrap( void )
804{
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200805 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200806
807 if( ctx != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200808 mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200809
810 return( ctx );
811}
812
813static void ecdsa_free_wrap( void *ctx )
814{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200815 mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx );
816 mbedtls_free( ctx );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200817}
818
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200819#if defined(MBEDTLS_ECP_RESTARTABLE)
820static void *ecdsa_rs_alloc( void )
821{
822 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_restart_ctx ) );
823
824 if( ctx != NULL )
825 mbedtls_ecdsa_restart_init( ctx );
826
827 return( ctx );
828}
829
830static void ecdsa_rs_free( void *ctx )
831{
832 mbedtls_ecdsa_restart_free( ctx );
833 mbedtls_free( ctx );
834}
835#endif /* MBEDTLS_ECP_RESTARTABLE */
836
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200837const mbedtls_pk_info_t mbedtls_ecdsa_info = {
838 MBEDTLS_PK_ECDSA,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200839 "ECDSA",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200840 eckey_get_bitlen, /* Compatible key structures */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200841 ecdsa_can_do,
842 ecdsa_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200843 ecdsa_sign_wrap,
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200844#if defined(MBEDTLS_ECP_RESTARTABLE)
845 ecdsa_verify_rs_wrap,
846 ecdsa_sign_rs_wrap,
847#endif
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200848 NULL,
849 NULL,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100850 eckey_check_pair, /* Compatible key structures */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200851 ecdsa_alloc_wrap,
852 ecdsa_free_wrap,
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200853#if defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200854 ecdsa_rs_alloc,
855 ecdsa_rs_free,
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200856#endif
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200857 eckey_debug, /* Compatible key structures */
858};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200859#endif /* MBEDTLS_ECDSA_C */
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200860
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200861#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200862/*
863 * Support for alternative RSA-private implementations
864 */
865
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200866static int rsa_alt_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200867{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200868 return( type == MBEDTLS_PK_RSA );
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200869}
870
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200871static size_t rsa_alt_get_bitlen( const void *ctx )
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200872{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200873 const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200874
Manuel Pégourié-Gonnard01488752014-04-03 22:09:18 +0200875 return( 8 * rsa_alt->key_len_func( rsa_alt->key ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200876}
877
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200878static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200879 const unsigned char *hash, size_t hash_len,
880 unsigned char *sig, size_t *sig_len,
881 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
882{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200883 mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200884
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100885#if SIZE_MAX > UINT_MAX
Andres AG72849872017-01-19 11:24:33 +0000886 if( UINT_MAX < hash_len )
887 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100888#endif /* SIZE_MAX > UINT_MAX */
Andres AG72849872017-01-19 11:24:33 +0000889
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200890 *sig_len = rsa_alt->key_len_func( rsa_alt->key );
891
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200892 return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200893 md_alg, (unsigned int) hash_len, hash, sig ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200894}
895
896static int rsa_alt_decrypt_wrap( void *ctx,
897 const unsigned char *input, size_t ilen,
898 unsigned char *output, size_t *olen, size_t osize,
899 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
900{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200901 mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200902
903 ((void) f_rng);
904 ((void) p_rng);
905
906 if( ilen != rsa_alt->key_len_func( rsa_alt->key ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200907 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200908
909 return( rsa_alt->decrypt_func( rsa_alt->key,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200910 MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200911}
912
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200913#if defined(MBEDTLS_RSA_C)
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100914static int rsa_alt_check_pair( const void *pub, const void *prv )
915{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200916 unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100917 unsigned char hash[32];
918 size_t sig_len = 0;
919 int ret;
920
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200921 if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200922 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100923
924 memset( hash, 0x2a, sizeof( hash ) );
925
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200926 if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE,
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100927 hash, sizeof( hash ),
928 sig, &sig_len, NULL, NULL ) ) != 0 )
929 {
930 return( ret );
931 }
932
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200933 if( rsa_verify_wrap( (void *) pub, MBEDTLS_MD_NONE,
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100934 hash, sizeof( hash ), sig, sig_len ) != 0 )
935 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200936 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100937 }
938
939 return( 0 );
940}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200941#endif /* MBEDTLS_RSA_C */
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100942
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200943static void *rsa_alt_alloc_wrap( void )
944{
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200945 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200946
947 if( ctx != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200948 memset( ctx, 0, sizeof( mbedtls_rsa_alt_context ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200949
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200950 return( ctx );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200951}
952
953static void rsa_alt_free_wrap( void *ctx )
954{
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500955 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200956 mbedtls_free( ctx );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200957}
958
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200959const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
960 MBEDTLS_PK_RSA_ALT,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200961 "RSA-alt",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200962 rsa_alt_get_bitlen,
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200963 rsa_alt_can_do,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200964 NULL,
965 rsa_alt_sign_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200966#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200967 NULL,
968 NULL,
969#endif
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200970 rsa_alt_decrypt_wrap,
971 NULL,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200972#if defined(MBEDTLS_RSA_C)
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100973 rsa_alt_check_pair,
Manuel Pégourié-Gonnard7c13d692014-11-12 00:01:34 +0100974#else
975 NULL,
976#endif
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200977 rsa_alt_alloc_wrap,
978 rsa_alt_free_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200979#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200980 NULL,
981 NULL,
982#endif
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200983 NULL,
984};
Manuel Pégourié-Gonnardc40b4c32013-08-22 13:29:31 +0200985
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200986#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
Manuel Pégourié-Gonnard348bcb32015-03-31 14:01:33 +0200987
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200988#endif /* MBEDTLS_PK_C */