00001
00016 #include "includes.h"
00017 #include <tomcrypt.h>
00018
00019 #include "common.h"
00020 #include "crypto.h"
00021
00022 #ifndef mp_init_multi
00023 #define mp_init_multi ltc_init_multi
00024 #define mp_clear_multi ltc_deinit_multi
00025 #define mp_unsigned_bin_size(a) ltc_mp.unsigned_size(a)
00026 #define mp_to_unsigned_bin(a, b) ltc_mp.unsigned_write(a, b)
00027 #define mp_read_unsigned_bin(a, b, c) ltc_mp.unsigned_read(a, b, c)
00028 #define mp_exptmod(a,b,c,d) ltc_mp.exptmod(a,b,c,d)
00029 #endif
00030
00031
00032 int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
00033 {
00034 hash_state md;
00035 size_t i;
00036
00037 md4_init(&md);
00038 for (i = 0; i < num_elem; i++)
00039 md4_process(&md, addr[i], len[i]);
00040 md4_done(&md, mac);
00041 return 0;
00042 }
00043
00044
00045 void des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
00046 {
00047 u8 pkey[8], next, tmp;
00048 int i;
00049 symmetric_key skey;
00050
00051
00052 next = 0;
00053 for (i = 0; i < 7; i++) {
00054 tmp = key[i];
00055 pkey[i] = (tmp >> i) | next | 1;
00056 next = tmp << (7 - i);
00057 }
00058 pkey[i] = next | 1;
00059
00060 des_setup(pkey, 8, 0, &skey);
00061 des_ecb_encrypt(clear, cypher, &skey);
00062 des_done(&skey);
00063 }
00064
00065
00066 #ifdef EAP_TLS_FUNCS
00067 int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
00068 {
00069 hash_state md;
00070 size_t i;
00071
00072 md5_init(&md);
00073 for (i = 0; i < num_elem; i++)
00074 md5_process(&md, addr[i], len[i]);
00075 md5_done(&md, mac);
00076 return 0;
00077 }
00078
00079
00080 int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
00081 {
00082 hash_state md;
00083 size_t i;
00084
00085 sha1_init(&md);
00086 for (i = 0; i < num_elem; i++)
00087 sha1_process(&md, addr[i], len[i]);
00088 sha1_done(&md, mac);
00089 return 0;
00090 }
00091
00092
00093 void * aes_encrypt_init(const u8 *key, size_t len)
00094 {
00095 symmetric_key *skey;
00096 skey = os_malloc(sizeof(*skey));
00097 if (skey == NULL)
00098 return NULL;
00099 if (aes_setup(key, len, 0, skey) != CRYPT_OK) {
00100 os_free(skey);
00101 return NULL;
00102 }
00103 return skey;
00104 }
00105
00106
00107 void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
00108 {
00109 symmetric_key *skey = ctx;
00110 aes_ecb_encrypt(plain, crypt, skey);
00111 }
00112
00113
00114 void aes_encrypt_deinit(void *ctx)
00115 {
00116 symmetric_key *skey = ctx;
00117 aes_done(skey);
00118 os_free(skey);
00119 }
00120
00121
00122 void * aes_decrypt_init(const u8 *key, size_t len)
00123 {
00124 symmetric_key *skey;
00125 skey = os_malloc(sizeof(*skey));
00126 if (skey == NULL)
00127 return NULL;
00128 if (aes_setup(key, len, 0, skey) != CRYPT_OK) {
00129 os_free(skey);
00130 return NULL;
00131 }
00132 return skey;
00133 }
00134
00135
00136 void aes_decrypt(void *ctx, const u8 *crypt, u8 *plain)
00137 {
00138 symmetric_key *skey = ctx;
00139 aes_ecb_encrypt(plain, (u8 *) crypt, skey);
00140 }
00141
00142
00143 void aes_decrypt_deinit(void *ctx)
00144 {
00145 symmetric_key *skey = ctx;
00146 aes_done(skey);
00147 os_free(skey);
00148 }
00149
00150
00151 #ifdef CONFIG_TLS_INTERNAL
00152
00153 struct crypto_hash {
00154 enum crypto_hash_alg alg;
00155 int error;
00156 union {
00157 hash_state md;
00158 hmac_state hmac;
00159 } u;
00160 };
00161
00162
00163 struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
00164 size_t key_len)
00165 {
00166 struct crypto_hash *ctx;
00167
00168 ctx = os_zalloc(sizeof(*ctx));
00169 if (ctx == NULL)
00170 return NULL;
00171
00172 ctx->alg = alg;
00173
00174 switch (alg) {
00175 case CRYPTO_HASH_ALG_MD5:
00176 if (md5_init(&ctx->u.md) != CRYPT_OK)
00177 goto fail;
00178 break;
00179 case CRYPTO_HASH_ALG_SHA1:
00180 if (sha1_init(&ctx->u.md) != CRYPT_OK)
00181 goto fail;
00182 break;
00183 case CRYPTO_HASH_ALG_HMAC_MD5:
00184 if (hmac_init(&ctx->u.hmac, find_hash("md5"), key, key_len) !=
00185 CRYPT_OK)
00186 goto fail;
00187 break;
00188 case CRYPTO_HASH_ALG_HMAC_SHA1:
00189 if (hmac_init(&ctx->u.hmac, find_hash("sha1"), key, key_len) !=
00190 CRYPT_OK)
00191 goto fail;
00192 break;
00193 default:
00194 goto fail;
00195 }
00196
00197 return ctx;
00198
00199 fail:
00200 os_free(ctx);
00201 return NULL;
00202 }
00203
00204 void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
00205 {
00206 if (ctx == NULL || ctx->error)
00207 return;
00208
00209 switch (ctx->alg) {
00210 case CRYPTO_HASH_ALG_MD5:
00211 ctx->error = md5_process(&ctx->u.md, data, len) != CRYPT_OK;
00212 break;
00213 case CRYPTO_HASH_ALG_SHA1:
00214 ctx->error = sha1_process(&ctx->u.md, data, len) != CRYPT_OK;
00215 break;
00216 case CRYPTO_HASH_ALG_HMAC_MD5:
00217 case CRYPTO_HASH_ALG_HMAC_SHA1:
00218 ctx->error = hmac_process(&ctx->u.hmac, data, len) != CRYPT_OK;
00219 break;
00220 }
00221 }
00222
00223
00224 int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
00225 {
00226 int ret = 0;
00227 unsigned long clen;
00228
00229 if (ctx == NULL)
00230 return -2;
00231
00232 if (mac == NULL || len == NULL) {
00233 os_free(ctx);
00234 return 0;
00235 }
00236
00237 if (ctx->error) {
00238 os_free(ctx);
00239 return -2;
00240 }
00241
00242 switch (ctx->alg) {
00243 case CRYPTO_HASH_ALG_MD5:
00244 if (*len < 16) {
00245 *len = 16;
00246 os_free(ctx);
00247 return -1;
00248 }
00249 *len = 16;
00250 if (md5_done(&ctx->u.md, mac) != CRYPT_OK)
00251 ret = -2;
00252 break;
00253 case CRYPTO_HASH_ALG_SHA1:
00254 if (*len < 20) {
00255 *len = 20;
00256 os_free(ctx);
00257 return -1;
00258 }
00259 *len = 20;
00260 if (sha1_done(&ctx->u.md, mac) != CRYPT_OK)
00261 ret = -2;
00262 break;
00263 case CRYPTO_HASH_ALG_HMAC_SHA1:
00264 if (*len < 20) {
00265 *len = 20;
00266 os_free(ctx);
00267 return -1;
00268 }
00269
00270 case CRYPTO_HASH_ALG_HMAC_MD5:
00271 if (*len < 16) {
00272 *len = 16;
00273 os_free(ctx);
00274 return -1;
00275 }
00276 clen = *len;
00277 if (hmac_done(&ctx->u.hmac, mac, &clen) != CRYPT_OK) {
00278 os_free(ctx);
00279 return -1;
00280 }
00281 *len = clen;
00282 break;
00283 default:
00284 ret = -2;
00285 break;
00286 }
00287
00288 os_free(ctx);
00289
00290 return ret;
00291 }
00292
00293
00294 struct crypto_cipher {
00295 int rc4;
00296 union {
00297 symmetric_CBC cbc;
00298 struct {
00299 size_t used_bytes;
00300 u8 key[16];
00301 size_t keylen;
00302 } rc4;
00303 } u;
00304 };
00305
00306
00307 struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
00308 const u8 *iv, const u8 *key,
00309 size_t key_len)
00310 {
00311 struct crypto_cipher *ctx;
00312 int idx, res, rc4 = 0;
00313
00314 switch (alg) {
00315 case CRYPTO_CIPHER_ALG_AES:
00316 idx = find_cipher("aes");
00317 break;
00318 case CRYPTO_CIPHER_ALG_3DES:
00319 idx = find_cipher("3des");
00320 break;
00321 case CRYPTO_CIPHER_ALG_DES:
00322 idx = find_cipher("des");
00323 break;
00324 case CRYPTO_CIPHER_ALG_RC2:
00325 idx = find_cipher("rc2");
00326 break;
00327 case CRYPTO_CIPHER_ALG_RC4:
00328 idx = -1;
00329 rc4 = 1;
00330 break;
00331 default:
00332 return NULL;
00333 }
00334
00335 ctx = os_zalloc(sizeof(*ctx));
00336 if (ctx == NULL)
00337 return NULL;
00338
00339 if (rc4) {
00340 ctx->rc4 = 1;
00341 if (key_len > sizeof(ctx->u.rc4.key)) {
00342 os_free(ctx);
00343 return NULL;
00344 }
00345 ctx->u.rc4.keylen = key_len;
00346 os_memcpy(ctx->u.rc4.key, key, key_len);
00347 } else {
00348 res = cbc_start(idx, iv, key, key_len, 0, &ctx->u.cbc);
00349 if (res != CRYPT_OK) {
00350 wpa_printf(MSG_DEBUG, "LibTomCrypt: Cipher start "
00351 "failed: %s", error_to_string(res));
00352 os_free(ctx);
00353 return NULL;
00354 }
00355 }
00356
00357 return ctx;
00358 }
00359
00360 int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
00361 u8 *crypt, size_t len)
00362 {
00363 int res;
00364
00365 if (ctx->rc4) {
00366 if (plain != crypt)
00367 os_memcpy(crypt, plain, len);
00368 rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen,
00369 ctx->u.rc4.used_bytes, crypt, len);
00370 ctx->u.rc4.used_bytes += len;
00371 return 0;
00372 }
00373
00374 res = cbc_encrypt(plain, crypt, len, &ctx->u.cbc);
00375 if (res != CRYPT_OK) {
00376 wpa_printf(MSG_DEBUG, "LibTomCrypt: CBC encryption "
00377 "failed: %s", error_to_string(res));
00378 return -1;
00379 }
00380 return 0;
00381 }
00382
00383
00384 int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
00385 u8 *plain, size_t len)
00386 {
00387 int res;
00388
00389 if (ctx->rc4) {
00390 if (plain != crypt)
00391 os_memcpy(plain, crypt, len);
00392 rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen,
00393 ctx->u.rc4.used_bytes, plain, len);
00394 ctx->u.rc4.used_bytes += len;
00395 return 0;
00396 }
00397
00398 res = cbc_decrypt(crypt, plain, len, &ctx->u.cbc);
00399 if (res != CRYPT_OK) {
00400 wpa_printf(MSG_DEBUG, "LibTomCrypt: CBC decryption "
00401 "failed: %s", error_to_string(res));
00402 return -1;
00403 }
00404
00405 return 0;
00406 }
00407
00408
00409 void crypto_cipher_deinit(struct crypto_cipher *ctx)
00410 {
00411 if (!ctx->rc4)
00412 cbc_done(&ctx->u.cbc);
00413 os_free(ctx);
00414 }
00415
00416
00417 struct crypto_public_key {
00418 rsa_key rsa;
00419 };
00420
00421 struct crypto_private_key {
00422 rsa_key rsa;
00423 };
00424
00425
00426 struct crypto_public_key * crypto_public_key_import(const u8 *key, size_t len)
00427 {
00428 int res;
00429 struct crypto_public_key *pk;
00430
00431 pk = os_zalloc(sizeof(*pk));
00432 if (pk == NULL)
00433 return NULL;
00434
00435 res = rsa_import(key, len, &pk->rsa);
00436 if (res != CRYPT_OK) {
00437 wpa_printf(MSG_ERROR, "LibTomCrypt: Failed to import "
00438 "public key (res=%d '%s')",
00439 res, error_to_string(res));
00440 os_free(pk);
00441 return NULL;
00442 }
00443
00444 if (pk->rsa.type != PK_PUBLIC) {
00445 wpa_printf(MSG_ERROR, "LibTomCrypt: Public key was not of "
00446 "correct type");
00447 rsa_free(&pk->rsa);
00448 os_free(pk);
00449 return NULL;
00450 }
00451
00452 return pk;
00453 }
00454
00455
00456 struct crypto_private_key * crypto_private_key_import(const u8 *key,
00457 size_t len,
00458 const char *passwd)
00459 {
00460 int res;
00461 struct crypto_private_key *pk;
00462
00463 pk = os_zalloc(sizeof(*pk));
00464 if (pk == NULL)
00465 return NULL;
00466
00467 res = rsa_import(key, len, &pk->rsa);
00468 if (res != CRYPT_OK) {
00469 wpa_printf(MSG_ERROR, "LibTomCrypt: Failed to import "
00470 "private key (res=%d '%s')",
00471 res, error_to_string(res));
00472 os_free(pk);
00473 return NULL;
00474 }
00475
00476 if (pk->rsa.type != PK_PRIVATE) {
00477 wpa_printf(MSG_ERROR, "LibTomCrypt: Private key was not of "
00478 "correct type");
00479 rsa_free(&pk->rsa);
00480 os_free(pk);
00481 return NULL;
00482 }
00483
00484 return pk;
00485 }
00486
00487
00488 struct crypto_public_key * crypto_public_key_from_cert(const u8 *buf,
00489 size_t len)
00490 {
00491
00492 return NULL;
00493 }
00494
00495
00496 static int pkcs1_generate_encryption_block(u8 block_type, size_t modlen,
00497 const u8 *in, size_t inlen,
00498 u8 *out, size_t *outlen)
00499 {
00500 size_t ps_len;
00501 u8 *pos;
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513 if (modlen < 12 || modlen > *outlen || inlen > modlen - 11) {
00514 wpa_printf(MSG_DEBUG, "PKCS #1: %s - Invalid buffer "
00515 "lengths (modlen=%lu outlen=%lu inlen=%lu)",
00516 __func__, (unsigned long) modlen,
00517 (unsigned long) *outlen,
00518 (unsigned long) inlen);
00519 return -1;
00520 }
00521
00522 pos = out;
00523 *pos++ = 0x00;
00524 *pos++ = block_type;
00525 ps_len = modlen - inlen - 3;
00526 switch (block_type) {
00527 case 0:
00528 os_memset(pos, 0x00, ps_len);
00529 pos += ps_len;
00530 break;
00531 case 1:
00532 os_memset(pos, 0xff, ps_len);
00533 pos += ps_len;
00534 break;
00535 case 2:
00536 if (os_get_random(pos, ps_len) < 0) {
00537 wpa_printf(MSG_DEBUG, "PKCS #1: %s - Failed to get "
00538 "random data for PS", __func__);
00539 return -1;
00540 }
00541 while (ps_len--) {
00542 if (*pos == 0x00)
00543 *pos = 0x01;
00544 pos++;
00545 }
00546 break;
00547 default:
00548 wpa_printf(MSG_DEBUG, "PKCS #1: %s - Unsupported block type "
00549 "%d", __func__, block_type);
00550 return -1;
00551 }
00552 *pos++ = 0x00;
00553 os_memcpy(pos, in, inlen);
00554
00555 return 0;
00556 }
00557
00558
00559 static int crypto_rsa_encrypt_pkcs1(int block_type, rsa_key *key, int key_type,
00560 const u8 *in, size_t inlen,
00561 u8 *out, size_t *outlen)
00562 {
00563 unsigned long len, modlen;
00564 int res;
00565
00566 modlen = mp_unsigned_bin_size(key->N);
00567
00568 if (pkcs1_generate_encryption_block(block_type, modlen, in, inlen,
00569 out, outlen) < 0)
00570 return -1;
00571
00572 len = *outlen;
00573 res = rsa_exptmod(out, modlen, out, &len, key_type, key);
00574 if (res != CRYPT_OK) {
00575 wpa_printf(MSG_DEBUG, "LibTomCrypt: rsa_exptmod failed: %s",
00576 error_to_string(res));
00577 return -1;
00578 }
00579 *outlen = len;
00580
00581 return 0;
00582 }
00583
00584
00585 int crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key *key,
00586 const u8 *in, size_t inlen,
00587 u8 *out, size_t *outlen)
00588 {
00589 return crypto_rsa_encrypt_pkcs1(2, &key->rsa, PK_PUBLIC, in, inlen,
00590 out, outlen);
00591 }
00592
00593
00594 int crypto_private_key_sign_pkcs1(struct crypto_private_key *key,
00595 const u8 *in, size_t inlen,
00596 u8 *out, size_t *outlen)
00597 {
00598 return crypto_rsa_encrypt_pkcs1(1, &key->rsa, PK_PRIVATE, in, inlen,
00599 out, outlen);
00600 }
00601
00602
00603 void crypto_public_key_free(struct crypto_public_key *key)
00604 {
00605 if (key) {
00606 rsa_free(&key->rsa);
00607 os_free(key);
00608 }
00609 }
00610
00611
00612 void crypto_private_key_free(struct crypto_private_key *key)
00613 {
00614 if (key) {
00615 rsa_free(&key->rsa);
00616 os_free(key);
00617 }
00618 }
00619
00620
00621 int crypto_public_key_decrypt_pkcs1(struct crypto_public_key *key,
00622 const u8 *crypt, size_t crypt_len,
00623 u8 *plain, size_t *plain_len)
00624 {
00625 int res;
00626 unsigned long len;
00627 u8 *pos;
00628
00629 len = *plain_len;
00630 res = rsa_exptmod(crypt, crypt_len, plain, &len, PK_PUBLIC,
00631 &key->rsa);
00632 if (res != CRYPT_OK) {
00633 wpa_printf(MSG_DEBUG, "LibTomCrypt: rsa_exptmod failed: %s",
00634 error_to_string(res));
00635 return -1;
00636 }
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647 if (len < 3 + 8 + 16 ||
00648 plain[0] != 0x00 || plain[1] != 0x01 || plain[2] != 0xff) {
00649 wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature EB "
00650 "structure");
00651 return -1;
00652 }
00653
00654 pos = plain + 3;
00655 while (pos < plain + len && *pos == 0xff)
00656 pos++;
00657 if (pos - plain - 2 < 8) {
00658
00659 wpa_printf(MSG_INFO, "LibTomCrypt: Too short signature "
00660 "padding");
00661 return -1;
00662 }
00663
00664 if (pos + 16 >= plain + len || *pos != 0x00) {
00665 wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature EB "
00666 "structure (2)");
00667 return -1;
00668 }
00669 pos++;
00670 len -= pos - plain;
00671
00672
00673 os_memmove(plain, pos, len);
00674 *plain_len = len;
00675
00676 return 0;
00677 }
00678
00679
00680 int crypto_global_init(void)
00681 {
00682 ltc_mp = tfm_desc;
00683
00684 if (register_hash(&md4_desc) < 0 ||
00685 register_hash(&md5_desc) < 0 ||
00686 register_hash(&sha1_desc) < 0 ||
00687 register_cipher(&aes_desc) < 0 ||
00688 register_cipher(&des_desc) < 0 ||
00689 register_cipher(&des3_desc) < 0) {
00690 wpa_printf(MSG_ERROR, "TLSv1: Failed to register "
00691 "hash/cipher functions");
00692 return -1;
00693 }
00694
00695 return 0;
00696 }
00697
00698
00699 void crypto_global_deinit(void)
00700 {
00701 }
00702
00703
00704 #ifdef CONFIG_MODEXP
00705
00706 int crypto_mod_exp(const u8 *base, size_t base_len,
00707 const u8 *power, size_t power_len,
00708 const u8 *modulus, size_t modulus_len,
00709 u8 *result, size_t *result_len)
00710 {
00711 void *b, *p, *m, *r;
00712
00713 if (mp_init_multi(&b, &p, &m, &r, NULL) != CRYPT_OK)
00714 return -1;
00715
00716 if (mp_read_unsigned_bin(b, (u8 *) base, base_len) != CRYPT_OK ||
00717 mp_read_unsigned_bin(p, (u8 *) power, power_len) != CRYPT_OK ||
00718 mp_read_unsigned_bin(m, (u8 *) modulus, modulus_len) != CRYPT_OK)
00719 goto fail;
00720
00721 if (mp_exptmod(b, p, m, r) != CRYPT_OK)
00722 goto fail;
00723
00724 *result_len = mp_unsigned_bin_size(r);
00725 if (mp_to_unsigned_bin(r, result) != CRYPT_OK)
00726 goto fail;
00727
00728 mp_clear_multi(b, p, m, r, NULL);
00729 return 0;
00730
00731 fail:
00732 mp_clear_multi(b, p, m, r, NULL);
00733 return -1;
00734 }
00735
00736 #endif
00737
00738 #endif
00739
00740 #endif
00741