/**
 * Copyright (c) 2020-2023 Qualcomm Technologies, Inc.
 * All Rights Reserved.
 * Confidential and Proprietary - Qualcomm Technologies, Inc.
 */

/** @file IHWKeyFactory.idl */

/** @cond */

struct IHWKey_operationPolicy {
  uint32 operations; /**< Mask of operations allowed for key */
  uint32 algorithm;  /**< Algorithm key can be used for */
};

struct IHWKey_policy {
  IHWKey_operationPolicy opPolicy; /**< Parameters for operational key */
  uint32 kdfDepth;                 /**< Number of KDF iterations to use when deriving child key */
  uint32 permissions;              /**< Mask of permissions for key */
  uint32 keyType;                  /**< Type of key */
  uint32 destination;              /**< Destination hardware instance */
};

struct IHWKey_bindings {
  uint32 bindings;   /**< Device and software state bindings for key */
  uint32 contextLen; /**< The software context length */
  uint8[64] context; /**< Software context to be mixed in for key derivation */
};

/** @endcond */

/** @cond */
interface IHWKey {
/** @endcond */

  /**
    @addtogroup IHWKey
    @{
   */

  /** @cond */

  /**
    Key permissions associated with the wrapped key. The
    permissions field of IHWKey_policy should be a
    mask created by ORing all selected permissions.

    WARNING: Setting reserved permission bits may cause errors
    and backward compatibility issues and should be avoided
   */
  const uint32 PERMISSION_WRAP_KEY_EXPORT = 1; /**< Allow key to be wrapped by a wrapping key and exported to TA */
  const uint32 PERMISSION_RESERVE_MASTER_SLOT_1 = 2;       /**< Allow use of persistent slot 1 */
  const uint32 PERMISSION_RESERVE_MASTER_SLOT_2 = 4;       /**< Allow use of persistent slot 2 */
  const uint32 PERMISSION_RESERVED3 = 8;       /**< Reserved permission bit */
  const uint32 PERMISSION_RESERVED4 = 16;      /**< Reserved permission bit */
  const uint32 PERMISSION_RESERVED5 = 32;      /**< Reserved permission bit */
  const uint32 PERMISSION_RESERVED6 = 64;      /**< Reserved permission bit */
  const uint32 PERMISSION_RESERVED7 = 128;      /**< Reserved permission bit */
  const uint32 PERMISSION_RESERVED8 = 256;      /**< Reserved permission bit */
  const uint32 PERMISSION_RESERVED9 = 512;      /**< Reserved permission bit */
  const uint32 PERMISSION_UNWRAP_MASTER_SLOT_1 = 1024;      /**< Allow unwrapping to persistent slot 1 */
  const uint32 PERMISSION_UNWRAP_MASTER_SLOT_2 = 2048;      /**< Allow unwrapping to persistent slot 2 */
  const uint32 PERMISSION_RESERVED12 = 4096;      /**< Reserved permission bit */
  const uint32 PERMISSION_KEY_IS_A_SW_KEY = 8192;      /**< Allow the security level of a key to be of type SW_KEY */  

  /**
    Key types supported for a key. The keyType field of
    IHWKey_policy should be one of these values.
   */
  const uint32 KEY_TYPE_DERIVATION = 0;  /**< Key which is to be used to for key derivation */
  const uint32 KEY_TYPE_WRAPPING = 1;    /**< Key which is to be used to for key wrapping */
  const uint32 KEY_TYPE_OPERATIONAL = 2; /**< Key which is to be used to for crypto operations */
  const uint32 KEY_TYPE_DERIVATION_HKDF = 3; /**< Key which is to be used to for key derivation */

  /**
    Algorithms supported for an operational key. The algorithm field
    of IHWKey_operationPolicy should be one of these values if the key
    represents an operational key.
    WARNING: Using reserved algorithm values may cause errors and
    backward compatibility issues and should be avoided
   */
  const uint32 ALGORITHM_AES128_ECB = 0;
  const uint32 ALGORITHM_AES256_ECB = 1;
  const uint32 ALGORITHM_DES_ECB = 2;
  const uint32 ALGORITHM_TDES_ECB = 3;
  const uint32 ALGORITHM_AES128_CBC = 4;
  const uint32 ALGORITHM_AES256_CBC = 5;
  const uint32 ALGORITHM_DES_CBC = 6;
  const uint32 ALGORITHM_TDES_CBC = 7;
  const uint32 ALGORITHM_RESERVED1 = 8;
  const uint32 ALGORITHM_AES128_CCM = 9;
  const uint32 ALGORITHM_RESERVED2 = 10;
  const uint32 ALGORITHM_AES256_CCM = 11;
  const uint32 ALGORITHM_RESERVED3 = 12;
  const uint32 ALGORITHM_AES128_CTR = 13;
  const uint32 ALGORITHM_AES256_CTR = 14;
  const uint32 ALGORITHM_AES128_XTS = 15;
  const uint32 ALGORITHM_AES256_XTS = 16;
  const uint32 ALGORITHM_SHA1_HMAC = 17;
  const uint32 ALGORITHM_SHA256_HMAC = 18;
  const uint32 ALGORITHM_AES128_CMAC = 19;
  const uint32 ALGORITHM_AES256_CMAC = 20;
  const uint32 ALGORITHM_RESERVED6 = 21;
  const uint32 ALGORITHM_RESERVED7 = 22;
  const uint32 ALGORITHM_AES128_GCM = 23;
  const uint32 ALGORITHM_AES256_GCM = 24;
  const uint32 ALGORITHM_KASUMI = 25;
  const uint32 ALGORITHM_SNOW3G = 26;
  const uint32 ALGORITHM_ZUC = 27;
  const uint32 ALGORITHM_PRINCE = 28;
  const uint32 ALGORITHM_SIPHASH = 29;

  /**
    Key bindings for a wrapped key. The bindings field of IHWKey_bindings
    should be a mask created by ORing all selected bindings. A key derivation operation
    using a key will incorporate these bindings as part of the context, so if these
    bindings change, a different key will be derived, preserving the confidentiality
    of any keys previously derived.
   */
  const uint32 BINDING_KEY_POLICY_VERSION = 1; /**< Bind key to current key policy version */
  const uint32 BINDING_SECURITY_STATE = 2;     /**< Bind key to current SOC security state (debug enablement state) */
  const uint32 BINDING_CHILD_KEY_POLICY = 4;   /**< Bind key to its policy */
  const uint32 BINDING_TA_OEM_ROT = 8;         /**< Bind key to whether the TA is OEM signed */
  const uint32 BINDING_TA_QCOM_ROT = 16;       /**< Bind key to whether the TA is QCOM signed */
  const uint32 BINDING_PK_HASH = 32;           /**< Bind key to device's public key hash */
  const uint32 BINDING_OEM_ID = 64;            /**< Bind key to OEM ID */
  const uint32 BINDING_BOOT_STAGE = 128;       /**< Bind key to current boot stage */
  const uint32 BINDING_RESERVED1 = 256;        /**< Reserved binding bits */
  const uint32 BINDING_RESERVED2 = 512;        /**< Reserved binding bits */
  const uint32 BINDING_OEM_PRODUCT_SEED = 1024; /**< Bind key to OEM Product Seed */
  const uint32 BINDING_NO_SALT_SW_CONTEXT = 2048;     /**< Custom binding to remove salt and SW context */

  /**
    Operations allowed for an operational key. The operations field of IHWKey_operationPolicy
    for an operational key should be a mask created by ORing all allowed operations.
   */
  const uint32 OPERATION_ENCRYPT_ALLOWED = 1; /**< Key can be used for encryption */
  const uint32 OPERATION_DECRYPT_ALLOWED = 2; /**< Key can be used for decryption */

  /**
    Destination HW instance where key can be used
    WARNING: Using reserved destination values may cause errors
    and backward compatibility issues and should be avoided
   */
  const uint32 DESTINATION_DEFAULT = 0;   /** Key destination defaults to most appropriate for its type */
  const uint32 DESTINATION_RESERVED1 = 1; /** Reserved destination */
  const uint32 DESTINATION_RESERVED2 = 2; /** Reserved destination */

  /** @endcond */

  /**
    Wrap the hardware key using a hardware wrapping key.
    On success, the wrapped key blob will be returned to the client.
    This wrapped blob can be stored on the device and can be converted
    into a key object at any later time.

    @param [in] wrapping_key  Key to be used for wrapping, 
                              whose type will depend on the interface 
                              invoked (i.e. for example IHWKey)
    @param [out] blob         A blob containing the wrapped key. \n
                              WARNING: The size and format of a wrapped key blob
                              may differ between chipsets. To use this API in a
                              chipset agnostic manner, a client should ensure that
                              the size of the output buffer is greater than or equal
                              to the value returned by getBlobSize()

    @return
    Object_OK on success
   */
  method wrap(in interface wrappingKey, out buffer blob);

  /**
    Get the size of a wrapped key blob in bytes. The size and format
    of a wrapped key blob will vary depending on the version of the HW
    used in the chipset. Clients should ensure that buffers passed into
    wrap() are large enough to accomodate the size returned by this method.

    @param [out] size  Size of a wrapped key blob in bytes

    @return
    Object_OK on success
   */
  method getBlobSize(out uint32 size);

  /**
    If the key is present in a persistent slot, this can be used to get the slot ID
    provided the key object has the persistent permissions set correctly.

    @param [out] slotId Persistent slot in which the key is present.

    @return
    Object_OK on success
   */
  method getSlotId(out uint32 slotId);

  /**
    Clear a key present in one of the persistent slots.

    @param [in] slotId Persistent slot in which the key is present.

    @return
    Object_OK on success
   */
  method clearSlotId(in uint32 slotId);

  /** @} */ /* end_addtogroup IHWKey */
};

/** @cond */
interface IHWKeyFactory {
/** @endcond */

  /**
    @addtogroup IHWKeyFactory
    @{
   */

  /** @cond */

  /**
    HW source values to be passed to deriveFromHWSource() as the source parameter.
    WARNING: Using reserved values may cause errors and backward compatibility issues and should be avoided.
    WARNING: Reserved source values map to keys with values retained by QCOM.
   */
  const uint32 HW_SOURCE_RESERVED1 = 1;       /**< Reserved */
  const uint32 HW_SOURCE_RESERVED2 = 2;       /**< Reserved */
  const uint32 HW_SOURCE_CHIP_RANDOM_KEY = 3; /**< Unique key per device, randomly generated during manufacturing */

  error ERROR_MISSING_PRIVILEGE;       /**< Client does not have sufficient privilege for requested operation */
  error ERROR_MISSING_PERMISSION;      /**< Key policy missing permission for requested operation */
  error ERROR_INVALID_WRAPPING_KEY;    /**< Wrapping key parameter is invalid */
  error ERROR_INVALID_DERIVATION_KEY;  /**< Derivation key parameter is invalid */
  error ERROR_INVALID_KEY_TYPE;        /**< Expected different key type than provided */
  error ERROR_INVALID_SOURCE;          /**< Undefined source value */
  error ERROR_INVALID_POLICY;          /**< Policy structure contains invalid values */
  error ERROR_KEY_BLOB_CORRUPTED;      /**< Key blob failed integrity check during unwrap */
  error ERROR_INVALID_WRAP_KEY_SOURCE; /**< Client has attempted to create a wrapping key from an imported key */
  error ERROR_NOT_SUPPORTED;           /**< Feature is not supported on this chipset */

  /** @endcond */

  /**
    Generate a random hardware key.

    @param [in] policy  Key policy for the generated key
    @param [out] key    Output key object, whose type will depend on the interface invoked (i.e. for example IHWKey)

    @return
    Object_OK on success
   */
  method generate(in IHWKey_policy policy, out interface key);

  /**
    Derive a hardware key from a derivation key. \n
    WARNING: Wrapping keys created through this method must not be descendants of keys created by importKey()

    @param [in] policy         Key policy for the derived key
    @param [in] bindings       Software and device state bindings for the key
    @param [in] derivationKey  Key object representing the derivation key
    @param [in] mixingKey      Optional argument. Key object to be mixed to the context during key derivation
    @param [out] key           Output key object, whose type will depend on the interface invoked (i.e. for example IHWKey)

    @return
    Object_OK on success \n
    ERROR_INVALID_WRAP_KEY_SOURCE if policy's keyType is KEY_TYPE_WRAPPING and derivationKey is a descendant of a key created through importKey()
   */
  method derive(in IHWKey_policy policy, in IHWKey_bindings bindings, in IHWKey derivationKey, in IHWKey mixingKey, out interface key);

  /**
    Derive a hardware key from a deterministic HW source.

    @param [in] policy     Key policy for the resulting key
    @param [in] bindings   Software and device state bindings for the key
    @param [in] source     HW source to be used to derive the child key
    @param [in] mixingKey  Optional argument. Key object to be mixed to the context during key derivation
    @param [out] key       Output key object, whose type will depend on the interface invoked (i.e. for example IHWKey)

    @return
    Object_OK on success
   */
  method deriveFromHWSource(in IHWKey_policy policy, in IHWKey_bindings bindings, in uint32 source, in IHWKey mixingKey, out interface key);

  /**
    Import a software key to create an IHWKey object managed by HW key manager. \n
    WARNING: Wrapping keys cannot be created through this method.

    @param [in] policy  Key policy for the created key
    @param [in] swKey   Plaintext software key to be managed by hardware - algorithm in policy determines key size
    @param [out] key    Output key object, whose type will depend on the interface invoked (i.e. for example IHWKey)

    @return
    Object_OK on success \n
    ERROR_INVALID_WRAP_KEY_SOURCE if policy's keyType is KEY_TYPE_WRAPPING
   */
  method importKey(in IHWKey_policy policy, in buffer swKey, out interface key);

  /**
    Create a hardware key from a wrapped key blob.

    @param [in] wrappingKey  Key to be used for unwrapping.
    @param [in] wrappedBlob  Blob containing the wrapped key
    @param [out] key         Output key object, whose type will depend on the interface invoked (i.e. for example IHWKey)

    @return
    Object_OK on success
   */
  method unwrap(in IHWKey wrappingKey, in buffer wrappedBlob, out interface key);

  /** @} */ /* end_addtogroup IHWKeyFactory */
};
