1817466cbSJens Wiklander /* 2817466cbSJens Wiklander * Public Key abstraction layer: wrapper functions 3817466cbSJens Wiklander * 4*7901324dSJerome Forissier * Copyright The Mbed TLS Contributors 5*7901324dSJerome Forissier * SPDX-License-Identifier: Apache-2.0 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 20*7901324dSJerome Forissier #include "common.h" 21817466cbSJens Wiklander 22817466cbSJens Wiklander #if defined(MBEDTLS_PK_C) 23817466cbSJens Wiklander #include "mbedtls/pk_internal.h" 2411fa71b9SJerome Forissier #include "mbedtls/error.h" 25817466cbSJens Wiklander 26817466cbSJens Wiklander /* Even if RSA not activated, for the sake of RSA-alt */ 27817466cbSJens Wiklander #include "mbedtls/rsa.h" 28817466cbSJens Wiklander 29817466cbSJens Wiklander #include <string.h> 30817466cbSJens Wiklander 31817466cbSJens Wiklander #if defined(MBEDTLS_ECP_C) 32817466cbSJens Wiklander #include "mbedtls/ecp.h" 33817466cbSJens Wiklander #endif 34817466cbSJens Wiklander 35817466cbSJens Wiklander #if defined(MBEDTLS_ECDSA_C) 36817466cbSJens Wiklander #include "mbedtls/ecdsa.h" 37817466cbSJens Wiklander #endif 38817466cbSJens Wiklander 3911fa71b9SJerome Forissier #if defined(MBEDTLS_USE_PSA_CRYPTO) 4011fa71b9SJerome Forissier #include "mbedtls/asn1write.h" 4111fa71b9SJerome Forissier #endif 4211fa71b9SJerome Forissier 433d3b0591SJens Wiklander #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) 443d3b0591SJens Wiklander #include "mbedtls/platform_util.h" 453d3b0591SJens Wiklander #endif 463d3b0591SJens Wiklander 4711fa71b9SJerome Forissier #if defined(MBEDTLS_USE_PSA_CRYPTO) 4811fa71b9SJerome Forissier #include "psa/crypto.h" 4911fa71b9SJerome Forissier #include "mbedtls/psa_util.h" 5011fa71b9SJerome Forissier #include "mbedtls/asn1.h" 5111fa71b9SJerome Forissier #endif 5211fa71b9SJerome Forissier 53817466cbSJens Wiklander #if defined(MBEDTLS_PLATFORM_C) 54817466cbSJens Wiklander #include "mbedtls/platform.h" 55817466cbSJens Wiklander #else 56817466cbSJens Wiklander #include <stdlib.h> 57817466cbSJens Wiklander #define mbedtls_calloc calloc 58817466cbSJens Wiklander #define mbedtls_free free 59817466cbSJens Wiklander #endif 60817466cbSJens Wiklander 61817466cbSJens Wiklander #include <limits.h> 623d3b0591SJens Wiklander #include <stdint.h> 63817466cbSJens Wiklander 64817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C) 65817466cbSJens Wiklander static int rsa_can_do( mbedtls_pk_type_t type ) 66817466cbSJens Wiklander { 67817466cbSJens Wiklander return( type == MBEDTLS_PK_RSA || 68817466cbSJens Wiklander type == MBEDTLS_PK_RSASSA_PSS ); 69817466cbSJens Wiklander } 70817466cbSJens Wiklander 71817466cbSJens Wiklander static size_t rsa_get_bitlen( const void *ctx ) 72817466cbSJens Wiklander { 733d3b0591SJens Wiklander const mbedtls_rsa_context * rsa = (const mbedtls_rsa_context *) ctx; 743d3b0591SJens Wiklander return( 8 * mbedtls_rsa_get_len( rsa ) ); 75817466cbSJens Wiklander } 76817466cbSJens Wiklander 77817466cbSJens Wiklander static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, 78817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 79817466cbSJens Wiklander const unsigned char *sig, size_t sig_len ) 80817466cbSJens Wiklander { 8111fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 823d3b0591SJens Wiklander mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; 833d3b0591SJens Wiklander size_t rsa_len = mbedtls_rsa_get_len( rsa ); 84817466cbSJens Wiklander 853d3b0591SJens Wiklander #if SIZE_MAX > UINT_MAX 86817466cbSJens Wiklander if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) 87817466cbSJens Wiklander return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 883d3b0591SJens Wiklander #endif /* SIZE_MAX > UINT_MAX */ 89817466cbSJens Wiklander 903d3b0591SJens Wiklander if( sig_len < rsa_len ) 91817466cbSJens Wiklander return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); 92817466cbSJens Wiklander 933d3b0591SJens Wiklander if( ( ret = mbedtls_rsa_pkcs1_verify( rsa, NULL, NULL, 94817466cbSJens Wiklander MBEDTLS_RSA_PUBLIC, md_alg, 95817466cbSJens Wiklander (unsigned int) hash_len, hash, sig ) ) != 0 ) 96817466cbSJens Wiklander return( ret ); 97817466cbSJens Wiklander 983d3b0591SJens Wiklander /* The buffer contains a valid signature followed by extra data. 993d3b0591SJens Wiklander * We have a special error code for that so that so that callers can 1003d3b0591SJens Wiklander * use mbedtls_pk_verify() to check "Does the buffer start with a 1013d3b0591SJens Wiklander * valid signature?" and not just "Does the buffer contain a valid 1023d3b0591SJens Wiklander * signature?". */ 1033d3b0591SJens Wiklander if( sig_len > rsa_len ) 104817466cbSJens Wiklander return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); 105817466cbSJens Wiklander 106817466cbSJens Wiklander return( 0 ); 107817466cbSJens Wiklander } 108817466cbSJens Wiklander 109817466cbSJens Wiklander static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, 110817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 111817466cbSJens Wiklander unsigned char *sig, size_t *sig_len, 112817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 113817466cbSJens Wiklander { 1143d3b0591SJens Wiklander mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; 1153d3b0591SJens Wiklander 1163d3b0591SJens Wiklander #if SIZE_MAX > UINT_MAX 117817466cbSJens Wiklander if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) 118817466cbSJens Wiklander return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 1193d3b0591SJens Wiklander #endif /* SIZE_MAX > UINT_MAX */ 120817466cbSJens Wiklander 1213d3b0591SJens Wiklander *sig_len = mbedtls_rsa_get_len( rsa ); 122817466cbSJens Wiklander 1233d3b0591SJens Wiklander return( mbedtls_rsa_pkcs1_sign( rsa, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, 124817466cbSJens Wiklander md_alg, (unsigned int) hash_len, hash, sig ) ); 125817466cbSJens Wiklander } 126817466cbSJens Wiklander 127817466cbSJens Wiklander static int rsa_decrypt_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 { 1323d3b0591SJens Wiklander mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; 1333d3b0591SJens Wiklander 1343d3b0591SJens Wiklander if( ilen != mbedtls_rsa_get_len( rsa ) ) 135817466cbSJens Wiklander return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); 136817466cbSJens Wiklander 1373d3b0591SJens Wiklander return( mbedtls_rsa_pkcs1_decrypt( rsa, f_rng, p_rng, 138817466cbSJens Wiklander MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) ); 139817466cbSJens Wiklander } 140817466cbSJens Wiklander 141817466cbSJens Wiklander static int rsa_encrypt_wrap( void *ctx, 142817466cbSJens Wiklander const unsigned char *input, size_t ilen, 143817466cbSJens Wiklander unsigned char *output, size_t *olen, size_t osize, 144817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 145817466cbSJens Wiklander { 1463d3b0591SJens Wiklander mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; 1473d3b0591SJens Wiklander *olen = mbedtls_rsa_get_len( rsa ); 148817466cbSJens Wiklander 149817466cbSJens Wiklander if( *olen > osize ) 150817466cbSJens Wiklander return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE ); 151817466cbSJens Wiklander 1523d3b0591SJens Wiklander return( mbedtls_rsa_pkcs1_encrypt( rsa, f_rng, p_rng, MBEDTLS_RSA_PUBLIC, 1533d3b0591SJens Wiklander ilen, input, output ) ); 154817466cbSJens Wiklander } 155817466cbSJens Wiklander 156817466cbSJens Wiklander static int rsa_check_pair_wrap( const void *pub, const void *prv ) 157817466cbSJens Wiklander { 158817466cbSJens Wiklander return( mbedtls_rsa_check_pub_priv( (const mbedtls_rsa_context *) pub, 159817466cbSJens Wiklander (const mbedtls_rsa_context *) prv ) ); 160817466cbSJens Wiklander } 161817466cbSJens Wiklander 162817466cbSJens Wiklander static void *rsa_alloc_wrap( void ) 163817466cbSJens Wiklander { 164817466cbSJens Wiklander void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_context ) ); 165817466cbSJens Wiklander 166817466cbSJens Wiklander if( ctx != NULL ) 167817466cbSJens Wiklander mbedtls_rsa_init( (mbedtls_rsa_context *) ctx, 0, 0 ); 168817466cbSJens Wiklander 169817466cbSJens Wiklander return( ctx ); 170817466cbSJens Wiklander } 171817466cbSJens Wiklander 172817466cbSJens Wiklander static void rsa_free_wrap( void *ctx ) 173817466cbSJens Wiklander { 174817466cbSJens Wiklander mbedtls_rsa_free( (mbedtls_rsa_context *) ctx ); 175817466cbSJens Wiklander mbedtls_free( ctx ); 176817466cbSJens Wiklander } 177817466cbSJens Wiklander 178817466cbSJens Wiklander static void rsa_debug( const void *ctx, mbedtls_pk_debug_item *items ) 179817466cbSJens Wiklander { 180817466cbSJens Wiklander items->type = MBEDTLS_PK_DEBUG_MPI; 181817466cbSJens Wiklander items->name = "rsa.N"; 182817466cbSJens Wiklander items->value = &( ((mbedtls_rsa_context *) ctx)->N ); 183817466cbSJens Wiklander 184817466cbSJens Wiklander items++; 185817466cbSJens Wiklander 186817466cbSJens Wiklander items->type = MBEDTLS_PK_DEBUG_MPI; 187817466cbSJens Wiklander items->name = "rsa.E"; 188817466cbSJens Wiklander items->value = &( ((mbedtls_rsa_context *) ctx)->E ); 189817466cbSJens Wiklander } 190817466cbSJens Wiklander 191817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_rsa_info = { 192817466cbSJens Wiklander MBEDTLS_PK_RSA, 193817466cbSJens Wiklander "RSA", 194817466cbSJens Wiklander rsa_get_bitlen, 195817466cbSJens Wiklander rsa_can_do, 196817466cbSJens Wiklander rsa_verify_wrap, 197817466cbSJens Wiklander rsa_sign_wrap, 1983d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 1993d3b0591SJens Wiklander NULL, 2003d3b0591SJens Wiklander NULL, 2013d3b0591SJens Wiklander #endif 202817466cbSJens Wiklander rsa_decrypt_wrap, 203817466cbSJens Wiklander rsa_encrypt_wrap, 204817466cbSJens Wiklander rsa_check_pair_wrap, 205817466cbSJens Wiklander rsa_alloc_wrap, 206817466cbSJens Wiklander rsa_free_wrap, 2073d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 2083d3b0591SJens Wiklander NULL, 2093d3b0591SJens Wiklander NULL, 2103d3b0591SJens Wiklander #endif 211817466cbSJens Wiklander rsa_debug, 212817466cbSJens Wiklander }; 213817466cbSJens Wiklander #endif /* MBEDTLS_RSA_C */ 214817466cbSJens Wiklander 215817466cbSJens Wiklander #if defined(MBEDTLS_ECP_C) 216817466cbSJens Wiklander /* 217817466cbSJens Wiklander * Generic EC key 218817466cbSJens Wiklander */ 219817466cbSJens Wiklander static int eckey_can_do( mbedtls_pk_type_t type ) 220817466cbSJens Wiklander { 221817466cbSJens Wiklander return( type == MBEDTLS_PK_ECKEY || 222817466cbSJens Wiklander type == MBEDTLS_PK_ECKEY_DH || 223817466cbSJens Wiklander type == MBEDTLS_PK_ECDSA ); 224817466cbSJens Wiklander } 225817466cbSJens Wiklander 226817466cbSJens Wiklander static size_t eckey_get_bitlen( const void *ctx ) 227817466cbSJens Wiklander { 228817466cbSJens Wiklander return( ((mbedtls_ecp_keypair *) ctx)->grp.pbits ); 229817466cbSJens Wiklander } 230817466cbSJens Wiklander 231817466cbSJens Wiklander #if defined(MBEDTLS_ECDSA_C) 232817466cbSJens Wiklander /* Forward declarations */ 233817466cbSJens Wiklander static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, 234817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 235817466cbSJens Wiklander const unsigned char *sig, size_t sig_len ); 236817466cbSJens Wiklander 237817466cbSJens Wiklander static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, 238817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 239817466cbSJens Wiklander unsigned char *sig, size_t *sig_len, 240817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); 241817466cbSJens Wiklander 242817466cbSJens Wiklander static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, 243817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 244817466cbSJens Wiklander const unsigned char *sig, size_t sig_len ) 245817466cbSJens Wiklander { 24611fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 247817466cbSJens Wiklander mbedtls_ecdsa_context ecdsa; 248817466cbSJens Wiklander 249817466cbSJens Wiklander mbedtls_ecdsa_init( &ecdsa ); 250817466cbSJens Wiklander 251817466cbSJens Wiklander if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 ) 252817466cbSJens Wiklander ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len ); 253817466cbSJens Wiklander 254817466cbSJens Wiklander mbedtls_ecdsa_free( &ecdsa ); 255817466cbSJens Wiklander 256817466cbSJens Wiklander return( ret ); 257817466cbSJens Wiklander } 258817466cbSJens Wiklander 259817466cbSJens Wiklander static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, 260817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 261817466cbSJens Wiklander unsigned char *sig, size_t *sig_len, 262817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 263817466cbSJens Wiklander { 26411fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 265817466cbSJens Wiklander mbedtls_ecdsa_context ecdsa; 266817466cbSJens Wiklander 267817466cbSJens Wiklander mbedtls_ecdsa_init( &ecdsa ); 268817466cbSJens Wiklander 269817466cbSJens Wiklander if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 ) 270817466cbSJens Wiklander ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len, 271817466cbSJens Wiklander f_rng, p_rng ); 272817466cbSJens Wiklander 273817466cbSJens Wiklander mbedtls_ecdsa_free( &ecdsa ); 274817466cbSJens Wiklander 275817466cbSJens Wiklander return( ret ); 276817466cbSJens Wiklander } 277817466cbSJens Wiklander 2783d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE) 2793d3b0591SJens Wiklander /* Forward declarations */ 2803d3b0591SJens Wiklander static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, 2813d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 2823d3b0591SJens Wiklander const unsigned char *sig, size_t sig_len, 2833d3b0591SJens Wiklander void *rs_ctx ); 2843d3b0591SJens Wiklander 2853d3b0591SJens Wiklander static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, 2863d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 2873d3b0591SJens Wiklander unsigned char *sig, size_t *sig_len, 2883d3b0591SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, 2893d3b0591SJens Wiklander void *rs_ctx ); 2903d3b0591SJens Wiklander 2913d3b0591SJens Wiklander /* 2923d3b0591SJens Wiklander * Restart context for ECDSA operations with ECKEY context 2933d3b0591SJens Wiklander * 2943d3b0591SJens Wiklander * We need to store an actual ECDSA context, as we need to pass the same to 2953d3b0591SJens Wiklander * the underlying ecdsa function, so we can't create it on the fly every time. 2963d3b0591SJens Wiklander */ 2973d3b0591SJens Wiklander typedef struct 2983d3b0591SJens Wiklander { 2993d3b0591SJens Wiklander mbedtls_ecdsa_restart_ctx ecdsa_rs; 3003d3b0591SJens Wiklander mbedtls_ecdsa_context ecdsa_ctx; 3013d3b0591SJens Wiklander } eckey_restart_ctx; 3023d3b0591SJens Wiklander 3033d3b0591SJens Wiklander static void *eckey_rs_alloc( void ) 3043d3b0591SJens Wiklander { 3053d3b0591SJens Wiklander eckey_restart_ctx *rs_ctx; 3063d3b0591SJens Wiklander 3073d3b0591SJens Wiklander void *ctx = mbedtls_calloc( 1, sizeof( eckey_restart_ctx ) ); 3083d3b0591SJens Wiklander 3093d3b0591SJens Wiklander if( ctx != NULL ) 3103d3b0591SJens Wiklander { 3113d3b0591SJens Wiklander rs_ctx = ctx; 3123d3b0591SJens Wiklander mbedtls_ecdsa_restart_init( &rs_ctx->ecdsa_rs ); 3133d3b0591SJens Wiklander mbedtls_ecdsa_init( &rs_ctx->ecdsa_ctx ); 3143d3b0591SJens Wiklander } 3153d3b0591SJens Wiklander 3163d3b0591SJens Wiklander return( ctx ); 3173d3b0591SJens Wiklander } 3183d3b0591SJens Wiklander 3193d3b0591SJens Wiklander static void eckey_rs_free( void *ctx ) 3203d3b0591SJens Wiklander { 3213d3b0591SJens Wiklander eckey_restart_ctx *rs_ctx; 3223d3b0591SJens Wiklander 3233d3b0591SJens Wiklander if( ctx == NULL) 3243d3b0591SJens Wiklander return; 3253d3b0591SJens Wiklander 3263d3b0591SJens Wiklander rs_ctx = ctx; 3273d3b0591SJens Wiklander mbedtls_ecdsa_restart_free( &rs_ctx->ecdsa_rs ); 3283d3b0591SJens Wiklander mbedtls_ecdsa_free( &rs_ctx->ecdsa_ctx ); 3293d3b0591SJens Wiklander 3303d3b0591SJens Wiklander mbedtls_free( ctx ); 3313d3b0591SJens Wiklander } 3323d3b0591SJens Wiklander 3333d3b0591SJens Wiklander static int eckey_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, 3343d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 3353d3b0591SJens Wiklander const unsigned char *sig, size_t sig_len, 3363d3b0591SJens Wiklander void *rs_ctx ) 3373d3b0591SJens Wiklander { 33811fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 3393d3b0591SJens Wiklander eckey_restart_ctx *rs = rs_ctx; 3403d3b0591SJens Wiklander 3413d3b0591SJens Wiklander /* Should never happen */ 3423d3b0591SJens Wiklander if( rs == NULL ) 3433d3b0591SJens Wiklander return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 3443d3b0591SJens Wiklander 3453d3b0591SJens Wiklander /* set up our own sub-context if needed (that is, on first run) */ 3463d3b0591SJens Wiklander if( rs->ecdsa_ctx.grp.pbits == 0 ) 3473d3b0591SJens Wiklander MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) ); 3483d3b0591SJens Wiklander 3493d3b0591SJens Wiklander MBEDTLS_MPI_CHK( ecdsa_verify_rs_wrap( &rs->ecdsa_ctx, 3503d3b0591SJens Wiklander md_alg, hash, hash_len, 3513d3b0591SJens Wiklander sig, sig_len, &rs->ecdsa_rs ) ); 3523d3b0591SJens Wiklander 3533d3b0591SJens Wiklander cleanup: 3543d3b0591SJens Wiklander return( ret ); 3553d3b0591SJens Wiklander } 3563d3b0591SJens Wiklander 3573d3b0591SJens Wiklander static int eckey_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, 3583d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 3593d3b0591SJens Wiklander unsigned char *sig, size_t *sig_len, 3603d3b0591SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, 3613d3b0591SJens Wiklander void *rs_ctx ) 3623d3b0591SJens Wiklander { 36311fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 3643d3b0591SJens Wiklander eckey_restart_ctx *rs = rs_ctx; 3653d3b0591SJens Wiklander 3663d3b0591SJens Wiklander /* Should never happen */ 3673d3b0591SJens Wiklander if( rs == NULL ) 3683d3b0591SJens Wiklander return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 3693d3b0591SJens Wiklander 3703d3b0591SJens Wiklander /* set up our own sub-context if needed (that is, on first run) */ 3713d3b0591SJens Wiklander if( rs->ecdsa_ctx.grp.pbits == 0 ) 3723d3b0591SJens Wiklander MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) ); 3733d3b0591SJens Wiklander 3743d3b0591SJens Wiklander MBEDTLS_MPI_CHK( ecdsa_sign_rs_wrap( &rs->ecdsa_ctx, md_alg, 3753d3b0591SJens Wiklander hash, hash_len, sig, sig_len, 3763d3b0591SJens Wiklander f_rng, p_rng, &rs->ecdsa_rs ) ); 3773d3b0591SJens Wiklander 3783d3b0591SJens Wiklander cleanup: 3793d3b0591SJens Wiklander return( ret ); 3803d3b0591SJens Wiklander } 3813d3b0591SJens Wiklander #endif /* MBEDTLS_ECP_RESTARTABLE */ 382817466cbSJens Wiklander #endif /* MBEDTLS_ECDSA_C */ 383817466cbSJens Wiklander 384817466cbSJens Wiklander static int eckey_check_pair( const void *pub, const void *prv ) 385817466cbSJens Wiklander { 386817466cbSJens Wiklander return( mbedtls_ecp_check_pub_priv( (const mbedtls_ecp_keypair *) pub, 387817466cbSJens Wiklander (const mbedtls_ecp_keypair *) prv ) ); 388817466cbSJens Wiklander } 389817466cbSJens Wiklander 390817466cbSJens Wiklander static void *eckey_alloc_wrap( void ) 391817466cbSJens Wiklander { 392817466cbSJens Wiklander void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) ); 393817466cbSJens Wiklander 394817466cbSJens Wiklander if( ctx != NULL ) 395817466cbSJens Wiklander mbedtls_ecp_keypair_init( ctx ); 396817466cbSJens Wiklander 397817466cbSJens Wiklander return( ctx ); 398817466cbSJens Wiklander } 399817466cbSJens Wiklander 400817466cbSJens Wiklander static void eckey_free_wrap( void *ctx ) 401817466cbSJens Wiklander { 402817466cbSJens Wiklander mbedtls_ecp_keypair_free( (mbedtls_ecp_keypair *) ctx ); 403817466cbSJens Wiklander mbedtls_free( ctx ); 404817466cbSJens Wiklander } 405817466cbSJens Wiklander 406817466cbSJens Wiklander static void eckey_debug( const void *ctx, mbedtls_pk_debug_item *items ) 407817466cbSJens Wiklander { 408817466cbSJens Wiklander items->type = MBEDTLS_PK_DEBUG_ECP; 409817466cbSJens Wiklander items->name = "eckey.Q"; 410817466cbSJens Wiklander items->value = &( ((mbedtls_ecp_keypair *) ctx)->Q ); 411817466cbSJens Wiklander } 412817466cbSJens Wiklander 413817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_eckey_info = { 414817466cbSJens Wiklander MBEDTLS_PK_ECKEY, 415817466cbSJens Wiklander "EC", 416817466cbSJens Wiklander eckey_get_bitlen, 417817466cbSJens Wiklander eckey_can_do, 418817466cbSJens Wiklander #if defined(MBEDTLS_ECDSA_C) 419817466cbSJens Wiklander eckey_verify_wrap, 420817466cbSJens Wiklander eckey_sign_wrap, 4213d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE) 4223d3b0591SJens Wiklander eckey_verify_rs_wrap, 4233d3b0591SJens Wiklander eckey_sign_rs_wrap, 424817466cbSJens Wiklander #endif 4253d3b0591SJens Wiklander #else /* MBEDTLS_ECDSA_C */ 4263d3b0591SJens Wiklander NULL, 4273d3b0591SJens Wiklander NULL, 4283d3b0591SJens Wiklander #endif /* MBEDTLS_ECDSA_C */ 429817466cbSJens Wiklander NULL, 430817466cbSJens Wiklander NULL, 431817466cbSJens Wiklander eckey_check_pair, 432817466cbSJens Wiklander eckey_alloc_wrap, 433817466cbSJens Wiklander eckey_free_wrap, 4343d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 4353d3b0591SJens Wiklander eckey_rs_alloc, 4363d3b0591SJens Wiklander eckey_rs_free, 4373d3b0591SJens Wiklander #endif 438817466cbSJens Wiklander eckey_debug, 439817466cbSJens Wiklander }; 440817466cbSJens Wiklander 441817466cbSJens Wiklander /* 442817466cbSJens Wiklander * EC key restricted to ECDH 443817466cbSJens Wiklander */ 444817466cbSJens Wiklander static int eckeydh_can_do( mbedtls_pk_type_t type ) 445817466cbSJens Wiklander { 446817466cbSJens Wiklander return( type == MBEDTLS_PK_ECKEY || 447817466cbSJens Wiklander type == MBEDTLS_PK_ECKEY_DH ); 448817466cbSJens Wiklander } 449817466cbSJens Wiklander 450817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_eckeydh_info = { 451817466cbSJens Wiklander MBEDTLS_PK_ECKEY_DH, 452817466cbSJens Wiklander "EC_DH", 453817466cbSJens Wiklander eckey_get_bitlen, /* Same underlying key structure */ 454817466cbSJens Wiklander eckeydh_can_do, 455817466cbSJens Wiklander NULL, 456817466cbSJens Wiklander NULL, 4573d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 4583d3b0591SJens Wiklander NULL, 4593d3b0591SJens Wiklander NULL, 4603d3b0591SJens Wiklander #endif 461817466cbSJens Wiklander NULL, 462817466cbSJens Wiklander NULL, 463817466cbSJens Wiklander eckey_check_pair, 464817466cbSJens Wiklander eckey_alloc_wrap, /* Same underlying key structure */ 465817466cbSJens Wiklander eckey_free_wrap, /* Same underlying key structure */ 4663d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 4673d3b0591SJens Wiklander NULL, 4683d3b0591SJens Wiklander NULL, 4693d3b0591SJens Wiklander #endif 470817466cbSJens Wiklander eckey_debug, /* Same underlying key structure */ 471817466cbSJens Wiklander }; 472817466cbSJens Wiklander #endif /* MBEDTLS_ECP_C */ 473817466cbSJens Wiklander 474817466cbSJens Wiklander #if defined(MBEDTLS_ECDSA_C) 475817466cbSJens Wiklander static int ecdsa_can_do( mbedtls_pk_type_t type ) 476817466cbSJens Wiklander { 477817466cbSJens Wiklander return( type == MBEDTLS_PK_ECDSA ); 478817466cbSJens Wiklander } 479817466cbSJens Wiklander 48011fa71b9SJerome Forissier #if defined(MBEDTLS_USE_PSA_CRYPTO) 48111fa71b9SJerome Forissier /* 48211fa71b9SJerome Forissier * An ASN.1 encoded signature is a sequence of two ASN.1 integers. Parse one of 48311fa71b9SJerome Forissier * those integers and convert it to the fixed-length encoding expected by PSA. 48411fa71b9SJerome Forissier */ 48511fa71b9SJerome Forissier static int extract_ecdsa_sig_int( unsigned char **from, const unsigned char *end, 48611fa71b9SJerome Forissier unsigned char *to, size_t to_len ) 48711fa71b9SJerome Forissier { 48811fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 48911fa71b9SJerome Forissier size_t unpadded_len, padding_len; 49011fa71b9SJerome Forissier 49111fa71b9SJerome Forissier if( ( ret = mbedtls_asn1_get_tag( from, end, &unpadded_len, 49211fa71b9SJerome Forissier MBEDTLS_ASN1_INTEGER ) ) != 0 ) 49311fa71b9SJerome Forissier { 49411fa71b9SJerome Forissier return( ret ); 49511fa71b9SJerome Forissier } 49611fa71b9SJerome Forissier 49711fa71b9SJerome Forissier while( unpadded_len > 0 && **from == 0x00 ) 49811fa71b9SJerome Forissier { 49911fa71b9SJerome Forissier ( *from )++; 50011fa71b9SJerome Forissier unpadded_len--; 50111fa71b9SJerome Forissier } 50211fa71b9SJerome Forissier 50311fa71b9SJerome Forissier if( unpadded_len > to_len || unpadded_len == 0 ) 50411fa71b9SJerome Forissier return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 50511fa71b9SJerome Forissier 50611fa71b9SJerome Forissier padding_len = to_len - unpadded_len; 50711fa71b9SJerome Forissier memset( to, 0x00, padding_len ); 50811fa71b9SJerome Forissier memcpy( to + padding_len, *from, unpadded_len ); 50911fa71b9SJerome Forissier ( *from ) += unpadded_len; 51011fa71b9SJerome Forissier 51111fa71b9SJerome Forissier return( 0 ); 51211fa71b9SJerome Forissier } 51311fa71b9SJerome Forissier 51411fa71b9SJerome Forissier /* 51511fa71b9SJerome Forissier * Convert a signature from an ASN.1 sequence of two integers 51611fa71b9SJerome Forissier * to a raw {r,s} buffer. Note: the provided sig buffer must be at least 51711fa71b9SJerome Forissier * twice as big as int_size. 51811fa71b9SJerome Forissier */ 51911fa71b9SJerome Forissier static int extract_ecdsa_sig( unsigned char **p, const unsigned char *end, 52011fa71b9SJerome Forissier unsigned char *sig, size_t int_size ) 52111fa71b9SJerome Forissier { 52211fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 52311fa71b9SJerome Forissier size_t tmp_size; 52411fa71b9SJerome Forissier 52511fa71b9SJerome Forissier if( ( ret = mbedtls_asn1_get_tag( p, end, &tmp_size, 52611fa71b9SJerome Forissier MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 52711fa71b9SJerome Forissier return( ret ); 52811fa71b9SJerome Forissier 52911fa71b9SJerome Forissier /* Extract r */ 53011fa71b9SJerome Forissier if( ( ret = extract_ecdsa_sig_int( p, end, sig, int_size ) ) != 0 ) 53111fa71b9SJerome Forissier return( ret ); 53211fa71b9SJerome Forissier /* Extract s */ 53311fa71b9SJerome Forissier if( ( ret = extract_ecdsa_sig_int( p, end, sig + int_size, int_size ) ) != 0 ) 53411fa71b9SJerome Forissier return( ret ); 53511fa71b9SJerome Forissier 53611fa71b9SJerome Forissier return( 0 ); 53711fa71b9SJerome Forissier } 53811fa71b9SJerome Forissier 53911fa71b9SJerome Forissier static int ecdsa_verify_wrap( void *ctx_arg, mbedtls_md_type_t md_alg, 54011fa71b9SJerome Forissier const unsigned char *hash, size_t hash_len, 54111fa71b9SJerome Forissier const unsigned char *sig, size_t sig_len ) 54211fa71b9SJerome Forissier { 54311fa71b9SJerome Forissier mbedtls_ecdsa_context *ctx = ctx_arg; 54411fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 54511fa71b9SJerome Forissier psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 546*7901324dSJerome Forissier psa_key_id_t key_id = 0; 54711fa71b9SJerome Forissier psa_status_t status; 54811fa71b9SJerome Forissier mbedtls_pk_context key; 54911fa71b9SJerome Forissier int key_len; 55011fa71b9SJerome Forissier /* see ECP_PUB_DER_MAX_BYTES in pkwrite.c */ 55111fa71b9SJerome Forissier unsigned char buf[30 + 2 * MBEDTLS_ECP_MAX_BYTES]; 55211fa71b9SJerome Forissier unsigned char *p; 55311fa71b9SJerome Forissier mbedtls_pk_info_t pk_info = mbedtls_eckey_info; 554*7901324dSJerome Forissier psa_algorithm_t psa_sig_md = PSA_ALG_ECDSA_ANY; 55511fa71b9SJerome Forissier size_t curve_bits; 556*7901324dSJerome Forissier psa_ecc_family_t curve = 55711fa71b9SJerome Forissier mbedtls_ecc_group_to_psa( ctx->grp.id, &curve_bits ); 55811fa71b9SJerome Forissier const size_t signature_part_size = ( ctx->grp.nbits + 7 ) / 8; 559*7901324dSJerome Forissier ((void) md_alg); 56011fa71b9SJerome Forissier 56111fa71b9SJerome Forissier if( curve == 0 ) 56211fa71b9SJerome Forissier return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 56311fa71b9SJerome Forissier 56411fa71b9SJerome Forissier /* mbedtls_pk_write_pubkey() expects a full PK context; 56511fa71b9SJerome Forissier * re-construct one to make it happy */ 56611fa71b9SJerome Forissier key.pk_info = &pk_info; 56711fa71b9SJerome Forissier key.pk_ctx = ctx; 56811fa71b9SJerome Forissier p = buf + sizeof( buf ); 56911fa71b9SJerome Forissier key_len = mbedtls_pk_write_pubkey( &p, buf, &key ); 57011fa71b9SJerome Forissier if( key_len <= 0 ) 57111fa71b9SJerome Forissier return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 57211fa71b9SJerome Forissier 57311fa71b9SJerome Forissier psa_set_key_type( &attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY( curve ) ); 57411fa71b9SJerome Forissier psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY_HASH ); 57511fa71b9SJerome Forissier psa_set_key_algorithm( &attributes, psa_sig_md ); 57611fa71b9SJerome Forissier 57711fa71b9SJerome Forissier status = psa_import_key( &attributes, 57811fa71b9SJerome Forissier buf + sizeof( buf ) - key_len, key_len, 579*7901324dSJerome Forissier &key_id ); 58011fa71b9SJerome Forissier if( status != PSA_SUCCESS ) 58111fa71b9SJerome Forissier { 58211fa71b9SJerome Forissier ret = mbedtls_psa_err_translate_pk( status ); 58311fa71b9SJerome Forissier goto cleanup; 58411fa71b9SJerome Forissier } 58511fa71b9SJerome Forissier 58611fa71b9SJerome Forissier /* We don't need the exported key anymore and can 58711fa71b9SJerome Forissier * reuse its buffer for signature extraction. */ 58811fa71b9SJerome Forissier if( 2 * signature_part_size > sizeof( buf ) ) 58911fa71b9SJerome Forissier { 59011fa71b9SJerome Forissier ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA; 59111fa71b9SJerome Forissier goto cleanup; 59211fa71b9SJerome Forissier } 59311fa71b9SJerome Forissier 59411fa71b9SJerome Forissier p = (unsigned char*) sig; 59511fa71b9SJerome Forissier if( ( ret = extract_ecdsa_sig( &p, sig + sig_len, buf, 59611fa71b9SJerome Forissier signature_part_size ) ) != 0 ) 59711fa71b9SJerome Forissier { 59811fa71b9SJerome Forissier goto cleanup; 59911fa71b9SJerome Forissier } 60011fa71b9SJerome Forissier 601*7901324dSJerome Forissier if( psa_verify_hash( key_id, psa_sig_md, 60211fa71b9SJerome Forissier hash, hash_len, 60311fa71b9SJerome Forissier buf, 2 * signature_part_size ) 60411fa71b9SJerome Forissier != PSA_SUCCESS ) 60511fa71b9SJerome Forissier { 60611fa71b9SJerome Forissier ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; 60711fa71b9SJerome Forissier goto cleanup; 60811fa71b9SJerome Forissier } 60911fa71b9SJerome Forissier 61011fa71b9SJerome Forissier if( p != sig + sig_len ) 61111fa71b9SJerome Forissier { 61211fa71b9SJerome Forissier ret = MBEDTLS_ERR_PK_SIG_LEN_MISMATCH; 61311fa71b9SJerome Forissier goto cleanup; 61411fa71b9SJerome Forissier } 61511fa71b9SJerome Forissier ret = 0; 61611fa71b9SJerome Forissier 61711fa71b9SJerome Forissier cleanup: 618*7901324dSJerome Forissier psa_destroy_key( key_id ); 61911fa71b9SJerome Forissier return( ret ); 62011fa71b9SJerome Forissier } 62111fa71b9SJerome Forissier #else /* MBEDTLS_USE_PSA_CRYPTO */ 622817466cbSJens Wiklander static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, 623817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 624817466cbSJens Wiklander const unsigned char *sig, size_t sig_len ) 625817466cbSJens Wiklander { 62611fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 627817466cbSJens Wiklander ((void) md_alg); 628817466cbSJens Wiklander 629817466cbSJens Wiklander ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx, 630817466cbSJens Wiklander hash, hash_len, sig, sig_len ); 631817466cbSJens Wiklander 632817466cbSJens Wiklander if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH ) 633817466cbSJens Wiklander return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); 634817466cbSJens Wiklander 635817466cbSJens Wiklander return( ret ); 636817466cbSJens Wiklander } 63711fa71b9SJerome Forissier #endif /* MBEDTLS_USE_PSA_CRYPTO */ 638817466cbSJens Wiklander 639817466cbSJens Wiklander static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, 640817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 641817466cbSJens Wiklander unsigned char *sig, size_t *sig_len, 642817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 643817466cbSJens Wiklander { 644817466cbSJens Wiklander return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx, 645817466cbSJens Wiklander md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) ); 646817466cbSJens Wiklander } 647817466cbSJens Wiklander 6483d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE) 6493d3b0591SJens Wiklander static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, 6503d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 6513d3b0591SJens Wiklander const unsigned char *sig, size_t sig_len, 6523d3b0591SJens Wiklander void *rs_ctx ) 6533d3b0591SJens Wiklander { 65411fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 6553d3b0591SJens Wiklander ((void) md_alg); 6563d3b0591SJens Wiklander 6573d3b0591SJens Wiklander ret = mbedtls_ecdsa_read_signature_restartable( 6583d3b0591SJens Wiklander (mbedtls_ecdsa_context *) ctx, 6593d3b0591SJens Wiklander hash, hash_len, sig, sig_len, 6603d3b0591SJens Wiklander (mbedtls_ecdsa_restart_ctx *) rs_ctx ); 6613d3b0591SJens Wiklander 6623d3b0591SJens Wiklander if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH ) 6633d3b0591SJens Wiklander return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); 6643d3b0591SJens Wiklander 6653d3b0591SJens Wiklander return( ret ); 6663d3b0591SJens Wiklander } 6673d3b0591SJens Wiklander 6683d3b0591SJens Wiklander static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, 6693d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 6703d3b0591SJens Wiklander unsigned char *sig, size_t *sig_len, 6713d3b0591SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, 6723d3b0591SJens Wiklander void *rs_ctx ) 6733d3b0591SJens Wiklander { 6743d3b0591SJens Wiklander return( mbedtls_ecdsa_write_signature_restartable( 6753d3b0591SJens Wiklander (mbedtls_ecdsa_context *) ctx, 6763d3b0591SJens Wiklander md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng, 6773d3b0591SJens Wiklander (mbedtls_ecdsa_restart_ctx *) rs_ctx ) ); 6783d3b0591SJens Wiklander 6793d3b0591SJens Wiklander } 6803d3b0591SJens Wiklander #endif /* MBEDTLS_ECP_RESTARTABLE */ 6813d3b0591SJens Wiklander 682817466cbSJens Wiklander static void *ecdsa_alloc_wrap( void ) 683817466cbSJens Wiklander { 684817466cbSJens Wiklander void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) ); 685817466cbSJens Wiklander 686817466cbSJens Wiklander if( ctx != NULL ) 687817466cbSJens Wiklander mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx ); 688817466cbSJens Wiklander 689817466cbSJens Wiklander return( ctx ); 690817466cbSJens Wiklander } 691817466cbSJens Wiklander 692817466cbSJens Wiklander static void ecdsa_free_wrap( void *ctx ) 693817466cbSJens Wiklander { 694817466cbSJens Wiklander mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx ); 695817466cbSJens Wiklander mbedtls_free( ctx ); 696817466cbSJens Wiklander } 697817466cbSJens Wiklander 6983d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE) 6993d3b0591SJens Wiklander static void *ecdsa_rs_alloc( void ) 7003d3b0591SJens Wiklander { 7013d3b0591SJens Wiklander void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_restart_ctx ) ); 7023d3b0591SJens Wiklander 7033d3b0591SJens Wiklander if( ctx != NULL ) 7043d3b0591SJens Wiklander mbedtls_ecdsa_restart_init( ctx ); 7053d3b0591SJens Wiklander 7063d3b0591SJens Wiklander return( ctx ); 7073d3b0591SJens Wiklander } 7083d3b0591SJens Wiklander 7093d3b0591SJens Wiklander static void ecdsa_rs_free( void *ctx ) 7103d3b0591SJens Wiklander { 7113d3b0591SJens Wiklander mbedtls_ecdsa_restart_free( ctx ); 7123d3b0591SJens Wiklander mbedtls_free( ctx ); 7133d3b0591SJens Wiklander } 7143d3b0591SJens Wiklander #endif /* MBEDTLS_ECP_RESTARTABLE */ 7153d3b0591SJens Wiklander 716817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_ecdsa_info = { 717817466cbSJens Wiklander MBEDTLS_PK_ECDSA, 718817466cbSJens Wiklander "ECDSA", 719817466cbSJens Wiklander eckey_get_bitlen, /* Compatible key structures */ 720817466cbSJens Wiklander ecdsa_can_do, 721817466cbSJens Wiklander ecdsa_verify_wrap, 722817466cbSJens Wiklander ecdsa_sign_wrap, 7233d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE) 7243d3b0591SJens Wiklander ecdsa_verify_rs_wrap, 7253d3b0591SJens Wiklander ecdsa_sign_rs_wrap, 7263d3b0591SJens Wiklander #endif 727817466cbSJens Wiklander NULL, 728817466cbSJens Wiklander NULL, 729817466cbSJens Wiklander eckey_check_pair, /* Compatible key structures */ 730817466cbSJens Wiklander ecdsa_alloc_wrap, 731817466cbSJens Wiklander ecdsa_free_wrap, 7323d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE) 7333d3b0591SJens Wiklander ecdsa_rs_alloc, 7343d3b0591SJens Wiklander ecdsa_rs_free, 7353d3b0591SJens Wiklander #endif 736817466cbSJens Wiklander eckey_debug, /* Compatible key structures */ 737817466cbSJens Wiklander }; 738817466cbSJens Wiklander #endif /* MBEDTLS_ECDSA_C */ 739817466cbSJens Wiklander 740817466cbSJens Wiklander #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) 741817466cbSJens Wiklander /* 742817466cbSJens Wiklander * Support for alternative RSA-private implementations 743817466cbSJens Wiklander */ 744817466cbSJens Wiklander 745817466cbSJens Wiklander static int rsa_alt_can_do( mbedtls_pk_type_t type ) 746817466cbSJens Wiklander { 747817466cbSJens Wiklander return( type == MBEDTLS_PK_RSA ); 748817466cbSJens Wiklander } 749817466cbSJens Wiklander 750817466cbSJens Wiklander static size_t rsa_alt_get_bitlen( const void *ctx ) 751817466cbSJens Wiklander { 752817466cbSJens Wiklander const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx; 753817466cbSJens Wiklander 754817466cbSJens Wiklander return( 8 * rsa_alt->key_len_func( rsa_alt->key ) ); 755817466cbSJens Wiklander } 756817466cbSJens Wiklander 757817466cbSJens Wiklander static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, 758817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 759817466cbSJens Wiklander unsigned char *sig, size_t *sig_len, 760817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 761817466cbSJens Wiklander { 762817466cbSJens Wiklander mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx; 763817466cbSJens Wiklander 7643d3b0591SJens Wiklander #if SIZE_MAX > UINT_MAX 765817466cbSJens Wiklander if( UINT_MAX < hash_len ) 766817466cbSJens Wiklander return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 7673d3b0591SJens Wiklander #endif /* SIZE_MAX > UINT_MAX */ 768817466cbSJens Wiklander 769817466cbSJens Wiklander *sig_len = rsa_alt->key_len_func( rsa_alt->key ); 77011fa71b9SJerome Forissier if( *sig_len > MBEDTLS_PK_SIGNATURE_MAX_SIZE ) 77111fa71b9SJerome Forissier return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 772817466cbSJens Wiklander 773817466cbSJens Wiklander return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, 774817466cbSJens Wiklander md_alg, (unsigned int) hash_len, hash, sig ) ); 775817466cbSJens Wiklander } 776817466cbSJens Wiklander 777817466cbSJens Wiklander static int rsa_alt_decrypt_wrap( void *ctx, 778817466cbSJens Wiklander const unsigned char *input, size_t ilen, 779817466cbSJens Wiklander unsigned char *output, size_t *olen, size_t osize, 780817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 781817466cbSJens Wiklander { 782817466cbSJens Wiklander mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx; 783817466cbSJens Wiklander 784817466cbSJens Wiklander ((void) f_rng); 785817466cbSJens Wiklander ((void) p_rng); 786817466cbSJens Wiklander 787817466cbSJens Wiklander if( ilen != rsa_alt->key_len_func( rsa_alt->key ) ) 788817466cbSJens Wiklander return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); 789817466cbSJens Wiklander 790817466cbSJens Wiklander return( rsa_alt->decrypt_func( rsa_alt->key, 791817466cbSJens Wiklander MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) ); 792817466cbSJens Wiklander } 793817466cbSJens Wiklander 794817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C) 795817466cbSJens Wiklander static int rsa_alt_check_pair( const void *pub, const void *prv ) 796817466cbSJens Wiklander { 797817466cbSJens Wiklander unsigned char sig[MBEDTLS_MPI_MAX_SIZE]; 798817466cbSJens Wiklander unsigned char hash[32]; 799817466cbSJens Wiklander size_t sig_len = 0; 80011fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 801817466cbSJens Wiklander 802817466cbSJens Wiklander if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) ) 803817466cbSJens Wiklander return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); 804817466cbSJens Wiklander 805817466cbSJens Wiklander memset( hash, 0x2a, sizeof( hash ) ); 806817466cbSJens Wiklander 807817466cbSJens Wiklander if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE, 808817466cbSJens Wiklander hash, sizeof( hash ), 809817466cbSJens Wiklander sig, &sig_len, NULL, NULL ) ) != 0 ) 810817466cbSJens Wiklander { 811817466cbSJens Wiklander return( ret ); 812817466cbSJens Wiklander } 813817466cbSJens Wiklander 814817466cbSJens Wiklander if( rsa_verify_wrap( (void *) pub, MBEDTLS_MD_NONE, 815817466cbSJens Wiklander hash, sizeof( hash ), sig, sig_len ) != 0 ) 816817466cbSJens Wiklander { 817817466cbSJens Wiklander return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); 818817466cbSJens Wiklander } 819817466cbSJens Wiklander 820817466cbSJens Wiklander return( 0 ); 821817466cbSJens Wiklander } 822817466cbSJens Wiklander #endif /* MBEDTLS_RSA_C */ 823817466cbSJens Wiklander 824817466cbSJens Wiklander static void *rsa_alt_alloc_wrap( void ) 825817466cbSJens Wiklander { 826817466cbSJens Wiklander void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context ) ); 827817466cbSJens Wiklander 828817466cbSJens Wiklander if( ctx != NULL ) 829817466cbSJens Wiklander memset( ctx, 0, sizeof( mbedtls_rsa_alt_context ) ); 830817466cbSJens Wiklander 831817466cbSJens Wiklander return( ctx ); 832817466cbSJens Wiklander } 833817466cbSJens Wiklander 834817466cbSJens Wiklander static void rsa_alt_free_wrap( void *ctx ) 835817466cbSJens Wiklander { 8363d3b0591SJens Wiklander mbedtls_platform_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) ); 837817466cbSJens Wiklander mbedtls_free( ctx ); 838817466cbSJens Wiklander } 839817466cbSJens Wiklander 840817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_rsa_alt_info = { 841817466cbSJens Wiklander MBEDTLS_PK_RSA_ALT, 842817466cbSJens Wiklander "RSA-alt", 843817466cbSJens Wiklander rsa_alt_get_bitlen, 844817466cbSJens Wiklander rsa_alt_can_do, 845817466cbSJens Wiklander NULL, 846817466cbSJens Wiklander rsa_alt_sign_wrap, 8473d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 8483d3b0591SJens Wiklander NULL, 8493d3b0591SJens Wiklander NULL, 8503d3b0591SJens Wiklander #endif 851817466cbSJens Wiklander rsa_alt_decrypt_wrap, 852817466cbSJens Wiklander NULL, 853817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C) 854817466cbSJens Wiklander rsa_alt_check_pair, 855817466cbSJens Wiklander #else 856817466cbSJens Wiklander NULL, 857817466cbSJens Wiklander #endif 858817466cbSJens Wiklander rsa_alt_alloc_wrap, 859817466cbSJens Wiklander rsa_alt_free_wrap, 8603d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 8613d3b0591SJens Wiklander NULL, 8623d3b0591SJens Wiklander NULL, 8633d3b0591SJens Wiklander #endif 864817466cbSJens Wiklander NULL, 865817466cbSJens Wiklander }; 866817466cbSJens Wiklander 867817466cbSJens Wiklander #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ 868817466cbSJens Wiklander 86911fa71b9SJerome Forissier #if defined(MBEDTLS_USE_PSA_CRYPTO) 87011fa71b9SJerome Forissier 87111fa71b9SJerome Forissier static void *pk_opaque_alloc_wrap( void ) 87211fa71b9SJerome Forissier { 873*7901324dSJerome Forissier void *ctx = mbedtls_calloc( 1, sizeof( psa_key_id_t ) ); 87411fa71b9SJerome Forissier 87511fa71b9SJerome Forissier /* no _init() function to call, an calloc() already zeroized */ 87611fa71b9SJerome Forissier 87711fa71b9SJerome Forissier return( ctx ); 87811fa71b9SJerome Forissier } 87911fa71b9SJerome Forissier 88011fa71b9SJerome Forissier static void pk_opaque_free_wrap( void *ctx ) 88111fa71b9SJerome Forissier { 882*7901324dSJerome Forissier mbedtls_platform_zeroize( ctx, sizeof( psa_key_id_t ) ); 88311fa71b9SJerome Forissier mbedtls_free( ctx ); 88411fa71b9SJerome Forissier } 88511fa71b9SJerome Forissier 88611fa71b9SJerome Forissier static size_t pk_opaque_get_bitlen( const void *ctx ) 88711fa71b9SJerome Forissier { 888*7901324dSJerome Forissier const psa_key_id_t *key = (const psa_key_id_t *) ctx; 88911fa71b9SJerome Forissier size_t bits; 89011fa71b9SJerome Forissier psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 89111fa71b9SJerome Forissier 89211fa71b9SJerome Forissier if( PSA_SUCCESS != psa_get_key_attributes( *key, &attributes ) ) 89311fa71b9SJerome Forissier return( 0 ); 89411fa71b9SJerome Forissier 89511fa71b9SJerome Forissier bits = psa_get_key_bits( &attributes ); 89611fa71b9SJerome Forissier psa_reset_key_attributes( &attributes ); 89711fa71b9SJerome Forissier return( bits ); 89811fa71b9SJerome Forissier } 89911fa71b9SJerome Forissier 90011fa71b9SJerome Forissier static int pk_opaque_can_do( mbedtls_pk_type_t type ) 90111fa71b9SJerome Forissier { 90211fa71b9SJerome Forissier /* For now opaque PSA keys can only wrap ECC keypairs, 90311fa71b9SJerome Forissier * as checked by setup_psa(). 90411fa71b9SJerome Forissier * Also, ECKEY_DH does not really make sense with the current API. */ 90511fa71b9SJerome Forissier return( type == MBEDTLS_PK_ECKEY || 90611fa71b9SJerome Forissier type == MBEDTLS_PK_ECDSA ); 90711fa71b9SJerome Forissier } 90811fa71b9SJerome Forissier 909*7901324dSJerome Forissier #if defined(MBEDTLS_ECDSA_C) 910*7901324dSJerome Forissier 91111fa71b9SJerome Forissier /* 91211fa71b9SJerome Forissier * Simultaneously convert and move raw MPI from the beginning of a buffer 91311fa71b9SJerome Forissier * to an ASN.1 MPI at the end of the buffer. 91411fa71b9SJerome Forissier * See also mbedtls_asn1_write_mpi(). 91511fa71b9SJerome Forissier * 91611fa71b9SJerome Forissier * p: pointer to the end of the output buffer 91711fa71b9SJerome Forissier * start: start of the output buffer, and also of the mpi to write at the end 91811fa71b9SJerome Forissier * n_len: length of the mpi to read from start 91911fa71b9SJerome Forissier */ 92011fa71b9SJerome Forissier static int asn1_write_mpibuf( unsigned char **p, unsigned char *start, 92111fa71b9SJerome Forissier size_t n_len ) 92211fa71b9SJerome Forissier { 92311fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 92411fa71b9SJerome Forissier size_t len = 0; 92511fa71b9SJerome Forissier 92611fa71b9SJerome Forissier if( (size_t)( *p - start ) < n_len ) 92711fa71b9SJerome Forissier return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 92811fa71b9SJerome Forissier 92911fa71b9SJerome Forissier len = n_len; 93011fa71b9SJerome Forissier *p -= len; 93111fa71b9SJerome Forissier memmove( *p, start, len ); 93211fa71b9SJerome Forissier 93311fa71b9SJerome Forissier /* ASN.1 DER encoding requires minimal length, so skip leading 0s. 93411fa71b9SJerome Forissier * Neither r nor s should be 0, but as a failsafe measure, still detect 93511fa71b9SJerome Forissier * that rather than overflowing the buffer in case of a PSA error. */ 93611fa71b9SJerome Forissier while( len > 0 && **p == 0x00 ) 93711fa71b9SJerome Forissier { 93811fa71b9SJerome Forissier ++(*p); 93911fa71b9SJerome Forissier --len; 94011fa71b9SJerome Forissier } 94111fa71b9SJerome Forissier 94211fa71b9SJerome Forissier /* this is only reached if the signature was invalid */ 94311fa71b9SJerome Forissier if( len == 0 ) 94411fa71b9SJerome Forissier return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED ); 94511fa71b9SJerome Forissier 94611fa71b9SJerome Forissier /* if the msb is 1, ASN.1 requires that we prepend a 0. 94711fa71b9SJerome Forissier * Neither r nor s can be 0, so we can assume len > 0 at all times. */ 94811fa71b9SJerome Forissier if( **p & 0x80 ) 94911fa71b9SJerome Forissier { 95011fa71b9SJerome Forissier if( *p - start < 1 ) 95111fa71b9SJerome Forissier return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 95211fa71b9SJerome Forissier 95311fa71b9SJerome Forissier *--(*p) = 0x00; 95411fa71b9SJerome Forissier len += 1; 95511fa71b9SJerome Forissier } 95611fa71b9SJerome Forissier 95711fa71b9SJerome Forissier MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 95811fa71b9SJerome Forissier MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, 95911fa71b9SJerome Forissier MBEDTLS_ASN1_INTEGER ) ); 96011fa71b9SJerome Forissier 96111fa71b9SJerome Forissier return( (int) len ); 96211fa71b9SJerome Forissier } 96311fa71b9SJerome Forissier 96411fa71b9SJerome Forissier /* Transcode signature from PSA format to ASN.1 sequence. 96511fa71b9SJerome Forissier * See ecdsa_signature_to_asn1 in ecdsa.c, but with byte buffers instead of 96611fa71b9SJerome Forissier * MPIs, and in-place. 96711fa71b9SJerome Forissier * 96811fa71b9SJerome Forissier * [in/out] sig: the signature pre- and post-transcoding 96911fa71b9SJerome Forissier * [in/out] sig_len: signature length pre- and post-transcoding 97011fa71b9SJerome Forissier * [int] buf_len: the available size the in/out buffer 97111fa71b9SJerome Forissier */ 97211fa71b9SJerome Forissier static int pk_ecdsa_sig_asn1_from_psa( unsigned char *sig, size_t *sig_len, 97311fa71b9SJerome Forissier size_t buf_len ) 97411fa71b9SJerome Forissier { 97511fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 97611fa71b9SJerome Forissier size_t len = 0; 97711fa71b9SJerome Forissier const size_t rs_len = *sig_len / 2; 97811fa71b9SJerome Forissier unsigned char *p = sig + buf_len; 97911fa71b9SJerome Forissier 98011fa71b9SJerome Forissier MBEDTLS_ASN1_CHK_ADD( len, asn1_write_mpibuf( &p, sig + rs_len, rs_len ) ); 98111fa71b9SJerome Forissier MBEDTLS_ASN1_CHK_ADD( len, asn1_write_mpibuf( &p, sig, rs_len ) ); 98211fa71b9SJerome Forissier 98311fa71b9SJerome Forissier MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &p, sig, len ) ); 98411fa71b9SJerome Forissier MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, sig, 98511fa71b9SJerome Forissier MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); 98611fa71b9SJerome Forissier 98711fa71b9SJerome Forissier memmove( sig, p, len ); 98811fa71b9SJerome Forissier *sig_len = len; 98911fa71b9SJerome Forissier 99011fa71b9SJerome Forissier return( 0 ); 99111fa71b9SJerome Forissier } 99211fa71b9SJerome Forissier 993*7901324dSJerome Forissier #endif /* MBEDTLS_ECDSA_C */ 994*7901324dSJerome Forissier 99511fa71b9SJerome Forissier static int pk_opaque_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, 99611fa71b9SJerome Forissier const unsigned char *hash, size_t hash_len, 99711fa71b9SJerome Forissier unsigned char *sig, size_t *sig_len, 99811fa71b9SJerome Forissier int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 99911fa71b9SJerome Forissier { 1000*7901324dSJerome Forissier #if !defined(MBEDTLS_ECDSA_C) 1001*7901324dSJerome Forissier ((void) ctx); 1002*7901324dSJerome Forissier ((void) md_alg); 1003*7901324dSJerome Forissier ((void) hash); 1004*7901324dSJerome Forissier ((void) hash_len); 1005*7901324dSJerome Forissier ((void) sig); 1006*7901324dSJerome Forissier ((void) sig_len); 1007*7901324dSJerome Forissier ((void) f_rng); 1008*7901324dSJerome Forissier ((void) p_rng); 1009*7901324dSJerome Forissier return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); 1010*7901324dSJerome Forissier #else /* !MBEDTLS_ECDSA_C */ 1011*7901324dSJerome Forissier const psa_key_id_t *key = (const psa_key_id_t *) ctx; 101211fa71b9SJerome Forissier psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 101311fa71b9SJerome Forissier psa_algorithm_t alg = PSA_ALG_ECDSA( mbedtls_psa_translate_md( md_alg ) ); 101411fa71b9SJerome Forissier size_t buf_len; 101511fa71b9SJerome Forissier psa_status_t status; 101611fa71b9SJerome Forissier 101711fa71b9SJerome Forissier /* PSA has its own RNG */ 101811fa71b9SJerome Forissier (void) f_rng; 101911fa71b9SJerome Forissier (void) p_rng; 102011fa71b9SJerome Forissier 102111fa71b9SJerome Forissier /* PSA needs an output buffer of known size, but our API doesn't provide 102211fa71b9SJerome Forissier * that information. Assume that the buffer is large enough for a 102311fa71b9SJerome Forissier * maximal-length signature with that key (otherwise the application is 102411fa71b9SJerome Forissier * buggy anyway). */ 102511fa71b9SJerome Forissier status = psa_get_key_attributes( *key, &attributes ); 102611fa71b9SJerome Forissier if( status != PSA_SUCCESS ) 102711fa71b9SJerome Forissier return( mbedtls_psa_err_translate_pk( status ) ); 102811fa71b9SJerome Forissier buf_len = MBEDTLS_ECDSA_MAX_SIG_LEN( psa_get_key_bits( &attributes ) ); 102911fa71b9SJerome Forissier psa_reset_key_attributes( &attributes ); 103011fa71b9SJerome Forissier if( buf_len > MBEDTLS_PK_SIGNATURE_MAX_SIZE ) 103111fa71b9SJerome Forissier return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 103211fa71b9SJerome Forissier 103311fa71b9SJerome Forissier /* make the signature */ 103411fa71b9SJerome Forissier status = psa_sign_hash( *key, alg, hash, hash_len, 103511fa71b9SJerome Forissier sig, buf_len, sig_len ); 103611fa71b9SJerome Forissier if( status != PSA_SUCCESS ) 103711fa71b9SJerome Forissier return( mbedtls_psa_err_translate_pk( status ) ); 103811fa71b9SJerome Forissier 103911fa71b9SJerome Forissier /* transcode it to ASN.1 sequence */ 104011fa71b9SJerome Forissier return( pk_ecdsa_sig_asn1_from_psa( sig, sig_len, buf_len ) ); 1041*7901324dSJerome Forissier #endif /* !MBEDTLS_ECDSA_C */ 104211fa71b9SJerome Forissier } 104311fa71b9SJerome Forissier 104411fa71b9SJerome Forissier const mbedtls_pk_info_t mbedtls_pk_opaque_info = { 104511fa71b9SJerome Forissier MBEDTLS_PK_OPAQUE, 104611fa71b9SJerome Forissier "Opaque", 104711fa71b9SJerome Forissier pk_opaque_get_bitlen, 104811fa71b9SJerome Forissier pk_opaque_can_do, 104911fa71b9SJerome Forissier NULL, /* verify - will be done later */ 105011fa71b9SJerome Forissier pk_opaque_sign_wrap, 105111fa71b9SJerome Forissier #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 105211fa71b9SJerome Forissier NULL, /* restartable verify - not relevant */ 105311fa71b9SJerome Forissier NULL, /* restartable sign - not relevant */ 105411fa71b9SJerome Forissier #endif 105511fa71b9SJerome Forissier NULL, /* decrypt - will be done later */ 105611fa71b9SJerome Forissier NULL, /* encrypt - will be done later */ 105711fa71b9SJerome Forissier NULL, /* check_pair - could be done later or left NULL */ 105811fa71b9SJerome Forissier pk_opaque_alloc_wrap, 105911fa71b9SJerome Forissier pk_opaque_free_wrap, 106011fa71b9SJerome Forissier #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 106111fa71b9SJerome Forissier NULL, /* restart alloc - not relevant */ 106211fa71b9SJerome Forissier NULL, /* restart free - not relevant */ 106311fa71b9SJerome Forissier #endif 106411fa71b9SJerome Forissier NULL, /* debug - could be done later, or even left NULL */ 106511fa71b9SJerome Forissier }; 106611fa71b9SJerome Forissier 106711fa71b9SJerome Forissier #endif /* MBEDTLS_USE_PSA_CRYPTO */ 106811fa71b9SJerome Forissier 1069817466cbSJens Wiklander #endif /* MBEDTLS_PK_C */ 1070