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