blob: aef8e7b87a54c0da252b6496788c3535e1240655 [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library fuchsia.tpm.cr50;
using zx;
/// All the errors that can be returned by the CR50 for the PinWeaver protocol.
type PinWeaverError = strict enum : uint32 {
VERSION_MISMATCH = 0x10000;
TREE_INVALID = 0x10001;
LENGTH_INVALID = 0x10002;
TYPE_INVALID = 0x10003;
BITS_PER_LEVEL_INVALID = 0x10004;
HEIGHT_INVALID = 0x10005;
LABEL_INVALID = 0x10006;
DELAY_SCHEUDLE_INVALID = 0x10007;
PATH_AUTH_FAILED = 0x10008;
LEAF_VERSION_MISMATCH = 0x10009;
HMAC_AUTH_FAILED = 0x1000A;
LOWENT_AUTH_FAILED = 0x1000B;
RESET_AUTH_FAILED = 0x1000C;
CRYPTO_FAILURE = 0x1000D;
RATE_LIMIT_REACHED = 0x1000E;
ROOT_NOT_FOUND = 0x1000F;
NV_EMPTY = 0x10010;
NV_LENGTH_MISMATCH = 0x10011;
NV_VERSION_MISMATCH = 0x10012;
PCR_NOT_MATCH = 0x10013;
};
/// Maximum number of delay schedule entries.
const DELAY_SCHEDULE_MAX_COUNT uint32 = 16;
/// Maximum size of the credential metadata.
const CREDENTIAL_METADATA_MAX_SIZE uint32 = 2048;
/// Maximum size of a low entropy secret
const LE_SECRET_MAX_SIZE uint32 = 32;
/// Maximum size of a high entropy secret
const HE_SECRET_MAX_SIZE uint32 = 32;
/// Size of a SHA256 hash.
const HASH_SIZE uint32 = 32;
/// Size of a HMAC-SHA256 hash.
const MAC_SIZE uint32 = 32;
/// Maximum number of log entries returned by GetLog.
const MAX_LOG_ENTRIES uint32 = 2;
/// The identifier corresponding to a credential within the Merkle tree.
/// This is a globally unique identifier that identifies a specific
/// location in the tree.
alias Label = uint64;
/// A secure SHA256 sized byte buffer. These are used by the intermediate
/// Merkle tree nodes including the root hash.
alias Hash = array<byte, HASH_SIZE>;
/// A HMAC-SHA256 over the credential metadata and a secret key stored by
/// the CR50. These form the leaf hashes of the Merkle tree.
alias Mac = array<byte, MAC_SIZE>;
/// Opaque metadata for credential as produced by the PinWeaver server.
alias CredMetadata = vector<uint8>:CREDENTIAL_METADATA_MAX_SIZE;
/// A low entropy or user provided secret such as a pin or password.
alias LeSecret = vector<uint8>:LE_SECRET_MAX_SIZE;
/// A high entropy secret that is randomly generated and usable for symmetric
/// key encryption.
alias HeSecret = vector<uint8>:HE_SECRET_MAX_SIZE;
/// The list of auxiliary hashes for a particular leaf node. These are the
/// hashes which together with the leaf nodes HMAC are required to recompute
/// the updated root hash of the hash tree.
alias AuxiliaryHashes = vector<Hash>:128;
/// Defines a single entry in the table of failed authentication attempt number
/// to authentication delay.
type DelayScheduleEntry = struct {
/// The number of successive failed attempts at which this entry begins
/// to apply.
attempt_count uint32;
/// The delay before another authentication attempt is allowed. May either
/// be a duration between 1 second and 49710 days to enforce a delay or
/// duration::INFINITE to prevent further authentication attempts.
time_delay zx.Duration;
};
/// Parameters to InsertLeaf method.
/// TODO(https://fxbug.dev/42169565): Replace with anonymous tables when avaliable as
/// parameter arguments.
type InsertLeafParams = table {
/// `label` is the location of the leaf in the tree.
1: label Label;
/// `h_aux` is the auxiliary hashes from the bottom left to top right.
2: h_aux AuxiliaryHashes;
/// `le_secret` is the low entropy secret.
3: le_secret LeSecret;
/// `he_secret` is the high entropy secret protected by the `le_secret`.
4: he_secret HeSecret;
/// `reset_secret` is the reset secret to reset the leaf node.
5: reset_secret HeSecret;
/// `delay_schedule` defines the delay between authentication attempts
/// as a function of the number of successive failed attempts.
6: delay_schedule vector<DelayScheduleEntry>:DELAY_SCHEDULE_MAX_COUNT;
};
/// Response from the InsertLeaf method.
/// TODO(https://fxbug.dev/42169565): Replace with anonymous tables when avaliable as
/// parameter arguments.
type InsertLeafResponse = table {
/// `root_hash` is set to the updated root hash of the tree.
1: root_hash Hash;
/// `cred_metadata` is set to the wrapped leaf data.
2: cred_metadata CredMetadata;
/// `mac` is set to the hmac used in the merkle tree calculation.
3: mac Mac;
};
/// Parameters to RemoveLeaf method.
/// TODO(https://fxbug.dev/42169565): Replace with anonymous tables when avaliable as
/// parameter arguments.
type RemoveLeafParams = table {
/// `label` is the location of the leaf in the tree.
1: label Label;
/// `h_aux` is the auxiliary hashes from bottom left to top right.
2: h_aux AuxiliaryHashes;
/// `mac` is set to the HMAC used in the Merkle tree calculation.
3: mac Mac;
};
/// Parameters to the TryAuth method.
/// TODO(https://fxbug.dev/42169565): Replace with anonymous tables when avaliable as
/// parameter arguments.
type TryAuthParams = table {
/// `le_secret` is the low entropy secret limited by the delay_schedule.
1: le_secret LeSecret;
/// `h_aux` is the auxiliary hashes from bottom left to top right.
2: h_aux AuxiliaryHashes;
/// `cred_metadata` is set to the wrapped leaf data.
3: cred_metadata CredMetadata;
};
/// Authentication can succeed and fail three distinct ways see the `TryAuth()`
/// method for how. This response is returned on all `TryAuth()` calls with
/// one member of the union being filled based on the success or error type.
type TryAuthResponse = flexible union {
1: success TryAuthSuccess;
2: failed TryAuthFailed;
3: rate_limited TryAuthRateLimited;
};
/// Returned on authentication success when the low entropy secret is correct.
type TryAuthSuccess = table {
1: root_hash Hash;
2: he_secret HeSecret;
3: reset_secret HeSecret;
4: cred_metadata CredMetadata;
5: mac Mac;
};
/// Returned on authentication failure when the low entropy secret is incorrect.
type TryAuthFailed = table {
1: root_hash Hash;
2: cred_metadata CredMetadata;
3: mac Mac;
};
/// Describes a log entry as returned from GetLog.
type LogEntry = table {
1: root_hash Hash;
2: label Label;
3: message_type MessageType;
4: entry_data EntryData;
};
/// Enum defining the types of `LogEntry`s that can be returned.
type MessageType = strict enum : uint32 {
INSERT_LEAF = 1;
REMOVE_LEAF = 2;
RESET_TREE = 3;
TRY_AUTH = 4;
};
/// Additional data included as part of `LogEntry` required to execute the
/// replay step.
type EntryData = table {
1: leaf_hmac Mac;
2: timestamp uint64;
3: boot_count uint32;
4: return_code uint32;
};
/// Parameters to LogReplay method.
type LogReplayParams = table {
1: root_hash Hash;
2: cred_metadata CredMetadata;
3: h_aux AuxiliaryHashes;
};
/// Response from LogReplay method.
type LogReplayResponse = table {
1: cred_metadata CredMetadata;
2: leaf_hash Hash;
};
/// Returned on authentication failure when the rate limit has been reached.
/// This is distinct from the other failure mode as the provided low entropy
/// secret may be correct but the caller is locked out until `time_to_wait`
/// has passed.
type TryAuthRateLimited = table {
1: time_to_wait zx.Duration;
};
/// The PinWeaver protocol defines the low level interface to the CR50
/// firmware for low entropy credentials. This interface allows the caller
/// which should be a high trust component the ability to seal high entropy
/// secrets behind rate-limited low entropy secrets which can only be unsealed
/// if the correct low entropy secret is provided and the rate limit has not
/// been reached.
@discoverable
closed protocol PinWeaver {
/// Returns the current protocol version.
strict GetVersion() -> (struct {
protocol_version uint8;
});
/// Creates an empty Merkle tree with `bits_per_level` and `height`.
/// On Success
/// Returns the `root_hash` of the empty tree with the given parameters.
strict ResetTree(struct {
bits_per_level uint8;
height uint8;
}) -> (struct {
root_hash Hash;
}) error PinWeaverError;
/// Inserts a leaf into the Merkle tree.
/// `params` see `InsertLeafParams`.
/// On Success
/// `result` see `InsertLeafResponse`.
strict InsertLeaf(struct {
params InsertLeafParams;
}) -> (struct {
result InsertLeafResponse;
}) error PinWeaverError;
/// Removes a leaf from the Merkle tree.
/// `params` see `RemoveLeafParams`.
/// On Success
/// `root_hash` is the updated root hash of the tree.
strict RemoveLeaf(struct {
params RemoveLeafParams;
}) -> (struct {
root_hash Hash;
}) error PinWeaverError;
/// Attempts to authenticate a leaf of the Merkle tree.
/// On Success: TryAuthSuccess is returned in the union.
/// On Authentication Failure: TryAuthFailed is returned in the union.
/// On Rate Limited Error: TryAuthRateLimited is returned in the union.
strict TryAuth(struct {
params TryAuthParams;
}) -> (struct {
result TryAuthResponse;
}) error PinWeaverError;
/// Retrieves the set of replay logs starting from the specified root hash.
/// If Found: Returns all log entries including and starting from the
/// operation specified by the root hash parameter.
/// If Not Found: Returns all known log entries.
strict GetLog(struct {
root_hash Hash;
}) -> (struct {
logs vector<LogEntry>:MAX_LOG_ENTRIES;
}) error PinWeaverError;
/// Applies a TryAuth operation replay log by modifying the credential
/// metadata based on the state of the replay log.
/// This will step forward any credential metadata for the appropriate
/// label, whether or not it matches the exact state in history.
/// On Success: Returns the updated leaf hmac and credential metadata.
/// On Failure: Returns an error.
strict LogReplay(struct {
params LogReplayParams;
}) -> (struct {
result LogReplayResponse;
}) error PinWeaverError;
};