blob: 9f868d403c6f047c3e6dde1c709456386579b0ed [file] [log] [blame]
// 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_