BEncryption.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /**
  2. * @file BEncryption.c
  3. * @author Ambroz Bizjak <ambrop7@gmail.com>
  4. *
  5. * @section LICENSE
  6. *
  7. * This file is part of BadVPN.
  8. *
  9. * BadVPN is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License version 2
  11. * as published by the Free Software Foundation.
  12. *
  13. * BadVPN is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License along
  19. * with this program; if not, write to the Free Software Foundation, Inc.,
  20. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  21. */
  22. #include <security/BEncryption.h>
  23. int BEncryption_cipher_valid (int cipher)
  24. {
  25. switch (cipher) {
  26. case BENCRYPTION_CIPHER_BLOWFISH:
  27. case BENCRYPTION_CIPHER_AES:
  28. return 1;
  29. default:
  30. return 0;
  31. }
  32. }
  33. int BEncryption_cipher_block_size (int cipher)
  34. {
  35. switch (cipher) {
  36. case BENCRYPTION_CIPHER_BLOWFISH:
  37. return BENCRYPTION_CIPHER_BLOWFISH_BLOCK_SIZE;
  38. case BENCRYPTION_CIPHER_AES:
  39. return BENCRYPTION_CIPHER_AES_BLOCK_SIZE;
  40. default:
  41. ASSERT(0)
  42. return 0;
  43. }
  44. }
  45. int BEncryption_cipher_key_size (int cipher)
  46. {
  47. switch (cipher) {
  48. case BENCRYPTION_CIPHER_BLOWFISH:
  49. return BENCRYPTION_CIPHER_BLOWFISH_KEY_SIZE;
  50. case BENCRYPTION_CIPHER_AES:
  51. return BENCRYPTION_CIPHER_AES_KEY_SIZE;
  52. default:
  53. ASSERT(0)
  54. return 0;
  55. }
  56. }
  57. void BEncryption_Init (BEncryption *enc, int mode, int cipher, uint8_t *key)
  58. {
  59. ASSERT(!(mode&~(BENCRYPTION_MODE_ENCRYPT|BENCRYPTION_MODE_DECRYPT)))
  60. ASSERT((mode&BENCRYPTION_MODE_ENCRYPT) || (mode&BENCRYPTION_MODE_DECRYPT))
  61. enc->mode = mode;
  62. enc->cipher = cipher;
  63. #ifdef BADVPN_USE_CRYPTODEV
  64. switch (enc->cipher) {
  65. case BENCRYPTION_CIPHER_AES:
  66. enc->cryptodev.cipher = CRYPTO_AES_CBC;
  67. break;
  68. default:
  69. goto fail1;
  70. }
  71. if ((enc->cryptodev.fd = open("/dev/crypto", O_RDWR, 0)) < 0) {
  72. DEBUG("failed to open /dev/crypto");
  73. goto fail1;
  74. }
  75. if (ioctl(enc->cryptodev.fd, CRIOGET, &enc->cryptodev.cfd)) {
  76. DEBUG("failed ioctl(CRIOGET)");
  77. goto fail2;
  78. }
  79. struct session_op sess;
  80. memset(&sess, 0, sizeof(sess));
  81. sess.cipher = enc->cryptodev.cipher;
  82. sess.keylen = BEncryption_cipher_key_size(enc->cipher);
  83. sess.key = key;
  84. if (ioctl(enc->cryptodev.cfd, CIOCGSESSION, &sess)) {
  85. DEBUG("failed ioctl(CIOCGSESSION)");
  86. goto fail3;
  87. }
  88. enc->cryptodev.ses = sess.ses;
  89. enc->use_cryptodev = 1;
  90. goto success;
  91. fail3:
  92. ASSERT_FORCE(close(enc->cryptodev.cfd) == 0)
  93. fail2:
  94. ASSERT_FORCE(close(enc->cryptodev.fd) == 0)
  95. fail1:
  96. enc->use_cryptodev = 0;
  97. #endif
  98. int res;
  99. switch (enc->cipher) {
  100. case BENCRYPTION_CIPHER_BLOWFISH:
  101. BF_set_key(&enc->blowfish, BENCRYPTION_CIPHER_BLOWFISH_KEY_SIZE, key);
  102. break;
  103. case BENCRYPTION_CIPHER_AES:
  104. if (enc->mode&BENCRYPTION_MODE_ENCRYPT) {
  105. res = AES_set_encrypt_key(key, 128, &enc->aes.encrypt);
  106. ASSERT(res >= 0)
  107. }
  108. if (enc->mode&BENCRYPTION_MODE_DECRYPT) {
  109. res = AES_set_decrypt_key(key, 128, &enc->aes.decrypt);
  110. ASSERT(res >= 0)
  111. }
  112. break;
  113. default:
  114. ASSERT(0)
  115. ;
  116. }
  117. success:
  118. // init debug object
  119. DebugObject_Init(&enc->d_obj);
  120. }
  121. void BEncryption_Free (BEncryption *enc)
  122. {
  123. // free debug object
  124. DebugObject_Free(&enc->d_obj);
  125. #ifdef BADVPN_USE_CRYPTODEV
  126. if (enc->use_cryptodev) {
  127. ASSERT_FORCE(ioctl(enc->cryptodev.cfd, CIOCFSESSION, &enc->cryptodev.ses) == 0)
  128. ASSERT_FORCE(close(enc->cryptodev.cfd) == 0)
  129. ASSERT_FORCE(close(enc->cryptodev.fd) == 0)
  130. }
  131. #endif
  132. }
  133. void BEncryption_Encrypt (BEncryption *enc, uint8_t *in, uint8_t *out, int len, uint8_t *iv)
  134. {
  135. ASSERT(enc->mode&BENCRYPTION_MODE_ENCRYPT)
  136. ASSERT(len >= 0)
  137. ASSERT(len % BEncryption_cipher_block_size(enc->cipher) == 0)
  138. #ifdef BADVPN_USE_CRYPTODEV
  139. if (enc->use_cryptodev) {
  140. struct crypt_op cryp;
  141. memset(&cryp, 0, sizeof(cryp));
  142. cryp.ses = enc->cryptodev.ses;
  143. cryp.len = len;
  144. cryp.src = in;
  145. cryp.dst = out;
  146. cryp.iv = iv;
  147. cryp.op = COP_ENCRYPT;
  148. ASSERT_FORCE(ioctl(enc->cryptodev.cfd, CIOCCRYPT, &cryp) == 0)
  149. return;
  150. }
  151. #endif
  152. switch (enc->cipher) {
  153. case BENCRYPTION_CIPHER_BLOWFISH:
  154. BF_cbc_encrypt(in, out, len, &enc->blowfish, iv, BF_ENCRYPT);
  155. break;
  156. case BENCRYPTION_CIPHER_AES:
  157. AES_cbc_encrypt(in, out, len, &enc->aes.encrypt, iv, AES_ENCRYPT);
  158. break;
  159. default:
  160. ASSERT(0);
  161. }
  162. }
  163. void BEncryption_Decrypt (BEncryption *enc, uint8_t *in, uint8_t *out, int len, uint8_t *iv)
  164. {
  165. ASSERT(enc->mode&BENCRYPTION_MODE_DECRYPT)
  166. ASSERT(len >= 0)
  167. ASSERT(len % BEncryption_cipher_block_size(enc->cipher) == 0)
  168. #ifdef BADVPN_USE_CRYPTODEV
  169. if (enc->use_cryptodev) {
  170. struct crypt_op cryp;
  171. memset(&cryp, 0, sizeof(cryp));
  172. cryp.ses = enc->cryptodev.ses;
  173. cryp.len = len;
  174. cryp.src = in;
  175. cryp.dst = out;
  176. cryp.iv = iv;
  177. cryp.op = COP_DECRYPT;
  178. ASSERT_FORCE(ioctl(enc->cryptodev.cfd, CIOCCRYPT, &cryp) == 0)
  179. return;
  180. }
  181. #endif
  182. switch (enc->cipher) {
  183. case BENCRYPTION_CIPHER_BLOWFISH:
  184. BF_cbc_encrypt(in, out, len, &enc->blowfish, iv, BF_DECRYPT);
  185. break;
  186. case BENCRYPTION_CIPHER_AES:
  187. AES_cbc_encrypt(in, out, len, &enc->aes.decrypt, iv, AES_DECRYPT);
  188. break;
  189. default:
  190. ASSERT(0);
  191. }
  192. }