blob: 2c27552d9b2792f1ee6c8be7fe580b9a63df9d32 [file] [log] [blame]
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +02001/*
2 * Public Key abstraction layer: wrapper functions
3 *
Bence Szépkútia2947ac2020-08-19 16:37:36 +02004 * Copyright The Mbed TLS Contributors
Bence Szépkútif744bd72020-06-05 13:02:18 +02005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 *
7 * This file is provided under the Apache License 2.0, or the
8 * GNU General Public License v2.0 or later.
9 *
10 * **********
11 * Apache License 2.0:
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +020012 *
13 * Licensed under the Apache License, Version 2.0 (the "License"); you may
14 * not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020024 *
Bence Szépkútif744bd72020-06-05 13:02:18 +020025 * **********
26 *
27 * **********
28 * GNU General Public License v2.0 or later:
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License along
41 * with this program; if not, write to the Free Software Foundation, Inc.,
42 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43 *
44 * **********
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020045 */
46
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020047#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000048#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020049#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020051#endif
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020052
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053#if defined(MBEDTLS_PK_C)
Manuel Pégourié-Gonnard50518f42015-05-26 11:04:15 +020054#include "mbedtls/pk_internal.h"
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020055
Manuel Pégourié-Gonnarde511ffc2013-08-22 17:33:21 +020056/* Even if RSA not activated, for the sake of RSA-alt */
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000057#include "mbedtls/rsa.h"
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020058
Rich Evans00ab4702015-02-06 13:43:58 +000059#include <string.h>
60
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020061#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000062#include "mbedtls/ecp.h"
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020063#endif
64
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020065#if defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000066#include "mbedtls/ecdsa.h"
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020067#endif
68
Andres Amaya Garciae32df082017-10-25 09:37:04 +010069#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050070#include "mbedtls/platform_util.h"
Andres Amaya Garciae32df082017-10-25 09:37:04 +010071#endif
72
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020073#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000074#include "mbedtls/platform.h"
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +020075#else
76#include <stdlib.h>
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +020077#define mbedtls_calloc calloc
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020078#define mbedtls_free free
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +020079#endif
80
Andres AG72849872017-01-19 11:24:33 +000081#include <limits.h>
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +010082#include <stdint.h>
Paul Bakker34617722014-06-13 17:20:13 +020083
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020084#if defined(MBEDTLS_RSA_C)
85static int rsa_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +020086{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020087 return( type == MBEDTLS_PK_RSA ||
88 type == MBEDTLS_PK_RSASSA_PSS );
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +020089}
90
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +020091static size_t rsa_get_bitlen( const void *ctx )
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +020092{
Hanno Becker6a1e7e52017-08-22 13:55:00 +010093 const mbedtls_rsa_context * rsa = (const mbedtls_rsa_context *) ctx;
94 return( 8 * mbedtls_rsa_get_len( rsa ) );
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +020095}
96
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020097static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +020098 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020099 const unsigned char *sig, size_t sig_len )
100{
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200101 int ret;
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100102 mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
103 size_t rsa_len = mbedtls_rsa_get_len( rsa );
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200104
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100105#if SIZE_MAX > UINT_MAX
Andres AG72849872017-01-19 11:24:33 +0000106 if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
107 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100108#endif /* SIZE_MAX > UINT_MAX */
Andres AG72849872017-01-19 11:24:33 +0000109
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100110 if( sig_len < rsa_len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200111 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200112
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100113 if( ( ret = mbedtls_rsa_pkcs1_verify( rsa, NULL, NULL,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200114 MBEDTLS_RSA_PUBLIC, md_alg,
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200115 (unsigned int) hash_len, hash, sig ) ) != 0 )
116 return( ret );
117
Gilles Peskine5114d3e2018-03-30 07:12:15 +0200118 /* The buffer contains a valid signature followed by extra data.
119 * We have a special error code for that so that so that callers can
120 * use mbedtls_pk_verify() to check "Does the buffer start with a
121 * valid signature?" and not just "Does the buffer contain a valid
122 * signature?". */
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100123 if( sig_len > rsa_len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200124 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200125
126 return( 0 );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200127}
128
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200129static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200130 const unsigned char *hash, size_t hash_len,
131 unsigned char *sig, size_t *sig_len,
132 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
133{
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100134 mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
135
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100136#if SIZE_MAX > UINT_MAX
Andres AG72849872017-01-19 11:24:33 +0000137 if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
138 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100139#endif /* SIZE_MAX > UINT_MAX */
Andres AG72849872017-01-19 11:24:33 +0000140
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100141 *sig_len = mbedtls_rsa_get_len( rsa );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200142
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100143 return( mbedtls_rsa_pkcs1_sign( rsa, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200144 md_alg, (unsigned int) hash_len, hash, sig ) );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200145}
146
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200147static int rsa_decrypt_wrap( void *ctx,
148 const unsigned char *input, size_t ilen,
149 unsigned char *output, size_t *olen, size_t osize,
150 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
151{
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100152 mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
153
154 if( ilen != mbedtls_rsa_get_len( rsa ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200155 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200156
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100157 return( mbedtls_rsa_pkcs1_decrypt( rsa, f_rng, p_rng,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200158 MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200159}
160
161static int rsa_encrypt_wrap( void *ctx,
162 const unsigned char *input, size_t ilen,
163 unsigned char *output, size_t *olen, size_t osize,
164 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
165{
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100166 mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
167 *olen = mbedtls_rsa_get_len( rsa );
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200168
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100169 if( *olen > osize )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200170 return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE );
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100171
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100172 return( mbedtls_rsa_pkcs1_encrypt( rsa, f_rng, p_rng, MBEDTLS_RSA_PUBLIC,
173 ilen, input, output ) );
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200174}
175
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100176static int rsa_check_pair_wrap( const void *pub, const void *prv )
177{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200178 return( mbedtls_rsa_check_pub_priv( (const mbedtls_rsa_context *) pub,
179 (const mbedtls_rsa_context *) prv ) );
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100180}
181
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200182static void *rsa_alloc_wrap( void )
183{
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200184 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_context ) );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200185
186 if( ctx != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200187 mbedtls_rsa_init( (mbedtls_rsa_context *) ctx, 0, 0 );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200188
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200189 return( ctx );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200190}
191
192static void rsa_free_wrap( void *ctx )
193{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200194 mbedtls_rsa_free( (mbedtls_rsa_context *) ctx );
195 mbedtls_free( ctx );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200196}
197
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200198static void rsa_debug( const void *ctx, mbedtls_pk_debug_item *items )
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200199{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200200 items->type = MBEDTLS_PK_DEBUG_MPI;
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200201 items->name = "rsa.N";
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200202 items->value = &( ((mbedtls_rsa_context *) ctx)->N );
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200203
204 items++;
205
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200206 items->type = MBEDTLS_PK_DEBUG_MPI;
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200207 items->name = "rsa.E";
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200208 items->value = &( ((mbedtls_rsa_context *) ctx)->E );
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200209}
210
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200211const mbedtls_pk_info_t mbedtls_rsa_info = {
212 MBEDTLS_PK_RSA,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200213 "RSA",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200214 rsa_get_bitlen,
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200215 rsa_can_do,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200216 rsa_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200217 rsa_sign_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200218#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200219 NULL,
220 NULL,
221#endif
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200222 rsa_decrypt_wrap,
223 rsa_encrypt_wrap,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100224 rsa_check_pair_wrap,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200225 rsa_alloc_wrap,
226 rsa_free_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200227#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200228 NULL,
229 NULL,
230#endif
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200231 rsa_debug,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200232};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200233#endif /* MBEDTLS_RSA_C */
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200234
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200235#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200236/*
237 * Generic EC key
238 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200239static int eckey_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200240{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200241 return( type == MBEDTLS_PK_ECKEY ||
242 type == MBEDTLS_PK_ECKEY_DH ||
243 type == MBEDTLS_PK_ECDSA );
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200244}
245
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200246static size_t eckey_get_bitlen( const void *ctx )
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200247{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200248 return( ((mbedtls_ecp_keypair *) ctx)->grp.pbits );
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200249}
250
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200251#if defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200252/* Forward declarations */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200253static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200254 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200255 const unsigned char *sig, size_t sig_len );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200256
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200257static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200258 const unsigned char *hash, size_t hash_len,
259 unsigned char *sig, size_t *sig_len,
260 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
261
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200262static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200263 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200264 const unsigned char *sig, size_t sig_len )
265{
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200266 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200267 mbedtls_ecdsa_context ecdsa;
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200268
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200269 mbedtls_ecdsa_init( &ecdsa );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200270
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200271 if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
Manuel Pégourié-Gonnard583b6082013-08-20 16:58:13 +0200272 ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200273
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200274 mbedtls_ecdsa_free( &ecdsa );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200275
276 return( ret );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200277}
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200278
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200279static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200280 const unsigned char *hash, size_t hash_len,
281 unsigned char *sig, size_t *sig_len,
282 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
283{
284 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200285 mbedtls_ecdsa_context ecdsa;
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200286
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200287 mbedtls_ecdsa_init( &ecdsa );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200288
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200289 if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200290 ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len,
291 f_rng, p_rng );
292
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200293 mbedtls_ecdsa_free( &ecdsa );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200294
295 return( ret );
296}
297
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200298#if defined(MBEDTLS_ECP_RESTARTABLE)
299/* Forward declarations */
300static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
301 const unsigned char *hash, size_t hash_len,
302 const unsigned char *sig, size_t sig_len,
303 void *rs_ctx );
304
305static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
306 const unsigned char *hash, size_t hash_len,
307 unsigned char *sig, size_t *sig_len,
308 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
309 void *rs_ctx );
310
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200311/*
312 * Restart context for ECDSA operations with ECKEY context
313 *
314 * We need to store an actual ECDSA context, as we need to pass the same to
315 * the underlying ecdsa function, so we can't create it on the fly every time.
316 */
317typedef struct
318{
319 mbedtls_ecdsa_restart_ctx ecdsa_rs;
320 mbedtls_ecdsa_context ecdsa_ctx;
321} eckey_restart_ctx;
322
323static void *eckey_rs_alloc( void )
324{
325 eckey_restart_ctx *rs_ctx;
326
327 void *ctx = mbedtls_calloc( 1, sizeof( eckey_restart_ctx ) );
328
329 if( ctx != NULL )
330 {
331 rs_ctx = ctx;
332 mbedtls_ecdsa_restart_init( &rs_ctx->ecdsa_rs );
333 mbedtls_ecdsa_init( &rs_ctx->ecdsa_ctx );
334 }
335
336 return( ctx );
337}
338
339static void eckey_rs_free( void *ctx )
340{
341 eckey_restart_ctx *rs_ctx;
342
343 if( ctx == NULL)
344 return;
345
346 rs_ctx = ctx;
347 mbedtls_ecdsa_restart_free( &rs_ctx->ecdsa_rs );
348 mbedtls_ecdsa_free( &rs_ctx->ecdsa_ctx );
349
350 mbedtls_free( ctx );
351}
352
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200353static int eckey_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
354 const unsigned char *hash, size_t hash_len,
355 const unsigned char *sig, size_t sig_len,
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200356 void *rs_ctx )
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200357{
358 int ret;
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200359 eckey_restart_ctx *rs = rs_ctx;
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200360
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200361 /* Should never happen */
362 if( rs == NULL )
363 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200364
Manuel Pégourié-Gonnardee68cff2018-10-15 15:27:49 +0200365 /* set up our own sub-context if needed (that is, on first run) */
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200366 if( rs->ecdsa_ctx.grp.pbits == 0 )
367 MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) );
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200368
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200369 MBEDTLS_MPI_CHK( ecdsa_verify_rs_wrap( &rs->ecdsa_ctx,
370 md_alg, hash, hash_len,
371 sig, sig_len, &rs->ecdsa_rs ) );
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200372
373cleanup:
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200374 return( ret );
375}
376
377static int eckey_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
378 const unsigned char *hash, size_t hash_len,
379 unsigned char *sig, size_t *sig_len,
380 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200381 void *rs_ctx )
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200382{
383 int ret;
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200384 eckey_restart_ctx *rs = rs_ctx;
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200385
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200386 /* Should never happen */
387 if( rs == NULL )
388 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200389
Manuel Pégourié-Gonnardee68cff2018-10-15 15:27:49 +0200390 /* set up our own sub-context if needed (that is, on first run) */
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200391 if( rs->ecdsa_ctx.grp.pbits == 0 )
392 MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) );
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200393
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200394 MBEDTLS_MPI_CHK( ecdsa_sign_rs_wrap( &rs->ecdsa_ctx, md_alg,
395 hash, hash_len, sig, sig_len,
396 f_rng, p_rng, &rs->ecdsa_rs ) );
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200397
398cleanup:
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200399 return( ret );
400}
401#endif /* MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200402#endif /* MBEDTLS_ECDSA_C */
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200403
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100404static int eckey_check_pair( const void *pub, const void *prv )
405{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200406 return( mbedtls_ecp_check_pub_priv( (const mbedtls_ecp_keypair *) pub,
407 (const mbedtls_ecp_keypair *) prv ) );
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100408}
409
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200410static void *eckey_alloc_wrap( void )
411{
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200412 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200413
414 if( ctx != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200415 mbedtls_ecp_keypair_init( ctx );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200416
417 return( ctx );
418}
419
420static void eckey_free_wrap( void *ctx )
421{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200422 mbedtls_ecp_keypair_free( (mbedtls_ecp_keypair *) ctx );
423 mbedtls_free( ctx );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200424}
425
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200426static void eckey_debug( const void *ctx, mbedtls_pk_debug_item *items )
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200427{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200428 items->type = MBEDTLS_PK_DEBUG_ECP;
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200429 items->name = "eckey.Q";
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200430 items->value = &( ((mbedtls_ecp_keypair *) ctx)->Q );
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200431}
432
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200433const mbedtls_pk_info_t mbedtls_eckey_info = {
434 MBEDTLS_PK_ECKEY,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200435 "EC",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200436 eckey_get_bitlen,
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200437 eckey_can_do,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200438#if defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200439 eckey_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200440 eckey_sign_wrap,
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200441#if defined(MBEDTLS_ECP_RESTARTABLE)
442 eckey_verify_rs_wrap,
443 eckey_sign_rs_wrap,
444#endif
445#else /* MBEDTLS_ECDSA_C */
446 NULL,
447 NULL,
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200448#endif /* MBEDTLS_ECDSA_C */
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200449 NULL,
450 NULL,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100451 eckey_check_pair,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200452 eckey_alloc_wrap,
453 eckey_free_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200454#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200455 eckey_rs_alloc,
456 eckey_rs_free,
457#endif
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200458 eckey_debug,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200459};
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200460
461/*
Paul Bakker75342a62014-04-08 17:35:40 +0200462 * EC key restricted to ECDH
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200463 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200464static int eckeydh_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200465{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466 return( type == MBEDTLS_PK_ECKEY ||
467 type == MBEDTLS_PK_ECKEY_DH );
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200468}
469
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200470const mbedtls_pk_info_t mbedtls_eckeydh_info = {
471 MBEDTLS_PK_ECKEY_DH,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200472 "EC_DH",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200473 eckey_get_bitlen, /* Same underlying key structure */
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200474 eckeydh_can_do,
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200475 NULL,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200476 NULL,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200477#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200478 NULL,
479 NULL,
480#endif
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200481 NULL,
482 NULL,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100483 eckey_check_pair,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200484 eckey_alloc_wrap, /* Same underlying key structure */
485 eckey_free_wrap, /* Same underlying key structure */
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200486#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200487 NULL,
488 NULL,
489#endif
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200490 eckey_debug, /* Same underlying key structure */
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200491};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200492#endif /* MBEDTLS_ECP_C */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200493
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494#if defined(MBEDTLS_ECDSA_C)
495static int ecdsa_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200496{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200497 return( type == MBEDTLS_PK_ECDSA );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200498}
499
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200500static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200501 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200502 const unsigned char *sig, size_t sig_len )
503{
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200504 int ret;
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200505 ((void) md_alg);
506
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200507 ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx,
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200508 hash, hash_len, sig, sig_len );
509
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200510 if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )
511 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200512
513 return( ret );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200514}
515
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200516static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200517 const unsigned char *hash, size_t hash_len,
518 unsigned char *sig, size_t *sig_len,
519 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
520{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200521 return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx,
Manuel Pégourié-Gonnarddfdcac92015-03-31 11:41:42 +0200522 md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200523}
524
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200525#if defined(MBEDTLS_ECP_RESTARTABLE)
526static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
527 const unsigned char *hash, size_t hash_len,
528 const unsigned char *sig, size_t sig_len,
529 void *rs_ctx )
530{
531 int ret;
532 ((void) md_alg);
533
534 ret = mbedtls_ecdsa_read_signature_restartable(
535 (mbedtls_ecdsa_context *) ctx,
536 hash, hash_len, sig, sig_len,
537 (mbedtls_ecdsa_restart_ctx *) rs_ctx );
538
539 if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )
540 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
541
542 return( ret );
543}
544
545static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
546 const unsigned char *hash, size_t hash_len,
547 unsigned char *sig, size_t *sig_len,
548 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
549 void *rs_ctx )
550{
551 return( mbedtls_ecdsa_write_signature_restartable(
552 (mbedtls_ecdsa_context *) ctx,
553 md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng,
554 (mbedtls_ecdsa_restart_ctx *) rs_ctx ) );
555
556}
557#endif /* MBEDTLS_ECP_RESTARTABLE */
558
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200559static void *ecdsa_alloc_wrap( void )
560{
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200561 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200562
563 if( ctx != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200564 mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200565
566 return( ctx );
567}
568
569static void ecdsa_free_wrap( void *ctx )
570{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200571 mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx );
572 mbedtls_free( ctx );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200573}
574
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200575#if defined(MBEDTLS_ECP_RESTARTABLE)
576static void *ecdsa_rs_alloc( void )
577{
578 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_restart_ctx ) );
579
580 if( ctx != NULL )
581 mbedtls_ecdsa_restart_init( ctx );
582
583 return( ctx );
584}
585
586static void ecdsa_rs_free( void *ctx )
587{
588 mbedtls_ecdsa_restart_free( ctx );
589 mbedtls_free( ctx );
590}
591#endif /* MBEDTLS_ECP_RESTARTABLE */
592
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200593const mbedtls_pk_info_t mbedtls_ecdsa_info = {
594 MBEDTLS_PK_ECDSA,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200595 "ECDSA",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200596 eckey_get_bitlen, /* Compatible key structures */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200597 ecdsa_can_do,
598 ecdsa_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200599 ecdsa_sign_wrap,
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200600#if defined(MBEDTLS_ECP_RESTARTABLE)
601 ecdsa_verify_rs_wrap,
602 ecdsa_sign_rs_wrap,
603#endif
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200604 NULL,
605 NULL,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100606 eckey_check_pair, /* Compatible key structures */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200607 ecdsa_alloc_wrap,
608 ecdsa_free_wrap,
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200609#if defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200610 ecdsa_rs_alloc,
611 ecdsa_rs_free,
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200612#endif
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200613 eckey_debug, /* Compatible key structures */
614};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200615#endif /* MBEDTLS_ECDSA_C */
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200616
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200617#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200618/*
619 * Support for alternative RSA-private implementations
620 */
621
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200622static int rsa_alt_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200623{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200624 return( type == MBEDTLS_PK_RSA );
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200625}
626
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200627static size_t rsa_alt_get_bitlen( const void *ctx )
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200628{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200629 const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200630
Manuel Pégourié-Gonnard01488752014-04-03 22:09:18 +0200631 return( 8 * rsa_alt->key_len_func( rsa_alt->key ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200632}
633
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200634static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200635 const unsigned char *hash, size_t hash_len,
636 unsigned char *sig, size_t *sig_len,
637 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
638{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200639 mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200640
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100641#if SIZE_MAX > UINT_MAX
Andres AG72849872017-01-19 11:24:33 +0000642 if( UINT_MAX < hash_len )
643 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100644#endif /* SIZE_MAX > UINT_MAX */
Andres AG72849872017-01-19 11:24:33 +0000645
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200646 *sig_len = rsa_alt->key_len_func( rsa_alt->key );
647
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200648 return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200649 md_alg, (unsigned int) hash_len, hash, sig ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200650}
651
652static int rsa_alt_decrypt_wrap( void *ctx,
653 const unsigned char *input, size_t ilen,
654 unsigned char *output, size_t *olen, size_t osize,
655 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
656{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200657 mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200658
659 ((void) f_rng);
660 ((void) p_rng);
661
662 if( ilen != rsa_alt->key_len_func( rsa_alt->key ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200663 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200664
665 return( rsa_alt->decrypt_func( rsa_alt->key,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200666 MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200667}
668
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200669#if defined(MBEDTLS_RSA_C)
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100670static int rsa_alt_check_pair( const void *pub, const void *prv )
671{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200672 unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100673 unsigned char hash[32];
674 size_t sig_len = 0;
675 int ret;
676
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200677 if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200678 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100679
680 memset( hash, 0x2a, sizeof( hash ) );
681
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200682 if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE,
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100683 hash, sizeof( hash ),
684 sig, &sig_len, NULL, NULL ) ) != 0 )
685 {
686 return( ret );
687 }
688
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200689 if( rsa_verify_wrap( (void *) pub, MBEDTLS_MD_NONE,
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100690 hash, sizeof( hash ), sig, sig_len ) != 0 )
691 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200692 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100693 }
694
695 return( 0 );
696}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200697#endif /* MBEDTLS_RSA_C */
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100698
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200699static void *rsa_alt_alloc_wrap( void )
700{
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200701 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200702
703 if( ctx != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200704 memset( ctx, 0, sizeof( mbedtls_rsa_alt_context ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200705
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200706 return( ctx );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200707}
708
709static void rsa_alt_free_wrap( void *ctx )
710{
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500711 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200712 mbedtls_free( ctx );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200713}
714
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200715const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
716 MBEDTLS_PK_RSA_ALT,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200717 "RSA-alt",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200718 rsa_alt_get_bitlen,
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200719 rsa_alt_can_do,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200720 NULL,
721 rsa_alt_sign_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200722#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200723 NULL,
724 NULL,
725#endif
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200726 rsa_alt_decrypt_wrap,
727 NULL,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200728#if defined(MBEDTLS_RSA_C)
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100729 rsa_alt_check_pair,
Manuel Pégourié-Gonnard7c13d692014-11-12 00:01:34 +0100730#else
731 NULL,
732#endif
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200733 rsa_alt_alloc_wrap,
734 rsa_alt_free_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200735#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200736 NULL,
737 NULL,
738#endif
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200739 NULL,
740};
Manuel Pégourié-Gonnardc40b4c32013-08-22 13:29:31 +0200741
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200742#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
Manuel Pégourié-Gonnard348bcb32015-03-31 14:01:33 +0200743
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200744#endif /* MBEDTLS_PK_C */