| // Copyright 2022 The ChromiumOS Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef LIBHWSEC_BACKEND_RECOVERY_CRYPTO_H_ |
| #define LIBHWSEC_BACKEND_RECOVERY_CRYPTO_H_ |
| |
| #include <optional> |
| #include <string> |
| |
| #include <brillo/secure_blob.h> |
| #include <crypto/scoped_openssl_types.h> |
| |
| #include "libhwsec/status.h" |
| #include "libhwsec/structures/no_default_init.h" |
| #include "libhwsec/structures/operation_policy.h" |
| #include "libhwsec-foundation/crypto/elliptic_curve.h" |
| |
| namespace hwsec { |
| |
| // Recovery crypto backend input parameters for function EncryptEccPrivateKey. |
| struct EncryptEccPrivateKeyRequest { |
| // Note: The EllipticCurve cannot be destructed before the call finished. |
| const hwsec_foundation::EllipticCurve& ec; |
| // Private key from one's own key pair would be imported to TPM2.0 or sealed |
| // by TPM1.2. |
| crypto::ScopedEC_KEY own_key_pair; |
| // Additional secret to seal the destination share. Used for TPM 1.2 only. |
| NoDefault<std::optional<brillo::SecureBlob>> auth_value; |
| // The obfuscated username that key needs to be bound to. |
| NoDefault<std::string> current_user; |
| }; |
| |
| // Recovery crypto backend output parameters for function EncryptEccPrivateKey. |
| struct EncryptEccPrivateKeyResponse { |
| // One's own private key after imported/sealed to TPM. |
| brillo::Blob encrypted_own_priv_key; |
| // One's own private key after sealed to TPM1.2 with binding to extended PCR. |
| brillo::Blob extended_pcr_bound_own_priv_key; |
| }; |
| |
| // Recovery crypto backend input parameters for function |
| // GenerateDiffieHellmanSharedSecret. |
| struct GenerateDhSharedSecretRequest { |
| // Note: The EllipticCurve cannot be destructed before the call finished. |
| const hwsec_foundation::EllipticCurve& ec; |
| // One's own private key which is imported to TPM2.0 or sealed by TPM1.2. |
| NoDefault<brillo::Blob> encrypted_own_priv_key; |
| // One's own private key which is sealed by TPM1.2 and bound to extended PCR. |
| NoDefault<brillo::Blob> extended_pcr_bound_own_priv_key; |
| // Additional secret to Blob the destination share. Used for TPM 1.2 only. |
| NoDefault<std::optional<brillo::SecureBlob>> auth_value; |
| // The obfuscated username that key is bound to. |
| NoDefault<std::string> current_user; |
| // Public key from the other part, used to generate shared secret. |
| crypto::ScopedEC_POINT others_pub_point; |
| }; |
| |
| // A Hardware-backed RSA key pair. |
| // The RSA private key would be used to sign recovery request payload |
| // when channel private key cannot be restored in a secure manner. |
| // Therefore, it will only be implemented in TPM1 backend. |
| struct RecoveryCryptoRsaKeyPair { |
| // The encrypted private key for the RSA key pair. |
| brillo::Blob encrypted_rsa_private_key; |
| // The DER encoded SPKI format public key. |
| brillo::Blob rsa_public_key_spki_der; |
| }; |
| |
| // RecoveryCrypto - class for performing cryptorecovery |
| // encryption/decryption in the secure hardware. For cryptorecovery, the |
| // secure hardware may be used as a way to strengthen the secret shares/ |
| // private keys stored on disk. |
| class RecoveryCrypto { |
| public: |
| // Generate key_auth_value. key auth value is required for sealing/ |
| // unsealing in TPM1.2 only and the required length is 32 bytes. The |
| // implementation for TPM2 backend will return std::nullopt. |
| virtual StatusOr<std::optional<brillo::SecureBlob>> |
| GenerateKeyAuthValue() = 0; |
| |
| // Encrypts the provided ECC private key using TPM, and returns it via |
| // `encrypted_own_priv_key`, which is one's own private key. (the format of |
| // this blob is TPM-specific). Returns false on failure. |
| // As TPM1.2 does not support ECC, instead of encrypting the ECC private key, |
| // it will seal the private key with the provided auth_value. |
| virtual StatusOr<EncryptEccPrivateKeyResponse> EncryptEccPrivateKey( |
| const EncryptEccPrivateKeyRequest& request) = 0; |
| |
| // Multiplies the private key, provided in encrypted form, with the given the |
| // other party's public EC point. Returns the multiplication, or nullptr on |
| // failure. |
| // As TPM1.2 does not support ECC, instead of loading the ECC private key and |
| // computing the shared secret from TPM modules, the private key will be |
| // unsealed with the provided auth_value and the shared secret will be |
| // computed via openssl lib. |
| virtual StatusOr<crypto::ScopedEC_POINT> GenerateDiffieHellmanSharedSecret( |
| const GenerateDhSharedSecretRequest& request) = 0; |
| |
| // Generate a TPM-backed RSA key pair. |
| // Generated RSA private key would be used to sign recovery request payload |
| // when channel private key cannot be restored in a secure manner. |
| // Therefore, it will only be implemented in TPM1 backend. For TPM2, a dummy |
| // std::nullopt would be returned. |
| virtual StatusOr<std::optional<RecoveryCryptoRsaKeyPair>> |
| GenerateRsaKeyPair() = 0; |
| |
| // Sign the request payload with the provided RSA private key. The RSA |
| // private key would be loaded from the TPM modules first and used to sign |
| // the payload. As signing the request payload is only required for TPM1, |
| // the implementation of TPM2 would return a dummy std::nullopt. |
| virtual StatusOr<std::optional<brillo::Blob>> SignRequestPayload( |
| const brillo::Blob& encrypted_rsa_private_key, |
| const brillo::Blob& request_payload) = 0; |
| |
| protected: |
| RecoveryCrypto() = default; |
| ~RecoveryCrypto() = default; |
| }; |
| |
| } // namespace hwsec |
| |
| #endif // LIBHWSEC_BACKEND_RECOVERY_CRYPTO_H_ |