crypto_gnutls.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. /*
  2. * WPA Supplicant / wrapper functions for libgcrypt
  3. * Copyright (c) 2004-2009, 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. #include "includes.h"
  15. #include <gcrypt.h>
  16. #include "common.h"
  17. #include "crypto.h"
  18. int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
  19. {
  20. gcry_md_hd_t hd;
  21. unsigned char *p;
  22. size_t i;
  23. if (gcry_md_open(&hd, GCRY_MD_MD4, 0) != GPG_ERR_NO_ERROR)
  24. return -1;
  25. for (i = 0; i < num_elem; i++)
  26. gcry_md_write(hd, addr[i], len[i]);
  27. p = gcry_md_read(hd, GCRY_MD_MD4);
  28. if (p)
  29. memcpy(mac, p, gcry_md_get_algo_dlen(GCRY_MD_MD4));
  30. gcry_md_close(hd);
  31. return 0;
  32. }
  33. void des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
  34. {
  35. gcry_cipher_hd_t hd;
  36. u8 pkey[8], next, tmp;
  37. int i;
  38. /* Add parity bits to the key */
  39. next = 0;
  40. for (i = 0; i < 7; i++) {
  41. tmp = key[i];
  42. pkey[i] = (tmp >> i) | next | 1;
  43. next = tmp << (7 - i);
  44. }
  45. pkey[i] = next | 1;
  46. gcry_cipher_open(&hd, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
  47. gcry_err_code(gcry_cipher_setkey(hd, pkey, 8));
  48. gcry_cipher_encrypt(hd, cypher, 8, clear, 8);
  49. gcry_cipher_close(hd);
  50. }
  51. int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
  52. {
  53. gcry_md_hd_t hd;
  54. unsigned char *p;
  55. size_t i;
  56. if (gcry_md_open(&hd, GCRY_MD_MD5, 0) != GPG_ERR_NO_ERROR)
  57. return -1;
  58. for (i = 0; i < num_elem; i++)
  59. gcry_md_write(hd, addr[i], len[i]);
  60. p = gcry_md_read(hd, GCRY_MD_MD5);
  61. if (p)
  62. memcpy(mac, p, gcry_md_get_algo_dlen(GCRY_MD_MD5));
  63. gcry_md_close(hd);
  64. return 0;
  65. }
  66. int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
  67. {
  68. gcry_md_hd_t hd;
  69. unsigned char *p;
  70. size_t i;
  71. if (gcry_md_open(&hd, GCRY_MD_SHA1, 0) != GPG_ERR_NO_ERROR)
  72. return -1;
  73. for (i = 0; i < num_elem; i++)
  74. gcry_md_write(hd, addr[i], len[i]);
  75. p = gcry_md_read(hd, GCRY_MD_SHA1);
  76. if (p)
  77. memcpy(mac, p, gcry_md_get_algo_dlen(GCRY_MD_SHA1));
  78. gcry_md_close(hd);
  79. return 0;
  80. }
  81. void * aes_encrypt_init(const u8 *key, size_t len)
  82. {
  83. gcry_cipher_hd_t hd;
  84. if (gcry_cipher_open(&hd, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0) !=
  85. GPG_ERR_NO_ERROR) {
  86. printf("cipher open failed\n");
  87. return NULL;
  88. }
  89. if (gcry_cipher_setkey(hd, key, len) != GPG_ERR_NO_ERROR) {
  90. printf("setkey failed\n");
  91. gcry_cipher_close(hd);
  92. return NULL;
  93. }
  94. return hd;
  95. }
  96. void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
  97. {
  98. gcry_cipher_hd_t hd = ctx;
  99. gcry_cipher_encrypt(hd, crypt, 16, plain, 16);
  100. }
  101. void aes_encrypt_deinit(void *ctx)
  102. {
  103. gcry_cipher_hd_t hd = ctx;
  104. gcry_cipher_close(hd);
  105. }
  106. void * aes_decrypt_init(const u8 *key, size_t len)
  107. {
  108. gcry_cipher_hd_t hd;
  109. if (gcry_cipher_open(&hd, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0) !=
  110. GPG_ERR_NO_ERROR)
  111. return NULL;
  112. if (gcry_cipher_setkey(hd, key, len) != GPG_ERR_NO_ERROR) {
  113. gcry_cipher_close(hd);
  114. return NULL;
  115. }
  116. return hd;
  117. }
  118. void aes_decrypt(void *ctx, const u8 *crypt, u8 *plain)
  119. {
  120. gcry_cipher_hd_t hd = ctx;
  121. gcry_cipher_decrypt(hd, plain, 16, crypt, 16);
  122. }
  123. void aes_decrypt_deinit(void *ctx)
  124. {
  125. gcry_cipher_hd_t hd = ctx;
  126. gcry_cipher_close(hd);
  127. }
  128. int crypto_mod_exp(const u8 *base, size_t base_len,
  129. const u8 *power, size_t power_len,
  130. const u8 *modulus, size_t modulus_len,
  131. u8 *result, size_t *result_len)
  132. {
  133. gcry_mpi_t bn_base = NULL, bn_exp = NULL, bn_modulus = NULL,
  134. bn_result = NULL;
  135. int ret = -1;
  136. if (gcry_mpi_scan(&bn_base, GCRYMPI_FMT_USG, base, base_len, NULL) !=
  137. GPG_ERR_NO_ERROR ||
  138. gcry_mpi_scan(&bn_exp, GCRYMPI_FMT_USG, power, power_len, NULL) !=
  139. GPG_ERR_NO_ERROR ||
  140. gcry_mpi_scan(&bn_modulus, GCRYMPI_FMT_USG, modulus, modulus_len,
  141. NULL) != GPG_ERR_NO_ERROR)
  142. goto error;
  143. bn_result = gcry_mpi_new(modulus_len * 8);
  144. gcry_mpi_powm(bn_result, bn_base, bn_exp, bn_modulus);
  145. if (gcry_mpi_print(GCRYMPI_FMT_USG, result, *result_len, result_len,
  146. bn_result) != GPG_ERR_NO_ERROR)
  147. goto error;
  148. ret = 0;
  149. error:
  150. gcry_mpi_release(bn_base);
  151. gcry_mpi_release(bn_exp);
  152. gcry_mpi_release(bn_modulus);
  153. gcry_mpi_release(bn_result);
  154. return ret;
  155. }
  156. struct crypto_cipher {
  157. gcry_cipher_hd_t enc;
  158. gcry_cipher_hd_t dec;
  159. };
  160. struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
  161. const u8 *iv, const u8 *key,
  162. size_t key_len)
  163. {
  164. struct crypto_cipher *ctx;
  165. gcry_error_t res;
  166. enum gcry_cipher_algos a;
  167. int ivlen;
  168. ctx = os_zalloc(sizeof(*ctx));
  169. if (ctx == NULL)
  170. return NULL;
  171. switch (alg) {
  172. case CRYPTO_CIPHER_ALG_RC4:
  173. a = GCRY_CIPHER_ARCFOUR;
  174. res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_STREAM,
  175. 0);
  176. gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_STREAM, 0);
  177. break;
  178. case CRYPTO_CIPHER_ALG_AES:
  179. if (key_len == 24)
  180. a = GCRY_CIPHER_AES192;
  181. else if (key_len == 32)
  182. a = GCRY_CIPHER_AES256;
  183. else
  184. a = GCRY_CIPHER_AES;
  185. res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_CBC, 0);
  186. gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_CBC, 0);
  187. break;
  188. case CRYPTO_CIPHER_ALG_3DES:
  189. a = GCRY_CIPHER_3DES;
  190. res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_CBC, 0);
  191. gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_CBC, 0);
  192. break;
  193. case CRYPTO_CIPHER_ALG_DES:
  194. a = GCRY_CIPHER_DES;
  195. res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_CBC, 0);
  196. gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_CBC, 0);
  197. break;
  198. case CRYPTO_CIPHER_ALG_RC2:
  199. if (key_len == 5)
  200. a = GCRY_CIPHER_RFC2268_40;
  201. else
  202. a = GCRY_CIPHER_RFC2268_128;
  203. res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_CBC, 0);
  204. gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_CBC, 0);
  205. break;
  206. default:
  207. os_free(ctx);
  208. return NULL;
  209. }
  210. if (res != GPG_ERR_NO_ERROR) {
  211. os_free(ctx);
  212. return NULL;
  213. }
  214. if (gcry_cipher_setkey(ctx->enc, key, key_len) != GPG_ERR_NO_ERROR ||
  215. gcry_cipher_setkey(ctx->dec, key, key_len) != GPG_ERR_NO_ERROR) {
  216. gcry_cipher_close(ctx->enc);
  217. gcry_cipher_close(ctx->dec);
  218. os_free(ctx);
  219. return NULL;
  220. }
  221. ivlen = gcry_cipher_get_algo_blklen(a);
  222. if (gcry_cipher_setiv(ctx->enc, iv, ivlen) != GPG_ERR_NO_ERROR ||
  223. gcry_cipher_setiv(ctx->dec, iv, ivlen) != GPG_ERR_NO_ERROR) {
  224. gcry_cipher_close(ctx->enc);
  225. gcry_cipher_close(ctx->dec);
  226. os_free(ctx);
  227. return NULL;
  228. }
  229. return ctx;
  230. }
  231. int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
  232. u8 *crypt, size_t len)
  233. {
  234. if (gcry_cipher_encrypt(ctx->enc, crypt, len, plain, len) !=
  235. GPG_ERR_NO_ERROR)
  236. return -1;
  237. return 0;
  238. }
  239. int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
  240. u8 *plain, size_t len)
  241. {
  242. if (gcry_cipher_decrypt(ctx->dec, plain, len, crypt, len) !=
  243. GPG_ERR_NO_ERROR)
  244. return -1;
  245. return 0;
  246. }
  247. void crypto_cipher_deinit(struct crypto_cipher *ctx)
  248. {
  249. gcry_cipher_close(ctx->enc);
  250. gcry_cipher_close(ctx->dec);
  251. os_free(ctx);
  252. }