source: azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/pk.c@ 398

Last change on this file since 398 was 398, checked in by coas-nagasima, 5 years ago

mbedTLS版Azure IoT Hub接続サンプルのソースコードを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 15.4 KB
Line 
1/*
2 * Public Key abstraction layer
3 *
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22#if !defined(MBEDTLS_CONFIG_FILE)
23#include "mbedtls/config.h"
24#else
25#include MBEDTLS_CONFIG_FILE
26#endif
27
28#if defined(MBEDTLS_PK_C)
29#include "mbedtls/pk.h"
30#include "mbedtls/pk_internal.h"
31
32#include "mbedtls/platform_util.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/* Parameter validation macros based on platform_util.h */
48#define PK_VALIDATE_RET( cond ) \
49 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA )
50#define PK_VALIDATE( cond ) \
51 MBEDTLS_INTERNAL_VALIDATE( cond )
52
53/*
54 * Initialise a mbedtls_pk_context
55 */
56void mbedtls_pk_init( mbedtls_pk_context *ctx )
57{
58 PK_VALIDATE( ctx != NULL );
59
60 ctx->pk_info = NULL;
61 ctx->pk_ctx = NULL;
62}
63
64/*
65 * Free (the components of) a mbedtls_pk_context
66 */
67void mbedtls_pk_free( mbedtls_pk_context *ctx )
68{
69 if( ctx == NULL )
70 return;
71
72 if ( ctx->pk_info != NULL )
73 ctx->pk_info->ctx_free_func( ctx->pk_ctx );
74
75 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pk_context ) );
76}
77
78#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
79/*
80 * Initialize a restart context
81 */
82void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx )
83{
84 PK_VALIDATE( ctx != NULL );
85 ctx->pk_info = NULL;
86 ctx->rs_ctx = NULL;
87}
88
89/*
90 * Free the components of a restart context
91 */
92void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx )
93{
94 if( ctx == NULL || ctx->pk_info == NULL ||
95 ctx->pk_info->rs_free_func == NULL )
96 {
97 return;
98 }
99
100 ctx->pk_info->rs_free_func( ctx->rs_ctx );
101
102 ctx->pk_info = NULL;
103 ctx->rs_ctx = NULL;
104}
105#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
106
107/*
108 * Get pk_info structure from type
109 */
110const mbedtls_pk_info_t * mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type )
111{
112 switch( pk_type ) {
113#if defined(MBEDTLS_RSA_C)
114 case MBEDTLS_PK_RSA:
115 return( &mbedtls_rsa_info );
116#endif
117#if defined(MBEDTLS_ECP_C)
118 case MBEDTLS_PK_ECKEY:
119 return( &mbedtls_eckey_info );
120 case MBEDTLS_PK_ECKEY_DH:
121 return( &mbedtls_eckeydh_info );
122#endif
123#if defined(MBEDTLS_ECDSA_C)
124 case MBEDTLS_PK_ECDSA:
125 return( &mbedtls_ecdsa_info );
126#endif
127 /* MBEDTLS_PK_RSA_ALT omitted on purpose */
128 default:
129 return( NULL );
130 }
131}
132
133/*
134 * Initialise context
135 */
136int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info )
137{
138 PK_VALIDATE_RET( ctx != NULL );
139 if( info == NULL || ctx->pk_info != NULL )
140 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
141
142 if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
143 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
144
145 ctx->pk_info = info;
146
147 return( 0 );
148}
149
150#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
151/*
152 * Initialize an RSA-alt context
153 */
154int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key,
155 mbedtls_pk_rsa_alt_decrypt_func decrypt_func,
156 mbedtls_pk_rsa_alt_sign_func sign_func,
157 mbedtls_pk_rsa_alt_key_len_func key_len_func )
158{
159 mbedtls_rsa_alt_context *rsa_alt;
160 const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info;
161
162 PK_VALIDATE_RET( ctx != NULL );
163 if( ctx->pk_info != NULL )
164 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
165
166 if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
167 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
168
169 ctx->pk_info = info;
170
171 rsa_alt = (mbedtls_rsa_alt_context *) ctx->pk_ctx;
172
173 rsa_alt->key = key;
174 rsa_alt->decrypt_func = decrypt_func;
175 rsa_alt->sign_func = sign_func;
176 rsa_alt->key_len_func = key_len_func;
177
178 return( 0 );
179}
180#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
181
182/*
183 * Tell if a PK can do the operations of the given type
184 */
185int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type )
186{
187 /* A context with null pk_info is not set up yet and can't do anything.
188 * For backward compatibility, also accept NULL instead of a context
189 * pointer. */
190 if( ctx == NULL || ctx->pk_info == NULL )
191 return( 0 );
192
193 return( ctx->pk_info->can_do( type ) );
194}
195
196/*
197 * Helper for mbedtls_pk_sign and mbedtls_pk_verify
198 */
199static inline int pk_hashlen_helper( mbedtls_md_type_t md_alg, size_t *hash_len )
200{
201 const mbedtls_md_info_t *md_info;
202
203 if( *hash_len != 0 )
204 return( 0 );
205
206 if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL )
207 return( -1 );
208
209 *hash_len = mbedtls_md_get_size( md_info );
210 return( 0 );
211}
212
213#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
214/*
215 * Helper to set up a restart context if needed
216 */
217static int pk_restart_setup( mbedtls_pk_restart_ctx *ctx,
218 const mbedtls_pk_info_t *info )
219{
220 /* Don't do anything if already set up or invalid */
221 if( ctx == NULL || ctx->pk_info != NULL )
222 return( 0 );
223
224 /* Should never happen when we're called */
225 if( info->rs_alloc_func == NULL || info->rs_free_func == NULL )
226 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
227
228 if( ( ctx->rs_ctx = info->rs_alloc_func() ) == NULL )
229 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
230
231 ctx->pk_info = info;
232
233 return( 0 );
234}
235#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
236
237/*
238 * Verify a signature (restartable)
239 */
240int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx,
241 mbedtls_md_type_t md_alg,
242 const unsigned char *hash, size_t hash_len,
243 const unsigned char *sig, size_t sig_len,
244 mbedtls_pk_restart_ctx *rs_ctx )
245{
246 PK_VALIDATE_RET( ctx != NULL );
247 PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
248 hash != NULL );
249 PK_VALIDATE_RET( sig != NULL );
250
251 if( ctx->pk_info == NULL ||
252 pk_hashlen_helper( md_alg, &hash_len ) != 0 )
253 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
254
255#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
256 /* optimization: use non-restartable version if restart disabled */
257 if( rs_ctx != NULL &&
258 mbedtls_ecp_restart_is_enabled() &&
259 ctx->pk_info->verify_rs_func != NULL )
260 {
261 int ret;
262
263 if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
264 return( ret );
265
266 ret = ctx->pk_info->verify_rs_func( ctx->pk_ctx,
267 md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx );
268
269 if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
270 mbedtls_pk_restart_free( rs_ctx );
271
272 return( ret );
273 }
274#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
275 (void) rs_ctx;
276#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
277
278 if( ctx->pk_info->verify_func == NULL )
279 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
280
281 return( ctx->pk_info->verify_func( ctx->pk_ctx, md_alg, hash, hash_len,
282 sig, sig_len ) );
283}
284
285/*
286 * Verify a signature
287 */
288int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
289 const unsigned char *hash, size_t hash_len,
290 const unsigned char *sig, size_t sig_len )
291{
292 return( mbedtls_pk_verify_restartable( ctx, md_alg, hash, hash_len,
293 sig, sig_len, NULL ) );
294}
295
296/*
297 * Verify a signature with options
298 */
299int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
300 mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
301 const unsigned char *hash, size_t hash_len,
302 const unsigned char *sig, size_t sig_len )
303{
304 PK_VALIDATE_RET( ctx != NULL );
305 PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
306 hash != NULL );
307 PK_VALIDATE_RET( sig != NULL );
308
309 if( ctx->pk_info == NULL )
310 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
311
312 if( ! mbedtls_pk_can_do( ctx, type ) )
313 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
314
315 if( type == MBEDTLS_PK_RSASSA_PSS )
316 {
317#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
318 int ret;
319 const mbedtls_pk_rsassa_pss_options *pss_opts;
320
321#if SIZE_MAX > UINT_MAX
322 if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
323 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
324#endif /* SIZE_MAX > UINT_MAX */
325
326 if( options == NULL )
327 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
328
329 pss_opts = (const mbedtls_pk_rsassa_pss_options *) options;
330
331 if( sig_len < mbedtls_pk_get_len( ctx ) )
332 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
333
334 ret = mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_pk_rsa( *ctx ),
335 NULL, NULL, MBEDTLS_RSA_PUBLIC,
336 md_alg, (unsigned int) hash_len, hash,
337 pss_opts->mgf1_hash_id,
338 pss_opts->expected_salt_len,
339 sig );
340 if( ret != 0 )
341 return( ret );
342
343 if( sig_len > mbedtls_pk_get_len( ctx ) )
344 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
345
346 return( 0 );
347#else
348 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
349#endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */
350 }
351
352 /* General case: no options */
353 if( options != NULL )
354 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
355
356 return( mbedtls_pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) );
357}
358
359/*
360 * Make a signature (restartable)
361 */
362int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx,
363 mbedtls_md_type_t md_alg,
364 const unsigned char *hash, size_t hash_len,
365 unsigned char *sig, size_t *sig_len,
366 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
367 mbedtls_pk_restart_ctx *rs_ctx )
368{
369 PK_VALIDATE_RET( ctx != NULL );
370 PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
371 hash != NULL );
372 PK_VALIDATE_RET( sig != NULL );
373
374 if( ctx->pk_info == NULL ||
375 pk_hashlen_helper( md_alg, &hash_len ) != 0 )
376 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
377
378#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
379 /* optimization: use non-restartable version if restart disabled */
380 if( rs_ctx != NULL &&
381 mbedtls_ecp_restart_is_enabled() &&
382 ctx->pk_info->sign_rs_func != NULL )
383 {
384 int ret;
385
386 if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
387 return( ret );
388
389 ret = ctx->pk_info->sign_rs_func( ctx->pk_ctx, md_alg,
390 hash, hash_len, sig, sig_len, f_rng, p_rng, rs_ctx->rs_ctx );
391
392 if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
393 mbedtls_pk_restart_free( rs_ctx );
394
395 return( ret );
396 }
397#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
398 (void) rs_ctx;
399#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
400
401 if( ctx->pk_info->sign_func == NULL )
402 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
403
404 return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg, hash, hash_len,
405 sig, sig_len, f_rng, p_rng ) );
406}
407
408/*
409 * Make a signature
410 */
411int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
412 const unsigned char *hash, size_t hash_len,
413 unsigned char *sig, size_t *sig_len,
414 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
415{
416 return( mbedtls_pk_sign_restartable( ctx, md_alg, hash, hash_len,
417 sig, sig_len, f_rng, p_rng, NULL ) );
418}
419
420/*
421 * Decrypt message
422 */
423int mbedtls_pk_decrypt( mbedtls_pk_context *ctx,
424 const unsigned char *input, size_t ilen,
425 unsigned char *output, size_t *olen, size_t osize,
426 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
427{
428 PK_VALIDATE_RET( ctx != NULL );
429 PK_VALIDATE_RET( input != NULL || ilen == 0 );
430 PK_VALIDATE_RET( output != NULL || osize == 0 );
431 PK_VALIDATE_RET( olen != NULL );
432
433 if( ctx->pk_info == NULL )
434 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
435
436 if( ctx->pk_info->decrypt_func == NULL )
437 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
438
439 return( ctx->pk_info->decrypt_func( ctx->pk_ctx, input, ilen,
440 output, olen, osize, f_rng, p_rng ) );
441}
442
443/*
444 * Encrypt message
445 */
446int mbedtls_pk_encrypt( mbedtls_pk_context *ctx,
447 const unsigned char *input, size_t ilen,
448 unsigned char *output, size_t *olen, size_t osize,
449 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
450{
451 PK_VALIDATE_RET( ctx != NULL );
452 PK_VALIDATE_RET( input != NULL || ilen == 0 );
453 PK_VALIDATE_RET( output != NULL || osize == 0 );
454 PK_VALIDATE_RET( olen != NULL );
455
456 if( ctx->pk_info == NULL )
457 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
458
459 if( ctx->pk_info->encrypt_func == NULL )
460 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
461
462 return( ctx->pk_info->encrypt_func( ctx->pk_ctx, input, ilen,
463 output, olen, osize, f_rng, p_rng ) );
464}
465
466/*
467 * Check public-private key pair
468 */
469int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv )
470{
471 PK_VALIDATE_RET( pub != NULL );
472 PK_VALIDATE_RET( prv != NULL );
473
474 if( pub->pk_info == NULL ||
475 prv->pk_info == NULL ||
476 prv->pk_info->check_pair_func == NULL )
477 {
478 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
479 }
480
481 if( prv->pk_info->type == MBEDTLS_PK_RSA_ALT )
482 {
483 if( pub->pk_info->type != MBEDTLS_PK_RSA )
484 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
485 }
486 else
487 {
488 if( pub->pk_info != prv->pk_info )
489 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
490 }
491
492 return( prv->pk_info->check_pair_func( pub->pk_ctx, prv->pk_ctx ) );
493}
494
495/*
496 * Get key size in bits
497 */
498size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx )
499{
500 /* For backward compatibility, accept NULL or a context that
501 * isn't set up yet, and return a fake value that should be safe. */
502 if( ctx == NULL || ctx->pk_info == NULL )
503 return( 0 );
504
505 return( ctx->pk_info->get_bitlen( ctx->pk_ctx ) );
506}
507
508/*
509 * Export debug information
510 */
511int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items )
512{
513 PK_VALIDATE_RET( ctx != NULL );
514 if( ctx->pk_info == NULL )
515 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
516
517 if( ctx->pk_info->debug_func == NULL )
518 return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
519
520 ctx->pk_info->debug_func( ctx->pk_ctx, items );
521 return( 0 );
522}
523
524/*
525 * Access the PK type name
526 */
527const char *mbedtls_pk_get_name( const mbedtls_pk_context *ctx )
528{
529 if( ctx == NULL || ctx->pk_info == NULL )
530 return( "invalid PK" );
531
532 return( ctx->pk_info->name );
533}
534
535/*
536 * Access the PK type
537 */
538mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx )
539{
540 if( ctx == NULL || ctx->pk_info == NULL )
541 return( MBEDTLS_PK_NONE );
542
543 return( ctx->pk_info->type );
544}
545
546#endif /* MBEDTLS_PK_C */
Note: See TracBrowser for help on using the repository browser.