// Copyright (c) 2012 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 CRYPTOHOME_CRYPTOLIB_H_
#define CRYPTOHOME_CRYPTOLIB_H_

#include <string>
#include <vector>

#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>

#include <base/files/file_path.h>
#include <base/macros.h>
#include <brillo/secure_blob.h>

#include "cryptohome/crypto_error.h"

#include "attestation.pb.h"  // NOLINT(build/include)

namespace cryptohome {

extern const unsigned int kDefaultPasswordRounds;
extern const unsigned int kWellKnownExponent;
extern const unsigned int kAesBlockSize;
extern const unsigned int kAesGcmTagSize;
extern const unsigned int kAesGcmIVSize;
extern const unsigned int kAesGcm256KeySize;
extern const unsigned int kDefaultAesKeySize;
extern const unsigned int kDefaultLegacyPasswordRounds;
extern const unsigned int kDefaultPassBlobSize;
extern const unsigned int kScryptMetadataSize;
extern const unsigned int kScryptMaxMem;
extern const double kScryptMaxEncryptTime;
extern const int kTpmDecryptMaxRetries;

// 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;
};

extern const ScryptParameters kDefaultScryptParams;
extern const ScryptParameters kTestScryptParams;

class CryptoLib {
 public:
  CryptoLib();
  ~CryptoLib();

  enum PaddingScheme {
    kPaddingNone = 0,
    // Also called PKCS padding.
    // See http://tools.ietf.org/html/rfc5652#section-6.3.
    kPaddingStandard = 1,
    kPaddingCryptohomeDefaultDeprecated = 2,
  };

  enum BlockMode {
    kEcb = 1,
    kCbc = 2,
    kCtr = 3,
  };

  static void GetSecureRandom(unsigned char *bytes, size_t len);
  static brillo::SecureBlob CreateSecureRandomBlob(size_t length);

  static bool CreateRsaKey(size_t bits, brillo::SecureBlob* n,
                           brillo::SecureBlob* p);

  // Fills out all fields related to the RSA private key information, given the
  // public key information provided via |rsa| and the secret prime via
  // |secret_prime|.
  static bool FillRsaPrivateKeyFromSecretPrime(
      const brillo::SecureBlob& secret_prime, RSA* rsa);

  // TODO(jorgelo,crbug.com/728047): Review current usage of these functions and
  // consider making the functions that take a plain Blob also return a plain
  // Blob.
  static brillo::Blob Sha1(const brillo::Blob& data);
  static brillo::SecureBlob Sha1ToSecureBlob(const brillo::Blob& data);
  static brillo::SecureBlob Sha1(const brillo::SecureBlob& data);

  static brillo::Blob Sha256(const brillo::Blob& data);
  static brillo::SecureBlob Sha256ToSecureBlob(const brillo::Blob& data);
  static brillo::SecureBlob Sha256(const brillo::SecureBlob& data);

  static brillo::SecureBlob HmacSha512(const brillo::SecureBlob& key,
                                       const brillo::Blob& data);
  static brillo::SecureBlob HmacSha512(const brillo::SecureBlob& key,
                                       const brillo::SecureBlob& data);

  static brillo::SecureBlob HmacSha256(const brillo::SecureBlob& key,
                                       const brillo::Blob& data);
  static brillo::SecureBlob HmacSha256(const brillo::SecureBlob& key,
                                       const brillo::SecureBlob& data);

  static size_t GetAesBlockSize();
  static bool PasskeyToAesKey(const brillo::SecureBlob& passkey,
                              const brillo::SecureBlob& salt,
                              unsigned int rounds,
                              brillo::SecureBlob* key,
                              brillo::SecureBlob* iv);

  // Decrypts data encrypted with AesEncrypt.
  //
  // Parameters
  //   wrapped - The blob containing the encrypted data
  //   key - The AES key to use in decryption
  //   iv - The initialization vector to use
  //   plaintext - The unwrapped (decrypted) data
  static bool AesDecryptDeprecated(const brillo::SecureBlob& ciphertext,
                                   const brillo::SecureBlob& key,
                                   const brillo::SecureBlob& iv,
                                   brillo::SecureBlob* plaintext);

  // AES encrypts the plain text data using the specified key and IV.  This
  // method uses custom padding and is not inter-operable with other crypto
  // systems.  The encrypted data can be decrypted with AesDecrypt.
  //
  // Parameters
  //   plaintext - The plain text data to encrypt
  //   key - The AES key to use
  //   iv - The initialization vector to use
  //   ciphertext - On success, the encrypted data
  static bool AesEncryptDeprecated(const brillo::SecureBlob& plaintext,
                                   const brillo::SecureBlob& key,
                                   const brillo::SecureBlob& iv,
                                   brillo::SecureBlob* ciphertext);

  // AES-GCM decrypts the |ciphertext| using the |key| and |iv|. |key| must be
  // 256-bits and |iv| must be 96-bits.
  //
  // Parameters:
  //   ciphertext - The encrypted data.
  //   tag - The integrity check of the data.
  //   key - The key to decrypt with.
  //   iv - The IV to decrypt with.
  //   plaintext - On success, the decrypted data.
  static bool AesGcmDecrypt(const brillo::SecureBlob& ciphertext,
                            const brillo::SecureBlob& tag,
                            const brillo::SecureBlob& key,
                            const brillo::SecureBlob& iv,
                            brillo::SecureBlob* plaintext);

  // AES-GCM encrypts the |plaintext| using the |key|. A random initialization
  // vector is created and retuned in |iv|. The encrypted data can be decrypted
  // with AesGcmDecrypt. |key| must be 256-bits.
  //
  // Parameters:
  //   plaintext - The plain text data to encrypt.
  //   key - The AES key to use.
  //   iv - The initialization vector generated randomly.
  //   tag - On success, the integrity tag of the data.
  //   ciphertext - On success, the encrypted data.
  static bool AesGcmEncrypt(const brillo::SecureBlob& plaintext,
                            const brillo::SecureBlob& key,
                            brillo::SecureBlob* iv,
                            brillo::SecureBlob* tag,
                            brillo::SecureBlob* ciphertext);

  // Same as AesDecrypt, but allows using either CBC or ECB
  static bool AesDecryptSpecifyBlockMode(const brillo::SecureBlob& ciphertext,
                                         unsigned int start, unsigned int count,
                                         const brillo::SecureBlob& key,
                                         const brillo::SecureBlob& iv,
                                         PaddingScheme padding, BlockMode mode,
                                         brillo::SecureBlob* plaintext);

  // Same as AesEncrypt, but allows using either CBC or ECB
  static bool AesEncryptSpecifyBlockMode(const brillo::SecureBlob& plaintext,
                                         unsigned int start, unsigned int count,
                                         const brillo::SecureBlob& key,
                                         const brillo::SecureBlob& iv,
                                         PaddingScheme padding, BlockMode mode,
                                         brillo::SecureBlob* ciphertext);

  // Obscure an RSA message by encrypting part of it.
  // The TPM could _in theory_ produce an RSA message (as a response from Bind)
  // that contains a header of a known format. If it did, and we encrypted the
  // whole message with a passphrase-derived AES key, then one could test
  // passphrase correctness by trial-decrypting the header. Instead, encrypt
  // only part of the message, and hope the part we encrypt is part of the RSA
  // message.
  //
  // In practice, this never makes any difference, because no TPM does that; the
  // result is always a bare PKCS1.5-padded RSA-encrypted message, which is
  // (as far as the author knows, although no proof is known) indistinguishable
  // from random data, and hence the attack this would protect against is
  // infeasible.
  static bool ObscureRSAMessage(const brillo::SecureBlob& plaintext,
                                const brillo::SecureBlob& key,
                                brillo::SecureBlob* ciphertext);
  static bool UnobscureRSAMessage(const brillo::SecureBlob& ciphertext,
                                  const brillo::SecureBlob& key,
                                  brillo::SecureBlob* plaintext);

  // Encrypts data using the RSA OAEP scheme with the SHA-1 hash function, the
  // MGF1 mask function, and an empty label parameter.
  static bool RsaOaepEncrypt(const brillo::SecureBlob& plaintext,
                             RSA* key,
                             brillo::Blob* ciphertext);
  // Decrypts the data encrypted with RSA OAEP with the SHA-1 hash function, the
  // MGF1 mask function, and the label parameter equal to |oaep_label|.
  static bool RsaOaepDecrypt(const brillo::SecureBlob& ciphertext,
                             const brillo::SecureBlob& oaep_label,
                             RSA* key,
                             brillo::SecureBlob* plaintext);

  // Encodes a binary blob to hex-ascii. Similar to base::HexEncode but
  // produces lowercase letters for hex digits.
  //
  // Parameters
  //   blob - The binary blob to convert
  static std::string BlobToHex(const brillo::Blob& blob);
  static std::string SecureBlobToHex(const brillo::SecureBlob& blob);

  // Parameters
  //   blob - The binary blob to convert
  //   buffer (IN/OUT) - Where to store the converted blob
  //   buffer_length - The size of the buffer
  static void BlobToHexToBuffer(const brillo::Blob& blob,
                                void* buffer,
                                size_t buffer_length);
  static void SecureBlobToHexToBuffer(const brillo::SecureBlob& blob,
                                      void* buffer,
                                      size_t buffer_length);
  // Computes an HMAC over the iv and encrypted_data fields of an EncryptedData
  // protobuf.
  // Parameters
  //   encrypted_data - encrypted data protobuf..
  //   hmac_key - secret key to use in hmac computation.
  static std::string ComputeEncryptedDataHMAC(
      const EncryptedData& encrypted_data,
      const brillo::SecureBlob& hmac_key);

  // Encrypts data using the TPM_ES_RSAESOAEP_SHA1_MGF1 scheme.
  //
  // Parameters
  //   key - The RSA public key.
  //   input - The data to be encrypted.
  //   output - The encrypted data.
  static bool TpmCompatibleOAEPEncrypt(RSA* key,
                                       const brillo::SecureBlob& input,
                                       brillo::SecureBlob* output);

  // Checks an RSA key modulus for the ROCA fingerprint (i.e. whether the RSA
  // modulus has a discrete logarithm modulus small primes). See research paper
  // for details: https://crocs.fi.muni.cz/public/papers/rsa_ccs17
  static bool TestRocaVulnerable(const BIGNUM* rsa_modulus);

  // 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 size.
  //
  static bool DeriveSecretsScrypt(const brillo::SecureBlob& passkey,
                                  const brillo::SecureBlob& salt,
                                  std::vector<brillo::SecureBlob*> gen_secrets);

  // This wraps the |crypto_scrypt| function so that it always called
  // |malloc_trim| after to free the used heap space.
  //
  // |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 crypto_scrypt.
  // |block_size| - The block size passed to crypto_scrypt.
  // |parallel_factor| - The parallel factor passed to crypto_scrypt.
  // |result| - The blob, allocated by the caller to the correct size,
  //            containing the result secret.
  //
  //  Returns 0 on success.
  static int 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.
  static bool EncryptScryptBlob(const brillo::SecureBlob& blob,
                                const brillo::SecureBlob& key_source,
                                brillo::SecureBlob* wrapped_blob);

  // Companion decryption function for EncryptScryptBlob().
  // This decrypts the data blobs which were encrypted using
  // EncryptScryptBlob().
  //
  // Returns true on success. On failure, false is returned, and
  // |error| is set with the appropriate error code.
  static bool DecryptScryptBlob(const brillo::SecureBlob& wrapped_blob,
                                const brillo::SecureBlob& key,
                                brillo::SecureBlob* blob,
                                CryptoError* error);

  // This verifies that the default scrypt params are used in production.
  static void AssertProductionScryptParams();

  // This updates the global static scrypt testing parameters.
  static void SetScryptTestingParams();

  // Global static override-able for testing.
  static ScryptParameters gScryptParams;
};

}  // namespace cryptohome

#endif  // CRYPTOHOME_CRYPTOLIB_H_
