xref: /reactos/dll/3rdparty/mbedtls/pk.c (revision c2c66aff)
1 /*
2  *  Public Key abstraction layer
3  *
4  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5  *  SPDX-License-Identifier: GPL-2.0
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License along
18  *  with this program; if not, write to the Free Software Foundation, Inc.,
19  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  *  This file is part of mbed TLS (https://tls.mbed.org)
22  */
23 
24 #if !defined(MBEDTLS_CONFIG_FILE)
25 #include "mbedtls/config.h"
26 #else
27 #include MBEDTLS_CONFIG_FILE
28 #endif
29 
30 #if defined(MBEDTLS_PK_C)
31 #include "mbedtls/pk.h"
32 #include "mbedtls/pk_internal.h"
33 
34 #include "mbedtls/bignum.h"
35 
36 #if defined(MBEDTLS_RSA_C)
37 #include "mbedtls/rsa.h"
38 #endif
39 #if defined(MBEDTLS_ECP_C)
40 #include "mbedtls/ecp.h"
41 #endif
42 #if defined(MBEDTLS_ECDSA_C)
43 #include "mbedtls/ecdsa.h"
44 #endif
45 
46 #include <limits.h>
47 
48 /* Implementation that should never be optimized out by the compiler */
49 static void mbedtls_zeroize( void *v, size_t n ) {
50     volatile unsigned char *p = v; while( n-- ) *p++ = 0;
51 }
52 
53 /*
54  * Initialise a mbedtls_pk_context
55  */
56 void mbedtls_pk_init( mbedtls_pk_context *ctx )
57 {
58     if( ctx == NULL )
59         return;
60 
61     ctx->pk_info = NULL;
62     ctx->pk_ctx = NULL;
63 }
64 
65 /*
66  * Free (the components of) a mbedtls_pk_context
67  */
68 void mbedtls_pk_free( mbedtls_pk_context *ctx )
69 {
70     if( ctx == NULL || ctx->pk_info == NULL )
71         return;
72 
73     ctx->pk_info->ctx_free_func( ctx->pk_ctx );
74 
75     mbedtls_zeroize( ctx, sizeof( mbedtls_pk_context ) );
76 }
77 
78 /*
79  * Get pk_info structure from type
80  */
81 const mbedtls_pk_info_t * mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type )
82 {
83     switch( pk_type ) {
84 #if defined(MBEDTLS_RSA_C)
85         case MBEDTLS_PK_RSA:
86             return( &mbedtls_rsa_info );
87 #endif
88 #if defined(MBEDTLS_ECP_C)
89         case MBEDTLS_PK_ECKEY:
90             return( &mbedtls_eckey_info );
91         case MBEDTLS_PK_ECKEY_DH:
92             return( &mbedtls_eckeydh_info );
93 #endif
94 #if defined(MBEDTLS_ECDSA_C)
95         case MBEDTLS_PK_ECDSA:
96             return( &mbedtls_ecdsa_info );
97 #endif
98         /* MBEDTLS_PK_RSA_ALT omitted on purpose */
99         default:
100             return( NULL );
101     }
102 }
103 
104 /*
105  * Initialise context
106  */
107 int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info )
108 {
109     if( ctx == NULL || info == NULL || ctx->pk_info != NULL )
110         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
111 
112     if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
113         return( MBEDTLS_ERR_PK_ALLOC_FAILED );
114 
115     ctx->pk_info = info;
116 
117     return( 0 );
118 }
119 
120 #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
121 /*
122  * Initialize an RSA-alt context
123  */
124 int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key,
125                          mbedtls_pk_rsa_alt_decrypt_func decrypt_func,
126                          mbedtls_pk_rsa_alt_sign_func sign_func,
127                          mbedtls_pk_rsa_alt_key_len_func key_len_func )
128 {
129     mbedtls_rsa_alt_context *rsa_alt;
130     const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info;
131 
132     if( ctx == NULL || ctx->pk_info != NULL )
133         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
134 
135     if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
136         return( MBEDTLS_ERR_PK_ALLOC_FAILED );
137 
138     ctx->pk_info = info;
139 
140     rsa_alt = (mbedtls_rsa_alt_context *) ctx->pk_ctx;
141 
142     rsa_alt->key = key;
143     rsa_alt->decrypt_func = decrypt_func;
144     rsa_alt->sign_func = sign_func;
145     rsa_alt->key_len_func = key_len_func;
146 
147     return( 0 );
148 }
149 #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
150 
151 /*
152  * Tell if a PK can do the operations of the given type
153  */
154 int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type )
155 {
156     /* null or NONE context can't do anything */
157     if( ctx == NULL || ctx->pk_info == NULL )
158         return( 0 );
159 
160     return( ctx->pk_info->can_do( type ) );
161 }
162 
163 /*
164  * Helper for mbedtls_pk_sign and mbedtls_pk_verify
165  */
166 static inline int pk_hashlen_helper( mbedtls_md_type_t md_alg, size_t *hash_len )
167 {
168     const mbedtls_md_info_t *md_info;
169 
170     if( *hash_len != 0 )
171         return( 0 );
172 
173     if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL )
174         return( -1 );
175 
176     *hash_len = mbedtls_md_get_size( md_info );
177     return( 0 );
178 }
179 
180 /*
181  * Verify a signature
182  */
183 int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
184                const unsigned char *hash, size_t hash_len,
185                const unsigned char *sig, size_t sig_len )
186 {
187     if( ctx == NULL || ctx->pk_info == NULL ||
188         pk_hashlen_helper( md_alg, &hash_len ) != 0 )
189         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
190 
191     if( ctx->pk_info->verify_func == NULL )
192         return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
193 
194     return( ctx->pk_info->verify_func( ctx->pk_ctx, md_alg, hash, hash_len,
195                                        sig, sig_len ) );
196 }
197 
198 /*
199  * Verify a signature with options
200  */
201 int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
202                    mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
203                    const unsigned char *hash, size_t hash_len,
204                    const unsigned char *sig, size_t sig_len )
205 {
206     if( ctx == NULL || ctx->pk_info == NULL )
207         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
208 
209     if( ! mbedtls_pk_can_do( ctx, type ) )
210         return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
211 
212     if( type == MBEDTLS_PK_RSASSA_PSS )
213     {
214 #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
215         int ret;
216         const mbedtls_pk_rsassa_pss_options *pss_opts;
217 
218 #if defined(MBEDTLS_HAVE_INT64)
219         if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
220             return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
221 #endif /* MBEDTLS_HAVE_INT64 */
222 
223         if( options == NULL )
224             return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
225 
226         pss_opts = (const mbedtls_pk_rsassa_pss_options *) options;
227 
228         if( sig_len < mbedtls_pk_get_len( ctx ) )
229             return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
230 
231         ret = mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_pk_rsa( *ctx ),
232                 NULL, NULL, MBEDTLS_RSA_PUBLIC,
233                 md_alg, (unsigned int) hash_len, hash,
234                 pss_opts->mgf1_hash_id,
235                 pss_opts->expected_salt_len,
236                 sig );
237         if( ret != 0 )
238             return( ret );
239 
240         if( sig_len > mbedtls_pk_get_len( ctx ) )
241             return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
242 
243         return( 0 );
244 #else
245         return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
246 #endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */
247     }
248 
249     /* General case: no options */
250     if( options != NULL )
251         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
252 
253     return( mbedtls_pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) );
254 }
255 
256 /*
257  * Make a signature
258  */
259 int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
260              const unsigned char *hash, size_t hash_len,
261              unsigned char *sig, size_t *sig_len,
262              int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
263 {
264     if( ctx == NULL || ctx->pk_info == NULL ||
265         pk_hashlen_helper( md_alg, &hash_len ) != 0 )
266         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
267 
268     if( ctx->pk_info->sign_func == NULL )
269         return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
270 
271     return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg, hash, hash_len,
272                                      sig, sig_len, f_rng, p_rng ) );
273 }
274 
275 /*
276  * Decrypt message
277  */
278 int mbedtls_pk_decrypt( mbedtls_pk_context *ctx,
279                 const unsigned char *input, size_t ilen,
280                 unsigned char *output, size_t *olen, size_t osize,
281                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
282 {
283     if( ctx == NULL || ctx->pk_info == NULL )
284         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
285 
286     if( ctx->pk_info->decrypt_func == NULL )
287         return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
288 
289     return( ctx->pk_info->decrypt_func( ctx->pk_ctx, input, ilen,
290                 output, olen, osize, f_rng, p_rng ) );
291 }
292 
293 /*
294  * Encrypt message
295  */
296 int mbedtls_pk_encrypt( mbedtls_pk_context *ctx,
297                 const unsigned char *input, size_t ilen,
298                 unsigned char *output, size_t *olen, size_t osize,
299                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
300 {
301     if( ctx == NULL || ctx->pk_info == NULL )
302         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
303 
304     if( ctx->pk_info->encrypt_func == NULL )
305         return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
306 
307     return( ctx->pk_info->encrypt_func( ctx->pk_ctx, input, ilen,
308                 output, olen, osize, f_rng, p_rng ) );
309 }
310 
311 /*
312  * Check public-private key pair
313  */
314 int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv )
315 {
316     if( pub == NULL || pub->pk_info == NULL ||
317         prv == NULL || prv->pk_info == NULL ||
318         prv->pk_info->check_pair_func == NULL )
319     {
320         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
321     }
322 
323     if( prv->pk_info->type == MBEDTLS_PK_RSA_ALT )
324     {
325         if( pub->pk_info->type != MBEDTLS_PK_RSA )
326             return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
327     }
328     else
329     {
330         if( pub->pk_info != prv->pk_info )
331             return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
332     }
333 
334     return( prv->pk_info->check_pair_func( pub->pk_ctx, prv->pk_ctx ) );
335 }
336 
337 /*
338  * Get key size in bits
339  */
340 size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx )
341 {
342     if( ctx == NULL || ctx->pk_info == NULL )
343         return( 0 );
344 
345     return( ctx->pk_info->get_bitlen( ctx->pk_ctx ) );
346 }
347 
348 /*
349  * Export debug information
350  */
351 int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items )
352 {
353     if( ctx == NULL || ctx->pk_info == NULL )
354         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
355 
356     if( ctx->pk_info->debug_func == NULL )
357         return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
358 
359     ctx->pk_info->debug_func( ctx->pk_ctx, items );
360     return( 0 );
361 }
362 
363 /*
364  * Access the PK type name
365  */
366 const char *mbedtls_pk_get_name( const mbedtls_pk_context *ctx )
367 {
368     if( ctx == NULL || ctx->pk_info == NULL )
369         return( "invalid PK" );
370 
371     return( ctx->pk_info->name );
372 }
373 
374 /*
375  * Access the PK type
376  */
377 mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx )
378 {
379     if( ctx == NULL || ctx->pk_info == NULL )
380         return( MBEDTLS_PK_NONE );
381 
382     return( ctx->pk_info->type );
383 }
384 
385 #endif /* MBEDTLS_PK_C */
386