1*c6672fdcSEdison 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 #include "mbedtls/bignum.h" 34817466cbSJens Wiklander 35817466cbSJens Wiklander #include <string.h> 36817466cbSJens Wiklander 37817466cbSJens Wiklander #if defined(MBEDTLS_ECP_C) 38817466cbSJens Wiklander #include "mbedtls/ecp.h" 39817466cbSJens Wiklander #endif 40817466cbSJens Wiklander 41817466cbSJens Wiklander #if defined(MBEDTLS_ECDSA_C) 42817466cbSJens Wiklander #include "mbedtls/ecdsa.h" 43817466cbSJens Wiklander #endif 44817466cbSJens Wiklander 45817466cbSJens Wiklander #if defined(MBEDTLS_PLATFORM_C) 46817466cbSJens Wiklander #include "mbedtls/platform.h" 47817466cbSJens Wiklander #else 48817466cbSJens Wiklander #include <stdlib.h> 49817466cbSJens Wiklander #define mbedtls_calloc calloc 50817466cbSJens Wiklander #define mbedtls_free free 51817466cbSJens Wiklander #endif 52817466cbSJens Wiklander 53817466cbSJens Wiklander #include <limits.h> 54817466cbSJens Wiklander 55817466cbSJens Wiklander #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) 56817466cbSJens Wiklander /* Implementation that should never be optimized out by the compiler */ 57817466cbSJens Wiklander static void mbedtls_zeroize( void *v, size_t n ) { 58817466cbSJens Wiklander volatile unsigned char *p = v; while( n-- ) *p++ = 0; 59817466cbSJens Wiklander } 60817466cbSJens Wiklander #endif 61817466cbSJens Wiklander 62817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C) 63817466cbSJens Wiklander static int rsa_can_do( mbedtls_pk_type_t type ) 64817466cbSJens Wiklander { 65817466cbSJens Wiklander return( type == MBEDTLS_PK_RSA || 66817466cbSJens Wiklander type == MBEDTLS_PK_RSASSA_PSS ); 67817466cbSJens Wiklander } 68817466cbSJens Wiklander 69817466cbSJens Wiklander static size_t rsa_get_bitlen( const void *ctx ) 70817466cbSJens Wiklander { 71817466cbSJens Wiklander return( 8 * ((const mbedtls_rsa_context *) ctx)->len ); 72817466cbSJens Wiklander } 73817466cbSJens Wiklander 74817466cbSJens Wiklander static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, 75817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 76817466cbSJens Wiklander const unsigned char *sig, size_t sig_len ) 77817466cbSJens Wiklander { 78817466cbSJens Wiklander int ret; 79817466cbSJens Wiklander 80817466cbSJens Wiklander #if defined(MBEDTLS_HAVE_INT64) 81817466cbSJens Wiklander if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) 82817466cbSJens Wiklander return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 83817466cbSJens Wiklander #endif /* MBEDTLS_HAVE_INT64 */ 84817466cbSJens Wiklander 85817466cbSJens Wiklander if( sig_len < ((mbedtls_rsa_context *) ctx)->len ) 86817466cbSJens Wiklander return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); 87817466cbSJens Wiklander 88817466cbSJens Wiklander if( ( ret = mbedtls_rsa_pkcs1_verify( (mbedtls_rsa_context *) ctx, NULL, NULL, 89817466cbSJens Wiklander MBEDTLS_RSA_PUBLIC, md_alg, 90817466cbSJens Wiklander (unsigned int) hash_len, hash, sig ) ) != 0 ) 91817466cbSJens Wiklander return( ret ); 92817466cbSJens Wiklander 93817466cbSJens Wiklander if( sig_len > ((mbedtls_rsa_context *) ctx)->len ) 94817466cbSJens Wiklander return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); 95817466cbSJens Wiklander 96817466cbSJens Wiklander return( 0 ); 97817466cbSJens Wiklander } 98817466cbSJens Wiklander 99817466cbSJens Wiklander static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, 100817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 101817466cbSJens Wiklander unsigned char *sig, size_t *sig_len, 102817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 103817466cbSJens Wiklander { 104817466cbSJens Wiklander #if defined(MBEDTLS_HAVE_INT64) 105817466cbSJens Wiklander if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) 106817466cbSJens Wiklander return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 107817466cbSJens Wiklander #endif /* MBEDTLS_HAVE_INT64 */ 108817466cbSJens Wiklander 109817466cbSJens Wiklander *sig_len = ((mbedtls_rsa_context *) ctx)->len; 110817466cbSJens Wiklander 111817466cbSJens Wiklander return( mbedtls_rsa_pkcs1_sign( (mbedtls_rsa_context *) ctx, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, 112817466cbSJens Wiklander md_alg, (unsigned int) hash_len, hash, sig ) ); 113817466cbSJens Wiklander } 114817466cbSJens Wiklander 115817466cbSJens Wiklander static int rsa_decrypt_wrap( void *ctx, 116817466cbSJens Wiklander const unsigned char *input, size_t ilen, 117817466cbSJens Wiklander unsigned char *output, size_t *olen, size_t osize, 118817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 119817466cbSJens Wiklander { 120817466cbSJens Wiklander if( ilen != ((mbedtls_rsa_context *) ctx)->len ) 121817466cbSJens Wiklander return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); 122817466cbSJens Wiklander 123817466cbSJens Wiklander return( mbedtls_rsa_pkcs1_decrypt( (mbedtls_rsa_context *) ctx, f_rng, p_rng, 124817466cbSJens Wiklander MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) ); 125817466cbSJens Wiklander } 126817466cbSJens Wiklander 127817466cbSJens Wiklander static int rsa_encrypt_wrap( void *ctx, 128817466cbSJens Wiklander const unsigned char *input, size_t ilen, 129817466cbSJens Wiklander unsigned char *output, size_t *olen, size_t osize, 130817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 131817466cbSJens Wiklander { 132817466cbSJens Wiklander *olen = ((mbedtls_rsa_context *) ctx)->len; 133817466cbSJens Wiklander 134817466cbSJens Wiklander if( *olen > osize ) 135817466cbSJens Wiklander return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE ); 136817466cbSJens Wiklander 137817466cbSJens Wiklander return( mbedtls_rsa_pkcs1_encrypt( (mbedtls_rsa_context *) ctx, 138817466cbSJens Wiklander f_rng, p_rng, MBEDTLS_RSA_PUBLIC, ilen, input, output ) ); 139817466cbSJens Wiklander } 140817466cbSJens Wiklander 141817466cbSJens Wiklander static int rsa_check_pair_wrap( const void *pub, const void *prv ) 142817466cbSJens Wiklander { 143817466cbSJens Wiklander return( mbedtls_rsa_check_pub_priv( (const mbedtls_rsa_context *) pub, 144817466cbSJens Wiklander (const mbedtls_rsa_context *) prv ) ); 145817466cbSJens Wiklander } 146817466cbSJens Wiklander 147817466cbSJens Wiklander static void *rsa_alloc_wrap( void ) 148817466cbSJens Wiklander { 149817466cbSJens Wiklander void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_context ) ); 150817466cbSJens Wiklander 151817466cbSJens Wiklander if( ctx != NULL ) 152817466cbSJens Wiklander mbedtls_rsa_init( (mbedtls_rsa_context *) ctx, 0, 0 ); 153817466cbSJens Wiklander 154817466cbSJens Wiklander return( ctx ); 155817466cbSJens Wiklander } 156817466cbSJens Wiklander 157817466cbSJens Wiklander static void rsa_free_wrap( void *ctx ) 158817466cbSJens Wiklander { 159817466cbSJens Wiklander mbedtls_rsa_free( (mbedtls_rsa_context *) ctx ); 160817466cbSJens Wiklander mbedtls_free( ctx ); 161817466cbSJens Wiklander } 162817466cbSJens Wiklander 163817466cbSJens Wiklander static void rsa_debug( const void *ctx, mbedtls_pk_debug_item *items ) 164817466cbSJens Wiklander { 165817466cbSJens Wiklander items->type = MBEDTLS_PK_DEBUG_MPI; 166817466cbSJens Wiklander items->name = "rsa.N"; 167817466cbSJens Wiklander items->value = &( ((mbedtls_rsa_context *) ctx)->N ); 168817466cbSJens Wiklander 169817466cbSJens Wiklander items++; 170817466cbSJens Wiklander 171817466cbSJens Wiklander items->type = MBEDTLS_PK_DEBUG_MPI; 172817466cbSJens Wiklander items->name = "rsa.E"; 173817466cbSJens Wiklander items->value = &( ((mbedtls_rsa_context *) ctx)->E ); 174817466cbSJens Wiklander } 175817466cbSJens Wiklander 176817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_rsa_info = { 177817466cbSJens Wiklander MBEDTLS_PK_RSA, 178817466cbSJens Wiklander "RSA", 179817466cbSJens Wiklander rsa_get_bitlen, 180817466cbSJens Wiklander rsa_can_do, 181817466cbSJens Wiklander rsa_verify_wrap, 182817466cbSJens Wiklander rsa_sign_wrap, 183817466cbSJens Wiklander rsa_decrypt_wrap, 184817466cbSJens Wiklander rsa_encrypt_wrap, 185817466cbSJens Wiklander rsa_check_pair_wrap, 186817466cbSJens Wiklander rsa_alloc_wrap, 187817466cbSJens Wiklander rsa_free_wrap, 188817466cbSJens Wiklander rsa_debug, 189817466cbSJens Wiklander }; 190817466cbSJens Wiklander #endif /* MBEDTLS_RSA_C */ 191817466cbSJens Wiklander 192817466cbSJens Wiklander #if defined(MBEDTLS_ECP_C) 193817466cbSJens Wiklander /* 194817466cbSJens Wiklander * Generic EC key 195817466cbSJens Wiklander */ 196817466cbSJens Wiklander static int eckey_can_do( mbedtls_pk_type_t type ) 197817466cbSJens Wiklander { 198817466cbSJens Wiklander return( type == MBEDTLS_PK_ECKEY || 199817466cbSJens Wiklander type == MBEDTLS_PK_ECKEY_DH || 200817466cbSJens Wiklander type == MBEDTLS_PK_ECDSA ); 201817466cbSJens Wiklander } 202817466cbSJens Wiklander 203817466cbSJens Wiklander static size_t eckey_get_bitlen( const void *ctx ) 204817466cbSJens Wiklander { 205817466cbSJens Wiklander return( ((mbedtls_ecp_keypair *) ctx)->grp.pbits ); 206817466cbSJens Wiklander } 207817466cbSJens Wiklander 208817466cbSJens Wiklander #if defined(MBEDTLS_ECDSA_C) 209817466cbSJens Wiklander /* Forward declarations */ 210817466cbSJens Wiklander static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, 211817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 212817466cbSJens Wiklander const unsigned char *sig, size_t sig_len ); 213817466cbSJens Wiklander 214817466cbSJens Wiklander static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, 215817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 216817466cbSJens Wiklander unsigned char *sig, size_t *sig_len, 217817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); 218817466cbSJens Wiklander 219817466cbSJens Wiklander static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, 220817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 221817466cbSJens Wiklander const unsigned char *sig, size_t sig_len ) 222817466cbSJens Wiklander { 223817466cbSJens Wiklander int ret; 224817466cbSJens Wiklander mbedtls_ecdsa_context ecdsa; 225817466cbSJens Wiklander 226817466cbSJens Wiklander mbedtls_ecdsa_init( &ecdsa ); 227817466cbSJens Wiklander 228817466cbSJens Wiklander if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 ) 229817466cbSJens Wiklander ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len ); 230817466cbSJens Wiklander 231817466cbSJens Wiklander mbedtls_ecdsa_free( &ecdsa ); 232817466cbSJens Wiklander 233817466cbSJens Wiklander return( ret ); 234817466cbSJens Wiklander } 235817466cbSJens Wiklander 236817466cbSJens Wiklander static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, 237817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 238817466cbSJens Wiklander unsigned char *sig, size_t *sig_len, 239817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 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_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len, 248817466cbSJens Wiklander f_rng, p_rng ); 249817466cbSJens Wiklander 250817466cbSJens Wiklander mbedtls_ecdsa_free( &ecdsa ); 251817466cbSJens Wiklander 252817466cbSJens Wiklander return( ret ); 253817466cbSJens Wiklander } 254817466cbSJens Wiklander 255817466cbSJens Wiklander #endif /* MBEDTLS_ECDSA_C */ 256817466cbSJens Wiklander 257817466cbSJens Wiklander static int eckey_check_pair( const void *pub, const void *prv ) 258817466cbSJens Wiklander { 259817466cbSJens Wiklander return( mbedtls_ecp_check_pub_priv( (const mbedtls_ecp_keypair *) pub, 260817466cbSJens Wiklander (const mbedtls_ecp_keypair *) prv ) ); 261817466cbSJens Wiklander } 262817466cbSJens Wiklander 263817466cbSJens Wiklander static void *eckey_alloc_wrap( void ) 264817466cbSJens Wiklander { 265817466cbSJens Wiklander void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) ); 266817466cbSJens Wiklander 267817466cbSJens Wiklander if( ctx != NULL ) 268817466cbSJens Wiklander mbedtls_ecp_keypair_init( ctx ); 269817466cbSJens Wiklander 270817466cbSJens Wiklander return( ctx ); 271817466cbSJens Wiklander } 272817466cbSJens Wiklander 273817466cbSJens Wiklander static void eckey_free_wrap( void *ctx ) 274817466cbSJens Wiklander { 275817466cbSJens Wiklander mbedtls_ecp_keypair_free( (mbedtls_ecp_keypair *) ctx ); 276817466cbSJens Wiklander mbedtls_free( ctx ); 277817466cbSJens Wiklander } 278817466cbSJens Wiklander 279817466cbSJens Wiklander static void eckey_debug( const void *ctx, mbedtls_pk_debug_item *items ) 280817466cbSJens Wiklander { 281817466cbSJens Wiklander items->type = MBEDTLS_PK_DEBUG_ECP; 282817466cbSJens Wiklander items->name = "eckey.Q"; 283817466cbSJens Wiklander items->value = &( ((mbedtls_ecp_keypair *) ctx)->Q ); 284817466cbSJens Wiklander } 285817466cbSJens Wiklander 286817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_eckey_info = { 287817466cbSJens Wiklander MBEDTLS_PK_ECKEY, 288817466cbSJens Wiklander "EC", 289817466cbSJens Wiklander eckey_get_bitlen, 290817466cbSJens Wiklander eckey_can_do, 291817466cbSJens Wiklander #if defined(MBEDTLS_ECDSA_C) 292817466cbSJens Wiklander eckey_verify_wrap, 293817466cbSJens Wiklander eckey_sign_wrap, 294817466cbSJens Wiklander #else 295817466cbSJens Wiklander NULL, 296817466cbSJens Wiklander NULL, 297817466cbSJens Wiklander #endif 298817466cbSJens Wiklander NULL, 299817466cbSJens Wiklander NULL, 300817466cbSJens Wiklander eckey_check_pair, 301817466cbSJens Wiklander eckey_alloc_wrap, 302817466cbSJens Wiklander eckey_free_wrap, 303817466cbSJens Wiklander eckey_debug, 304817466cbSJens Wiklander }; 305817466cbSJens Wiklander 306817466cbSJens Wiklander /* 307817466cbSJens Wiklander * EC key restricted to ECDH 308817466cbSJens Wiklander */ 309817466cbSJens Wiklander static int eckeydh_can_do( mbedtls_pk_type_t type ) 310817466cbSJens Wiklander { 311817466cbSJens Wiklander return( type == MBEDTLS_PK_ECKEY || 312817466cbSJens Wiklander type == MBEDTLS_PK_ECKEY_DH ); 313817466cbSJens Wiklander } 314817466cbSJens Wiklander 315817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_eckeydh_info = { 316817466cbSJens Wiklander MBEDTLS_PK_ECKEY_DH, 317817466cbSJens Wiklander "EC_DH", 318817466cbSJens Wiklander eckey_get_bitlen, /* Same underlying key structure */ 319817466cbSJens Wiklander eckeydh_can_do, 320817466cbSJens Wiklander NULL, 321817466cbSJens Wiklander NULL, 322817466cbSJens Wiklander NULL, 323817466cbSJens Wiklander NULL, 324817466cbSJens Wiklander eckey_check_pair, 325817466cbSJens Wiklander eckey_alloc_wrap, /* Same underlying key structure */ 326817466cbSJens Wiklander eckey_free_wrap, /* Same underlying key structure */ 327817466cbSJens Wiklander eckey_debug, /* Same underlying key structure */ 328817466cbSJens Wiklander }; 329817466cbSJens Wiklander #endif /* MBEDTLS_ECP_C */ 330817466cbSJens Wiklander 331817466cbSJens Wiklander #if defined(MBEDTLS_ECDSA_C) 332817466cbSJens Wiklander static int ecdsa_can_do( mbedtls_pk_type_t type ) 333817466cbSJens Wiklander { 334817466cbSJens Wiklander return( type == MBEDTLS_PK_ECDSA ); 335817466cbSJens Wiklander } 336817466cbSJens Wiklander 337817466cbSJens Wiklander static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, 338817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 339817466cbSJens Wiklander const unsigned char *sig, size_t sig_len ) 340817466cbSJens Wiklander { 341817466cbSJens Wiklander int ret; 342817466cbSJens Wiklander ((void) md_alg); 343817466cbSJens Wiklander 344817466cbSJens Wiklander ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx, 345817466cbSJens Wiklander hash, hash_len, sig, sig_len ); 346817466cbSJens Wiklander 347817466cbSJens Wiklander if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH ) 348817466cbSJens Wiklander return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); 349817466cbSJens Wiklander 350817466cbSJens Wiklander return( ret ); 351817466cbSJens Wiklander } 352817466cbSJens Wiklander 353817466cbSJens Wiklander static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, 354817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 355817466cbSJens Wiklander unsigned char *sig, size_t *sig_len, 356817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 357817466cbSJens Wiklander { 358817466cbSJens Wiklander return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx, 359817466cbSJens Wiklander md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) ); 360817466cbSJens Wiklander } 361817466cbSJens Wiklander 362817466cbSJens Wiklander static void *ecdsa_alloc_wrap( void ) 363817466cbSJens Wiklander { 364817466cbSJens Wiklander void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) ); 365817466cbSJens Wiklander 366817466cbSJens Wiklander if( ctx != NULL ) 367817466cbSJens Wiklander mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx ); 368817466cbSJens Wiklander 369817466cbSJens Wiklander return( ctx ); 370817466cbSJens Wiklander } 371817466cbSJens Wiklander 372817466cbSJens Wiklander static void ecdsa_free_wrap( void *ctx ) 373817466cbSJens Wiklander { 374817466cbSJens Wiklander mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx ); 375817466cbSJens Wiklander mbedtls_free( ctx ); 376817466cbSJens Wiklander } 377817466cbSJens Wiklander 378817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_ecdsa_info = { 379817466cbSJens Wiklander MBEDTLS_PK_ECDSA, 380817466cbSJens Wiklander "ECDSA", 381817466cbSJens Wiklander eckey_get_bitlen, /* Compatible key structures */ 382817466cbSJens Wiklander ecdsa_can_do, 383817466cbSJens Wiklander ecdsa_verify_wrap, 384817466cbSJens Wiklander ecdsa_sign_wrap, 385817466cbSJens Wiklander NULL, 386817466cbSJens Wiklander NULL, 387817466cbSJens Wiklander eckey_check_pair, /* Compatible key structures */ 388817466cbSJens Wiklander ecdsa_alloc_wrap, 389817466cbSJens Wiklander ecdsa_free_wrap, 390817466cbSJens Wiklander eckey_debug, /* Compatible key structures */ 391817466cbSJens Wiklander }; 392817466cbSJens Wiklander #endif /* MBEDTLS_ECDSA_C */ 393817466cbSJens Wiklander 394817466cbSJens Wiklander #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) 395817466cbSJens Wiklander /* 396817466cbSJens Wiklander * Support for alternative RSA-private implementations 397817466cbSJens Wiklander */ 398817466cbSJens Wiklander 399817466cbSJens Wiklander static int rsa_alt_can_do( mbedtls_pk_type_t type ) 400817466cbSJens Wiklander { 401817466cbSJens Wiklander return( type == MBEDTLS_PK_RSA ); 402817466cbSJens Wiklander } 403817466cbSJens Wiklander 404817466cbSJens Wiklander static size_t rsa_alt_get_bitlen( const void *ctx ) 405817466cbSJens Wiklander { 406817466cbSJens Wiklander const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx; 407817466cbSJens Wiklander 408817466cbSJens Wiklander return( 8 * rsa_alt->key_len_func( rsa_alt->key ) ); 409817466cbSJens Wiklander } 410817466cbSJens Wiklander 411817466cbSJens Wiklander static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, 412817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 413817466cbSJens Wiklander unsigned char *sig, size_t *sig_len, 414817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 415817466cbSJens Wiklander { 416817466cbSJens Wiklander mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx; 417817466cbSJens Wiklander 418817466cbSJens Wiklander #if defined(MBEDTLS_HAVE_INT64) 419817466cbSJens Wiklander if( UINT_MAX < hash_len ) 420817466cbSJens Wiklander return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 421817466cbSJens Wiklander #endif /* MBEDTLS_HAVE_INT64 */ 422817466cbSJens Wiklander 423817466cbSJens Wiklander *sig_len = rsa_alt->key_len_func( rsa_alt->key ); 424817466cbSJens Wiklander 425817466cbSJens Wiklander return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, 426817466cbSJens Wiklander md_alg, (unsigned int) hash_len, hash, sig ) ); 427817466cbSJens Wiklander } 428817466cbSJens Wiklander 429817466cbSJens Wiklander static int rsa_alt_decrypt_wrap( void *ctx, 430817466cbSJens Wiklander const unsigned char *input, size_t ilen, 431817466cbSJens Wiklander unsigned char *output, size_t *olen, size_t osize, 432817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 433817466cbSJens Wiklander { 434817466cbSJens Wiklander mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx; 435817466cbSJens Wiklander 436817466cbSJens Wiklander ((void) f_rng); 437817466cbSJens Wiklander ((void) p_rng); 438817466cbSJens Wiklander 439817466cbSJens Wiklander if( ilen != rsa_alt->key_len_func( rsa_alt->key ) ) 440817466cbSJens Wiklander return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); 441817466cbSJens Wiklander 442817466cbSJens Wiklander return( rsa_alt->decrypt_func( rsa_alt->key, 443817466cbSJens Wiklander MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) ); 444817466cbSJens Wiklander } 445817466cbSJens Wiklander 446817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C) 447817466cbSJens Wiklander static int rsa_alt_check_pair( const void *pub, const void *prv ) 448817466cbSJens Wiklander { 449817466cbSJens Wiklander unsigned char sig[MBEDTLS_MPI_MAX_SIZE]; 450817466cbSJens Wiklander unsigned char hash[32]; 451817466cbSJens Wiklander size_t sig_len = 0; 452817466cbSJens Wiklander int ret; 453817466cbSJens Wiklander 454817466cbSJens Wiklander if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) ) 455817466cbSJens Wiklander return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); 456817466cbSJens Wiklander 457817466cbSJens Wiklander memset( hash, 0x2a, sizeof( hash ) ); 458817466cbSJens Wiklander 459817466cbSJens Wiklander if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE, 460817466cbSJens Wiklander hash, sizeof( hash ), 461817466cbSJens Wiklander sig, &sig_len, NULL, NULL ) ) != 0 ) 462817466cbSJens Wiklander { 463817466cbSJens Wiklander return( ret ); 464817466cbSJens Wiklander } 465817466cbSJens Wiklander 466817466cbSJens Wiklander if( rsa_verify_wrap( (void *) pub, MBEDTLS_MD_NONE, 467817466cbSJens Wiklander hash, sizeof( hash ), sig, sig_len ) != 0 ) 468817466cbSJens Wiklander { 469817466cbSJens Wiklander return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); 470817466cbSJens Wiklander } 471817466cbSJens Wiklander 472817466cbSJens Wiklander return( 0 ); 473817466cbSJens Wiklander } 474817466cbSJens Wiklander #endif /* MBEDTLS_RSA_C */ 475817466cbSJens Wiklander 476817466cbSJens Wiklander static void *rsa_alt_alloc_wrap( void ) 477817466cbSJens Wiklander { 478817466cbSJens Wiklander void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context ) ); 479817466cbSJens Wiklander 480817466cbSJens Wiklander if( ctx != NULL ) 481817466cbSJens Wiklander memset( ctx, 0, sizeof( mbedtls_rsa_alt_context ) ); 482817466cbSJens Wiklander 483817466cbSJens Wiklander return( ctx ); 484817466cbSJens Wiklander } 485817466cbSJens Wiklander 486817466cbSJens Wiklander static void rsa_alt_free_wrap( void *ctx ) 487817466cbSJens Wiklander { 488817466cbSJens Wiklander mbedtls_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) ); 489817466cbSJens Wiklander mbedtls_free( ctx ); 490817466cbSJens Wiklander } 491817466cbSJens Wiklander 492817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_rsa_alt_info = { 493817466cbSJens Wiklander MBEDTLS_PK_RSA_ALT, 494817466cbSJens Wiklander "RSA-alt", 495817466cbSJens Wiklander rsa_alt_get_bitlen, 496817466cbSJens Wiklander rsa_alt_can_do, 497817466cbSJens Wiklander NULL, 498817466cbSJens Wiklander rsa_alt_sign_wrap, 499817466cbSJens Wiklander rsa_alt_decrypt_wrap, 500817466cbSJens Wiklander NULL, 501817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C) 502817466cbSJens Wiklander rsa_alt_check_pair, 503817466cbSJens Wiklander #else 504817466cbSJens Wiklander NULL, 505817466cbSJens Wiklander #endif 506817466cbSJens Wiklander rsa_alt_alloc_wrap, 507817466cbSJens Wiklander rsa_alt_free_wrap, 508817466cbSJens Wiklander NULL, 509817466cbSJens Wiklander }; 510817466cbSJens Wiklander 511817466cbSJens Wiklander #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ 512817466cbSJens Wiklander 513817466cbSJens Wiklander #endif /* MBEDTLS_PK_C */ 514