crypto_libtomcrypt.c 14 KB

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