pbkdf.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*
  2. * QEMU Crypto PBKDF support (Password-Based Key Derivation Function)
  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_PBKDF_H
  21. #define QCRYPTO_PBKDF_H
  22. #include "crypto/hash.h"
  23. /**
  24. * This module provides an interface to the PBKDF2 algorithm
  25. *
  26. * https://en.wikipedia.org/wiki/PBKDF2
  27. *
  28. * <example>
  29. * <title>Generating an AES encryption key from a user password</title>
  30. * <programlisting>
  31. * #include "crypto/cipher.h"
  32. * #include "crypto/random.h"
  33. * #include "crypto/pbkdf.h"
  34. *
  35. * ....
  36. *
  37. * char *password = "a-typical-awful-user-password";
  38. * size_t nkey = qcrypto_cipher_get_key_len(QCRYPTO_CIPHER_ALGO_AES_128);
  39. * uint8_t *salt = g_new0(uint8_t, nkey);
  40. * uint8_t *key = g_new0(uint8_t, nkey);
  41. * int iterations;
  42. * QCryptoCipher *cipher;
  43. *
  44. * if (qcrypto_random_bytes(salt, nkey, errp) < 0) {
  45. * g_free(key);
  46. * g_free(salt);
  47. * return -1;
  48. * }
  49. *
  50. * iterations = qcrypto_pbkdf2_count_iters(QCRYPTO_HASH_ALGO_SHA256,
  51. * (const uint8_t *)password,
  52. * strlen(password),
  53. * salt, nkey, errp);
  54. * if (iterations < 0) {
  55. * g_free(key);
  56. * g_free(salt);
  57. * return -1;
  58. * }
  59. *
  60. * if (qcrypto_pbkdf2(QCRYPTO_HASH_ALGO_SHA256,
  61. * (const uint8_t *)password, strlen(password),
  62. * salt, nkey, iterations, key, nkey, errp) < 0) {
  63. * g_free(key);
  64. * g_free(salt);
  65. * return -1;
  66. * }
  67. *
  68. * g_free(salt);
  69. *
  70. * cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALGO_AES_128,
  71. * QCRYPTO_CIPHER_MODE_ECB,
  72. * key, nkey, errp);
  73. * g_free(key);
  74. *
  75. * ....encrypt some data...
  76. *
  77. * qcrypto_cipher_free(cipher);
  78. * </programlisting>
  79. * </example>
  80. *
  81. */
  82. /**
  83. * qcrypto_pbkdf2_supports:
  84. * @hash: the hash algorithm
  85. *
  86. * Determine if the current build supports the PBKDF2 algorithm
  87. * in combination with the hash @hash.
  88. *
  89. * Returns true if supported, false otherwise
  90. */
  91. bool qcrypto_pbkdf2_supports(QCryptoHashAlgo hash);
  92. /**
  93. * qcrypto_pbkdf2:
  94. * @hash: the hash algorithm to use
  95. * @key: the user password / key
  96. * @nkey: the length of @key in bytes
  97. * @salt: a random salt
  98. * @nsalt: length of @salt in bytes
  99. * @iterations: the number of iterations to compute
  100. * @out: pointer to pre-allocated buffer to hold output
  101. * @nout: length of @out in bytes
  102. * @errp: pointer to a NULL-initialized error object
  103. *
  104. * Apply the PBKDF2 algorithm to derive an encryption
  105. * key from a user password provided in @key. The
  106. * @salt parameter is used to perturb the algorithm.
  107. * The @iterations count determines how many times
  108. * the hashing process is run, which influences how
  109. * hard it is to crack the key. The number of @iterations
  110. * should be large enough such that the algorithm takes
  111. * 1 second or longer to derive a key. The derived key
  112. * will be stored in the preallocated buffer @out.
  113. *
  114. * Returns: 0 on success, -1 on error
  115. */
  116. int qcrypto_pbkdf2(QCryptoHashAlgo hash,
  117. const uint8_t *key, size_t nkey,
  118. const uint8_t *salt, size_t nsalt,
  119. uint64_t iterations,
  120. uint8_t *out, size_t nout,
  121. Error **errp);
  122. /**
  123. * qcrypto_pbkdf2_count_iters:
  124. * @hash: the hash algorithm to use
  125. * @key: the user password / key
  126. * @nkey: the length of @key in bytes
  127. * @salt: a random salt
  128. * @nsalt: length of @salt in bytes
  129. * @nout: size of desired derived key
  130. * @errp: pointer to a NULL-initialized error object
  131. *
  132. * Time the PBKDF2 algorithm to determine how many
  133. * iterations are required to derive an encryption
  134. * key from a user password provided in @key in 1
  135. * second of compute time. The result of this can
  136. * be used as a the @iterations parameter of a later
  137. * call to qcrypto_pbkdf2(). The value of @nout should
  138. * match that value that will later be provided with
  139. * a call to qcrypto_pbkdf2().
  140. *
  141. * Returns: number of iterations in 1 second, -1 on error
  142. */
  143. uint64_t qcrypto_pbkdf2_count_iters(QCryptoHashAlgo hash,
  144. const uint8_t *key, size_t nkey,
  145. const uint8_t *salt, size_t nsalt,
  146. size_t nout,
  147. Error **errp);
  148. #endif /* QCRYPTO_PBKDF_H */