BEncryption.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  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 <base/BLog.h>
  23. #include <security/BEncryption.h>
  24. #include <generated/blog_channel_BEncryption.h>
  25. int BEncryption_cipher_valid (int cipher)
  26. {
  27. switch (cipher) {
  28. case BENCRYPTION_CIPHER_BLOWFISH:
  29. case BENCRYPTION_CIPHER_AES:
  30. return 1;
  31. default:
  32. return 0;
  33. }
  34. }
  35. int BEncryption_cipher_block_size (int cipher)
  36. {
  37. switch (cipher) {
  38. case BENCRYPTION_CIPHER_BLOWFISH:
  39. return BENCRYPTION_CIPHER_BLOWFISH_BLOCK_SIZE;
  40. case BENCRYPTION_CIPHER_AES:
  41. return BENCRYPTION_CIPHER_AES_BLOCK_SIZE;
  42. default:
  43. ASSERT(0)
  44. return 0;
  45. }
  46. }
  47. int BEncryption_cipher_key_size (int cipher)
  48. {
  49. switch (cipher) {
  50. case BENCRYPTION_CIPHER_BLOWFISH:
  51. return BENCRYPTION_CIPHER_BLOWFISH_KEY_SIZE;
  52. case BENCRYPTION_CIPHER_AES:
  53. return BENCRYPTION_CIPHER_AES_KEY_SIZE;
  54. default:
  55. ASSERT(0)
  56. return 0;
  57. }
  58. }
  59. void BEncryption_Init (BEncryption *enc, int mode, int cipher, uint8_t *key)
  60. {
  61. ASSERT(!(mode&~(BENCRYPTION_MODE_ENCRYPT|BENCRYPTION_MODE_DECRYPT)))
  62. ASSERT((mode&BENCRYPTION_MODE_ENCRYPT) || (mode&BENCRYPTION_MODE_DECRYPT))
  63. enc->mode = mode;
  64. enc->cipher = cipher;
  65. #ifdef BADVPN_USE_CRYPTODEV
  66. switch (enc->cipher) {
  67. case BENCRYPTION_CIPHER_AES:
  68. enc->cryptodev.cipher = CRYPTO_AES_CBC;
  69. break;
  70. default:
  71. goto fail1;
  72. }
  73. if ((enc->cryptodev.fd = open("/dev/crypto", O_RDWR, 0)) < 0) {
  74. BLog(BLOG_ERROR, "failed to open /dev/crypto");
  75. goto fail1;
  76. }
  77. if (ioctl(enc->cryptodev.fd, CRIOGET, &enc->cryptodev.cfd)) {
  78. BLog(BLOG_ERROR, "failed ioctl(CRIOGET)");
  79. goto fail2;
  80. }
  81. struct session_op sess;
  82. memset(&sess, 0, sizeof(sess));
  83. sess.cipher = enc->cryptodev.cipher;
  84. sess.keylen = BEncryption_cipher_key_size(enc->cipher);
  85. sess.key = key;
  86. if (ioctl(enc->cryptodev.cfd, CIOCGSESSION, &sess)) {
  87. BLog(BLOG_ERROR, "failed ioctl(CIOCGSESSION)");
  88. goto fail3;
  89. }
  90. enc->cryptodev.ses = sess.ses;
  91. enc->use_cryptodev = 1;
  92. goto success;
  93. fail3:
  94. ASSERT_FORCE(close(enc->cryptodev.cfd) == 0)
  95. fail2:
  96. ASSERT_FORCE(close(enc->cryptodev.fd) == 0)
  97. fail1:
  98. enc->use_cryptodev = 0;
  99. #endif
  100. int res;
  101. switch (enc->cipher) {
  102. case BENCRYPTION_CIPHER_BLOWFISH:
  103. BF_set_key(&enc->blowfish, BENCRYPTION_CIPHER_BLOWFISH_KEY_SIZE, key);
  104. break;
  105. case BENCRYPTION_CIPHER_AES:
  106. if (enc->mode&BENCRYPTION_MODE_ENCRYPT) {
  107. res = AES_set_encrypt_key(key, 128, &enc->aes.encrypt);
  108. ASSERT(res >= 0)
  109. }
  110. if (enc->mode&BENCRYPTION_MODE_DECRYPT) {
  111. res = AES_set_decrypt_key(key, 128, &enc->aes.decrypt);
  112. ASSERT(res >= 0)
  113. }
  114. break;
  115. default:
  116. ASSERT(0)
  117. ;
  118. }
  119. success:
  120. // init debug object
  121. DebugObject_Init(&enc->d_obj);
  122. }
  123. void BEncryption_Free (BEncryption *enc)
  124. {
  125. // free debug object
  126. DebugObject_Free(&enc->d_obj);
  127. #ifdef BADVPN_USE_CRYPTODEV
  128. if (enc->use_cryptodev) {
  129. ASSERT_FORCE(ioctl(enc->cryptodev.cfd, CIOCFSESSION, &enc->cryptodev.ses) == 0)
  130. ASSERT_FORCE(close(enc->cryptodev.cfd) == 0)
  131. ASSERT_FORCE(close(enc->cryptodev.fd) == 0)
  132. }
  133. #endif
  134. }
  135. void BEncryption_Encrypt (BEncryption *enc, uint8_t *in, uint8_t *out, int len, uint8_t *iv)
  136. {
  137. ASSERT(enc->mode&BENCRYPTION_MODE_ENCRYPT)
  138. ASSERT(len >= 0)
  139. ASSERT(len % BEncryption_cipher_block_size(enc->cipher) == 0)
  140. #ifdef BADVPN_USE_CRYPTODEV
  141. if (enc->use_cryptodev) {
  142. struct crypt_op cryp;
  143. memset(&cryp, 0, sizeof(cryp));
  144. cryp.ses = enc->cryptodev.ses;
  145. cryp.len = len;
  146. cryp.src = in;
  147. cryp.dst = out;
  148. cryp.iv = iv;
  149. cryp.op = COP_ENCRYPT;
  150. ASSERT_FORCE(ioctl(enc->cryptodev.cfd, CIOCCRYPT, &cryp) == 0)
  151. return;
  152. }
  153. #endif
  154. switch (enc->cipher) {
  155. case BENCRYPTION_CIPHER_BLOWFISH:
  156. BF_cbc_encrypt(in, out, len, &enc->blowfish, iv, BF_ENCRYPT);
  157. break;
  158. case BENCRYPTION_CIPHER_AES:
  159. AES_cbc_encrypt(in, out, len, &enc->aes.encrypt, iv, AES_ENCRYPT);
  160. break;
  161. default:
  162. ASSERT(0);
  163. }
  164. }
  165. void BEncryption_Decrypt (BEncryption *enc, uint8_t *in, uint8_t *out, int len, uint8_t *iv)
  166. {
  167. ASSERT(enc->mode&BENCRYPTION_MODE_DECRYPT)
  168. ASSERT(len >= 0)
  169. ASSERT(len % BEncryption_cipher_block_size(enc->cipher) == 0)
  170. #ifdef BADVPN_USE_CRYPTODEV
  171. if (enc->use_cryptodev) {
  172. struct crypt_op cryp;
  173. memset(&cryp, 0, sizeof(cryp));
  174. cryp.ses = enc->cryptodev.ses;
  175. cryp.len = len;
  176. cryp.src = in;
  177. cryp.dst = out;
  178. cryp.iv = iv;
  179. cryp.op = COP_DECRYPT;
  180. ASSERT_FORCE(ioctl(enc->cryptodev.cfd, CIOCCRYPT, &cryp) == 0)
  181. return;
  182. }
  183. #endif
  184. switch (enc->cipher) {
  185. case BENCRYPTION_CIPHER_BLOWFISH:
  186. BF_cbc_encrypt(in, out, len, &enc->blowfish, iv, BF_DECRYPT);
  187. break;
  188. case BENCRYPTION_CIPHER_AES:
  189. AES_cbc_encrypt(in, out, len, &enc->aes.decrypt, iv, AES_DECRYPT);
  190. break;
  191. default:
  192. ASSERT(0);
  193. }
  194. }