
/*
 * COPYRIGHT (c) International Business Machines Corp. 2001-2017
 *
 * This program is provided under the terms of the Common Public License,
 * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this
 * software constitutes recipient's acceptance of CPL-1.0 terms which can be
 * found in the file LICENSE file or at
 * https://opensource.org/licenses/cpl1.0.php
 */

/*
 * openCryptoki CCA token
 *
 * Author: Kent E. Yoder <yoder1@us.ibm.com>
 *
 */

#ifndef __CCA_STDLL_H__
#define __CCA_STDLL_H__

#include <pthread.h>

#include "pkcs11types.h"
#include "defs.h"
#include "host_defs.h"
#include "csulincl.h"
#include "cca_func.h"
#include "hsm_mk_change.h"
#include "configuration.h"

/* CCA library constants */

#define CCA_PRIVATE_KEY_NAME_SIZE       64
#define CCA_REGENERATION_DATA_SIZE      64
#define CCA_KEY_TOKEN_SIZE              8000
#define CCA_KEY_VALUE_STRUCT_SIZE       8000
#define CCA_MAX_AES_CIPHER_KEY_SIZE     455
#define CCA_RULE_ARRAY_SIZE             256
#define CCA_KEYWORD_SIZE                8
#define CCA_KEY_ID_SIZE                 64
#define CCA_RNG_SIZE                    8
#define CCA_OCV_SIZE                    18
#define CCA_SUCCESS                     0
#define CCA_PKB_E_OFFSET                18
#define CCA_PKB_E_SIZE                  2
#define CCA_PKB_E_SIZE_OFFSET           4
#define CCA_CHAIN_VECTOR_LEN            128
#define CCA_CHAIN_VECTOR_SHA3_LEN       256

/* Elliptic Curve constants */
/* CCA spec: page 94 */
#define CCA_EC_KEY_VALUE_STRUCT_SIZE    8
#define CCA_PKB_EC_TYPE_OFFSET          0
#define CCA_PKB_EC_LEN_OFFSET           2
#define CCA_PKB_EC_PRIV_KEY_LEN_OFFSET  4
#define CCA_PKB_EC_PUBL_KEY_LEN_OFFSET  6
#define CCATOK_EC_MAX_D_LEN             66
#define CCATOK_EC_MAX_Q_LEN             133

/* QSA constants */
#define CCA_QSA_KEY_VALUE_STRUCT_SIZE   8
#define CCA_PKB_QSA_CLEAR_FORMAT_OFFSET 1
#define CCA_PKB_QSA_ALGO_PARAM_OFFSET   2
#define CCA_PKB_QSA_CLEAR_LEN_OFFSET    4
#define CCA_QSA_ALGO_DILITHIUM_ROUND_2  0x01
#define CCA_QSA_ALGO_DILITHIUM_ROUND_3  0x03
#define CCA_QSA_ALGO_ML_DSA_PURE        0x05
#define CCA_QSA_ALGO_ML_KEM             0x06
#define CCA_QSA_ALGO_ML_DSA_PRE_HASH    0x07
#define CCA_QSA_ALGO_DILITHIUM_65       0x0605
#define CCA_QSA_ALGO_DILITHIUM_87       0x0807
#define CCA_QSA_ALGO_ML_DSA_44          0x0404
#define CCA_QSA_ALGO_ML_DSA_65          0x0605
#define CCA_QSA_ALGO_ML_DSA_87          0x0807
#define CCA_QSA_ALGO_ML_KEM_512         0x0512
#define CCA_QSA_ALGO_ML_KEM_768         0x0768
#define CCA_QSA_ALGO_ML_KEM_1024        0x1024
#define CCA_QSA_CLEAR_FORMAT_NO_KEY     0x00
#define CCA_QSA_CLEAR_FORMAT_KAT        0x01
#define CCA_QSA_CLEAR_FORMAT_PUB_ONLY   0x03
#define CCA_MAX_ML_DSA_SIGNATURE_LEN    5000
#define CCA_MAX_DILITHIUM_65_DATA_LEN   6000
#define CCA_MAX_DILITHIUM_87_DATA_LEN   4000
#define CCA_MAX_CEX8_DILITHIUM_65_DATA_LEN   18000
#define CCA_MAX_CEX8_DILITHIUM_87_DATA_LEN   16000
#define CCA_MAX_CEX8_ML_DSA_44_DATA_LEN      18000
#define CCA_MAX_CEX8_ML_DSA_65_DATA_LEN      18000
#define CCA_MAX_CEX8_ML_DSA_87_DATA_LEN      16000

/*
 * ECC private key section (X'20'), Key-usage and translation control flag.
 */
#define CCA_XPRTCPAC                          0x01
#define CCA_ECC_TOKEN_KEYUSAGE_OFFSET         16
#define CCA_VAR_SYM_TOKEN_KEYMGMT1_OFFSET     50
#define CCA_VAR_SYM_XPRT_SYM                  0x8000
#define CCA_VAR_SYM_XPRT_UASYM                0x4000
#define CCA_VAR_SYM_XPRT_AASYM                0x2000
#define CCA_VAR_SYM_XPRT_RAW                  0x1000
#define CCA_VAR_SYM_XPRT_CPACF                0x0800
#define CCA_VAR_SYM_NOEX_DES                  0x0080
#define CCA_VAR_SYM_NOEX_AES                  0x0040
#define CCA_VAR_SYM_NOEX_RSA                  0x0008

/* Key token generated by CSNDPKG */
/* CCA spec: page 460 & 470 & 471 */
#define CCA_PRIVKEY_ID                  0x20
#define CCA_PUBLKEY_ID                  0x21
#define CCA_ECCDERIVEINFO_ID            0x23
#define CCA_SECTION_LEN_OFFSET          2
#define CCA_SECTION_HEADER_LEN          4
#define CCA_EC_HEADER_SIZE              8
#define CCA_PRIV_P_LEN_OFFSET           12
#define CCA_PUBL_P_LEN_OFFSET           10
/* Offset into the EC public key section to length of q */
#define CCA_EC_INTTOK_PUBKEY_Q_LEN_OFFSET 12
/* Offset into the EC public key section to q */
#define CCA_EC_INTTOK_PUBKEY_Q_OFFSET   14
#define CCA_EC_INTTOK_PRIVKEY_KEY_SOURCE_OFFSET   11

#define CCA_EC_INTTOK_PRIVKEY_KEY_SOURCE_RANDOM     0x24

/* CCA Internal Key Token parsing constants */

/* Size of an RSA internal key token header */
#define CCA_RSA_INTTOK_HDR_LENGTH  8
/* Offset into an RSA internal key token of the private key area */
#define CCA_RSA_INTTOK_PRIVKEY_OFFSET  8
/* Offset into an RSA key area of the total length */
#define CCA_RSA_INTTOK_PRIVKEY_LENGTH_OFFSET 2
#define CCA_RSA_INTTOK_PUBKEY_LENGTH_OFFSET 2
/* Offset into an RSA private key (4096 bits, ME format) area of the length of n, the modulus */
#define CCA_RSA_INTTOK_PRIVKEY_ME_N_LENGTH_OFFSET 52
/* Offset into an RSA private key (4096 bits, ME format) area of n, the modulus */
#define CCA_RSA_INTTOK_PRIVKEY_ME_N_OFFSET 122
/* Offset into an RSA private key (4096 bits, CRT format) area of the length of n, the modulus */
#define CCA_RSA_INTTOK_PRIVKEY_CRT_N_LENGTH_OFFSET 62
/* Offset into an RSA private key (4096 bits, CRT format) area of n, the modulus */
#define CCA_RSA_INTTOK_PRIVKEY_CRT_N_OFFSET 134
/* Offset into an RSA public key area of the length of e, the public exponent */
#define CCA_RSA_INTTOK_PUBKEY_E_LENGTH_OFFSET 6
/* Offset into an RSA public key area of the value of e, the public exponent */
#define CCA_RSA_INTTOK_PUBKEY_E_OFFSET  12

/* Offset into an QSA internal key token of the private key area */
#define CCA_QSA_INTTOK_PRIVKEY_OFFSET      8
/* Offset into an QSA private key area of the algorithm id */
#define CCA_QSA_INTTOK_ALGO_ID_OFFSET      9
/* Offset into an QSA private key area of the algorithm parameters */
#define CCA_QSA_INTTOK_ALGO_PARAMS_OFFSET  10
/* Offset into an QSA private key area of the MKVP */
#define CCA_QSA_INTTOK_MKVP_OFFSET         118
/* Offset into an QSA external key token of the public key area */
#define CCA_QSA_EXTTOK_PUBLKEY_OFFSET      8
/* Offset into an QSA public key area of the algorithm id */
#define CCA_QSA_EXTTOK_ALGO_ID_OFFSET      5
/* Offset into an QSA public key area of the algorithm parameters */
#define CCA_QSA_EXTTOK_ALGO_PARAMS_OFFSET  6
/* Offset into an QSA public key area of the rho length */
#define CCA_QSA_EXTTOK_RHO_OFFSET          10
/* Offset into an QSA public key area of the t1 length */
#define CCA_QSA_EXTTOK_T1_OFFSET           12
/* Offset into an QSA public key area of the pk length */
#define CCA_QSA_EXTTOK_PK_OFFSET           10
/* Offset into an QSA public key area of the seed length */
#define CCA_QSA_EXTTOK_SEED_OFFSET         12
/* Offset into an QSA public key area of the payload area */
#define CCA_QSA_EXTTOK_PAYLOAD_OFFSET      24

/* Offset into the rule array returned by STATCCA and length of the returned
 * CCA version field. */
#define CCA_STATCCA_CCA_VERSION_OFFSET         24
#define CCA_STATCCA_CCA_VERSION_LENGTH          8
/* Offset into the rule_array returned by the STATCCAE command for the
 * New and Current Symmetric Master Key register status */
#define CCA_STATCCAE_SYM_NMK_OFFSET   0
#define CCA_STATCCAE_SYM_CMK_OFFSET   8
/* Offset into the rule_array returned by the STATAES command for the
 * New and Current AES Master Key register status */
#define CCA_STATAES_AES_NMK_OFFSET   0
#define CCA_STATAES_AES_CMK_OFFSET   8
/* Offset into the rule_array returned by the STATAPKA command for the
 * New and Current APKA Master Key register status */
#define CCA_STATAPKA_APKA_NMK_OFFSET  0
#define CCA_STATAPKA_APKA_CMK_OFFSET  8
/* Offsets into the verb_data returned by the STATICSB command for the
 * Master Key register verification pattern */
#define CCA_STATICSB_SYM_CMK_ID            0x0f07
#define CCA_STATICSB_SYM_CMK_ID_OFFSET     134 /* ID = 0x0f07 */
#define CCA_STATICSB_SYM_CMK_MKVP_OFFSET   136 /* 8 bytes MKVP */
#define CCA_STATICSB_SYM_NMK_ID            0x0f06
#define CCA_STATICSB_SYM_NMK_ID_OFFSET     146 /* ID = 0x0f06 */
#define CCA_STATICSB_SYM_NMK_MKVP_OFFSET   148 /* 8 bytes MKVP */
#define CCA_STATICSB_AES_CMK_ID            0x0f0b
#define CCA_STATICSB_AES_CMK_ID_OFFSET     182 /* ID = 0x0f0b */
#define CCA_STATICSB_AES_CMK_MKVP_OFFSET   184 /* 8 bytes MKVP */
#define CCA_STATICSB_AES_NMK_ID            0x0f0a
#define CCA_STATICSB_AES_NMK_ID_OFFSET     194 /* ID = 0x0f0a */
#define CCA_STATICSB_AES_NMK_MKVP_OFFSET   196 /* 8 bytes MKVP */
#define CCA_STATICSB_APKA_CMK_ID           0x0f0e
#define CCA_STATICSB_APKA_CMK_ID_OFFSET    218 /* ID = 0x0f0e */
#define CCA_STATICSB_APKA_CMK_MKVP_OFFSET  220 /* 8 bytes MKVP */
#define CCA_STATICSB_APKA_NMK_ID           0x0f0d
#define CCA_STATICSB_APKA_NMK_ID_OFFSET    230 /* ID = 0x0f0d */
#define CCA_STATICSB_APKA_NMK_MKVP_OFFSET  232 /* 8 bytes MKVP */
/* Offset to start of public RSA key section for an external public RSA key token */
#define CCA_RSA_EXTTOK_PUBKEY_OFFSET  8
/* Offset to length of n within an public RSA key section in an ext public RSA key token */
#define CCA_RSA_EXTTOK_PUBKEY_N_LENGTH_OFFSET 10
/* Offset into the rule_array returned by the STATCRD2 command for the
 * adapter serial number */
#define CCA_STATCRD2_SERIAL_NUMBER_OFFSET  112

#define CCA_SERIALNO_LENGTH                8

/* CCA internal HMAC token payload bit length field offset */
#define CCA_HMAC_INTTOK_PAYLOAD_LENGTH_OFFSET 38

struct cca_key_derivation_data {
    uint8_t key_algorithm; /* CCA_AES_KEY or CCA_DES_KEY */
    uint8_t key_type;      /* CCA_KEY_DERIVE_TYPE_xxx values */
    uint16_t key_size;     /* in bits */
} __attribute__ ((__packed__));

#define CCA_KEY_DERIVE_TYPE_DATA     0x01 /* DATA key */
#define CCA_KEY_DERIVE_TYPE_CIPHER   0x04 /* CIPHER key */

struct cca_acp_segment {
    uint16_t       start_bit_no;
    uint16_t       end_bit_no;
    uint16_t       num_bytes;
    uint16_t       reserved;
} __attribute__ ((__packed__));

#define ACP_BYTE_NO(acp)      ((acp) / 8)
#define ACP_BIT_IN_BYTE(acp)  ((acp) % 8)
#define ACP_BIT_MASK(acp)     (0x80 >> ACP_BIT_IN_BYTE(acp))

struct cca_role_data {
    uint16_t       version;            /* 0x0101 */
    char           comment[20];
    uint16_t       auth_level;
    uint16_t       lower_time_limit;   /* 0xhhmm */
    uint16_t       upper_time_limit;   /* 0xhhmm */
    uint8_t        days_valid;         /* 7 bits, Sunday, Monday ... Saturday */
    uint16_t       num_segments;
    uint16_t       reserved;
} __attribute__ ((__packed__));

struct cca_acp_info {
    CK_BBOOL acp_03B8; /* Symmetric Key Export - AES, CKM-RAKW */
    CK_BBOOL acp_03CD; /* Permit import of an AES key token from a PKCS#11
                          CKM_RSA_AES_KEY_WRAP object */
};

/* CCA STDLL constants */

#define CCATOK_MAX_N_LEN  1024
#define CCATOK_MAX_E_LEN  512

enum cca_key_type {
    CCA_AES_KEY = 0x02,
    CCA_DES_KEY = 0x01,
};

#define CCA_DEFAULT_ADAPTER_ENVAR   "CSU_DEFAULT_ADAPTER"
#define CCA_DEFAULT_DOMAIN_ENVAR    "CSU_DEFAULT_DOMAIN"
#define CCA_DEVICE_ANY              "DEV-ANY"
#define CCA_DOMAIN_ANY              "DOM-ANY"

#define CCA_MKVP_LENGTH             8

enum cca_mk_type {
    CCA_MK_SYM,
    CCA_MK_AES,
    CCA_MK_APKA,
};

#define CCA_NUM_MK_TYPES        3

enum cca_nmk_state {
    CCA_NMK_STATUS_CLEAR   = 1,
    CCA_NMK_STATUS_PARTIAL = 2,
    CCA_NMK_STATUS_FULL    = 3,
};

enum cca_cmk_state {
    CCA_CMK_STATUS_CLEAR = 1,
    CCA_CMK_STATUS_FULL  = 2,
};

enum cca_ktc_type {
    CCA_KTC_DATA,
    CCA_KTC_CIPHER,
    CCA_KTC_PKA,
};

/* CCA STDLL debug logging definitions */

#ifdef DEBUG
#define CCADBG(fn, rc, reason) ock_logit("CCA_TOK DEBUG %s:%d  %s failed. " \
        "return: %ld, reason: %ld\n", __func__, __LINE__, fn, rc, reason)

#define DBG(fmt, ...) ock_logit("CCA_TOK DEBUG %s:%d %s " fmt "\n", \
    __FILE__, __LINE__, __func__, ##__VA_ARGS__)
#else
#define CCADBG(...)   do { } while (0)
#define DBG(...)   do { } while (0)
#endif

/* cca token type enum, used with analyse_cca_key_token() */
enum cca_token_type {
    sec_des_data_key,
    sec_aes_data_key,
    sec_aes_cipher_key,
    sec_hmac_key,
    sec_rsa_priv_key,
    sec_rsa_publ_key,
    sec_ecc_priv_key,
    sec_ecc_publ_key,
    sec_qsa_priv_key,
    sec_qsa_publ_key
};

struct cca_mk_change_op {
    volatile int mk_change_active;
    char mk_change_op[8]; /* set if mk_change_active = 1 */
    unsigned char new_sym_mkvp[CCA_MKVP_LENGTH];
    unsigned char new_aes_mkvp[CCA_MKVP_LENGTH];
    unsigned char new_apka_mkvp[CCA_MKVP_LENGTH];
    CK_BBOOL new_sym_mkvp_set;
    CK_BBOOL new_aes_mkvp_set;
    CK_BBOOL new_apka_mkvp_set;
    struct apqn *apqns;
    unsigned int num_apqns;
};

/* CCA token private data */
#define PKEY_MK_VP_LENGTH           32

#define PKEY_MODE_DISABLED          0
#define PKEY_MODE_DEFAULT           1
#define PKEY_MODE_ENABLED           2

#define AES_KEY_MODE_DATA           0
#define AES_KEY_MODE_CIPHER         1

struct cca_version {
    unsigned int ver;
    unsigned int rel;
    unsigned int mod;
};

struct cca_private_data {
    void *lib_csulcca;
    struct cca_version cca_lib_version;
    struct cca_version min_card_version;
    struct cca_version min_cex7_card_version;
    struct cca_version min_cex8_card_version;
    pthread_rwlock_t min_card_version_rwlock;
    unsigned char expected_sym_mkvp[CCA_MKVP_LENGTH];
    unsigned char expected_aes_mkvp[CCA_MKVP_LENGTH];
    unsigned char expected_apka_mkvp[CCA_MKVP_LENGTH];
    CK_BBOOL expected_sym_mkvp_set;
    CK_BBOOL expected_aes_mkvp_set;
    CK_BBOOL expected_apka_mkvp_set;
    CK_BBOOL dev_any;
    CK_BBOOL dom_any;
    unsigned int num_adapters;
    unsigned int num_domains;
    unsigned int num_usagedoms;
    unsigned short usage_domains[256];
    CK_BBOOL inconsistent;
    struct cca_mk_change_op mk_change_ops[CCA_NUM_MK_TYPES];
    char token_config_filename[PATH_MAX];
    int pkey_mode;
    int pkey_wrap_supported;
    char pkey_mk_vp[PKEY_MK_VP_LENGTH];
    pthread_rwlock_t pkey_rwlock;
    int pkeyfd;
    int msa_level;
    CK_BBOOL cka_sensitive_default_true;
    int aes_key_mode;
    pthread_rwlock_t acp_info_rwlock;
    struct cca_acp_info acp_info;
};

#define CCA_CFG_EXPECTED_MKVPS  "EXPECTED_MKVPS"
#define CCA_CFG_SYM_MKVP        "SYM"
#define CCA_CFG_AES_MKVP        "AES"
#define CCA_CFG_APKA_MKVP       "APKA"

#define SYSFS_BUS_AP            "/sys/bus/ap/"
#define SYSFS_DEVICES_AP        "/sys/devices/ap/"
#define REGEX_CARD_PATTERN      "card[0-9a-fA-F]+"
#define MASK_COPRO              0x10000000

extern CSUACRA_t dll_CSUACRA;
extern CSUACRD_t dll_CSUACRD;
extern CSNBKTC_t dll_CSNBKTC;
extern CSNBKTC2_t dll_CSNBKTC2;
extern CSNDKTC_t dll_CSNDKTC;

/*
 * Macros to enclose CCA verbs that use a secure key blob.
 * If the CCA verb fails with return code 8 reason code 48 "One or more keys
 * has a master key verification pattern that is not valid.", check if the
 * secure key bob is enciphered with the new MK already. If so, and if a
 * MK change operation for that master key type is currently active, select
 * a single APQN that has the new MK set/activated. Wait in case no APQN is
 * currently available. Once a single APQN has been selected, retry the CCA
 * verb on the now selected single APQN.
 */
#define RETRY_NEW_MK_BLOB_START()                                            \
                do {                                                         \
                    int single_selected = 0;                                 \
                    char serialno[CCA_SERIALNO_LENGTH + 1];                  \
                    do {

#define RETRY_NEW_MK_BLOB_END(tokdata, return_code, reason_code,             \
                              blob, bloblen)                                 \
                RETRY_NEW_MK_BLOB2_END(tokdata, return_code, reason_code,    \
                                       blob, bloblen, NULL, 0)

#define RETRY_NEW_MK_BLOB2_END(tokdata, return_code, reason_code,            \
                               blob1, bloblen1, blob2, bloblen2)             \
                        if (constant_time_eq((return_code), 8) &             \
                            constant_time_eq((reason_code), 48)) {           \
                            TRACE_DEVEL("%s MKVP mismatch\n", __func__);     \
                            if (!single_selected &&                          \
                                cca_check_blob_select_single_apqn((tokdata), \
                                                      (blob1), (bloblen1),   \
                                                      (blob2), (bloblen2),   \
                                                      serialno)) {           \
                                single_selected = 1;                         \
                                continue;                                    \
                            }                                                \
                        }                                                    \
                        if (single_selected) {                               \
                            if (cca_deselect_single_apqn((tokdata),          \
                                                      serialno) != CKR_OK) { \
                                TRACE_ERROR("%s Failed to de-select single " \
                                            "APQN\n", __func__);             \
                                (return_code) = 16;                          \
                                (reason_code) = 336;                         \
                            }                                                \
                        }                                                    \
                        break;                                               \
                    } while (1);                                             \
                } while (0);

/*
 * Macros to enclose any usage of CCA verbs.
 * Obtains a READ lock on the CCA adapter lock, if a DOM-ANY configuration is
 * used. This prevents CCA adapter usage concurrent to another thread performing
 * Domain selection processing. Domain selection works on process scope, so
 * it would influence all threads that currently use CCA verbs.
 */
#define USE_CCA_ADAPTER_START(tokdata, return_code, reason_code)             \
                do {                                                         \
                    if (((struct cca_private_data *)                         \
                                      (tokdata)->private_data)->dom_any) {   \
                        if (pthread_rwlock_rdlock(&cca_adapter_rwlock)       \
                                                                    != 0) {  \
                            TRACE_ERROR("CCA adapter RD-Lock failed.\n");    \
                            (return_code) = 16;                              \
                            (reason_code) = 336;                             \
                            break;                                           \
                        }                                                    \
                    }

#define USE_CCA_ADAPTER_END(tokdata, return_code, reason_code)               \
                    if (((struct cca_private_data *)                         \
                                       (tokdata)->private_data)->dom_any) {  \
                        if (pthread_rwlock_unlock(&cca_adapter_rwlock)       \
                                                                    != 0) {  \
                            TRACE_ERROR("CCA adapter Unlock failed.\n");     \
                            (return_code) = 16;                              \
                            (reason_code) = 336;                             \
                            break;                                           \
                        }                                                    \
                    }                                                        \
                } while (0);

extern pthread_rwlock_t cca_adapter_rwlock;

CK_RV build_update_attribute(TEMPLATE * tmpl,
                             CK_ATTRIBUTE_TYPE type,
                             CK_BYTE * data, CK_ULONG data_len);
CK_BBOOL analyse_cca_key_token(const CK_BYTE *t, CK_ULONG tlen,
                               enum cca_token_type *keytype,
                               unsigned int *keybitsize,
                               const CK_BYTE **mkvp);
CK_RV check_expected_mkvp(STDLL_TokData_t *tokdata,
                          enum cca_token_type keytype,
                          const CK_BYTE *mkvp, CK_BBOOL *new_mk);
CK_RV cca_get_mkvps(unsigned char *cur_sym, unsigned char *new_sym,
                    unsigned char *cur_aes, unsigned char *new_aes,
                    unsigned char *cur_apka, unsigned char *new_apka);
CK_RV cca_get_mk_state(enum cca_mk_type mk_type,
                       enum cca_cmk_state *cur,
                       enum cca_nmk_state *new);
void cca_config_parse_error(int line, int col, const char *msg);
CK_RV cca_config_parse_exp_mkvps(char *fname,
                                 struct ConfigStructNode *exp_mkvp_node,
                                 unsigned char *expected_sym_mkvp,
                                 CK_BBOOL *expected_sym_mkvp_set,
                                 unsigned char *expected_aes_mkvp,
                                 CK_BBOOL *expected_aes_mkvp_set,
                                 unsigned char *expected_apka_mkvp,
                                 CK_BBOOL *expected_apka_mkvp_set);
CK_RV cca_get_adapter_serial_number(char *serialno);
CK_RV cca_iterate_adapters(STDLL_TokData_t *tokdata,
                           CK_RV (*cb)(STDLL_TokData_t *tokdata,
                                       const char *adapter,
                                       unsigned short card,
                                       unsigned short domain,
                                       void *private),
                           void *cb_private);
unsigned char *cca_mk_change_find_mkvp_in_ops(STDLL_TokData_t *tokdata,
                                              enum cca_mk_type mk_type,
                                              unsigned int *idx);
struct cca_mk_change_op *cca_mk_change_find_op_by_keytype(
                                                   STDLL_TokData_t *tokdata,
                                                   enum cca_token_type keytype);
CK_RV cca_mk_change_check_pending_ops(STDLL_TokData_t *tokdata);
CK_BBOOL cca_check_blob_select_single_apqn(STDLL_TokData_t *tokdata,
                                           const CK_BYTE *sec_key1,
                                           CK_ULONG sec_key1_len,
                                           const CK_BYTE *sec_key2,
                                           CK_ULONG sec_key2_len,
                                           char *serialno);
CK_RV cca_deselect_single_apqn(STDLL_TokData_t *tokdata, char *serialno);
CK_RV cca_reencipher_created_key(STDLL_TokData_t *tokdata,
                                 TEMPLATE* tmpl,  CK_BYTE *sec_key,
                                 CK_ULONG sec_key_len, CK_BBOOL new_mk,
                                 enum cca_token_type keytype,
                                 CK_BBOOL aes_xts_2dn_key);
CK_RV cca_handle_mk_change_event(STDLL_TokData_t *tokdata,
                                 unsigned int event_type,
                                 unsigned int event_flags,
                                 const char *payload,
                                 unsigned int payload_len);

#endif
