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