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