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