blob: e576f733491d84305456b3d4f3f2caba5b129161 [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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020036#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000037#include "mbedtls/ecp.h"
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020038#endif
39
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020040#if defined(MBEDTLS_ECDSA_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000041#include "mbedtls/ecdsa.h"
Manuel Pégourié-Gonnardd73b3c12013-08-12 17:06:05 +020042#endif
43
Manuel Pégourié-Gonnard36867712018-10-31 16:22:49 +010044#if defined(MBEDTLS_USE_PSA_CRYPTO)
45#include "mbedtls/asn1write.h"
46#endif
47
Andres Amaya Garciae32df082017-10-25 09:37:04 +010048#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050049#include "mbedtls/platform_util.h"
Andres Amaya Garciae32df082017-10-25 09:37:04 +010050#endif
51
Manuel Pégourié-Gonnard36867712018-10-31 16:22:49 +010052#if defined(MBEDTLS_USE_PSA_CRYPTO)
53#include "mbedtls/psa_util.h"
54#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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200477#if defined(MBEDTLS_ECDSA_C)
478static int ecdsa_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200479{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200480 return( type == MBEDTLS_PK_ECDSA );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200481}
482
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200483static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200484 const unsigned char *hash, size_t hash_len,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200485 const unsigned char *sig, size_t sig_len )
486{
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200487 int ret;
Manuel Pégourié-Gonnardf73da022013-08-17 14:36:32 +0200488 ((void) md_alg);
489
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200490 ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx,
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200491 hash, hash_len, sig, sig_len );
492
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200493 if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )
494 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
Manuel Pégourié-Gonnard2abed842014-04-08 12:40:15 +0200495
496 return( ret );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200497}
498
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200500 const unsigned char *hash, size_t hash_len,
501 unsigned char *sig, size_t *sig_len,
502 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
503{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200504 return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx,
Manuel Pégourié-Gonnarddfdcac92015-03-31 11:41:42 +0200505 md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) );
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200506}
507
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200508#if defined(MBEDTLS_ECP_RESTARTABLE)
509static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
510 const unsigned char *hash, size_t hash_len,
511 const unsigned char *sig, size_t sig_len,
512 void *rs_ctx )
513{
514 int ret;
515 ((void) md_alg);
516
517 ret = mbedtls_ecdsa_read_signature_restartable(
518 (mbedtls_ecdsa_context *) ctx,
519 hash, hash_len, sig, sig_len,
520 (mbedtls_ecdsa_restart_ctx *) rs_ctx );
521
522 if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )
523 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
524
525 return( ret );
526}
527
528static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
529 const unsigned char *hash, size_t hash_len,
530 unsigned char *sig, size_t *sig_len,
531 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
532 void *rs_ctx )
533{
534 return( mbedtls_ecdsa_write_signature_restartable(
535 (mbedtls_ecdsa_context *) ctx,
536 md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng,
537 (mbedtls_ecdsa_restart_ctx *) rs_ctx ) );
538
539}
540#endif /* MBEDTLS_ECP_RESTARTABLE */
541
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200542static void *ecdsa_alloc_wrap( void )
543{
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200544 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200545
546 if( ctx != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200547 mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200548
549 return( ctx );
550}
551
552static void ecdsa_free_wrap( void *ctx )
553{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200554 mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx );
555 mbedtls_free( ctx );
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200556}
557
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200558#if defined(MBEDTLS_ECP_RESTARTABLE)
559static void *ecdsa_rs_alloc( void )
560{
561 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_restart_ctx ) );
562
563 if( ctx != NULL )
564 mbedtls_ecdsa_restart_init( ctx );
565
566 return( ctx );
567}
568
569static void ecdsa_rs_free( void *ctx )
570{
571 mbedtls_ecdsa_restart_free( ctx );
572 mbedtls_free( ctx );
573}
574#endif /* MBEDTLS_ECP_RESTARTABLE */
575
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200576const mbedtls_pk_info_t mbedtls_ecdsa_info = {
577 MBEDTLS_PK_ECDSA,
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200578 "ECDSA",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200579 eckey_get_bitlen, /* Compatible key structures */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200580 ecdsa_can_do,
581 ecdsa_verify_wrap,
Manuel Pégourié-Gonnard8df27692013-08-21 10:34:38 +0200582 ecdsa_sign_wrap,
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200583#if defined(MBEDTLS_ECP_RESTARTABLE)
584 ecdsa_verify_rs_wrap,
585 ecdsa_sign_rs_wrap,
586#endif
Manuel Pégourié-Gonnarda2d3f222013-08-21 11:51:08 +0200587 NULL,
588 NULL,
Manuel Pégourié-Gonnard70bdadf2014-11-06 16:51:20 +0100589 eckey_check_pair, /* Compatible key structures */
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200590 ecdsa_alloc_wrap,
591 ecdsa_free_wrap,
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200592#if defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnardfe687702017-08-18 17:04:07 +0200593 ecdsa_rs_alloc,
594 ecdsa_rs_free,
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200595#endif
Manuel Pégourié-Gonnard09162dd2013-08-14 18:16:50 +0200596 eckey_debug, /* Compatible key structures */
597};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200598#endif /* MBEDTLS_ECDSA_C */
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200599
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200600#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200601/*
602 * Support for alternative RSA-private implementations
603 */
604
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200605static int rsa_alt_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200606{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200607 return( type == MBEDTLS_PK_RSA );
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200608}
609
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200610static size_t rsa_alt_get_bitlen( const void *ctx )
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200611{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200612 const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200613
Manuel Pégourié-Gonnard01488752014-04-03 22:09:18 +0200614 return( 8 * rsa_alt->key_len_func( rsa_alt->key ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200615}
616
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200617static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200618 const unsigned char *hash, size_t hash_len,
619 unsigned char *sig, size_t *sig_len,
620 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
621{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200622 mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200623
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100624#if SIZE_MAX > UINT_MAX
Andres AG72849872017-01-19 11:24:33 +0000625 if( UINT_MAX < hash_len )
626 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
Andres Amaya Garcia7c02c502017-08-04 13:32:15 +0100627#endif /* SIZE_MAX > UINT_MAX */
Andres AG72849872017-01-19 11:24:33 +0000628
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200629 *sig_len = rsa_alt->key_len_func( rsa_alt->key );
630
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200631 return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200632 md_alg, (unsigned int) hash_len, hash, sig ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200633}
634
635static int rsa_alt_decrypt_wrap( void *ctx,
636 const unsigned char *input, size_t ilen,
637 unsigned char *output, size_t *olen, size_t osize,
638 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
639{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200640 mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200641
642 ((void) f_rng);
643 ((void) p_rng);
644
645 if( ilen != rsa_alt->key_len_func( rsa_alt->key ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200646 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200647
648 return( rsa_alt->decrypt_func( rsa_alt->key,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200649 MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200650}
651
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200652#if defined(MBEDTLS_RSA_C)
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100653static int rsa_alt_check_pair( const void *pub, const void *prv )
654{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200655 unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100656 unsigned char hash[32];
657 size_t sig_len = 0;
658 int ret;
659
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200660 if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200661 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100662
663 memset( hash, 0x2a, sizeof( hash ) );
664
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200665 if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE,
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100666 hash, sizeof( hash ),
667 sig, &sig_len, NULL, NULL ) ) != 0 )
668 {
669 return( ret );
670 }
671
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200672 if( rsa_verify_wrap( (void *) pub, MBEDTLS_MD_NONE,
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100673 hash, sizeof( hash ), sig, sig_len ) != 0 )
674 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200675 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100676 }
677
678 return( 0 );
679}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200680#endif /* MBEDTLS_RSA_C */
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100681
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200682static void *rsa_alt_alloc_wrap( void )
683{
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200684 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200685
686 if( ctx != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200687 memset( ctx, 0, sizeof( mbedtls_rsa_alt_context ) );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200688
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200689 return( ctx );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200690}
691
692static void rsa_alt_free_wrap( void *ctx )
693{
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500694 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200695 mbedtls_free( ctx );
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200696}
697
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200698const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
699 MBEDTLS_PK_RSA_ALT,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200700 "RSA-alt",
Manuel Pégourié-Gonnard39a48f42015-06-18 16:06:55 +0200701 rsa_alt_get_bitlen,
Manuel Pégourié-Gonnard20422e92014-06-05 13:41:44 +0200702 rsa_alt_can_do,
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200703 NULL,
704 rsa_alt_sign_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200705#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard1f596062017-05-09 10:42:40 +0200706 NULL,
707 NULL,
708#endif
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200709 rsa_alt_decrypt_wrap,
710 NULL,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200711#if defined(MBEDTLS_RSA_C)
Manuel Pégourié-Gonnarda1efcb02014-11-08 17:08:08 +0100712 rsa_alt_check_pair,
Manuel Pégourié-Gonnard7c13d692014-11-12 00:01:34 +0100713#else
714 NULL,
715#endif
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200716 rsa_alt_alloc_wrap,
717 rsa_alt_free_wrap,
Manuel Pégourié-Gonnardaaa98142017-08-18 17:30:37 +0200718#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard0bbc66c2017-08-18 16:22:06 +0200719 NULL,
720 NULL,
721#endif
Manuel Pégourié-Gonnard12c1ff02013-08-21 12:28:31 +0200722 NULL,
723};
Manuel Pégourié-Gonnardc40b4c32013-08-22 13:29:31 +0200724
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200725#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
Manuel Pégourié-Gonnard348bcb32015-03-31 14:01:33 +0200726
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200727#if defined(MBEDTLS_USE_PSA_CRYPTO)
728
Manuel Pégourié-Gonnard69baf702018-11-06 09:34:30 +0100729static void *pk_opaque_alloc_wrap( void )
Manuel Pégourié-Gonnard7b5fe042018-10-31 09:57:45 +0100730{
731 void *ctx = mbedtls_calloc( 1, sizeof( psa_key_slot_t ) );
732
733 /* no _init() function to call, an calloc() already zeroized */
734
735 return( ctx );
736}
737
Manuel Pégourié-Gonnard69baf702018-11-06 09:34:30 +0100738static void pk_opaque_free_wrap( void *ctx )
Manuel Pégourié-Gonnard7b5fe042018-10-31 09:57:45 +0100739{
740 mbedtls_platform_zeroize( ctx, sizeof( psa_key_slot_t ) );
741 mbedtls_free( ctx );
742}
743
Manuel Pégourié-Gonnard69baf702018-11-06 09:34:30 +0100744static size_t pk_opaque_get_bitlen( const void *ctx )
Manuel Pégourié-Gonnard0184b3c2018-10-31 10:36:51 +0100745{
746 const psa_key_slot_t *key = (const psa_key_slot_t *) ctx;
747 size_t bits;
748
749 if( PSA_SUCCESS != psa_get_key_information( *key, NULL, &bits ) )
750 return( 0 );
751
752 return( bits );
753}
754
Manuel Pégourié-Gonnard69baf702018-11-06 09:34:30 +0100755static int pk_opaque_can_do( mbedtls_pk_type_t type )
Manuel Pégourié-Gonnard920c0632018-10-31 10:57:29 +0100756{
757 /* For now opaque PSA keys can only wrap ECC keypairs,
758 * as checked by setup_psa().
759 * Also, ECKEY_DH does not really make sense with the current API. */
760 return( type == MBEDTLS_PK_ECKEY ||
761 type == MBEDTLS_PK_ECDSA );
762}
763
Manuel Pégourié-Gonnard36867712018-10-31 16:22:49 +0100764/* Like mbedtls_asn1_write_mpi, but from a buffer */
765static int asn1_write_mpibuf( unsigned char **p, unsigned char *start,
766 const unsigned char *src, size_t slen )
767{
768 int ret;
769 size_t len = 0;
770
771 if( (size_t)( *p - start ) < slen )
772 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
773
774 len = slen;
775 *p -= len;
776 memcpy( *p, src, len );
777
778 if( **p & 0x80 )
779 {
780 if( *p - start < 1 )
781 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
782
783 *--(*p) = 0x00;
784 len += 1;
785 }
786
787 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
788 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_INTEGER ) );
789
790 return( (int) len );
791}
792
793/* Transcode signature from PSA format to ASN.1 sequence.
794 * See ecdsa_signature_to_asn1 in ecdsa.c.
795 *
796 * [in] sig: the signature in PSA format
797 * [in/out] sig_len: signature length pre- and post-transcoding
798 * [out] dst: the signature in ASN.1 format
799 */
800static int pk_ecdsa_sig_asn1_from_psa( const unsigned char *sig, size_t *sig_len,
801 unsigned char *dst )
802{
803 int ret;
804 unsigned char buf[MBEDTLS_ECDSA_MAX_LEN];
805 unsigned char *p = buf + sizeof( buf );
806 size_t len = 0;
807 const size_t mpi_len = *sig_len / 2;
808
809 MBEDTLS_ASN1_CHK_ADD( len, asn1_write_mpibuf( &p, buf, sig + mpi_len, mpi_len ) );
810 MBEDTLS_ASN1_CHK_ADD( len, asn1_write_mpibuf( &p, buf, sig, mpi_len ) );
811
812 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &p, buf, len ) );
813 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, buf,
814 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
815
816 memcpy( dst, p, len );
817 *sig_len = len;
818
819 return( 0 );
820}
821
Manuel Pégourié-Gonnard69baf702018-11-06 09:34:30 +0100822static int pk_opaque_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard36867712018-10-31 16:22:49 +0100823 const unsigned char *hash, size_t hash_len,
824 unsigned char *sig, size_t *sig_len,
825 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
826{
827 const psa_key_slot_t *key = (const psa_key_slot_t *) ctx;
828 psa_status_t status;
829 psa_algorithm_t alg = PSA_ALG_ECDSA( mbedtls_psa_translate_md( md_alg ) );
830 /* PSA needs a buffer of know size */
831 unsigned char buf[2 * MBEDTLS_ECP_MAX_BYTES];
832 const size_t buf_len = sizeof( buf );
833
834 /* PSA has its own RNG */
835 (void) f_rng;
836 (void) p_rng;
837
838 status = psa_asymmetric_sign( *key, alg, hash, hash_len,
839 buf, buf_len, sig_len );
840
841 /* translate errors to best approximation */
842 switch( status )
843 {
844 case PSA_SUCCESS:
845 break; /* don't return now */
846 case PSA_ERROR_NOT_SUPPORTED:
847 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
848 case PSA_ERROR_INSUFFICIENT_MEMORY:
849 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
850 case PSA_ERROR_COMMUNICATION_FAILURE:
851 case PSA_ERROR_HARDWARE_FAILURE:
852 case PSA_ERROR_TAMPERING_DETECTED:
853 return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
854 case PSA_ERROR_INSUFFICIENT_ENTROPY:
855 return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
856 case PSA_ERROR_BAD_STATE:
857 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
858 default: /* should never happen */
859 return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
860 }
861
862 pk_ecdsa_sig_asn1_from_psa( buf, sig_len, sig );
863
864 return( 0 );
865}
866
Manuel Pégourié-Gonnard69baf702018-11-06 09:34:30 +0100867const mbedtls_pk_info_t mbedtls_pk_opaque_info = {
868 MBEDTLS_PK_OPAQUE,
869 "Opaque",
870 pk_opaque_get_bitlen,
871 pk_opaque_can_do,
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200872 NULL, /* verify - will be done later */
Manuel Pégourié-Gonnard69baf702018-11-06 09:34:30 +0100873 pk_opaque_sign_wrap,
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200874#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
875 NULL, /* restartable verify - not relevant */
876 NULL, /* restartable sign - not relevant */
877#endif
878 NULL, /* decrypt - will be done later */
879 NULL, /* encrypt - will be done later */
880 NULL, /* check_pair - could be done later or left NULL */
Manuel Pégourié-Gonnard69baf702018-11-06 09:34:30 +0100881 pk_opaque_alloc_wrap,
882 pk_opaque_free_wrap,
Manuel Pégourié-Gonnard20678b22018-10-22 12:11:15 +0200883#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
884 NULL, /* restart alloc - not relevant */
885 NULL, /* restart free - not relevant */
886#endif
887 NULL, /* debug - could be done later, or even left NULL */
888};
889
890#endif /* MBEDTLS_USE_PSA_CRYPTO */
891
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200892#endif /* MBEDTLS_PK_C */