~ubuntu-branches/ubuntu/vivid/wpasupplicant/vivid

« back to all changes in this revision

Viewing changes to src/crypto/crypto_libtomcrypt.c

  • Committer: Bazaar Package Importer
  • Author(s): Kel Modderman
  • Date: 2008-03-12 20:03:04 UTC
  • mfrom: (1.1.10 upstream)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20080312200304-4331y9wj46pdd34z
Tags: 0.6.3-1
* New upstream release.
* Drop patches applied upstream:
  - debian/patches/30_wpa_gui_qt4_eventhistoryui_rework.patch
  - debian/patches/31_wpa_gui_qt4_eventhistory_always_scrollbar.patch
  - debian/patches/32_wpa_gui_qt4_eventhistory_scroll_with_events.patch
  - debian/patches/40_dbus_ssid_data.patch
* Tidy up the clean target of debian/rules. Now that the madwifi headers are
  handled differently we no longer need to do any cleanup.
* Fix formatting error in debian/ifupdown/wpa_action.8 to make lintian
  quieter.
* Add patch to fix formatting errors in manpages build from sgml source. Use
  <emphasis> tags to hightlight keywords instead of surrounding them in
  strong quotes.
  - debian/patches/41_manpage_format_fixes.patch
* wpasupplicant binary package no longer suggests pcscd, guessnet, iproute
  or wireless-tools, nor does it recommend dhcp3-client. These are not
  needed.
* Add debian/patches/10_silence_siocsiwauth_icotl_failure.patch to disable
  ioctl failure messages that occur under normal conditions.
* Cherry pick two upstream git commits concerning the dbus interface:
  - debian/patches/11_avoid_dbus_version_namespace.patch
  - debian/patches/12_fix_potential_use_after_free.patch
* Add debian/patches/42_manpage_explain_available_drivers.patch to explain
  that not all of the driver backends are available in the provided
  wpa_supplicant binary, and that the canonical list of supported driver
  backends can be retrieved from the wpa_supplicant -h (help) output.
  (Closes: #466910)
* Add debian/patches/20_wpa_gui_qt4_disable_link_prl.patch to remove
  link_prl CONFIG compile flag added by qmake-qt4 >= 4.3.4-2 to avoid excess
  linking.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * WPA Supplicant / Crypto wrapper for LibTomCrypt (for internal TLSv1)
 
3
 * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License version 2 as
 
7
 * published by the Free Software Foundation.
 
8
 *
 
9
 * Alternatively, this software may be distributed under the terms of BSD
 
10
 * license.
 
11
 *
 
12
 * See README and COPYING for more details.
 
13
 */
 
14
 
 
15
#include "includes.h"
 
16
#include <tomcrypt.h>
 
17
 
 
18
#include "common.h"
 
19
#include "rc4.h"
 
20
#include "crypto.h"
 
21
 
 
22
#ifndef mp_init_multi
 
23
#define mp_init_multi                ltc_init_multi
 
24
#define mp_clear_multi               ltc_deinit_multi
 
25
#define mp_unsigned_bin_size(a)      ltc_mp.unsigned_size(a)
 
26
#define mp_to_unsigned_bin(a, b)     ltc_mp.unsigned_write(a, b)
 
27
#define mp_read_unsigned_bin(a, b, c) ltc_mp.unsigned_read(a, b, c)
 
28
#define mp_exptmod(a,b,c,d)          ltc_mp.exptmod(a,b,c,d)
 
29
#endif
 
30
 
 
31
 
 
32
void md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 
33
{
 
34
        hash_state md;
 
35
        size_t i;
 
36
 
 
37
        md4_init(&md);
 
38
        for (i = 0; i < num_elem; i++)
 
39
                md4_process(&md, addr[i], len[i]);
 
40
        md4_done(&md, mac);
 
41
}
 
42
 
 
43
 
 
44
void des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
 
45
{
 
46
        u8 pkey[8], next, tmp;
 
47
        int i;
 
48
        symmetric_key skey;
 
49
 
 
50
        /* Add parity bits to the key */
 
51
        next = 0;
 
52
        for (i = 0; i < 7; i++) {
 
53
                tmp = key[i];
 
54
                pkey[i] = (tmp >> i) | next | 1;
 
55
                next = tmp << (7 - i);
 
56
        }
 
57
        pkey[i] = next | 1;
 
58
 
 
59
        des_setup(pkey, 8, 0, &skey);
 
60
        des_ecb_encrypt(clear, cypher, &skey);
 
61
        des_done(&skey);
 
62
}
 
63
 
 
64
 
 
65
#ifdef EAP_TLS_FUNCS
 
66
void md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 
67
{
 
68
        hash_state md;
 
69
        size_t i;
 
70
 
 
71
        md5_init(&md);
 
72
        for (i = 0; i < num_elem; i++)
 
73
                md5_process(&md, addr[i], len[i]);
 
74
        md5_done(&md, mac);
 
75
}
 
76
 
 
77
 
 
78
void sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 
79
{
 
80
        hash_state md;
 
81
        size_t i;
 
82
 
 
83
        sha1_init(&md);
 
84
        for (i = 0; i < num_elem; i++)
 
85
                sha1_process(&md, addr[i], len[i]);
 
86
        sha1_done(&md, mac);
 
87
}
 
88
 
 
89
 
 
90
void * aes_encrypt_init(const u8 *key, size_t len)
 
91
{
 
92
        symmetric_key *skey;
 
93
        skey = os_malloc(sizeof(*skey));
 
94
        if (skey == NULL)
 
95
                return NULL;
 
96
        if (aes_setup(key, len, 0, skey) != CRYPT_OK) {
 
97
                os_free(skey);
 
98
                return NULL;
 
99
        }
 
100
        return skey;
 
101
}
 
102
 
 
103
 
 
104
void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
 
105
{
 
106
        symmetric_key *skey = ctx;
 
107
        aes_ecb_encrypt(plain, crypt, skey);
 
108
}
 
109
 
 
110
 
 
111
void aes_encrypt_deinit(void *ctx)
 
112
{
 
113
        symmetric_key *skey = ctx;
 
114
        aes_done(skey);
 
115
        os_free(skey);
 
116
}
 
117
 
 
118
 
 
119
void * aes_decrypt_init(const u8 *key, size_t len)
 
120
{
 
121
        symmetric_key *skey;
 
122
        skey = os_malloc(sizeof(*skey));
 
123
        if (skey == NULL)
 
124
                return NULL;
 
125
        if (aes_setup(key, len, 0, skey) != CRYPT_OK) {
 
126
                os_free(skey);
 
127
                return NULL;
 
128
        }
 
129
        return skey;
 
130
}
 
131
 
 
132
 
 
133
void aes_decrypt(void *ctx, const u8 *crypt, u8 *plain)
 
134
{
 
135
        symmetric_key *skey = ctx;
 
136
        aes_ecb_encrypt(plain, (u8 *) crypt, skey);
 
137
}
 
138
 
 
139
 
 
140
void aes_decrypt_deinit(void *ctx)
 
141
{
 
142
        symmetric_key *skey = ctx;
 
143
        aes_done(skey);
 
144
        os_free(skey);
 
145
}
 
146
 
 
147
 
 
148
#ifdef CONFIG_TLS_INTERNAL
 
149
 
 
150
struct crypto_hash {
 
151
        enum crypto_hash_alg alg;
 
152
        int error;
 
153
        union {
 
154
                hash_state md;
 
155
                hmac_state hmac;
 
156
        } u;
 
157
};
 
158
 
 
159
 
 
160
struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
 
161
                                      size_t key_len)
 
162
{
 
163
        struct crypto_hash *ctx;
 
164
 
 
165
        ctx = os_zalloc(sizeof(*ctx));
 
166
        if (ctx == NULL)
 
167
                return NULL;
 
168
 
 
169
        ctx->alg = alg;
 
170
 
 
171
        switch (alg) {
 
172
        case CRYPTO_HASH_ALG_MD5:
 
173
                if (md5_init(&ctx->u.md) != CRYPT_OK)
 
174
                        goto fail;
 
175
                break;
 
176
        case CRYPTO_HASH_ALG_SHA1:
 
177
                if (sha1_init(&ctx->u.md) != CRYPT_OK)
 
178
                        goto fail;
 
179
                break;
 
180
        case CRYPTO_HASH_ALG_HMAC_MD5:
 
181
                if (hmac_init(&ctx->u.hmac, find_hash("md5"), key, key_len) !=
 
182
                    CRYPT_OK)
 
183
                        goto fail;
 
184
                break;
 
185
        case CRYPTO_HASH_ALG_HMAC_SHA1:
 
186
                if (hmac_init(&ctx->u.hmac, find_hash("sha1"), key, key_len) !=
 
187
                    CRYPT_OK)
 
188
                        goto fail;
 
189
                break;
 
190
        default:
 
191
                goto fail;
 
192
        }
 
193
 
 
194
        return ctx;
 
195
 
 
196
fail:
 
197
        os_free(ctx);
 
198
        return NULL;
 
199
}
 
200
 
 
201
void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
 
202
{
 
203
        if (ctx == NULL || ctx->error)
 
204
                return;
 
205
 
 
206
        switch (ctx->alg) {
 
207
        case CRYPTO_HASH_ALG_MD5:
 
208
                ctx->error = md5_process(&ctx->u.md, data, len) != CRYPT_OK;
 
209
                break;
 
210
        case CRYPTO_HASH_ALG_SHA1:
 
211
                ctx->error = sha1_process(&ctx->u.md, data, len) != CRYPT_OK;
 
212
                break;
 
213
        case CRYPTO_HASH_ALG_HMAC_MD5:
 
214
        case CRYPTO_HASH_ALG_HMAC_SHA1:
 
215
                ctx->error = hmac_process(&ctx->u.hmac, data, len) != CRYPT_OK;
 
216
                break;
 
217
        }
 
218
}
 
219
 
 
220
 
 
221
int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
 
222
{
 
223
        int ret = 0;
 
224
        unsigned long clen;
 
225
 
 
226
        if (ctx == NULL)
 
227
                return -2;
 
228
 
 
229
        if (mac == NULL || len == NULL) {
 
230
                os_free(ctx);
 
231
                return 0;
 
232
        }
 
233
 
 
234
        if (ctx->error) {
 
235
                os_free(ctx);
 
236
                return -2;
 
237
        }
 
238
 
 
239
        switch (ctx->alg) {
 
240
        case CRYPTO_HASH_ALG_MD5:
 
241
                if (*len < 16) {
 
242
                        *len = 16;
 
243
                        os_free(ctx);
 
244
                        return -1;
 
245
                }
 
246
                *len = 16;
 
247
                if (md5_done(&ctx->u.md, mac) != CRYPT_OK)
 
248
                        ret = -2;
 
249
                break;
 
250
        case CRYPTO_HASH_ALG_SHA1:
 
251
                if (*len < 20) {
 
252
                        *len = 20;
 
253
                        os_free(ctx);
 
254
                        return -1;
 
255
                }
 
256
                *len = 20;
 
257
                if (sha1_done(&ctx->u.md, mac) != CRYPT_OK)
 
258
                        ret = -2;
 
259
                break;
 
260
        case CRYPTO_HASH_ALG_HMAC_SHA1:
 
261
                if (*len < 20) {
 
262
                        *len = 20;
 
263
                        os_free(ctx);
 
264
                        return -1;
 
265
                }
 
266
                /* continue */
 
267
        case CRYPTO_HASH_ALG_HMAC_MD5:
 
268
                if (*len < 16) {
 
269
                        *len = 16;
 
270
                        os_free(ctx);
 
271
                        return -1;
 
272
                }
 
273
                clen = *len;
 
274
                if (hmac_done(&ctx->u.hmac, mac, &clen) != CRYPT_OK) {
 
275
                        os_free(ctx);
 
276
                        return -1;
 
277
                }
 
278
                *len = clen;
 
279
                break;
 
280
        default:
 
281
                ret = -2;
 
282
                break;
 
283
        }
 
284
 
 
285
        os_free(ctx);
 
286
 
 
287
        return ret;
 
288
}
 
289
 
 
290
 
 
291
struct crypto_cipher {
 
292
        int rc4;
 
293
        union {
 
294
                symmetric_CBC cbc;
 
295
                struct {
 
296
                        size_t used_bytes;
 
297
                        u8 key[16];
 
298
                        size_t keylen;
 
299
                } rc4;
 
300
        } u;
 
301
};
 
302
 
 
303
 
 
304
struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
 
305
                                          const u8 *iv, const u8 *key,
 
306
                                          size_t key_len)
 
307
{       
 
308
        struct crypto_cipher *ctx;
 
309
        int idx, res, rc4 = 0;
 
310
 
 
311
        switch (alg) {
 
312
        case CRYPTO_CIPHER_ALG_AES:
 
313
                idx = find_cipher("aes");
 
314
                break;
 
315
        case CRYPTO_CIPHER_ALG_3DES:
 
316
                idx = find_cipher("3des");
 
317
                break;
 
318
        case CRYPTO_CIPHER_ALG_DES:
 
319
                idx = find_cipher("des");
 
320
                break;
 
321
        case CRYPTO_CIPHER_ALG_RC2:
 
322
                idx = find_cipher("rc2");
 
323
                break;
 
324
        case CRYPTO_CIPHER_ALG_RC4:
 
325
                idx = -1;
 
326
                rc4 = 1;
 
327
                break;
 
328
        default:
 
329
                return NULL;
 
330
        }
 
331
 
 
332
        ctx = os_zalloc(sizeof(*ctx));
 
333
        if (ctx == NULL)
 
334
                return NULL;
 
335
 
 
336
        if (rc4) {
 
337
                ctx->rc4 = 1;
 
338
                if (key_len > sizeof(ctx->u.rc4.key)) {
 
339
                        os_free(ctx);
 
340
                        return NULL;
 
341
                }
 
342
                ctx->u.rc4.keylen = key_len;
 
343
                os_memcpy(ctx->u.rc4.key, key, key_len);
 
344
        } else {
 
345
                res = cbc_start(idx, iv, key, key_len, 0, &ctx->u.cbc);
 
346
                if (res != CRYPT_OK) {
 
347
                        wpa_printf(MSG_DEBUG, "LibTomCrypt: Cipher start "
 
348
                                   "failed: %s", error_to_string(res));
 
349
                        os_free(ctx);
 
350
                        return NULL;
 
351
                }
 
352
        }
 
353
 
 
354
        return ctx;
 
355
}
 
356
 
 
357
int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
 
358
                          u8 *crypt, size_t len)
 
359
{
 
360
        int res;
 
361
 
 
362
        if (ctx->rc4) {
 
363
                if (plain != crypt)
 
364
                        os_memcpy(crypt, plain, len);
 
365
                rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen,
 
366
                         ctx->u.rc4.used_bytes, crypt, len);
 
367
                ctx->u.rc4.used_bytes += len;
 
368
                return 0;
 
369
        }
 
370
 
 
371
        res = cbc_encrypt(plain, crypt, len, &ctx->u.cbc);
 
372
        if (res != CRYPT_OK) {
 
373
                wpa_printf(MSG_DEBUG, "LibTomCrypt: CBC encryption "
 
374
                           "failed: %s", error_to_string(res));
 
375
                return -1;
 
376
        }
 
377
        return 0;
 
378
}
 
379
 
 
380
 
 
381
int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
 
382
                          u8 *plain, size_t len)
 
383
{
 
384
        int res;
 
385
 
 
386
        if (ctx->rc4) {
 
387
                if (plain != crypt)
 
388
                        os_memcpy(plain, crypt, len);
 
389
                rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen,
 
390
                         ctx->u.rc4.used_bytes, plain, len);
 
391
                ctx->u.rc4.used_bytes += len;
 
392
                return 0;
 
393
        }
 
394
 
 
395
        res = cbc_decrypt(crypt, plain, len, &ctx->u.cbc);
 
396
        if (res != CRYPT_OK) {
 
397
                wpa_printf(MSG_DEBUG, "LibTomCrypt: CBC decryption "
 
398
                           "failed: %s", error_to_string(res));
 
399
                return -1;
 
400
        }
 
401
 
 
402
        return 0;
 
403
}
 
404
 
 
405
 
 
406
void crypto_cipher_deinit(struct crypto_cipher *ctx)
 
407
{
 
408
        if (!ctx->rc4)
 
409
                cbc_done(&ctx->u.cbc);
 
410
        os_free(ctx);
 
411
}
 
412
 
 
413
 
 
414
struct crypto_public_key {
 
415
        rsa_key rsa;
 
416
};
 
417
 
 
418
struct crypto_private_key {
 
419
        rsa_key rsa;
 
420
};
 
421
 
 
422
 
 
423
struct crypto_public_key * crypto_public_key_import(const u8 *key, size_t len)
 
424
{
 
425
        int res;
 
426
        struct crypto_public_key *pk;
 
427
 
 
428
        pk = os_zalloc(sizeof(*pk));
 
429
        if (pk == NULL)
 
430
                return NULL;
 
431
 
 
432
        res = rsa_import(key, len, &pk->rsa);
 
433
        if (res != CRYPT_OK) {
 
434
                wpa_printf(MSG_ERROR, "LibTomCrypt: Failed to import "
 
435
                           "public key (res=%d '%s')",
 
436
                           res, error_to_string(res));
 
437
                os_free(pk);
 
438
                return NULL;
 
439
        }
 
440
 
 
441
        if (pk->rsa.type != PK_PUBLIC) {
 
442
                wpa_printf(MSG_ERROR, "LibTomCrypt: Public key was not of "
 
443
                           "correct type");
 
444
                rsa_free(&pk->rsa);
 
445
                os_free(pk);
 
446
                return NULL;
 
447
        }
 
448
 
 
449
        return pk;
 
450
}
 
451
 
 
452
 
 
453
struct crypto_private_key * crypto_private_key_import(const u8 *key,
 
454
                                                      size_t len)
 
455
{
 
456
        int res;
 
457
        struct crypto_private_key *pk;
 
458
 
 
459
        pk = os_zalloc(sizeof(*pk));
 
460
        if (pk == NULL)
 
461
                return NULL;
 
462
 
 
463
        res = rsa_import(key, len, &pk->rsa);
 
464
        if (res != CRYPT_OK) {
 
465
                wpa_printf(MSG_ERROR, "LibTomCrypt: Failed to import "
 
466
                           "private key (res=%d '%s')",
 
467
                           res, error_to_string(res));
 
468
                os_free(pk);
 
469
                return NULL;
 
470
        }
 
471
 
 
472
        if (pk->rsa.type != PK_PRIVATE) {
 
473
                wpa_printf(MSG_ERROR, "LibTomCrypt: Private key was not of "
 
474
                           "correct type");
 
475
                rsa_free(&pk->rsa);
 
476
                os_free(pk);
 
477
                return NULL;
 
478
        }
 
479
 
 
480
        return pk;
 
481
}
 
482
 
 
483
 
 
484
struct crypto_public_key * crypto_public_key_from_cert(const u8 *buf,
 
485
                                                       size_t len)
 
486
{
 
487
        /* No X.509 support in LibTomCrypt */
 
488
        return NULL;
 
489
}
 
490
 
 
491
 
 
492
static int pkcs1_generate_encryption_block(u8 block_type, size_t modlen,
 
493
                                           const u8 *in, size_t inlen,
 
494
                                           u8 *out, size_t *outlen)
 
495
{
 
496
        size_t ps_len;
 
497
        u8 *pos;
 
498
 
 
499
        /*
 
500
         * PKCS #1 v1.5, 8.1:
 
501
         *
 
502
         * EB = 00 || BT || PS || 00 || D
 
503
         * BT = 00 or 01 for private-key operation; 02 for public-key operation
 
504
         * PS = k-3-||D||; at least eight octets
 
505
         * (BT=0: PS=0x00, BT=1: PS=0xff, BT=2: PS=pseudorandom non-zero)
 
506
         * k = length of modulus in octets (modlen)
 
507
         */
 
508
 
 
509
        if (modlen < 12 || modlen > *outlen || inlen > modlen - 11) {
 
510
                wpa_printf(MSG_DEBUG, "PKCS #1: %s - Invalid buffer "
 
511
                           "lengths (modlen=%lu outlen=%lu inlen=%lu)",
 
512
                           __func__, (unsigned long) modlen,
 
513
                           (unsigned long) *outlen,
 
514
                           (unsigned long) inlen);
 
515
                return -1;
 
516
        }
 
517
 
 
518
        pos = out;
 
519
        *pos++ = 0x00;
 
520
        *pos++ = block_type; /* BT */
 
521
        ps_len = modlen - inlen - 3;
 
522
        switch (block_type) {
 
523
        case 0:
 
524
                os_memset(pos, 0x00, ps_len);
 
525
                pos += ps_len;
 
526
                break;
 
527
        case 1:
 
528
                os_memset(pos, 0xff, ps_len);
 
529
                pos += ps_len;
 
530
                break;
 
531
        case 2:
 
532
                if (os_get_random(pos, ps_len) < 0) {
 
533
                        wpa_printf(MSG_DEBUG, "PKCS #1: %s - Failed to get "
 
534
                                   "random data for PS", __func__);
 
535
                        return -1;
 
536
                }
 
537
                while (ps_len--) {
 
538
                        if (*pos == 0x00)
 
539
                                *pos = 0x01;
 
540
                        pos++;
 
541
                }
 
542
                break;
 
543
        default:
 
544
                wpa_printf(MSG_DEBUG, "PKCS #1: %s - Unsupported block type "
 
545
                           "%d", __func__, block_type);
 
546
                return -1;
 
547
        }
 
548
        *pos++ = 0x00;
 
549
        os_memcpy(pos, in, inlen); /* D */
 
550
 
 
551
        return 0;
 
552
}
 
553
 
 
554
 
 
555
static int crypto_rsa_encrypt_pkcs1(int block_type, rsa_key *key, int key_type,
 
556
                                    const u8 *in, size_t inlen,
 
557
                                    u8 *out, size_t *outlen)
 
558
{
 
559
        unsigned long len, modlen;
 
560
        int res;
 
561
 
 
562
        modlen = mp_unsigned_bin_size(key->N);
 
563
 
 
564
        if (pkcs1_generate_encryption_block(block_type, modlen, in, inlen,
 
565
                                            out, outlen) < 0)
 
566
                return -1;
 
567
 
 
568
        len = *outlen;
 
569
        res = rsa_exptmod(out, modlen, out, &len, key_type, key);
 
570
        if (res != CRYPT_OK) {
 
571
                wpa_printf(MSG_DEBUG, "LibTomCrypt: rsa_exptmod failed: %s",
 
572
                           error_to_string(res));
 
573
                return -1;
 
574
        }
 
575
        *outlen = len;
 
576
 
 
577
        return 0;
 
578
}
 
579
 
 
580
 
 
581
int crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key *key,
 
582
                                        const u8 *in, size_t inlen,
 
583
                                        u8 *out, size_t *outlen)
 
584
{
 
585
        return crypto_rsa_encrypt_pkcs1(2, &key->rsa, PK_PUBLIC, in, inlen,
 
586
                                        out, outlen);
 
587
}
 
588
 
 
589
 
 
590
int crypto_private_key_sign_pkcs1(struct crypto_private_key *key,
 
591
                                  const u8 *in, size_t inlen,
 
592
                                  u8 *out, size_t *outlen)
 
593
{
 
594
        return crypto_rsa_encrypt_pkcs1(1, &key->rsa, PK_PRIVATE, in, inlen,
 
595
                                        out, outlen);
 
596
}
 
597
 
 
598
 
 
599
void crypto_public_key_free(struct crypto_public_key *key)
 
600
{
 
601
        if (key) {
 
602
                rsa_free(&key->rsa);
 
603
                os_free(key);
 
604
        }
 
605
}
 
606
 
 
607
 
 
608
void crypto_private_key_free(struct crypto_private_key *key)
 
609
{
 
610
        if (key) {
 
611
                rsa_free(&key->rsa);
 
612
                os_free(key);
 
613
        }
 
614
}
 
615
 
 
616
 
 
617
int crypto_public_key_decrypt_pkcs1(struct crypto_public_key *key,
 
618
                                    const u8 *crypt, size_t crypt_len,
 
619
                                    u8 *plain, size_t *plain_len)
 
620
{
 
621
        int res;
 
622
        unsigned long len;
 
623
        u8 *pos;
 
624
 
 
625
        len = *plain_len;
 
626
        res = rsa_exptmod(crypt, crypt_len, plain, &len, PK_PUBLIC,
 
627
                          &key->rsa);
 
628
        if (res != CRYPT_OK) {
 
629
                wpa_printf(MSG_DEBUG, "LibTomCrypt: rsa_exptmod failed: %s",
 
630
                           error_to_string(res));
 
631
                return -1;
 
632
        }
 
633
 
 
634
        /*
 
635
         * PKCS #1 v1.5, 8.1:
 
636
         *
 
637
         * EB = 00 || BT || PS || 00 || D
 
638
         * BT = 01
 
639
         * PS = k-3-||D|| times FF
 
640
         * k = length of modulus in octets
 
641
         */
 
642
 
 
643
        if (len < 3 + 8 + 16 /* min hash len */ ||
 
644
            plain[0] != 0x00 || plain[1] != 0x01 || plain[2] != 0xff) {
 
645
                wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature EB "
 
646
                           "structure");
 
647
                return -1;
 
648
        }
 
649
 
 
650
        pos = plain + 3;
 
651
        while (pos < plain + len && *pos == 0xff)
 
652
                pos++;
 
653
        if (pos - plain - 2 < 8) {
 
654
                /* PKCS #1 v1.5, 8.1: At least eight octets long PS */
 
655
                wpa_printf(MSG_INFO, "LibTomCrypt: Too short signature "
 
656
                           "padding");
 
657
                return -1;
 
658
        }
 
659
 
 
660
        if (pos + 16 /* min hash len */ >= plain + len || *pos != 0x00) {
 
661
                wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature EB "
 
662
                           "structure (2)");
 
663
                return -1;
 
664
        }
 
665
        pos++;
 
666
        len -= pos - plain;
 
667
 
 
668
        /* Strip PKCS #1 header */
 
669
        os_memmove(plain, pos, len);
 
670
        *plain_len = len;
 
671
 
 
672
        return 0;
 
673
}
 
674
 
 
675
 
 
676
int crypto_global_init(void)
 
677
{
 
678
        ltc_mp = tfm_desc;
 
679
        /* TODO: only register algorithms that are really needed */
 
680
        if (register_hash(&md4_desc) < 0 ||
 
681
            register_hash(&md5_desc) < 0 ||
 
682
            register_hash(&sha1_desc) < 0 ||
 
683
            register_cipher(&aes_desc) < 0 ||
 
684
            register_cipher(&des_desc) < 0 ||
 
685
            register_cipher(&des3_desc) < 0) {
 
686
                wpa_printf(MSG_ERROR, "TLSv1: Failed to register "
 
687
                           "hash/cipher functions");
 
688
                return -1;
 
689
        }
 
690
 
 
691
        return 0;
 
692
}
 
693
 
 
694
 
 
695
void crypto_global_deinit(void)
 
696
{
 
697
}
 
698
 
 
699
 
 
700
#ifdef EAP_FAST
 
701
 
 
702
int crypto_mod_exp(const u8 *base, size_t base_len,
 
703
                   const u8 *power, size_t power_len,
 
704
                   const u8 *modulus, size_t modulus_len,
 
705
                   u8 *result, size_t *result_len)
 
706
{
 
707
        void *b, *p, *m, *r;
 
708
 
 
709
        if (mp_init_multi(&b, &p, &m, &r, NULL) != CRYPT_OK)
 
710
                return -1;
 
711
 
 
712
        if (mp_read_unsigned_bin(b, (u8 *) base, base_len) != CRYPT_OK ||
 
713
            mp_read_unsigned_bin(p, (u8 *) power, power_len) != CRYPT_OK ||
 
714
            mp_read_unsigned_bin(m, (u8 *) modulus, modulus_len) != CRYPT_OK)
 
715
                goto fail;
 
716
 
 
717
        if (mp_exptmod(b, p, m, r) != CRYPT_OK)
 
718
                goto fail;
 
719
 
 
720
        *result_len = mp_unsigned_bin_size(r);
 
721
        if (mp_to_unsigned_bin(r, result) != CRYPT_OK)
 
722
                goto fail;
 
723
 
 
724
        mp_clear_multi(b, p, m, r, NULL);
 
725
        return 0;
 
726
 
 
727
fail:
 
728
        mp_clear_multi(b, p, m, r, NULL);
 
729
        return -1;
 
730
}
 
731
 
 
732
#endif /* EAP_FAST */
 
733
 
 
734
#endif /* CONFIG_TLS_INTERNAL */
 
735
 
 
736
#endif /* EAP_TLS_FUNCS */