/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.hardware.keymaster@3.0;

enum TagType : uint32_t {
    INVALID = 0 << 28, /* Invalid type, used to designate a tag as uninitialized */
    ENUM = 1 << 28,
    ENUM_REP = 2 << 28, /* Repeatable enumeration value. */
    UINT = 3 << 28,
    UINT_REP = 4 << 28, /* Repeatable integer value */
    ULONG = 5 << 28,
    DATE = 6 << 28,
    BOOL = 7 << 28,
    BIGNUM = 8 << 28,
    BYTES = 9 << 28,
    ULONG_REP = 10 << 28, /* Repeatable long value */
};

enum Tag : uint32_t {
    INVALID = TagType:INVALID | 0,

    /**
     * Tags that must be semantically enforced by hardware and software implementations.
     */

    /** Crypto parameters */
    PURPOSE = TagType:ENUM_REP | 1,    /** KeyPurpose. */
    ALGORITHM = TagType:ENUM | 2,      /** Algorithm. */
    KEY_SIZE = TagType:UINT | 3,       /** Key size in bits. */
    BLOCK_MODE = TagType:ENUM_REP | 4, /** BlockMode. */
    DIGEST = TagType:ENUM_REP | 5,     /** Digest. */
    PADDING = TagType:ENUM_REP | 6,    /** PaddingMode. */
    CALLER_NONCE = TagType:BOOL | 7,   /** Allow caller to specify nonce or IV. */
    MIN_MAC_LENGTH = TagType:UINT | 8, /* Minimum length of MAC or AEAD authentication tag in
                                        * bits. */
    KDF = TagType:ENUM_REP | 9,        /** KeyDerivationFunction. */
    EC_CURVE = TagType:ENUM | 10,      /** EcCurve. */

    /** Algorithm-specific. */
    RSA_PUBLIC_EXPONENT = TagType:ULONG | 200,
    ECIES_SINGLE_HASH_MODE = TagType:BOOL | 201, /* Whether the ephemeral public key is fed into the
                                                  * KDF. */
    INCLUDE_UNIQUE_ID = TagType:BOOL | 202,      /* If true, attestation certificates for this key
                                                  * will contain an application-scoped and
                                                  * time-bounded device-unique ID.*/

    /** Other hardware-enforced. */
    BLOB_USAGE_REQUIREMENTS = TagType:ENUM | 301, /** KeyBlobUsageRequirements. */
    BOOTLOADER_ONLY = TagType:BOOL | 302,         /** Usable only by bootloader. */

    /**
     * Tags that should be semantically enforced by hardware if possible and will otherwise be
     * enforced by software (keystore).
     */

    /** Key validity period */
    ACTIVE_DATETIME = TagType:DATE | 400,             /** Start of validity. */
    ORIGINATION_EXPIRE_DATETIME = TagType:DATE | 401, /* Date when new "messages" should no longer
                                                       * be created. */
    USAGE_EXPIRE_DATETIME = TagType:DATE | 402,       /* Date when existing "messages" should no
                                                       * longer be trusted. */
    MIN_SECONDS_BETWEEN_OPS = TagType:UINT | 403,     /* Minimum elapsed time between
                                                       * cryptographic operations with the key. */
    MAX_USES_PER_BOOT = TagType:UINT | 404,           /* Number of times the key can be used per
                                                       * boot. */

    /** User authentication */
    ALL_USERS = TagType:BOOL | 500,           /** Reserved for future use -- ignore. */
    USER_ID = TagType:UINT | 501,             /** Reserved for future use -- ignore. */
    USER_SECURE_ID = TagType:ULONG_REP | 502, /* Secure ID of authorized user or authenticator(s).
                                               * Disallowed if ALL_USERS or NO_AUTH_REQUIRED is
                                               * present. */
    NO_AUTH_REQUIRED = TagType:BOOL | 503,    /** If key is usable without authentication. */
    USER_AUTH_TYPE = TagType:ENUM | 504,      /* Bitmask of authenticator types allowed when
                                               * USER_SECURE_ID contains a secure user ID, rather
                                               * than a secure authenticator ID.  Defined in
                                               * HardwareAuthenticatorType. */
    AUTH_TIMEOUT = TagType:UINT | 505,        /* Required freshness of user authentication for
                                               * private/secret key operations, in seconds.  Public
                                               * key operations require no authentication.  If
                                               * absent, authentication is required for every use.
                                               * Authentication state is lost when the device is
                                               * powered off. */
    ALLOW_WHILE_ON_BODY = TagType:BOOL | 506, /* Allow key to be used after authentication timeout
                                               * if device is still on-body (requires secure on-body
                                               * sensor. */

    /** Application access control */
    ALL_APPLICATIONS = TagType:BOOL | 600, /* Specified to indicate key is usable by all
                                            * applications. */
    APPLICATION_ID = TagType:BYTES | 601,  /** Byte string identifying the authorized application. */
    EXPORTABLE = TagType:BOOL | 602,       /* If true, private/secret key can be exported, but only
                                            * if all access control requirements for use are
                                            * met. (keymaster2) */

    /**
     * Semantically unenforceable tags, either because they have no specific meaning or because
     * they're informational only.
     */
    APPLICATION_DATA = TagType:BYTES | 700,      /** Data provided by authorized application. */
    CREATION_DATETIME = TagType:DATE | 701,      /** Key creation time */
    ORIGIN = TagType:ENUM | 702,                 /** keymaster_key_origin_t. */
    ROLLBACK_RESISTANT = TagType:BOOL | 703,     /** Whether key is rollback-resistant. */
    ROOT_OF_TRUST = TagType:BYTES | 704,         /** Root of trust ID. */
    OS_VERSION = TagType:UINT | 705,             /** Version of system (keymaster2) */
    OS_PATCHLEVEL = TagType:UINT | 706,          /** Patch level of system (keymaster2) */
    UNIQUE_ID = TagType:BYTES | 707,             /** Used to provide unique ID in attestation */
    ATTESTATION_CHALLENGE = TagType:BYTES | 708, /** Used to provide challenge in attestation */
    ATTESTATION_APPLICATION_ID = TagType:BYTES | 709, /* Used to identify the set of possible
                                                       * applications of which one has initiated a
                                                       * key attestation */
    ATTESTATION_ID_BRAND = TagType:BYTES | 710,  /* Used to provide the device's brand name to be
                                                    included in attestation */
    ATTESTATION_ID_DEVICE = TagType:BYTES | 711, /* Used to provide the device's device name to be
                                                    included in attestation */
    ATTESTATION_ID_PRODUCT = TagType:BYTES | 712, /* Used to provide the device's product name to be
                                                     included in attestation */
    ATTESTATION_ID_SERIAL = TagType:BYTES | 713, /* Used to provide the device's serial number to be
                                                    included in attestation */
    ATTESTATION_ID_IMEI = TagType:BYTES | 714,   /* Used to provide the device's IMEI to be included
                                                    in attestation */
    ATTESTATION_ID_MEID = TagType:BYTES | 715,   /* Used to provide the device's MEID to be included
                                                    in attestation */
    ATTESTATION_ID_MANUFACTURER = TagType:BYTES | 716, /* Used to provide the device's manufacturer
                                                          name to be included in attestation */
    ATTESTATION_ID_MODEL = TagType:BYTES | 717,  /* Used to provide the device's model name to be
                                                    included in attestation */

    /** Tags used only to provide data to or receive data from operations */
    ASSOCIATED_DATA = TagType:BYTES | 1000, /** Used to provide associated data for AEAD modes. */
    NONCE = TagType:BYTES | 1001,           /** Nonce or Initialization Vector */
    AUTH_TOKEN = TagType:BYTES | 1002,      /* Authentication token that proves secure user
                                             * authentication has been performed.  Structure defined
                                             * in hw_auth_token_t in hw_auth_token.h. */
    MAC_LENGTH = TagType:UINT | 1003,       /** MAC or AEAD authentication tag length in bits. */

    RESET_SINCE_ID_ROTATION = TagType:BOOL | 1004, /* Whether the device has beeen factory reset
                                                    * since the last unique ID rotation.  Used for
                                                    * key attestation. */
};

enum Algorithm : uint32_t {
    /** Asymmetric algorithms. */
    RSA = 1,
    // DSA = 2, -- Removed, do not re-use value 2.
    EC = 3,

    /** Block ciphers algorithms */
    AES = 32,

    /** MAC algorithms */
    HMAC = 128,
};

/**
 * Symmetric block cipher modes provided by keymaster implementations.
 */
enum BlockMode : uint32_t {
    /**
     * Unauthenticated modes, usable only for encryption/decryption and not generally recommended
     * except for compatibility with existing other protocols. */
    ECB = 1,
    CBC = 2,
    CTR = 3,

    /**
     * Authenticated modes, usable for encryption/decryption and signing/verification.  Recommended
     * over unauthenticated modes for all purposes. */
    GCM = 32,
};

/**
 * Padding modes that may be applied to plaintext for encryption operations.  This list includes
 * padding modes for both symmetric and asymmetric algorithms.  Note that implementations should not
 * provide all possible combinations of algorithm and padding, only the
 * cryptographically-appropriate pairs.
 */
enum PaddingMode : uint32_t {
    NONE = 1, /** deprecated */
    RSA_OAEP = 2,
    RSA_PSS = 3,
    RSA_PKCS1_1_5_ENCRYPT = 4,
    RSA_PKCS1_1_5_SIGN = 5,
    PKCS7 = 64,
};

/**
 * Digests provided by keymaster implementations.
 */
enum Digest : uint32_t {
    NONE = 0,
    MD5 = 1, /* Optional, may not be implemented in hardware, will be handled in software if
              * needed. */
    SHA1 = 2,
    SHA_2_224 = 3,
    SHA_2_256 = 4,
    SHA_2_384 = 5,
    SHA_2_512 = 6,
};

/**
 * Supported EC curves, used in ECDSA
 */
enum EcCurve : uint32_t {
    P_224 = 0,
    P_256 = 1,
    P_384 = 2,
    P_521 = 3,
};

/**
 * The origin of a key (or pair), i.e. where it was generated.  Note that ORIGIN can be found in
 * either the hardware-enforced or software-enforced list for a key, indicating whether the key is
 * hardware or software-based.  Specifically, a key with GENERATED in the hardware-enforced list is
 * guaranteed never to have existed outide the secure hardware.
 */
enum KeyOrigin : uint32_t {
    GENERATED = 0, /** Generated in keymaster.  Should not exist outside the TEE. */
    DERIVED = 1,   /** Derived inside keymaster.  Likely exists off-device. */
    IMPORTED = 2,  /** Imported into keymaster.  Existed as cleartext in Android. */
    UNKNOWN = 3,   /* Keymaster did not record origin.  This value can only be seen on keys in a
                    * keymaster0 implementation.  The keymaster0 adapter uses this value to document
                    * the fact that it is unkown whether the key was generated inside or imported
                    * into keymaster. */
};

/**
 * Usability requirements of key blobs.  This defines what system functionality must be available
 * for the key to function.  For example, key "blobs" which are actually handles referencing
 * encrypted key material stored in the file system cannot be used until the file system is
 * available, and should have BLOB_REQUIRES_FILE_SYSTEM.  Other requirements entries will be added
 * as needed for implementations.
 */
enum KeyBlobUsageRequirements : uint32_t {
    STANDALONE = 0,
    REQUIRES_FILE_SYSTEM = 1,
};

/**
 * Possible purposes of a key (or pair).
 */
enum KeyPurpose : uint32_t {
    ENCRYPT = 0,    /* Usable with RSA, EC and AES keys. */
    DECRYPT = 1,    /* Usable with RSA, EC and AES keys. */
    SIGN = 2,       /* Usable with RSA, EC and HMAC keys. */
    VERIFY = 3,     /* Usable with RSA, EC and HMAC keys. */
    DERIVE_KEY = 4, /* Usable with EC keys. */
    WRAP_KEY = 5,   /* Usable with wrapping keys. */
};

/**
 * Keymaster error codes.
 */
enum ErrorCode : uint32_t {
    OK = 0,
    ROOT_OF_TRUST_ALREADY_SET = -1,
    UNSUPPORTED_PURPOSE = -2,
    INCOMPATIBLE_PURPOSE = -3,
    UNSUPPORTED_ALGORITHM = -4,
    INCOMPATIBLE_ALGORITHM = -5,
    UNSUPPORTED_KEY_SIZE = -6,
    UNSUPPORTED_BLOCK_MODE = -7,
    INCOMPATIBLE_BLOCK_MODE = -8,
    UNSUPPORTED_MAC_LENGTH = -9,
    UNSUPPORTED_PADDING_MODE = -10,
    INCOMPATIBLE_PADDING_MODE = -11,
    UNSUPPORTED_DIGEST = -12,
    INCOMPATIBLE_DIGEST = -13,
    INVALID_EXPIRATION_TIME = -14,
    INVALID_USER_ID = -15,
    INVALID_AUTHORIZATION_TIMEOUT = -16,
    UNSUPPORTED_KEY_FORMAT = -17,
    INCOMPATIBLE_KEY_FORMAT = -18,
    UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM = -19,   /** For PKCS8 & PKCS12 */
    UNSUPPORTED_KEY_VERIFICATION_ALGORITHM = -20, /** For PKCS8 & PKCS12 */
    INVALID_INPUT_LENGTH = -21,
    KEY_EXPORT_OPTIONS_INVALID = -22,
    DELEGATION_NOT_ALLOWED = -23,
    KEY_NOT_YET_VALID = -24,
    KEY_EXPIRED = -25,
    KEY_USER_NOT_AUTHENTICATED = -26,
    OUTPUT_PARAMETER_NULL = -27,
    INVALID_OPERATION_HANDLE = -28,
    INSUFFICIENT_BUFFER_SPACE = -29,
    VERIFICATION_FAILED = -30,
    TOO_MANY_OPERATIONS = -31,
    UNEXPECTED_NULL_POINTER = -32,
    INVALID_KEY_BLOB = -33,
    IMPORTED_KEY_NOT_ENCRYPTED = -34,
    IMPORTED_KEY_DECRYPTION_FAILED = -35,
    IMPORTED_KEY_NOT_SIGNED = -36,
    IMPORTED_KEY_VERIFICATION_FAILED = -37,
    INVALID_ARGUMENT = -38,
    UNSUPPORTED_TAG = -39,
    INVALID_TAG = -40,
    MEMORY_ALLOCATION_FAILED = -41,
    IMPORT_PARAMETER_MISMATCH = -44,
    SECURE_HW_ACCESS_DENIED = -45,
    OPERATION_CANCELLED = -46,
    CONCURRENT_ACCESS_CONFLICT = -47,
    SECURE_HW_BUSY = -48,
    SECURE_HW_COMMUNICATION_FAILED = -49,
    UNSUPPORTED_EC_FIELD = -50,
    MISSING_NONCE = -51,
    INVALID_NONCE = -52,
    MISSING_MAC_LENGTH = -53,
    KEY_RATE_LIMIT_EXCEEDED = -54,
    CALLER_NONCE_PROHIBITED = -55,
    KEY_MAX_OPS_EXCEEDED = -56,
    INVALID_MAC_LENGTH = -57,
    MISSING_MIN_MAC_LENGTH = -58,
    UNSUPPORTED_MIN_MAC_LENGTH = -59,
    UNSUPPORTED_KDF = -60,
    UNSUPPORTED_EC_CURVE = -61,
    KEY_REQUIRES_UPGRADE = -62,
    ATTESTATION_CHALLENGE_MISSING = -63,
    KEYMASTER_NOT_CONFIGURED = -64,
    ATTESTATION_APPLICATION_ID_MISSING = -65,
    CANNOT_ATTEST_IDS = -66,

    UNIMPLEMENTED = -100,
    VERSION_MISMATCH = -101,

    UNKNOWN_ERROR = -1000,
};

/**
 * Key derivation functions, mostly used in ECIES.
 */
enum KeyDerivationFunction : uint32_t {
    /** Do not apply a key derivation function; use the raw agreed key */
    NONE = 0,
    /** HKDF defined in RFC 5869 with SHA256 */
    RFC5869_SHA256 = 1,
    /** KDF1 defined in ISO 18033-2 with SHA1 */
    ISO18033_2_KDF1_SHA1 = 2,
    /** KDF1 defined in ISO 18033-2 with SHA256 */
    ISO18033_2_KDF1_SHA256 = 3,
    /** KDF2 defined in ISO 18033-2 with SHA1 */
    ISO18033_2_KDF2_SHA1 = 4,
    /** KDF2 defined in ISO 18033-2 with SHA256 */
    ISO18033_2_KDF2_SHA256 = 5,
};

/**
 * Hardware authentication type, used by HardwareAuthTokens to specify the mechanism used to
 * authentiate the user, and in KeyCharacteristics to specify the allowable mechanisms for
 * authenticating to activate a key.
 */
enum HardwareAuthenticatorType : uint32_t {
    NONE = 0,
    PASSWORD = 1 << 0,
    FINGERPRINT = 1 << 1,
    // Additional entries must be powers of 2.
    ANY = 0xFFFFFFFF,
};

struct KeyParameter {
    /**
     * Discriminates the uinon/blob field used.  The blob cannot be coincided with the union, but
     * only one of "f" and "blob" is ever used at a time. */
    Tag tag;
    union IntegerParams {
        /** Enum types */
        Algorithm algorithm;
        BlockMode blockMode;
        PaddingMode paddingMode;
        Digest digest;
        EcCurve ecCurve;
        KeyOrigin origin;
        KeyBlobUsageRequirements keyBlobUsageRequirements;
        KeyPurpose purpose;
        KeyDerivationFunction keyDerivationFunction;
        HardwareAuthenticatorType hardwareAuthenticatorType;

        /** Other types */
        bool boolValue;  // Always true, if a boolean tag is present.
        uint32_t integer;
        uint64_t longInteger;
        uint64_t dateTime;
    };
    IntegerParams f;  // Hidl does not support anonymous unions, so we have to name it.
    vec<uint8_t> blob;
};

struct KeyCharacteristics {
    vec<KeyParameter> softwareEnforced;
    vec<KeyParameter> teeEnforced;
};

/**
 * Data used to prove successful authentication.
 */
struct HardwareAuthToken {
    uint64_t challenge;
    uint64_t userId;             // Secure User ID, not Android user ID.
    uint64_t authenticatorId;    // Secure authenticator ID.
    uint32_t authenticatorType;  // HardwareAuthenticatorType, in network order.
    uint64_t timestamp;          // In network order.
    uint8_t[32] hmac;            // HMAC is computed over 0 || challenge || user_id ||
                                 // authenticator_id || authenticator_type || timestamp, with a
                                 // prefixed 0 byte (which was a version field in Keymaster1 and
                                 // Keymaster2) and the fields packed (no padding; so you probably
                                 // can't just compute over the bytes of the struct).
};

enum SecurityLevel : uint32_t {
    SOFTWARE = 0,
    TRUSTED_ENVIRONMENT = 1,
};

/**
 * Formats for key import and export.
 */
enum KeyFormat : uint32_t {
    X509 = 0,  /** for public key export */
    PKCS8 = 1, /** for asymmetric key pair import */
    RAW = 3,   /* for symmetric key import and export*/
};

typedef uint64_t OperationHandle;
