blob: 966a17c1855efbdeed0583bf355454a82f8a1aca [file] [log] [blame]
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +02001/*
2 * Public Key abstraction layer: wrapper functions
3 *
Bence Szépkúti44bfbe32020-08-19 16:54:51 +02004 * Copyright The Mbed TLS Contributors
Bence Szépkúti4e9f7122020-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úti4e9f7122020-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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020069#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000070#include "mbedtls/platform.h"
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +020071#else
72#include <stdlib.h>
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +020073#define mbedtls_calloc calloc
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020074#define mbedtls_free free
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +020075#endif
76
Andres AG72849872017-01-19 11:24:33 +000077#include <limits.h>
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +010078#include <stdint.h>
Andres AG72849872017-01-19 11:24:33 +000079
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020080#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
Paul Bakker34617722014-06-13 17:20:13 +020081/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020082static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020083 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
84}
Manuel Pégourié-Gonnard348bcb32015-03-31 14:01:33 +020085#endif
Paul Bakker34617722014-06-13 17:20:13 +020086
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020087#if defined(MBEDTLS_RSA_C)
88static int rsa_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +020089{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020090 return( type == MBEDTLS_PK_RSA ||
91 type == MBEDTLS_PK_RSASSA_PSS );
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +020092}
93
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +020094static size_t rsa_get_bitlen( const void *ctx )
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +020095{
Hanno Becker6a1e7e52017-08-22 13:55:00 +010096 const mbedtls_rsa_context * rsa = (const mbedtls_rsa_context *) ctx;
97 return( 8 * mbedtls_rsa_get_len( rsa ) );
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +020098}
99
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200100static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200101 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200102 const unsigned char *sig, size_t sig_len )
103{
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200104 int ret;
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100105 mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
106 size_t rsa_len = mbedtls_rsa_get_len( rsa );
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200107
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100108#if SIZE_MAX > UINT_MAX
Andres AG72849872017-01-19 11:24:33 +0000109 if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
110 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100111#endif /* SIZE_MAX > UINT_MAX */
Andres AG72849872017-01-19 11:24:33 +0000112
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100113 if( sig_len < rsa_len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200114 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200115
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100116 if( ( ret = mbedtls_rsa_pkcs1_verify( rsa, NULL, NULL,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200117 MBEDTLS_RSA_PUBLIC, md_alg,
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200118 (unsigned int) hash_len, hash, sig ) ) != 0 )
119 return( ret );
120
Gilles Peskine5114d3e2018-03-30 07:12:15 +0200121 /* The buffer contains a valid signature followed by extra data.
122 * We have a special error code for that so that so that callers can
123 * use mbedtls_pk_verify() to check "Does the buffer start with a
124 * valid signature?" and not just "Does the buffer contain a valid
125 * signature?". */
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100126 if( sig_len > rsa_len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200127 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200128
129 return( 0 );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200130}
131
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200132static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200133 const unsigned char *hash, size_t hash_len,
134 unsigned char *sig, size_t *sig_len,
135 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
136{
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100137 mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
138
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100139#if SIZE_MAX > UINT_MAX
Andres AG72849872017-01-19 11:24:33 +0000140 if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
141 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100142#endif /* SIZE_MAX > UINT_MAX */
Andres AG72849872017-01-19 11:24:33 +0000143
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100144 *sig_len = mbedtls_rsa_get_len( rsa );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200145
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100146 return( mbedtls_rsa_pkcs1_sign( rsa, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200147 md_alg, (unsigned int) hash_len, hash, sig ) );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200148}
149
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200150static int rsa_decrypt_wrap( void *ctx,
151 const unsigned char *input, size_t ilen,
152 unsigned char *output, size_t *olen, size_t osize,
153 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
154{
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100155 mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
156
157 if( ilen != mbedtls_rsa_get_len( rsa ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200158 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200159
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100160 return( mbedtls_rsa_pkcs1_decrypt( rsa, f_rng, p_rng,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200161 MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200162}
163
164static int rsa_encrypt_wrap( void *ctx,
165 const unsigned char *input, size_t ilen,
166 unsigned char *output, size_t *olen, size_t osize,
167 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
168{
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100169 mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
170 *olen = mbedtls_rsa_get_len( rsa );
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200171
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100172 if( *olen > osize )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200173 return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE );
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100174
Hanno Becker6a1e7e52017-08-22 13:55:00 +0100175 return( mbedtls_rsa_pkcs1_encrypt( rsa, f_rng, p_rng, MBEDTLS_RSA_PUBLIC,
176 ilen, input, output ) );
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200177}
178
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100179static int rsa_check_pair_wrap( const void *pub, const void *prv )
180{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200181 return( mbedtls_rsa_check_pub_priv( (const mbedtls_rsa_context *) pub,
182 (const mbedtls_rsa_context *) prv ) );
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100183}
184
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200185static void *rsa_alloc_wrap( void )
186{
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200187 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_context ) );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200188
189 if( ctx != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200190 mbedtls_rsa_init( (mbedtls_rsa_context *) ctx, 0, 0 );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200191
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200192 return( ctx );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200193}
194
195static void rsa_free_wrap( void *ctx )
196{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200197 mbedtls_rsa_free( (mbedtls_rsa_context *) ctx );
198 mbedtls_free( ctx );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200199}
200
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200201static void rsa_debug( const void *ctx, mbedtls_pk_debug_item *items )
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200202{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200203 items->type = MBEDTLS_PK_DEBUG_MPI;
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200204 items->name = "rsa.N";
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200205 items->value = &( ((mbedtls_rsa_context *) ctx)->N );
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200206
207 items++;
208
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200209 items->type = MBEDTLS_PK_DEBUG_MPI;
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200210 items->name = "rsa.E";
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200211 items->value = &( ((mbedtls_rsa_context *) ctx)->E );
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200212}
213
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200214const mbedtls_pk_info_t mbedtls_rsa_info = {
215 MBEDTLS_PK_RSA,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200216 "RSA",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200217 rsa_get_bitlen,
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200218 rsa_can_do,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200219 rsa_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200220 rsa_sign_wrap,
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200221 rsa_decrypt_wrap,
222 rsa_encrypt_wrap,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100223 rsa_check_pair_wrap,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200224 rsa_alloc_wrap,
225 rsa_free_wrap,
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200226 rsa_debug,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200227};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200228#endif /* MBEDTLS_RSA_C */
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200229
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200230#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200231/*
232 * Generic EC key
233 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200234static int eckey_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200235{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200236 return( type == MBEDTLS_PK_ECKEY ||
237 type == MBEDTLS_PK_ECKEY_DH ||
238 type == MBEDTLS_PK_ECDSA );
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200239}
240
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200241static size_t eckey_get_bitlen( const void *ctx )
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200242{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200243 return( ((mbedtls_ecp_keypair *) ctx)->grp.pbits );
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200244}
245
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200246#if defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200247/* Forward declarations */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200248static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200249 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200250 const unsigned char *sig, size_t sig_len );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200251
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200252static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200253 const unsigned char *hash, size_t hash_len,
254 unsigned char *sig, size_t *sig_len,
255 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
256
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200257static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200258 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200259 const unsigned char *sig, size_t sig_len )
260{
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200261 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200262 mbedtls_ecdsa_context ecdsa;
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200263
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200264 mbedtls_ecdsa_init( &ecdsa );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200265
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200266 if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
Manuel Pégourié-Gonnard583b6082013-08-20 16:58:13 +0200267 ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200268
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200269 mbedtls_ecdsa_free( &ecdsa );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200270
271 return( ret );
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200272}
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200273
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200274static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200275 const unsigned char *hash, size_t hash_len,
276 unsigned char *sig, size_t *sig_len,
277 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
278{
279 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200280 mbedtls_ecdsa_context ecdsa;
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200281
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200282 mbedtls_ecdsa_init( &ecdsa );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200283
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200284 if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200285 ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len,
286 f_rng, p_rng );
287
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200288 mbedtls_ecdsa_free( &ecdsa );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200289
290 return( ret );
291}
292
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200293#endif /* MBEDTLS_ECDSA_C */
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200294
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100295static int eckey_check_pair( const void *pub, const void *prv )
296{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200297 return( mbedtls_ecp_check_pub_priv( (const mbedtls_ecp_keypair *) pub,
298 (const mbedtls_ecp_keypair *) prv ) );
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100299}
300
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200301static void *eckey_alloc_wrap( void )
302{
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200303 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200304
305 if( ctx != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200306 mbedtls_ecp_keypair_init( ctx );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200307
308 return( ctx );
309}
310
311static void eckey_free_wrap( void *ctx )
312{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200313 mbedtls_ecp_keypair_free( (mbedtls_ecp_keypair *) ctx );
314 mbedtls_free( ctx );
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200315}
316
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200317static void eckey_debug( const void *ctx, mbedtls_pk_debug_item *items )
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200318{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200319 items->type = MBEDTLS_PK_DEBUG_ECP;
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200320 items->name = "eckey.Q";
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200321 items->value = &( ((mbedtls_ecp_keypair *) ctx)->Q );
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200322}
323
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200324const mbedtls_pk_info_t mbedtls_eckey_info = {
325 MBEDTLS_PK_ECKEY,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200326 "EC",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200327 eckey_get_bitlen,
Manuel Pégourié-Gonnardf18c3e02013-08-12 18:41:18 +0200328 eckey_can_do,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200329#if defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200330 eckey_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200331 eckey_sign_wrap,
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200332#else
333 NULL,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200334 NULL,
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200335#endif
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200336 NULL,
337 NULL,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100338 eckey_check_pair,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200339 eckey_alloc_wrap,
340 eckey_free_wrap,
Manuel Pégourié-Gonnardc6ac8872013-08-14 18:04:18 +0200341 eckey_debug,
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +0200342};
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200343
344/*
Paul Bakker75342a62014-04-08 17:35:40 +0200345 * EC key restricted to ECDH
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200346 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200347static int eckeydh_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200348{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200349 return( type == MBEDTLS_PK_ECKEY ||
350 type == MBEDTLS_PK_ECKEY_DH );
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200351}
352
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200353const mbedtls_pk_info_t mbedtls_eckeydh_info = {
354 MBEDTLS_PK_ECKEY_DH,
Manuel Pégourié-Gonnardf8c948a2013-08-12 19:45:32 +0200355 "EC_DH",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200356 eckey_get_bitlen, /* Same underlying key structure */
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200357 eckeydh_can_do,
Manuel Pégourié-Gonnardfff80f82013-08-17 15:20:06 +0200358 NULL,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200359 NULL,
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200360 NULL,
361 NULL,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100362 eckey_check_pair,
Manuel Pégourié-Gonnard765db072013-08-14 15:00:27 +0200363 eckey_alloc_wrap, /* Same underlying key structure */
364 eckey_free_wrap, /* Same underlying key structure */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200365 eckey_debug, /* Same underlying key structure */
Manuel Pégourié-Gonnard835eb592013-08-12 18:51:26 +0200366};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200367#endif /* MBEDTLS_ECP_C */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200368
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200369#if defined(MBEDTLS_ECDSA_C)
370static int ecdsa_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200371{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200372 return( type == MBEDTLS_PK_ECDSA );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200373}
374
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200375static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200376 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200377 const unsigned char *sig, size_t sig_len )
378{
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200379 int ret;
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200380 ((void) md_alg);
381
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200382 ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx,
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200383 hash, hash_len, sig, sig_len );
384
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200385 if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )
386 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200387
388 return( ret );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200389}
390
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200391static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200392 const unsigned char *hash, size_t hash_len,
393 unsigned char *sig, size_t *sig_len,
394 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
395{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200396 return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx,
Manuel Pégourié-Gonnarddfdcac92015-03-31 11:41:42 +0200397 md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200398}
399
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200400static void *ecdsa_alloc_wrap( void )
401{
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200402 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200403
404 if( ctx != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200405 mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200406
407 return( ctx );
408}
409
410static void ecdsa_free_wrap( void *ctx )
411{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200412 mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx );
413 mbedtls_free( ctx );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200414}
415
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200416const mbedtls_pk_info_t mbedtls_ecdsa_info = {
417 MBEDTLS_PK_ECDSA,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200418 "ECDSA",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200419 eckey_get_bitlen, /* Compatible key structures */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200420 ecdsa_can_do,
421 ecdsa_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200422 ecdsa_sign_wrap,
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200423 NULL,
424 NULL,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100425 eckey_check_pair, /* Compatible key structures */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200426 ecdsa_alloc_wrap,
427 ecdsa_free_wrap,
428 eckey_debug, /* Compatible key structures */
429};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200430#endif /* MBEDTLS_ECDSA_C */
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200431
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200432#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200433/*
434 * Support for alternative RSA-private implementations
435 */
436
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200437static int rsa_alt_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200438{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200439 return( type == MBEDTLS_PK_RSA );
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200440}
441
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200442static size_t rsa_alt_get_bitlen( const void *ctx )
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200443{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200444 const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200445
Manuel Pégourié-Gonnard01488752014-04-03 22:09:18 +0200446 return( 8 * rsa_alt->key_len_func( rsa_alt->key ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200447}
448
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200449static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200450 const unsigned char *hash, size_t hash_len,
451 unsigned char *sig, size_t *sig_len,
452 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
453{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200454 mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200455
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100456#if SIZE_MAX > UINT_MAX
Andres AG72849872017-01-19 11:24:33 +0000457 if( UINT_MAX < hash_len )
458 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100459#endif /* SIZE_MAX > UINT_MAX */
Andres AG72849872017-01-19 11:24:33 +0000460
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200461 *sig_len = rsa_alt->key_len_func( rsa_alt->key );
462
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200463 return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200464 md_alg, (unsigned int) hash_len, hash, sig ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200465}
466
467static int rsa_alt_decrypt_wrap( void *ctx,
468 const unsigned char *input, size_t ilen,
469 unsigned char *output, size_t *olen, size_t osize,
470 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
471{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200472 mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200473
474 ((void) f_rng);
475 ((void) p_rng);
476
477 if( ilen != rsa_alt->key_len_func( rsa_alt->key ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200478 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200479
480 return( rsa_alt->decrypt_func( rsa_alt->key,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200481 MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200482}
483
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200484#if defined(MBEDTLS_RSA_C)
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100485static int rsa_alt_check_pair( const void *pub, const void *prv )
486{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200487 unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100488 unsigned char hash[32];
489 size_t sig_len = 0;
490 int ret;
491
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200492 if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200493 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100494
495 memset( hash, 0x2a, sizeof( hash ) );
496
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200497 if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE,
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100498 hash, sizeof( hash ),
499 sig, &sig_len, NULL, NULL ) ) != 0 )
500 {
501 return( ret );
502 }
503
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200504 if( rsa_verify_wrap( (void *) pub, MBEDTLS_MD_NONE,
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100505 hash, sizeof( hash ), sig, sig_len ) != 0 )
506 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200507 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100508 }
509
510 return( 0 );
511}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200512#endif /* MBEDTLS_RSA_C */
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100513
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200514static void *rsa_alt_alloc_wrap( void )
515{
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200516 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200517
518 if( ctx != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200519 memset( ctx, 0, sizeof( mbedtls_rsa_alt_context ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200520
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200521 return( ctx );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200522}
523
524static void rsa_alt_free_wrap( void *ctx )
525{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200526 mbedtls_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) );
527 mbedtls_free( ctx );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200528}
529
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200530const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
531 MBEDTLS_PK_RSA_ALT,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200532 "RSA-alt",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200533 rsa_alt_get_bitlen,
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200534 rsa_alt_can_do,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200535 NULL,
536 rsa_alt_sign_wrap,
537 rsa_alt_decrypt_wrap,
538 NULL,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200539#if defined(MBEDTLS_RSA_C)
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100540 rsa_alt_check_pair,
Manuel Pégourié-Gonnard7c13d692014-11-12 00:01:34 +0100541#else
542 NULL,
543#endif
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200544 rsa_alt_alloc_wrap,
545 rsa_alt_free_wrap,
546 NULL,
547};
Manuel Pégourié-Gonnardc40b4c32013-08-22 13:29:31 +0200548
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200549#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
Manuel Pégourié-Gonnard348bcb32015-03-31 14:01:33 +0200550
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200551#endif /* MBEDTLS_PK_C */