Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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