xref: /reactos/dll/3rdparty/mbedtls/pk_wrap.c (revision d7fd62d4)
1 /*
2  *  Public Key abstraction layer: wrapper functions
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_internal.h"
57 
58 /* Even if RSA not activated, for the sake of RSA-alt */
59 #include "mbedtls/rsa.h"
60 
61 #include <string.h>
62 
63 #if defined(MBEDTLS_ECP_C)
64 #include "mbedtls/ecp.h"
65 #endif
66 
67 #if defined(MBEDTLS_ECDSA_C)
68 #include "mbedtls/ecdsa.h"
69 #endif
70 
71 #if defined(MBEDTLS_PLATFORM_C)
72 #include "mbedtls/platform.h"
73 #else
74 #include <stdlib.h>
75 #define mbedtls_calloc    calloc
76 #define mbedtls_free       free
77 #endif
78 
79 #include <limits.h>
80 #include <stdint.h>
81 
82 #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
83 /* Implementation that should never be optimized out by the compiler */
84 static void mbedtls_zeroize( void *v, size_t n ) {
85     volatile unsigned char *p = v; while( n-- ) *p++ = 0;
86 }
87 #endif
88 
89 #if defined(MBEDTLS_RSA_C)
90 static int rsa_can_do( mbedtls_pk_type_t type )
91 {
92     return( type == MBEDTLS_PK_RSA ||
93             type == MBEDTLS_PK_RSASSA_PSS );
94 }
95 
96 static size_t rsa_get_bitlen( const void *ctx )
97 {
98     const mbedtls_rsa_context * rsa = (const mbedtls_rsa_context *) ctx;
99     return( 8 * mbedtls_rsa_get_len( rsa ) );
100 }
101 
102 static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
103                    const unsigned char *hash, size_t hash_len,
104                    const unsigned char *sig, size_t sig_len )
105 {
106     int ret;
107     mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
108     size_t rsa_len = mbedtls_rsa_get_len( rsa );
109 
110 #if SIZE_MAX > UINT_MAX
111     if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
112         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
113 #endif /* SIZE_MAX > UINT_MAX */
114 
115     if( sig_len < rsa_len )
116         return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
117 
118     if( ( ret = mbedtls_rsa_pkcs1_verify( rsa, NULL, NULL,
119                                   MBEDTLS_RSA_PUBLIC, md_alg,
120                                   (unsigned int) hash_len, hash, sig ) ) != 0 )
121         return( ret );
122 
123     /* The buffer contains a valid signature followed by extra data.
124      * We have a special error code for that so that so that callers can
125      * use mbedtls_pk_verify() to check "Does the buffer start with a
126      * valid signature?" and not just "Does the buffer contain a valid
127      * signature?". */
128     if( sig_len > rsa_len )
129         return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
130 
131     return( 0 );
132 }
133 
134 static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
135                    const unsigned char *hash, size_t hash_len,
136                    unsigned char *sig, size_t *sig_len,
137                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
138 {
139     mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
140 
141 #if SIZE_MAX > UINT_MAX
142     if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
143         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
144 #endif /* SIZE_MAX > UINT_MAX */
145 
146     *sig_len = mbedtls_rsa_get_len( rsa );
147 
148     return( mbedtls_rsa_pkcs1_sign( rsa, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
149                 md_alg, (unsigned int) hash_len, hash, sig ) );
150 }
151 
152 static int rsa_decrypt_wrap( void *ctx,
153                     const unsigned char *input, size_t ilen,
154                     unsigned char *output, size_t *olen, size_t osize,
155                     int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
156 {
157     mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
158 
159     if( ilen != mbedtls_rsa_get_len( rsa ) )
160         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
161 
162     return( mbedtls_rsa_pkcs1_decrypt( rsa, f_rng, p_rng,
163                 MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
164 }
165 
166 static int rsa_encrypt_wrap( void *ctx,
167                     const unsigned char *input, size_t ilen,
168                     unsigned char *output, size_t *olen, size_t osize,
169                     int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
170 {
171     mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
172     *olen = mbedtls_rsa_get_len( rsa );
173 
174     if( *olen > osize )
175         return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE );
176 
177     return( mbedtls_rsa_pkcs1_encrypt( rsa, f_rng, p_rng, MBEDTLS_RSA_PUBLIC,
178                                        ilen, input, output ) );
179 }
180 
181 static int rsa_check_pair_wrap( const void *pub, const void *prv )
182 {
183     return( mbedtls_rsa_check_pub_priv( (const mbedtls_rsa_context *) pub,
184                                 (const mbedtls_rsa_context *) prv ) );
185 }
186 
187 static void *rsa_alloc_wrap( void )
188 {
189     void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_context ) );
190 
191     if( ctx != NULL )
192         mbedtls_rsa_init( (mbedtls_rsa_context *) ctx, 0, 0 );
193 
194     return( ctx );
195 }
196 
197 static void rsa_free_wrap( void *ctx )
198 {
199     mbedtls_rsa_free( (mbedtls_rsa_context *) ctx );
200     mbedtls_free( ctx );
201 }
202 
203 static void rsa_debug( const void *ctx, mbedtls_pk_debug_item *items )
204 {
205     items->type = MBEDTLS_PK_DEBUG_MPI;
206     items->name = "rsa.N";
207     items->value = &( ((mbedtls_rsa_context *) ctx)->N );
208 
209     items++;
210 
211     items->type = MBEDTLS_PK_DEBUG_MPI;
212     items->name = "rsa.E";
213     items->value = &( ((mbedtls_rsa_context *) ctx)->E );
214 }
215 
216 const mbedtls_pk_info_t mbedtls_rsa_info = {
217     MBEDTLS_PK_RSA,
218     "RSA",
219     rsa_get_bitlen,
220     rsa_can_do,
221     rsa_verify_wrap,
222     rsa_sign_wrap,
223     rsa_decrypt_wrap,
224     rsa_encrypt_wrap,
225     rsa_check_pair_wrap,
226     rsa_alloc_wrap,
227     rsa_free_wrap,
228     rsa_debug,
229 };
230 #endif /* MBEDTLS_RSA_C */
231 
232 #if defined(MBEDTLS_ECP_C)
233 /*
234  * Generic EC key
235  */
236 static int eckey_can_do( mbedtls_pk_type_t type )
237 {
238     return( type == MBEDTLS_PK_ECKEY ||
239             type == MBEDTLS_PK_ECKEY_DH ||
240             type == MBEDTLS_PK_ECDSA );
241 }
242 
243 static size_t eckey_get_bitlen( const void *ctx )
244 {
245     return( ((mbedtls_ecp_keypair *) ctx)->grp.pbits );
246 }
247 
248 #if defined(MBEDTLS_ECDSA_C)
249 /* Forward declarations */
250 static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
251                        const unsigned char *hash, size_t hash_len,
252                        const unsigned char *sig, size_t sig_len );
253 
254 static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
255                    const unsigned char *hash, size_t hash_len,
256                    unsigned char *sig, size_t *sig_len,
257                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
258 
259 static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
260                        const unsigned char *hash, size_t hash_len,
261                        const unsigned char *sig, size_t sig_len )
262 {
263     int ret;
264     mbedtls_ecdsa_context ecdsa;
265 
266     mbedtls_ecdsa_init( &ecdsa );
267 
268     if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
269         ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len );
270 
271     mbedtls_ecdsa_free( &ecdsa );
272 
273     return( ret );
274 }
275 
276 static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
277                    const unsigned char *hash, size_t hash_len,
278                    unsigned char *sig, size_t *sig_len,
279                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
280 {
281     int ret;
282     mbedtls_ecdsa_context ecdsa;
283 
284     mbedtls_ecdsa_init( &ecdsa );
285 
286     if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
287         ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len,
288                                f_rng, p_rng );
289 
290     mbedtls_ecdsa_free( &ecdsa );
291 
292     return( ret );
293 }
294 
295 #endif /* MBEDTLS_ECDSA_C */
296 
297 static int eckey_check_pair( const void *pub, const void *prv )
298 {
299     return( mbedtls_ecp_check_pub_priv( (const mbedtls_ecp_keypair *) pub,
300                                 (const mbedtls_ecp_keypair *) prv ) );
301 }
302 
303 static void *eckey_alloc_wrap( void )
304 {
305     void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
306 
307     if( ctx != NULL )
308         mbedtls_ecp_keypair_init( ctx );
309 
310     return( ctx );
311 }
312 
313 static void eckey_free_wrap( void *ctx )
314 {
315     mbedtls_ecp_keypair_free( (mbedtls_ecp_keypair *) ctx );
316     mbedtls_free( ctx );
317 }
318 
319 static void eckey_debug( const void *ctx, mbedtls_pk_debug_item *items )
320 {
321     items->type = MBEDTLS_PK_DEBUG_ECP;
322     items->name = "eckey.Q";
323     items->value = &( ((mbedtls_ecp_keypair *) ctx)->Q );
324 }
325 
326 const mbedtls_pk_info_t mbedtls_eckey_info = {
327     MBEDTLS_PK_ECKEY,
328     "EC",
329     eckey_get_bitlen,
330     eckey_can_do,
331 #if defined(MBEDTLS_ECDSA_C)
332     eckey_verify_wrap,
333     eckey_sign_wrap,
334 #else
335     NULL,
336     NULL,
337 #endif
338     NULL,
339     NULL,
340     eckey_check_pair,
341     eckey_alloc_wrap,
342     eckey_free_wrap,
343     eckey_debug,
344 };
345 
346 /*
347  * EC key restricted to ECDH
348  */
349 static int eckeydh_can_do( mbedtls_pk_type_t type )
350 {
351     return( type == MBEDTLS_PK_ECKEY ||
352             type == MBEDTLS_PK_ECKEY_DH );
353 }
354 
355 const mbedtls_pk_info_t mbedtls_eckeydh_info = {
356     MBEDTLS_PK_ECKEY_DH,
357     "EC_DH",
358     eckey_get_bitlen,         /* Same underlying key structure */
359     eckeydh_can_do,
360     NULL,
361     NULL,
362     NULL,
363     NULL,
364     eckey_check_pair,
365     eckey_alloc_wrap,       /* Same underlying key structure */
366     eckey_free_wrap,        /* Same underlying key structure */
367     eckey_debug,            /* Same underlying key structure */
368 };
369 #endif /* MBEDTLS_ECP_C */
370 
371 #if defined(MBEDTLS_ECDSA_C)
372 static int ecdsa_can_do( mbedtls_pk_type_t type )
373 {
374     return( type == MBEDTLS_PK_ECDSA );
375 }
376 
377 static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
378                        const unsigned char *hash, size_t hash_len,
379                        const unsigned char *sig, size_t sig_len )
380 {
381     int ret;
382     ((void) md_alg);
383 
384     ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx,
385                                 hash, hash_len, sig, sig_len );
386 
387     if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )
388         return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
389 
390     return( ret );
391 }
392 
393 static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
394                    const unsigned char *hash, size_t hash_len,
395                    unsigned char *sig, size_t *sig_len,
396                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
397 {
398     return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx,
399                 md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) );
400 }
401 
402 static void *ecdsa_alloc_wrap( void )
403 {
404     void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) );
405 
406     if( ctx != NULL )
407         mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx );
408 
409     return( ctx );
410 }
411 
412 static void ecdsa_free_wrap( void *ctx )
413 {
414     mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx );
415     mbedtls_free( ctx );
416 }
417 
418 const mbedtls_pk_info_t mbedtls_ecdsa_info = {
419     MBEDTLS_PK_ECDSA,
420     "ECDSA",
421     eckey_get_bitlen,     /* Compatible key structures */
422     ecdsa_can_do,
423     ecdsa_verify_wrap,
424     ecdsa_sign_wrap,
425     NULL,
426     NULL,
427     eckey_check_pair,   /* Compatible key structures */
428     ecdsa_alloc_wrap,
429     ecdsa_free_wrap,
430     eckey_debug,        /* Compatible key structures */
431 };
432 #endif /* MBEDTLS_ECDSA_C */
433 
434 #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
435 /*
436  * Support for alternative RSA-private implementations
437  */
438 
439 static int rsa_alt_can_do( mbedtls_pk_type_t type )
440 {
441     return( type == MBEDTLS_PK_RSA );
442 }
443 
444 static size_t rsa_alt_get_bitlen( const void *ctx )
445 {
446     const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx;
447 
448     return( 8 * rsa_alt->key_len_func( rsa_alt->key ) );
449 }
450 
451 static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
452                    const unsigned char *hash, size_t hash_len,
453                    unsigned char *sig, size_t *sig_len,
454                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
455 {
456     mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
457 
458 #if SIZE_MAX > UINT_MAX
459     if( UINT_MAX < hash_len )
460         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
461 #endif /* SIZE_MAX > UINT_MAX */
462 
463     *sig_len = rsa_alt->key_len_func( rsa_alt->key );
464 
465     return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
466                 md_alg, (unsigned int) hash_len, hash, sig ) );
467 }
468 
469 static int rsa_alt_decrypt_wrap( void *ctx,
470                     const unsigned char *input, size_t ilen,
471                     unsigned char *output, size_t *olen, size_t osize,
472                     int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
473 {
474     mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
475 
476     ((void) f_rng);
477     ((void) p_rng);
478 
479     if( ilen != rsa_alt->key_len_func( rsa_alt->key ) )
480         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
481 
482     return( rsa_alt->decrypt_func( rsa_alt->key,
483                 MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
484 }
485 
486 #if defined(MBEDTLS_RSA_C)
487 static int rsa_alt_check_pair( const void *pub, const void *prv )
488 {
489     unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
490     unsigned char hash[32];
491     size_t sig_len = 0;
492     int ret;
493 
494     if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) )
495         return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
496 
497     memset( hash, 0x2a, sizeof( hash ) );
498 
499     if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE,
500                                    hash, sizeof( hash ),
501                                    sig, &sig_len, NULL, NULL ) ) != 0 )
502     {
503         return( ret );
504     }
505 
506     if( rsa_verify_wrap( (void *) pub, MBEDTLS_MD_NONE,
507                          hash, sizeof( hash ), sig, sig_len ) != 0 )
508     {
509         return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
510     }
511 
512     return( 0 );
513 }
514 #endif /* MBEDTLS_RSA_C */
515 
516 static void *rsa_alt_alloc_wrap( void )
517 {
518     void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context ) );
519 
520     if( ctx != NULL )
521         memset( ctx, 0, sizeof( mbedtls_rsa_alt_context ) );
522 
523     return( ctx );
524 }
525 
526 static void rsa_alt_free_wrap( void *ctx )
527 {
528     mbedtls_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) );
529     mbedtls_free( ctx );
530 }
531 
532 const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
533     MBEDTLS_PK_RSA_ALT,
534     "RSA-alt",
535     rsa_alt_get_bitlen,
536     rsa_alt_can_do,
537     NULL,
538     rsa_alt_sign_wrap,
539     rsa_alt_decrypt_wrap,
540     NULL,
541 #if defined(MBEDTLS_RSA_C)
542     rsa_alt_check_pair,
543 #else
544     NULL,
545 #endif
546     rsa_alt_alloc_wrap,
547     rsa_alt_free_wrap,
548     NULL,
549 };
550 
551 #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
552 
553 #endif /* MBEDTLS_PK_C */
554