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