xref: /openbmc/qemu/include/crypto/pbkdf.h (revision b8eada54b2ad8a7d98d93d5ab4d3e888c5880097)
137788f25SDaniel P. Berrange /*
237788f25SDaniel P. Berrange  * QEMU Crypto PBKDF support (Password-Based Key Derivation Function)
337788f25SDaniel P. Berrange  *
437788f25SDaniel P. Berrange  * Copyright (c) 2015-2016 Red Hat, Inc.
537788f25SDaniel P. Berrange  *
637788f25SDaniel P. Berrange  * This library is free software; you can redistribute it and/or
737788f25SDaniel P. Berrange  * modify it under the terms of the GNU Lesser General Public
837788f25SDaniel P. Berrange  * License as published by the Free Software Foundation; either
9b7cbb874SThomas Huth  * version 2.1 of the License, or (at your option) any later version.
1037788f25SDaniel P. Berrange  *
1137788f25SDaniel P. Berrange  * This library is distributed in the hope that it will be useful,
1237788f25SDaniel P. Berrange  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1337788f25SDaniel P. Berrange  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1437788f25SDaniel P. Berrange  * Lesser General Public License for more details.
1537788f25SDaniel P. Berrange  *
1637788f25SDaniel P. Berrange  * You should have received a copy of the GNU Lesser General Public
1737788f25SDaniel P. Berrange  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
1837788f25SDaniel P. Berrange  *
1937788f25SDaniel P. Berrange  */
2037788f25SDaniel P. Berrange 
212a6a4076SMarkus Armbruster #ifndef QCRYPTO_PBKDF_H
222a6a4076SMarkus Armbruster #define QCRYPTO_PBKDF_H
2337788f25SDaniel P. Berrange 
2437788f25SDaniel P. Berrange #include "crypto/hash.h"
2537788f25SDaniel P. Berrange 
2637788f25SDaniel P. Berrange /**
2737788f25SDaniel P. Berrange  * This module provides an interface to the PBKDF2 algorithm
2837788f25SDaniel P. Berrange  *
2937788f25SDaniel P. Berrange  *   https://en.wikipedia.org/wiki/PBKDF2
3037788f25SDaniel P. Berrange  *
3137788f25SDaniel P. Berrange  * <example>
3237788f25SDaniel P. Berrange  *   <title>Generating an AES encryption key from a user password</title>
3337788f25SDaniel P. Berrange  *   <programlisting>
3437788f25SDaniel P. Berrange  * #include "crypto/cipher.h"
3537788f25SDaniel P. Berrange  * #include "crypto/random.h"
3637788f25SDaniel P. Berrange  * #include "crypto/pbkdf.h"
3737788f25SDaniel P. Berrange  *
3837788f25SDaniel P. Berrange  * ....
3937788f25SDaniel P. Berrange  *
4037788f25SDaniel P. Berrange  * char *password = "a-typical-awful-user-password";
41*a092c513SMarkus Armbruster  * size_t nkey = qcrypto_cipher_get_key_len(QCRYPTO_CIPHER_ALGO_AES_128);
4237788f25SDaniel P. Berrange  * uint8_t *salt = g_new0(uint8_t, nkey);
4337788f25SDaniel P. Berrange  * uint8_t *key = g_new0(uint8_t, nkey);
4437788f25SDaniel P. Berrange  * int iterations;
4537788f25SDaniel P. Berrange  * QCryptoCipher *cipher;
4637788f25SDaniel P. Berrange  *
4737788f25SDaniel P. Berrange  * if (qcrypto_random_bytes(salt, nkey, errp) < 0) {
4837788f25SDaniel P. Berrange  *     g_free(key);
4937788f25SDaniel P. Berrange  *     g_free(salt);
5037788f25SDaniel P. Berrange  *     return -1;
5137788f25SDaniel P. Berrange  * }
5237788f25SDaniel P. Berrange  *
53ef834aa2SMarkus Armbruster  * iterations = qcrypto_pbkdf2_count_iters(QCRYPTO_HASH_ALGO_SHA256,
5437788f25SDaniel P. Berrange  *                                         (const uint8_t *)password,
5537788f25SDaniel P. Berrange  *                                         strlen(password),
5637788f25SDaniel P. Berrange  *                                         salt, nkey, errp);
5737788f25SDaniel P. Berrange  * if (iterations < 0) {
5837788f25SDaniel P. Berrange  *     g_free(key);
5937788f25SDaniel P. Berrange  *     g_free(salt);
6037788f25SDaniel P. Berrange  *     return -1;
6137788f25SDaniel P. Berrange  * }
6237788f25SDaniel P. Berrange  *
63ef834aa2SMarkus Armbruster  * if (qcrypto_pbkdf2(QCRYPTO_HASH_ALGO_SHA256,
6437788f25SDaniel P. Berrange  *                    (const uint8_t *)password, strlen(password),
6537788f25SDaniel P. Berrange  *                    salt, nkey, iterations, key, nkey, errp) < 0) {
6637788f25SDaniel P. Berrange  *     g_free(key);
6737788f25SDaniel P. Berrange  *     g_free(salt);
6837788f25SDaniel P. Berrange  *     return -1;
6937788f25SDaniel P. Berrange  * }
7037788f25SDaniel P. Berrange  *
7137788f25SDaniel P. Berrange  * g_free(salt);
7237788f25SDaniel P. Berrange  *
73*a092c513SMarkus Armbruster  * cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALGO_AES_128,
7437788f25SDaniel P. Berrange  *                             QCRYPTO_CIPHER_MODE_ECB,
7537788f25SDaniel P. Berrange  *                             key, nkey, errp);
7637788f25SDaniel P. Berrange  * g_free(key);
7737788f25SDaniel P. Berrange  *
7837788f25SDaniel P. Berrange  * ....encrypt some data...
7937788f25SDaniel P. Berrange  *
8037788f25SDaniel P. Berrange  * qcrypto_cipher_free(cipher);
8137788f25SDaniel P. Berrange  *   </programlisting>
8237788f25SDaniel P. Berrange  * </example>
8337788f25SDaniel P. Berrange  *
8437788f25SDaniel P. Berrange  */
8537788f25SDaniel P. Berrange 
8637788f25SDaniel P. Berrange /**
8737788f25SDaniel P. Berrange  * qcrypto_pbkdf2_supports:
8837788f25SDaniel P. Berrange  * @hash: the hash algorithm
8937788f25SDaniel P. Berrange  *
9037788f25SDaniel P. Berrange  * Determine if the current build supports the PBKDF2 algorithm
9137788f25SDaniel P. Berrange  * in combination with the hash @hash.
9237788f25SDaniel P. Berrange  *
9337788f25SDaniel P. Berrange  * Returns true if supported, false otherwise
9437788f25SDaniel P. Berrange  */
95ef834aa2SMarkus Armbruster bool qcrypto_pbkdf2_supports(QCryptoHashAlgo hash);
9637788f25SDaniel P. Berrange 
9737788f25SDaniel P. Berrange 
9837788f25SDaniel P. Berrange /**
9937788f25SDaniel P. Berrange  * qcrypto_pbkdf2:
10037788f25SDaniel P. Berrange  * @hash: the hash algorithm to use
10137788f25SDaniel P. Berrange  * @key: the user password / key
10237788f25SDaniel P. Berrange  * @nkey: the length of @key in bytes
10337788f25SDaniel P. Berrange  * @salt: a random salt
10437788f25SDaniel P. Berrange  * @nsalt: length of @salt in bytes
10537788f25SDaniel P. Berrange  * @iterations: the number of iterations to compute
10637788f25SDaniel P. Berrange  * @out: pointer to pre-allocated buffer to hold output
10737788f25SDaniel P. Berrange  * @nout: length of @out in bytes
10837788f25SDaniel P. Berrange  * @errp: pointer to a NULL-initialized error object
10937788f25SDaniel P. Berrange  *
11037788f25SDaniel P. Berrange  * Apply the PBKDF2 algorithm to derive an encryption
11137788f25SDaniel P. Berrange  * key from a user password provided in @key. The
11237788f25SDaniel P. Berrange  * @salt parameter is used to perturb the algorithm.
11337788f25SDaniel P. Berrange  * The @iterations count determines how many times
11437788f25SDaniel P. Berrange  * the hashing process is run, which influences how
11537788f25SDaniel P. Berrange  * hard it is to crack the key. The number of @iterations
11637788f25SDaniel P. Berrange  * should be large enough such that the algorithm takes
11737788f25SDaniel P. Berrange  * 1 second or longer to derive a key. The derived key
11837788f25SDaniel P. Berrange  * will be stored in the preallocated buffer @out.
11937788f25SDaniel P. Berrange  *
12037788f25SDaniel P. Berrange  * Returns: 0 on success, -1 on error
12137788f25SDaniel P. Berrange  */
122ef834aa2SMarkus Armbruster int qcrypto_pbkdf2(QCryptoHashAlgo hash,
12337788f25SDaniel P. Berrange                    const uint8_t *key, size_t nkey,
12437788f25SDaniel P. Berrange                    const uint8_t *salt, size_t nsalt,
12559b060beSDaniel P. Berrange                    uint64_t iterations,
12637788f25SDaniel P. Berrange                    uint8_t *out, size_t nout,
12737788f25SDaniel P. Berrange                    Error **errp);
12837788f25SDaniel P. Berrange 
12937788f25SDaniel P. Berrange /**
13037788f25SDaniel P. Berrange  * qcrypto_pbkdf2_count_iters:
13137788f25SDaniel P. Berrange  * @hash: the hash algorithm to use
13237788f25SDaniel P. Berrange  * @key: the user password / key
13337788f25SDaniel P. Berrange  * @nkey: the length of @key in bytes
13437788f25SDaniel P. Berrange  * @salt: a random salt
13537788f25SDaniel P. Berrange  * @nsalt: length of @salt in bytes
136e74aabcfSDaniel P. Berrange  * @nout: size of desired derived key
13737788f25SDaniel P. Berrange  * @errp: pointer to a NULL-initialized error object
13837788f25SDaniel P. Berrange  *
13937788f25SDaniel P. Berrange  * Time the PBKDF2 algorithm to determine how many
14037788f25SDaniel P. Berrange  * iterations are required to derive an encryption
14137788f25SDaniel P. Berrange  * key from a user password provided in @key in 1
14237788f25SDaniel P. Berrange  * second of compute time. The result of this can
14337788f25SDaniel P. Berrange  * be used as a the @iterations parameter of a later
144e74aabcfSDaniel P. Berrange  * call to qcrypto_pbkdf2(). The value of @nout should
145e74aabcfSDaniel P. Berrange  * match that value that will later be provided with
146e74aabcfSDaniel P. Berrange  * a call to qcrypto_pbkdf2().
14737788f25SDaniel P. Berrange  *
14837788f25SDaniel P. Berrange  * Returns: number of iterations in 1 second, -1 on error
14937788f25SDaniel P. Berrange  */
150ef834aa2SMarkus Armbruster uint64_t qcrypto_pbkdf2_count_iters(QCryptoHashAlgo hash,
15137788f25SDaniel P. Berrange                                     const uint8_t *key, size_t nkey,
15237788f25SDaniel P. Berrange                                     const uint8_t *salt, size_t nsalt,
153e74aabcfSDaniel P. Berrange                                     size_t nout,
15437788f25SDaniel P. Berrange                                     Error **errp);
15537788f25SDaniel P. Berrange 
1562a6a4076SMarkus Armbruster #endif /* QCRYPTO_PBKDF_H */
157