#ifndef _SM_H
#define _SM_H
#include <stdio.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
#include <libopensc/errors.h>
#include <libopensc/types.h>
#include <common/libscdl.h>
#define SM_TYPE_GP_SCP01 0x100
#define SM_TYPE_CWA14890 0x400
#define SM_TYPE_DH_RSA 0x500
#define SM_MODE_NONE 0x0
#define SM_MODE_ACL 0x100
#define SM_MODE_TRANSMIT 0x200
#define SM_CMD_INITIALIZE 0x10
#define SM_CMD_MUTUAL_AUTHENTICATION 0x20
#define SM_CMD_RSA 0x100
#define SM_CMD_RSA_GENERATE 0x101
#define SM_CMD_RSA_UPDATE 0x102
#define SM_CMD_RSA_READ_PUBLIC 0x103
#define SM_CMD_FILE 0x200
#define SM_CMD_FILE_READ 0x201
#define SM_CMD_FILE_UPDATE 0x202
#define SM_CMD_FILE_CREATE 0x203
#define SM_CMD_FILE_DELETE 0x204
#define SM_CMD_PIN 0x300
#define SM_CMD_PIN_VERIFY 0x301
#define SM_CMD_PIN_RESET 0x302
#define SM_CMD_PIN_SET_PIN 0x303
#define SM_CMD_PSO 0x400
#define SM_CMD_PSO_DST 0x401
#define SM_CMD_APDU 0x500
#define SM_CMD_APDU_TRANSMIT 0x501
#define SM_CMD_APDU_RAW 0x502
#define SM_CMD_APPLET 0x600
#define SM_CMD_APPLET_DELETE 0x601
#define SM_CMD_APPLET_LOAD 0x602
#define SM_CMD_APPLET_INSTALL 0x603
#define SM_CMD_EXTERNAL_AUTH 0x700
#define SM_CMD_EXTERNAL_AUTH_INIT 0x701
#define SM_CMD_EXTERNAL_AUTH_CHALLENGE 0x702
#define SM_CMD_EXTERNAL_AUTH_DOIT 0x703
#define SM_CMD_SDO_UPDATE 0x800
#define SM_CMD_FINALIZE 0x900
#define SM_RESPONSE_CONTEXT_TAG 0xA1
#define SM_RESPONSE_CONTEXT_DATA_TAG 0xA2
#define SM_MAX_DATA_SIZE 0xE0
#define SM_SMALL_CHALLENGE_LEN 8
#define SM_GP_SECURITY_NO 0x00
#define SM_GP_SECURITY_MAC 0x01
#define SM_GP_SECURITY_ENC 0x03
struct sm_type_params_gp {
unsigned level;
unsigned index;
unsigned version;
struct sc_cplc cplc;
};
struct sm_gp_keyset {
int version;
int index;
unsigned char enc[16];
unsigned char mac[16];
unsigned char kek[16];
unsigned char kmc[48];
unsigned kmc_len;
};
struct sm_gp_session {
struct sm_gp_keyset gp_keyset;
struct sm_type_params_gp params;
unsigned char host_challenge[SM_SMALL_CHALLENGE_LEN];
unsigned char card_challenge[SM_SMALL_CHALLENGE_LEN];
unsigned char *session_enc, *session_mac, *session_kek;
unsigned char mac_icv[8];
};
struct sm_type_params_cwa {
struct sc_crt crt_at;
};
struct sm_cwa_keyset {
unsigned sdo_reference;
unsigned char enc[16];
unsigned char mac[16];
};
struct sm_cwa_token_data {
unsigned char sn[8];
unsigned char rnd[8];
unsigned char k[32];
};
struct sm_cwa_session {
struct sm_cwa_keyset cwa_keyset;
struct sm_type_params_cwa params;
struct sm_cwa_token_data icc;
struct sm_cwa_token_data ifd;
unsigned char session_enc[16];
unsigned char session_mac[16];
unsigned char ssc[8];
unsigned char host_challenge[SM_SMALL_CHALLENGE_LEN];
unsigned char card_challenge[SM_SMALL_CHALLENGE_LEN];
unsigned char mdata[0x48];
size_t mdata_len;
};
struct sm_dh_session {
struct sc_tlv_data g;
struct sc_tlv_data N;
struct sc_tlv_data ifd_p;
struct sc_tlv_data ifd_y;
struct sc_tlv_data icc_p;
struct sc_tlv_data shared_secret;
unsigned char session_enc[16];
unsigned char session_mac[16];
unsigned char card_challenge[32];
unsigned char ssc[8];
};
struct sm_info {
char config_section[64];
unsigned card_type;
unsigned cmd;
void *cmd_data;
unsigned sm_type;
union {
struct sm_gp_session gp;
struct sm_cwa_session cwa;
struct sm_dh_session dh;
} session;
struct sc_serial_number serialnr;
unsigned security_condition;
struct sc_path current_path_df;
struct sc_path current_path_ef;
struct sc_aid current_aid;
unsigned char *rdata;
size_t rdata_len;
};
typedef struct sm_card_response {
int num;
unsigned char data[SC_MAX_APDU_BUFFER_SIZE];
size_t data_len;
unsigned char mac[8];
size_t mac_len;
unsigned char sw1, sw2;
struct sm_card_response *next;
struct sm_card_response *prev;
} sm_card_response_t;
struct sc_context;
struct sc_card;
struct sm_card_operations {
int (*open)(struct sc_card *card);
int (*get_sm_apdu)(struct sc_card *card, struct sc_apdu *apdu, struct sc_apdu **sm_apdu);
int (*free_sm_apdu)(struct sc_card *card, struct sc_apdu *apdu, struct sc_apdu **sm_apdu);
int (*close)(struct sc_card *card);
int (*read_binary)(struct sc_card *card, unsigned int idx,
unsigned char * buf, size_t count);
int (*update_binary)(struct sc_card *card, unsigned int idx,
const unsigned char * buf, size_t count);
};
struct sm_module_operations {
int (*initialize)(struct sc_context *ctx, struct sm_info *info,
struct sc_remote_data *out);
int (*get_apdus)(struct sc_context *ctx, struct sm_info *sm_info,
unsigned char *init_data, size_t init_len,
struct sc_remote_data *out);
int (*finalize)(struct sc_context *ctx, struct sm_info *info, struct sc_remote_data *rdata,
unsigned char *out, size_t out_len);
int (*module_init)(struct sc_context *ctx, const char *data);
int (*module_cleanup)(struct sc_context *ctx);
int (*test)(struct sc_context *ctx, struct sm_info *info, char *out);
};
typedef struct sm_module {
char filename[128];
void *handle;
struct sm_module_operations ops;
} sm_module_t;
typedef struct sm_context {
char config_section[64];
unsigned sm_mode, sm_flags;
struct sm_info info;
struct sm_card_operations ops;
struct sm_module module;
unsigned long (*app_lock)(void);
void (*app_unlock)(void);
} sm_context_t;
int sc_sm_parse_answer(struct sc_card *, unsigned char *, size_t, struct sm_card_response *);
int sc_sm_update_apdu_response(struct sc_card *, unsigned char *, size_t, int, struct sc_apdu *);
int sc_sm_single_transmit(struct sc_card *, struct sc_apdu *);
int sc_sm_stop(struct sc_card *card);
#ifdef __cplusplus
}
#endif
#endif