1c6672fdcSEdison Ai // SPDX-License-Identifier: Apache-2.0 2817466cbSJens Wiklander /* 3817466cbSJens Wiklander * Public Key abstraction layer: wrapper functions 4817466cbSJens Wiklander * 5817466cbSJens Wiklander * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 6817466cbSJens Wiklander * 7817466cbSJens Wiklander * Licensed under the Apache License, Version 2.0 (the "License"); you may 8817466cbSJens Wiklander * not use this file except in compliance with the License. 9817466cbSJens Wiklander * You may obtain a copy of the License at 10817466cbSJens Wiklander * 11817466cbSJens Wiklander * http://www.apache.org/licenses/LICENSE-2.0 12817466cbSJens Wiklander * 13817466cbSJens Wiklander * Unless required by applicable law or agreed to in writing, software 14817466cbSJens Wiklander * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15817466cbSJens Wiklander * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16817466cbSJens Wiklander * See the License for the specific language governing permissions and 17817466cbSJens Wiklander * limitations under the License. 18817466cbSJens Wiklander * 19817466cbSJens Wiklander * This file is part of mbed TLS (https://tls.mbed.org) 20817466cbSJens Wiklander */ 21817466cbSJens Wiklander 22817466cbSJens Wiklander #if !defined(MBEDTLS_CONFIG_FILE) 23817466cbSJens Wiklander #include "mbedtls/config.h" 24817466cbSJens Wiklander #else 25817466cbSJens Wiklander #include MBEDTLS_CONFIG_FILE 26817466cbSJens Wiklander #endif 27817466cbSJens Wiklander 28817466cbSJens Wiklander #if defined(MBEDTLS_PK_C) 29817466cbSJens Wiklander #include "mbedtls/pk_internal.h" 30817466cbSJens Wiklander 31817466cbSJens Wiklander /* Even if RSA not activated, for the sake of RSA-alt */ 32817466cbSJens Wiklander #include "mbedtls/rsa.h" 33817466cbSJens Wiklander 34817466cbSJens Wiklander #include <string.h> 35817466cbSJens Wiklander 36817466cbSJens Wiklander #if defined(MBEDTLS_ECP_C) 37817466cbSJens Wiklander #include "mbedtls/ecp.h" 38817466cbSJens Wiklander #endif 39817466cbSJens Wiklander 40817466cbSJens Wiklander #if defined(MBEDTLS_ECDSA_C) 41817466cbSJens Wiklander #include "mbedtls/ecdsa.h" 42817466cbSJens Wiklander #endif 43817466cbSJens Wiklander 44*3d3b0591SJens Wiklander #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) 45*3d3b0591SJens Wiklander #include "mbedtls/platform_util.h" 46*3d3b0591SJens Wiklander #endif 47*3d3b0591SJens Wiklander 48817466cbSJens Wiklander #if defined(MBEDTLS_PLATFORM_C) 49817466cbSJens Wiklander #include "mbedtls/platform.h" 50817466cbSJens Wiklander #else 51817466cbSJens Wiklander #include <stdlib.h> 52817466cbSJens Wiklander #define mbedtls_calloc calloc 53817466cbSJens Wiklander #define mbedtls_free free 54817466cbSJens Wiklander #endif 55817466cbSJens Wiklander 56817466cbSJens Wiklander #include <limits.h> 57*3d3b0591SJens Wiklander #include <stdint.h> 58817466cbSJens Wiklander 59817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C) 60817466cbSJens Wiklander static int rsa_can_do( mbedtls_pk_type_t type ) 61817466cbSJens Wiklander { 62817466cbSJens Wiklander return( type == MBEDTLS_PK_RSA || 63817466cbSJens Wiklander type == MBEDTLS_PK_RSASSA_PSS ); 64817466cbSJens Wiklander } 65817466cbSJens Wiklander 66817466cbSJens Wiklander static size_t rsa_get_bitlen( const void *ctx ) 67817466cbSJens Wiklander { 68*3d3b0591SJens Wiklander const mbedtls_rsa_context * rsa = (const mbedtls_rsa_context *) ctx; 69*3d3b0591SJens Wiklander return( 8 * mbedtls_rsa_get_len( rsa ) ); 70817466cbSJens Wiklander } 71817466cbSJens Wiklander 72817466cbSJens Wiklander static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, 73817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 74817466cbSJens Wiklander const unsigned char *sig, size_t sig_len ) 75817466cbSJens Wiklander { 76817466cbSJens Wiklander int ret; 77*3d3b0591SJens Wiklander mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; 78*3d3b0591SJens Wiklander size_t rsa_len = mbedtls_rsa_get_len( rsa ); 79817466cbSJens Wiklander 80*3d3b0591SJens Wiklander #if SIZE_MAX > UINT_MAX 81817466cbSJens Wiklander if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) 82817466cbSJens Wiklander return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 83*3d3b0591SJens Wiklander #endif /* SIZE_MAX > UINT_MAX */ 84817466cbSJens Wiklander 85*3d3b0591SJens Wiklander if( sig_len < rsa_len ) 86817466cbSJens Wiklander return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); 87817466cbSJens Wiklander 88*3d3b0591SJens Wiklander if( ( ret = mbedtls_rsa_pkcs1_verify( rsa, NULL, NULL, 89817466cbSJens Wiklander MBEDTLS_RSA_PUBLIC, md_alg, 90817466cbSJens Wiklander (unsigned int) hash_len, hash, sig ) ) != 0 ) 91817466cbSJens Wiklander return( ret ); 92817466cbSJens Wiklander 93*3d3b0591SJens Wiklander /* The buffer contains a valid signature followed by extra data. 94*3d3b0591SJens Wiklander * We have a special error code for that so that so that callers can 95*3d3b0591SJens Wiklander * use mbedtls_pk_verify() to check "Does the buffer start with a 96*3d3b0591SJens Wiklander * valid signature?" and not just "Does the buffer contain a valid 97*3d3b0591SJens Wiklander * signature?". */ 98*3d3b0591SJens Wiklander if( sig_len > rsa_len ) 99817466cbSJens Wiklander return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); 100817466cbSJens Wiklander 101817466cbSJens Wiklander return( 0 ); 102817466cbSJens Wiklander } 103817466cbSJens Wiklander 104817466cbSJens Wiklander static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, 105817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 106817466cbSJens Wiklander unsigned char *sig, size_t *sig_len, 107817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 108817466cbSJens Wiklander { 109*3d3b0591SJens Wiklander mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; 110*3d3b0591SJens Wiklander 111*3d3b0591SJens Wiklander #if SIZE_MAX > UINT_MAX 112817466cbSJens Wiklander if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) 113817466cbSJens Wiklander return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 114*3d3b0591SJens Wiklander #endif /* SIZE_MAX > UINT_MAX */ 115817466cbSJens Wiklander 116*3d3b0591SJens Wiklander *sig_len = mbedtls_rsa_get_len( rsa ); 117817466cbSJens Wiklander 118*3d3b0591SJens Wiklander return( mbedtls_rsa_pkcs1_sign( rsa, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, 119817466cbSJens Wiklander md_alg, (unsigned int) hash_len, hash, sig ) ); 120817466cbSJens Wiklander } 121817466cbSJens Wiklander 122817466cbSJens Wiklander static int rsa_decrypt_wrap( void *ctx, 123817466cbSJens Wiklander const unsigned char *input, size_t ilen, 124817466cbSJens Wiklander unsigned char *output, size_t *olen, size_t osize, 125817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 126817466cbSJens Wiklander { 127*3d3b0591SJens Wiklander mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; 128*3d3b0591SJens Wiklander 129*3d3b0591SJens Wiklander if( ilen != mbedtls_rsa_get_len( rsa ) ) 130817466cbSJens Wiklander return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); 131817466cbSJens Wiklander 132*3d3b0591SJens Wiklander return( mbedtls_rsa_pkcs1_decrypt( rsa, f_rng, p_rng, 133817466cbSJens Wiklander MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) ); 134817466cbSJens Wiklander } 135817466cbSJens Wiklander 136817466cbSJens Wiklander static int rsa_encrypt_wrap( void *ctx, 137817466cbSJens Wiklander const unsigned char *input, size_t ilen, 138817466cbSJens Wiklander unsigned char *output, size_t *olen, size_t osize, 139817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 140817466cbSJens Wiklander { 141*3d3b0591SJens Wiklander mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; 142*3d3b0591SJens Wiklander *olen = mbedtls_rsa_get_len( rsa ); 143817466cbSJens Wiklander 144817466cbSJens Wiklander if( *olen > osize ) 145817466cbSJens Wiklander return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE ); 146817466cbSJens Wiklander 147*3d3b0591SJens Wiklander return( mbedtls_rsa_pkcs1_encrypt( rsa, f_rng, p_rng, MBEDTLS_RSA_PUBLIC, 148*3d3b0591SJens Wiklander ilen, input, output ) ); 149817466cbSJens Wiklander } 150817466cbSJens Wiklander 151817466cbSJens Wiklander static int rsa_check_pair_wrap( const void *pub, const void *prv ) 152817466cbSJens Wiklander { 153817466cbSJens Wiklander return( mbedtls_rsa_check_pub_priv( (const mbedtls_rsa_context *) pub, 154817466cbSJens Wiklander (const mbedtls_rsa_context *) prv ) ); 155817466cbSJens Wiklander } 156817466cbSJens Wiklander 157817466cbSJens Wiklander static void *rsa_alloc_wrap( void ) 158817466cbSJens Wiklander { 159817466cbSJens Wiklander void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_context ) ); 160817466cbSJens Wiklander 161817466cbSJens Wiklander if( ctx != NULL ) 162817466cbSJens Wiklander mbedtls_rsa_init( (mbedtls_rsa_context *) ctx, 0, 0 ); 163817466cbSJens Wiklander 164817466cbSJens Wiklander return( ctx ); 165817466cbSJens Wiklander } 166817466cbSJens Wiklander 167817466cbSJens Wiklander static void rsa_free_wrap( void *ctx ) 168817466cbSJens Wiklander { 169817466cbSJens Wiklander mbedtls_rsa_free( (mbedtls_rsa_context *) ctx ); 170817466cbSJens Wiklander mbedtls_free( ctx ); 171817466cbSJens Wiklander } 172817466cbSJens Wiklander 173817466cbSJens Wiklander static void rsa_debug( const void *ctx, mbedtls_pk_debug_item *items ) 174817466cbSJens Wiklander { 175817466cbSJens Wiklander items->type = MBEDTLS_PK_DEBUG_MPI; 176817466cbSJens Wiklander items->name = "rsa.N"; 177817466cbSJens Wiklander items->value = &( ((mbedtls_rsa_context *) ctx)->N ); 178817466cbSJens Wiklander 179817466cbSJens Wiklander items++; 180817466cbSJens Wiklander 181817466cbSJens Wiklander items->type = MBEDTLS_PK_DEBUG_MPI; 182817466cbSJens Wiklander items->name = "rsa.E"; 183817466cbSJens Wiklander items->value = &( ((mbedtls_rsa_context *) ctx)->E ); 184817466cbSJens Wiklander } 185817466cbSJens Wiklander 186817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_rsa_info = { 187817466cbSJens Wiklander MBEDTLS_PK_RSA, 188817466cbSJens Wiklander "RSA", 189817466cbSJens Wiklander rsa_get_bitlen, 190817466cbSJens Wiklander rsa_can_do, 191817466cbSJens Wiklander rsa_verify_wrap, 192817466cbSJens Wiklander rsa_sign_wrap, 193*3d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 194*3d3b0591SJens Wiklander NULL, 195*3d3b0591SJens Wiklander NULL, 196*3d3b0591SJens Wiklander #endif 197817466cbSJens Wiklander rsa_decrypt_wrap, 198817466cbSJens Wiklander rsa_encrypt_wrap, 199817466cbSJens Wiklander rsa_check_pair_wrap, 200817466cbSJens Wiklander rsa_alloc_wrap, 201817466cbSJens Wiklander rsa_free_wrap, 202*3d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 203*3d3b0591SJens Wiklander NULL, 204*3d3b0591SJens Wiklander NULL, 205*3d3b0591SJens Wiklander #endif 206817466cbSJens Wiklander rsa_debug, 207817466cbSJens Wiklander }; 208817466cbSJens Wiklander #endif /* MBEDTLS_RSA_C */ 209817466cbSJens Wiklander 210817466cbSJens Wiklander #if defined(MBEDTLS_ECP_C) 211817466cbSJens Wiklander /* 212817466cbSJens Wiklander * Generic EC key 213817466cbSJens Wiklander */ 214817466cbSJens Wiklander static int eckey_can_do( mbedtls_pk_type_t type ) 215817466cbSJens Wiklander { 216817466cbSJens Wiklander return( type == MBEDTLS_PK_ECKEY || 217817466cbSJens Wiklander type == MBEDTLS_PK_ECKEY_DH || 218817466cbSJens Wiklander type == MBEDTLS_PK_ECDSA ); 219817466cbSJens Wiklander } 220817466cbSJens Wiklander 221817466cbSJens Wiklander static size_t eckey_get_bitlen( const void *ctx ) 222817466cbSJens Wiklander { 223817466cbSJens Wiklander return( ((mbedtls_ecp_keypair *) ctx)->grp.pbits ); 224817466cbSJens Wiklander } 225817466cbSJens Wiklander 226817466cbSJens Wiklander #if defined(MBEDTLS_ECDSA_C) 227817466cbSJens Wiklander /* Forward declarations */ 228817466cbSJens Wiklander static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, 229817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 230817466cbSJens Wiklander const unsigned char *sig, size_t sig_len ); 231817466cbSJens Wiklander 232817466cbSJens Wiklander static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, 233817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 234817466cbSJens Wiklander unsigned char *sig, size_t *sig_len, 235817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); 236817466cbSJens Wiklander 237817466cbSJens Wiklander static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, 238817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 239817466cbSJens Wiklander const unsigned char *sig, size_t sig_len ) 240817466cbSJens Wiklander { 241817466cbSJens Wiklander int ret; 242817466cbSJens Wiklander mbedtls_ecdsa_context ecdsa; 243817466cbSJens Wiklander 244817466cbSJens Wiklander mbedtls_ecdsa_init( &ecdsa ); 245817466cbSJens Wiklander 246817466cbSJens Wiklander if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 ) 247817466cbSJens Wiklander ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len ); 248817466cbSJens Wiklander 249817466cbSJens Wiklander mbedtls_ecdsa_free( &ecdsa ); 250817466cbSJens Wiklander 251817466cbSJens Wiklander return( ret ); 252817466cbSJens Wiklander } 253817466cbSJens Wiklander 254817466cbSJens Wiklander static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, 255817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 256817466cbSJens Wiklander unsigned char *sig, size_t *sig_len, 257817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 258817466cbSJens Wiklander { 259817466cbSJens Wiklander int ret; 260817466cbSJens Wiklander mbedtls_ecdsa_context ecdsa; 261817466cbSJens Wiklander 262817466cbSJens Wiklander mbedtls_ecdsa_init( &ecdsa ); 263817466cbSJens Wiklander 264817466cbSJens Wiklander if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 ) 265817466cbSJens Wiklander ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len, 266817466cbSJens Wiklander f_rng, p_rng ); 267817466cbSJens Wiklander 268817466cbSJens Wiklander mbedtls_ecdsa_free( &ecdsa ); 269817466cbSJens Wiklander 270817466cbSJens Wiklander return( ret ); 271817466cbSJens Wiklander } 272817466cbSJens Wiklander 273*3d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE) 274*3d3b0591SJens Wiklander /* Forward declarations */ 275*3d3b0591SJens Wiklander static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, 276*3d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 277*3d3b0591SJens Wiklander const unsigned char *sig, size_t sig_len, 278*3d3b0591SJens Wiklander void *rs_ctx ); 279*3d3b0591SJens Wiklander 280*3d3b0591SJens Wiklander static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, 281*3d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 282*3d3b0591SJens Wiklander unsigned char *sig, size_t *sig_len, 283*3d3b0591SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, 284*3d3b0591SJens Wiklander void *rs_ctx ); 285*3d3b0591SJens Wiklander 286*3d3b0591SJens Wiklander /* 287*3d3b0591SJens Wiklander * Restart context for ECDSA operations with ECKEY context 288*3d3b0591SJens Wiklander * 289*3d3b0591SJens Wiklander * We need to store an actual ECDSA context, as we need to pass the same to 290*3d3b0591SJens Wiklander * the underlying ecdsa function, so we can't create it on the fly every time. 291*3d3b0591SJens Wiklander */ 292*3d3b0591SJens Wiklander typedef struct 293*3d3b0591SJens Wiklander { 294*3d3b0591SJens Wiklander mbedtls_ecdsa_restart_ctx ecdsa_rs; 295*3d3b0591SJens Wiklander mbedtls_ecdsa_context ecdsa_ctx; 296*3d3b0591SJens Wiklander } eckey_restart_ctx; 297*3d3b0591SJens Wiklander 298*3d3b0591SJens Wiklander static void *eckey_rs_alloc( void ) 299*3d3b0591SJens Wiklander { 300*3d3b0591SJens Wiklander eckey_restart_ctx *rs_ctx; 301*3d3b0591SJens Wiklander 302*3d3b0591SJens Wiklander void *ctx = mbedtls_calloc( 1, sizeof( eckey_restart_ctx ) ); 303*3d3b0591SJens Wiklander 304*3d3b0591SJens Wiklander if( ctx != NULL ) 305*3d3b0591SJens Wiklander { 306*3d3b0591SJens Wiklander rs_ctx = ctx; 307*3d3b0591SJens Wiklander mbedtls_ecdsa_restart_init( &rs_ctx->ecdsa_rs ); 308*3d3b0591SJens Wiklander mbedtls_ecdsa_init( &rs_ctx->ecdsa_ctx ); 309*3d3b0591SJens Wiklander } 310*3d3b0591SJens Wiklander 311*3d3b0591SJens Wiklander return( ctx ); 312*3d3b0591SJens Wiklander } 313*3d3b0591SJens Wiklander 314*3d3b0591SJens Wiklander static void eckey_rs_free( void *ctx ) 315*3d3b0591SJens Wiklander { 316*3d3b0591SJens Wiklander eckey_restart_ctx *rs_ctx; 317*3d3b0591SJens Wiklander 318*3d3b0591SJens Wiklander if( ctx == NULL) 319*3d3b0591SJens Wiklander return; 320*3d3b0591SJens Wiklander 321*3d3b0591SJens Wiklander rs_ctx = ctx; 322*3d3b0591SJens Wiklander mbedtls_ecdsa_restart_free( &rs_ctx->ecdsa_rs ); 323*3d3b0591SJens Wiklander mbedtls_ecdsa_free( &rs_ctx->ecdsa_ctx ); 324*3d3b0591SJens Wiklander 325*3d3b0591SJens Wiklander mbedtls_free( ctx ); 326*3d3b0591SJens Wiklander } 327*3d3b0591SJens Wiklander 328*3d3b0591SJens Wiklander static int eckey_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, 329*3d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 330*3d3b0591SJens Wiklander const unsigned char *sig, size_t sig_len, 331*3d3b0591SJens Wiklander void *rs_ctx ) 332*3d3b0591SJens Wiklander { 333*3d3b0591SJens Wiklander int ret; 334*3d3b0591SJens Wiklander eckey_restart_ctx *rs = rs_ctx; 335*3d3b0591SJens Wiklander 336*3d3b0591SJens Wiklander /* Should never happen */ 337*3d3b0591SJens Wiklander if( rs == NULL ) 338*3d3b0591SJens Wiklander return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 339*3d3b0591SJens Wiklander 340*3d3b0591SJens Wiklander /* set up our own sub-context if needed (that is, on first run) */ 341*3d3b0591SJens Wiklander if( rs->ecdsa_ctx.grp.pbits == 0 ) 342*3d3b0591SJens Wiklander MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) ); 343*3d3b0591SJens Wiklander 344*3d3b0591SJens Wiklander MBEDTLS_MPI_CHK( ecdsa_verify_rs_wrap( &rs->ecdsa_ctx, 345*3d3b0591SJens Wiklander md_alg, hash, hash_len, 346*3d3b0591SJens Wiklander sig, sig_len, &rs->ecdsa_rs ) ); 347*3d3b0591SJens Wiklander 348*3d3b0591SJens Wiklander cleanup: 349*3d3b0591SJens Wiklander return( ret ); 350*3d3b0591SJens Wiklander } 351*3d3b0591SJens Wiklander 352*3d3b0591SJens Wiklander static int eckey_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, 353*3d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 354*3d3b0591SJens Wiklander unsigned char *sig, size_t *sig_len, 355*3d3b0591SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, 356*3d3b0591SJens Wiklander void *rs_ctx ) 357*3d3b0591SJens Wiklander { 358*3d3b0591SJens Wiklander int ret; 359*3d3b0591SJens Wiklander eckey_restart_ctx *rs = rs_ctx; 360*3d3b0591SJens Wiklander 361*3d3b0591SJens Wiklander /* Should never happen */ 362*3d3b0591SJens Wiklander if( rs == NULL ) 363*3d3b0591SJens Wiklander return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 364*3d3b0591SJens Wiklander 365*3d3b0591SJens Wiklander /* set up our own sub-context if needed (that is, on first run) */ 366*3d3b0591SJens Wiklander if( rs->ecdsa_ctx.grp.pbits == 0 ) 367*3d3b0591SJens Wiklander MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) ); 368*3d3b0591SJens Wiklander 369*3d3b0591SJens Wiklander MBEDTLS_MPI_CHK( ecdsa_sign_rs_wrap( &rs->ecdsa_ctx, md_alg, 370*3d3b0591SJens Wiklander hash, hash_len, sig, sig_len, 371*3d3b0591SJens Wiklander f_rng, p_rng, &rs->ecdsa_rs ) ); 372*3d3b0591SJens Wiklander 373*3d3b0591SJens Wiklander cleanup: 374*3d3b0591SJens Wiklander return( ret ); 375*3d3b0591SJens Wiklander } 376*3d3b0591SJens Wiklander #endif /* MBEDTLS_ECP_RESTARTABLE */ 377817466cbSJens Wiklander #endif /* MBEDTLS_ECDSA_C */ 378817466cbSJens Wiklander 379817466cbSJens Wiklander static int eckey_check_pair( const void *pub, const void *prv ) 380817466cbSJens Wiklander { 381817466cbSJens Wiklander return( mbedtls_ecp_check_pub_priv( (const mbedtls_ecp_keypair *) pub, 382817466cbSJens Wiklander (const mbedtls_ecp_keypair *) prv ) ); 383817466cbSJens Wiklander } 384817466cbSJens Wiklander 385817466cbSJens Wiklander static void *eckey_alloc_wrap( void ) 386817466cbSJens Wiklander { 387817466cbSJens Wiklander void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) ); 388817466cbSJens Wiklander 389817466cbSJens Wiklander if( ctx != NULL ) 390817466cbSJens Wiklander mbedtls_ecp_keypair_init( ctx ); 391817466cbSJens Wiklander 392817466cbSJens Wiklander return( ctx ); 393817466cbSJens Wiklander } 394817466cbSJens Wiklander 395817466cbSJens Wiklander static void eckey_free_wrap( void *ctx ) 396817466cbSJens Wiklander { 397817466cbSJens Wiklander mbedtls_ecp_keypair_free( (mbedtls_ecp_keypair *) ctx ); 398817466cbSJens Wiklander mbedtls_free( ctx ); 399817466cbSJens Wiklander } 400817466cbSJens Wiklander 401817466cbSJens Wiklander static void eckey_debug( const void *ctx, mbedtls_pk_debug_item *items ) 402817466cbSJens Wiklander { 403817466cbSJens Wiklander items->type = MBEDTLS_PK_DEBUG_ECP; 404817466cbSJens Wiklander items->name = "eckey.Q"; 405817466cbSJens Wiklander items->value = &( ((mbedtls_ecp_keypair *) ctx)->Q ); 406817466cbSJens Wiklander } 407817466cbSJens Wiklander 408817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_eckey_info = { 409817466cbSJens Wiklander MBEDTLS_PK_ECKEY, 410817466cbSJens Wiklander "EC", 411817466cbSJens Wiklander eckey_get_bitlen, 412817466cbSJens Wiklander eckey_can_do, 413817466cbSJens Wiklander #if defined(MBEDTLS_ECDSA_C) 414817466cbSJens Wiklander eckey_verify_wrap, 415817466cbSJens Wiklander eckey_sign_wrap, 416*3d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE) 417*3d3b0591SJens Wiklander eckey_verify_rs_wrap, 418*3d3b0591SJens Wiklander eckey_sign_rs_wrap, 419817466cbSJens Wiklander #endif 420*3d3b0591SJens Wiklander #else /* MBEDTLS_ECDSA_C */ 421*3d3b0591SJens Wiklander NULL, 422*3d3b0591SJens Wiklander NULL, 423*3d3b0591SJens Wiklander #endif /* MBEDTLS_ECDSA_C */ 424817466cbSJens Wiklander NULL, 425817466cbSJens Wiklander NULL, 426817466cbSJens Wiklander eckey_check_pair, 427817466cbSJens Wiklander eckey_alloc_wrap, 428817466cbSJens Wiklander eckey_free_wrap, 429*3d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 430*3d3b0591SJens Wiklander eckey_rs_alloc, 431*3d3b0591SJens Wiklander eckey_rs_free, 432*3d3b0591SJens Wiklander #endif 433817466cbSJens Wiklander eckey_debug, 434817466cbSJens Wiklander }; 435817466cbSJens Wiklander 436817466cbSJens Wiklander /* 437817466cbSJens Wiklander * EC key restricted to ECDH 438817466cbSJens Wiklander */ 439817466cbSJens Wiklander static int eckeydh_can_do( mbedtls_pk_type_t type ) 440817466cbSJens Wiklander { 441817466cbSJens Wiklander return( type == MBEDTLS_PK_ECKEY || 442817466cbSJens Wiklander type == MBEDTLS_PK_ECKEY_DH ); 443817466cbSJens Wiklander } 444817466cbSJens Wiklander 445817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_eckeydh_info = { 446817466cbSJens Wiklander MBEDTLS_PK_ECKEY_DH, 447817466cbSJens Wiklander "EC_DH", 448817466cbSJens Wiklander eckey_get_bitlen, /* Same underlying key structure */ 449817466cbSJens Wiklander eckeydh_can_do, 450817466cbSJens Wiklander NULL, 451817466cbSJens Wiklander NULL, 452*3d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 453*3d3b0591SJens Wiklander NULL, 454*3d3b0591SJens Wiklander NULL, 455*3d3b0591SJens Wiklander #endif 456817466cbSJens Wiklander NULL, 457817466cbSJens Wiklander NULL, 458817466cbSJens Wiklander eckey_check_pair, 459817466cbSJens Wiklander eckey_alloc_wrap, /* Same underlying key structure */ 460817466cbSJens Wiklander eckey_free_wrap, /* Same underlying key structure */ 461*3d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 462*3d3b0591SJens Wiklander NULL, 463*3d3b0591SJens Wiklander NULL, 464*3d3b0591SJens Wiklander #endif 465817466cbSJens Wiklander eckey_debug, /* Same underlying key structure */ 466817466cbSJens Wiklander }; 467817466cbSJens Wiklander #endif /* MBEDTLS_ECP_C */ 468817466cbSJens Wiklander 469817466cbSJens Wiklander #if defined(MBEDTLS_ECDSA_C) 470817466cbSJens Wiklander static int ecdsa_can_do( mbedtls_pk_type_t type ) 471817466cbSJens Wiklander { 472817466cbSJens Wiklander return( type == MBEDTLS_PK_ECDSA ); 473817466cbSJens Wiklander } 474817466cbSJens Wiklander 475817466cbSJens Wiklander static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, 476817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 477817466cbSJens Wiklander const unsigned char *sig, size_t sig_len ) 478817466cbSJens Wiklander { 479817466cbSJens Wiklander int ret; 480817466cbSJens Wiklander ((void) md_alg); 481817466cbSJens Wiklander 482817466cbSJens Wiklander ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx, 483817466cbSJens Wiklander hash, hash_len, sig, sig_len ); 484817466cbSJens Wiklander 485817466cbSJens Wiklander if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH ) 486817466cbSJens Wiklander return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); 487817466cbSJens Wiklander 488817466cbSJens Wiklander return( ret ); 489817466cbSJens Wiklander } 490817466cbSJens Wiklander 491817466cbSJens Wiklander static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, 492817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 493817466cbSJens Wiklander unsigned char *sig, size_t *sig_len, 494817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 495817466cbSJens Wiklander { 496817466cbSJens Wiklander return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx, 497817466cbSJens Wiklander md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) ); 498817466cbSJens Wiklander } 499817466cbSJens Wiklander 500*3d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE) 501*3d3b0591SJens Wiklander static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, 502*3d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 503*3d3b0591SJens Wiklander const unsigned char *sig, size_t sig_len, 504*3d3b0591SJens Wiklander void *rs_ctx ) 505*3d3b0591SJens Wiklander { 506*3d3b0591SJens Wiklander int ret; 507*3d3b0591SJens Wiklander ((void) md_alg); 508*3d3b0591SJens Wiklander 509*3d3b0591SJens Wiklander ret = mbedtls_ecdsa_read_signature_restartable( 510*3d3b0591SJens Wiklander (mbedtls_ecdsa_context *) ctx, 511*3d3b0591SJens Wiklander hash, hash_len, sig, sig_len, 512*3d3b0591SJens Wiklander (mbedtls_ecdsa_restart_ctx *) rs_ctx ); 513*3d3b0591SJens Wiklander 514*3d3b0591SJens Wiklander if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH ) 515*3d3b0591SJens Wiklander return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); 516*3d3b0591SJens Wiklander 517*3d3b0591SJens Wiklander return( ret ); 518*3d3b0591SJens Wiklander } 519*3d3b0591SJens Wiklander 520*3d3b0591SJens Wiklander static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, 521*3d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 522*3d3b0591SJens Wiklander unsigned char *sig, size_t *sig_len, 523*3d3b0591SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, 524*3d3b0591SJens Wiklander void *rs_ctx ) 525*3d3b0591SJens Wiklander { 526*3d3b0591SJens Wiklander return( mbedtls_ecdsa_write_signature_restartable( 527*3d3b0591SJens Wiklander (mbedtls_ecdsa_context *) ctx, 528*3d3b0591SJens Wiklander md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng, 529*3d3b0591SJens Wiklander (mbedtls_ecdsa_restart_ctx *) rs_ctx ) ); 530*3d3b0591SJens Wiklander 531*3d3b0591SJens Wiklander } 532*3d3b0591SJens Wiklander #endif /* MBEDTLS_ECP_RESTARTABLE */ 533*3d3b0591SJens Wiklander 534817466cbSJens Wiklander static void *ecdsa_alloc_wrap( void ) 535817466cbSJens Wiklander { 536817466cbSJens Wiklander void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) ); 537817466cbSJens Wiklander 538817466cbSJens Wiklander if( ctx != NULL ) 539817466cbSJens Wiklander mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx ); 540817466cbSJens Wiklander 541817466cbSJens Wiklander return( ctx ); 542817466cbSJens Wiklander } 543817466cbSJens Wiklander 544817466cbSJens Wiklander static void ecdsa_free_wrap( void *ctx ) 545817466cbSJens Wiklander { 546817466cbSJens Wiklander mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx ); 547817466cbSJens Wiklander mbedtls_free( ctx ); 548817466cbSJens Wiklander } 549817466cbSJens Wiklander 550*3d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE) 551*3d3b0591SJens Wiklander static void *ecdsa_rs_alloc( void ) 552*3d3b0591SJens Wiklander { 553*3d3b0591SJens Wiklander void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_restart_ctx ) ); 554*3d3b0591SJens Wiklander 555*3d3b0591SJens Wiklander if( ctx != NULL ) 556*3d3b0591SJens Wiklander mbedtls_ecdsa_restart_init( ctx ); 557*3d3b0591SJens Wiklander 558*3d3b0591SJens Wiklander return( ctx ); 559*3d3b0591SJens Wiklander } 560*3d3b0591SJens Wiklander 561*3d3b0591SJens Wiklander static void ecdsa_rs_free( void *ctx ) 562*3d3b0591SJens Wiklander { 563*3d3b0591SJens Wiklander mbedtls_ecdsa_restart_free( ctx ); 564*3d3b0591SJens Wiklander mbedtls_free( ctx ); 565*3d3b0591SJens Wiklander } 566*3d3b0591SJens Wiklander #endif /* MBEDTLS_ECP_RESTARTABLE */ 567*3d3b0591SJens Wiklander 568817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_ecdsa_info = { 569817466cbSJens Wiklander MBEDTLS_PK_ECDSA, 570817466cbSJens Wiklander "ECDSA", 571817466cbSJens Wiklander eckey_get_bitlen, /* Compatible key structures */ 572817466cbSJens Wiklander ecdsa_can_do, 573817466cbSJens Wiklander ecdsa_verify_wrap, 574817466cbSJens Wiklander ecdsa_sign_wrap, 575*3d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE) 576*3d3b0591SJens Wiklander ecdsa_verify_rs_wrap, 577*3d3b0591SJens Wiklander ecdsa_sign_rs_wrap, 578*3d3b0591SJens Wiklander #endif 579817466cbSJens Wiklander NULL, 580817466cbSJens Wiklander NULL, 581817466cbSJens Wiklander eckey_check_pair, /* Compatible key structures */ 582817466cbSJens Wiklander ecdsa_alloc_wrap, 583817466cbSJens Wiklander ecdsa_free_wrap, 584*3d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE) 585*3d3b0591SJens Wiklander ecdsa_rs_alloc, 586*3d3b0591SJens Wiklander ecdsa_rs_free, 587*3d3b0591SJens Wiklander #endif 588817466cbSJens Wiklander eckey_debug, /* Compatible key structures */ 589817466cbSJens Wiklander }; 590817466cbSJens Wiklander #endif /* MBEDTLS_ECDSA_C */ 591817466cbSJens Wiklander 592817466cbSJens Wiklander #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) 593817466cbSJens Wiklander /* 594817466cbSJens Wiklander * Support for alternative RSA-private implementations 595817466cbSJens Wiklander */ 596817466cbSJens Wiklander 597817466cbSJens Wiklander static int rsa_alt_can_do( mbedtls_pk_type_t type ) 598817466cbSJens Wiklander { 599817466cbSJens Wiklander return( type == MBEDTLS_PK_RSA ); 600817466cbSJens Wiklander } 601817466cbSJens Wiklander 602817466cbSJens Wiklander static size_t rsa_alt_get_bitlen( const void *ctx ) 603817466cbSJens Wiklander { 604817466cbSJens Wiklander const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx; 605817466cbSJens Wiklander 606817466cbSJens Wiklander return( 8 * rsa_alt->key_len_func( rsa_alt->key ) ); 607817466cbSJens Wiklander } 608817466cbSJens Wiklander 609817466cbSJens Wiklander static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, 610817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 611817466cbSJens Wiklander unsigned char *sig, size_t *sig_len, 612817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 613817466cbSJens Wiklander { 614817466cbSJens Wiklander mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx; 615817466cbSJens Wiklander 616*3d3b0591SJens Wiklander #if SIZE_MAX > UINT_MAX 617817466cbSJens Wiklander if( UINT_MAX < hash_len ) 618817466cbSJens Wiklander return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 619*3d3b0591SJens Wiklander #endif /* SIZE_MAX > UINT_MAX */ 620817466cbSJens Wiklander 621817466cbSJens Wiklander *sig_len = rsa_alt->key_len_func( rsa_alt->key ); 622817466cbSJens Wiklander 623817466cbSJens Wiklander return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, 624817466cbSJens Wiklander md_alg, (unsigned int) hash_len, hash, sig ) ); 625817466cbSJens Wiklander } 626817466cbSJens Wiklander 627817466cbSJens Wiklander static int rsa_alt_decrypt_wrap( void *ctx, 628817466cbSJens Wiklander const unsigned char *input, size_t ilen, 629817466cbSJens Wiklander unsigned char *output, size_t *olen, size_t osize, 630817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 631817466cbSJens Wiklander { 632817466cbSJens Wiklander mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx; 633817466cbSJens Wiklander 634817466cbSJens Wiklander ((void) f_rng); 635817466cbSJens Wiklander ((void) p_rng); 636817466cbSJens Wiklander 637817466cbSJens Wiklander if( ilen != rsa_alt->key_len_func( rsa_alt->key ) ) 638817466cbSJens Wiklander return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); 639817466cbSJens Wiklander 640817466cbSJens Wiklander return( rsa_alt->decrypt_func( rsa_alt->key, 641817466cbSJens Wiklander MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) ); 642817466cbSJens Wiklander } 643817466cbSJens Wiklander 644817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C) 645817466cbSJens Wiklander static int rsa_alt_check_pair( const void *pub, const void *prv ) 646817466cbSJens Wiklander { 647817466cbSJens Wiklander unsigned char sig[MBEDTLS_MPI_MAX_SIZE]; 648817466cbSJens Wiklander unsigned char hash[32]; 649817466cbSJens Wiklander size_t sig_len = 0; 650817466cbSJens Wiklander int ret; 651817466cbSJens Wiklander 652817466cbSJens Wiklander if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) ) 653817466cbSJens Wiklander return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); 654817466cbSJens Wiklander 655817466cbSJens Wiklander memset( hash, 0x2a, sizeof( hash ) ); 656817466cbSJens Wiklander 657817466cbSJens Wiklander if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE, 658817466cbSJens Wiklander hash, sizeof( hash ), 659817466cbSJens Wiklander sig, &sig_len, NULL, NULL ) ) != 0 ) 660817466cbSJens Wiklander { 661817466cbSJens Wiklander return( ret ); 662817466cbSJens Wiklander } 663817466cbSJens Wiklander 664817466cbSJens Wiklander if( rsa_verify_wrap( (void *) pub, MBEDTLS_MD_NONE, 665817466cbSJens Wiklander hash, sizeof( hash ), sig, sig_len ) != 0 ) 666817466cbSJens Wiklander { 667817466cbSJens Wiklander return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); 668817466cbSJens Wiklander } 669817466cbSJens Wiklander 670817466cbSJens Wiklander return( 0 ); 671817466cbSJens Wiklander } 672817466cbSJens Wiklander #endif /* MBEDTLS_RSA_C */ 673817466cbSJens Wiklander 674817466cbSJens Wiklander static void *rsa_alt_alloc_wrap( void ) 675817466cbSJens Wiklander { 676817466cbSJens Wiklander void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context ) ); 677817466cbSJens Wiklander 678817466cbSJens Wiklander if( ctx != NULL ) 679817466cbSJens Wiklander memset( ctx, 0, sizeof( mbedtls_rsa_alt_context ) ); 680817466cbSJens Wiklander 681817466cbSJens Wiklander return( ctx ); 682817466cbSJens Wiklander } 683817466cbSJens Wiklander 684817466cbSJens Wiklander static void rsa_alt_free_wrap( void *ctx ) 685817466cbSJens Wiklander { 686*3d3b0591SJens Wiklander mbedtls_platform_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) ); 687817466cbSJens Wiklander mbedtls_free( ctx ); 688817466cbSJens Wiklander } 689817466cbSJens Wiklander 690817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_rsa_alt_info = { 691817466cbSJens Wiklander MBEDTLS_PK_RSA_ALT, 692817466cbSJens Wiklander "RSA-alt", 693817466cbSJens Wiklander rsa_alt_get_bitlen, 694817466cbSJens Wiklander rsa_alt_can_do, 695817466cbSJens Wiklander NULL, 696817466cbSJens Wiklander rsa_alt_sign_wrap, 697*3d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 698*3d3b0591SJens Wiklander NULL, 699*3d3b0591SJens Wiklander NULL, 700*3d3b0591SJens Wiklander #endif 701817466cbSJens Wiklander rsa_alt_decrypt_wrap, 702817466cbSJens Wiklander NULL, 703817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C) 704817466cbSJens Wiklander rsa_alt_check_pair, 705817466cbSJens Wiklander #else 706817466cbSJens Wiklander NULL, 707817466cbSJens Wiklander #endif 708817466cbSJens Wiklander rsa_alt_alloc_wrap, 709817466cbSJens Wiklander rsa_alt_free_wrap, 710*3d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 711*3d3b0591SJens Wiklander NULL, 712*3d3b0591SJens Wiklander NULL, 713*3d3b0591SJens Wiklander #endif 714817466cbSJens Wiklander NULL, 715817466cbSJens Wiklander }; 716817466cbSJens Wiklander 717817466cbSJens Wiklander #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ 718817466cbSJens Wiklander 719817466cbSJens Wiklander #endif /* MBEDTLS_PK_C */ 720