| // Copyright 2022 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef LIBHWSEC_FOUNDATION_CRYPTO_SCRYPT_H_ |
| #define LIBHWSEC_FOUNDATION_CRYPTO_SCRYPT_H_ |
| |
| #include <string> |
| #include <vector> |
| |
| #include <openssl/bn.h> |
| #include <openssl/evp.h> |
| |
| #include <base/files/file_path.h> |
| #include <brillo/secure_blob.h> |
| |
| #include "libhwsec-foundation/hwsec-foundation_export.h" |
| |
| namespace hwsec_foundation { |
| |
| // The current number of hash rounds we use. Large enough to be a measurable |
| // amount of time, but not add too much overhead to login (around 10ms). |
| inline constexpr unsigned int kDefaultPasswordRounds = 1337; |
| |
| // The number of hash rounds we originally used when converting a password to a |
| // key. This is used when converting older hwsec_foundation vault keysets. |
| inline constexpr unsigned int kDefaultLegacyPasswordRounds = 1; |
| |
| // The maximum number of times to try decryption with the TPM. |
| inline constexpr int kTpmDecryptMaxRetries = 2; |
| |
| // The size in bytes of password blob to be generated by Scrypt. Should be the |
| // same size as the modulus of hwsec_foundation key, since we need to be able to |
| // decrypt it. |
| inline constexpr unsigned int kDefaultPassBlobSize = 256; |
| |
| // Scrypt creates a header in the cipher text that we need to account for in |
| // buffer sizing. This accounts for both the header and the HMAC. |
| inline constexpr unsigned int kScryptMetadataSize = 128; |
| |
| // An upper bound on the amount of memory that we allow Scrypt to use when |
| // performing key strengthening (32MB). A large size is okay since we only use |
| // Scrypt during the login process, before the user is logged in. This memory |
| // is managed (and freed) by the scrypt library. |
| inline constexpr unsigned int kScryptMaxMem = 32 * 1024 * 1024; |
| |
| // An upper bound on the amount of time we allow Scrypt to use when performing |
| // key strenthening (1/3s) for encryption. |
| inline constexpr double kScryptMaxEncryptTime = 0.333; |
| |
| // A struct wrapping the scrypt parameters, with the default production |
| // parameters set. |
| struct ScryptParameters { |
| // N is the work factor. Scrypt stores N sequential hash results in RAM, |
| // randomizes their order, and XORs them. |
| int n_factor = 16384; |
| // The r factor iterates the hash function 2r times, so that memory and CPU |
| // consumption grow with r. |
| uint32_t r_factor = 8; |
| // P is the parallelization factor. |
| uint32_t p_factor = 1; |
| }; |
| |
| // These are the params to use for production code. |
| inline constexpr ScryptParameters kDefaultScryptParams; |
| |
| // scrypt, with the default params, is too slow for unit testing so here are |
| // some fast parameters only for test code. |
| inline constexpr ScryptParameters kTestScryptParams = {1024, 8, 1}; |
| |
| // Derives secrets and other values from User Passkey. |
| // |
| // Parameters |
| // passkey - The User Passkey, from which to derive the secrets. |
| // salt - The salt used when deriving the secrets. |
| // gen_secrets (IN-OUT) - Vector containing resulting secrets. |
| // The caller allocates each blob in |gen_secrets| |
| // to the appropriate (non-empty) size. |
| // |
| bool HWSEC_FOUNDATION_EXPORT |
| DeriveSecretsScrypt(const brillo::SecureBlob& passkey, |
| const brillo::SecureBlob& salt, |
| std::vector<brillo::SecureBlob*> gen_secrets); |
| |
| // |passkey| - The User Passkey, from which to derive the secrets. |
| // |salt| - The salt used when deriving the secrets. |
| // |work_factor| - The work factor passed to scrypt. |
| // |block_size| - The block size passed to scrypt. |
| // |parallel_factor| - The parallel factor passed to scrypt. |
| // |result| - The blob, allocated by the caller to the correct size, |
| // containing the result secret. |
| // |
| // Returns true on success. |
| bool HWSEC_FOUNDATION_EXPORT Scrypt(const brillo::SecureBlob& passkey, |
| const brillo::SecureBlob& salt, |
| int work_factor, |
| int block_size, |
| int parallel_factor, |
| brillo::SecureBlob* result); |
| |
| // Encrypt a provided blob using libscrypt, which sets up a header, derives |
| // the keys, encrypts, and HMACs. |
| // |
| // The parameters are as follows: |
| // - blob: Data blob to be encrypted. |
| // - key_source: User passphrase key used for encryption. |
| // - max_encrypt_time: A max encryption time which can specified. |
| // - wrapped_blob: Pointer to blob where encrypted data is stored. |
| // |
| // Returns true on success, and false on failure. |
| bool HWSEC_FOUNDATION_EXPORT |
| DeprecatedEncryptScryptBlob(const brillo::SecureBlob& blob, |
| const brillo::SecureBlob& key_source, |
| brillo::SecureBlob* wrapped_blob); |
| |
| // This verifies that the default scrypt params are used in production. |
| void HWSEC_FOUNDATION_EXPORT AssertProductionScryptParams(); |
| |
| // This updates the global scrypt testing parameters. |
| void HWSEC_FOUNDATION_EXPORT SetScryptTestingParams(); |
| |
| } // namespace hwsec_foundation |
| |
| #endif // LIBHWSEC_FOUNDATION_CRYPTO_SCRYPT_H_ |