/* SPDX-License-Identifier: BSD-2-Clause */
/*******************************************************************************
 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
 * All rights reserved.
 ******************************************************************************/
#ifndef IFAPI_POLICY_TYPES_H
#define IFAPI_POLICY_TYPES_H

#include <stdint.h> // for uint8_t

#include "fapi_types.h"      // for UINT8_ARY
#include "tss2_common.h"     // for UINT32, INT32, UINT16
#include "tss2_tpm2_types.h" // for TPM2B_DIGEST, TPM2B_NAME, TPM2B_NONCE

struct TPML_POLICYELEMENTS;

typedef UINT32 TPMI_POLICYTYPE;
#define POLICYELEMENTS          0
#define POLICYOR                1  /**< None */
#define POLICYSIGNED            2  /**< None */
#define POLICYSECRET            3  /**< None */
#define POLICYPCR               4  /**< None */
#define POLICYLOCALITY          5  /**< None */
#define POLICYNV                6  /**< None */
#define POLICYCOUNTERTIMER      7  /**< None */
#define POLICYCOMMANDCODE       8  /**< None */
#define POLICYPHYSICALPRESENCE  9  /**< None */
#define POLICYCPHASH            10 /**< None */
#define POLICYNAMEHASH          11 /**< None */
#define POLICYDUPLICATIONSELECT 12 /**< None */
#define POLICYAUTHORIZE         13 /**< None */
#define POLICYAUTHVALUE         14 /**< None */
#define POLICYPASSWORD          15 /**< None */
#define POLICYNVWRITTEN         16 /**< None */
#define POLICYTEMPLATE          17 /**< None */
#define POLICYAUTHORIZENV       18 /**< None */
#define POLICYACTION            19 /**< None */

/** Policy type TPMS_POLICYSIGNED
 */
typedef struct {
    TPM2B_NONCE     nonceTPM;   /**< This is a value returned by TPM2_StartAuthSession and thus n */
    TPM2B_DIGEST    cpHashA;    /**< This value will be automatically generated by the FAPI. */
    TPM2B_NONCE     policyRef;  /**< Default is zero-length */
    INT32           expiration; /**< This value will be -1 by the FAPI */
    TPMT_SIGNATURE  auth;       /**< This value is generated from at runtime via a callback. */
    TPM2B_NAME      publicKey;  /**< This will be automatically generated from keyPath, keyPublic */
    char           *publicKeyHint; /**< A human readable hint to denote which public key to use. */
    char           *keyPath;       /**< A reference to a key inside the FAPI keystore */
    TPMT_PUBLIC     keyPublic;     /**< None */
    char           *keyPEM; /**< <p>The TPM2B_NAME is constructed with a TPMT_PUBLIC from this */
    TPMI_ALG_HASH   keyPEMhashAlg; /**< (optional) Default = SHA256 */
    TPMT_RSA_SCHEME rsaScheme;     /**< (optional) Default = TPM2_ALG_RSAPSS */
    TPMT_SIGNATURE  signature_tpm;
} TPMS_POLICYSIGNED;

/** Policy type TPMS_POLICYSECRET
 */
typedef struct {
    TPM2B_NONCE  nonceTPM;   /**< None */
    TPM2B_DIGEST cpHashA;    /**< None */
    TPM2B_NONCE  policyRef;  /**< Default is zero length */
    INT32        expiration; /**< None */
    char        *objectPath; /**< Path of the object */
    TPM2B_NAME   objectName; /**< Public name of the object */
} TPMS_POLICYSECRET;

/** Policy type TPMS_POLICYLOCALITY
 */
typedef struct {
    TPMA_LOCALITY locality; /**< None */
} TPMS_POLICYLOCALITY;

/** Policy type TPMS_POLICYNV
 */
typedef struct {
    char            *nvPath;     /**< None */
    TPMI_RH_NV_INDEX nvIndex;    /**< None */
    TPMS_NV_PUBLIC   nvPublic;   /**< None */
    TPMI_RH_NV_AUTH  authHandle; /**< This is determined by FAPI at runtime. */
    TPM2B_OPERAND    operandB;   /**< None */
    UINT16           offset;     /**< Default value is 0 */
    TPM2_EO          operation;  /**< Default value is EQUAL */
} TPMS_POLICYNV;

/** Policy type TPMS_POLICYCOUNTERTIMER
 */
typedef struct {
    TPM2B_OPERAND operandB;  /**< None */
    UINT16        offset;    /**< Default is 0 */
    TPM2_EO       operation; /**< None */
} TPMS_POLICYCOUNTERTIMER;

/** Policy type TPMS_POLICYCOMMANDCODE
 */
typedef struct {
    TPM2_CC code; /**< None */
} TPMS_POLICYCOMMANDCODE;

/** Policy type TPMS_POLICYPHYSICALPRESENCE
 */
typedef struct {
} TPMS_POLICYPHYSICALPRESENCE;

/** Policy type TPMS_POLICYCPHASH
 */
typedef struct {
    TPM2B_DIGEST cpHash; /**< None */
} TPMS_POLICYCPHASH;

/** Policy type TPMS_POLICYNAMEHASH
 */
typedef struct {
    UINT32       count;          /**< Computed during instantiation */
    UINT32       i;              /**< Temporary index for policy calculation */
    TPM2B_NAME   objectNames[3]; /**< computed during instantiation (if not initialized) */
    char        *namePaths[3];   /**< Paths of objects used for retrieving the names */
    TPM2B_DIGEST nameHash;       /**< computed during policy calculation */
} TPMS_POLICYNAMEHASH;

/** Policy type TPMS_POLICYDUPLICATIONSELECT
 */
typedef struct {
    TPM2B_NAME  objectName;      /**< Will not be used (see includeObject) */
    TPM2B_NAME  newParentName;   /**< Automatically calculated */
    TPMI_YES_NO includeObject;   /**< Always NO */
    char       *newParentPath;   /**< None */
    TPMT_PUBLIC newParentPublic; /**< None */
} TPMS_POLICYDUPLICATIONSELECT;

/** Policy type TPMS_POLICYAUTHORIZATION
 */
typedef struct {
    char           *type;      /**< tpm */
    TPMT_PUBLIC     key;       /**< Selector of the algorithm used for the signature and the pub */
    TPM2B_NONCE     policyRef; /**< None */
    TPMT_SIGNATURE  signature; /**< None */
    TPMI_ALG_HASH   hashAlg;
    UINT8_ARY       pemSignature;
    char           *keyPEM;
    TPMT_RSA_SCHEME rsaScheme;
} TPMS_POLICYAUTHORIZATION;

typedef struct policy_object_node POLICY_OBJECT;

/** Policy type TPMS_POLICYAUTHORIZE
 */
typedef struct {
    TPM2B_DIGEST     approvedPolicy; /**< None */
    TPM2B_NONCE      policyRef;      /**< None */
    TPM2B_NAME       keyName; /**< Not exposed in JSON, but generated from keyPath, keyPublic o */
    TPMT_TK_VERIFIED checkTicket; /**< None */
    char            *keyPath;     /**< A reference to a key inside the FAPI keystore */
    TPMT_PUBLIC      keyPublic;   /**< None */
    char            *keyPEM; /**< <p> everyone in favour<br /> The TPM2B_NAME is constructed w */
    TPMI_ALG_HASH    keyPEMhashAlg; /**< (optional) Default = SHA256 */
    TPMT_RSA_SCHEME  rsaScheme;     /**< (optional) Default = TPM2_ALG_RSAPSS */
    TPMT_SIGNATURE   signature;
} TPMS_POLICYAUTHORIZE;

/** Policy type TPMS_POLICYAUTHVALUE
 */
typedef struct {
} TPMS_POLICYAUTHVALUE;

/** Policy type TPMS_POLICYPASSWORD
 */
typedef struct {
} TPMS_POLICYPASSWORD;

/** Policy type TPMS_POLICYNVWRITTEN
 */
typedef struct {
    TPMI_YES_NO writtenSet; /**< Default is yes */
} TPMS_POLICYNVWRITTEN;

/** Policy type TPMS_POLICYTEMPLATE
 */
typedef struct {
    TPM2B_DIGEST templateHash;   /**< None */
    TPM2B_PUBLIC templatePublic; /**< None */
} TPMS_POLICYTEMPLATE;

/** Policy type TPMS_POLICYAUTHORIZENV
 */
typedef struct {
    char          *nvPath;    /**< None */
    TPMS_NV_PUBLIC nvPublic;  /**< None */
    TPM2B_DIGEST   policy;    /**< Policy Digest */
    TPMT_HA        nv_policy; /**< Policy stored in NV ram */
    uint8_t       *policy_buffer;
} TPMS_POLICYAUTHORIZENV;

/** Policy type TPMS_POLICYACTION
 */
typedef struct {
    char *action; /**< The FAPI will return a string representation of the JSON sub */
} TPMS_POLICYACTION;

/** Policy type TPMS_POLICYPCR
 */
typedef struct {
    struct TPML_PCRVALUES *pcrs;               /**< None */
    TPMS_PCR_SELECT        currentPCRs;        /**< The hashAlg are inferred from */
    TPML_PCR_SELECTION     currentPCRandBanks; /**< Complete selection with banks  */
} TPMS_POLICYPCR;

/** Policy type TPML_POLICYAUTHORIZATIONS
 */
typedef struct TPML_POLICYAUTHORIZATIONS {
    UINT32                   count;            /**< None */
    TPMS_POLICYAUTHORIZATION authorizations[]; /**< Array of policy elements */
} TPML_POLICYAUTHORIZATIONS;

typedef struct TPML_POLICYELEMENTS TPML_POLICYELEMENTS;

/** Policy type TPMS_POLICYBRANCH
 */
typedef struct {
    char                       *name;        /**< None */
    char                       *description; /**< None */
    TPML_DIGEST_VALUES          policyDigests;
    struct TPML_POLICYELEMENTS *policy; /**< Array of policy elements */
} TPMS_POLICYBRANCH;

/** Policy type TPML_POLICYBRANCHES
 */
typedef struct TPML_POLICYBRANCHES {
    UINT32            count;            /**< None */
    TPMS_POLICYBRANCH authorizations[]; /**< Array of policy elements */
} TPML_POLICYBRANCHES;

/** Policy type TPMS_POLICYOR
 */
typedef struct {
    struct TPML_POLICYBRANCHES
        *branches; /**< An (infinite) array of policy elements. This does not contai */
} TPMS_POLICYOR;

/** [u'']
 */
typedef union {
    TPMS_POLICYOR                PolicyOr;                /**< None */
    TPMS_POLICYSIGNED            PolicySigned;            /**< None */
    TPMS_POLICYSECRET            PolicySecret;            /**< None */
    TPMS_POLICYPCR               PolicyPCR;               /**< None */
    TPMS_POLICYLOCALITY          PolicyLocality;          /**< None */
    TPMS_POLICYNV                PolicyNV;                /**< None */
    TPMS_POLICYCOUNTERTIMER      PolicyCounterTimer;      /**< None */
    TPMS_POLICYCOMMANDCODE       PolicyCommandCode;       /**< None */
    TPMS_POLICYPHYSICALPRESENCE  PolicyPhysicalPresence;  /**< None */
    TPMS_POLICYCPHASH            PolicyCpHash;            /**< None */
    TPMS_POLICYNAMEHASH          PolicyNameHash;          /**< None */
    TPMS_POLICYDUPLICATIONSELECT PolicyDuplicationSelect; /**< None */
    TPMS_POLICYAUTHORIZE         PolicyAuthorize;         /**< None */
    TPMS_POLICYAUTHVALUE         PolicyAuthValue;         /**< None */
    TPMS_POLICYPASSWORD          PolicyPassword;          /**< None */
    TPMS_POLICYNVWRITTEN         PolicyNvWritten;         /**< None */
    TPMS_POLICYTEMPLATE          PolicyTemplate;          /**< None */
    TPMS_POLICYAUTHORIZENV       PolicyAuthorizeNv;       /**< None */
    TPMS_POLICYACTION            PolicyAction;            /**< None */
} TPMU_POLICYELEMENT;

/** Policy type TPMT_POLICYELEMENT
 */
typedef struct {
    TPMI_POLICYTYPE    type;          /**< None */
    TPML_DIGEST_VALUES policyDigests; /**< None */
    TPMU_POLICYELEMENT element;       /**< The union does is not embedded inside a field. */
} TPMT_POLICYELEMENT;

/** Policy type TPML_POLICYELEMENTS
 */
struct TPML_POLICYELEMENTS {
    UINT32             count;      /**< None */
    TPMT_POLICYELEMENT elements[]; /**< Array of policy elements */
};

/** Policy type TPMS_POLICY
 */
typedef struct TPMS_POLICY {
    char                             *description;          /**< O */
    TPML_DIGEST_VALUES                policyDigests;        /**< O */
    struct TPML_POLICYAUTHORIZATIONS *policyAuthorizations; /**< O */
    struct TPML_POLICYELEMENTS       *policy;               /**< X */
} TPMS_POLICY;

#endif /* IFAPI_POLICY_TYPES_H */
