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