blob: eb4cb5380bfef9a4919c474ab70978622997f89e [file] [log] [blame]
// Copyright 2014 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 TRUNKS_TPM_UTILITY_H_
#define TRUNKS_TPM_UTILITY_H_
#include <map>
#include <string>
#include <vector>
#include <base/macros.h>
#include <brillo/secure_blob.h>
#include "trunks/hmac_session.h"
#include "trunks/pinweaver.pb.h"
#include "trunks/tpm_alerts.h"
#include "trunks/tpm_generated.h"
#include "trunks/trunks_export.h"
namespace trunks {
// These handles will be used by TpmUtility.
// * kStorageRootKey: Storage Root Key (Primary Key in Storage Hierarchy in
// TPM2.0) It is ECC key by default, if the RSA key is already generated, we
// will keep use it.
// * kSaltingKey: a RSA key under kStorageRootKey for
// asymmetric encrypting the salt when creating a HMAC session.
const TPMI_DH_PERSISTENT kStorageRootKey = PERSISTENT_FIRST;
// Deprecated: kECCStorageRootKey = PERSISTENT_FIRST + 1;
const TPMI_DH_PERSISTENT kSaltingKey = PERSISTENT_FIRST + 2;
const TPMI_DH_PERSISTENT kRSAEndorsementKey = PERSISTENT_FIRST + 3;
// VENDOR_RC_ERR | VENDOR_RC_NO_SUCH_COMMAND
const int TPM_RC_NO_SUCH_COMMAND = 0x57f;
// Real NVRAM index for endoresement certificate. It is the real index which
// sent to TPM.
constexpr uint32_t kRsaEndorsementCertificateIndex = 0x1C00000;
constexpr uint32_t kEccEndorsementCertificateIndex = 0x1C00001;
// The non-real NVRAM index is only used and accepted by tpm_utility API.
// TODO(crbug/956855): remove these indexes.
constexpr uint32_t kRsaEndorsementCertificateNonRealIndex =
kRsaEndorsementCertificateIndex & 0xFFFFFF;
constexpr uint32_t kEccEndorsementCertificateNonRealIndex =
kEccEndorsementCertificateIndex & 0xFFFFFF;
// An interface which provides convenient methods for common TPM operations.
class TRUNKS_EXPORT TpmUtility {
public:
enum AsymmetricKeyUsage { kDecryptKey, kSignKey, kDecryptAndSignKey };
TpmUtility() {}
TpmUtility(const TpmUtility&) = delete;
TpmUtility& operator=(const TpmUtility&) = delete;
virtual ~TpmUtility() {}
// Synchronously performs a TPM startup sequence and self tests. Typically
// this is done by the platform firmware. Returns the result of the startup
// and self-tests or, if already started, just the result of the self-tests.
virtual TPM_RC Startup() = 0;
// Check if the TPM is in a state which allows trunks to proceed. The only
// condition when the state is considered unacceptable and an error is
// returned is if there is no way to communicate with the TPM.
virtual TPM_RC CheckState() = 0;
// This method removes all TPM context associated with a specific Owner.
// As part of this process, it resets the SPS to a new random value, and
// clears ownerAuth, endorsementAuth and lockoutAuth.
// NOTE: This method needs to be called before InitializeTPM.
virtual TPM_RC Clear() = 0;
// Synchronously performs a TPM shutdown operation. It should always be
// successful.
virtual void Shutdown() = 0;
// Synchronously prepares a TPM for use by Chromium OS. Typically this is done
// by the platform firmware and, in that case, this method has no effect.
virtual TPM_RC InitializeTpm() = 0;
// Synchronously allocates the PCRs in the TPM. Currently we allocate
// the first 16 PCRs to use the SHA-256 hash algorithm.
// NOTE: PCR allocation only takes place at the next TPM_Startup call.
// NOTE: This command needs platform authorization and PP assertion.
virtual TPM_RC AllocatePCR(const std::string& platform_password) = 0;
// Performs steps needed for taking ownership, which can be done before
// a signal that an ownership can be attempted is received.
// This operation is an optional optimization: if PrepareForOwnership
// is not called, TakeOwnership will later run through those preparational
// steps, if needed.
virtual TPM_RC PrepareForOwnership() = 0;
// Synchronously takes ownership of the TPM with the given passwords as
// authorization values.
virtual TPM_RC TakeOwnership(const std::string& owner_password,
const std::string& endorsement_password,
const std::string& lockout_password) = 0;
// Stir the tpm random generation module with some random entropy data.
// |delegate| specifies an optional authorization delegate to be used.
virtual TPM_RC StirRandom(const std::string& entropy_data,
AuthorizationDelegate* delegate) = 0;
// This method returns |num_bytes| of random data generated by the tpm.
// |delegate| specifies an optional authorization delegate to be used.
virtual TPM_RC GenerateRandom(size_t num_bytes,
AuthorizationDelegate* delegate,
std::string* random_data) = 0;
// This method extends the pcr specified by |pcr_index| with the SHA256
// hash of |extend_data|. The exact action performed is
// TPM2_PCR_Extend(Sha256(extend_data));
// |delegate| specifies an optional authorization delegate to be used.
virtual TPM_RC ExtendPCR(int pcr_index,
const std::string& extend_data,
AuthorizationDelegate* delegate) = 0;
// This method reads the pcr specified by |pcr_index| and returns its value
// in |pcr_value|. NOTE: it assumes we are using SHA256 as our hash alg.
virtual TPM_RC ReadPCR(int pcr_index, std::string* pcr_value) = 0;
// This method performs an encryption operation using a LOADED RSA key
// referrenced by its handle |key_handle|. The |plaintext| is then encrypted
// to give us the |ciphertext|. |scheme| refers to the encryption scheme
// to be used. By default keys use OAEP, but can also use TPM_ALG_RSAES.
// |delegate| specifies an optional authorization delegate to be used.
virtual TPM_RC AsymmetricEncrypt(TPM_HANDLE key_handle,
TPM_ALG_ID scheme,
TPM_ALG_ID hash_alg,
const std::string& plaintext,
AuthorizationDelegate* delegate,
std::string* ciphertext) = 0;
// This method performs a decryption operating using a loaded RSA key
// referenced by its handle |key_handle|. The |ciphertext| is then decrypted
// to give us the |plaintext|. |scheme| refers to the decryption scheme
// used. Valid schemes are: TPM_ALG_NULL, TPM_ALG_OAEP, TPM_ALG_RSAES.
// |delegate| is an AuthorizationDelegate used to authorize this command.
virtual TPM_RC AsymmetricDecrypt(TPM_HANDLE key_handle,
TPM_ALG_ID scheme,
TPM_ALG_ID hash_alg,
const std::string& ciphertext,
AuthorizationDelegate* delegate,
std::string* plaintext) = 0;
// This method takes an unrestricted signing key referenced by |key_handle|
// and uses it to sign a hash: if |generate_hash| is true then get the hash
// of |plaintext| using |hash_alg|, otherwise |plaintext| is already the hash
// to sign. The signature produced is returned using the |signature| argument.
// |scheme| is used to specify the signature scheme used. By default it is
// TPM_ALG_RSASSA, but TPM_ALG_RSAPPS and TPM_ALG_ECDSA can be specified.
// |hash_alg| is the algorithm used in the signing operation. It is by default
// TPM_ALG_SHA256. |delegate| is an AuthorizationDelegate used to authorize
// this command.
virtual TPM_RC Sign(TPM_HANDLE key_handle,
TPM_ALG_ID scheme,
TPM_ALG_ID hash_alg,
const std::string& plaintext,
bool generate_hash,
AuthorizationDelegate* delegate,
std::string* signature) = 0;
// This method is identical to Sign() above except it returns the result
// in TPMT_SIGNATURE type, not in string type.
virtual TPM_RC RawSign(TPM_HANDLE key_handle,
TPM_ALG_ID scheme,
TPM_ALG_ID hash_alg,
const std::string& plaintext,
bool generate_hash,
AuthorizationDelegate* delegate,
TPMT_SIGNATURE* auth) = 0;
// Dead code removed at CL:1366670 (https://crrev.com/c/1366670)
// It's because we doesn't use Verify() in the reality.
// We sign-with-TPM -> verify-in-software at this moment.
//
// This method verifies that the signature produced on the plaintext was
// performed by |key_handle|. |scheme| and |hash| refer to the signature
// scheme used to produce the signature: if |generate_hash| is true, the
// hash of |plaintext| is signed, otherwise |plaintext| is already the hash
// to sign. The signature scheme is by default TPM_ALG_RSASSA with
// TPM_ALG_SHA256 but can take the value of TPM_ALG_RSAPPS with other hash
// algorithms supported by the tpm. Returns TPM_RC_SUCCESS when the signature
// is correct. |delegate| specifies an optional authorization delegate to be
// used.
// virtual TPM_RC Verify(TPM_HANDLE key_handle,
// TPM_ALG_ID scheme,
// TPM_ALG_ID hash_alg,
// const std::string& plaintext,
// bool generate_hash,
// const std::string& signature,
// AuthorizationDelegate* delegate) = 0;
// This method is used to check if a key was created in the TPM. |key_handle|
// refers to a loaded Tpm2.0 object, and |creation_blob| is the blob
// generated when the object was created. Returns TPM_RC_SUCCESS iff the
// object was created in the TPM.
virtual TPM_RC CertifyCreation(TPM_HANDLE key_handle,
const std::string& creation_blob) = 0;
// This method is used to change the authorization value associated with a
// |key_handle| to |new_password|. |delegate| is an AuthorizationDelegate
// that is loaded with the old authorization value of |key_handle|.
// When |key_blob| is not null, it is populated with the new encrypted key
// blob. Note: the key must be unloaded and reloaded to use the
// new authorization value.
virtual TPM_RC ChangeKeyAuthorizationData(TPM_HANDLE key_handle,
const std::string& new_password,
AuthorizationDelegate* delegate,
std::string* key_blob) = 0;
// This method imports an external RSA key of |key_type| into the TPM.
// |modulus| and |prime_factor| are interpreted as raw bytes in big-endian
// order. If the out argument |key_blob| is not null, it is populated with
// the imported key, which can then be loaded into the TPM.
virtual TPM_RC ImportRSAKey(AsymmetricKeyUsage key_type,
const std::string& modulus,
uint32_t public_exponent,
const std::string& prime_factor,
const std::string& password,
AuthorizationDelegate* delegate,
std::string* key_blob) = 0;
// This method imports an external ECC key of |key_type| into the TPM.
// |public_point_x| and |public_point_y| are the coordinates of the public key
// point on the curve |curve_id|. |private_value| is the private key.
// |public_point_x|, |public_point_y|, and |private_value| are interpreted as
// raw bytes in big-endian. |password| is the authorization value for the
// imported key. If the out argument |key_blob| is not null, it is populated
// with the imported key, which can then be loaded into the TPM.
virtual TPM_RC ImportECCKey(AsymmetricKeyUsage key_type,
TPMI_ECC_CURVE curve_id,
const std::string& public_point_x,
const std::string& public_point_y,
const std::string& private_value,
const std::string& password,
AuthorizationDelegate* delegate,
std::string* key_blob) = 0;
// This method uses the TPM to generates an RSA key of type |key_type|.
// |modulus_bits| is used to specify the size of the modulus, and
// |public_exponent| specifies the exponent of the key. After this function
// terminates, |key_blob| contains a key blob that can be loaded into the TPM.
// |policy_digest| specifies an optional policy to use to authorize this key.
// |use_only_policy_authorization| specifies if we can use HmacSession in
// addition to PolicySession to authorize use of this key.
// |creation_pcr_indexes| allows the caller to specify a list of pcr indexes
// in the creation data.
// If the |creation_blob| out param is defined, it will contain the
// serialized creation structures generated by the TPM.
// This can be used to verify the state of the TPM during key creation.
// NOTE: if |use_only_policy_authorization| is set to true,
// parameter_encryption must be disabled when the key is used.
virtual TPM_RC CreateRSAKeyPair(
AsymmetricKeyUsage key_type,
int modulus_bits,
uint32_t public_exponent,
const std::string& password,
const std::string& policy_digest,
bool use_only_policy_authorization,
const std::vector<uint32_t>& creation_pcr_indexes,
AuthorizationDelegate* delegate,
std::string* key_blob,
std::string* creation_blob) = 0;
// This method uses the TPM to generates an ECC key of type |key_type|.
// |curve_id| is the TPM curve ID of EC curve used for the generating the key.
// |password| is the authorization value to use to authorize the generating
// key.
// |policy_digest| specifies an optional policy to use to authorize the
// generating key.
// |use_only_policy_authorization| specifies if we can use
// HmacSession in addition to PolicySession to authorize use of this key.
// |creation_pcr_indexes| allows the caller to specify a list of pcr indexes
// in the creation data.
// |delegate| is an AuthorizationDelegate used to authorize the SRK which is
// the parent of created key.
// |key_blob| contains the key blob of created key that can be loaded into the
// TPM.
// If the |creation_blob| out param is defined, it will contain the serialized
// creation structures generated by the TPM. This can be used to verify the
// state of the TPM during key creation. NOTE: if
// |use_only_policy_authorization| is set to true, parameter_encryption must
// be disabled when the key is used.
virtual TPM_RC CreateECCKeyPair(
AsymmetricKeyUsage key_type,
TPMI_ECC_CURVE curve_id,
const std::string& password,
const std::string& policy_digest,
bool use_only_policy_authorization,
const std::vector<uint32_t>& creation_pcr_indexes,
AuthorizationDelegate* delegate,
std::string* key_blob,
std::string* creation_blob) = 0;
// This method loads a pregenerated TPM key into the TPM. |key_blob| contains
// the blob returned by a key creation function. The loaded key's handle is
// returned using |key_handle|.
virtual TPM_RC LoadKey(const std::string& key_blob,
AuthorizationDelegate* delegate,
TPM_HANDLE* key_handle) = 0;
// This method loads the public part of an external RSA key into the TPM. Key
// is of type |key_type|. Algorithm scheme and hashing algorithm are passed
// via |scheme| and |hash_alg|. |modulus| is interpreted as raw bytes in
// big-endian order. |public_exponent| specifies the exponent of the key. The
// loaded key's handle is returned using |key_handle|.
virtual TPM_RC LoadRSAPublicKey(AsymmetricKeyUsage key_type,
TPM_ALG_ID scheme,
TPM_ALG_ID hash_alg,
const std::string& modulus,
uint32_t public_exponent,
AuthorizationDelegate* delegate,
TPM_HANDLE* key_handle) = 0;
// This methods loads the public part of an external ECC key to TPM. Key is
// is of type |key_type|. Algorithm scheme and hash algorithm are passed via
// |scheme| and |hash_alg|.
virtual TPM_RC LoadECPublicKey(AsymmetricKeyUsage key_type,
TPM_ECC_CURVE curve_id,
TPM_ALG_ID scheme,
TPM_ALG_ID hash_alg,
const std::string& x,
const std::string& y,
AuthorizationDelegate* delegate,
TPM_HANDLE* key_handle) = 0;
// This function sets |name| to the name of the object referenced by
// |handle|. This function only works on Transient and Permanent objects.
virtual TPM_RC GetKeyName(TPM_HANDLE handle, std::string* name) = 0;
// This function returns the public area of a handle in the tpm.
virtual TPM_RC GetKeyPublicArea(TPM_HANDLE handle,
TPMT_PUBLIC* public_data) = 0;
// This method seals |data_to_seal| to the TPM. The |sealed_data| can be
// retrieved by fulfilling the policy represented by |policy_digest|. The
// session used to unseal the data will need to have the
// EntityAuthorizationValue set to |auth_value| if non-empty.
virtual TPM_RC SealData(const std::string& data_to_seal,
const std::string& policy_digest,
const std::string& auth_value,
AuthorizationDelegate* delegate,
std::string* sealed_data) = 0;
// This method is used to retrieve data that was sealed to the TPM.
// |sealed_data| refers to sealed data returned from SealData.
virtual TPM_RC UnsealData(const std::string& sealed_data,
AuthorizationDelegate* delegate,
std::string* unsealed_data) = 0;
// This method sets up a given HmacSession with parameter encryption set to
// true. Returns an TPM_RC_SUCCESS on success.
virtual TPM_RC StartSession(HmacSession* session) = 0;
// This method uses a trial session to compute the |policy_digest| when
// the policy is bound to a given map of pcr_index -> pcr_value in |pcr_map|.
// If some values in the map are empty, the method uses the current value of
// the pcr for the corresponding indexes. If |use_auth_value| is set to true
// then a authorization value will be required when using the digest. In this
// case PolicyAuthValue is called on session first, and PolicyPCR is called
// after this. Those two calls must be made in the same order when we need to
// reveal the secret guarded by the authorization value.
virtual TPM_RC GetPolicyDigestForPcrValues(
const std::map<uint32_t, std::string>& pcr_map,
bool use_auth_value,
std::string* policy_digest) = 0;
// This method defines a non-volatile storage area in the TPM, referenced
// by |index| of size |num_bytes|. This command needs owner authorization.
// The |attributes| of the space must be specified as a combination of
// TPMA_NV_* values. Optionally, an |authorization_value| and / or
// |policy_digest| can be specified which will be associated with the space.
// These values must either be a valid SHA256 digest (or empty).
virtual TPM_RC DefineNVSpace(uint32_t index,
size_t num_bytes,
TPMA_NV attributes,
const std::string& authorization_value,
const std::string& policy_digest,
AuthorizationDelegate* delegate) = 0;
// This method destroys the non-volatile space referred to by |index|.
// This command needs owner authorization.
virtual TPM_RC DestroyNVSpace(uint32_t index,
AuthorizationDelegate* delegate) = 0;
// This method locks the non-volatile space referred to by |index|. The caller
// needs indicate whether they want to |lock_read| and / or |lock_write|. They
// also need to indicate if they are |using_owner_authorization|.
virtual TPM_RC LockNVSpace(uint32_t index,
bool lock_read,
bool lock_write,
bool using_owner_authorization,
AuthorizationDelegate* delegate) = 0;
// This method writes |nvram_data| to the non-volatile space referenced by
// |index|, at |offset| bytes from the start of the non-volatile space. The
// caller needs to indicate if they are |using_owner_authorization|. If
// |extend| is set, the value will be extended and offset ignored.
virtual TPM_RC WriteNVSpace(uint32_t index,
uint32_t offset,
const std::string& nvram_data,
bool using_owner_authorization,
bool extend,
AuthorizationDelegate* delegate) = 0;
// This method reads |num_bytes| of data from the |offset| located at the
// non-volatile space defined by |index|. This method returns an error if
// |length| + |offset| is larger than the size of the defined non-volatile
// space. The caller needs to indicate if they are |using_owner_authorization|
virtual TPM_RC ReadNVSpace(uint32_t index,
uint32_t offset,
size_t num_bytes,
bool using_owner_authorization,
std::string* nvram_data,
AuthorizationDelegate* delegate) = 0;
// This function sets |name| to the name of the non-volatile space referenced
// by |index|.
virtual TPM_RC GetNVSpaceName(uint32_t index, std::string* name) = 0;
// This function returns the public area of an non-volatile space defined in
// the TPM.
virtual TPM_RC GetNVSpacePublicArea(uint32_t index,
TPMS_NV_PUBLIC* public_data) = 0;
// Lists all defined NV indexes.
virtual TPM_RC ListNVSpaces(std::vector<uint32_t>* index_list) = 0;
// Sets dictionary attack parameters. Requires lockout authorization.
// Parameters map directly to TPM2_DictionaryAttackParameters in the TPM 2.0
// specification.
virtual TPM_RC SetDictionaryAttackParameters(
uint32_t max_tries,
uint32_t recovery_time,
uint32_t lockout_recovery,
AuthorizationDelegate* delegate) = 0;
// Reset dictionary attack lockout. Requires lockout authorization.
virtual TPM_RC ResetDictionaryAttackLock(AuthorizationDelegate* delegate) = 0;
// Gets the endorsement key of a given |key_type|, creating the key as needed
// If the |key_type| is RSA, the key will be made persistent. On success
// returns TPM_RC_SUCCESS and populates |key_handle|. Requires endorsement
// authorization to create the key and owner authorization to make the key
// persistent (RSA only). The |owner_delegate| is ignored if |key_type| is not
// RSA or if the key is already persistent.
virtual TPM_RC GetEndorsementKey(TPM_ALG_ID key_type,
AuthorizationDelegate* endorsement_delegate,
AuthorizationDelegate* owner_delegate,
TPM_HANDLE* key_handle) = 0;
// Creates an asymmetric restricted signing key of the given |key_type|.
// On success returns TPM_RC_SUCCESS and populates |key_blob|.
virtual TPM_RC CreateIdentityKey(TPM_ALG_ID key_type,
AuthorizationDelegate* delegate,
std::string* key_blob) = 0;
// For TPMs with updateable firmware: Declate the current firmware
// version stable and invalidate previous versions, if any.
// Returns the result of sending the appropriate command to the TPM.
// For TPMs with fixed firmware: NOP, always returns TPM_RC_SUCCESS.
virtual TPM_RC DeclareTpmFirmwareStable() = 0;
// Reads the RSA certificate from nvram space and extracts the public key
// modulus into |ekm|. Returns TPM_RC_SUCCESS on success.
virtual TPM_RC GetPublicRSAEndorsementKeyModulus(std::string* ekm) = 0;
// For TPMs that support it: allow setting the CCD password if |allow_pwd|
// is true, prohibit otherwise.
// Returns the result of sending the appropriate command to the TPM.
// For TPMs that don't support it: NOP, always returns TPM_RC_SUCCESS.
// Rationale for this behavior: All TPM revisions that need restricting CCD
// password implement this command. If the command is not implemented, the
// TPM firmware has no notion of restricting the CCD password and doesn't need
// a signal to lock things down at login.
virtual TPM_RC ManageCCDPwd(bool allow_pwd) = 0;
// Reads TPM alerts information from the chip.
// If alerts->chip_family equals to kFamilyUndefined then
// this operation is not supported by the chip.
// Returns TPM_RC_SUCCESS on success.
virtual TPM_RC GetAlertsData(TpmAlertsData* alerts) = 0;
// Input parameter:
// |request_version| is the pinweaver protocol version that cryptohome
// knows about.
// Output parameters:
// |protocol_version| is the current protocol version used by pinweaver.
// Returns TPM_RC_SUCCESS if PinWeaver is supported.
virtual TPM_RC PinWeaverIsSupported(uint8_t request_version,
uint8_t* protocol_version) = 0;
// Create an empty Merkle tree with the given parameters.
// On success:
// returns VENDOR_RC_SUCCESS
// |result_code| is set to EC_SUCCESS (0).
// |root_hash| is set to the root hash of the empty tree with the given
// parameters.
// On failure:
// returns VENDOR_RC_SUCCESS
// |result_code| is set to one of pw_error_codes_enum.
// |root_hash| is set to the root hash of the empty tree with the given.
// parameters.
virtual TPM_RC PinWeaverResetTree(uint8_t protocol_version,
uint8_t bits_per_level,
uint8_t height,
uint32_t* result_code,
std::string* root_hash) = 0;
// Insert a leaf to the Merkle tree where:
// |protocol_version| is the protocol version used to comunicate with
// pinweaver.
// |label| is the location of the leaf in the tree.
// |h_aux| is the auxiliary hashes started from the bottom of the tree
// working toward the root in index order.
// |le_secret| is the low entropy secret that is limited by the delay
// schedule.
// |he_secret| is the high entropy secret that is protected by Cr50 and
// returned on successful authentication.
// |reset_secret| is the high entropy secret used to reset the attempt
// counters and authenticate without following the delay schedule.
// |delay_schedule| is constructed of (attempt_count, time_delay) with at
// most PW_SCHED_COUNT entries.
// |valid_pcr_criteria| is list of at most PW_MAX_PCR_CRITERIA_COUNT entries
// where each entry represents a bitmask of PCR indexes and the expected
// digest corresponding to those PCR.
// On success:
// returns VENDOR_RC_SUCCESS
// |result_code| is set to EC_SUCCESS (0).
// |root_hash| is set to the updated root hash of the tree.
// |cred_metadata| is set to the wrapped leaf data.
// |mac| is set to the HMAC used in the Merkle tree calculations.
// On failure:
// returns VENDOR_RC_SUCCESS
// |result_code| is set to one of pw_error_codes_enum.
// |root_hash| is set to the unchanged root hash of the tree.
// |cred_metadata| and |mac| are both empty.
virtual TPM_RC PinWeaverInsertLeaf(
uint8_t protocol_version,
uint64_t label,
const std::string& h_aux,
const brillo::SecureBlob& le_secret,
const brillo::SecureBlob& he_secret,
const brillo::SecureBlob& reset_secret,
const std::map<uint32_t, uint32_t>& delay_schedule,
const ValidPcrCriteria& valid_pcr_criteria,
uint32_t* result_code,
std::string* root_hash,
std::string* cred_metadata,
std::string* mac) = 0;
// Remove a leaf from the Merkle tree where:
// |protocol_version| is the protocol version used to comunicate with
// pinweaver.
// |label| is the location of the leaf in the tree.
// |h_aux| is the auxiliary hashes started from the bottom of the tree
// working toward the root in index order.
// |mac| is set to the HMAC used in the Merkle tree calculations.
// On success:
// returns VENDOR_RC_SUCCESS
// |result_code| is set to EC_SUCCESS (0).
// |root_hash| is set to the updated root hash of the tree.
// On failure:
// returns VENDOR_RC_SUCCESS
// |result_code| is set to one of pw_error_codes_enum.
// |root_hash| is set to the unchanged root hash of the tree.
virtual TPM_RC PinWeaverRemoveLeaf(uint8_t protocol_version,
uint64_t label,
const std::string& h_aux,
const std::string& mac,
uint32_t* result_code,
std::string* root_hash) = 0;
// Attempts to authenticate a leaf from the Merkle tree where:
// |protocol_version| is the protocol version used to comunicate with
// pinweaver.
// |le_secret| is the low entropy secret that is limited by the delay
// schedule.
// |h_aux| is the auxiliary hashes started from the bottom of the tree
// working toward the root in index order.
// |cred_metadata| is set to the wrapped leaf data.
// On auth success:
// returns VENDOR_RC_SUCCESS
// |result_code| is set to EC_SUCCESS (0).
// |root_hash| is set to the updated root hash of the tree.
// |he_secret| is the high entropy secret that is protected by Cr50 and
// returned on successful authentication.
// |reset_secret| is the reset secret that is protected by Cr50 and
// returned on successful authentication.
// |cred_metadata_out| is set to the updated wrapped leaf data.
// |mac_out| is set to the updated HMAC used in the Merkle tree
// calculations.
// |seconds_to_wait| is 0
// On auth fail:
// returns VENDOR_RC_SUCCESS
// |result_code| is set to PW_ERR_LOWENT_AUTH_FAILED.
// |root_hash| is set to the updated root hash of the tree.
// |cred_metadata_out| is set to the updated wrapped leaf data.
// |mac_out| is set to the updated HMAC used in the Merkle tree
// calculations.
// |seconds_to_wait| is 0
// |he_secret| and |reset_secret| are empty.
// On rate limited:
// returns VENDOR_RC_SUCCESS
// |result_code| is set to PW_ERR_RATE_LIMIT_REACHED.
// |root_hash| is set to the unchanged root hash of the tree.
// |seconds_to_wait| is set to the seconds required before an authentication
// attempt can be made.
// |he_secret|, |reset_secret|, |cred_metadata_out|, and |mac| are all
// empty.
// On error:
// returns VENDOR_RC_SUCCESS
// |result_code| is set to one of pw_error_codes_enum.
// |root_hash| is set to the unchanged root hash of the tree.
// |seconds_to_wait| is 0
// |he_secret|, |reset_secret|, |cred_metadata_out|, and |mac| are all
// empty.
//
// Note that for the invalid fields |seconds_to_wait| will be zero and the
// rest will be cleared (e.g. zero length), so it isn't necessary to check
// |result_code| to determine if fields are valid or not.
virtual TPM_RC PinWeaverTryAuth(uint8_t protocol_version,
const brillo::SecureBlob& le_secret,
const std::string& h_aux,
const std::string& cred_metadata,
uint32_t* result_code,
std::string* root_hash,
uint32_t* seconds_to_wait,
brillo::SecureBlob* he_secret,
brillo::SecureBlob* reset_secret,
std::string* cred_metadata_out,
std::string* mac_out) = 0;
// Attempts to reset a leaf from the Merkle tree where:
// |protocol_version| is the protocol version used to comunicate with
// pinweaver.
// |reset_secret| is the high entropy secret used to reset the attempt
// counters and authenticate without following the delay schedule.
// |h_aux| is the auxiliary hashes started from the bottom of the tree
// working toward the root in index order.
// |cred_metadata| is set to the wrapped leaf data.
// On auth success:
// returns VENDOR_RC_SUCCESS
// |result_code| is set to EC_SUCCESS (0).
// |root_hash| is set to the updated root hash of the tree.
// |he_secret| is the high entropy secret that is protected by Cr50 and
// returned on successful authentication.
// |cred_metadata_out| is set to the updated wrapped leaf data.
// |mac_out| is set to the updated HMAC used in the Merkle tree
// calculations.
// On auth fail or error:
// returns VENDOR_RC_SUCCESS
// |result_code| is set to one of pw_error_codes_enum.
// |root_hash| is set to the unchanged root hash of the tree.
// |he_secret|, |cred_metadata_out|, and |mac| are all empty.
virtual TPM_RC PinWeaverResetAuth(uint8_t protocol_version,
const brillo::SecureBlob& reset_secret,
const std::string& h_aux,
const std::string& cred_metadata,
uint32_t* result_code,
std::string* root_hash,
brillo::SecureBlob* he_secret,
std::string* cred_metadata_out,
std::string* mac_out) = 0;
// Retrieves the log of recent operations where:
// |protocol_version| is the protocol version used to comunicate with
// pinweaver.
// |root| is the last known root hash.
// On success:
// returns VENDOR_RC_SUCCESS
// |result_code| is set to EC_SUCCESS (0).
// |root_hash| is set to the unchanged root hash of the tree.
// |log| is set to operations since |root| (inclusive) or the entire log if
// |root| isn't found.
// On error:
// returns VENDOR_RC_SUCCESS
// |result_code| is set to one of pw_error_codes_enum.
// |root_hash| is set to the unchanged root hash of the tree.
// |log| is empty.
virtual TPM_RC PinWeaverGetLog(
uint8_t protocol_version,
const std::string& root,
uint32_t* result_code,
std::string* root_hash,
std::vector<trunks::PinWeaverLogEntry>* log) = 0;
// Attempts to replay a previous transaction from the PinWeaver log where:
// |log_root| is the root hash of the log entry to be replayed.
// |h_aux| is the auxiliary hashes started from the bottom of the tree
// working toward the root in index order.
// |cred_metadata| is set to the wrapped leaf data.
// On success:
// returns VENDOR_RC_SUCCESS
// |result_code| is set to EC_SUCCESS (0).
// |root_hash| is set to the unchanged root hash of the tree.
// |cred_metadata_out| is set to the updated wrapped leaf data.
// |mac_out| is set to the updated HMAC used in the Merkle tree
// calculations.
// On error:
// returns VENDOR_RC_SUCCESS
// |result_code| is set to one of pw_error_codes_enum.
// |root_hash| is set to the unchanged root hash of the tree.
virtual TPM_RC PinWeaverLogReplay(uint8_t protocol_version,
const std::string& log_root,
const std::string& h_aux,
const std::string& cred_metadata,
uint32_t* result_code,
std::string* root_hash,
std::string* cred_metadata_out,
std::string* mac_out) = 0;
// Retrieves cached RSU device id.
virtual TPM_RC GetRsuDeviceId(std::string* device_id) = 0;
};
} // namespace trunks
#endif // TRUNKS_TPM_UTILITY_H_