xref: /openbmc/qemu/include/crypto/pbkdf.h (revision 37788f253a4a9ad5f27dae68aee261c784e1fa17)
1*37788f25SDaniel P. Berrange /*
2*37788f25SDaniel P. Berrange  * QEMU Crypto PBKDF support (Password-Based Key Derivation Function)
3*37788f25SDaniel P. Berrange  *
4*37788f25SDaniel P. Berrange  * Copyright (c) 2015-2016 Red Hat, Inc.
5*37788f25SDaniel P. Berrange  *
6*37788f25SDaniel P. Berrange  * This library is free software; you can redistribute it and/or
7*37788f25SDaniel P. Berrange  * modify it under the terms of the GNU Lesser General Public
8*37788f25SDaniel P. Berrange  * License as published by the Free Software Foundation; either
9*37788f25SDaniel P. Berrange  * version 2 of the License, or (at your option) any later version.
10*37788f25SDaniel P. Berrange  *
11*37788f25SDaniel P. Berrange  * This library is distributed in the hope that it will be useful,
12*37788f25SDaniel P. Berrange  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13*37788f25SDaniel P. Berrange  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14*37788f25SDaniel P. Berrange  * Lesser General Public License for more details.
15*37788f25SDaniel P. Berrange  *
16*37788f25SDaniel P. Berrange  * You should have received a copy of the GNU Lesser General Public
17*37788f25SDaniel P. Berrange  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18*37788f25SDaniel P. Berrange  *
19*37788f25SDaniel P. Berrange  */
20*37788f25SDaniel P. Berrange 
21*37788f25SDaniel P. Berrange #ifndef QCRYPTO_PBKDF_H__
22*37788f25SDaniel P. Berrange #define QCRYPTO_PBKDF_H__
23*37788f25SDaniel P. Berrange 
24*37788f25SDaniel P. Berrange #include "crypto/hash.h"
25*37788f25SDaniel P. Berrange 
26*37788f25SDaniel P. Berrange /**
27*37788f25SDaniel P. Berrange  * This module provides an interface to the PBKDF2 algorithm
28*37788f25SDaniel P. Berrange  *
29*37788f25SDaniel P. Berrange  *   https://en.wikipedia.org/wiki/PBKDF2
30*37788f25SDaniel P. Berrange  *
31*37788f25SDaniel P. Berrange  * <example>
32*37788f25SDaniel P. Berrange  *   <title>Generating an AES encryption key from a user password</title>
33*37788f25SDaniel P. Berrange  *   <programlisting>
34*37788f25SDaniel P. Berrange  * #include "crypto/cipher.h"
35*37788f25SDaniel P. Berrange  * #include "crypto/random.h"
36*37788f25SDaniel P. Berrange  * #include "crypto/pbkdf.h"
37*37788f25SDaniel P. Berrange  *
38*37788f25SDaniel P. Berrange  * ....
39*37788f25SDaniel P. Berrange  *
40*37788f25SDaniel P. Berrange  * char *password = "a-typical-awful-user-password";
41*37788f25SDaniel P. Berrange  * size_t nkey = qcrypto_cipher_get_key_len(QCRYPTO_CIPHER_ALG_AES_128);
42*37788f25SDaniel P. Berrange  * uint8_t *salt = g_new0(uint8_t, nkey);
43*37788f25SDaniel P. Berrange  * uint8_t *key = g_new0(uint8_t, nkey);
44*37788f25SDaniel P. Berrange  * int iterations;
45*37788f25SDaniel P. Berrange  * QCryptoCipher *cipher;
46*37788f25SDaniel P. Berrange  *
47*37788f25SDaniel P. Berrange  * if (qcrypto_random_bytes(salt, nkey, errp) < 0) {
48*37788f25SDaniel P. Berrange  *     g_free(key);
49*37788f25SDaniel P. Berrange  *     g_free(salt);
50*37788f25SDaniel P. Berrange  *     return -1;
51*37788f25SDaniel P. Berrange  * }
52*37788f25SDaniel P. Berrange  *
53*37788f25SDaniel P. Berrange  * iterations = qcrypto_pbkdf2_count_iters(QCRYPTO_HASH_ALG_SHA256,
54*37788f25SDaniel P. Berrange  *                                         (const uint8_t *)password,
55*37788f25SDaniel P. Berrange  *                                         strlen(password),
56*37788f25SDaniel P. Berrange  *                                         salt, nkey, errp);
57*37788f25SDaniel P. Berrange  * if (iterations < 0) {
58*37788f25SDaniel P. Berrange  *     g_free(key);
59*37788f25SDaniel P. Berrange  *     g_free(salt);
60*37788f25SDaniel P. Berrange  *     return -1;
61*37788f25SDaniel P. Berrange  * }
62*37788f25SDaniel P. Berrange  *
63*37788f25SDaniel P. Berrange  * if (qcrypto_pbkdf2(QCRYPTO_HASH_ALG_SHA256,
64*37788f25SDaniel P. Berrange  *                    (const uint8_t *)password, strlen(password),
65*37788f25SDaniel P. Berrange  *                    salt, nkey, iterations, key, nkey, errp) < 0) {
66*37788f25SDaniel P. Berrange  *     g_free(key);
67*37788f25SDaniel P. Berrange  *     g_free(salt);
68*37788f25SDaniel P. Berrange  *     return -1;
69*37788f25SDaniel P. Berrange  * }
70*37788f25SDaniel P. Berrange  *
71*37788f25SDaniel P. Berrange  * g_free(salt);
72*37788f25SDaniel P. Berrange  *
73*37788f25SDaniel P. Berrange  * cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_128,
74*37788f25SDaniel P. Berrange  *                             QCRYPTO_CIPHER_MODE_ECB,
75*37788f25SDaniel P. Berrange  *                             key, nkey, errp);
76*37788f25SDaniel P. Berrange  * g_free(key);
77*37788f25SDaniel P. Berrange  *
78*37788f25SDaniel P. Berrange  * ....encrypt some data...
79*37788f25SDaniel P. Berrange  *
80*37788f25SDaniel P. Berrange  * qcrypto_cipher_free(cipher);
81*37788f25SDaniel P. Berrange  *   </programlisting>
82*37788f25SDaniel P. Berrange  * </example>
83*37788f25SDaniel P. Berrange  *
84*37788f25SDaniel P. Berrange  */
85*37788f25SDaniel P. Berrange 
86*37788f25SDaniel P. Berrange /**
87*37788f25SDaniel P. Berrange  * qcrypto_pbkdf2_supports:
88*37788f25SDaniel P. Berrange  * @hash: the hash algorithm
89*37788f25SDaniel P. Berrange  *
90*37788f25SDaniel P. Berrange  * Determine if the current build supports the PBKDF2 algorithm
91*37788f25SDaniel P. Berrange  * in combination with the hash @hash.
92*37788f25SDaniel P. Berrange  *
93*37788f25SDaniel P. Berrange  * Returns true if supported, false otherwise
94*37788f25SDaniel P. Berrange  */
95*37788f25SDaniel P. Berrange bool qcrypto_pbkdf2_supports(QCryptoHashAlgorithm hash);
96*37788f25SDaniel P. Berrange 
97*37788f25SDaniel P. Berrange 
98*37788f25SDaniel P. Berrange /**
99*37788f25SDaniel P. Berrange  * qcrypto_pbkdf2:
100*37788f25SDaniel P. Berrange  * @hash: the hash algorithm to use
101*37788f25SDaniel P. Berrange  * @key: the user password / key
102*37788f25SDaniel P. Berrange  * @nkey: the length of @key in bytes
103*37788f25SDaniel P. Berrange  * @salt: a random salt
104*37788f25SDaniel P. Berrange  * @nsalt: length of @salt in bytes
105*37788f25SDaniel P. Berrange  * @iterations: the number of iterations to compute
106*37788f25SDaniel P. Berrange  * @out: pointer to pre-allocated buffer to hold output
107*37788f25SDaniel P. Berrange  * @nout: length of @out in bytes
108*37788f25SDaniel P. Berrange  * @errp: pointer to a NULL-initialized error object
109*37788f25SDaniel P. Berrange  *
110*37788f25SDaniel P. Berrange  * Apply the PBKDF2 algorithm to derive an encryption
111*37788f25SDaniel P. Berrange  * key from a user password provided in @key. The
112*37788f25SDaniel P. Berrange  * @salt parameter is used to perturb the algorithm.
113*37788f25SDaniel P. Berrange  * The @iterations count determines how many times
114*37788f25SDaniel P. Berrange  * the hashing process is run, which influences how
115*37788f25SDaniel P. Berrange  * hard it is to crack the key. The number of @iterations
116*37788f25SDaniel P. Berrange  * should be large enough such that the algorithm takes
117*37788f25SDaniel P. Berrange  * 1 second or longer to derive a key. The derived key
118*37788f25SDaniel P. Berrange  * will be stored in the preallocated buffer @out.
119*37788f25SDaniel P. Berrange  *
120*37788f25SDaniel P. Berrange  * Returns: 0 on success, -1 on error
121*37788f25SDaniel P. Berrange  */
122*37788f25SDaniel P. Berrange int qcrypto_pbkdf2(QCryptoHashAlgorithm hash,
123*37788f25SDaniel P. Berrange                    const uint8_t *key, size_t nkey,
124*37788f25SDaniel P. Berrange                    const uint8_t *salt, size_t nsalt,
125*37788f25SDaniel P. Berrange                    unsigned int iterations,
126*37788f25SDaniel P. Berrange                    uint8_t *out, size_t nout,
127*37788f25SDaniel P. Berrange                    Error **errp);
128*37788f25SDaniel P. Berrange 
129*37788f25SDaniel P. Berrange /**
130*37788f25SDaniel P. Berrange  * qcrypto_pbkdf2_count_iters:
131*37788f25SDaniel P. Berrange  * @hash: the hash algorithm to use
132*37788f25SDaniel P. Berrange  * @key: the user password / key
133*37788f25SDaniel P. Berrange  * @nkey: the length of @key in bytes
134*37788f25SDaniel P. Berrange  * @salt: a random salt
135*37788f25SDaniel P. Berrange  * @nsalt: length of @salt in bytes
136*37788f25SDaniel P. Berrange  * @errp: pointer to a NULL-initialized error object
137*37788f25SDaniel P. Berrange  *
138*37788f25SDaniel P. Berrange  * Time the PBKDF2 algorithm to determine how many
139*37788f25SDaniel P. Berrange  * iterations are required to derive an encryption
140*37788f25SDaniel P. Berrange  * key from a user password provided in @key in 1
141*37788f25SDaniel P. Berrange  * second of compute time. The result of this can
142*37788f25SDaniel P. Berrange  * be used as a the @iterations parameter of a later
143*37788f25SDaniel P. Berrange  * call to qcrypto_pbkdf2().
144*37788f25SDaniel P. Berrange  *
145*37788f25SDaniel P. Berrange  * Returns: number of iterations in 1 second, -1 on error
146*37788f25SDaniel P. Berrange  */
147*37788f25SDaniel P. Berrange int qcrypto_pbkdf2_count_iters(QCryptoHashAlgorithm hash,
148*37788f25SDaniel P. Berrange                                const uint8_t *key, size_t nkey,
149*37788f25SDaniel P. Berrange                                const uint8_t *salt, size_t nsalt,
150*37788f25SDaniel P. Berrange                                Error **errp);
151*37788f25SDaniel P. Berrange 
152*37788f25SDaniel P. Berrange #endif /* QCRYPTO_PBKDF_H__ */
153