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" 30*11fa71b9SJerome Forissier #include "mbedtls/error.h" 31817466cbSJens Wiklander 32817466cbSJens Wiklander /* Even if RSA not activated, for the sake of RSA-alt */ 33817466cbSJens Wiklander #include "mbedtls/rsa.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 45*11fa71b9SJerome Forissier #if defined(MBEDTLS_USE_PSA_CRYPTO) 46*11fa71b9SJerome Forissier #include "mbedtls/asn1write.h" 47*11fa71b9SJerome Forissier #endif 48*11fa71b9SJerome Forissier 493d3b0591SJens Wiklander #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) 503d3b0591SJens Wiklander #include "mbedtls/platform_util.h" 513d3b0591SJens Wiklander #endif 523d3b0591SJens Wiklander 53*11fa71b9SJerome Forissier #if defined(MBEDTLS_USE_PSA_CRYPTO) 54*11fa71b9SJerome Forissier #include "psa/crypto.h" 55*11fa71b9SJerome Forissier #include "mbedtls/psa_util.h" 56*11fa71b9SJerome Forissier #include "mbedtls/asn1.h" 57*11fa71b9SJerome Forissier #endif 58*11fa71b9SJerome Forissier 59817466cbSJens Wiklander #if defined(MBEDTLS_PLATFORM_C) 60817466cbSJens Wiklander #include "mbedtls/platform.h" 61817466cbSJens Wiklander #else 62817466cbSJens Wiklander #include <stdlib.h> 63817466cbSJens Wiklander #define mbedtls_calloc calloc 64817466cbSJens Wiklander #define mbedtls_free free 65817466cbSJens Wiklander #endif 66817466cbSJens Wiklander 67817466cbSJens Wiklander #include <limits.h> 683d3b0591SJens Wiklander #include <stdint.h> 69817466cbSJens Wiklander 70817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C) 71817466cbSJens Wiklander static int rsa_can_do( mbedtls_pk_type_t type ) 72817466cbSJens Wiklander { 73817466cbSJens Wiklander return( type == MBEDTLS_PK_RSA || 74817466cbSJens Wiklander type == MBEDTLS_PK_RSASSA_PSS ); 75817466cbSJens Wiklander } 76817466cbSJens Wiklander 77817466cbSJens Wiklander static size_t rsa_get_bitlen( const void *ctx ) 78817466cbSJens Wiklander { 793d3b0591SJens Wiklander const mbedtls_rsa_context * rsa = (const mbedtls_rsa_context *) ctx; 803d3b0591SJens Wiklander return( 8 * mbedtls_rsa_get_len( rsa ) ); 81817466cbSJens Wiklander } 82817466cbSJens Wiklander 83817466cbSJens Wiklander static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, 84817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 85817466cbSJens Wiklander const unsigned char *sig, size_t sig_len ) 86817466cbSJens Wiklander { 87*11fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 883d3b0591SJens Wiklander mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; 893d3b0591SJens Wiklander size_t rsa_len = mbedtls_rsa_get_len( rsa ); 90817466cbSJens Wiklander 913d3b0591SJens Wiklander #if SIZE_MAX > UINT_MAX 92817466cbSJens Wiklander if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) 93817466cbSJens Wiklander return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 943d3b0591SJens Wiklander #endif /* SIZE_MAX > UINT_MAX */ 95817466cbSJens Wiklander 963d3b0591SJens Wiklander if( sig_len < rsa_len ) 97817466cbSJens Wiklander return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); 98817466cbSJens Wiklander 993d3b0591SJens Wiklander if( ( ret = mbedtls_rsa_pkcs1_verify( rsa, NULL, NULL, 100817466cbSJens Wiklander MBEDTLS_RSA_PUBLIC, md_alg, 101817466cbSJens Wiklander (unsigned int) hash_len, hash, sig ) ) != 0 ) 102817466cbSJens Wiklander return( ret ); 103817466cbSJens Wiklander 1043d3b0591SJens Wiklander /* The buffer contains a valid signature followed by extra data. 1053d3b0591SJens Wiklander * We have a special error code for that so that so that callers can 1063d3b0591SJens Wiklander * use mbedtls_pk_verify() to check "Does the buffer start with a 1073d3b0591SJens Wiklander * valid signature?" and not just "Does the buffer contain a valid 1083d3b0591SJens Wiklander * signature?". */ 1093d3b0591SJens Wiklander if( sig_len > rsa_len ) 110817466cbSJens Wiklander return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); 111817466cbSJens Wiklander 112817466cbSJens Wiklander return( 0 ); 113817466cbSJens Wiklander } 114817466cbSJens Wiklander 115817466cbSJens Wiklander static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, 116817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 117817466cbSJens Wiklander unsigned char *sig, size_t *sig_len, 118817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 119817466cbSJens Wiklander { 1203d3b0591SJens Wiklander mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; 1213d3b0591SJens Wiklander 1223d3b0591SJens Wiklander #if SIZE_MAX > UINT_MAX 123817466cbSJens Wiklander if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) 124817466cbSJens Wiklander return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 1253d3b0591SJens Wiklander #endif /* SIZE_MAX > UINT_MAX */ 126817466cbSJens Wiklander 1273d3b0591SJens Wiklander *sig_len = mbedtls_rsa_get_len( rsa ); 128817466cbSJens Wiklander 1293d3b0591SJens Wiklander return( mbedtls_rsa_pkcs1_sign( rsa, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, 130817466cbSJens Wiklander md_alg, (unsigned int) hash_len, hash, sig ) ); 131817466cbSJens Wiklander } 132817466cbSJens Wiklander 133817466cbSJens Wiklander static int rsa_decrypt_wrap( void *ctx, 134817466cbSJens Wiklander const unsigned char *input, size_t ilen, 135817466cbSJens Wiklander unsigned char *output, size_t *olen, size_t osize, 136817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 137817466cbSJens Wiklander { 1383d3b0591SJens Wiklander mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; 1393d3b0591SJens Wiklander 1403d3b0591SJens Wiklander if( ilen != mbedtls_rsa_get_len( rsa ) ) 141817466cbSJens Wiklander return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); 142817466cbSJens Wiklander 1433d3b0591SJens Wiklander return( mbedtls_rsa_pkcs1_decrypt( rsa, f_rng, p_rng, 144817466cbSJens Wiklander MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) ); 145817466cbSJens Wiklander } 146817466cbSJens Wiklander 147817466cbSJens Wiklander static int rsa_encrypt_wrap( void *ctx, 148817466cbSJens Wiklander const unsigned char *input, size_t ilen, 149817466cbSJens Wiklander unsigned char *output, size_t *olen, size_t osize, 150817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 151817466cbSJens Wiklander { 1523d3b0591SJens Wiklander mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; 1533d3b0591SJens Wiklander *olen = mbedtls_rsa_get_len( rsa ); 154817466cbSJens Wiklander 155817466cbSJens Wiklander if( *olen > osize ) 156817466cbSJens Wiklander return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE ); 157817466cbSJens Wiklander 1583d3b0591SJens Wiklander return( mbedtls_rsa_pkcs1_encrypt( rsa, f_rng, p_rng, MBEDTLS_RSA_PUBLIC, 1593d3b0591SJens Wiklander ilen, input, output ) ); 160817466cbSJens Wiklander } 161817466cbSJens Wiklander 162817466cbSJens Wiklander static int rsa_check_pair_wrap( const void *pub, const void *prv ) 163817466cbSJens Wiklander { 164817466cbSJens Wiklander return( mbedtls_rsa_check_pub_priv( (const mbedtls_rsa_context *) pub, 165817466cbSJens Wiklander (const mbedtls_rsa_context *) prv ) ); 166817466cbSJens Wiklander } 167817466cbSJens Wiklander 168817466cbSJens Wiklander static void *rsa_alloc_wrap( void ) 169817466cbSJens Wiklander { 170817466cbSJens Wiklander void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_context ) ); 171817466cbSJens Wiklander 172817466cbSJens Wiklander if( ctx != NULL ) 173817466cbSJens Wiklander mbedtls_rsa_init( (mbedtls_rsa_context *) ctx, 0, 0 ); 174817466cbSJens Wiklander 175817466cbSJens Wiklander return( ctx ); 176817466cbSJens Wiklander } 177817466cbSJens Wiklander 178817466cbSJens Wiklander static void rsa_free_wrap( void *ctx ) 179817466cbSJens Wiklander { 180817466cbSJens Wiklander mbedtls_rsa_free( (mbedtls_rsa_context *) ctx ); 181817466cbSJens Wiklander mbedtls_free( ctx ); 182817466cbSJens Wiklander } 183817466cbSJens Wiklander 184817466cbSJens Wiklander static void rsa_debug( const void *ctx, mbedtls_pk_debug_item *items ) 185817466cbSJens Wiklander { 186817466cbSJens Wiklander items->type = MBEDTLS_PK_DEBUG_MPI; 187817466cbSJens Wiklander items->name = "rsa.N"; 188817466cbSJens Wiklander items->value = &( ((mbedtls_rsa_context *) ctx)->N ); 189817466cbSJens Wiklander 190817466cbSJens Wiklander items++; 191817466cbSJens Wiklander 192817466cbSJens Wiklander items->type = MBEDTLS_PK_DEBUG_MPI; 193817466cbSJens Wiklander items->name = "rsa.E"; 194817466cbSJens Wiklander items->value = &( ((mbedtls_rsa_context *) ctx)->E ); 195817466cbSJens Wiklander } 196817466cbSJens Wiklander 197817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_rsa_info = { 198817466cbSJens Wiklander MBEDTLS_PK_RSA, 199817466cbSJens Wiklander "RSA", 200817466cbSJens Wiklander rsa_get_bitlen, 201817466cbSJens Wiklander rsa_can_do, 202817466cbSJens Wiklander rsa_verify_wrap, 203817466cbSJens Wiklander rsa_sign_wrap, 2043d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 2053d3b0591SJens Wiklander NULL, 2063d3b0591SJens Wiklander NULL, 2073d3b0591SJens Wiklander #endif 208817466cbSJens Wiklander rsa_decrypt_wrap, 209817466cbSJens Wiklander rsa_encrypt_wrap, 210817466cbSJens Wiklander rsa_check_pair_wrap, 211817466cbSJens Wiklander rsa_alloc_wrap, 212817466cbSJens Wiklander rsa_free_wrap, 2133d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 2143d3b0591SJens Wiklander NULL, 2153d3b0591SJens Wiklander NULL, 2163d3b0591SJens Wiklander #endif 217817466cbSJens Wiklander rsa_debug, 218817466cbSJens Wiklander }; 219817466cbSJens Wiklander #endif /* MBEDTLS_RSA_C */ 220817466cbSJens Wiklander 221817466cbSJens Wiklander #if defined(MBEDTLS_ECP_C) 222817466cbSJens Wiklander /* 223817466cbSJens Wiklander * Generic EC key 224817466cbSJens Wiklander */ 225817466cbSJens Wiklander static int eckey_can_do( mbedtls_pk_type_t type ) 226817466cbSJens Wiklander { 227817466cbSJens Wiklander return( type == MBEDTLS_PK_ECKEY || 228817466cbSJens Wiklander type == MBEDTLS_PK_ECKEY_DH || 229817466cbSJens Wiklander type == MBEDTLS_PK_ECDSA ); 230817466cbSJens Wiklander } 231817466cbSJens Wiklander 232817466cbSJens Wiklander static size_t eckey_get_bitlen( const void *ctx ) 233817466cbSJens Wiklander { 234817466cbSJens Wiklander return( ((mbedtls_ecp_keypair *) ctx)->grp.pbits ); 235817466cbSJens Wiklander } 236817466cbSJens Wiklander 237817466cbSJens Wiklander #if defined(MBEDTLS_ECDSA_C) 238817466cbSJens Wiklander /* Forward declarations */ 239817466cbSJens Wiklander static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, 240817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 241817466cbSJens Wiklander const unsigned char *sig, size_t sig_len ); 242817466cbSJens Wiklander 243817466cbSJens Wiklander static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, 244817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 245817466cbSJens Wiklander unsigned char *sig, size_t *sig_len, 246817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); 247817466cbSJens Wiklander 248817466cbSJens Wiklander static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, 249817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 250817466cbSJens Wiklander const unsigned char *sig, size_t sig_len ) 251817466cbSJens Wiklander { 252*11fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 253817466cbSJens Wiklander mbedtls_ecdsa_context ecdsa; 254817466cbSJens Wiklander 255817466cbSJens Wiklander mbedtls_ecdsa_init( &ecdsa ); 256817466cbSJens Wiklander 257817466cbSJens Wiklander if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 ) 258817466cbSJens Wiklander ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len ); 259817466cbSJens Wiklander 260817466cbSJens Wiklander mbedtls_ecdsa_free( &ecdsa ); 261817466cbSJens Wiklander 262817466cbSJens Wiklander return( ret ); 263817466cbSJens Wiklander } 264817466cbSJens Wiklander 265817466cbSJens Wiklander static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, 266817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 267817466cbSJens Wiklander unsigned char *sig, size_t *sig_len, 268817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 269817466cbSJens Wiklander { 270*11fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 271817466cbSJens Wiklander mbedtls_ecdsa_context ecdsa; 272817466cbSJens Wiklander 273817466cbSJens Wiklander mbedtls_ecdsa_init( &ecdsa ); 274817466cbSJens Wiklander 275817466cbSJens Wiklander if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 ) 276817466cbSJens Wiklander ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len, 277817466cbSJens Wiklander f_rng, p_rng ); 278817466cbSJens Wiklander 279817466cbSJens Wiklander mbedtls_ecdsa_free( &ecdsa ); 280817466cbSJens Wiklander 281817466cbSJens Wiklander return( ret ); 282817466cbSJens Wiklander } 283817466cbSJens Wiklander 2843d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE) 2853d3b0591SJens Wiklander /* Forward declarations */ 2863d3b0591SJens Wiklander static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, 2873d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 2883d3b0591SJens Wiklander const unsigned char *sig, size_t sig_len, 2893d3b0591SJens Wiklander void *rs_ctx ); 2903d3b0591SJens Wiklander 2913d3b0591SJens Wiklander static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, 2923d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 2933d3b0591SJens Wiklander unsigned char *sig, size_t *sig_len, 2943d3b0591SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, 2953d3b0591SJens Wiklander void *rs_ctx ); 2963d3b0591SJens Wiklander 2973d3b0591SJens Wiklander /* 2983d3b0591SJens Wiklander * Restart context for ECDSA operations with ECKEY context 2993d3b0591SJens Wiklander * 3003d3b0591SJens Wiklander * We need to store an actual ECDSA context, as we need to pass the same to 3013d3b0591SJens Wiklander * the underlying ecdsa function, so we can't create it on the fly every time. 3023d3b0591SJens Wiklander */ 3033d3b0591SJens Wiklander typedef struct 3043d3b0591SJens Wiklander { 3053d3b0591SJens Wiklander mbedtls_ecdsa_restart_ctx ecdsa_rs; 3063d3b0591SJens Wiklander mbedtls_ecdsa_context ecdsa_ctx; 3073d3b0591SJens Wiklander } eckey_restart_ctx; 3083d3b0591SJens Wiklander 3093d3b0591SJens Wiklander static void *eckey_rs_alloc( void ) 3103d3b0591SJens Wiklander { 3113d3b0591SJens Wiklander eckey_restart_ctx *rs_ctx; 3123d3b0591SJens Wiklander 3133d3b0591SJens Wiklander void *ctx = mbedtls_calloc( 1, sizeof( eckey_restart_ctx ) ); 3143d3b0591SJens Wiklander 3153d3b0591SJens Wiklander if( ctx != NULL ) 3163d3b0591SJens Wiklander { 3173d3b0591SJens Wiklander rs_ctx = ctx; 3183d3b0591SJens Wiklander mbedtls_ecdsa_restart_init( &rs_ctx->ecdsa_rs ); 3193d3b0591SJens Wiklander mbedtls_ecdsa_init( &rs_ctx->ecdsa_ctx ); 3203d3b0591SJens Wiklander } 3213d3b0591SJens Wiklander 3223d3b0591SJens Wiklander return( ctx ); 3233d3b0591SJens Wiklander } 3243d3b0591SJens Wiklander 3253d3b0591SJens Wiklander static void eckey_rs_free( void *ctx ) 3263d3b0591SJens Wiklander { 3273d3b0591SJens Wiklander eckey_restart_ctx *rs_ctx; 3283d3b0591SJens Wiklander 3293d3b0591SJens Wiklander if( ctx == NULL) 3303d3b0591SJens Wiklander return; 3313d3b0591SJens Wiklander 3323d3b0591SJens Wiklander rs_ctx = ctx; 3333d3b0591SJens Wiklander mbedtls_ecdsa_restart_free( &rs_ctx->ecdsa_rs ); 3343d3b0591SJens Wiklander mbedtls_ecdsa_free( &rs_ctx->ecdsa_ctx ); 3353d3b0591SJens Wiklander 3363d3b0591SJens Wiklander mbedtls_free( ctx ); 3373d3b0591SJens Wiklander } 3383d3b0591SJens Wiklander 3393d3b0591SJens Wiklander static int eckey_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, 3403d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 3413d3b0591SJens Wiklander const unsigned char *sig, size_t sig_len, 3423d3b0591SJens Wiklander void *rs_ctx ) 3433d3b0591SJens Wiklander { 344*11fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 3453d3b0591SJens Wiklander eckey_restart_ctx *rs = rs_ctx; 3463d3b0591SJens Wiklander 3473d3b0591SJens Wiklander /* Should never happen */ 3483d3b0591SJens Wiklander if( rs == NULL ) 3493d3b0591SJens Wiklander return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 3503d3b0591SJens Wiklander 3513d3b0591SJens Wiklander /* set up our own sub-context if needed (that is, on first run) */ 3523d3b0591SJens Wiklander if( rs->ecdsa_ctx.grp.pbits == 0 ) 3533d3b0591SJens Wiklander MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) ); 3543d3b0591SJens Wiklander 3553d3b0591SJens Wiklander MBEDTLS_MPI_CHK( ecdsa_verify_rs_wrap( &rs->ecdsa_ctx, 3563d3b0591SJens Wiklander md_alg, hash, hash_len, 3573d3b0591SJens Wiklander sig, sig_len, &rs->ecdsa_rs ) ); 3583d3b0591SJens Wiklander 3593d3b0591SJens Wiklander cleanup: 3603d3b0591SJens Wiklander return( ret ); 3613d3b0591SJens Wiklander } 3623d3b0591SJens Wiklander 3633d3b0591SJens Wiklander static int eckey_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, 3643d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 3653d3b0591SJens Wiklander unsigned char *sig, size_t *sig_len, 3663d3b0591SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, 3673d3b0591SJens Wiklander void *rs_ctx ) 3683d3b0591SJens Wiklander { 369*11fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 3703d3b0591SJens Wiklander eckey_restart_ctx *rs = rs_ctx; 3713d3b0591SJens Wiklander 3723d3b0591SJens Wiklander /* Should never happen */ 3733d3b0591SJens Wiklander if( rs == NULL ) 3743d3b0591SJens Wiklander return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 3753d3b0591SJens Wiklander 3763d3b0591SJens Wiklander /* set up our own sub-context if needed (that is, on first run) */ 3773d3b0591SJens Wiklander if( rs->ecdsa_ctx.grp.pbits == 0 ) 3783d3b0591SJens Wiklander MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) ); 3793d3b0591SJens Wiklander 3803d3b0591SJens Wiklander MBEDTLS_MPI_CHK( ecdsa_sign_rs_wrap( &rs->ecdsa_ctx, md_alg, 3813d3b0591SJens Wiklander hash, hash_len, sig, sig_len, 3823d3b0591SJens Wiklander f_rng, p_rng, &rs->ecdsa_rs ) ); 3833d3b0591SJens Wiklander 3843d3b0591SJens Wiklander cleanup: 3853d3b0591SJens Wiklander return( ret ); 3863d3b0591SJens Wiklander } 3873d3b0591SJens Wiklander #endif /* MBEDTLS_ECP_RESTARTABLE */ 388817466cbSJens Wiklander #endif /* MBEDTLS_ECDSA_C */ 389817466cbSJens Wiklander 390817466cbSJens Wiklander static int eckey_check_pair( const void *pub, const void *prv ) 391817466cbSJens Wiklander { 392817466cbSJens Wiklander return( mbedtls_ecp_check_pub_priv( (const mbedtls_ecp_keypair *) pub, 393817466cbSJens Wiklander (const mbedtls_ecp_keypair *) prv ) ); 394817466cbSJens Wiklander } 395817466cbSJens Wiklander 396817466cbSJens Wiklander static void *eckey_alloc_wrap( void ) 397817466cbSJens Wiklander { 398817466cbSJens Wiklander void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) ); 399817466cbSJens Wiklander 400817466cbSJens Wiklander if( ctx != NULL ) 401817466cbSJens Wiklander mbedtls_ecp_keypair_init( ctx ); 402817466cbSJens Wiklander 403817466cbSJens Wiklander return( ctx ); 404817466cbSJens Wiklander } 405817466cbSJens Wiklander 406817466cbSJens Wiklander static void eckey_free_wrap( void *ctx ) 407817466cbSJens Wiklander { 408817466cbSJens Wiklander mbedtls_ecp_keypair_free( (mbedtls_ecp_keypair *) ctx ); 409817466cbSJens Wiklander mbedtls_free( ctx ); 410817466cbSJens Wiklander } 411817466cbSJens Wiklander 412817466cbSJens Wiklander static void eckey_debug( const void *ctx, mbedtls_pk_debug_item *items ) 413817466cbSJens Wiklander { 414817466cbSJens Wiklander items->type = MBEDTLS_PK_DEBUG_ECP; 415817466cbSJens Wiklander items->name = "eckey.Q"; 416817466cbSJens Wiklander items->value = &( ((mbedtls_ecp_keypair *) ctx)->Q ); 417817466cbSJens Wiklander } 418817466cbSJens Wiklander 419817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_eckey_info = { 420817466cbSJens Wiklander MBEDTLS_PK_ECKEY, 421817466cbSJens Wiklander "EC", 422817466cbSJens Wiklander eckey_get_bitlen, 423817466cbSJens Wiklander eckey_can_do, 424817466cbSJens Wiklander #if defined(MBEDTLS_ECDSA_C) 425817466cbSJens Wiklander eckey_verify_wrap, 426817466cbSJens Wiklander eckey_sign_wrap, 4273d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE) 4283d3b0591SJens Wiklander eckey_verify_rs_wrap, 4293d3b0591SJens Wiklander eckey_sign_rs_wrap, 430817466cbSJens Wiklander #endif 4313d3b0591SJens Wiklander #else /* MBEDTLS_ECDSA_C */ 4323d3b0591SJens Wiklander NULL, 4333d3b0591SJens Wiklander NULL, 4343d3b0591SJens Wiklander #endif /* MBEDTLS_ECDSA_C */ 435817466cbSJens Wiklander NULL, 436817466cbSJens Wiklander NULL, 437817466cbSJens Wiklander eckey_check_pair, 438817466cbSJens Wiklander eckey_alloc_wrap, 439817466cbSJens Wiklander eckey_free_wrap, 4403d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 4413d3b0591SJens Wiklander eckey_rs_alloc, 4423d3b0591SJens Wiklander eckey_rs_free, 4433d3b0591SJens Wiklander #endif 444817466cbSJens Wiklander eckey_debug, 445817466cbSJens Wiklander }; 446817466cbSJens Wiklander 447817466cbSJens Wiklander /* 448817466cbSJens Wiklander * EC key restricted to ECDH 449817466cbSJens Wiklander */ 450817466cbSJens Wiklander static int eckeydh_can_do( mbedtls_pk_type_t type ) 451817466cbSJens Wiklander { 452817466cbSJens Wiklander return( type == MBEDTLS_PK_ECKEY || 453817466cbSJens Wiklander type == MBEDTLS_PK_ECKEY_DH ); 454817466cbSJens Wiklander } 455817466cbSJens Wiklander 456817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_eckeydh_info = { 457817466cbSJens Wiklander MBEDTLS_PK_ECKEY_DH, 458817466cbSJens Wiklander "EC_DH", 459817466cbSJens Wiklander eckey_get_bitlen, /* Same underlying key structure */ 460817466cbSJens Wiklander eckeydh_can_do, 461817466cbSJens Wiklander NULL, 462817466cbSJens Wiklander NULL, 4633d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 4643d3b0591SJens Wiklander NULL, 4653d3b0591SJens Wiklander NULL, 4663d3b0591SJens Wiklander #endif 467817466cbSJens Wiklander NULL, 468817466cbSJens Wiklander NULL, 469817466cbSJens Wiklander eckey_check_pair, 470817466cbSJens Wiklander eckey_alloc_wrap, /* Same underlying key structure */ 471817466cbSJens Wiklander eckey_free_wrap, /* Same underlying key structure */ 4723d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 4733d3b0591SJens Wiklander NULL, 4743d3b0591SJens Wiklander NULL, 4753d3b0591SJens Wiklander #endif 476817466cbSJens Wiklander eckey_debug, /* Same underlying key structure */ 477817466cbSJens Wiklander }; 478817466cbSJens Wiklander #endif /* MBEDTLS_ECP_C */ 479817466cbSJens Wiklander 480817466cbSJens Wiklander #if defined(MBEDTLS_ECDSA_C) 481817466cbSJens Wiklander static int ecdsa_can_do( mbedtls_pk_type_t type ) 482817466cbSJens Wiklander { 483817466cbSJens Wiklander return( type == MBEDTLS_PK_ECDSA ); 484817466cbSJens Wiklander } 485817466cbSJens Wiklander 486*11fa71b9SJerome Forissier #if defined(MBEDTLS_USE_PSA_CRYPTO) 487*11fa71b9SJerome Forissier /* 488*11fa71b9SJerome Forissier * An ASN.1 encoded signature is a sequence of two ASN.1 integers. Parse one of 489*11fa71b9SJerome Forissier * those integers and convert it to the fixed-length encoding expected by PSA. 490*11fa71b9SJerome Forissier */ 491*11fa71b9SJerome Forissier static int extract_ecdsa_sig_int( unsigned char **from, const unsigned char *end, 492*11fa71b9SJerome Forissier unsigned char *to, size_t to_len ) 493*11fa71b9SJerome Forissier { 494*11fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 495*11fa71b9SJerome Forissier size_t unpadded_len, padding_len; 496*11fa71b9SJerome Forissier 497*11fa71b9SJerome Forissier if( ( ret = mbedtls_asn1_get_tag( from, end, &unpadded_len, 498*11fa71b9SJerome Forissier MBEDTLS_ASN1_INTEGER ) ) != 0 ) 499*11fa71b9SJerome Forissier { 500*11fa71b9SJerome Forissier return( ret ); 501*11fa71b9SJerome Forissier } 502*11fa71b9SJerome Forissier 503*11fa71b9SJerome Forissier while( unpadded_len > 0 && **from == 0x00 ) 504*11fa71b9SJerome Forissier { 505*11fa71b9SJerome Forissier ( *from )++; 506*11fa71b9SJerome Forissier unpadded_len--; 507*11fa71b9SJerome Forissier } 508*11fa71b9SJerome Forissier 509*11fa71b9SJerome Forissier if( unpadded_len > to_len || unpadded_len == 0 ) 510*11fa71b9SJerome Forissier return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 511*11fa71b9SJerome Forissier 512*11fa71b9SJerome Forissier padding_len = to_len - unpadded_len; 513*11fa71b9SJerome Forissier memset( to, 0x00, padding_len ); 514*11fa71b9SJerome Forissier memcpy( to + padding_len, *from, unpadded_len ); 515*11fa71b9SJerome Forissier ( *from ) += unpadded_len; 516*11fa71b9SJerome Forissier 517*11fa71b9SJerome Forissier return( 0 ); 518*11fa71b9SJerome Forissier } 519*11fa71b9SJerome Forissier 520*11fa71b9SJerome Forissier /* 521*11fa71b9SJerome Forissier * Convert a signature from an ASN.1 sequence of two integers 522*11fa71b9SJerome Forissier * to a raw {r,s} buffer. Note: the provided sig buffer must be at least 523*11fa71b9SJerome Forissier * twice as big as int_size. 524*11fa71b9SJerome Forissier */ 525*11fa71b9SJerome Forissier static int extract_ecdsa_sig( unsigned char **p, const unsigned char *end, 526*11fa71b9SJerome Forissier unsigned char *sig, size_t int_size ) 527*11fa71b9SJerome Forissier { 528*11fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 529*11fa71b9SJerome Forissier size_t tmp_size; 530*11fa71b9SJerome Forissier 531*11fa71b9SJerome Forissier if( ( ret = mbedtls_asn1_get_tag( p, end, &tmp_size, 532*11fa71b9SJerome Forissier MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 533*11fa71b9SJerome Forissier return( ret ); 534*11fa71b9SJerome Forissier 535*11fa71b9SJerome Forissier /* Extract r */ 536*11fa71b9SJerome Forissier if( ( ret = extract_ecdsa_sig_int( p, end, sig, int_size ) ) != 0 ) 537*11fa71b9SJerome Forissier return( ret ); 538*11fa71b9SJerome Forissier /* Extract s */ 539*11fa71b9SJerome Forissier if( ( ret = extract_ecdsa_sig_int( p, end, sig + int_size, int_size ) ) != 0 ) 540*11fa71b9SJerome Forissier return( ret ); 541*11fa71b9SJerome Forissier 542*11fa71b9SJerome Forissier return( 0 ); 543*11fa71b9SJerome Forissier } 544*11fa71b9SJerome Forissier 545*11fa71b9SJerome Forissier static int ecdsa_verify_wrap( void *ctx_arg, mbedtls_md_type_t md_alg, 546*11fa71b9SJerome Forissier const unsigned char *hash, size_t hash_len, 547*11fa71b9SJerome Forissier const unsigned char *sig, size_t sig_len ) 548*11fa71b9SJerome Forissier { 549*11fa71b9SJerome Forissier mbedtls_ecdsa_context *ctx = ctx_arg; 550*11fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 551*11fa71b9SJerome Forissier psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 552*11fa71b9SJerome Forissier psa_key_handle_t key_handle = 0; 553*11fa71b9SJerome Forissier psa_status_t status; 554*11fa71b9SJerome Forissier mbedtls_pk_context key; 555*11fa71b9SJerome Forissier int key_len; 556*11fa71b9SJerome Forissier /* see ECP_PUB_DER_MAX_BYTES in pkwrite.c */ 557*11fa71b9SJerome Forissier unsigned char buf[30 + 2 * MBEDTLS_ECP_MAX_BYTES]; 558*11fa71b9SJerome Forissier unsigned char *p; 559*11fa71b9SJerome Forissier mbedtls_pk_info_t pk_info = mbedtls_eckey_info; 560*11fa71b9SJerome Forissier psa_algorithm_t psa_sig_md, psa_md; 561*11fa71b9SJerome Forissier size_t curve_bits; 562*11fa71b9SJerome Forissier psa_ecc_curve_t curve = 563*11fa71b9SJerome Forissier mbedtls_ecc_group_to_psa( ctx->grp.id, &curve_bits ); 564*11fa71b9SJerome Forissier const size_t signature_part_size = ( ctx->grp.nbits + 7 ) / 8; 565*11fa71b9SJerome Forissier 566*11fa71b9SJerome Forissier if( curve == 0 ) 567*11fa71b9SJerome Forissier return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 568*11fa71b9SJerome Forissier 569*11fa71b9SJerome Forissier /* mbedtls_pk_write_pubkey() expects a full PK context; 570*11fa71b9SJerome Forissier * re-construct one to make it happy */ 571*11fa71b9SJerome Forissier key.pk_info = &pk_info; 572*11fa71b9SJerome Forissier key.pk_ctx = ctx; 573*11fa71b9SJerome Forissier p = buf + sizeof( buf ); 574*11fa71b9SJerome Forissier key_len = mbedtls_pk_write_pubkey( &p, buf, &key ); 575*11fa71b9SJerome Forissier if( key_len <= 0 ) 576*11fa71b9SJerome Forissier return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 577*11fa71b9SJerome Forissier 578*11fa71b9SJerome Forissier psa_md = mbedtls_psa_translate_md( md_alg ); 579*11fa71b9SJerome Forissier if( psa_md == 0 ) 580*11fa71b9SJerome Forissier return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 581*11fa71b9SJerome Forissier psa_sig_md = PSA_ALG_ECDSA( psa_md ); 582*11fa71b9SJerome Forissier 583*11fa71b9SJerome Forissier psa_set_key_type( &attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY( curve ) ); 584*11fa71b9SJerome Forissier psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY_HASH ); 585*11fa71b9SJerome Forissier psa_set_key_algorithm( &attributes, psa_sig_md ); 586*11fa71b9SJerome Forissier 587*11fa71b9SJerome Forissier status = psa_import_key( &attributes, 588*11fa71b9SJerome Forissier buf + sizeof( buf ) - key_len, key_len, 589*11fa71b9SJerome Forissier &key_handle ); 590*11fa71b9SJerome Forissier if( status != PSA_SUCCESS ) 591*11fa71b9SJerome Forissier { 592*11fa71b9SJerome Forissier ret = mbedtls_psa_err_translate_pk( status ); 593*11fa71b9SJerome Forissier goto cleanup; 594*11fa71b9SJerome Forissier } 595*11fa71b9SJerome Forissier 596*11fa71b9SJerome Forissier /* We don't need the exported key anymore and can 597*11fa71b9SJerome Forissier * reuse its buffer for signature extraction. */ 598*11fa71b9SJerome Forissier if( 2 * signature_part_size > sizeof( buf ) ) 599*11fa71b9SJerome Forissier { 600*11fa71b9SJerome Forissier ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA; 601*11fa71b9SJerome Forissier goto cleanup; 602*11fa71b9SJerome Forissier } 603*11fa71b9SJerome Forissier 604*11fa71b9SJerome Forissier p = (unsigned char*) sig; 605*11fa71b9SJerome Forissier if( ( ret = extract_ecdsa_sig( &p, sig + sig_len, buf, 606*11fa71b9SJerome Forissier signature_part_size ) ) != 0 ) 607*11fa71b9SJerome Forissier { 608*11fa71b9SJerome Forissier goto cleanup; 609*11fa71b9SJerome Forissier } 610*11fa71b9SJerome Forissier 611*11fa71b9SJerome Forissier if( psa_verify_hash( key_handle, psa_sig_md, 612*11fa71b9SJerome Forissier hash, hash_len, 613*11fa71b9SJerome Forissier buf, 2 * signature_part_size ) 614*11fa71b9SJerome Forissier != PSA_SUCCESS ) 615*11fa71b9SJerome Forissier { 616*11fa71b9SJerome Forissier ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; 617*11fa71b9SJerome Forissier goto cleanup; 618*11fa71b9SJerome Forissier } 619*11fa71b9SJerome Forissier 620*11fa71b9SJerome Forissier if( p != sig + sig_len ) 621*11fa71b9SJerome Forissier { 622*11fa71b9SJerome Forissier ret = MBEDTLS_ERR_PK_SIG_LEN_MISMATCH; 623*11fa71b9SJerome Forissier goto cleanup; 624*11fa71b9SJerome Forissier } 625*11fa71b9SJerome Forissier ret = 0; 626*11fa71b9SJerome Forissier 627*11fa71b9SJerome Forissier cleanup: 628*11fa71b9SJerome Forissier psa_destroy_key( key_handle ); 629*11fa71b9SJerome Forissier return( ret ); 630*11fa71b9SJerome Forissier } 631*11fa71b9SJerome Forissier #else /* MBEDTLS_USE_PSA_CRYPTO */ 632817466cbSJens Wiklander static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, 633817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 634817466cbSJens Wiklander const unsigned char *sig, size_t sig_len ) 635817466cbSJens Wiklander { 636*11fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 637817466cbSJens Wiklander ((void) md_alg); 638817466cbSJens Wiklander 639817466cbSJens Wiklander ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx, 640817466cbSJens Wiklander hash, hash_len, sig, sig_len ); 641817466cbSJens Wiklander 642817466cbSJens Wiklander if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH ) 643817466cbSJens Wiklander return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); 644817466cbSJens Wiklander 645817466cbSJens Wiklander return( ret ); 646817466cbSJens Wiklander } 647*11fa71b9SJerome Forissier #endif /* MBEDTLS_USE_PSA_CRYPTO */ 648817466cbSJens Wiklander 649817466cbSJens Wiklander static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, 650817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 651817466cbSJens Wiklander unsigned char *sig, size_t *sig_len, 652817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 653817466cbSJens Wiklander { 654817466cbSJens Wiklander return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx, 655817466cbSJens Wiklander md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) ); 656817466cbSJens Wiklander } 657817466cbSJens Wiklander 6583d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE) 6593d3b0591SJens Wiklander static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, 6603d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 6613d3b0591SJens Wiklander const unsigned char *sig, size_t sig_len, 6623d3b0591SJens Wiklander void *rs_ctx ) 6633d3b0591SJens Wiklander { 664*11fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 6653d3b0591SJens Wiklander ((void) md_alg); 6663d3b0591SJens Wiklander 6673d3b0591SJens Wiklander ret = mbedtls_ecdsa_read_signature_restartable( 6683d3b0591SJens Wiklander (mbedtls_ecdsa_context *) ctx, 6693d3b0591SJens Wiklander hash, hash_len, sig, sig_len, 6703d3b0591SJens Wiklander (mbedtls_ecdsa_restart_ctx *) rs_ctx ); 6713d3b0591SJens Wiklander 6723d3b0591SJens Wiklander if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH ) 6733d3b0591SJens Wiklander return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); 6743d3b0591SJens Wiklander 6753d3b0591SJens Wiklander return( ret ); 6763d3b0591SJens Wiklander } 6773d3b0591SJens Wiklander 6783d3b0591SJens Wiklander static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, 6793d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 6803d3b0591SJens Wiklander unsigned char *sig, size_t *sig_len, 6813d3b0591SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, 6823d3b0591SJens Wiklander void *rs_ctx ) 6833d3b0591SJens Wiklander { 6843d3b0591SJens Wiklander return( mbedtls_ecdsa_write_signature_restartable( 6853d3b0591SJens Wiklander (mbedtls_ecdsa_context *) ctx, 6863d3b0591SJens Wiklander md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng, 6873d3b0591SJens Wiklander (mbedtls_ecdsa_restart_ctx *) rs_ctx ) ); 6883d3b0591SJens Wiklander 6893d3b0591SJens Wiklander } 6903d3b0591SJens Wiklander #endif /* MBEDTLS_ECP_RESTARTABLE */ 6913d3b0591SJens Wiklander 692817466cbSJens Wiklander static void *ecdsa_alloc_wrap( void ) 693817466cbSJens Wiklander { 694817466cbSJens Wiklander void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) ); 695817466cbSJens Wiklander 696817466cbSJens Wiklander if( ctx != NULL ) 697817466cbSJens Wiklander mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx ); 698817466cbSJens Wiklander 699817466cbSJens Wiklander return( ctx ); 700817466cbSJens Wiklander } 701817466cbSJens Wiklander 702817466cbSJens Wiklander static void ecdsa_free_wrap( void *ctx ) 703817466cbSJens Wiklander { 704817466cbSJens Wiklander mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx ); 705817466cbSJens Wiklander mbedtls_free( ctx ); 706817466cbSJens Wiklander } 707817466cbSJens Wiklander 7083d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE) 7093d3b0591SJens Wiklander static void *ecdsa_rs_alloc( void ) 7103d3b0591SJens Wiklander { 7113d3b0591SJens Wiklander void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_restart_ctx ) ); 7123d3b0591SJens Wiklander 7133d3b0591SJens Wiklander if( ctx != NULL ) 7143d3b0591SJens Wiklander mbedtls_ecdsa_restart_init( ctx ); 7153d3b0591SJens Wiklander 7163d3b0591SJens Wiklander return( ctx ); 7173d3b0591SJens Wiklander } 7183d3b0591SJens Wiklander 7193d3b0591SJens Wiklander static void ecdsa_rs_free( void *ctx ) 7203d3b0591SJens Wiklander { 7213d3b0591SJens Wiklander mbedtls_ecdsa_restart_free( ctx ); 7223d3b0591SJens Wiklander mbedtls_free( ctx ); 7233d3b0591SJens Wiklander } 7243d3b0591SJens Wiklander #endif /* MBEDTLS_ECP_RESTARTABLE */ 7253d3b0591SJens Wiklander 726817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_ecdsa_info = { 727817466cbSJens Wiklander MBEDTLS_PK_ECDSA, 728817466cbSJens Wiklander "ECDSA", 729817466cbSJens Wiklander eckey_get_bitlen, /* Compatible key structures */ 730817466cbSJens Wiklander ecdsa_can_do, 731817466cbSJens Wiklander ecdsa_verify_wrap, 732817466cbSJens Wiklander ecdsa_sign_wrap, 7333d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE) 7343d3b0591SJens Wiklander ecdsa_verify_rs_wrap, 7353d3b0591SJens Wiklander ecdsa_sign_rs_wrap, 7363d3b0591SJens Wiklander #endif 737817466cbSJens Wiklander NULL, 738817466cbSJens Wiklander NULL, 739817466cbSJens Wiklander eckey_check_pair, /* Compatible key structures */ 740817466cbSJens Wiklander ecdsa_alloc_wrap, 741817466cbSJens Wiklander ecdsa_free_wrap, 7423d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE) 7433d3b0591SJens Wiklander ecdsa_rs_alloc, 7443d3b0591SJens Wiklander ecdsa_rs_free, 7453d3b0591SJens Wiklander #endif 746817466cbSJens Wiklander eckey_debug, /* Compatible key structures */ 747817466cbSJens Wiklander }; 748817466cbSJens Wiklander #endif /* MBEDTLS_ECDSA_C */ 749817466cbSJens Wiklander 750817466cbSJens Wiklander #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) 751817466cbSJens Wiklander /* 752817466cbSJens Wiklander * Support for alternative RSA-private implementations 753817466cbSJens Wiklander */ 754817466cbSJens Wiklander 755817466cbSJens Wiklander static int rsa_alt_can_do( mbedtls_pk_type_t type ) 756817466cbSJens Wiklander { 757817466cbSJens Wiklander return( type == MBEDTLS_PK_RSA ); 758817466cbSJens Wiklander } 759817466cbSJens Wiklander 760817466cbSJens Wiklander static size_t rsa_alt_get_bitlen( const void *ctx ) 761817466cbSJens Wiklander { 762817466cbSJens Wiklander const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx; 763817466cbSJens Wiklander 764817466cbSJens Wiklander return( 8 * rsa_alt->key_len_func( rsa_alt->key ) ); 765817466cbSJens Wiklander } 766817466cbSJens Wiklander 767817466cbSJens Wiklander static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, 768817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 769817466cbSJens Wiklander unsigned char *sig, size_t *sig_len, 770817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 771817466cbSJens Wiklander { 772817466cbSJens Wiklander mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx; 773817466cbSJens Wiklander 7743d3b0591SJens Wiklander #if SIZE_MAX > UINT_MAX 775817466cbSJens Wiklander if( UINT_MAX < hash_len ) 776817466cbSJens Wiklander return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 7773d3b0591SJens Wiklander #endif /* SIZE_MAX > UINT_MAX */ 778817466cbSJens Wiklander 779817466cbSJens Wiklander *sig_len = rsa_alt->key_len_func( rsa_alt->key ); 780*11fa71b9SJerome Forissier if( *sig_len > MBEDTLS_PK_SIGNATURE_MAX_SIZE ) 781*11fa71b9SJerome Forissier return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 782817466cbSJens Wiklander 783817466cbSJens Wiklander return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, 784817466cbSJens Wiklander md_alg, (unsigned int) hash_len, hash, sig ) ); 785817466cbSJens Wiklander } 786817466cbSJens Wiklander 787817466cbSJens Wiklander static int rsa_alt_decrypt_wrap( void *ctx, 788817466cbSJens Wiklander const unsigned char *input, size_t ilen, 789817466cbSJens Wiklander unsigned char *output, size_t *olen, size_t osize, 790817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 791817466cbSJens Wiklander { 792817466cbSJens Wiklander mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx; 793817466cbSJens Wiklander 794817466cbSJens Wiklander ((void) f_rng); 795817466cbSJens Wiklander ((void) p_rng); 796817466cbSJens Wiklander 797817466cbSJens Wiklander if( ilen != rsa_alt->key_len_func( rsa_alt->key ) ) 798817466cbSJens Wiklander return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); 799817466cbSJens Wiklander 800817466cbSJens Wiklander return( rsa_alt->decrypt_func( rsa_alt->key, 801817466cbSJens Wiklander MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) ); 802817466cbSJens Wiklander } 803817466cbSJens Wiklander 804817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C) 805817466cbSJens Wiklander static int rsa_alt_check_pair( const void *pub, const void *prv ) 806817466cbSJens Wiklander { 807817466cbSJens Wiklander unsigned char sig[MBEDTLS_MPI_MAX_SIZE]; 808817466cbSJens Wiklander unsigned char hash[32]; 809817466cbSJens Wiklander size_t sig_len = 0; 810*11fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 811817466cbSJens Wiklander 812817466cbSJens Wiklander if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) ) 813817466cbSJens Wiklander return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); 814817466cbSJens Wiklander 815817466cbSJens Wiklander memset( hash, 0x2a, sizeof( hash ) ); 816817466cbSJens Wiklander 817817466cbSJens Wiklander if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE, 818817466cbSJens Wiklander hash, sizeof( hash ), 819817466cbSJens Wiklander sig, &sig_len, NULL, NULL ) ) != 0 ) 820817466cbSJens Wiklander { 821817466cbSJens Wiklander return( ret ); 822817466cbSJens Wiklander } 823817466cbSJens Wiklander 824817466cbSJens Wiklander if( rsa_verify_wrap( (void *) pub, MBEDTLS_MD_NONE, 825817466cbSJens Wiklander hash, sizeof( hash ), sig, sig_len ) != 0 ) 826817466cbSJens Wiklander { 827817466cbSJens Wiklander return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); 828817466cbSJens Wiklander } 829817466cbSJens Wiklander 830817466cbSJens Wiklander return( 0 ); 831817466cbSJens Wiklander } 832817466cbSJens Wiklander #endif /* MBEDTLS_RSA_C */ 833817466cbSJens Wiklander 834817466cbSJens Wiklander static void *rsa_alt_alloc_wrap( void ) 835817466cbSJens Wiklander { 836817466cbSJens Wiklander void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context ) ); 837817466cbSJens Wiklander 838817466cbSJens Wiklander if( ctx != NULL ) 839817466cbSJens Wiklander memset( ctx, 0, sizeof( mbedtls_rsa_alt_context ) ); 840817466cbSJens Wiklander 841817466cbSJens Wiklander return( ctx ); 842817466cbSJens Wiklander } 843817466cbSJens Wiklander 844817466cbSJens Wiklander static void rsa_alt_free_wrap( void *ctx ) 845817466cbSJens Wiklander { 8463d3b0591SJens Wiklander mbedtls_platform_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) ); 847817466cbSJens Wiklander mbedtls_free( ctx ); 848817466cbSJens Wiklander } 849817466cbSJens Wiklander 850817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_rsa_alt_info = { 851817466cbSJens Wiklander MBEDTLS_PK_RSA_ALT, 852817466cbSJens Wiklander "RSA-alt", 853817466cbSJens Wiklander rsa_alt_get_bitlen, 854817466cbSJens Wiklander rsa_alt_can_do, 855817466cbSJens Wiklander NULL, 856817466cbSJens Wiklander rsa_alt_sign_wrap, 8573d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 8583d3b0591SJens Wiklander NULL, 8593d3b0591SJens Wiklander NULL, 8603d3b0591SJens Wiklander #endif 861817466cbSJens Wiklander rsa_alt_decrypt_wrap, 862817466cbSJens Wiklander NULL, 863817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C) 864817466cbSJens Wiklander rsa_alt_check_pair, 865817466cbSJens Wiklander #else 866817466cbSJens Wiklander NULL, 867817466cbSJens Wiklander #endif 868817466cbSJens Wiklander rsa_alt_alloc_wrap, 869817466cbSJens Wiklander rsa_alt_free_wrap, 8703d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 8713d3b0591SJens Wiklander NULL, 8723d3b0591SJens Wiklander NULL, 8733d3b0591SJens Wiklander #endif 874817466cbSJens Wiklander NULL, 875817466cbSJens Wiklander }; 876817466cbSJens Wiklander 877817466cbSJens Wiklander #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ 878817466cbSJens Wiklander 879*11fa71b9SJerome Forissier #if defined(MBEDTLS_USE_PSA_CRYPTO) 880*11fa71b9SJerome Forissier 881*11fa71b9SJerome Forissier static void *pk_opaque_alloc_wrap( void ) 882*11fa71b9SJerome Forissier { 883*11fa71b9SJerome Forissier void *ctx = mbedtls_calloc( 1, sizeof( psa_key_handle_t ) ); 884*11fa71b9SJerome Forissier 885*11fa71b9SJerome Forissier /* no _init() function to call, an calloc() already zeroized */ 886*11fa71b9SJerome Forissier 887*11fa71b9SJerome Forissier return( ctx ); 888*11fa71b9SJerome Forissier } 889*11fa71b9SJerome Forissier 890*11fa71b9SJerome Forissier static void pk_opaque_free_wrap( void *ctx ) 891*11fa71b9SJerome Forissier { 892*11fa71b9SJerome Forissier mbedtls_platform_zeroize( ctx, sizeof( psa_key_handle_t ) ); 893*11fa71b9SJerome Forissier mbedtls_free( ctx ); 894*11fa71b9SJerome Forissier } 895*11fa71b9SJerome Forissier 896*11fa71b9SJerome Forissier static size_t pk_opaque_get_bitlen( const void *ctx ) 897*11fa71b9SJerome Forissier { 898*11fa71b9SJerome Forissier const psa_key_handle_t *key = (const psa_key_handle_t *) ctx; 899*11fa71b9SJerome Forissier size_t bits; 900*11fa71b9SJerome Forissier psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 901*11fa71b9SJerome Forissier 902*11fa71b9SJerome Forissier if( PSA_SUCCESS != psa_get_key_attributes( *key, &attributes ) ) 903*11fa71b9SJerome Forissier return( 0 ); 904*11fa71b9SJerome Forissier 905*11fa71b9SJerome Forissier bits = psa_get_key_bits( &attributes ); 906*11fa71b9SJerome Forissier psa_reset_key_attributes( &attributes ); 907*11fa71b9SJerome Forissier return( bits ); 908*11fa71b9SJerome Forissier } 909*11fa71b9SJerome Forissier 910*11fa71b9SJerome Forissier static int pk_opaque_can_do( mbedtls_pk_type_t type ) 911*11fa71b9SJerome Forissier { 912*11fa71b9SJerome Forissier /* For now opaque PSA keys can only wrap ECC keypairs, 913*11fa71b9SJerome Forissier * as checked by setup_psa(). 914*11fa71b9SJerome Forissier * Also, ECKEY_DH does not really make sense with the current API. */ 915*11fa71b9SJerome Forissier return( type == MBEDTLS_PK_ECKEY || 916*11fa71b9SJerome Forissier type == MBEDTLS_PK_ECDSA ); 917*11fa71b9SJerome Forissier } 918*11fa71b9SJerome Forissier 919*11fa71b9SJerome Forissier /* 920*11fa71b9SJerome Forissier * Simultaneously convert and move raw MPI from the beginning of a buffer 921*11fa71b9SJerome Forissier * to an ASN.1 MPI at the end of the buffer. 922*11fa71b9SJerome Forissier * See also mbedtls_asn1_write_mpi(). 923*11fa71b9SJerome Forissier * 924*11fa71b9SJerome Forissier * p: pointer to the end of the output buffer 925*11fa71b9SJerome Forissier * start: start of the output buffer, and also of the mpi to write at the end 926*11fa71b9SJerome Forissier * n_len: length of the mpi to read from start 927*11fa71b9SJerome Forissier */ 928*11fa71b9SJerome Forissier static int asn1_write_mpibuf( unsigned char **p, unsigned char *start, 929*11fa71b9SJerome Forissier size_t n_len ) 930*11fa71b9SJerome Forissier { 931*11fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 932*11fa71b9SJerome Forissier size_t len = 0; 933*11fa71b9SJerome Forissier 934*11fa71b9SJerome Forissier if( (size_t)( *p - start ) < n_len ) 935*11fa71b9SJerome Forissier return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 936*11fa71b9SJerome Forissier 937*11fa71b9SJerome Forissier len = n_len; 938*11fa71b9SJerome Forissier *p -= len; 939*11fa71b9SJerome Forissier memmove( *p, start, len ); 940*11fa71b9SJerome Forissier 941*11fa71b9SJerome Forissier /* ASN.1 DER encoding requires minimal length, so skip leading 0s. 942*11fa71b9SJerome Forissier * Neither r nor s should be 0, but as a failsafe measure, still detect 943*11fa71b9SJerome Forissier * that rather than overflowing the buffer in case of a PSA error. */ 944*11fa71b9SJerome Forissier while( len > 0 && **p == 0x00 ) 945*11fa71b9SJerome Forissier { 946*11fa71b9SJerome Forissier ++(*p); 947*11fa71b9SJerome Forissier --len; 948*11fa71b9SJerome Forissier } 949*11fa71b9SJerome Forissier 950*11fa71b9SJerome Forissier /* this is only reached if the signature was invalid */ 951*11fa71b9SJerome Forissier if( len == 0 ) 952*11fa71b9SJerome Forissier return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED ); 953*11fa71b9SJerome Forissier 954*11fa71b9SJerome Forissier /* if the msb is 1, ASN.1 requires that we prepend a 0. 955*11fa71b9SJerome Forissier * Neither r nor s can be 0, so we can assume len > 0 at all times. */ 956*11fa71b9SJerome Forissier if( **p & 0x80 ) 957*11fa71b9SJerome Forissier { 958*11fa71b9SJerome Forissier if( *p - start < 1 ) 959*11fa71b9SJerome Forissier return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 960*11fa71b9SJerome Forissier 961*11fa71b9SJerome Forissier *--(*p) = 0x00; 962*11fa71b9SJerome Forissier len += 1; 963*11fa71b9SJerome Forissier } 964*11fa71b9SJerome Forissier 965*11fa71b9SJerome Forissier MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 966*11fa71b9SJerome Forissier MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, 967*11fa71b9SJerome Forissier MBEDTLS_ASN1_INTEGER ) ); 968*11fa71b9SJerome Forissier 969*11fa71b9SJerome Forissier return( (int) len ); 970*11fa71b9SJerome Forissier } 971*11fa71b9SJerome Forissier 972*11fa71b9SJerome Forissier /* Transcode signature from PSA format to ASN.1 sequence. 973*11fa71b9SJerome Forissier * See ecdsa_signature_to_asn1 in ecdsa.c, but with byte buffers instead of 974*11fa71b9SJerome Forissier * MPIs, and in-place. 975*11fa71b9SJerome Forissier * 976*11fa71b9SJerome Forissier * [in/out] sig: the signature pre- and post-transcoding 977*11fa71b9SJerome Forissier * [in/out] sig_len: signature length pre- and post-transcoding 978*11fa71b9SJerome Forissier * [int] buf_len: the available size the in/out buffer 979*11fa71b9SJerome Forissier */ 980*11fa71b9SJerome Forissier static int pk_ecdsa_sig_asn1_from_psa( unsigned char *sig, size_t *sig_len, 981*11fa71b9SJerome Forissier size_t buf_len ) 982*11fa71b9SJerome Forissier { 983*11fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 984*11fa71b9SJerome Forissier size_t len = 0; 985*11fa71b9SJerome Forissier const size_t rs_len = *sig_len / 2; 986*11fa71b9SJerome Forissier unsigned char *p = sig + buf_len; 987*11fa71b9SJerome Forissier 988*11fa71b9SJerome Forissier MBEDTLS_ASN1_CHK_ADD( len, asn1_write_mpibuf( &p, sig + rs_len, rs_len ) ); 989*11fa71b9SJerome Forissier MBEDTLS_ASN1_CHK_ADD( len, asn1_write_mpibuf( &p, sig, rs_len ) ); 990*11fa71b9SJerome Forissier 991*11fa71b9SJerome Forissier MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &p, sig, len ) ); 992*11fa71b9SJerome Forissier MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, sig, 993*11fa71b9SJerome Forissier MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); 994*11fa71b9SJerome Forissier 995*11fa71b9SJerome Forissier memmove( sig, p, len ); 996*11fa71b9SJerome Forissier *sig_len = len; 997*11fa71b9SJerome Forissier 998*11fa71b9SJerome Forissier return( 0 ); 999*11fa71b9SJerome Forissier } 1000*11fa71b9SJerome Forissier 1001*11fa71b9SJerome Forissier static int pk_opaque_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, 1002*11fa71b9SJerome Forissier const unsigned char *hash, size_t hash_len, 1003*11fa71b9SJerome Forissier unsigned char *sig, size_t *sig_len, 1004*11fa71b9SJerome Forissier int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 1005*11fa71b9SJerome Forissier { 1006*11fa71b9SJerome Forissier const psa_key_handle_t *key = (const psa_key_handle_t *) ctx; 1007*11fa71b9SJerome Forissier psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 1008*11fa71b9SJerome Forissier psa_algorithm_t alg = PSA_ALG_ECDSA( mbedtls_psa_translate_md( md_alg ) ); 1009*11fa71b9SJerome Forissier size_t buf_len; 1010*11fa71b9SJerome Forissier psa_status_t status; 1011*11fa71b9SJerome Forissier 1012*11fa71b9SJerome Forissier /* PSA has its own RNG */ 1013*11fa71b9SJerome Forissier (void) f_rng; 1014*11fa71b9SJerome Forissier (void) p_rng; 1015*11fa71b9SJerome Forissier 1016*11fa71b9SJerome Forissier /* PSA needs an output buffer of known size, but our API doesn't provide 1017*11fa71b9SJerome Forissier * that information. Assume that the buffer is large enough for a 1018*11fa71b9SJerome Forissier * maximal-length signature with that key (otherwise the application is 1019*11fa71b9SJerome Forissier * buggy anyway). */ 1020*11fa71b9SJerome Forissier status = psa_get_key_attributes( *key, &attributes ); 1021*11fa71b9SJerome Forissier if( status != PSA_SUCCESS ) 1022*11fa71b9SJerome Forissier return( mbedtls_psa_err_translate_pk( status ) ); 1023*11fa71b9SJerome Forissier buf_len = MBEDTLS_ECDSA_MAX_SIG_LEN( psa_get_key_bits( &attributes ) ); 1024*11fa71b9SJerome Forissier psa_reset_key_attributes( &attributes ); 1025*11fa71b9SJerome Forissier if( buf_len > MBEDTLS_PK_SIGNATURE_MAX_SIZE ) 1026*11fa71b9SJerome Forissier return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); 1027*11fa71b9SJerome Forissier 1028*11fa71b9SJerome Forissier /* make the signature */ 1029*11fa71b9SJerome Forissier status = psa_sign_hash( *key, alg, hash, hash_len, 1030*11fa71b9SJerome Forissier sig, buf_len, sig_len ); 1031*11fa71b9SJerome Forissier if( status != PSA_SUCCESS ) 1032*11fa71b9SJerome Forissier return( mbedtls_psa_err_translate_pk( status ) ); 1033*11fa71b9SJerome Forissier 1034*11fa71b9SJerome Forissier /* transcode it to ASN.1 sequence */ 1035*11fa71b9SJerome Forissier return( pk_ecdsa_sig_asn1_from_psa( sig, sig_len, buf_len ) ); 1036*11fa71b9SJerome Forissier } 1037*11fa71b9SJerome Forissier 1038*11fa71b9SJerome Forissier const mbedtls_pk_info_t mbedtls_pk_opaque_info = { 1039*11fa71b9SJerome Forissier MBEDTLS_PK_OPAQUE, 1040*11fa71b9SJerome Forissier "Opaque", 1041*11fa71b9SJerome Forissier pk_opaque_get_bitlen, 1042*11fa71b9SJerome Forissier pk_opaque_can_do, 1043*11fa71b9SJerome Forissier NULL, /* verify - will be done later */ 1044*11fa71b9SJerome Forissier pk_opaque_sign_wrap, 1045*11fa71b9SJerome Forissier #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 1046*11fa71b9SJerome Forissier NULL, /* restartable verify - not relevant */ 1047*11fa71b9SJerome Forissier NULL, /* restartable sign - not relevant */ 1048*11fa71b9SJerome Forissier #endif 1049*11fa71b9SJerome Forissier NULL, /* decrypt - will be done later */ 1050*11fa71b9SJerome Forissier NULL, /* encrypt - will be done later */ 1051*11fa71b9SJerome Forissier NULL, /* check_pair - could be done later or left NULL */ 1052*11fa71b9SJerome Forissier pk_opaque_alloc_wrap, 1053*11fa71b9SJerome Forissier pk_opaque_free_wrap, 1054*11fa71b9SJerome Forissier #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 1055*11fa71b9SJerome Forissier NULL, /* restart alloc - not relevant */ 1056*11fa71b9SJerome Forissier NULL, /* restart free - not relevant */ 1057*11fa71b9SJerome Forissier #endif 1058*11fa71b9SJerome Forissier NULL, /* debug - could be done later, or even left NULL */ 1059*11fa71b9SJerome Forissier }; 1060*11fa71b9SJerome Forissier 1061*11fa71b9SJerome Forissier #endif /* MBEDTLS_USE_PSA_CRYPTO */ 1062*11fa71b9SJerome Forissier 1063817466cbSJens Wiklander #endif /* MBEDTLS_PK_C */ 1064