blob: 78cee744ad326aec6cc7ced068ed7d3e311e174c [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 Becker9653d802019-08-21 13:49:13 +0100538static int uecc_eckey_check_pair( const void *pub, const void *prv )
539{
540 const mbedtls_uecc_keypair *uecc_pub =
541 (const mbedtls_uecc_keypair *) pub;
542 const mbedtls_uecc_keypair *uecc_prv =
543 (const mbedtls_uecc_keypair *) prv;
544
545 if( memcmp( uecc_pub->public_key,
546 uecc_prv->public_key,
547 2 * NUM_ECC_BYTES ) == 0 )
548 {
549 return( 0 );
550 }
551
552 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
553}
554
Hanno Beckeradf11e12019-08-21 13:03:44 +0100555static int uecc_eckey_can_do( mbedtls_pk_type_t type )
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300556{
Hanno Beckeradf11e12019-08-21 13:03:44 +0100557 return( type == MBEDTLS_PK_ECDSA ||
558 type == MBEDTLS_PK_ECKEY );
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300559}
560
Hanno Beckeradf11e12019-08-21 13:03:44 +0100561static int uecc_eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300562 const unsigned char *hash, size_t hash_len,
563 const unsigned char *sig, size_t sig_len )
564{
565 int ret;
566 uint8_t signature[2*NUM_ECC_BYTES];
567 unsigned char *p;
568 const struct uECC_Curve_t * uecc_curve = uECC_secp256r1();
Hanno Becker8ea35452019-08-20 15:39:13 +0100569 const mbedtls_uecc_keypair *keypair = (const mbedtls_uecc_keypair *) ctx;
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300570
571 ((void) md_alg);
572 p = (unsigned char*) sig;
573
Hanno Beckerad353f22019-08-20 13:04:30 +0100574 ret = extract_ecdsa_sig( &p, sig + sig_len, signature, NUM_ECC_BYTES );
575 if( ret != 0 )
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300576 return( ret );
577
Hanno Becker8ea35452019-08-20 15:39:13 +0100578 ret = uECC_verify( keypair->public_key, hash,
Hanno Beckerad353f22019-08-20 13:04:30 +0100579 (unsigned) hash_len, signature, uecc_curve );
Hanno Becker8ea35452019-08-20 15:39:13 +0100580 if( ret == 0 )
581 return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300582
Hanno Becker8ea35452019-08-20 15:39:13 +0100583 return( 0 );
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300584}
585
586/*
587 * Simultaneously convert and move raw MPI from the beginning of a buffer
588 * to an ASN.1 MPI at the end of the buffer.
589 * See also mbedtls_asn1_write_mpi().
590 *
591 * p: pointer to the end of the output buffer
592 * start: start of the output buffer, and also of the mpi to write at the end
593 * n_len: length of the mpi to read from start
594 */
595static int asn1_write_mpibuf( unsigned char **p, unsigned char *start,
596 size_t n_len )
597{
598 int ret;
599 size_t len = 0;
600
601 if( (size_t)( *p - start ) < n_len )
602 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
603
604 len = n_len;
605 *p -= len;
606 memmove( *p, start, len );
607
608 /* ASN.1 DER encoding requires minimal length, so skip leading 0s.
609 * Neither r nor s should be 0, but as a failsafe measure, still detect
Hanno Beckere8f14482019-08-20 13:28:59 +0100610 * that rather than overflowing the buffer in case of an error. */
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300611 while( len > 0 && **p == 0x00 )
612 {
613 ++(*p);
614 --len;
615 }
616
617 /* this is only reached if the signature was invalid */
618 if( len == 0 )
619 return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
620
621 /* if the msb is 1, ASN.1 requires that we prepend a 0.
622 * Neither r nor s can be 0, so we can assume len > 0 at all times. */
623 if( **p & 0x80 )
624 {
625 if( *p - start < 1 )
626 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
627
628 *--(*p) = 0x00;
629 len += 1;
630 }
631
632 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
633 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
634 MBEDTLS_ASN1_INTEGER ) );
635
636 return( (int) len );
637}
638
Jarno Lamsaad789312019-04-23 09:15:54 +0300639/* Transcode signature from uECC format to ASN.1 sequence.
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300640 * See ecdsa_signature_to_asn1 in ecdsa.c, but with byte buffers instead of
641 * MPIs, and in-place.
642 *
643 * [in/out] sig: the signature pre- and post-transcoding
644 * [in/out] sig_len: signature length pre- and post-transcoding
645 * [int] buf_len: the available size the in/out buffer
646 */
Hanno Beckere8f14482019-08-20 13:28:59 +0100647static int pk_ecdsa_sig_asn1_from_uecc( unsigned char *sig, size_t *sig_len,
648 size_t buf_len )
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300649{
650 int ret;
651 size_t len = 0;
652 const size_t rs_len = *sig_len / 2;
653 unsigned char *p = sig + buf_len;
654
655 MBEDTLS_ASN1_CHK_ADD( len, asn1_write_mpibuf( &p, sig + rs_len, rs_len ) );
656 MBEDTLS_ASN1_CHK_ADD( len, asn1_write_mpibuf( &p, sig, rs_len ) );
657
658 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &p, sig, len ) );
659 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, sig,
660 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
661
662 memmove( sig, p, len );
663 *sig_len = len;
664
665 return( 0 );
666}
667
Hanno Beckeradf11e12019-08-21 13:03:44 +0100668static int uecc_eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300669 const unsigned char *hash, size_t hash_len,
670 unsigned char *sig, size_t *sig_len,
671 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
672{
Jarno Lamsaad789312019-04-23 09:15:54 +0300673 const mbedtls_uecc_keypair *keypair = (const mbedtls_uecc_keypair *) ctx;
674 const struct uECC_Curve_t * uecc_curve = uECC_secp256r1();
Hanno Becker9c7a3592019-08-20 15:37:17 +0100675
676 /*
677 * RFC-4492 page 20:
678 *
679 * Ecdsa-Sig-Value ::= SEQUENCE {
680 * r INTEGER,
681 * s INTEGER
682 * }
683 *
684 * Size is at most
685 * 1 (tag) + 1 (len) + 1 (initial 0) + NUM_ECC_BYTES for each of r and s,
686 * twice that + 1 (tag) + 2 (len) for the sequence
687 * (assuming NUM_ECC_BYTES is less than 126 for r and s,
688 * and less than 124 (total len <= 255) for the sequence)
689 */
690 const size_t max_secp256r1_ecdsa_sig_len = 3 + 2 * ( 3 + NUM_ECC_BYTES );
691
692 uECC_sign( keypair->private_key, hash, hash_len, sig, uecc_curve );
693 *sig_len = 2 * NUM_ECC_BYTES;
Jarno Lamsaad789312019-04-23 09:15:54 +0300694
695 /* uECC owns its rng function pointer */
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300696 (void) f_rng;
697 (void) p_rng;
Jarno Lamsaad789312019-04-23 09:15:54 +0300698 (void) md_alg;
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300699
Hanno Becker9c7a3592019-08-20 15:37:17 +0100700 return( pk_ecdsa_sig_asn1_from_uecc( sig, sig_len, max_secp256r1_ecdsa_sig_len ) );
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300701}
702
Hanno Beckeradf11e12019-08-21 13:03:44 +0100703static void *uecc_eckey_alloc_wrap( void )
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300704{
Hanno Becker41029722019-08-20 13:18:56 +0100705 return( mbedtls_calloc( 1, sizeof( mbedtls_uecc_keypair ) ) );
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300706}
707
Hanno Beckeradf11e12019-08-21 13:03:44 +0100708static void uecc_eckey_free_wrap( void *ctx )
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300709{
Hanno Becker41029722019-08-20 13:18:56 +0100710 if( ctx == NULL )
711 return;
712
713 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_uecc_keypair ) );
714 mbedtls_free( ctx );
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300715}
716
Hanno Beckeradf11e12019-08-21 13:03:44 +0100717const mbedtls_pk_info_t mbedtls_uecc_eckey_info = {
718 MBEDTLS_PK_ECKEY,
719 "EC",
720 uecc_eckey_get_bitlen,
721 uecc_eckey_can_do,
722 uecc_eckey_verify_wrap,
723 uecc_eckey_sign_wrap,
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300724 NULL,
725 NULL,
Hanno Becker9653d802019-08-21 13:49:13 +0100726 uecc_eckey_check_pair,
Hanno Beckeradf11e12019-08-21 13:03:44 +0100727 uecc_eckey_alloc_wrap,
728 uecc_eckey_free_wrap,
Jarno Lamsa42b83db2019-04-16 16:48:22 +0300729 NULL,
730};
Hanno Becker11cb2632019-09-02 11:55:45 +0100731#endif /* MBEDTLS_USE_TINYCRYPT */
732
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200733#if defined(MBEDTLS_ECDSA_C)
734static int ecdsa_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200735{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200736 return( type == MBEDTLS_PK_ECDSA );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200737}
738
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200739static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200740 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200741 const unsigned char *sig, size_t sig_len )
742{
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200743 int ret;
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200744 ((void) md_alg);
745
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200746 ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx,
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200747 hash, hash_len, sig, sig_len );
748
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200749 if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )
750 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200751
752 return( ret );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200753}
754
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200755static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200756 const unsigned char *hash, size_t hash_len,
757 unsigned char *sig, size_t *sig_len,
758 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
759{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200760 return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx,
Manuel Pégourié-Gonnarddfdcac92015-03-31 11:41:42 +0200761 md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200762}
763
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200764#if defined(MBEDTLS_ECP_RESTARTABLE)
765static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
766 const unsigned char *hash, size_t hash_len,
767 const unsigned char *sig, size_t sig_len,
768 void *rs_ctx )
769{
770 int ret;
771 ((void) md_alg);
772
773 ret = mbedtls_ecdsa_read_signature_restartable(
774 (mbedtls_ecdsa_context *) ctx,
775 hash, hash_len, sig, sig_len,
776 (mbedtls_ecdsa_restart_ctx *) rs_ctx );
777
778 if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )
779 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
780
781 return( ret );
782}
783
784static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
785 const unsigned char *hash, size_t hash_len,
786 unsigned char *sig, size_t *sig_len,
787 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
788 void *rs_ctx )
789{
790 return( mbedtls_ecdsa_write_signature_restartable(
791 (mbedtls_ecdsa_context *) ctx,
792 md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng,
793 (mbedtls_ecdsa_restart_ctx *) rs_ctx ) );
794
795}
796#endif /* MBEDTLS_ECP_RESTARTABLE */
797
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200798static void *ecdsa_alloc_wrap( void )
799{
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200800 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200801
802 if( ctx != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200803 mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200804
805 return( ctx );
806}
807
808static void ecdsa_free_wrap( void *ctx )
809{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200810 mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx );
811 mbedtls_free( ctx );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200812}
813
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200814#if defined(MBEDTLS_ECP_RESTARTABLE)
815static void *ecdsa_rs_alloc( void )
816{
817 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_restart_ctx ) );
818
819 if( ctx != NULL )
820 mbedtls_ecdsa_restart_init( ctx );
821
822 return( ctx );
823}
824
825static void ecdsa_rs_free( void *ctx )
826{
827 mbedtls_ecdsa_restart_free( ctx );
828 mbedtls_free( ctx );
829}
830#endif /* MBEDTLS_ECP_RESTARTABLE */
831
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200832const mbedtls_pk_info_t mbedtls_ecdsa_info = {
833 MBEDTLS_PK_ECDSA,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200834 "ECDSA",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200835 eckey_get_bitlen, /* Compatible key structures */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200836 ecdsa_can_do,
837 ecdsa_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200838 ecdsa_sign_wrap,
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200839#if defined(MBEDTLS_ECP_RESTARTABLE)
840 ecdsa_verify_rs_wrap,
841 ecdsa_sign_rs_wrap,
842#endif
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200843 NULL,
844 NULL,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100845 eckey_check_pair, /* Compatible key structures */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200846 ecdsa_alloc_wrap,
847 ecdsa_free_wrap,
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200848#if defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200849 ecdsa_rs_alloc,
850 ecdsa_rs_free,
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200851#endif
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200852 eckey_debug, /* Compatible key structures */
853};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200854#endif /* MBEDTLS_ECDSA_C */
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200855
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200856#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200857/*
858 * Support for alternative RSA-private implementations
859 */
860
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200861static int rsa_alt_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200862{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200863 return( type == MBEDTLS_PK_RSA );
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200864}
865
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200866static size_t rsa_alt_get_bitlen( const void *ctx )
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200867{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200868 const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200869
Manuel Pégourié-Gonnard01488752014-04-03 22:09:18 +0200870 return( 8 * rsa_alt->key_len_func( rsa_alt->key ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200871}
872
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200873static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200874 const unsigned char *hash, size_t hash_len,
875 unsigned char *sig, size_t *sig_len,
876 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
877{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200878 mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200879
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100880#if SIZE_MAX > UINT_MAX
Andres AG72849872017-01-19 11:24:33 +0000881 if( UINT_MAX < hash_len )
882 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100883#endif /* SIZE_MAX > UINT_MAX */
Andres AG72849872017-01-19 11:24:33 +0000884
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200885 *sig_len = rsa_alt->key_len_func( rsa_alt->key );
886
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200887 return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200888 md_alg, (unsigned int) hash_len, hash, sig ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200889}
890
891static int rsa_alt_decrypt_wrap( void *ctx,
892 const unsigned char *input, size_t ilen,
893 unsigned char *output, size_t *olen, size_t osize,
894 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
895{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200896 mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200897
898 ((void) f_rng);
899 ((void) p_rng);
900
901 if( ilen != rsa_alt->key_len_func( rsa_alt->key ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200902 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200903
904 return( rsa_alt->decrypt_func( rsa_alt->key,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200905 MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200906}
907
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200908#if defined(MBEDTLS_RSA_C)
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100909static int rsa_alt_check_pair( const void *pub, const void *prv )
910{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200911 unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100912 unsigned char hash[32];
913 size_t sig_len = 0;
914 int ret;
915
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200916 if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200917 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100918
919 memset( hash, 0x2a, sizeof( hash ) );
920
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200921 if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE,
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100922 hash, sizeof( hash ),
923 sig, &sig_len, NULL, NULL ) ) != 0 )
924 {
925 return( ret );
926 }
927
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200928 if( rsa_verify_wrap( (void *) pub, MBEDTLS_MD_NONE,
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100929 hash, sizeof( hash ), sig, sig_len ) != 0 )
930 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200931 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100932 }
933
934 return( 0 );
935}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200936#endif /* MBEDTLS_RSA_C */
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100937
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200938static void *rsa_alt_alloc_wrap( void )
939{
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200940 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200941
942 if( ctx != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200943 memset( ctx, 0, sizeof( mbedtls_rsa_alt_context ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200944
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200945 return( ctx );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200946}
947
948static void rsa_alt_free_wrap( void *ctx )
949{
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500950 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200951 mbedtls_free( ctx );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200952}
953
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200954const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
955 MBEDTLS_PK_RSA_ALT,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200956 "RSA-alt",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200957 rsa_alt_get_bitlen,
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200958 rsa_alt_can_do,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200959 NULL,
960 rsa_alt_sign_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200961#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200962 NULL,
963 NULL,
964#endif
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200965 rsa_alt_decrypt_wrap,
966 NULL,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200967#if defined(MBEDTLS_RSA_C)
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100968 rsa_alt_check_pair,
Manuel Pégourié-Gonnard7c13d692014-11-12 00:01:34 +0100969#else
970 NULL,
971#endif
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200972 rsa_alt_alloc_wrap,
973 rsa_alt_free_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200974#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200975 NULL,
976 NULL,
977#endif
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200978 NULL,
979};
Manuel Pégourié-Gonnardc40b4c32013-08-22 13:29:31 +0200980
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200981#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
Manuel Pégourié-Gonnard348bcb32015-03-31 14:01:33 +0200982
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200983#endif /* MBEDTLS_PK_C */