1 /* 2 * sm.h: Support of Secure Messaging 3 * 4 * Copyright (C) 2010 Viktor Tarasov <vtarasov@opentrust.com> 5 * OpenTrust <www.opentrust.com> 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21 22 #ifndef _SM_H 23 #define _SM_H 24 25 #include <stdio.h> 26 #ifdef HAVE_UNISTD_H 27 #include <unistd.h> 28 #endif 29 30 #ifdef __cplusplus 31 extern "C" { 32 #endif 33 34 #include <libopensc/errors.h> 35 #include <libopensc/types.h> 36 #include <common/libscdl.h> 37 38 #define SM_TYPE_GP_SCP01 0x100 39 #define SM_TYPE_CWA14890 0x400 40 #define SM_TYPE_DH_RSA 0x500 41 42 /** don't use SM */ 43 #define SM_MODE_NONE 0x0 44 /** let the card driver decide when to use SM, possibly based on the card's ACLs */ 45 #define SM_MODE_ACL 0x100 46 /** use SM for all commands */ 47 #define SM_MODE_TRANSMIT 0x200 48 49 #define SM_CMD_INITIALIZE 0x10 50 #define SM_CMD_MUTUAL_AUTHENTICATION 0x20 51 #define SM_CMD_RSA 0x100 52 #define SM_CMD_RSA_GENERATE 0x101 53 #define SM_CMD_RSA_UPDATE 0x102 54 #define SM_CMD_RSA_READ_PUBLIC 0x103 55 #define SM_CMD_FILE 0x200 56 #define SM_CMD_FILE_READ 0x201 57 #define SM_CMD_FILE_UPDATE 0x202 58 #define SM_CMD_FILE_CREATE 0x203 59 #define SM_CMD_FILE_DELETE 0x204 60 #define SM_CMD_PIN 0x300 61 #define SM_CMD_PIN_VERIFY 0x301 62 #define SM_CMD_PIN_RESET 0x302 63 #define SM_CMD_PIN_SET_PIN 0x303 64 #define SM_CMD_PSO 0x400 65 #define SM_CMD_PSO_DST 0x401 66 #define SM_CMD_APDU 0x500 67 #define SM_CMD_APDU_TRANSMIT 0x501 68 #define SM_CMD_APDU_RAW 0x502 69 #define SM_CMD_APPLET 0x600 70 #define SM_CMD_APPLET_DELETE 0x601 71 #define SM_CMD_APPLET_LOAD 0x602 72 #define SM_CMD_APPLET_INSTALL 0x603 73 #define SM_CMD_EXTERNAL_AUTH 0x700 74 #define SM_CMD_EXTERNAL_AUTH_INIT 0x701 75 #define SM_CMD_EXTERNAL_AUTH_CHALLENGE 0x702 76 #define SM_CMD_EXTERNAL_AUTH_DOIT 0x703 77 #define SM_CMD_SDO_UPDATE 0x800 78 #define SM_CMD_FINALIZE 0x900 79 80 #define SM_RESPONSE_CONTEXT_TAG 0xA1 81 #define SM_RESPONSE_CONTEXT_DATA_TAG 0xA2 82 83 #define SM_MAX_DATA_SIZE 0xE0 84 85 #define SM_SMALL_CHALLENGE_LEN 8 86 87 #define SM_GP_SECURITY_NO 0x00 88 #define SM_GP_SECURITY_MAC 0x01 89 #define SM_GP_SECURITY_ENC 0x03 90 91 /* Global Platform (SCP01) data types */ 92 /* 93 * @struct sm_type_params_gp 94 * Global Platform SM channel parameters 95 */ 96 struct sm_type_params_gp { 97 unsigned level; 98 unsigned index; 99 unsigned version; 100 101 struct sc_cplc cplc; 102 }; 103 104 /* 105 * @struct sm_gp_keyset 106 * Global Platform keyset: 107 * - version, index; 108 * - keyset presented in three parts: 'ENC', 'MAC' and 'KEK'; 109 * - keyset presented in continuous manner - raw or 'to be diversified'. 110 */ 111 struct sm_gp_keyset { 112 int version; 113 int index; 114 unsigned char enc[16]; 115 unsigned char mac[16]; 116 unsigned char kek[16]; 117 118 unsigned char kmc[48]; 119 unsigned kmc_len; 120 }; 121 122 /* 123 * @struct sm_gp_session 124 * Global Platform SM session data 125 */ 126 struct sm_gp_session { 127 struct sm_gp_keyset gp_keyset; 128 129 struct sm_type_params_gp params; 130 131 unsigned char host_challenge[SM_SMALL_CHALLENGE_LEN]; 132 unsigned char card_challenge[SM_SMALL_CHALLENGE_LEN]; 133 134 unsigned char *session_enc, *session_mac, *session_kek; 135 unsigned char mac_icv[8]; 136 }; 137 138 139 /* CWA, IAS/ECC data types */ 140 141 /* 142 * @struct sm_type_params_cwa 143 */ 144 struct sm_type_params_cwa { 145 struct sc_crt crt_at; 146 }; 147 148 /* 149 * @struct sm_cwa_keyset 150 * CWA keyset: 151 * - SDO reference; 152 * - 'ENC' and 'MAC' 3DES keys. 153 */ 154 struct sm_cwa_keyset { 155 unsigned sdo_reference; 156 unsigned char enc[16]; 157 unsigned char mac[16]; 158 }; 159 160 /* 161 * @struct sm_cwa_token_data 162 * CWA token data: 163 * - serial; 164 * - 'small' random; 165 * - 'big' random. 166 */ 167 struct sm_cwa_token_data { 168 unsigned char sn[8]; 169 unsigned char rnd[8]; 170 unsigned char k[32]; 171 }; 172 173 /* 174 * @struct sm_cwa_session 175 * CWA working SM session data: 176 * - ICC and IFD token data; 177 * - ENC and MAC session keys; 178 * - SSC (SM Sequence Counter); 179 * - 'mutual authentication' data. 180 */ 181 struct sm_cwa_session { 182 struct sm_cwa_keyset cwa_keyset; 183 184 struct sm_type_params_cwa params; 185 186 struct sm_cwa_token_data icc; 187 struct sm_cwa_token_data ifd; 188 189 unsigned char session_enc[16]; 190 unsigned char session_mac[16]; 191 192 unsigned char ssc[8]; 193 194 unsigned char host_challenge[SM_SMALL_CHALLENGE_LEN]; 195 unsigned char card_challenge[SM_SMALL_CHALLENGE_LEN]; 196 197 unsigned char mdata[0x48]; 198 size_t mdata_len; 199 }; 200 201 /* 202 * @struct sm_dh_session 203 * DH SM session data: 204 */ 205 struct sm_dh_session { 206 struct sc_tlv_data g; 207 struct sc_tlv_data N; 208 struct sc_tlv_data ifd_p; 209 struct sc_tlv_data ifd_y; 210 struct sc_tlv_data icc_p; 211 struct sc_tlv_data shared_secret; 212 213 unsigned char session_enc[16]; 214 unsigned char session_mac[16]; 215 216 unsigned char card_challenge[32]; 217 218 unsigned char ssc[8]; 219 }; 220 221 /* 222 * @struct sc_info is the 223 * placehold for the secure messaging working data: 224 * - SM type; 225 * - SM session state; 226 * - command to execute by external SM module; 227 * - data related to the current card context. 228 */ 229 struct sm_info { 230 char config_section[64]; 231 unsigned card_type; 232 233 unsigned cmd; 234 void *cmd_data; 235 236 unsigned sm_type; 237 union { 238 struct sm_gp_session gp; 239 struct sm_cwa_session cwa; 240 struct sm_dh_session dh; 241 } session; 242 243 struct sc_serial_number serialnr; 244 245 unsigned security_condition; 246 247 struct sc_path current_path_df; 248 struct sc_path current_path_ef; 249 struct sc_aid current_aid; 250 251 unsigned char *rdata; 252 size_t rdata_len; 253 }; 254 255 /* 256 * @struct sm_card_response 257 * data type to return card response. 258 */ 259 typedef struct sm_card_response { 260 int num; 261 262 unsigned char data[SC_MAX_APDU_BUFFER_SIZE]; 263 size_t data_len; 264 265 unsigned char mac[8]; 266 size_t mac_len; 267 268 unsigned char sw1, sw2; 269 270 struct sm_card_response *next; 271 struct sm_card_response *prev; 272 } sm_card_response_t; 273 274 struct sc_context; 275 struct sc_card; 276 277 /* 278 * @struct sm_card_operations 279 * card driver handlers related to secure messaging (in 'APDU TRANSMIT' mode) 280 * - 'open' - initialize SM session; 281 * - 'encode apdu' - SM encoding of the raw APDU; 282 * - 'decrypt response' - decode card answer; 283 * - 'close' - close SM session. 284 */ 285 struct sm_card_operations { 286 int (*open)(struct sc_card *card); 287 int (*get_sm_apdu)(struct sc_card *card, struct sc_apdu *apdu, struct sc_apdu **sm_apdu); 288 int (*free_sm_apdu)(struct sc_card *card, struct sc_apdu *apdu, struct sc_apdu **sm_apdu); 289 int (*close)(struct sc_card *card); 290 291 int (*read_binary)(struct sc_card *card, unsigned int idx, 292 unsigned char * buf, size_t count); 293 int (*update_binary)(struct sc_card *card, unsigned int idx, 294 const unsigned char * buf, size_t count); 295 }; 296 297 /* 298 * @struct sm_module_operations 299 * API to use external SM modules: 300 * - 'initialize' - get APDU(s) to initialize SM session; 301 * - 'get apdus' - get secured APDUs to execute particular command; 302 * - 'finalize' - get APDU(s) to finalize SM session; 303 * - 'module init' - initialize external module (allocate data, read configuration, ...); 304 * - 'module cleanup' - free resources allocated by external module. 305 */ 306 struct sm_module_operations { 307 int (*initialize)(struct sc_context *ctx, struct sm_info *info, 308 struct sc_remote_data *out); 309 int (*get_apdus)(struct sc_context *ctx, struct sm_info *sm_info, 310 unsigned char *init_data, size_t init_len, 311 struct sc_remote_data *out); 312 int (*finalize)(struct sc_context *ctx, struct sm_info *info, struct sc_remote_data *rdata, 313 unsigned char *out, size_t out_len); 314 int (*module_init)(struct sc_context *ctx, const char *data); 315 int (*module_cleanup)(struct sc_context *ctx); 316 317 int (*test)(struct sc_context *ctx, struct sm_info *info, char *out); 318 }; 319 320 typedef struct sm_module { 321 char filename[128]; 322 void *handle; 323 324 struct sm_module_operations ops; 325 } sm_module_t; 326 327 /* @struct sm_context 328 * SM context -- top level of the SM data type 329 * - SM mode ('ACL' or 'APDU TRANSMIT'), flags; 330 * - working SM data; 331 * - card operations related to SM in 'APDU TRANSMIT' mode; 332 * - external SM module; 333 * - 'lock'/'unlock' handlers to allow SM transfer in the locked card session. 334 */ 335 typedef struct sm_context { 336 char config_section[64]; 337 unsigned sm_mode, sm_flags; 338 339 struct sm_info info; 340 341 struct sm_card_operations ops; 342 343 struct sm_module module; 344 345 unsigned long (*app_lock)(void); 346 void (*app_unlock)(void); 347 } sm_context_t; 348 349 int sc_sm_parse_answer(struct sc_card *, unsigned char *, size_t, struct sm_card_response *); 350 int sc_sm_update_apdu_response(struct sc_card *, unsigned char *, size_t, int, struct sc_apdu *); 351 int sc_sm_single_transmit(struct sc_card *, struct sc_apdu *); 352 353 /** 354 * @brief Stops SM and frees allocated resources. 355 * 356 * Calls \a card->sm_ctx.ops.close() if available and \c card->sm_ctx.sm_mode 357 * is \c SM_MODE_TRANSMIT 358 * 359 * @param[in] card card 360 * 361 * @return \c SC_SUCCESS or error code if an error occurred 362 */ 363 int sc_sm_stop(struct sc_card *card); 364 365 #ifdef __cplusplus 366 } 367 #endif 368 369 #endif 370