[AMSTREAM] Sync with Wine Staging 3.9. CORE-14656
[reactos.git] / dll / 3rdparty / mbedtls / pk.c
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 */