2
0

ivgen.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /*
  2. * QEMU Crypto block IV generator
  3. *
  4. * Copyright (c) 2015-2016 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. #ifndef QCRYPTO_IVGEN_H
  21. #define QCRYPTO_IVGEN_H
  22. #include "crypto/cipher.h"
  23. #include "crypto/hash.h"
  24. /**
  25. * This module provides a framework for generating initialization
  26. * vectors for block encryption schemes using chained cipher modes
  27. * CBC. The principle is that each disk sector is assigned a unique
  28. * initialization vector for use for encryption of data in that
  29. * sector.
  30. *
  31. * <example>
  32. * <title>Encrypting block data with initialization vectors</title>
  33. * <programlisting>
  34. * uint8_t *data = ....data to encrypt...
  35. * size_t ndata = XXX;
  36. * uint8_t *key = ....some encryption key...
  37. * size_t nkey = XXX;
  38. * uint8_t *iv;
  39. * size_t niv;
  40. * size_t sector = 0;
  41. *
  42. * g_assert((ndata % 512) == 0);
  43. *
  44. * QCryptoIVGen *ivgen = qcrypto_ivgen_new(QCRYPTO_IV_GEN_ALGO_ESSIV,
  45. * QCRYPTO_CIPHER_ALGO_AES_128,
  46. * QCRYPTO_HASH_ALGO_SHA256,
  47. * key, nkey, errp);
  48. * if (!ivgen) {
  49. * return -1;
  50. * }
  51. *
  52. * QCryptoCipher *cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALGO_AES_128,
  53. * QCRYPTO_CIPHER_MODE_CBC,
  54. * key, nkey, errp);
  55. * if (!cipher) {
  56. * goto error;
  57. * }
  58. *
  59. * niv = qcrypto_cipher_get_iv_len(QCRYPTO_CIPHER_ALGO_AES_128,
  60. * QCRYPTO_CIPHER_MODE_CBC);
  61. * iv = g_new0(uint8_t, niv);
  62. *
  63. *
  64. * while (ndata) {
  65. * if (qcrypto_ivgen_calculate(ivgen, sector, iv, niv, errp) < 0) {
  66. * goto error;
  67. * }
  68. * if (qcrypto_cipher_setiv(cipher, iv, niv, errp) < 0) {
  69. * goto error;
  70. * }
  71. * if (qcrypto_cipher_encrypt(cipher,
  72. * data + (sector * 512),
  73. * data + (sector * 512),
  74. * 512, errp) < 0) {
  75. * goto error;
  76. * }
  77. * sector++;
  78. * ndata -= 512;
  79. * }
  80. *
  81. * g_free(iv);
  82. * qcrypto_ivgen_free(ivgen);
  83. * qcrypto_cipher_free(cipher);
  84. * return 0;
  85. *
  86. *error:
  87. * g_free(iv);
  88. * qcrypto_ivgen_free(ivgen);
  89. * qcrypto_cipher_free(cipher);
  90. * return -1;
  91. * </programlisting>
  92. * </example>
  93. */
  94. typedef struct QCryptoIVGen QCryptoIVGen;
  95. /* See also QCryptoIVGenAlgo enum in qapi/crypto.json */
  96. /**
  97. * qcrypto_ivgen_new:
  98. * @alg: the initialization vector generation algorithm
  99. * @cipheralg: the cipher algorithm or 0
  100. * @hash: the hash algorithm or 0
  101. * @key: the encryption key or NULL
  102. * @nkey: the size of @key in bytes
  103. *
  104. * Create a new initialization vector generator that uses
  105. * the algorithm @alg. Whether the remaining parameters
  106. * are required or not depends on the choice of @alg
  107. * requested.
  108. *
  109. * - QCRYPTO_IV_GEN_ALGO_PLAIN
  110. *
  111. * The IVs are generated by the 32-bit truncated sector
  112. * number. This should never be used for block devices
  113. * that are larger than 2^32 sectors in size.
  114. * All the other parameters are unused.
  115. *
  116. * - QCRYPTO_IV_GEN_ALGO_PLAIN64
  117. *
  118. * The IVs are generated by the 64-bit sector number.
  119. * All the other parameters are unused.
  120. *
  121. * - QCRYPTO_IV_GEN_ALGO_ESSIV:
  122. *
  123. * The IVs are generated by encrypting the 64-bit sector
  124. * number with a hash of an encryption key. The @cipheralg,
  125. * @hash, @key and @nkey parameters are all required.
  126. *
  127. * Returns: a new IV generator, or NULL on error
  128. */
  129. QCryptoIVGen *qcrypto_ivgen_new(QCryptoIVGenAlgo alg,
  130. QCryptoCipherAlgo cipheralg,
  131. QCryptoHashAlgo hash,
  132. const uint8_t *key, size_t nkey,
  133. Error **errp);
  134. /**
  135. * qcrypto_ivgen_calculate:
  136. * @ivgen: the IV generator object
  137. * @sector: the 64-bit sector number
  138. * @iv: a pre-allocated buffer to hold the generated IV
  139. * @niv: the number of bytes in @iv
  140. * @errp: pointer to a NULL-initialized error object
  141. *
  142. * Calculate a new initialization vector for the data
  143. * to be stored in sector @sector. The IV will be
  144. * written into the buffer @iv of size @niv.
  145. *
  146. * Returns: 0 on success, -1 on error
  147. */
  148. int qcrypto_ivgen_calculate(QCryptoIVGen *ivgen,
  149. uint64_t sector,
  150. uint8_t *iv, size_t niv,
  151. Error **errp);
  152. /**
  153. * qcrypto_ivgen_get_algorithm:
  154. * @ivgen: the IV generator object
  155. *
  156. * Get the algorithm used by this IV generator
  157. *
  158. * Returns: the IV generator algorithm
  159. */
  160. QCryptoIVGenAlgo qcrypto_ivgen_get_algorithm(QCryptoIVGen *ivgen);
  161. /**
  162. * qcrypto_ivgen_get_cipher:
  163. * @ivgen: the IV generator object
  164. *
  165. * Get the cipher algorithm used by this IV generator (if
  166. * applicable)
  167. *
  168. * Returns: the cipher algorithm
  169. */
  170. QCryptoCipherAlgo qcrypto_ivgen_get_cipher(QCryptoIVGen *ivgen);
  171. /**
  172. * qcrypto_ivgen_get_hash:
  173. * @ivgen: the IV generator object
  174. *
  175. * Get the hash algorithm used by this IV generator (if
  176. * applicable)
  177. *
  178. * Returns: the hash algorithm
  179. */
  180. QCryptoHashAlgo qcrypto_ivgen_get_hash(QCryptoIVGen *ivgen);
  181. /**
  182. * qcrypto_ivgen_free:
  183. * @ivgen: the IV generator object
  184. *
  185. * Release all resources associated with @ivgen, or a no-op
  186. * if @ivgen is NULL
  187. */
  188. void qcrypto_ivgen_free(QCryptoIVGen *ivgen);
  189. G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoIVGen, qcrypto_ivgen_free)
  190. #endif /* QCRYPTO_IVGEN_H */