xref: /optee_os/lib/libmbedtls/mbedtls/library/pk_wrap.c (revision 817466cb476de705a8e3dabe1ef165fe27a18c2f)
1*817466cbSJens Wiklander /*
2*817466cbSJens Wiklander  *  Public Key abstraction layer: wrapper functions
3*817466cbSJens Wiklander  *
4*817466cbSJens Wiklander  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5*817466cbSJens Wiklander  *  SPDX-License-Identifier: Apache-2.0
6*817466cbSJens Wiklander  *
7*817466cbSJens Wiklander  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
8*817466cbSJens Wiklander  *  not use this file except in compliance with the License.
9*817466cbSJens Wiklander  *  You may obtain a copy of the License at
10*817466cbSJens Wiklander  *
11*817466cbSJens Wiklander  *  http://www.apache.org/licenses/LICENSE-2.0
12*817466cbSJens Wiklander  *
13*817466cbSJens Wiklander  *  Unless required by applicable law or agreed to in writing, software
14*817466cbSJens Wiklander  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15*817466cbSJens Wiklander  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*817466cbSJens Wiklander  *  See the License for the specific language governing permissions and
17*817466cbSJens Wiklander  *  limitations under the License.
18*817466cbSJens Wiklander  *
19*817466cbSJens Wiklander  *  This file is part of mbed TLS (https://tls.mbed.org)
20*817466cbSJens Wiklander  */
21*817466cbSJens Wiklander 
22*817466cbSJens Wiklander #if !defined(MBEDTLS_CONFIG_FILE)
23*817466cbSJens Wiklander #include "mbedtls/config.h"
24*817466cbSJens Wiklander #else
25*817466cbSJens Wiklander #include MBEDTLS_CONFIG_FILE
26*817466cbSJens Wiklander #endif
27*817466cbSJens Wiklander 
28*817466cbSJens Wiklander #if defined(MBEDTLS_PK_C)
29*817466cbSJens Wiklander #include "mbedtls/pk_internal.h"
30*817466cbSJens Wiklander 
31*817466cbSJens Wiklander /* Even if RSA not activated, for the sake of RSA-alt */
32*817466cbSJens Wiklander #include "mbedtls/rsa.h"
33*817466cbSJens Wiklander #include "mbedtls/bignum.h"
34*817466cbSJens Wiklander 
35*817466cbSJens Wiklander #include <string.h>
36*817466cbSJens Wiklander 
37*817466cbSJens Wiklander #if defined(MBEDTLS_ECP_C)
38*817466cbSJens Wiklander #include "mbedtls/ecp.h"
39*817466cbSJens Wiklander #endif
40*817466cbSJens Wiklander 
41*817466cbSJens Wiklander #if defined(MBEDTLS_ECDSA_C)
42*817466cbSJens Wiklander #include "mbedtls/ecdsa.h"
43*817466cbSJens Wiklander #endif
44*817466cbSJens Wiklander 
45*817466cbSJens Wiklander #if defined(MBEDTLS_PLATFORM_C)
46*817466cbSJens Wiklander #include "mbedtls/platform.h"
47*817466cbSJens Wiklander #else
48*817466cbSJens Wiklander #include <stdlib.h>
49*817466cbSJens Wiklander #define mbedtls_calloc    calloc
50*817466cbSJens Wiklander #define mbedtls_free       free
51*817466cbSJens Wiklander #endif
52*817466cbSJens Wiklander 
53*817466cbSJens Wiklander #include <limits.h>
54*817466cbSJens Wiklander 
55*817466cbSJens Wiklander #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
56*817466cbSJens Wiklander /* Implementation that should never be optimized out by the compiler */
57*817466cbSJens Wiklander static void mbedtls_zeroize( void *v, size_t n ) {
58*817466cbSJens Wiklander     volatile unsigned char *p = v; while( n-- ) *p++ = 0;
59*817466cbSJens Wiklander }
60*817466cbSJens Wiklander #endif
61*817466cbSJens Wiklander 
62*817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C)
63*817466cbSJens Wiklander static int rsa_can_do( mbedtls_pk_type_t type )
64*817466cbSJens Wiklander {
65*817466cbSJens Wiklander     return( type == MBEDTLS_PK_RSA ||
66*817466cbSJens Wiklander             type == MBEDTLS_PK_RSASSA_PSS );
67*817466cbSJens Wiklander }
68*817466cbSJens Wiklander 
69*817466cbSJens Wiklander static size_t rsa_get_bitlen( const void *ctx )
70*817466cbSJens Wiklander {
71*817466cbSJens Wiklander     return( 8 * ((const mbedtls_rsa_context *) ctx)->len );
72*817466cbSJens Wiklander }
73*817466cbSJens Wiklander 
74*817466cbSJens Wiklander static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
75*817466cbSJens Wiklander                    const unsigned char *hash, size_t hash_len,
76*817466cbSJens Wiklander                    const unsigned char *sig, size_t sig_len )
77*817466cbSJens Wiklander {
78*817466cbSJens Wiklander     int ret;
79*817466cbSJens Wiklander 
80*817466cbSJens Wiklander #if defined(MBEDTLS_HAVE_INT64)
81*817466cbSJens Wiklander     if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
82*817466cbSJens Wiklander         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
83*817466cbSJens Wiklander #endif /* MBEDTLS_HAVE_INT64 */
84*817466cbSJens Wiklander 
85*817466cbSJens Wiklander     if( sig_len < ((mbedtls_rsa_context *) ctx)->len )
86*817466cbSJens Wiklander         return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
87*817466cbSJens Wiklander 
88*817466cbSJens Wiklander     if( ( ret = mbedtls_rsa_pkcs1_verify( (mbedtls_rsa_context *) ctx, NULL, NULL,
89*817466cbSJens Wiklander                                   MBEDTLS_RSA_PUBLIC, md_alg,
90*817466cbSJens Wiklander                                   (unsigned int) hash_len, hash, sig ) ) != 0 )
91*817466cbSJens Wiklander         return( ret );
92*817466cbSJens Wiklander 
93*817466cbSJens Wiklander     if( sig_len > ((mbedtls_rsa_context *) ctx)->len )
94*817466cbSJens Wiklander         return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
95*817466cbSJens Wiklander 
96*817466cbSJens Wiklander     return( 0 );
97*817466cbSJens Wiklander }
98*817466cbSJens Wiklander 
99*817466cbSJens Wiklander static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
100*817466cbSJens Wiklander                    const unsigned char *hash, size_t hash_len,
101*817466cbSJens Wiklander                    unsigned char *sig, size_t *sig_len,
102*817466cbSJens Wiklander                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
103*817466cbSJens Wiklander {
104*817466cbSJens Wiklander #if defined(MBEDTLS_HAVE_INT64)
105*817466cbSJens Wiklander     if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
106*817466cbSJens Wiklander         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
107*817466cbSJens Wiklander #endif /* MBEDTLS_HAVE_INT64 */
108*817466cbSJens Wiklander 
109*817466cbSJens Wiklander     *sig_len = ((mbedtls_rsa_context *) ctx)->len;
110*817466cbSJens Wiklander 
111*817466cbSJens Wiklander     return( mbedtls_rsa_pkcs1_sign( (mbedtls_rsa_context *) ctx, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
112*817466cbSJens Wiklander                 md_alg, (unsigned int) hash_len, hash, sig ) );
113*817466cbSJens Wiklander }
114*817466cbSJens Wiklander 
115*817466cbSJens Wiklander static int rsa_decrypt_wrap( void *ctx,
116*817466cbSJens Wiklander                     const unsigned char *input, size_t ilen,
117*817466cbSJens Wiklander                     unsigned char *output, size_t *olen, size_t osize,
118*817466cbSJens Wiklander                     int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
119*817466cbSJens Wiklander {
120*817466cbSJens Wiklander     if( ilen != ((mbedtls_rsa_context *) ctx)->len )
121*817466cbSJens Wiklander         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
122*817466cbSJens Wiklander 
123*817466cbSJens Wiklander     return( mbedtls_rsa_pkcs1_decrypt( (mbedtls_rsa_context *) ctx, f_rng, p_rng,
124*817466cbSJens Wiklander                 MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
125*817466cbSJens Wiklander }
126*817466cbSJens Wiklander 
127*817466cbSJens Wiklander static int rsa_encrypt_wrap( void *ctx,
128*817466cbSJens Wiklander                     const unsigned char *input, size_t ilen,
129*817466cbSJens Wiklander                     unsigned char *output, size_t *olen, size_t osize,
130*817466cbSJens Wiklander                     int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
131*817466cbSJens Wiklander {
132*817466cbSJens Wiklander     *olen = ((mbedtls_rsa_context *) ctx)->len;
133*817466cbSJens Wiklander 
134*817466cbSJens Wiklander     if( *olen > osize )
135*817466cbSJens Wiklander         return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE );
136*817466cbSJens Wiklander 
137*817466cbSJens Wiklander     return( mbedtls_rsa_pkcs1_encrypt( (mbedtls_rsa_context *) ctx,
138*817466cbSJens Wiklander                 f_rng, p_rng, MBEDTLS_RSA_PUBLIC, ilen, input, output ) );
139*817466cbSJens Wiklander }
140*817466cbSJens Wiklander 
141*817466cbSJens Wiklander static int rsa_check_pair_wrap( const void *pub, const void *prv )
142*817466cbSJens Wiklander {
143*817466cbSJens Wiklander     return( mbedtls_rsa_check_pub_priv( (const mbedtls_rsa_context *) pub,
144*817466cbSJens Wiklander                                 (const mbedtls_rsa_context *) prv ) );
145*817466cbSJens Wiklander }
146*817466cbSJens Wiklander 
147*817466cbSJens Wiklander static void *rsa_alloc_wrap( void )
148*817466cbSJens Wiklander {
149*817466cbSJens Wiklander     void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_context ) );
150*817466cbSJens Wiklander 
151*817466cbSJens Wiklander     if( ctx != NULL )
152*817466cbSJens Wiklander         mbedtls_rsa_init( (mbedtls_rsa_context *) ctx, 0, 0 );
153*817466cbSJens Wiklander 
154*817466cbSJens Wiklander     return( ctx );
155*817466cbSJens Wiklander }
156*817466cbSJens Wiklander 
157*817466cbSJens Wiklander static void rsa_free_wrap( void *ctx )
158*817466cbSJens Wiklander {
159*817466cbSJens Wiklander     mbedtls_rsa_free( (mbedtls_rsa_context *) ctx );
160*817466cbSJens Wiklander     mbedtls_free( ctx );
161*817466cbSJens Wiklander }
162*817466cbSJens Wiklander 
163*817466cbSJens Wiklander static void rsa_debug( const void *ctx, mbedtls_pk_debug_item *items )
164*817466cbSJens Wiklander {
165*817466cbSJens Wiklander     items->type = MBEDTLS_PK_DEBUG_MPI;
166*817466cbSJens Wiklander     items->name = "rsa.N";
167*817466cbSJens Wiklander     items->value = &( ((mbedtls_rsa_context *) ctx)->N );
168*817466cbSJens Wiklander 
169*817466cbSJens Wiklander     items++;
170*817466cbSJens Wiklander 
171*817466cbSJens Wiklander     items->type = MBEDTLS_PK_DEBUG_MPI;
172*817466cbSJens Wiklander     items->name = "rsa.E";
173*817466cbSJens Wiklander     items->value = &( ((mbedtls_rsa_context *) ctx)->E );
174*817466cbSJens Wiklander }
175*817466cbSJens Wiklander 
176*817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_rsa_info = {
177*817466cbSJens Wiklander     MBEDTLS_PK_RSA,
178*817466cbSJens Wiklander     "RSA",
179*817466cbSJens Wiklander     rsa_get_bitlen,
180*817466cbSJens Wiklander     rsa_can_do,
181*817466cbSJens Wiklander     rsa_verify_wrap,
182*817466cbSJens Wiklander     rsa_sign_wrap,
183*817466cbSJens Wiklander     rsa_decrypt_wrap,
184*817466cbSJens Wiklander     rsa_encrypt_wrap,
185*817466cbSJens Wiklander     rsa_check_pair_wrap,
186*817466cbSJens Wiklander     rsa_alloc_wrap,
187*817466cbSJens Wiklander     rsa_free_wrap,
188*817466cbSJens Wiklander     rsa_debug,
189*817466cbSJens Wiklander };
190*817466cbSJens Wiklander #endif /* MBEDTLS_RSA_C */
191*817466cbSJens Wiklander 
192*817466cbSJens Wiklander #if defined(MBEDTLS_ECP_C)
193*817466cbSJens Wiklander /*
194*817466cbSJens Wiklander  * Generic EC key
195*817466cbSJens Wiklander  */
196*817466cbSJens Wiklander static int eckey_can_do( mbedtls_pk_type_t type )
197*817466cbSJens Wiklander {
198*817466cbSJens Wiklander     return( type == MBEDTLS_PK_ECKEY ||
199*817466cbSJens Wiklander             type == MBEDTLS_PK_ECKEY_DH ||
200*817466cbSJens Wiklander             type == MBEDTLS_PK_ECDSA );
201*817466cbSJens Wiklander }
202*817466cbSJens Wiklander 
203*817466cbSJens Wiklander static size_t eckey_get_bitlen( const void *ctx )
204*817466cbSJens Wiklander {
205*817466cbSJens Wiklander     return( ((mbedtls_ecp_keypair *) ctx)->grp.pbits );
206*817466cbSJens Wiklander }
207*817466cbSJens Wiklander 
208*817466cbSJens Wiklander #if defined(MBEDTLS_ECDSA_C)
209*817466cbSJens Wiklander /* Forward declarations */
210*817466cbSJens Wiklander static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
211*817466cbSJens Wiklander                        const unsigned char *hash, size_t hash_len,
212*817466cbSJens Wiklander                        const unsigned char *sig, size_t sig_len );
213*817466cbSJens Wiklander 
214*817466cbSJens Wiklander static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
215*817466cbSJens Wiklander                    const unsigned char *hash, size_t hash_len,
216*817466cbSJens Wiklander                    unsigned char *sig, size_t *sig_len,
217*817466cbSJens Wiklander                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
218*817466cbSJens Wiklander 
219*817466cbSJens Wiklander static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
220*817466cbSJens Wiklander                        const unsigned char *hash, size_t hash_len,
221*817466cbSJens Wiklander                        const unsigned char *sig, size_t sig_len )
222*817466cbSJens Wiklander {
223*817466cbSJens Wiklander     int ret;
224*817466cbSJens Wiklander     mbedtls_ecdsa_context ecdsa;
225*817466cbSJens Wiklander 
226*817466cbSJens Wiklander     mbedtls_ecdsa_init( &ecdsa );
227*817466cbSJens Wiklander 
228*817466cbSJens Wiklander     if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
229*817466cbSJens Wiklander         ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len );
230*817466cbSJens Wiklander 
231*817466cbSJens Wiklander     mbedtls_ecdsa_free( &ecdsa );
232*817466cbSJens Wiklander 
233*817466cbSJens Wiklander     return( ret );
234*817466cbSJens Wiklander }
235*817466cbSJens Wiklander 
236*817466cbSJens Wiklander static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
237*817466cbSJens Wiklander                    const unsigned char *hash, size_t hash_len,
238*817466cbSJens Wiklander                    unsigned char *sig, size_t *sig_len,
239*817466cbSJens Wiklander                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
240*817466cbSJens Wiklander {
241*817466cbSJens Wiklander     int ret;
242*817466cbSJens Wiklander     mbedtls_ecdsa_context ecdsa;
243*817466cbSJens Wiklander 
244*817466cbSJens Wiklander     mbedtls_ecdsa_init( &ecdsa );
245*817466cbSJens Wiklander 
246*817466cbSJens Wiklander     if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
247*817466cbSJens Wiklander         ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len,
248*817466cbSJens Wiklander                                f_rng, p_rng );
249*817466cbSJens Wiklander 
250*817466cbSJens Wiklander     mbedtls_ecdsa_free( &ecdsa );
251*817466cbSJens Wiklander 
252*817466cbSJens Wiklander     return( ret );
253*817466cbSJens Wiklander }
254*817466cbSJens Wiklander 
255*817466cbSJens Wiklander #endif /* MBEDTLS_ECDSA_C */
256*817466cbSJens Wiklander 
257*817466cbSJens Wiklander static int eckey_check_pair( const void *pub, const void *prv )
258*817466cbSJens Wiklander {
259*817466cbSJens Wiklander     return( mbedtls_ecp_check_pub_priv( (const mbedtls_ecp_keypair *) pub,
260*817466cbSJens Wiklander                                 (const mbedtls_ecp_keypair *) prv ) );
261*817466cbSJens Wiklander }
262*817466cbSJens Wiklander 
263*817466cbSJens Wiklander static void *eckey_alloc_wrap( void )
264*817466cbSJens Wiklander {
265*817466cbSJens Wiklander     void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
266*817466cbSJens Wiklander 
267*817466cbSJens Wiklander     if( ctx != NULL )
268*817466cbSJens Wiklander         mbedtls_ecp_keypair_init( ctx );
269*817466cbSJens Wiklander 
270*817466cbSJens Wiklander     return( ctx );
271*817466cbSJens Wiklander }
272*817466cbSJens Wiklander 
273*817466cbSJens Wiklander static void eckey_free_wrap( void *ctx )
274*817466cbSJens Wiklander {
275*817466cbSJens Wiklander     mbedtls_ecp_keypair_free( (mbedtls_ecp_keypair *) ctx );
276*817466cbSJens Wiklander     mbedtls_free( ctx );
277*817466cbSJens Wiklander }
278*817466cbSJens Wiklander 
279*817466cbSJens Wiklander static void eckey_debug( const void *ctx, mbedtls_pk_debug_item *items )
280*817466cbSJens Wiklander {
281*817466cbSJens Wiklander     items->type = MBEDTLS_PK_DEBUG_ECP;
282*817466cbSJens Wiklander     items->name = "eckey.Q";
283*817466cbSJens Wiklander     items->value = &( ((mbedtls_ecp_keypair *) ctx)->Q );
284*817466cbSJens Wiklander }
285*817466cbSJens Wiklander 
286*817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_eckey_info = {
287*817466cbSJens Wiklander     MBEDTLS_PK_ECKEY,
288*817466cbSJens Wiklander     "EC",
289*817466cbSJens Wiklander     eckey_get_bitlen,
290*817466cbSJens Wiklander     eckey_can_do,
291*817466cbSJens Wiklander #if defined(MBEDTLS_ECDSA_C)
292*817466cbSJens Wiklander     eckey_verify_wrap,
293*817466cbSJens Wiklander     eckey_sign_wrap,
294*817466cbSJens Wiklander #else
295*817466cbSJens Wiklander     NULL,
296*817466cbSJens Wiklander     NULL,
297*817466cbSJens Wiklander #endif
298*817466cbSJens Wiklander     NULL,
299*817466cbSJens Wiklander     NULL,
300*817466cbSJens Wiklander     eckey_check_pair,
301*817466cbSJens Wiklander     eckey_alloc_wrap,
302*817466cbSJens Wiklander     eckey_free_wrap,
303*817466cbSJens Wiklander     eckey_debug,
304*817466cbSJens Wiklander };
305*817466cbSJens Wiklander 
306*817466cbSJens Wiklander /*
307*817466cbSJens Wiklander  * EC key restricted to ECDH
308*817466cbSJens Wiklander  */
309*817466cbSJens Wiklander static int eckeydh_can_do( mbedtls_pk_type_t type )
310*817466cbSJens Wiklander {
311*817466cbSJens Wiklander     return( type == MBEDTLS_PK_ECKEY ||
312*817466cbSJens Wiklander             type == MBEDTLS_PK_ECKEY_DH );
313*817466cbSJens Wiklander }
314*817466cbSJens Wiklander 
315*817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_eckeydh_info = {
316*817466cbSJens Wiklander     MBEDTLS_PK_ECKEY_DH,
317*817466cbSJens Wiklander     "EC_DH",
318*817466cbSJens Wiklander     eckey_get_bitlen,         /* Same underlying key structure */
319*817466cbSJens Wiklander     eckeydh_can_do,
320*817466cbSJens Wiklander     NULL,
321*817466cbSJens Wiklander     NULL,
322*817466cbSJens Wiklander     NULL,
323*817466cbSJens Wiklander     NULL,
324*817466cbSJens Wiklander     eckey_check_pair,
325*817466cbSJens Wiklander     eckey_alloc_wrap,       /* Same underlying key structure */
326*817466cbSJens Wiklander     eckey_free_wrap,        /* Same underlying key structure */
327*817466cbSJens Wiklander     eckey_debug,            /* Same underlying key structure */
328*817466cbSJens Wiklander };
329*817466cbSJens Wiklander #endif /* MBEDTLS_ECP_C */
330*817466cbSJens Wiklander 
331*817466cbSJens Wiklander #if defined(MBEDTLS_ECDSA_C)
332*817466cbSJens Wiklander static int ecdsa_can_do( mbedtls_pk_type_t type )
333*817466cbSJens Wiklander {
334*817466cbSJens Wiklander     return( type == MBEDTLS_PK_ECDSA );
335*817466cbSJens Wiklander }
336*817466cbSJens Wiklander 
337*817466cbSJens Wiklander static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
338*817466cbSJens Wiklander                        const unsigned char *hash, size_t hash_len,
339*817466cbSJens Wiklander                        const unsigned char *sig, size_t sig_len )
340*817466cbSJens Wiklander {
341*817466cbSJens Wiklander     int ret;
342*817466cbSJens Wiklander     ((void) md_alg);
343*817466cbSJens Wiklander 
344*817466cbSJens Wiklander     ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx,
345*817466cbSJens Wiklander                                 hash, hash_len, sig, sig_len );
346*817466cbSJens Wiklander 
347*817466cbSJens Wiklander     if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )
348*817466cbSJens Wiklander         return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
349*817466cbSJens Wiklander 
350*817466cbSJens Wiklander     return( ret );
351*817466cbSJens Wiklander }
352*817466cbSJens Wiklander 
353*817466cbSJens Wiklander static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
354*817466cbSJens Wiklander                    const unsigned char *hash, size_t hash_len,
355*817466cbSJens Wiklander                    unsigned char *sig, size_t *sig_len,
356*817466cbSJens Wiklander                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
357*817466cbSJens Wiklander {
358*817466cbSJens Wiklander     return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx,
359*817466cbSJens Wiklander                 md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) );
360*817466cbSJens Wiklander }
361*817466cbSJens Wiklander 
362*817466cbSJens Wiklander static void *ecdsa_alloc_wrap( void )
363*817466cbSJens Wiklander {
364*817466cbSJens Wiklander     void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) );
365*817466cbSJens Wiklander 
366*817466cbSJens Wiklander     if( ctx != NULL )
367*817466cbSJens Wiklander         mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx );
368*817466cbSJens Wiklander 
369*817466cbSJens Wiklander     return( ctx );
370*817466cbSJens Wiklander }
371*817466cbSJens Wiklander 
372*817466cbSJens Wiklander static void ecdsa_free_wrap( void *ctx )
373*817466cbSJens Wiklander {
374*817466cbSJens Wiklander     mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx );
375*817466cbSJens Wiklander     mbedtls_free( ctx );
376*817466cbSJens Wiklander }
377*817466cbSJens Wiklander 
378*817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_ecdsa_info = {
379*817466cbSJens Wiklander     MBEDTLS_PK_ECDSA,
380*817466cbSJens Wiklander     "ECDSA",
381*817466cbSJens Wiklander     eckey_get_bitlen,     /* Compatible key structures */
382*817466cbSJens Wiklander     ecdsa_can_do,
383*817466cbSJens Wiklander     ecdsa_verify_wrap,
384*817466cbSJens Wiklander     ecdsa_sign_wrap,
385*817466cbSJens Wiklander     NULL,
386*817466cbSJens Wiklander     NULL,
387*817466cbSJens Wiklander     eckey_check_pair,   /* Compatible key structures */
388*817466cbSJens Wiklander     ecdsa_alloc_wrap,
389*817466cbSJens Wiklander     ecdsa_free_wrap,
390*817466cbSJens Wiklander     eckey_debug,        /* Compatible key structures */
391*817466cbSJens Wiklander };
392*817466cbSJens Wiklander #endif /* MBEDTLS_ECDSA_C */
393*817466cbSJens Wiklander 
394*817466cbSJens Wiklander #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
395*817466cbSJens Wiklander /*
396*817466cbSJens Wiklander  * Support for alternative RSA-private implementations
397*817466cbSJens Wiklander  */
398*817466cbSJens Wiklander 
399*817466cbSJens Wiklander static int rsa_alt_can_do( mbedtls_pk_type_t type )
400*817466cbSJens Wiklander {
401*817466cbSJens Wiklander     return( type == MBEDTLS_PK_RSA );
402*817466cbSJens Wiklander }
403*817466cbSJens Wiklander 
404*817466cbSJens Wiklander static size_t rsa_alt_get_bitlen( const void *ctx )
405*817466cbSJens Wiklander {
406*817466cbSJens Wiklander     const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx;
407*817466cbSJens Wiklander 
408*817466cbSJens Wiklander     return( 8 * rsa_alt->key_len_func( rsa_alt->key ) );
409*817466cbSJens Wiklander }
410*817466cbSJens Wiklander 
411*817466cbSJens Wiklander static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
412*817466cbSJens Wiklander                    const unsigned char *hash, size_t hash_len,
413*817466cbSJens Wiklander                    unsigned char *sig, size_t *sig_len,
414*817466cbSJens Wiklander                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
415*817466cbSJens Wiklander {
416*817466cbSJens Wiklander     mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
417*817466cbSJens Wiklander 
418*817466cbSJens Wiklander #if defined(MBEDTLS_HAVE_INT64)
419*817466cbSJens Wiklander     if( UINT_MAX < hash_len )
420*817466cbSJens Wiklander         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
421*817466cbSJens Wiklander #endif /* MBEDTLS_HAVE_INT64 */
422*817466cbSJens Wiklander 
423*817466cbSJens Wiklander     *sig_len = rsa_alt->key_len_func( rsa_alt->key );
424*817466cbSJens Wiklander 
425*817466cbSJens Wiklander     return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
426*817466cbSJens Wiklander                 md_alg, (unsigned int) hash_len, hash, sig ) );
427*817466cbSJens Wiklander }
428*817466cbSJens Wiklander 
429*817466cbSJens Wiklander static int rsa_alt_decrypt_wrap( void *ctx,
430*817466cbSJens Wiklander                     const unsigned char *input, size_t ilen,
431*817466cbSJens Wiklander                     unsigned char *output, size_t *olen, size_t osize,
432*817466cbSJens Wiklander                     int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
433*817466cbSJens Wiklander {
434*817466cbSJens Wiklander     mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
435*817466cbSJens Wiklander 
436*817466cbSJens Wiklander     ((void) f_rng);
437*817466cbSJens Wiklander     ((void) p_rng);
438*817466cbSJens Wiklander 
439*817466cbSJens Wiklander     if( ilen != rsa_alt->key_len_func( rsa_alt->key ) )
440*817466cbSJens Wiklander         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
441*817466cbSJens Wiklander 
442*817466cbSJens Wiklander     return( rsa_alt->decrypt_func( rsa_alt->key,
443*817466cbSJens Wiklander                 MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
444*817466cbSJens Wiklander }
445*817466cbSJens Wiklander 
446*817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C)
447*817466cbSJens Wiklander static int rsa_alt_check_pair( const void *pub, const void *prv )
448*817466cbSJens Wiklander {
449*817466cbSJens Wiklander     unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
450*817466cbSJens Wiklander     unsigned char hash[32];
451*817466cbSJens Wiklander     size_t sig_len = 0;
452*817466cbSJens Wiklander     int ret;
453*817466cbSJens Wiklander 
454*817466cbSJens Wiklander     if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) )
455*817466cbSJens Wiklander         return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
456*817466cbSJens Wiklander 
457*817466cbSJens Wiklander     memset( hash, 0x2a, sizeof( hash ) );
458*817466cbSJens Wiklander 
459*817466cbSJens Wiklander     if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE,
460*817466cbSJens Wiklander                                    hash, sizeof( hash ),
461*817466cbSJens Wiklander                                    sig, &sig_len, NULL, NULL ) ) != 0 )
462*817466cbSJens Wiklander     {
463*817466cbSJens Wiklander         return( ret );
464*817466cbSJens Wiklander     }
465*817466cbSJens Wiklander 
466*817466cbSJens Wiklander     if( rsa_verify_wrap( (void *) pub, MBEDTLS_MD_NONE,
467*817466cbSJens Wiklander                          hash, sizeof( hash ), sig, sig_len ) != 0 )
468*817466cbSJens Wiklander     {
469*817466cbSJens Wiklander         return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
470*817466cbSJens Wiklander     }
471*817466cbSJens Wiklander 
472*817466cbSJens Wiklander     return( 0 );
473*817466cbSJens Wiklander }
474*817466cbSJens Wiklander #endif /* MBEDTLS_RSA_C */
475*817466cbSJens Wiklander 
476*817466cbSJens Wiklander static void *rsa_alt_alloc_wrap( void )
477*817466cbSJens Wiklander {
478*817466cbSJens Wiklander     void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context ) );
479*817466cbSJens Wiklander 
480*817466cbSJens Wiklander     if( ctx != NULL )
481*817466cbSJens Wiklander         memset( ctx, 0, sizeof( mbedtls_rsa_alt_context ) );
482*817466cbSJens Wiklander 
483*817466cbSJens Wiklander     return( ctx );
484*817466cbSJens Wiklander }
485*817466cbSJens Wiklander 
486*817466cbSJens Wiklander static void rsa_alt_free_wrap( void *ctx )
487*817466cbSJens Wiklander {
488*817466cbSJens Wiklander     mbedtls_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) );
489*817466cbSJens Wiklander     mbedtls_free( ctx );
490*817466cbSJens Wiklander }
491*817466cbSJens Wiklander 
492*817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
493*817466cbSJens Wiklander     MBEDTLS_PK_RSA_ALT,
494*817466cbSJens Wiklander     "RSA-alt",
495*817466cbSJens Wiklander     rsa_alt_get_bitlen,
496*817466cbSJens Wiklander     rsa_alt_can_do,
497*817466cbSJens Wiklander     NULL,
498*817466cbSJens Wiklander     rsa_alt_sign_wrap,
499*817466cbSJens Wiklander     rsa_alt_decrypt_wrap,
500*817466cbSJens Wiklander     NULL,
501*817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C)
502*817466cbSJens Wiklander     rsa_alt_check_pair,
503*817466cbSJens Wiklander #else
504*817466cbSJens Wiklander     NULL,
505*817466cbSJens Wiklander #endif
506*817466cbSJens Wiklander     rsa_alt_alloc_wrap,
507*817466cbSJens Wiklander     rsa_alt_free_wrap,
508*817466cbSJens Wiklander     NULL,
509*817466cbSJens Wiklander };
510*817466cbSJens Wiklander 
511*817466cbSJens Wiklander #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
512*817466cbSJens Wiklander 
513*817466cbSJens Wiklander #endif /* MBEDTLS_PK_C */
514