2
0

cipher-gcrypt.c.inc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. /*
  2. * QEMU Crypto cipher libgcrypt algorithms
  3. *
  4. * Copyright (c) 2015 Red Hat, Inc.
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  18. *
  19. */
  20. #ifdef CONFIG_QEMU_PRIVATE_XTS
  21. #include "crypto/xts.h"
  22. #endif
  23. #include <gcrypt.h>
  24. bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
  25. QCryptoCipherMode mode)
  26. {
  27. switch (alg) {
  28. case QCRYPTO_CIPHER_ALG_DES_RFB:
  29. case QCRYPTO_CIPHER_ALG_3DES:
  30. case QCRYPTO_CIPHER_ALG_AES_128:
  31. case QCRYPTO_CIPHER_ALG_AES_192:
  32. case QCRYPTO_CIPHER_ALG_AES_256:
  33. case QCRYPTO_CIPHER_ALG_CAST5_128:
  34. case QCRYPTO_CIPHER_ALG_SERPENT_128:
  35. case QCRYPTO_CIPHER_ALG_SERPENT_192:
  36. case QCRYPTO_CIPHER_ALG_SERPENT_256:
  37. case QCRYPTO_CIPHER_ALG_TWOFISH_128:
  38. case QCRYPTO_CIPHER_ALG_TWOFISH_256:
  39. break;
  40. default:
  41. return false;
  42. }
  43. switch (mode) {
  44. case QCRYPTO_CIPHER_MODE_ECB:
  45. case QCRYPTO_CIPHER_MODE_CBC:
  46. case QCRYPTO_CIPHER_MODE_XTS:
  47. case QCRYPTO_CIPHER_MODE_CTR:
  48. return true;
  49. default:
  50. return false;
  51. }
  52. }
  53. typedef struct QCryptoCipherGcrypt {
  54. QCryptoCipher base;
  55. gcry_cipher_hd_t handle;
  56. size_t blocksize;
  57. #ifdef CONFIG_QEMU_PRIVATE_XTS
  58. gcry_cipher_hd_t tweakhandle;
  59. uint8_t iv[XTS_BLOCK_SIZE];
  60. #endif
  61. } QCryptoCipherGcrypt;
  62. static void qcrypto_gcrypt_ctx_free(QCryptoCipher *cipher)
  63. {
  64. QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
  65. gcry_cipher_close(ctx->handle);
  66. g_free(ctx);
  67. }
  68. static int qcrypto_gcrypt_encrypt(QCryptoCipher *cipher, const void *in,
  69. void *out, size_t len, Error **errp)
  70. {
  71. QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
  72. gcry_error_t err;
  73. if (len & (ctx->blocksize - 1)) {
  74. error_setg(errp, "Length %zu must be a multiple of block size %zu",
  75. len, ctx->blocksize);
  76. return -1;
  77. }
  78. err = gcry_cipher_encrypt(ctx->handle, out, len, in, len);
  79. if (err != 0) {
  80. error_setg(errp, "Cannot encrypt data: %s", gcry_strerror(err));
  81. return -1;
  82. }
  83. return 0;
  84. }
  85. static int qcrypto_gcrypt_decrypt(QCryptoCipher *cipher, const void *in,
  86. void *out, size_t len, Error **errp)
  87. {
  88. QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
  89. gcry_error_t err;
  90. if (len & (ctx->blocksize - 1)) {
  91. error_setg(errp, "Length %zu must be a multiple of block size %zu",
  92. len, ctx->blocksize);
  93. return -1;
  94. }
  95. err = gcry_cipher_decrypt(ctx->handle, out, len, in, len);
  96. if (err != 0) {
  97. error_setg(errp, "Cannot decrypt data: %s",
  98. gcry_strerror(err));
  99. return -1;
  100. }
  101. return 0;
  102. }
  103. static int qcrypto_gcrypt_setiv(QCryptoCipher *cipher,
  104. const uint8_t *iv, size_t niv,
  105. Error **errp)
  106. {
  107. QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
  108. gcry_error_t err;
  109. if (niv != ctx->blocksize) {
  110. error_setg(errp, "Expected IV size %zu not %zu",
  111. ctx->blocksize, niv);
  112. return -1;
  113. }
  114. gcry_cipher_reset(ctx->handle);
  115. err = gcry_cipher_setiv(ctx->handle, iv, niv);
  116. if (err != 0) {
  117. error_setg(errp, "Cannot set IV: %s", gcry_strerror(err));
  118. return -1;
  119. }
  120. return 0;
  121. }
  122. static int qcrypto_gcrypt_ctr_setiv(QCryptoCipher *cipher,
  123. const uint8_t *iv, size_t niv,
  124. Error **errp)
  125. {
  126. QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
  127. gcry_error_t err;
  128. if (niv != ctx->blocksize) {
  129. error_setg(errp, "Expected IV size %zu not %zu",
  130. ctx->blocksize, niv);
  131. return -1;
  132. }
  133. err = gcry_cipher_setctr(ctx->handle, iv, niv);
  134. if (err != 0) {
  135. error_setg(errp, "Cannot set Counter: %s", gcry_strerror(err));
  136. return -1;
  137. }
  138. return 0;
  139. }
  140. static const struct QCryptoCipherDriver qcrypto_gcrypt_driver = {
  141. .cipher_encrypt = qcrypto_gcrypt_encrypt,
  142. .cipher_decrypt = qcrypto_gcrypt_decrypt,
  143. .cipher_setiv = qcrypto_gcrypt_setiv,
  144. .cipher_free = qcrypto_gcrypt_ctx_free,
  145. };
  146. static const struct QCryptoCipherDriver qcrypto_gcrypt_ctr_driver = {
  147. .cipher_encrypt = qcrypto_gcrypt_encrypt,
  148. .cipher_decrypt = qcrypto_gcrypt_decrypt,
  149. .cipher_setiv = qcrypto_gcrypt_ctr_setiv,
  150. .cipher_free = qcrypto_gcrypt_ctx_free,
  151. };
  152. #ifdef CONFIG_QEMU_PRIVATE_XTS
  153. static void qcrypto_gcrypt_xts_ctx_free(QCryptoCipher *cipher)
  154. {
  155. QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
  156. gcry_cipher_close(ctx->tweakhandle);
  157. qcrypto_gcrypt_ctx_free(cipher);
  158. }
  159. static void qcrypto_gcrypt_xts_wrape(const void *ctx, size_t length,
  160. uint8_t *dst, const uint8_t *src)
  161. {
  162. gcry_error_t err;
  163. err = gcry_cipher_encrypt((gcry_cipher_hd_t)ctx, dst, length, src, length);
  164. g_assert(err == 0);
  165. }
  166. static void qcrypto_gcrypt_xts_wrapd(const void *ctx, size_t length,
  167. uint8_t *dst, const uint8_t *src)
  168. {
  169. gcry_error_t err;
  170. err = gcry_cipher_decrypt((gcry_cipher_hd_t)ctx, dst, length, src, length);
  171. g_assert(err == 0);
  172. }
  173. static int qcrypto_gcrypt_xts_encrypt(QCryptoCipher *cipher, const void *in,
  174. void *out, size_t len, Error **errp)
  175. {
  176. QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
  177. if (len & (ctx->blocksize - 1)) {
  178. error_setg(errp, "Length %zu must be a multiple of block size %zu",
  179. len, ctx->blocksize);
  180. return -1;
  181. }
  182. xts_encrypt(ctx->handle, ctx->tweakhandle,
  183. qcrypto_gcrypt_xts_wrape, qcrypto_gcrypt_xts_wrapd,
  184. ctx->iv, len, out, in);
  185. return 0;
  186. }
  187. static int qcrypto_gcrypt_xts_decrypt(QCryptoCipher *cipher, const void *in,
  188. void *out, size_t len, Error **errp)
  189. {
  190. QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
  191. if (len & (ctx->blocksize - 1)) {
  192. error_setg(errp, "Length %zu must be a multiple of block size %zu",
  193. len, ctx->blocksize);
  194. return -1;
  195. }
  196. xts_decrypt(ctx->handle, ctx->tweakhandle,
  197. qcrypto_gcrypt_xts_wrape, qcrypto_gcrypt_xts_wrapd,
  198. ctx->iv, len, out, in);
  199. return 0;
  200. }
  201. static int qcrypto_gcrypt_xts_setiv(QCryptoCipher *cipher,
  202. const uint8_t *iv, size_t niv,
  203. Error **errp)
  204. {
  205. QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
  206. if (niv != ctx->blocksize) {
  207. error_setg(errp, "Expected IV size %zu not %zu",
  208. ctx->blocksize, niv);
  209. return -1;
  210. }
  211. memcpy(ctx->iv, iv, niv);
  212. return 0;
  213. }
  214. static const struct QCryptoCipherDriver qcrypto_gcrypt_xts_driver = {
  215. .cipher_encrypt = qcrypto_gcrypt_xts_encrypt,
  216. .cipher_decrypt = qcrypto_gcrypt_xts_decrypt,
  217. .cipher_setiv = qcrypto_gcrypt_xts_setiv,
  218. .cipher_free = qcrypto_gcrypt_xts_ctx_free,
  219. };
  220. #endif /* CONFIG_QEMU_PRIVATE_XTS */
  221. static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
  222. QCryptoCipherMode mode,
  223. const uint8_t *key,
  224. size_t nkey,
  225. Error **errp)
  226. {
  227. QCryptoCipherGcrypt *ctx;
  228. const QCryptoCipherDriver *drv;
  229. gcry_error_t err;
  230. int gcryalg, gcrymode;
  231. if (!qcrypto_cipher_validate_key_length(alg, mode, nkey, errp)) {
  232. return NULL;
  233. }
  234. switch (alg) {
  235. case QCRYPTO_CIPHER_ALG_DES_RFB:
  236. gcryalg = GCRY_CIPHER_DES;
  237. break;
  238. case QCRYPTO_CIPHER_ALG_3DES:
  239. gcryalg = GCRY_CIPHER_3DES;
  240. break;
  241. case QCRYPTO_CIPHER_ALG_AES_128:
  242. gcryalg = GCRY_CIPHER_AES128;
  243. break;
  244. case QCRYPTO_CIPHER_ALG_AES_192:
  245. gcryalg = GCRY_CIPHER_AES192;
  246. break;
  247. case QCRYPTO_CIPHER_ALG_AES_256:
  248. gcryalg = GCRY_CIPHER_AES256;
  249. break;
  250. case QCRYPTO_CIPHER_ALG_CAST5_128:
  251. gcryalg = GCRY_CIPHER_CAST5;
  252. break;
  253. case QCRYPTO_CIPHER_ALG_SERPENT_128:
  254. gcryalg = GCRY_CIPHER_SERPENT128;
  255. break;
  256. case QCRYPTO_CIPHER_ALG_SERPENT_192:
  257. gcryalg = GCRY_CIPHER_SERPENT192;
  258. break;
  259. case QCRYPTO_CIPHER_ALG_SERPENT_256:
  260. gcryalg = GCRY_CIPHER_SERPENT256;
  261. break;
  262. case QCRYPTO_CIPHER_ALG_TWOFISH_128:
  263. gcryalg = GCRY_CIPHER_TWOFISH128;
  264. break;
  265. case QCRYPTO_CIPHER_ALG_TWOFISH_256:
  266. gcryalg = GCRY_CIPHER_TWOFISH;
  267. break;
  268. default:
  269. error_setg(errp, "Unsupported cipher algorithm %s",
  270. QCryptoCipherAlgorithm_str(alg));
  271. return NULL;
  272. }
  273. drv = &qcrypto_gcrypt_driver;
  274. switch (mode) {
  275. case QCRYPTO_CIPHER_MODE_ECB:
  276. gcrymode = GCRY_CIPHER_MODE_ECB;
  277. break;
  278. case QCRYPTO_CIPHER_MODE_XTS:
  279. #ifdef CONFIG_QEMU_PRIVATE_XTS
  280. drv = &qcrypto_gcrypt_xts_driver;
  281. gcrymode = GCRY_CIPHER_MODE_ECB;
  282. #else
  283. gcrymode = GCRY_CIPHER_MODE_XTS;
  284. #endif
  285. break;
  286. case QCRYPTO_CIPHER_MODE_CBC:
  287. gcrymode = GCRY_CIPHER_MODE_CBC;
  288. break;
  289. case QCRYPTO_CIPHER_MODE_CTR:
  290. drv = &qcrypto_gcrypt_ctr_driver;
  291. gcrymode = GCRY_CIPHER_MODE_CTR;
  292. break;
  293. default:
  294. error_setg(errp, "Unsupported cipher mode %s",
  295. QCryptoCipherMode_str(mode));
  296. return NULL;
  297. }
  298. ctx = g_new0(QCryptoCipherGcrypt, 1);
  299. ctx->base.driver = drv;
  300. err = gcry_cipher_open(&ctx->handle, gcryalg, gcrymode, 0);
  301. if (err != 0) {
  302. error_setg(errp, "Cannot initialize cipher: %s",
  303. gcry_strerror(err));
  304. goto error;
  305. }
  306. ctx->blocksize = gcry_cipher_get_algo_blklen(gcryalg);
  307. #ifdef CONFIG_QEMU_PRIVATE_XTS
  308. if (mode == QCRYPTO_CIPHER_MODE_XTS) {
  309. if (ctx->blocksize != XTS_BLOCK_SIZE) {
  310. error_setg(errp,
  311. "Cipher block size %zu must equal XTS block size %d",
  312. ctx->blocksize, XTS_BLOCK_SIZE);
  313. goto error;
  314. }
  315. err = gcry_cipher_open(&ctx->tweakhandle, gcryalg, gcrymode, 0);
  316. if (err != 0) {
  317. error_setg(errp, "Cannot initialize cipher: %s",
  318. gcry_strerror(err));
  319. goto error;
  320. }
  321. }
  322. #endif
  323. if (alg == QCRYPTO_CIPHER_ALG_DES_RFB) {
  324. /* We're using standard DES cipher from gcrypt, so we need
  325. * to munge the key so that the results are the same as the
  326. * bizarre RFB variant of DES :-)
  327. */
  328. uint8_t *rfbkey = qcrypto_cipher_munge_des_rfb_key(key, nkey);
  329. err = gcry_cipher_setkey(ctx->handle, rfbkey, nkey);
  330. g_free(rfbkey);
  331. } else {
  332. #ifdef CONFIG_QEMU_PRIVATE_XTS
  333. if (mode == QCRYPTO_CIPHER_MODE_XTS) {
  334. nkey /= 2;
  335. err = gcry_cipher_setkey(ctx->tweakhandle, key + nkey, nkey);
  336. if (err != 0) {
  337. error_setg(errp, "Cannot set key: %s", gcry_strerror(err));
  338. goto error;
  339. }
  340. }
  341. #endif
  342. err = gcry_cipher_setkey(ctx->handle, key, nkey);
  343. }
  344. if (err != 0) {
  345. error_setg(errp, "Cannot set key: %s", gcry_strerror(err));
  346. goto error;
  347. }
  348. return &ctx->base;
  349. error:
  350. #ifdef CONFIG_QEMU_PRIVATE_XTS
  351. gcry_cipher_close(ctx->tweakhandle);
  352. #endif
  353. gcry_cipher_close(ctx->handle);
  354. g_free(ctx);
  355. return NULL;
  356. }