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

« back to all changes in this revision

Viewing changes to src/crypto/crypto_internal.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 internal crypto implementation
 
3
 * Copyright (c) 2006-2007, 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
 
 
17
#include "common.h"
 
18
#include "crypto.h"
 
19
#include "md5.h"
 
20
#include "sha1.h"
 
21
#include "rc4.h"
 
22
#include "aes.h"
 
23
#include "tls/rsa.h"
 
24
#include "tls/bignum.h"
 
25
 
 
26
 
 
27
#ifdef EAP_TLS_FUNCS
 
28
 
 
29
#ifdef CONFIG_TLS_INTERNAL
 
30
 
 
31
/* from des.c */
 
32
struct des3_key_s {
 
33
        u32 ek[3][32];
 
34
        u32 dk[3][32];
 
35
};
 
36
 
 
37
void des3_key_setup(const u8 *key, struct des3_key_s *dkey);
 
38
void des3_encrypt(const u8 *plain, const struct des3_key_s *key, u8 *crypt);
 
39
void des3_decrypt(const u8 *crypt, const struct des3_key_s *key, u8 *plain);
 
40
 
 
41
 
 
42
struct MD5Context {
 
43
        u32 buf[4];
 
44
        u32 bits[2];
 
45
        u8 in[64];
 
46
};
 
47
 
 
48
struct SHA1Context {
 
49
        u32 state[5];
 
50
        u32 count[2];
 
51
        unsigned char buffer[64];
 
52
};
 
53
 
 
54
 
 
55
struct crypto_hash {
 
56
        enum crypto_hash_alg alg;
 
57
        union {
 
58
                struct MD5Context md5;
 
59
                struct SHA1Context sha1;
 
60
        } u;
 
61
        u8 key[64];
 
62
        size_t key_len;
 
63
};
 
64
 
 
65
 
 
66
struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
 
67
                                      size_t key_len)
 
68
{
 
69
        struct crypto_hash *ctx;
 
70
        u8 k_pad[64];
 
71
        u8 tk[20];
 
72
        size_t i;
 
73
 
 
74
        ctx = os_zalloc(sizeof(*ctx));
 
75
        if (ctx == NULL)
 
76
                return NULL;
 
77
 
 
78
        ctx->alg = alg;
 
79
 
 
80
        switch (alg) {
 
81
        case CRYPTO_HASH_ALG_MD5:
 
82
                MD5Init(&ctx->u.md5);
 
83
                break;
 
84
        case CRYPTO_HASH_ALG_SHA1:
 
85
                SHA1Init(&ctx->u.sha1);
 
86
                break;
 
87
        case CRYPTO_HASH_ALG_HMAC_MD5:
 
88
                if (key_len > sizeof(k_pad)) {
 
89
                        MD5Init(&ctx->u.md5);
 
90
                        MD5Update(&ctx->u.md5, key, key_len);
 
91
                        MD5Final(tk, &ctx->u.md5);
 
92
                        key = tk;
 
93
                        key_len = 16;
 
94
                }
 
95
                os_memcpy(ctx->key, key, key_len);
 
96
                ctx->key_len = key_len;
 
97
 
 
98
                os_memcpy(k_pad, key, key_len);
 
99
                os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len);
 
100
                for (i = 0; i < sizeof(k_pad); i++)
 
101
                        k_pad[i] ^= 0x36;
 
102
                MD5Init(&ctx->u.md5);
 
103
                MD5Update(&ctx->u.md5, k_pad, sizeof(k_pad));
 
104
                break;
 
105
        case CRYPTO_HASH_ALG_HMAC_SHA1:
 
106
                if (key_len > sizeof(k_pad)) {
 
107
                        SHA1Init(&ctx->u.sha1);
 
108
                        SHA1Update(&ctx->u.sha1, key, key_len);
 
109
                        SHA1Final(tk, &ctx->u.sha1);
 
110
                        key = tk;
 
111
                        key_len = 20;
 
112
                }
 
113
                os_memcpy(ctx->key, key, key_len);
 
114
                ctx->key_len = key_len;
 
115
 
 
116
                os_memcpy(k_pad, key, key_len);
 
117
                os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len);
 
118
                for (i = 0; i < sizeof(k_pad); i++)
 
119
                        k_pad[i] ^= 0x36;
 
120
                SHA1Init(&ctx->u.sha1);
 
121
                SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad));
 
122
                break;
 
123
        default:
 
124
                os_free(ctx);
 
125
                return NULL;
 
126
        }
 
127
 
 
128
        return ctx;
 
129
}
 
130
 
 
131
 
 
132
void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
 
133
{
 
134
        if (ctx == NULL)
 
135
                return;
 
136
 
 
137
        switch (ctx->alg) {
 
138
        case CRYPTO_HASH_ALG_MD5:
 
139
        case CRYPTO_HASH_ALG_HMAC_MD5:
 
140
                MD5Update(&ctx->u.md5, data, len);
 
141
                break;
 
142
        case CRYPTO_HASH_ALG_SHA1:
 
143
        case CRYPTO_HASH_ALG_HMAC_SHA1:
 
144
                SHA1Update(&ctx->u.sha1, data, len);
 
145
                break;
 
146
        }
 
147
}
 
148
 
 
149
 
 
150
int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
 
151
{
 
152
        u8 k_pad[64];
 
153
        size_t i;
 
154
 
 
155
        if (ctx == NULL)
 
156
                return -2;
 
157
 
 
158
        if (mac == NULL || len == NULL) {
 
159
                os_free(ctx);
 
160
                return 0;
 
161
        }
 
162
 
 
163
        switch (ctx->alg) {
 
164
        case CRYPTO_HASH_ALG_MD5:
 
165
                if (*len < 16) {
 
166
                        *len = 16;
 
167
                        os_free(ctx);
 
168
                        return -1;
 
169
                }
 
170
                *len = 16;
 
171
                MD5Final(mac, &ctx->u.md5);
 
172
                break;
 
173
        case CRYPTO_HASH_ALG_SHA1:
 
174
                if (*len < 20) {
 
175
                        *len = 20;
 
176
                        os_free(ctx);
 
177
                        return -1;
 
178
                }
 
179
                *len = 20;
 
180
                SHA1Final(mac, &ctx->u.sha1);
 
181
                break;
 
182
        case CRYPTO_HASH_ALG_HMAC_MD5:
 
183
                if (*len < 16) {
 
184
                        *len = 16;
 
185
                        os_free(ctx);
 
186
                        return -1;
 
187
                }
 
188
                *len = 16;
 
189
 
 
190
                MD5Final(mac, &ctx->u.md5);
 
191
 
 
192
                os_memcpy(k_pad, ctx->key, ctx->key_len);
 
193
                os_memset(k_pad + ctx->key_len, 0,
 
194
                          sizeof(k_pad) - ctx->key_len);
 
195
                for (i = 0; i < sizeof(k_pad); i++)
 
196
                        k_pad[i] ^= 0x5c;
 
197
                MD5Init(&ctx->u.md5);
 
198
                MD5Update(&ctx->u.md5, k_pad, sizeof(k_pad));
 
199
                MD5Update(&ctx->u.md5, mac, 16);
 
200
                MD5Final(mac, &ctx->u.md5);
 
201
                break;
 
202
        case CRYPTO_HASH_ALG_HMAC_SHA1:
 
203
                if (*len < 20) {
 
204
                        *len = 20;
 
205
                        os_free(ctx);
 
206
                        return -1;
 
207
                }
 
208
                *len = 20;
 
209
 
 
210
                SHA1Final(mac, &ctx->u.sha1);
 
211
 
 
212
                os_memcpy(k_pad, ctx->key, ctx->key_len);
 
213
                os_memset(k_pad + ctx->key_len, 0,
 
214
                          sizeof(k_pad) - ctx->key_len);
 
215
                for (i = 0; i < sizeof(k_pad); i++)
 
216
                        k_pad[i] ^= 0x5c;
 
217
                SHA1Init(&ctx->u.sha1);
 
218
                SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad));
 
219
                SHA1Update(&ctx->u.sha1, mac, 20);
 
220
                SHA1Final(mac, &ctx->u.sha1);
 
221
                break;
 
222
        }
 
223
 
 
224
        os_free(ctx);
 
225
 
 
226
        return 0;
 
227
}
 
228
 
 
229
 
 
230
struct crypto_cipher {
 
231
        enum crypto_cipher_alg alg;
 
232
        union {
 
233
                struct {
 
234
                        size_t used_bytes;
 
235
                        u8 key[16];
 
236
                        size_t keylen;
 
237
                } rc4;
 
238
                struct {
 
239
                        u8 cbc[32];
 
240
                        size_t block_size;
 
241
                        void *ctx_enc;
 
242
                        void *ctx_dec;
 
243
                } aes;
 
244
                struct {
 
245
                        struct des3_key_s key;
 
246
                        u8 cbc[8];
 
247
                } des3;
 
248
        } u;
 
249
};
 
250
 
 
251
 
 
252
struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
 
253
                                          const u8 *iv, const u8 *key,
 
254
                                          size_t key_len)
 
255
{
 
256
        struct crypto_cipher *ctx;
 
257
 
 
258
        ctx = os_zalloc(sizeof(*ctx));
 
259
        if (ctx == NULL)
 
260
                return NULL;
 
261
 
 
262
        ctx->alg = alg;
 
263
 
 
264
        switch (alg) {
 
265
        case CRYPTO_CIPHER_ALG_RC4:
 
266
                if (key_len > sizeof(ctx->u.rc4.key)) {
 
267
                        os_free(ctx);
 
268
                        return NULL;
 
269
                }
 
270
                ctx->u.rc4.keylen = key_len;
 
271
                os_memcpy(ctx->u.rc4.key, key, key_len);
 
272
                break;
 
273
        case CRYPTO_CIPHER_ALG_AES:
 
274
                if (key_len > sizeof(ctx->u.aes.cbc)) {
 
275
                        os_free(ctx);
 
276
                        return NULL;
 
277
                }
 
278
                ctx->u.aes.ctx_enc = aes_encrypt_init(key, key_len);
 
279
                if (ctx->u.aes.ctx_enc == NULL) {
 
280
                        os_free(ctx);
 
281
                        return NULL;
 
282
                }
 
283
                ctx->u.aes.ctx_dec = aes_decrypt_init(key, key_len);
 
284
                if (ctx->u.aes.ctx_dec == NULL) {
 
285
                        aes_encrypt_deinit(ctx->u.aes.ctx_enc);
 
286
                        os_free(ctx);
 
287
                        return NULL;
 
288
                }
 
289
                ctx->u.aes.block_size = key_len;
 
290
                os_memcpy(ctx->u.aes.cbc, iv, ctx->u.aes.block_size);
 
291
                break;
 
292
        case CRYPTO_CIPHER_ALG_3DES:
 
293
                if (key_len != 24) {
 
294
                        os_free(ctx);
 
295
                        return NULL;
 
296
                }
 
297
                des3_key_setup(key, &ctx->u.des3.key);
 
298
                os_memcpy(ctx->u.des3.cbc, iv, 8);
 
299
                break;
 
300
        default:
 
301
                os_free(ctx);
 
302
                return NULL;
 
303
        }
 
304
 
 
305
        return ctx;
 
306
}
 
307
 
 
308
 
 
309
int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
 
310
                          u8 *crypt, size_t len)
 
311
{
 
312
        size_t i, j, blocks;
 
313
 
 
314
        switch (ctx->alg) {
 
315
        case CRYPTO_CIPHER_ALG_RC4:
 
316
                if (plain != crypt)
 
317
                        os_memcpy(crypt, plain, len);
 
318
                rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen,
 
319
                         ctx->u.rc4.used_bytes, crypt, len);
 
320
                ctx->u.rc4.used_bytes += len;
 
321
                break;
 
322
        case CRYPTO_CIPHER_ALG_AES:
 
323
                if (len % ctx->u.aes.block_size)
 
324
                        return -1;
 
325
                blocks = len / ctx->u.aes.block_size;
 
326
                for (i = 0; i < blocks; i++) {
 
327
                        for (j = 0; j < ctx->u.aes.block_size; j++)
 
328
                                ctx->u.aes.cbc[j] ^= plain[j];
 
329
                        aes_encrypt(ctx->u.aes.ctx_enc, ctx->u.aes.cbc,
 
330
                                    ctx->u.aes.cbc);
 
331
                        os_memcpy(crypt, ctx->u.aes.cbc,
 
332
                                  ctx->u.aes.block_size);
 
333
                        plain += ctx->u.aes.block_size;
 
334
                        crypt += ctx->u.aes.block_size;
 
335
                }
 
336
                break;
 
337
        case CRYPTO_CIPHER_ALG_3DES:
 
338
                if (len % 8)
 
339
                        return -1;
 
340
                blocks = len / 8;
 
341
                for (i = 0; i < blocks; i++) {
 
342
                        for (j = 0; j < 8; j++)
 
343
                                ctx->u.des3.cbc[j] ^= plain[j];
 
344
                        des3_encrypt(ctx->u.des3.cbc, &ctx->u.des3.key,
 
345
                                     ctx->u.des3.cbc);
 
346
                        os_memcpy(crypt, ctx->u.des3.cbc, 8);
 
347
                        plain += 8;
 
348
                        crypt += 8;
 
349
                }
 
350
                break;
 
351
        default:
 
352
                return -1;
 
353
        }
 
354
 
 
355
        return 0;
 
356
}
 
357
 
 
358
 
 
359
int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
 
360
                          u8 *plain, size_t len)
 
361
{
 
362
        size_t i, j, blocks;
 
363
        u8 tmp[32];
 
364
 
 
365
        switch (ctx->alg) {
 
366
        case CRYPTO_CIPHER_ALG_RC4:
 
367
                if (plain != crypt)
 
368
                        os_memcpy(plain, crypt, len);
 
369
                rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen,
 
370
                         ctx->u.rc4.used_bytes, plain, len);
 
371
                ctx->u.rc4.used_bytes += len;
 
372
                break;
 
373
        case CRYPTO_CIPHER_ALG_AES:
 
374
                if (len % ctx->u.aes.block_size)
 
375
                        return -1;
 
376
                blocks = len / ctx->u.aes.block_size;
 
377
                for (i = 0; i < blocks; i++) {
 
378
                        os_memcpy(tmp, crypt, ctx->u.aes.block_size);
 
379
                        aes_decrypt(ctx->u.aes.ctx_dec, crypt, plain);
 
380
                        for (j = 0; j < ctx->u.aes.block_size; j++)
 
381
                                plain[j] ^= ctx->u.aes.cbc[j];
 
382
                        os_memcpy(ctx->u.aes.cbc, tmp, ctx->u.aes.block_size);
 
383
                        plain += ctx->u.aes.block_size;
 
384
                        crypt += ctx->u.aes.block_size;
 
385
                }
 
386
                break;
 
387
        case CRYPTO_CIPHER_ALG_3DES:
 
388
                if (len % 8)
 
389
                        return -1;
 
390
                blocks = len / 8;
 
391
                for (i = 0; i < blocks; i++) {
 
392
                        os_memcpy(tmp, crypt, 8);
 
393
                        des3_decrypt(crypt, &ctx->u.des3.key, plain);
 
394
                        for (j = 0; j < 8; j++)
 
395
                                plain[j] ^= ctx->u.des3.cbc[j];
 
396
                        os_memcpy(ctx->u.des3.cbc, tmp, 8);
 
397
                        plain += 8;
 
398
                        crypt += 8;
 
399
                }
 
400
                break;
 
401
        default:
 
402
                return -1;
 
403
        }
 
404
 
 
405
        return 0;
 
406
}
 
407
 
 
408
 
 
409
void crypto_cipher_deinit(struct crypto_cipher *ctx)
 
410
{
 
411
        switch (ctx->alg) {
 
412
        case CRYPTO_CIPHER_ALG_AES:
 
413
                aes_encrypt_deinit(ctx->u.aes.ctx_enc);
 
414
                aes_decrypt_deinit(ctx->u.aes.ctx_dec);
 
415
                break;
 
416
        case CRYPTO_CIPHER_ALG_3DES:
 
417
                break;
 
418
        default:
 
419
                break;
 
420
        }
 
421
        os_free(ctx);
 
422
}
 
423
 
 
424
 
 
425
/* Dummy structures; these are just typecast to struct crypto_rsa_key */
 
426
struct crypto_public_key;
 
427
struct crypto_private_key;
 
428
 
 
429
 
 
430
struct crypto_public_key * crypto_public_key_import(const u8 *key, size_t len)
 
431
{
 
432
        return (struct crypto_public_key *)
 
433
                crypto_rsa_import_public_key(key, len);
 
434
}
 
435
 
 
436
 
 
437
struct crypto_private_key * crypto_private_key_import(const u8 *key,
 
438
                                                      size_t len)
 
439
{
 
440
        return (struct crypto_private_key *)
 
441
                crypto_rsa_import_private_key(key, len);
 
442
}
 
443
 
 
444
 
 
445
struct crypto_public_key * crypto_public_key_from_cert(const u8 *buf,
 
446
                                                       size_t len)
 
447
{
 
448
        /* No X.509 support in crypto_internal.c */
 
449
        return NULL;
 
450
}
 
451
 
 
452
 
 
453
static int pkcs1_generate_encryption_block(u8 block_type, size_t modlen,
 
454
                                           const u8 *in, size_t inlen,
 
455
                                           u8 *out, size_t *outlen)
 
456
{
 
457
        size_t ps_len;
 
458
        u8 *pos;
 
459
 
 
460
        /*
 
461
         * PKCS #1 v1.5, 8.1:
 
462
         *
 
463
         * EB = 00 || BT || PS || 00 || D
 
464
         * BT = 00 or 01 for private-key operation; 02 for public-key operation
 
465
         * PS = k-3-||D||; at least eight octets
 
466
         * (BT=0: PS=0x00, BT=1: PS=0xff, BT=2: PS=pseudorandom non-zero)
 
467
         * k = length of modulus in octets (modlen)
 
468
         */
 
469
 
 
470
        if (modlen < 12 || modlen > *outlen || inlen > modlen - 11) {
 
471
                wpa_printf(MSG_DEBUG, "PKCS #1: %s - Invalid buffer "
 
472
                           "lengths (modlen=%lu outlen=%lu inlen=%lu)",
 
473
                           __func__, (unsigned long) modlen,
 
474
                           (unsigned long) *outlen,
 
475
                           (unsigned long) inlen);
 
476
                return -1;
 
477
        }
 
478
 
 
479
        pos = out;
 
480
        *pos++ = 0x00;
 
481
        *pos++ = block_type; /* BT */
 
482
        ps_len = modlen - inlen - 3;
 
483
        switch (block_type) {
 
484
        case 0:
 
485
                os_memset(pos, 0x00, ps_len);
 
486
                pos += ps_len;
 
487
                break;
 
488
        case 1:
 
489
                os_memset(pos, 0xff, ps_len);
 
490
                pos += ps_len;
 
491
                break;
 
492
        case 2:
 
493
                if (os_get_random(pos, ps_len) < 0) {
 
494
                        wpa_printf(MSG_DEBUG, "PKCS #1: %s - Failed to get "
 
495
                                   "random data for PS", __func__);
 
496
                        return -1;
 
497
                }
 
498
                while (ps_len--) {
 
499
                        if (*pos == 0x00)
 
500
                                *pos = 0x01;
 
501
                        pos++;
 
502
                }
 
503
                break;
 
504
        default:
 
505
                wpa_printf(MSG_DEBUG, "PKCS #1: %s - Unsupported block type "
 
506
                           "%d", __func__, block_type);
 
507
                return -1;
 
508
        }
 
509
        *pos++ = 0x00;
 
510
        os_memcpy(pos, in, inlen); /* D */
 
511
 
 
512
        return 0;
 
513
}
 
514
 
 
515
 
 
516
static int crypto_rsa_encrypt_pkcs1(int block_type, struct crypto_rsa_key *key,
 
517
                                    int use_private,
 
518
                                    const u8 *in, size_t inlen,
 
519
                                    u8 *out, size_t *outlen)
 
520
{
 
521
        size_t modlen;
 
522
 
 
523
        modlen = crypto_rsa_get_modulus_len(key);
 
524
 
 
525
        if (pkcs1_generate_encryption_block(block_type, modlen, in, inlen,
 
526
                                            out, outlen) < 0)
 
527
                return -1;
 
528
 
 
529
        return crypto_rsa_exptmod(out, modlen, out, outlen, key, use_private);
 
530
}
 
531
 
 
532
 
 
533
int crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key *key,
 
534
                                        const u8 *in, size_t inlen,
 
535
                                        u8 *out, size_t *outlen)
 
536
{
 
537
        return crypto_rsa_encrypt_pkcs1(2, (struct crypto_rsa_key *) key,
 
538
                                        0, in, inlen, out, outlen);
 
539
}
 
540
 
 
541
 
 
542
int crypto_private_key_decrypt_pkcs1_v15(struct crypto_private_key *key,
 
543
                                         const u8 *in, size_t inlen,
 
544
                                         u8 *out, size_t *outlen)
 
545
{
 
546
        struct crypto_rsa_key *rkey = (struct crypto_rsa_key *) key;
 
547
        int res;
 
548
        u8 *pos, *end;
 
549
 
 
550
        res = crypto_rsa_exptmod(in, inlen, out, outlen, rkey, 1);
 
551
        if (res)
 
552
                return res;
 
553
 
 
554
        if (*outlen < 2 || out[0] != 0 || out[1] != 2)
 
555
                return -1;
 
556
 
 
557
        /* Skip PS (pseudorandom non-zero octets) */
 
558
        pos = out + 2;
 
559
        end = out + *outlen;
 
560
        while (*pos && pos < end)
 
561
                pos++;
 
562
        if (pos == end)
 
563
                return -1;
 
564
        pos++;
 
565
 
 
566
        *outlen -= pos - out;
 
567
 
 
568
        /* Strip PKCS #1 header */
 
569
        os_memmove(out, pos, *outlen);
 
570
 
 
571
        return 0;
 
572
}
 
573
 
 
574
 
 
575
int crypto_private_key_sign_pkcs1(struct crypto_private_key *key,
 
576
                                  const u8 *in, size_t inlen,
 
577
                                  u8 *out, size_t *outlen)
 
578
{
 
579
        return crypto_rsa_encrypt_pkcs1(1, (struct crypto_rsa_key *) key,
 
580
                                        1, in, inlen, out, outlen);
 
581
}
 
582
 
 
583
 
 
584
void crypto_public_key_free(struct crypto_public_key *key)
 
585
{
 
586
        crypto_rsa_free((struct crypto_rsa_key *) key);
 
587
}
 
588
 
 
589
 
 
590
void crypto_private_key_free(struct crypto_private_key *key)
 
591
{
 
592
        crypto_rsa_free((struct crypto_rsa_key *) key);
 
593
}
 
594
 
 
595
 
 
596
int crypto_public_key_decrypt_pkcs1(struct crypto_public_key *key,
 
597
                                    const u8 *crypt, size_t crypt_len,
 
598
                                    u8 *plain, size_t *plain_len)
 
599
{
 
600
        size_t len;
 
601
        u8 *pos;
 
602
 
 
603
        len = *plain_len;
 
604
        if (crypto_rsa_exptmod(crypt, crypt_len, plain, &len,
 
605
                               (struct crypto_rsa_key *) key, 0) < 0)
 
606
                return -1;
 
607
 
 
608
        /*
 
609
         * PKCS #1 v1.5, 8.1:
 
610
         *
 
611
         * EB = 00 || BT || PS || 00 || D
 
612
         * BT = 00 or 01
 
613
         * PS = k-3-||D|| times (00 if BT=00) or (FF if BT=01)
 
614
         * k = length of modulus in octets
 
615
         */
 
616
 
 
617
        if (len < 3 + 8 + 16 /* min hash len */ ||
 
618
            plain[0] != 0x00 || (plain[1] != 0x00 && plain[1] != 0x01)) {
 
619
                wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature EB "
 
620
                           "structure");
 
621
                return -1;
 
622
        }
 
623
 
 
624
        pos = plain + 3;
 
625
        if (plain[1] == 0x00) {
 
626
                /* BT = 00 */
 
627
                if (plain[2] != 0x00) {
 
628
                        wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature "
 
629
                                   "PS (BT=00)");
 
630
                        return -1;
 
631
                }
 
632
                while (pos + 1 < plain + len && *pos == 0x00 && pos[1] == 0x00)
 
633
                        pos++;
 
634
        } else {
 
635
                /* BT = 01 */
 
636
                if (plain[2] != 0xff) {
 
637
                        wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature "
 
638
                                   "PS (BT=01)");
 
639
                        return -1;
 
640
                }
 
641
                while (pos < plain + len && *pos == 0xff)
 
642
                        pos++;
 
643
        }
 
644
 
 
645
        if (pos - plain - 2 < 8) {
 
646
                /* PKCS #1 v1.5, 8.1: At least eight octets long PS */
 
647
                wpa_printf(MSG_INFO, "LibTomCrypt: Too short signature "
 
648
                           "padding");
 
649
                return -1;
 
650
        }
 
651
 
 
652
        if (pos + 16 /* min hash len */ >= plain + len || *pos != 0x00) {
 
653
                wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature EB "
 
654
                           "structure (2)");
 
655
                return -1;
 
656
        }
 
657
        pos++;
 
658
        len -= pos - plain;
 
659
 
 
660
        /* Strip PKCS #1 header */
 
661
        os_memmove(plain, pos, len);
 
662
        *plain_len = len;
 
663
 
 
664
        return 0;
 
665
}
 
666
 
 
667
 
 
668
int crypto_global_init(void)
 
669
{
 
670
        return 0;
 
671
}
 
672
 
 
673
 
 
674
void crypto_global_deinit(void)
 
675
{
 
676
}
 
677
 
 
678
 
 
679
#ifdef EAP_FAST
 
680
 
 
681
int crypto_mod_exp(const u8 *base, size_t base_len,
 
682
                   const u8 *power, size_t power_len,
 
683
                   const u8 *modulus, size_t modulus_len,
 
684
                   u8 *result, size_t *result_len)
 
685
{
 
686
        struct bignum *bn_base, *bn_exp, *bn_modulus, *bn_result;
 
687
        int ret = -1;
 
688
 
 
689
        bn_base = bignum_init();
 
690
        bn_exp = bignum_init();
 
691
        bn_modulus = bignum_init();
 
692
        bn_result = bignum_init();
 
693
 
 
694
        if (bn_base == NULL || bn_exp == NULL || bn_modulus == NULL ||
 
695
            bn_result == NULL)
 
696
                goto error;
 
697
 
 
698
        if (bignum_set_unsigned_bin(bn_base, base, base_len) < 0 ||
 
699
            bignum_set_unsigned_bin(bn_exp, power, power_len) < 0 ||
 
700
            bignum_set_unsigned_bin(bn_modulus, modulus, modulus_len) < 0)
 
701
                goto error;
 
702
 
 
703
        if (bignum_exptmod(bn_base, bn_exp, bn_modulus, bn_result) < 0)
 
704
                goto error;
 
705
 
 
706
        ret = bignum_get_unsigned_bin(bn_result, result, result_len);
 
707
 
 
708
error:
 
709
        bignum_deinit(bn_base);
 
710
        bignum_deinit(bn_exp);
 
711
        bignum_deinit(bn_modulus);
 
712
        bignum_deinit(bn_result);
 
713
        return ret;
 
714
}
 
715
 
 
716
#endif /* EAP_FAST */
 
717
 
 
718
 
 
719
#endif /* CONFIG_TLS_INTERNAL */
 
720
 
 
721
#endif /* EAP_TLS_FUNCS */