pk_wrap.c 13.7 KB
Newer Older
1 2 3
/*
 *  Public Key abstraction layer: wrapper functions
 *
4
 *  Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
5
 *
6
 *  This file is part of mbed TLS (https://tls.mbed.org)
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

23
#if !defined(MBEDTLS_CONFIG_FILE)
24
#include "mbedtls/config.h"
25
#else
26
#include MBEDTLS_CONFIG_FILE
27
#endif
28

29
#if defined(MBEDTLS_PK_C)
30
#include "mbedtls/pk_internal.h"
31

32
/* Even if RSA not activated, for the sake of RSA-alt */
33
#include "mbedtls/rsa.h"
34

35 36
#include <string.h>

37
#if defined(MBEDTLS_ECP_C)
38
#include "mbedtls/ecp.h"
39 40
#endif

41
#if defined(MBEDTLS_ECDSA_C)
42
#include "mbedtls/ecdsa.h"
43 44
#endif

45
#if defined(MBEDTLS_PLATFORM_C)
46
#include "mbedtls/platform.h"
47 48
#else
#include <stdlib.h>
49
#define mbedtls_calloc    calloc
50
#define mbedtls_free       free
51 52
#endif

53
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
54
/* Implementation that should never be optimized out by the compiler */
55
static void mbedtls_zeroize( void *v, size_t n ) {
56 57
    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
58
#endif
59

60 61
#if defined(MBEDTLS_RSA_C)
static int rsa_can_do( mbedtls_pk_type_t type )
62
{
63 64
    return( type == MBEDTLS_PK_RSA ||
            type == MBEDTLS_PK_RSASSA_PSS );
65 66
}

67
static size_t rsa_get_size( const void *ctx )
68
{
69
    return( 8 * ((const mbedtls_rsa_context *) ctx)->len );
70 71
}

72
static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
73
                   const unsigned char *hash, size_t hash_len,
74 75
                   const unsigned char *sig, size_t sig_len )
{
76 77
    int ret;

78 79
    if( sig_len < ((mbedtls_rsa_context *) ctx)->len )
        return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
80

81 82
    if( ( ret = mbedtls_rsa_pkcs1_verify( (mbedtls_rsa_context *) ctx, NULL, NULL,
                                  MBEDTLS_RSA_PUBLIC, md_alg,
83 84 85
                                  (unsigned int) hash_len, hash, sig ) ) != 0 )
        return( ret );

86 87
    if( sig_len > ((mbedtls_rsa_context *) ctx)->len )
        return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
88 89

    return( 0 );
90 91
}

92
static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
93 94 95 96
                   const unsigned char *hash, size_t hash_len,
                   unsigned char *sig, size_t *sig_len,
                   int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
97
    *sig_len = ((mbedtls_rsa_context *) ctx)->len;
98

99
    return( mbedtls_rsa_pkcs1_sign( (mbedtls_rsa_context *) ctx, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
100
                md_alg, (unsigned int) hash_len, hash, sig ) );
101 102
}

103 104 105 106 107
static int rsa_decrypt_wrap( void *ctx,
                    const unsigned char *input, size_t ilen,
                    unsigned char *output, size_t *olen, size_t osize,
                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
108 109
    if( ilen != ((mbedtls_rsa_context *) ctx)->len )
        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
110

111 112
    return( mbedtls_rsa_pkcs1_decrypt( (mbedtls_rsa_context *) ctx, f_rng, p_rng,
                MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
113 114 115 116 117 118 119
}

static int rsa_encrypt_wrap( void *ctx,
                    const unsigned char *input, size_t ilen,
                    unsigned char *output, size_t *olen, size_t osize,
                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
120
    *olen = ((mbedtls_rsa_context *) ctx)->len;
121

122
    if( *olen > osize )
123
        return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE );
124

125 126
    return( mbedtls_rsa_pkcs1_encrypt( (mbedtls_rsa_context *) ctx,
                f_rng, p_rng, MBEDTLS_RSA_PUBLIC, ilen, input, output ) );
127 128
}

129 130
static int rsa_check_pair_wrap( const void *pub, const void *prv )
{
131 132
    return( mbedtls_rsa_check_pub_priv( (const mbedtls_rsa_context *) pub,
                                (const mbedtls_rsa_context *) prv ) );
133 134
}

135 136
static void *rsa_alloc_wrap( void )
{
137
    void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_context ) );
138 139

    if( ctx != NULL )
140
        mbedtls_rsa_init( (mbedtls_rsa_context *) ctx, 0, 0 );
141

142
    return( ctx );
143 144 145 146
}

static void rsa_free_wrap( void *ctx )
{
147 148
    mbedtls_rsa_free( (mbedtls_rsa_context *) ctx );
    mbedtls_free( ctx );
149 150
}

151
static void rsa_debug( const void *ctx, mbedtls_pk_debug_item *items )
152
{
153
    items->type = MBEDTLS_PK_DEBUG_MPI;
154
    items->name = "rsa.N";
155
    items->value = &( ((mbedtls_rsa_context *) ctx)->N );
156 157 158

    items++;

159
    items->type = MBEDTLS_PK_DEBUG_MPI;
160
    items->name = "rsa.E";
161
    items->value = &( ((mbedtls_rsa_context *) ctx)->E );
162 163
}

164 165
const mbedtls_pk_info_t mbedtls_rsa_info = {
    MBEDTLS_PK_RSA,
166 167
    "RSA",
    rsa_get_size,
168
    rsa_can_do,
169
    rsa_verify_wrap,
170
    rsa_sign_wrap,
171 172
    rsa_decrypt_wrap,
    rsa_encrypt_wrap,
173
    rsa_check_pair_wrap,
174 175
    rsa_alloc_wrap,
    rsa_free_wrap,
176
    rsa_debug,
177
};
178
#endif /* MBEDTLS_RSA_C */
179

180
#if defined(MBEDTLS_ECP_C)
181 182 183
/*
 * Generic EC key
 */
184
static int eckey_can_do( mbedtls_pk_type_t type )
185
{
186 187 188
    return( type == MBEDTLS_PK_ECKEY ||
            type == MBEDTLS_PK_ECKEY_DH ||
            type == MBEDTLS_PK_ECDSA );
189 190
}

191
static size_t eckey_get_size( const void *ctx )
192
{
193
    return( ((mbedtls_ecp_keypair *) ctx)->grp.pbits );
194 195
}

196
#if defined(MBEDTLS_ECDSA_C)
197
/* Forward declarations */
198
static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
199
                       const unsigned char *hash, size_t hash_len,
200 201
                       const unsigned char *sig, size_t sig_len );

202
static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
203 204 205 206
                   const unsigned char *hash, size_t hash_len,
                   unsigned char *sig, size_t *sig_len,
                   int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );

207
static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
208
                       const unsigned char *hash, size_t hash_len,
209 210 211
                       const unsigned char *sig, size_t sig_len )
{
    int ret;
212
    mbedtls_ecdsa_context ecdsa;
213

214
    mbedtls_ecdsa_init( &ecdsa );
215

216
    if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
217
        ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len );
218

219
    mbedtls_ecdsa_free( &ecdsa );
220 221 222

    return( ret );
}
223

224
static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
225 226 227 228 229
                   const unsigned char *hash, size_t hash_len,
                   unsigned char *sig, size_t *sig_len,
                   int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
    int ret;
230
    mbedtls_ecdsa_context ecdsa;
231

232
    mbedtls_ecdsa_init( &ecdsa );
233

234
    if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
235 236 237
        ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len,
                               f_rng, p_rng );

238
    mbedtls_ecdsa_free( &ecdsa );
239 240 241 242

    return( ret );
}

243
#endif /* MBEDTLS_ECDSA_C */
244

245 246
static int eckey_check_pair( const void *pub, const void *prv )
{
247 248
    return( mbedtls_ecp_check_pub_priv( (const mbedtls_ecp_keypair *) pub,
                                (const mbedtls_ecp_keypair *) prv ) );
249 250
}

251 252
static void *eckey_alloc_wrap( void )
{
253
    void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
254 255

    if( ctx != NULL )
256
        mbedtls_ecp_keypair_init( ctx );
257 258 259 260 261 262

    return( ctx );
}

static void eckey_free_wrap( void *ctx )
{
263 264
    mbedtls_ecp_keypair_free( (mbedtls_ecp_keypair *) ctx );
    mbedtls_free( ctx );
265 266
}

267
static void eckey_debug( const void *ctx, mbedtls_pk_debug_item *items )
268
{
269
    items->type = MBEDTLS_PK_DEBUG_ECP;
270
    items->name = "eckey.Q";
271
    items->value = &( ((mbedtls_ecp_keypair *) ctx)->Q );
272 273
}

274 275
const mbedtls_pk_info_t mbedtls_eckey_info = {
    MBEDTLS_PK_ECKEY,
276 277
    "EC",
    eckey_get_size,
278
    eckey_can_do,
279
#if defined(MBEDTLS_ECDSA_C)
280
    eckey_verify_wrap,
281
    eckey_sign_wrap,
282 283
#else
    NULL,
284
    NULL,
285
#endif
286 287
    NULL,
    NULL,
288
    eckey_check_pair,
289 290
    eckey_alloc_wrap,
    eckey_free_wrap,
291
    eckey_debug,
292
};
293 294

/*
Paul Bakker's avatar
Paul Bakker committed
295
 * EC key restricted to ECDH
296
 */
297
static int eckeydh_can_do( mbedtls_pk_type_t type )
298
{
299 300
    return( type == MBEDTLS_PK_ECKEY ||
            type == MBEDTLS_PK_ECKEY_DH );
301 302
}

303 304
const mbedtls_pk_info_t mbedtls_eckeydh_info = {
    MBEDTLS_PK_ECKEY_DH,
305 306
    "EC_DH",
    eckey_get_size,         /* Same underlying key structure */
307
    eckeydh_can_do,
308
    NULL,
309
    NULL,
310 311
    NULL,
    NULL,
312
    eckey_check_pair,
313 314
    eckey_alloc_wrap,       /* Same underlying key structure */
    eckey_free_wrap,        /* Same underlying key structure */
315
    eckey_debug,            /* Same underlying key structure */
316
};
317
#endif /* MBEDTLS_ECP_C */
318

319 320
#if defined(MBEDTLS_ECDSA_C)
static int ecdsa_can_do( mbedtls_pk_type_t type )
321
{
322
    return( type == MBEDTLS_PK_ECDSA );
323 324
}

325
static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
326
                       const unsigned char *hash, size_t hash_len,
327 328
                       const unsigned char *sig, size_t sig_len )
{
329
    int ret;
330 331
    ((void) md_alg);

332
    ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx,
333 334
                                hash, hash_len, sig, sig_len );

335 336
    if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )
        return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
337 338

    return( ret );
339 340
}

341
static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
342 343 344 345
                   const unsigned char *hash, size_t hash_len,
                   unsigned char *sig, size_t *sig_len,
                   int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
346
    return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx,
347
                md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) );
348 349
}

350 351
static void *ecdsa_alloc_wrap( void )
{
352
    void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) );
353 354

    if( ctx != NULL )
355
        mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx );
356 357 358 359 360 361

    return( ctx );
}

static void ecdsa_free_wrap( void *ctx )
{
362 363
    mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx );
    mbedtls_free( ctx );
364 365
}

366 367
const mbedtls_pk_info_t mbedtls_ecdsa_info = {
    MBEDTLS_PK_ECDSA,
368 369 370 371
    "ECDSA",
    eckey_get_size,     /* Compatible key structures */
    ecdsa_can_do,
    ecdsa_verify_wrap,
372
    ecdsa_sign_wrap,
373 374
    NULL,
    NULL,
375
    eckey_check_pair,   /* Compatible key structures */
376 377 378 379
    ecdsa_alloc_wrap,
    ecdsa_free_wrap,
    eckey_debug,        /* Compatible key structures */
};
380
#endif /* MBEDTLS_ECDSA_C */
381

382
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
383 384 385 386
/*
 * Support for alternative RSA-private implementations
 */

387
static int rsa_alt_can_do( mbedtls_pk_type_t type )
388
{
389
    return( type == MBEDTLS_PK_RSA );
390 391
}

392 393
static size_t rsa_alt_get_size( const void *ctx )
{
394
    const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx;
395

396
    return( 8 * rsa_alt->key_len_func( rsa_alt->key ) );
397 398
}

399
static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
400 401 402 403
                   const unsigned char *hash, size_t hash_len,
                   unsigned char *sig, size_t *sig_len,
                   int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
404
    mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
405 406 407

    *sig_len = rsa_alt->key_len_func( rsa_alt->key );

408
    return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
409
                md_alg, (unsigned int) hash_len, hash, sig ) );
410 411 412 413 414 415 416
}

static int rsa_alt_decrypt_wrap( void *ctx,
                    const unsigned char *input, size_t ilen,
                    unsigned char *output, size_t *olen, size_t osize,
                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
417
    mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
418 419 420 421 422

    ((void) f_rng);
    ((void) p_rng);

    if( ilen != rsa_alt->key_len_func( rsa_alt->key ) )
423
        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
424 425

    return( rsa_alt->decrypt_func( rsa_alt->key,
426
                MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
427 428
}

429
#if defined(MBEDTLS_RSA_C)
430 431
static int rsa_alt_check_pair( const void *pub, const void *prv )
{
432
    unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
433 434 435 436 437
    unsigned char hash[32];
    size_t sig_len = 0;
    int ret;

    if( rsa_alt_get_size( prv ) != rsa_get_size( pub ) )
438
        return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
439 440 441

    memset( hash, 0x2a, sizeof( hash ) );

442
    if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE,
443 444 445 446 447 448
                                   hash, sizeof( hash ),
                                   sig, &sig_len, NULL, NULL ) ) != 0 )
    {
        return( ret );
    }

449
    if( rsa_verify_wrap( (void *) pub, MBEDTLS_MD_NONE,
450 451
                         hash, sizeof( hash ), sig, sig_len ) != 0 )
    {
452
        return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
453 454 455 456
    }

    return( 0 );
}
457
#endif /* MBEDTLS_RSA_C */
458

459 460
static void *rsa_alt_alloc_wrap( void )
{
461
    void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context ) );
462 463

    if( ctx != NULL )
464
        memset( ctx, 0, sizeof( mbedtls_rsa_alt_context ) );
465

466
    return( ctx );
467 468 469 470
}

static void rsa_alt_free_wrap( void *ctx )
{
471 472
    mbedtls_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) );
    mbedtls_free( ctx );
473 474
}

475 476
const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
    MBEDTLS_PK_RSA_ALT,
477 478
    "RSA-alt",
    rsa_alt_get_size,
479
    rsa_alt_can_do,
480 481 482 483
    NULL,
    rsa_alt_sign_wrap,
    rsa_alt_decrypt_wrap,
    NULL,
484
#if defined(MBEDTLS_RSA_C)
485
    rsa_alt_check_pair,
486 487 488
#else
    NULL,
#endif
489 490 491 492
    rsa_alt_alloc_wrap,
    rsa_alt_free_wrap,
    NULL,
};
493

494
#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
495

496
#endif /* MBEDTLS_PK_C */