xref: /optee_os/lib/libmbedtls/mbedtls/library/pk_wrap.c (revision 11fa71b9ddb429088f325cfda430183003ccd1db)
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