mbed-os5 only for TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Committer:
kenjiArai
Date:
Tue Dec 17 23:23:45 2019 +0000
Revision:
0:5b88d5760320
Child:
1:9db0e321a9f4
mbed-os5 only for TYBLE16

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 0:5b88d5760320 1 /*
kenjiArai 0:5b88d5760320 2 * Public Key abstraction layer: wrapper functions
kenjiArai 0:5b88d5760320 3 *
kenjiArai 0:5b88d5760320 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
kenjiArai 0:5b88d5760320 5 * SPDX-License-Identifier: Apache-2.0
kenjiArai 0:5b88d5760320 6 *
kenjiArai 0:5b88d5760320 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
kenjiArai 0:5b88d5760320 8 * not use this file except in compliance with the License.
kenjiArai 0:5b88d5760320 9 * You may obtain a copy of the License at
kenjiArai 0:5b88d5760320 10 *
kenjiArai 0:5b88d5760320 11 * http://www.apache.org/licenses/LICENSE-2.0
kenjiArai 0:5b88d5760320 12 *
kenjiArai 0:5b88d5760320 13 * Unless required by applicable law or agreed to in writing, software
kenjiArai 0:5b88d5760320 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
kenjiArai 0:5b88d5760320 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kenjiArai 0:5b88d5760320 16 * See the License for the specific language governing permissions and
kenjiArai 0:5b88d5760320 17 * limitations under the License.
kenjiArai 0:5b88d5760320 18 *
kenjiArai 0:5b88d5760320 19 * This file is part of mbed TLS (https://tls.mbed.org)
kenjiArai 0:5b88d5760320 20 */
kenjiArai 0:5b88d5760320 21
kenjiArai 0:5b88d5760320 22 #if !defined(MBEDTLS_CONFIG_FILE)
kenjiArai 0:5b88d5760320 23 #include "mbedtls/config.h"
kenjiArai 0:5b88d5760320 24 #else
kenjiArai 0:5b88d5760320 25 #include MBEDTLS_CONFIG_FILE
kenjiArai 0:5b88d5760320 26 #endif
kenjiArai 0:5b88d5760320 27
kenjiArai 0:5b88d5760320 28 #if defined(MBEDTLS_PK_C)
kenjiArai 0:5b88d5760320 29 #include "mbedtls/pk_internal.h"
kenjiArai 0:5b88d5760320 30
kenjiArai 0:5b88d5760320 31 /* Even if RSA not activated, for the sake of RSA-alt */
kenjiArai 0:5b88d5760320 32 #include "mbedtls/rsa.h"
kenjiArai 0:5b88d5760320 33
kenjiArai 0:5b88d5760320 34 #include <string.h>
kenjiArai 0:5b88d5760320 35
kenjiArai 0:5b88d5760320 36 #if defined(MBEDTLS_ECP_C)
kenjiArai 0:5b88d5760320 37 #include "mbedtls/ecp.h"
kenjiArai 0:5b88d5760320 38 #endif
kenjiArai 0:5b88d5760320 39
kenjiArai 0:5b88d5760320 40 #if defined(MBEDTLS_ECDSA_C)
kenjiArai 0:5b88d5760320 41 #include "mbedtls/ecdsa.h"
kenjiArai 0:5b88d5760320 42 #endif
kenjiArai 0:5b88d5760320 43
kenjiArai 0:5b88d5760320 44 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 45 #include "mbedtls/asn1write.h"
kenjiArai 0:5b88d5760320 46 #endif
kenjiArai 0:5b88d5760320 47
kenjiArai 0:5b88d5760320 48 #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
kenjiArai 0:5b88d5760320 49 #include "mbedtls/platform_util.h"
kenjiArai 0:5b88d5760320 50 #endif
kenjiArai 0:5b88d5760320 51
kenjiArai 0:5b88d5760320 52 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 53 #include "psa/crypto.h"
kenjiArai 0:5b88d5760320 54 #include "mbedtls/psa_util.h"
kenjiArai 0:5b88d5760320 55 #include "mbedtls/asn1.h"
kenjiArai 0:5b88d5760320 56 #endif
kenjiArai 0:5b88d5760320 57
kenjiArai 0:5b88d5760320 58 #if defined(MBEDTLS_PLATFORM_C)
kenjiArai 0:5b88d5760320 59 #include "mbedtls/platform.h"
kenjiArai 0:5b88d5760320 60 #else
kenjiArai 0:5b88d5760320 61 #include <stdlib.h>
kenjiArai 0:5b88d5760320 62 #define mbedtls_calloc calloc
kenjiArai 0:5b88d5760320 63 #define mbedtls_free free
kenjiArai 0:5b88d5760320 64 #endif
kenjiArai 0:5b88d5760320 65
kenjiArai 0:5b88d5760320 66 #include <limits.h>
kenjiArai 0:5b88d5760320 67 #include <stdint.h>
kenjiArai 0:5b88d5760320 68
kenjiArai 0:5b88d5760320 69 #if defined(MBEDTLS_RSA_C)
kenjiArai 0:5b88d5760320 70 static int rsa_can_do( mbedtls_pk_type_t type )
kenjiArai 0:5b88d5760320 71 {
kenjiArai 0:5b88d5760320 72 return( type == MBEDTLS_PK_RSA ||
kenjiArai 0:5b88d5760320 73 type == MBEDTLS_PK_RSASSA_PSS );
kenjiArai 0:5b88d5760320 74 }
kenjiArai 0:5b88d5760320 75
kenjiArai 0:5b88d5760320 76 static size_t rsa_get_bitlen( const void *ctx )
kenjiArai 0:5b88d5760320 77 {
kenjiArai 0:5b88d5760320 78 const mbedtls_rsa_context * rsa = (const mbedtls_rsa_context *) ctx;
kenjiArai 0:5b88d5760320 79 return( 8 * mbedtls_rsa_get_len( rsa ) );
kenjiArai 0:5b88d5760320 80 }
kenjiArai 0:5b88d5760320 81
kenjiArai 0:5b88d5760320 82 static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
kenjiArai 0:5b88d5760320 83 const unsigned char *hash, size_t hash_len,
kenjiArai 0:5b88d5760320 84 const unsigned char *sig, size_t sig_len )
kenjiArai 0:5b88d5760320 85 {
kenjiArai 0:5b88d5760320 86 int ret;
kenjiArai 0:5b88d5760320 87 mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
kenjiArai 0:5b88d5760320 88 size_t rsa_len = mbedtls_rsa_get_len( rsa );
kenjiArai 0:5b88d5760320 89
kenjiArai 0:5b88d5760320 90 #if SIZE_MAX > UINT_MAX
kenjiArai 0:5b88d5760320 91 if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
kenjiArai 0:5b88d5760320 92 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 93 #endif /* SIZE_MAX > UINT_MAX */
kenjiArai 0:5b88d5760320 94
kenjiArai 0:5b88d5760320 95 if( sig_len < rsa_len )
kenjiArai 0:5b88d5760320 96 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
kenjiArai 0:5b88d5760320 97
kenjiArai 0:5b88d5760320 98 if( ( ret = mbedtls_rsa_pkcs1_verify( rsa, NULL, NULL,
kenjiArai 0:5b88d5760320 99 MBEDTLS_RSA_PUBLIC, md_alg,
kenjiArai 0:5b88d5760320 100 (unsigned int) hash_len, hash, sig ) ) != 0 )
kenjiArai 0:5b88d5760320 101 return( ret );
kenjiArai 0:5b88d5760320 102
kenjiArai 0:5b88d5760320 103 /* The buffer contains a valid signature followed by extra data.
kenjiArai 0:5b88d5760320 104 * We have a special error code for that so that so that callers can
kenjiArai 0:5b88d5760320 105 * use mbedtls_pk_verify() to check "Does the buffer start with a
kenjiArai 0:5b88d5760320 106 * valid signature?" and not just "Does the buffer contain a valid
kenjiArai 0:5b88d5760320 107 * signature?". */
kenjiArai 0:5b88d5760320 108 if( sig_len > rsa_len )
kenjiArai 0:5b88d5760320 109 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
kenjiArai 0:5b88d5760320 110
kenjiArai 0:5b88d5760320 111 return( 0 );
kenjiArai 0:5b88d5760320 112 }
kenjiArai 0:5b88d5760320 113
kenjiArai 0:5b88d5760320 114 static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
kenjiArai 0:5b88d5760320 115 const unsigned char *hash, size_t hash_len,
kenjiArai 0:5b88d5760320 116 unsigned char *sig, size_t *sig_len,
kenjiArai 0:5b88d5760320 117 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
kenjiArai 0:5b88d5760320 118 {
kenjiArai 0:5b88d5760320 119 mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
kenjiArai 0:5b88d5760320 120
kenjiArai 0:5b88d5760320 121 #if SIZE_MAX > UINT_MAX
kenjiArai 0:5b88d5760320 122 if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
kenjiArai 0:5b88d5760320 123 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 124 #endif /* SIZE_MAX > UINT_MAX */
kenjiArai 0:5b88d5760320 125
kenjiArai 0:5b88d5760320 126 *sig_len = mbedtls_rsa_get_len( rsa );
kenjiArai 0:5b88d5760320 127
kenjiArai 0:5b88d5760320 128 return( mbedtls_rsa_pkcs1_sign( rsa, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
kenjiArai 0:5b88d5760320 129 md_alg, (unsigned int) hash_len, hash, sig ) );
kenjiArai 0:5b88d5760320 130 }
kenjiArai 0:5b88d5760320 131
kenjiArai 0:5b88d5760320 132 static int rsa_decrypt_wrap( void *ctx,
kenjiArai 0:5b88d5760320 133 const unsigned char *input, size_t ilen,
kenjiArai 0:5b88d5760320 134 unsigned char *output, size_t *olen, size_t osize,
kenjiArai 0:5b88d5760320 135 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
kenjiArai 0:5b88d5760320 136 {
kenjiArai 0:5b88d5760320 137 mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
kenjiArai 0:5b88d5760320 138
kenjiArai 0:5b88d5760320 139 if( ilen != mbedtls_rsa_get_len( rsa ) )
kenjiArai 0:5b88d5760320 140 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 141
kenjiArai 0:5b88d5760320 142 return( mbedtls_rsa_pkcs1_decrypt( rsa, f_rng, p_rng,
kenjiArai 0:5b88d5760320 143 MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
kenjiArai 0:5b88d5760320 144 }
kenjiArai 0:5b88d5760320 145
kenjiArai 0:5b88d5760320 146 static int rsa_encrypt_wrap( void *ctx,
kenjiArai 0:5b88d5760320 147 const unsigned char *input, size_t ilen,
kenjiArai 0:5b88d5760320 148 unsigned char *output, size_t *olen, size_t osize,
kenjiArai 0:5b88d5760320 149 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
kenjiArai 0:5b88d5760320 150 {
kenjiArai 0:5b88d5760320 151 mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
kenjiArai 0:5b88d5760320 152 *olen = mbedtls_rsa_get_len( rsa );
kenjiArai 0:5b88d5760320 153
kenjiArai 0:5b88d5760320 154 if( *olen > osize )
kenjiArai 0:5b88d5760320 155 return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE );
kenjiArai 0:5b88d5760320 156
kenjiArai 0:5b88d5760320 157 return( mbedtls_rsa_pkcs1_encrypt( rsa, f_rng, p_rng, MBEDTLS_RSA_PUBLIC,
kenjiArai 0:5b88d5760320 158 ilen, input, output ) );
kenjiArai 0:5b88d5760320 159 }
kenjiArai 0:5b88d5760320 160
kenjiArai 0:5b88d5760320 161 static int rsa_check_pair_wrap( const void *pub, const void *prv )
kenjiArai 0:5b88d5760320 162 {
kenjiArai 0:5b88d5760320 163 return( mbedtls_rsa_check_pub_priv( (const mbedtls_rsa_context *) pub,
kenjiArai 0:5b88d5760320 164 (const mbedtls_rsa_context *) prv ) );
kenjiArai 0:5b88d5760320 165 }
kenjiArai 0:5b88d5760320 166
kenjiArai 0:5b88d5760320 167 static void *rsa_alloc_wrap( void )
kenjiArai 0:5b88d5760320 168 {
kenjiArai 0:5b88d5760320 169 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_context ) );
kenjiArai 0:5b88d5760320 170
kenjiArai 0:5b88d5760320 171 if( ctx != NULL )
kenjiArai 0:5b88d5760320 172 mbedtls_rsa_init( (mbedtls_rsa_context *) ctx, 0, 0 );
kenjiArai 0:5b88d5760320 173
kenjiArai 0:5b88d5760320 174 return( ctx );
kenjiArai 0:5b88d5760320 175 }
kenjiArai 0:5b88d5760320 176
kenjiArai 0:5b88d5760320 177 static void rsa_free_wrap( void *ctx )
kenjiArai 0:5b88d5760320 178 {
kenjiArai 0:5b88d5760320 179 mbedtls_rsa_free( (mbedtls_rsa_context *) ctx );
kenjiArai 0:5b88d5760320 180 mbedtls_free( ctx );
kenjiArai 0:5b88d5760320 181 }
kenjiArai 0:5b88d5760320 182
kenjiArai 0:5b88d5760320 183 static void rsa_debug( const void *ctx, mbedtls_pk_debug_item *items )
kenjiArai 0:5b88d5760320 184 {
kenjiArai 0:5b88d5760320 185 items->type = MBEDTLS_PK_DEBUG_MPI;
kenjiArai 0:5b88d5760320 186 items->name = "rsa.N";
kenjiArai 0:5b88d5760320 187 items->value = &( ((mbedtls_rsa_context *) ctx)->N );
kenjiArai 0:5b88d5760320 188
kenjiArai 0:5b88d5760320 189 items++;
kenjiArai 0:5b88d5760320 190
kenjiArai 0:5b88d5760320 191 items->type = MBEDTLS_PK_DEBUG_MPI;
kenjiArai 0:5b88d5760320 192 items->name = "rsa.E";
kenjiArai 0:5b88d5760320 193 items->value = &( ((mbedtls_rsa_context *) ctx)->E );
kenjiArai 0:5b88d5760320 194 }
kenjiArai 0:5b88d5760320 195
kenjiArai 0:5b88d5760320 196 const mbedtls_pk_info_t mbedtls_rsa_info = {
kenjiArai 0:5b88d5760320 197 MBEDTLS_PK_RSA,
kenjiArai 0:5b88d5760320 198 "RSA",
kenjiArai 0:5b88d5760320 199 rsa_get_bitlen,
kenjiArai 0:5b88d5760320 200 rsa_can_do,
kenjiArai 0:5b88d5760320 201 rsa_verify_wrap,
kenjiArai 0:5b88d5760320 202 rsa_sign_wrap,
kenjiArai 0:5b88d5760320 203 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 204 NULL,
kenjiArai 0:5b88d5760320 205 NULL,
kenjiArai 0:5b88d5760320 206 #endif
kenjiArai 0:5b88d5760320 207 rsa_decrypt_wrap,
kenjiArai 0:5b88d5760320 208 rsa_encrypt_wrap,
kenjiArai 0:5b88d5760320 209 rsa_check_pair_wrap,
kenjiArai 0:5b88d5760320 210 rsa_alloc_wrap,
kenjiArai 0:5b88d5760320 211 rsa_free_wrap,
kenjiArai 0:5b88d5760320 212 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 213 NULL,
kenjiArai 0:5b88d5760320 214 NULL,
kenjiArai 0:5b88d5760320 215 #endif
kenjiArai 0:5b88d5760320 216 rsa_debug,
kenjiArai 0:5b88d5760320 217 };
kenjiArai 0:5b88d5760320 218 #endif /* MBEDTLS_RSA_C */
kenjiArai 0:5b88d5760320 219
kenjiArai 0:5b88d5760320 220 #if defined(MBEDTLS_ECP_C)
kenjiArai 0:5b88d5760320 221 /*
kenjiArai 0:5b88d5760320 222 * Generic EC key
kenjiArai 0:5b88d5760320 223 */
kenjiArai 0:5b88d5760320 224 static int eckey_can_do( mbedtls_pk_type_t type )
kenjiArai 0:5b88d5760320 225 {
kenjiArai 0:5b88d5760320 226 return( type == MBEDTLS_PK_ECKEY ||
kenjiArai 0:5b88d5760320 227 type == MBEDTLS_PK_ECKEY_DH ||
kenjiArai 0:5b88d5760320 228 type == MBEDTLS_PK_ECDSA );
kenjiArai 0:5b88d5760320 229 }
kenjiArai 0:5b88d5760320 230
kenjiArai 0:5b88d5760320 231 static size_t eckey_get_bitlen( const void *ctx )
kenjiArai 0:5b88d5760320 232 {
kenjiArai 0:5b88d5760320 233 return( ((mbedtls_ecp_keypair *) ctx)->grp.pbits );
kenjiArai 0:5b88d5760320 234 }
kenjiArai 0:5b88d5760320 235
kenjiArai 0:5b88d5760320 236 #if defined(MBEDTLS_ECDSA_C)
kenjiArai 0:5b88d5760320 237 /* Forward declarations */
kenjiArai 0:5b88d5760320 238 static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
kenjiArai 0:5b88d5760320 239 const unsigned char *hash, size_t hash_len,
kenjiArai 0:5b88d5760320 240 const unsigned char *sig, size_t sig_len );
kenjiArai 0:5b88d5760320 241
kenjiArai 0:5b88d5760320 242 static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
kenjiArai 0:5b88d5760320 243 const unsigned char *hash, size_t hash_len,
kenjiArai 0:5b88d5760320 244 unsigned char *sig, size_t *sig_len,
kenjiArai 0:5b88d5760320 245 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
kenjiArai 0:5b88d5760320 246
kenjiArai 0:5b88d5760320 247 static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
kenjiArai 0:5b88d5760320 248 const unsigned char *hash, size_t hash_len,
kenjiArai 0:5b88d5760320 249 const unsigned char *sig, size_t sig_len )
kenjiArai 0:5b88d5760320 250 {
kenjiArai 0:5b88d5760320 251 int ret;
kenjiArai 0:5b88d5760320 252 mbedtls_ecdsa_context ecdsa;
kenjiArai 0:5b88d5760320 253
kenjiArai 0:5b88d5760320 254 mbedtls_ecdsa_init( &ecdsa );
kenjiArai 0:5b88d5760320 255
kenjiArai 0:5b88d5760320 256 if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
kenjiArai 0:5b88d5760320 257 ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len );
kenjiArai 0:5b88d5760320 258
kenjiArai 0:5b88d5760320 259 mbedtls_ecdsa_free( &ecdsa );
kenjiArai 0:5b88d5760320 260
kenjiArai 0:5b88d5760320 261 return( ret );
kenjiArai 0:5b88d5760320 262 }
kenjiArai 0:5b88d5760320 263
kenjiArai 0:5b88d5760320 264 static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
kenjiArai 0:5b88d5760320 265 const unsigned char *hash, size_t hash_len,
kenjiArai 0:5b88d5760320 266 unsigned char *sig, size_t *sig_len,
kenjiArai 0:5b88d5760320 267 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
kenjiArai 0:5b88d5760320 268 {
kenjiArai 0:5b88d5760320 269 int ret;
kenjiArai 0:5b88d5760320 270 mbedtls_ecdsa_context ecdsa;
kenjiArai 0:5b88d5760320 271
kenjiArai 0:5b88d5760320 272 mbedtls_ecdsa_init( &ecdsa );
kenjiArai 0:5b88d5760320 273
kenjiArai 0:5b88d5760320 274 if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
kenjiArai 0:5b88d5760320 275 ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len,
kenjiArai 0:5b88d5760320 276 f_rng, p_rng );
kenjiArai 0:5b88d5760320 277
kenjiArai 0:5b88d5760320 278 mbedtls_ecdsa_free( &ecdsa );
kenjiArai 0:5b88d5760320 279
kenjiArai 0:5b88d5760320 280 return( ret );
kenjiArai 0:5b88d5760320 281 }
kenjiArai 0:5b88d5760320 282
kenjiArai 0:5b88d5760320 283 #if defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 284 /* Forward declarations */
kenjiArai 0:5b88d5760320 285 static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
kenjiArai 0:5b88d5760320 286 const unsigned char *hash, size_t hash_len,
kenjiArai 0:5b88d5760320 287 const unsigned char *sig, size_t sig_len,
kenjiArai 0:5b88d5760320 288 void *rs_ctx );
kenjiArai 0:5b88d5760320 289
kenjiArai 0:5b88d5760320 290 static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
kenjiArai 0:5b88d5760320 291 const unsigned char *hash, size_t hash_len,
kenjiArai 0:5b88d5760320 292 unsigned char *sig, size_t *sig_len,
kenjiArai 0:5b88d5760320 293 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
kenjiArai 0:5b88d5760320 294 void *rs_ctx );
kenjiArai 0:5b88d5760320 295
kenjiArai 0:5b88d5760320 296 /*
kenjiArai 0:5b88d5760320 297 * Restart context for ECDSA operations with ECKEY context
kenjiArai 0:5b88d5760320 298 *
kenjiArai 0:5b88d5760320 299 * We need to store an actual ECDSA context, as we need to pass the same to
kenjiArai 0:5b88d5760320 300 * the underlying ecdsa function, so we can't create it on the fly every time.
kenjiArai 0:5b88d5760320 301 */
kenjiArai 0:5b88d5760320 302 typedef struct
kenjiArai 0:5b88d5760320 303 {
kenjiArai 0:5b88d5760320 304 mbedtls_ecdsa_restart_ctx ecdsa_rs;
kenjiArai 0:5b88d5760320 305 mbedtls_ecdsa_context ecdsa_ctx;
kenjiArai 0:5b88d5760320 306 } eckey_restart_ctx;
kenjiArai 0:5b88d5760320 307
kenjiArai 0:5b88d5760320 308 static void *eckey_rs_alloc( void )
kenjiArai 0:5b88d5760320 309 {
kenjiArai 0:5b88d5760320 310 eckey_restart_ctx *rs_ctx;
kenjiArai 0:5b88d5760320 311
kenjiArai 0:5b88d5760320 312 void *ctx = mbedtls_calloc( 1, sizeof( eckey_restart_ctx ) );
kenjiArai 0:5b88d5760320 313
kenjiArai 0:5b88d5760320 314 if( ctx != NULL )
kenjiArai 0:5b88d5760320 315 {
kenjiArai 0:5b88d5760320 316 rs_ctx = ctx;
kenjiArai 0:5b88d5760320 317 mbedtls_ecdsa_restart_init( &rs_ctx->ecdsa_rs );
kenjiArai 0:5b88d5760320 318 mbedtls_ecdsa_init( &rs_ctx->ecdsa_ctx );
kenjiArai 0:5b88d5760320 319 }
kenjiArai 0:5b88d5760320 320
kenjiArai 0:5b88d5760320 321 return( ctx );
kenjiArai 0:5b88d5760320 322 }
kenjiArai 0:5b88d5760320 323
kenjiArai 0:5b88d5760320 324 static void eckey_rs_free( void *ctx )
kenjiArai 0:5b88d5760320 325 {
kenjiArai 0:5b88d5760320 326 eckey_restart_ctx *rs_ctx;
kenjiArai 0:5b88d5760320 327
kenjiArai 0:5b88d5760320 328 if( ctx == NULL)
kenjiArai 0:5b88d5760320 329 return;
kenjiArai 0:5b88d5760320 330
kenjiArai 0:5b88d5760320 331 rs_ctx = ctx;
kenjiArai 0:5b88d5760320 332 mbedtls_ecdsa_restart_free( &rs_ctx->ecdsa_rs );
kenjiArai 0:5b88d5760320 333 mbedtls_ecdsa_free( &rs_ctx->ecdsa_ctx );
kenjiArai 0:5b88d5760320 334
kenjiArai 0:5b88d5760320 335 mbedtls_free( ctx );
kenjiArai 0:5b88d5760320 336 }
kenjiArai 0:5b88d5760320 337
kenjiArai 0:5b88d5760320 338 static int eckey_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
kenjiArai 0:5b88d5760320 339 const unsigned char *hash, size_t hash_len,
kenjiArai 0:5b88d5760320 340 const unsigned char *sig, size_t sig_len,
kenjiArai 0:5b88d5760320 341 void *rs_ctx )
kenjiArai 0:5b88d5760320 342 {
kenjiArai 0:5b88d5760320 343 int ret;
kenjiArai 0:5b88d5760320 344 eckey_restart_ctx *rs = rs_ctx;
kenjiArai 0:5b88d5760320 345
kenjiArai 0:5b88d5760320 346 /* Should never happen */
kenjiArai 0:5b88d5760320 347 if( rs == NULL )
kenjiArai 0:5b88d5760320 348 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 349
kenjiArai 0:5b88d5760320 350 /* set up our own sub-context if needed (that is, on first run) */
kenjiArai 0:5b88d5760320 351 if( rs->ecdsa_ctx.grp.pbits == 0 )
kenjiArai 0:5b88d5760320 352 MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) );
kenjiArai 0:5b88d5760320 353
kenjiArai 0:5b88d5760320 354 MBEDTLS_MPI_CHK( ecdsa_verify_rs_wrap( &rs->ecdsa_ctx,
kenjiArai 0:5b88d5760320 355 md_alg, hash, hash_len,
kenjiArai 0:5b88d5760320 356 sig, sig_len, &rs->ecdsa_rs ) );
kenjiArai 0:5b88d5760320 357
kenjiArai 0:5b88d5760320 358 cleanup:
kenjiArai 0:5b88d5760320 359 return( ret );
kenjiArai 0:5b88d5760320 360 }
kenjiArai 0:5b88d5760320 361
kenjiArai 0:5b88d5760320 362 static int eckey_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
kenjiArai 0:5b88d5760320 363 const unsigned char *hash, size_t hash_len,
kenjiArai 0:5b88d5760320 364 unsigned char *sig, size_t *sig_len,
kenjiArai 0:5b88d5760320 365 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
kenjiArai 0:5b88d5760320 366 void *rs_ctx )
kenjiArai 0:5b88d5760320 367 {
kenjiArai 0:5b88d5760320 368 int ret;
kenjiArai 0:5b88d5760320 369 eckey_restart_ctx *rs = rs_ctx;
kenjiArai 0:5b88d5760320 370
kenjiArai 0:5b88d5760320 371 /* Should never happen */
kenjiArai 0:5b88d5760320 372 if( rs == NULL )
kenjiArai 0:5b88d5760320 373 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 374
kenjiArai 0:5b88d5760320 375 /* set up our own sub-context if needed (that is, on first run) */
kenjiArai 0:5b88d5760320 376 if( rs->ecdsa_ctx.grp.pbits == 0 )
kenjiArai 0:5b88d5760320 377 MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) );
kenjiArai 0:5b88d5760320 378
kenjiArai 0:5b88d5760320 379 MBEDTLS_MPI_CHK( ecdsa_sign_rs_wrap( &rs->ecdsa_ctx, md_alg,
kenjiArai 0:5b88d5760320 380 hash, hash_len, sig, sig_len,
kenjiArai 0:5b88d5760320 381 f_rng, p_rng, &rs->ecdsa_rs ) );
kenjiArai 0:5b88d5760320 382
kenjiArai 0:5b88d5760320 383 cleanup:
kenjiArai 0:5b88d5760320 384 return( ret );
kenjiArai 0:5b88d5760320 385 }
kenjiArai 0:5b88d5760320 386 #endif /* MBEDTLS_ECP_RESTARTABLE */
kenjiArai 0:5b88d5760320 387 #endif /* MBEDTLS_ECDSA_C */
kenjiArai 0:5b88d5760320 388
kenjiArai 0:5b88d5760320 389 static int eckey_check_pair( const void *pub, const void *prv )
kenjiArai 0:5b88d5760320 390 {
kenjiArai 0:5b88d5760320 391 return( mbedtls_ecp_check_pub_priv( (const mbedtls_ecp_keypair *) pub,
kenjiArai 0:5b88d5760320 392 (const mbedtls_ecp_keypair *) prv ) );
kenjiArai 0:5b88d5760320 393 }
kenjiArai 0:5b88d5760320 394
kenjiArai 0:5b88d5760320 395 static void *eckey_alloc_wrap( void )
kenjiArai 0:5b88d5760320 396 {
kenjiArai 0:5b88d5760320 397 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
kenjiArai 0:5b88d5760320 398
kenjiArai 0:5b88d5760320 399 if( ctx != NULL )
kenjiArai 0:5b88d5760320 400 mbedtls_ecp_keypair_init( ctx );
kenjiArai 0:5b88d5760320 401
kenjiArai 0:5b88d5760320 402 return( ctx );
kenjiArai 0:5b88d5760320 403 }
kenjiArai 0:5b88d5760320 404
kenjiArai 0:5b88d5760320 405 static void eckey_free_wrap( void *ctx )
kenjiArai 0:5b88d5760320 406 {
kenjiArai 0:5b88d5760320 407 mbedtls_ecp_keypair_free( (mbedtls_ecp_keypair *) ctx );
kenjiArai 0:5b88d5760320 408 mbedtls_free( ctx );
kenjiArai 0:5b88d5760320 409 }
kenjiArai 0:5b88d5760320 410
kenjiArai 0:5b88d5760320 411 static void eckey_debug( const void *ctx, mbedtls_pk_debug_item *items )
kenjiArai 0:5b88d5760320 412 {
kenjiArai 0:5b88d5760320 413 items->type = MBEDTLS_PK_DEBUG_ECP;
kenjiArai 0:5b88d5760320 414 items->name = "eckey.Q";
kenjiArai 0:5b88d5760320 415 items->value = &( ((mbedtls_ecp_keypair *) ctx)->Q );
kenjiArai 0:5b88d5760320 416 }
kenjiArai 0:5b88d5760320 417
kenjiArai 0:5b88d5760320 418 const mbedtls_pk_info_t mbedtls_eckey_info = {
kenjiArai 0:5b88d5760320 419 MBEDTLS_PK_ECKEY,
kenjiArai 0:5b88d5760320 420 "EC",
kenjiArai 0:5b88d5760320 421 eckey_get_bitlen,
kenjiArai 0:5b88d5760320 422 eckey_can_do,
kenjiArai 0:5b88d5760320 423 #if defined(MBEDTLS_ECDSA_C)
kenjiArai 0:5b88d5760320 424 eckey_verify_wrap,
kenjiArai 0:5b88d5760320 425 eckey_sign_wrap,
kenjiArai 0:5b88d5760320 426 #if defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 427 eckey_verify_rs_wrap,
kenjiArai 0:5b88d5760320 428 eckey_sign_rs_wrap,
kenjiArai 0:5b88d5760320 429 #endif
kenjiArai 0:5b88d5760320 430 #else /* MBEDTLS_ECDSA_C */
kenjiArai 0:5b88d5760320 431 NULL,
kenjiArai 0:5b88d5760320 432 NULL,
kenjiArai 0:5b88d5760320 433 #endif /* MBEDTLS_ECDSA_C */
kenjiArai 0:5b88d5760320 434 NULL,
kenjiArai 0:5b88d5760320 435 NULL,
kenjiArai 0:5b88d5760320 436 eckey_check_pair,
kenjiArai 0:5b88d5760320 437 eckey_alloc_wrap,
kenjiArai 0:5b88d5760320 438 eckey_free_wrap,
kenjiArai 0:5b88d5760320 439 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 440 eckey_rs_alloc,
kenjiArai 0:5b88d5760320 441 eckey_rs_free,
kenjiArai 0:5b88d5760320 442 #endif
kenjiArai 0:5b88d5760320 443 eckey_debug,
kenjiArai 0:5b88d5760320 444 };
kenjiArai 0:5b88d5760320 445
kenjiArai 0:5b88d5760320 446 /*
kenjiArai 0:5b88d5760320 447 * EC key restricted to ECDH
kenjiArai 0:5b88d5760320 448 */
kenjiArai 0:5b88d5760320 449 static int eckeydh_can_do( mbedtls_pk_type_t type )
kenjiArai 0:5b88d5760320 450 {
kenjiArai 0:5b88d5760320 451 return( type == MBEDTLS_PK_ECKEY ||
kenjiArai 0:5b88d5760320 452 type == MBEDTLS_PK_ECKEY_DH );
kenjiArai 0:5b88d5760320 453 }
kenjiArai 0:5b88d5760320 454
kenjiArai 0:5b88d5760320 455 const mbedtls_pk_info_t mbedtls_eckeydh_info = {
kenjiArai 0:5b88d5760320 456 MBEDTLS_PK_ECKEY_DH,
kenjiArai 0:5b88d5760320 457 "EC_DH",
kenjiArai 0:5b88d5760320 458 eckey_get_bitlen, /* Same underlying key structure */
kenjiArai 0:5b88d5760320 459 eckeydh_can_do,
kenjiArai 0:5b88d5760320 460 NULL,
kenjiArai 0:5b88d5760320 461 NULL,
kenjiArai 0:5b88d5760320 462 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 463 NULL,
kenjiArai 0:5b88d5760320 464 NULL,
kenjiArai 0:5b88d5760320 465 #endif
kenjiArai 0:5b88d5760320 466 NULL,
kenjiArai 0:5b88d5760320 467 NULL,
kenjiArai 0:5b88d5760320 468 eckey_check_pair,
kenjiArai 0:5b88d5760320 469 eckey_alloc_wrap, /* Same underlying key structure */
kenjiArai 0:5b88d5760320 470 eckey_free_wrap, /* Same underlying key structure */
kenjiArai 0:5b88d5760320 471 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 472 NULL,
kenjiArai 0:5b88d5760320 473 NULL,
kenjiArai 0:5b88d5760320 474 #endif
kenjiArai 0:5b88d5760320 475 eckey_debug, /* Same underlying key structure */
kenjiArai 0:5b88d5760320 476 };
kenjiArai 0:5b88d5760320 477 #endif /* MBEDTLS_ECP_C */
kenjiArai 0:5b88d5760320 478
kenjiArai 0:5b88d5760320 479 #if defined(MBEDTLS_ECDSA_C)
kenjiArai 0:5b88d5760320 480 static int ecdsa_can_do( mbedtls_pk_type_t type )
kenjiArai 0:5b88d5760320 481 {
kenjiArai 0:5b88d5760320 482 return( type == MBEDTLS_PK_ECDSA );
kenjiArai 0:5b88d5760320 483 }
kenjiArai 0:5b88d5760320 484
kenjiArai 0:5b88d5760320 485 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 486 /*
kenjiArai 0:5b88d5760320 487 * An ASN.1 encoded signature is a sequence of two ASN.1 integers. Parse one of
kenjiArai 0:5b88d5760320 488 * those integers and convert it to the fixed-length encoding expected by PSA.
kenjiArai 0:5b88d5760320 489 */
kenjiArai 0:5b88d5760320 490 static int extract_ecdsa_sig_int( unsigned char **from, const unsigned char *end,
kenjiArai 0:5b88d5760320 491 unsigned char *to, size_t to_len )
kenjiArai 0:5b88d5760320 492 {
kenjiArai 0:5b88d5760320 493 int ret;
kenjiArai 0:5b88d5760320 494 size_t unpadded_len, padding_len;
kenjiArai 0:5b88d5760320 495
kenjiArai 0:5b88d5760320 496 if( ( ret = mbedtls_asn1_get_tag( from, end, &unpadded_len,
kenjiArai 0:5b88d5760320 497 MBEDTLS_ASN1_INTEGER ) ) != 0 )
kenjiArai 0:5b88d5760320 498 {
kenjiArai 0:5b88d5760320 499 return( ret );
kenjiArai 0:5b88d5760320 500 }
kenjiArai 0:5b88d5760320 501
kenjiArai 0:5b88d5760320 502 while( unpadded_len > 0 && **from == 0x00 )
kenjiArai 0:5b88d5760320 503 {
kenjiArai 0:5b88d5760320 504 ( *from )++;
kenjiArai 0:5b88d5760320 505 unpadded_len--;
kenjiArai 0:5b88d5760320 506 }
kenjiArai 0:5b88d5760320 507
kenjiArai 0:5b88d5760320 508 if( unpadded_len > to_len || unpadded_len == 0 )
kenjiArai 0:5b88d5760320 509 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
kenjiArai 0:5b88d5760320 510
kenjiArai 0:5b88d5760320 511 padding_len = to_len - unpadded_len;
kenjiArai 0:5b88d5760320 512 memset( to, 0x00, padding_len );
kenjiArai 0:5b88d5760320 513 memcpy( to + padding_len, *from, unpadded_len );
kenjiArai 0:5b88d5760320 514 ( *from ) += unpadded_len;
kenjiArai 0:5b88d5760320 515
kenjiArai 0:5b88d5760320 516 return( 0 );
kenjiArai 0:5b88d5760320 517 }
kenjiArai 0:5b88d5760320 518
kenjiArai 0:5b88d5760320 519 /*
kenjiArai 0:5b88d5760320 520 * Convert a signature from an ASN.1 sequence of two integers
kenjiArai 0:5b88d5760320 521 * to a raw {r,s} buffer. Note: the provided sig buffer must be at least
kenjiArai 0:5b88d5760320 522 * twice as big as int_size.
kenjiArai 0:5b88d5760320 523 */
kenjiArai 0:5b88d5760320 524 static int extract_ecdsa_sig( unsigned char **p, const unsigned char *end,
kenjiArai 0:5b88d5760320 525 unsigned char *sig, size_t int_size )
kenjiArai 0:5b88d5760320 526 {
kenjiArai 0:5b88d5760320 527 int ret;
kenjiArai 0:5b88d5760320 528 size_t tmp_size;
kenjiArai 0:5b88d5760320 529
kenjiArai 0:5b88d5760320 530 if( ( ret = mbedtls_asn1_get_tag( p, end, &tmp_size,
kenjiArai 0:5b88d5760320 531 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
kenjiArai 0:5b88d5760320 532 return( ret );
kenjiArai 0:5b88d5760320 533
kenjiArai 0:5b88d5760320 534 /* Extract r */
kenjiArai 0:5b88d5760320 535 if( ( ret = extract_ecdsa_sig_int( p, end, sig, int_size ) ) != 0 )
kenjiArai 0:5b88d5760320 536 return( ret );
kenjiArai 0:5b88d5760320 537 /* Extract s */
kenjiArai 0:5b88d5760320 538 if( ( ret = extract_ecdsa_sig_int( p, end, sig + int_size, int_size ) ) != 0 )
kenjiArai 0:5b88d5760320 539 return( ret );
kenjiArai 0:5b88d5760320 540
kenjiArai 0:5b88d5760320 541 return( 0 );
kenjiArai 0:5b88d5760320 542 }
kenjiArai 0:5b88d5760320 543
kenjiArai 0:5b88d5760320 544 static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
kenjiArai 0:5b88d5760320 545 const unsigned char *hash, size_t hash_len,
kenjiArai 0:5b88d5760320 546 const unsigned char *sig, size_t sig_len )
kenjiArai 0:5b88d5760320 547 {
kenjiArai 0:5b88d5760320 548 int ret;
kenjiArai 0:5b88d5760320 549 psa_key_handle_t key_slot;
kenjiArai 0:5b88d5760320 550 psa_key_policy_t policy;
kenjiArai 0:5b88d5760320 551 psa_key_type_t psa_type;
kenjiArai 0:5b88d5760320 552 mbedtls_pk_context key;
kenjiArai 0:5b88d5760320 553 int key_len;
kenjiArai 0:5b88d5760320 554 /* see ECP_PUB_DER_MAX_BYTES in pkwrite.c */
kenjiArai 0:5b88d5760320 555 unsigned char buf[30 + 2 * MBEDTLS_ECP_MAX_BYTES];
kenjiArai 0:5b88d5760320 556 unsigned char *p;
kenjiArai 0:5b88d5760320 557 mbedtls_pk_info_t pk_info = mbedtls_eckey_info;
kenjiArai 0:5b88d5760320 558 psa_algorithm_t psa_sig_md, psa_md;
kenjiArai 0:5b88d5760320 559 psa_ecc_curve_t curve = mbedtls_psa_translate_ecc_group(
kenjiArai 0:5b88d5760320 560 ( (mbedtls_ecdsa_context *) ctx )->grp.id );
kenjiArai 0:5b88d5760320 561 const size_t signature_part_size = ( ( (mbedtls_ecdsa_context *) ctx )->grp.nbits + 7 ) / 8;
kenjiArai 0:5b88d5760320 562
kenjiArai 0:5b88d5760320 563 if( curve == 0 )
kenjiArai 0:5b88d5760320 564 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 565
kenjiArai 0:5b88d5760320 566 /* mbedtls_pk_write_pubkey() expects a full PK context;
kenjiArai 0:5b88d5760320 567 * re-construct one to make it happy */
kenjiArai 0:5b88d5760320 568 key.pk_info = &pk_info;
kenjiArai 0:5b88d5760320 569 key.pk_ctx = ctx;
kenjiArai 0:5b88d5760320 570 p = buf + sizeof( buf );
kenjiArai 0:5b88d5760320 571 key_len = mbedtls_pk_write_pubkey( &p, buf, &key );
kenjiArai 0:5b88d5760320 572 if( key_len <= 0 )
kenjiArai 0:5b88d5760320 573 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 574
kenjiArai 0:5b88d5760320 575 psa_md = mbedtls_psa_translate_md( md_alg );
kenjiArai 0:5b88d5760320 576 if( psa_md == 0 )
kenjiArai 0:5b88d5760320 577 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 578 psa_sig_md = PSA_ALG_ECDSA( psa_md );
kenjiArai 0:5b88d5760320 579 psa_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY( curve );
kenjiArai 0:5b88d5760320 580
kenjiArai 0:5b88d5760320 581 if( ( ret = psa_allocate_key( &key_slot ) ) != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 582 return( mbedtls_psa_err_translate_pk( ret ) );
kenjiArai 0:5b88d5760320 583
kenjiArai 0:5b88d5760320 584 policy = psa_key_policy_init();
kenjiArai 0:5b88d5760320 585 psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, psa_sig_md );
kenjiArai 0:5b88d5760320 586 if( ( ret = psa_set_key_policy( key_slot, &policy ) ) != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 587 {
kenjiArai 0:5b88d5760320 588 ret = mbedtls_psa_err_translate_pk( ret );
kenjiArai 0:5b88d5760320 589 goto cleanup;
kenjiArai 0:5b88d5760320 590 }
kenjiArai 0:5b88d5760320 591
kenjiArai 0:5b88d5760320 592 if( psa_import_key( key_slot, psa_type, buf + sizeof( buf ) - key_len, key_len )
kenjiArai 0:5b88d5760320 593 != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 594 {
kenjiArai 0:5b88d5760320 595 ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;
kenjiArai 0:5b88d5760320 596 goto cleanup;
kenjiArai 0:5b88d5760320 597 }
kenjiArai 0:5b88d5760320 598
kenjiArai 0:5b88d5760320 599 /* We don't need the exported key anymore and can
kenjiArai 0:5b88d5760320 600 * reuse its buffer for signature extraction. */
kenjiArai 0:5b88d5760320 601 if( 2 * signature_part_size > sizeof( buf ) )
kenjiArai 0:5b88d5760320 602 {
kenjiArai 0:5b88d5760320 603 ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;
kenjiArai 0:5b88d5760320 604 goto cleanup;
kenjiArai 0:5b88d5760320 605 }
kenjiArai 0:5b88d5760320 606
kenjiArai 0:5b88d5760320 607 p = (unsigned char*) sig;
kenjiArai 0:5b88d5760320 608 if( ( ret = extract_ecdsa_sig( &p, sig + sig_len, buf,
kenjiArai 0:5b88d5760320 609 signature_part_size ) ) != 0 )
kenjiArai 0:5b88d5760320 610 {
kenjiArai 0:5b88d5760320 611 goto cleanup;
kenjiArai 0:5b88d5760320 612 }
kenjiArai 0:5b88d5760320 613
kenjiArai 0:5b88d5760320 614 if( psa_asymmetric_verify( key_slot, psa_sig_md,
kenjiArai 0:5b88d5760320 615 hash, hash_len,
kenjiArai 0:5b88d5760320 616 buf, 2 * signature_part_size )
kenjiArai 0:5b88d5760320 617 != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 618 {
kenjiArai 0:5b88d5760320 619 ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
kenjiArai 0:5b88d5760320 620 goto cleanup;
kenjiArai 0:5b88d5760320 621 }
kenjiArai 0:5b88d5760320 622
kenjiArai 0:5b88d5760320 623 if( p != sig + sig_len )
kenjiArai 0:5b88d5760320 624 {
kenjiArai 0:5b88d5760320 625 ret = MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
kenjiArai 0:5b88d5760320 626 goto cleanup;
kenjiArai 0:5b88d5760320 627 }
kenjiArai 0:5b88d5760320 628 ret = 0;
kenjiArai 0:5b88d5760320 629
kenjiArai 0:5b88d5760320 630 cleanup:
kenjiArai 0:5b88d5760320 631 psa_destroy_key( key_slot );
kenjiArai 0:5b88d5760320 632 return( ret );
kenjiArai 0:5b88d5760320 633 }
kenjiArai 0:5b88d5760320 634 #else /* MBEDTLS_USE_PSA_CRYPTO */
kenjiArai 0:5b88d5760320 635 static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
kenjiArai 0:5b88d5760320 636 const unsigned char *hash, size_t hash_len,
kenjiArai 0:5b88d5760320 637 const unsigned char *sig, size_t sig_len )
kenjiArai 0:5b88d5760320 638 {
kenjiArai 0:5b88d5760320 639 int ret;
kenjiArai 0:5b88d5760320 640 ((void) md_alg);
kenjiArai 0:5b88d5760320 641
kenjiArai 0:5b88d5760320 642 ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx,
kenjiArai 0:5b88d5760320 643 hash, hash_len, sig, sig_len );
kenjiArai 0:5b88d5760320 644
kenjiArai 0:5b88d5760320 645 if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )
kenjiArai 0:5b88d5760320 646 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
kenjiArai 0:5b88d5760320 647
kenjiArai 0:5b88d5760320 648 return( ret );
kenjiArai 0:5b88d5760320 649 }
kenjiArai 0:5b88d5760320 650 #endif /* MBEDTLS_USE_PSA_CRYPTO */
kenjiArai 0:5b88d5760320 651
kenjiArai 0:5b88d5760320 652 static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
kenjiArai 0:5b88d5760320 653 const unsigned char *hash, size_t hash_len,
kenjiArai 0:5b88d5760320 654 unsigned char *sig, size_t *sig_len,
kenjiArai 0:5b88d5760320 655 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
kenjiArai 0:5b88d5760320 656 {
kenjiArai 0:5b88d5760320 657 return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx,
kenjiArai 0:5b88d5760320 658 md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) );
kenjiArai 0:5b88d5760320 659 }
kenjiArai 0:5b88d5760320 660
kenjiArai 0:5b88d5760320 661 #if defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 662 static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
kenjiArai 0:5b88d5760320 663 const unsigned char *hash, size_t hash_len,
kenjiArai 0:5b88d5760320 664 const unsigned char *sig, size_t sig_len,
kenjiArai 0:5b88d5760320 665 void *rs_ctx )
kenjiArai 0:5b88d5760320 666 {
kenjiArai 0:5b88d5760320 667 int ret;
kenjiArai 0:5b88d5760320 668 ((void) md_alg);
kenjiArai 0:5b88d5760320 669
kenjiArai 0:5b88d5760320 670 ret = mbedtls_ecdsa_read_signature_restartable(
kenjiArai 0:5b88d5760320 671 (mbedtls_ecdsa_context *) ctx,
kenjiArai 0:5b88d5760320 672 hash, hash_len, sig, sig_len,
kenjiArai 0:5b88d5760320 673 (mbedtls_ecdsa_restart_ctx *) rs_ctx );
kenjiArai 0:5b88d5760320 674
kenjiArai 0:5b88d5760320 675 if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )
kenjiArai 0:5b88d5760320 676 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
kenjiArai 0:5b88d5760320 677
kenjiArai 0:5b88d5760320 678 return( ret );
kenjiArai 0:5b88d5760320 679 }
kenjiArai 0:5b88d5760320 680
kenjiArai 0:5b88d5760320 681 static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
kenjiArai 0:5b88d5760320 682 const unsigned char *hash, size_t hash_len,
kenjiArai 0:5b88d5760320 683 unsigned char *sig, size_t *sig_len,
kenjiArai 0:5b88d5760320 684 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
kenjiArai 0:5b88d5760320 685 void *rs_ctx )
kenjiArai 0:5b88d5760320 686 {
kenjiArai 0:5b88d5760320 687 return( mbedtls_ecdsa_write_signature_restartable(
kenjiArai 0:5b88d5760320 688 (mbedtls_ecdsa_context *) ctx,
kenjiArai 0:5b88d5760320 689 md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng,
kenjiArai 0:5b88d5760320 690 (mbedtls_ecdsa_restart_ctx *) rs_ctx ) );
kenjiArai 0:5b88d5760320 691
kenjiArai 0:5b88d5760320 692 }
kenjiArai 0:5b88d5760320 693 #endif /* MBEDTLS_ECP_RESTARTABLE */
kenjiArai 0:5b88d5760320 694
kenjiArai 0:5b88d5760320 695 static void *ecdsa_alloc_wrap( void )
kenjiArai 0:5b88d5760320 696 {
kenjiArai 0:5b88d5760320 697 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) );
kenjiArai 0:5b88d5760320 698
kenjiArai 0:5b88d5760320 699 if( ctx != NULL )
kenjiArai 0:5b88d5760320 700 mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx );
kenjiArai 0:5b88d5760320 701
kenjiArai 0:5b88d5760320 702 return( ctx );
kenjiArai 0:5b88d5760320 703 }
kenjiArai 0:5b88d5760320 704
kenjiArai 0:5b88d5760320 705 static void ecdsa_free_wrap( void *ctx )
kenjiArai 0:5b88d5760320 706 {
kenjiArai 0:5b88d5760320 707 mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx );
kenjiArai 0:5b88d5760320 708 mbedtls_free( ctx );
kenjiArai 0:5b88d5760320 709 }
kenjiArai 0:5b88d5760320 710
kenjiArai 0:5b88d5760320 711 #if defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 712 static void *ecdsa_rs_alloc( void )
kenjiArai 0:5b88d5760320 713 {
kenjiArai 0:5b88d5760320 714 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_restart_ctx ) );
kenjiArai 0:5b88d5760320 715
kenjiArai 0:5b88d5760320 716 if( ctx != NULL )
kenjiArai 0:5b88d5760320 717 mbedtls_ecdsa_restart_init( ctx );
kenjiArai 0:5b88d5760320 718
kenjiArai 0:5b88d5760320 719 return( ctx );
kenjiArai 0:5b88d5760320 720 }
kenjiArai 0:5b88d5760320 721
kenjiArai 0:5b88d5760320 722 static void ecdsa_rs_free( void *ctx )
kenjiArai 0:5b88d5760320 723 {
kenjiArai 0:5b88d5760320 724 mbedtls_ecdsa_restart_free( ctx );
kenjiArai 0:5b88d5760320 725 mbedtls_free( ctx );
kenjiArai 0:5b88d5760320 726 }
kenjiArai 0:5b88d5760320 727 #endif /* MBEDTLS_ECP_RESTARTABLE */
kenjiArai 0:5b88d5760320 728
kenjiArai 0:5b88d5760320 729 const mbedtls_pk_info_t mbedtls_ecdsa_info = {
kenjiArai 0:5b88d5760320 730 MBEDTLS_PK_ECDSA,
kenjiArai 0:5b88d5760320 731 "ECDSA",
kenjiArai 0:5b88d5760320 732 eckey_get_bitlen, /* Compatible key structures */
kenjiArai 0:5b88d5760320 733 ecdsa_can_do,
kenjiArai 0:5b88d5760320 734 ecdsa_verify_wrap,
kenjiArai 0:5b88d5760320 735 ecdsa_sign_wrap,
kenjiArai 0:5b88d5760320 736 #if defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 737 ecdsa_verify_rs_wrap,
kenjiArai 0:5b88d5760320 738 ecdsa_sign_rs_wrap,
kenjiArai 0:5b88d5760320 739 #endif
kenjiArai 0:5b88d5760320 740 NULL,
kenjiArai 0:5b88d5760320 741 NULL,
kenjiArai 0:5b88d5760320 742 eckey_check_pair, /* Compatible key structures */
kenjiArai 0:5b88d5760320 743 ecdsa_alloc_wrap,
kenjiArai 0:5b88d5760320 744 ecdsa_free_wrap,
kenjiArai 0:5b88d5760320 745 #if defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 746 ecdsa_rs_alloc,
kenjiArai 0:5b88d5760320 747 ecdsa_rs_free,
kenjiArai 0:5b88d5760320 748 #endif
kenjiArai 0:5b88d5760320 749 eckey_debug, /* Compatible key structures */
kenjiArai 0:5b88d5760320 750 };
kenjiArai 0:5b88d5760320 751 #endif /* MBEDTLS_ECDSA_C */
kenjiArai 0:5b88d5760320 752
kenjiArai 0:5b88d5760320 753 #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
kenjiArai 0:5b88d5760320 754 /*
kenjiArai 0:5b88d5760320 755 * Support for alternative RSA-private implementations
kenjiArai 0:5b88d5760320 756 */
kenjiArai 0:5b88d5760320 757
kenjiArai 0:5b88d5760320 758 static int rsa_alt_can_do( mbedtls_pk_type_t type )
kenjiArai 0:5b88d5760320 759 {
kenjiArai 0:5b88d5760320 760 return( type == MBEDTLS_PK_RSA );
kenjiArai 0:5b88d5760320 761 }
kenjiArai 0:5b88d5760320 762
kenjiArai 0:5b88d5760320 763 static size_t rsa_alt_get_bitlen( const void *ctx )
kenjiArai 0:5b88d5760320 764 {
kenjiArai 0:5b88d5760320 765 const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx;
kenjiArai 0:5b88d5760320 766
kenjiArai 0:5b88d5760320 767 return( 8 * rsa_alt->key_len_func( rsa_alt->key ) );
kenjiArai 0:5b88d5760320 768 }
kenjiArai 0:5b88d5760320 769
kenjiArai 0:5b88d5760320 770 static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
kenjiArai 0:5b88d5760320 771 const unsigned char *hash, size_t hash_len,
kenjiArai 0:5b88d5760320 772 unsigned char *sig, size_t *sig_len,
kenjiArai 0:5b88d5760320 773 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
kenjiArai 0:5b88d5760320 774 {
kenjiArai 0:5b88d5760320 775 mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
kenjiArai 0:5b88d5760320 776
kenjiArai 0:5b88d5760320 777 #if SIZE_MAX > UINT_MAX
kenjiArai 0:5b88d5760320 778 if( UINT_MAX < hash_len )
kenjiArai 0:5b88d5760320 779 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 780 #endif /* SIZE_MAX > UINT_MAX */
kenjiArai 0:5b88d5760320 781
kenjiArai 0:5b88d5760320 782 *sig_len = rsa_alt->key_len_func( rsa_alt->key );
kenjiArai 0:5b88d5760320 783
kenjiArai 0:5b88d5760320 784 return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
kenjiArai 0:5b88d5760320 785 md_alg, (unsigned int) hash_len, hash, sig ) );
kenjiArai 0:5b88d5760320 786 }
kenjiArai 0:5b88d5760320 787
kenjiArai 0:5b88d5760320 788 static int rsa_alt_decrypt_wrap( void *ctx,
kenjiArai 0:5b88d5760320 789 const unsigned char *input, size_t ilen,
kenjiArai 0:5b88d5760320 790 unsigned char *output, size_t *olen, size_t osize,
kenjiArai 0:5b88d5760320 791 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
kenjiArai 0:5b88d5760320 792 {
kenjiArai 0:5b88d5760320 793 mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
kenjiArai 0:5b88d5760320 794
kenjiArai 0:5b88d5760320 795 ((void) f_rng);
kenjiArai 0:5b88d5760320 796 ((void) p_rng);
kenjiArai 0:5b88d5760320 797
kenjiArai 0:5b88d5760320 798 if( ilen != rsa_alt->key_len_func( rsa_alt->key ) )
kenjiArai 0:5b88d5760320 799 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
kenjiArai 0:5b88d5760320 800
kenjiArai 0:5b88d5760320 801 return( rsa_alt->decrypt_func( rsa_alt->key,
kenjiArai 0:5b88d5760320 802 MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
kenjiArai 0:5b88d5760320 803 }
kenjiArai 0:5b88d5760320 804
kenjiArai 0:5b88d5760320 805 #if defined(MBEDTLS_RSA_C)
kenjiArai 0:5b88d5760320 806 static int rsa_alt_check_pair( const void *pub, const void *prv )
kenjiArai 0:5b88d5760320 807 {
kenjiArai 0:5b88d5760320 808 unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
kenjiArai 0:5b88d5760320 809 unsigned char hash[32];
kenjiArai 0:5b88d5760320 810 size_t sig_len = 0;
kenjiArai 0:5b88d5760320 811 int ret;
kenjiArai 0:5b88d5760320 812
kenjiArai 0:5b88d5760320 813 if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) )
kenjiArai 0:5b88d5760320 814 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
kenjiArai 0:5b88d5760320 815
kenjiArai 0:5b88d5760320 816 memset( hash, 0x2a, sizeof( hash ) );
kenjiArai 0:5b88d5760320 817
kenjiArai 0:5b88d5760320 818 if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE,
kenjiArai 0:5b88d5760320 819 hash, sizeof( hash ),
kenjiArai 0:5b88d5760320 820 sig, &sig_len, NULL, NULL ) ) != 0 )
kenjiArai 0:5b88d5760320 821 {
kenjiArai 0:5b88d5760320 822 return( ret );
kenjiArai 0:5b88d5760320 823 }
kenjiArai 0:5b88d5760320 824
kenjiArai 0:5b88d5760320 825 if( rsa_verify_wrap( (void *) pub, MBEDTLS_MD_NONE,
kenjiArai 0:5b88d5760320 826 hash, sizeof( hash ), sig, sig_len ) != 0 )
kenjiArai 0:5b88d5760320 827 {
kenjiArai 0:5b88d5760320 828 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
kenjiArai 0:5b88d5760320 829 }
kenjiArai 0:5b88d5760320 830
kenjiArai 0:5b88d5760320 831 return( 0 );
kenjiArai 0:5b88d5760320 832 }
kenjiArai 0:5b88d5760320 833 #endif /* MBEDTLS_RSA_C */
kenjiArai 0:5b88d5760320 834
kenjiArai 0:5b88d5760320 835 static void *rsa_alt_alloc_wrap( void )
kenjiArai 0:5b88d5760320 836 {
kenjiArai 0:5b88d5760320 837 void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context ) );
kenjiArai 0:5b88d5760320 838
kenjiArai 0:5b88d5760320 839 if( ctx != NULL )
kenjiArai 0:5b88d5760320 840 memset( ctx, 0, sizeof( mbedtls_rsa_alt_context ) );
kenjiArai 0:5b88d5760320 841
kenjiArai 0:5b88d5760320 842 return( ctx );
kenjiArai 0:5b88d5760320 843 }
kenjiArai 0:5b88d5760320 844
kenjiArai 0:5b88d5760320 845 static void rsa_alt_free_wrap( void *ctx )
kenjiArai 0:5b88d5760320 846 {
kenjiArai 0:5b88d5760320 847 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) );
kenjiArai 0:5b88d5760320 848 mbedtls_free( ctx );
kenjiArai 0:5b88d5760320 849 }
kenjiArai 0:5b88d5760320 850
kenjiArai 0:5b88d5760320 851 const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
kenjiArai 0:5b88d5760320 852 MBEDTLS_PK_RSA_ALT,
kenjiArai 0:5b88d5760320 853 "RSA-alt",
kenjiArai 0:5b88d5760320 854 rsa_alt_get_bitlen,
kenjiArai 0:5b88d5760320 855 rsa_alt_can_do,
kenjiArai 0:5b88d5760320 856 NULL,
kenjiArai 0:5b88d5760320 857 rsa_alt_sign_wrap,
kenjiArai 0:5b88d5760320 858 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 859 NULL,
kenjiArai 0:5b88d5760320 860 NULL,
kenjiArai 0:5b88d5760320 861 #endif
kenjiArai 0:5b88d5760320 862 rsa_alt_decrypt_wrap,
kenjiArai 0:5b88d5760320 863 NULL,
kenjiArai 0:5b88d5760320 864 #if defined(MBEDTLS_RSA_C)
kenjiArai 0:5b88d5760320 865 rsa_alt_check_pair,
kenjiArai 0:5b88d5760320 866 #else
kenjiArai 0:5b88d5760320 867 NULL,
kenjiArai 0:5b88d5760320 868 #endif
kenjiArai 0:5b88d5760320 869 rsa_alt_alloc_wrap,
kenjiArai 0:5b88d5760320 870 rsa_alt_free_wrap,
kenjiArai 0:5b88d5760320 871 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 872 NULL,
kenjiArai 0:5b88d5760320 873 NULL,
kenjiArai 0:5b88d5760320 874 #endif
kenjiArai 0:5b88d5760320 875 NULL,
kenjiArai 0:5b88d5760320 876 };
kenjiArai 0:5b88d5760320 877
kenjiArai 0:5b88d5760320 878 #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
kenjiArai 0:5b88d5760320 879
kenjiArai 0:5b88d5760320 880 #if defined(MBEDTLS_USE_PSA_CRYPTO)
kenjiArai 0:5b88d5760320 881
kenjiArai 0:5b88d5760320 882 static void *pk_opaque_alloc_wrap( void )
kenjiArai 0:5b88d5760320 883 {
kenjiArai 0:5b88d5760320 884 void *ctx = mbedtls_calloc( 1, sizeof( psa_key_handle_t ) );
kenjiArai 0:5b88d5760320 885
kenjiArai 0:5b88d5760320 886 /* no _init() function to call, an calloc() already zeroized */
kenjiArai 0:5b88d5760320 887
kenjiArai 0:5b88d5760320 888 return( ctx );
kenjiArai 0:5b88d5760320 889 }
kenjiArai 0:5b88d5760320 890
kenjiArai 0:5b88d5760320 891 static void pk_opaque_free_wrap( void *ctx )
kenjiArai 0:5b88d5760320 892 {
kenjiArai 0:5b88d5760320 893 mbedtls_platform_zeroize( ctx, sizeof( psa_key_handle_t ) );
kenjiArai 0:5b88d5760320 894 mbedtls_free( ctx );
kenjiArai 0:5b88d5760320 895 }
kenjiArai 0:5b88d5760320 896
kenjiArai 0:5b88d5760320 897 static size_t pk_opaque_get_bitlen( const void *ctx )
kenjiArai 0:5b88d5760320 898 {
kenjiArai 0:5b88d5760320 899 const psa_key_handle_t *key = (const psa_key_handle_t *) ctx;
kenjiArai 0:5b88d5760320 900 size_t bits;
kenjiArai 0:5b88d5760320 901
kenjiArai 0:5b88d5760320 902 if( PSA_SUCCESS != psa_get_key_information( *key, NULL, &bits ) )
kenjiArai 0:5b88d5760320 903 return( 0 );
kenjiArai 0:5b88d5760320 904
kenjiArai 0:5b88d5760320 905 return( bits );
kenjiArai 0:5b88d5760320 906 }
kenjiArai 0:5b88d5760320 907
kenjiArai 0:5b88d5760320 908 static int pk_opaque_can_do( mbedtls_pk_type_t type )
kenjiArai 0:5b88d5760320 909 {
kenjiArai 0:5b88d5760320 910 /* For now opaque PSA keys can only wrap ECC keypairs,
kenjiArai 0:5b88d5760320 911 * as checked by setup_psa().
kenjiArai 0:5b88d5760320 912 * Also, ECKEY_DH does not really make sense with the current API. */
kenjiArai 0:5b88d5760320 913 return( type == MBEDTLS_PK_ECKEY ||
kenjiArai 0:5b88d5760320 914 type == MBEDTLS_PK_ECDSA );
kenjiArai 0:5b88d5760320 915 }
kenjiArai 0:5b88d5760320 916
kenjiArai 0:5b88d5760320 917 /*
kenjiArai 0:5b88d5760320 918 * Simultaneously convert and move raw MPI from the beginning of a buffer
kenjiArai 0:5b88d5760320 919 * to an ASN.1 MPI at the end of the buffer.
kenjiArai 0:5b88d5760320 920 * See also mbedtls_asn1_write_mpi().
kenjiArai 0:5b88d5760320 921 *
kenjiArai 0:5b88d5760320 922 * p: pointer to the end of the output buffer
kenjiArai 0:5b88d5760320 923 * start: start of the output buffer, and also of the mpi to write at the end
kenjiArai 0:5b88d5760320 924 * n_len: length of the mpi to read from start
kenjiArai 0:5b88d5760320 925 */
kenjiArai 0:5b88d5760320 926 static int asn1_write_mpibuf( unsigned char **p, unsigned char *start,
kenjiArai 0:5b88d5760320 927 size_t n_len )
kenjiArai 0:5b88d5760320 928 {
kenjiArai 0:5b88d5760320 929 int ret;
kenjiArai 0:5b88d5760320 930 size_t len = 0;
kenjiArai 0:5b88d5760320 931
kenjiArai 0:5b88d5760320 932 if( (size_t)( *p - start ) < n_len )
kenjiArai 0:5b88d5760320 933 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
kenjiArai 0:5b88d5760320 934
kenjiArai 0:5b88d5760320 935 len = n_len;
kenjiArai 0:5b88d5760320 936 *p -= len;
kenjiArai 0:5b88d5760320 937 memmove( *p, start, len );
kenjiArai 0:5b88d5760320 938
kenjiArai 0:5b88d5760320 939 /* ASN.1 DER encoding requires minimal length, so skip leading 0s.
kenjiArai 0:5b88d5760320 940 * Neither r nor s should be 0, but as a failsafe measure, still detect
kenjiArai 0:5b88d5760320 941 * that rather than overflowing the buffer in case of a PSA error. */
kenjiArai 0:5b88d5760320 942 while( len > 0 && **p == 0x00 )
kenjiArai 0:5b88d5760320 943 {
kenjiArai 0:5b88d5760320 944 ++(*p);
kenjiArai 0:5b88d5760320 945 --len;
kenjiArai 0:5b88d5760320 946 }
kenjiArai 0:5b88d5760320 947
kenjiArai 0:5b88d5760320 948 /* this is only reached if the signature was invalid */
kenjiArai 0:5b88d5760320 949 if( len == 0 )
kenjiArai 0:5b88d5760320 950 return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
kenjiArai 0:5b88d5760320 951
kenjiArai 0:5b88d5760320 952 /* if the msb is 1, ASN.1 requires that we prepend a 0.
kenjiArai 0:5b88d5760320 953 * Neither r nor s can be 0, so we can assume len > 0 at all times. */
kenjiArai 0:5b88d5760320 954 if( **p & 0x80 )
kenjiArai 0:5b88d5760320 955 {
kenjiArai 0:5b88d5760320 956 if( *p - start < 1 )
kenjiArai 0:5b88d5760320 957 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
kenjiArai 0:5b88d5760320 958
kenjiArai 0:5b88d5760320 959 *--(*p) = 0x00;
kenjiArai 0:5b88d5760320 960 len += 1;
kenjiArai 0:5b88d5760320 961 }
kenjiArai 0:5b88d5760320 962
kenjiArai 0:5b88d5760320 963 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
kenjiArai 0:5b88d5760320 964 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
kenjiArai 0:5b88d5760320 965 MBEDTLS_ASN1_INTEGER ) );
kenjiArai 0:5b88d5760320 966
kenjiArai 0:5b88d5760320 967 return( (int) len );
kenjiArai 0:5b88d5760320 968 }
kenjiArai 0:5b88d5760320 969
kenjiArai 0:5b88d5760320 970 /* Transcode signature from PSA format to ASN.1 sequence.
kenjiArai 0:5b88d5760320 971 * See ecdsa_signature_to_asn1 in ecdsa.c, but with byte buffers instead of
kenjiArai 0:5b88d5760320 972 * MPIs, and in-place.
kenjiArai 0:5b88d5760320 973 *
kenjiArai 0:5b88d5760320 974 * [in/out] sig: the signature pre- and post-transcoding
kenjiArai 0:5b88d5760320 975 * [in/out] sig_len: signature length pre- and post-transcoding
kenjiArai 0:5b88d5760320 976 * [int] buf_len: the available size the in/out buffer
kenjiArai 0:5b88d5760320 977 */
kenjiArai 0:5b88d5760320 978 static int pk_ecdsa_sig_asn1_from_psa( unsigned char *sig, size_t *sig_len,
kenjiArai 0:5b88d5760320 979 size_t buf_len )
kenjiArai 0:5b88d5760320 980 {
kenjiArai 0:5b88d5760320 981 int ret;
kenjiArai 0:5b88d5760320 982 size_t len = 0;
kenjiArai 0:5b88d5760320 983 const size_t rs_len = *sig_len / 2;
kenjiArai 0:5b88d5760320 984 unsigned char *p = sig + buf_len;
kenjiArai 0:5b88d5760320 985
kenjiArai 0:5b88d5760320 986 MBEDTLS_ASN1_CHK_ADD( len, asn1_write_mpibuf( &p, sig + rs_len, rs_len ) );
kenjiArai 0:5b88d5760320 987 MBEDTLS_ASN1_CHK_ADD( len, asn1_write_mpibuf( &p, sig, rs_len ) );
kenjiArai 0:5b88d5760320 988
kenjiArai 0:5b88d5760320 989 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &p, sig, len ) );
kenjiArai 0:5b88d5760320 990 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, sig,
kenjiArai 0:5b88d5760320 991 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
kenjiArai 0:5b88d5760320 992
kenjiArai 0:5b88d5760320 993 memmove( sig, p, len );
kenjiArai 0:5b88d5760320 994 *sig_len = len;
kenjiArai 0:5b88d5760320 995
kenjiArai 0:5b88d5760320 996 return( 0 );
kenjiArai 0:5b88d5760320 997 }
kenjiArai 0:5b88d5760320 998
kenjiArai 0:5b88d5760320 999 static int pk_opaque_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
kenjiArai 0:5b88d5760320 1000 const unsigned char *hash, size_t hash_len,
kenjiArai 0:5b88d5760320 1001 unsigned char *sig, size_t *sig_len,
kenjiArai 0:5b88d5760320 1002 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
kenjiArai 0:5b88d5760320 1003 {
kenjiArai 0:5b88d5760320 1004 const psa_key_handle_t *key = (const psa_key_handle_t *) ctx;
kenjiArai 0:5b88d5760320 1005 psa_algorithm_t alg = PSA_ALG_ECDSA( mbedtls_psa_translate_md( md_alg ) );
kenjiArai 0:5b88d5760320 1006 size_t bits, buf_len;
kenjiArai 0:5b88d5760320 1007 psa_status_t status;
kenjiArai 0:5b88d5760320 1008
kenjiArai 0:5b88d5760320 1009 /* PSA has its own RNG */
kenjiArai 0:5b88d5760320 1010 (void) f_rng;
kenjiArai 0:5b88d5760320 1011 (void) p_rng;
kenjiArai 0:5b88d5760320 1012
kenjiArai 0:5b88d5760320 1013 /* PSA needs an output buffer of known size, but our API doesn't provide
kenjiArai 0:5b88d5760320 1014 * that information. Assume that the buffer is large enough for a
kenjiArai 0:5b88d5760320 1015 * maximal-length signature with that key (otherwise the application is
kenjiArai 0:5b88d5760320 1016 * buggy anyway). */
kenjiArai 0:5b88d5760320 1017 status = psa_get_key_information( *key, NULL, &bits );
kenjiArai 0:5b88d5760320 1018 if( status != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 1019 return( mbedtls_psa_err_translate_pk( status ) );
kenjiArai 0:5b88d5760320 1020
kenjiArai 0:5b88d5760320 1021 buf_len = MBEDTLS_ECDSA_MAX_SIG_LEN( bits );
kenjiArai 0:5b88d5760320 1022
kenjiArai 0:5b88d5760320 1023 /* make the signature */
kenjiArai 0:5b88d5760320 1024 status = psa_asymmetric_sign( *key, alg, hash, hash_len,
kenjiArai 0:5b88d5760320 1025 sig, buf_len, sig_len );
kenjiArai 0:5b88d5760320 1026 if( status != PSA_SUCCESS )
kenjiArai 0:5b88d5760320 1027 return( mbedtls_psa_err_translate_pk( status ) );
kenjiArai 0:5b88d5760320 1028
kenjiArai 0:5b88d5760320 1029 /* transcode it to ASN.1 sequence */
kenjiArai 0:5b88d5760320 1030 return( pk_ecdsa_sig_asn1_from_psa( sig, sig_len, buf_len ) );
kenjiArai 0:5b88d5760320 1031 }
kenjiArai 0:5b88d5760320 1032
kenjiArai 0:5b88d5760320 1033 const mbedtls_pk_info_t mbedtls_pk_opaque_info = {
kenjiArai 0:5b88d5760320 1034 MBEDTLS_PK_OPAQUE,
kenjiArai 0:5b88d5760320 1035 "Opaque",
kenjiArai 0:5b88d5760320 1036 pk_opaque_get_bitlen,
kenjiArai 0:5b88d5760320 1037 pk_opaque_can_do,
kenjiArai 0:5b88d5760320 1038 NULL, /* verify - will be done later */
kenjiArai 0:5b88d5760320 1039 pk_opaque_sign_wrap,
kenjiArai 0:5b88d5760320 1040 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 1041 NULL, /* restartable verify - not relevant */
kenjiArai 0:5b88d5760320 1042 NULL, /* restartable sign - not relevant */
kenjiArai 0:5b88d5760320 1043 #endif
kenjiArai 0:5b88d5760320 1044 NULL, /* decrypt - will be done later */
kenjiArai 0:5b88d5760320 1045 NULL, /* encrypt - will be done later */
kenjiArai 0:5b88d5760320 1046 NULL, /* check_pair - could be done later or left NULL */
kenjiArai 0:5b88d5760320 1047 pk_opaque_alloc_wrap,
kenjiArai 0:5b88d5760320 1048 pk_opaque_free_wrap,
kenjiArai 0:5b88d5760320 1049 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
kenjiArai 0:5b88d5760320 1050 NULL, /* restart alloc - not relevant */
kenjiArai 0:5b88d5760320 1051 NULL, /* restart free - not relevant */
kenjiArai 0:5b88d5760320 1052 #endif
kenjiArai 0:5b88d5760320 1053 NULL, /* debug - could be done later, or even left NULL */
kenjiArai 0:5b88d5760320 1054 };
kenjiArai 0:5b88d5760320 1055
kenjiArai 0:5b88d5760320 1056 #endif /* MBEDTLS_USE_PSA_CRYPTO */
kenjiArai 0:5b88d5760320 1057
kenjiArai 0:5b88d5760320 1058 #endif /* MBEDTLS_PK_C */