1 /*
2  * card-masktech.c: Support for Masktech smart cards using the MTCOS operating system.
3  *
4  * Copyright (C) 2011-2015 MaskTech GmbH Fischerstrasse 19, 87435 Kempten, Germany
5  * Copyright (C) 2011 Andrey Uvarov (X-Infotech) <andrejs.uvarovs@x-infotech.com>
6  * Copyright (C) 2015 Vincent Le Toux (My Smart Logon) <vincent.letoux@mysmartlogon.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22 
23 #if HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 
27 #include <stdlib.h>
28 #include <string.h>
29 
30 #include "internal.h"
31 #include "cardctl.h"
32 #include "iso7816.h"
33 
34 static struct sc_atr_table masktech_atrs[] = {
35 	{"3B:89:80:01:4D:54:43:4F:53:70:02:00:04:31",
36 	 "FF:FF:FF:FF:FF:FF:FF:FF:FF:FC:FF:FC:F4:F5" , NULL,
37 	 SC_CARD_TYPE_MASKTECH_GENERIC, 0, NULL},
38 	{"3B:88:80:01:00:00:00:00:77:81:80:00:6E", "FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:EE:FF:EE", NULL,
39 	 SC_CARD_TYPE_MASKTECH_GENERIC, 0, NULL},
40 	{"3B:9D:13:81:31:60:35:80:31:C0:69:4D:54:43:4F:53:73:02:00:00:40",
41 	 "FF:FF:FF:FF:FF:FF:FD:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FC:F0:F0", NULL,
42 	 SC_CARD_TYPE_MASKTECH_GENERIC, 0, NULL},
43 	{NULL, NULL, NULL, 0, 0, NULL}
44 };
45 
46 static struct sc_card_operations *iso_ops;
47 static struct sc_card_operations masktech_ops;
48 static struct sc_card_driver masktech_drv = {
49 	"MaskTech Smart Card",
50 	"MaskTech",
51 	&masktech_ops,
52 	masktech_atrs, 0, NULL
53 };
54 
55 struct masktech_private_data {
56 	/* save the key reference set at set_masktech_set_security_env to recover it as the signature step */
57 	int	rsa_key_ref;
58 
59 };
60 
masktech_match_card(sc_card_t * card)61 static int masktech_match_card(sc_card_t * card)
62 {
63 	/* check if the ATR is in the known ATR */
64 	if (_sc_match_atr(card, masktech_atrs, &card->type) < 0)
65 		return 0;
66 
67 	return 1;
68 }
69 
masktech_init(sc_card_t * card)70 static int masktech_init(sc_card_t * card)
71 {
72 	unsigned long flags;
73 	struct masktech_private_data *data;
74 
75 	sc_log(card->ctx,  "masktech_init()\n");
76 
77 	/* private data kept during the live of the driver */
78 	if (!(data = (struct masktech_private_data *) malloc(sizeof(*data))))
79 		return SC_ERROR_OUT_OF_MEMORY;
80 	card->drv_data = data;
81 
82 	/* supported RSA keys and how padding is done */
83 	flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE;
84 	_sc_card_add_rsa_alg(card, 1024, flags, 0);
85 	_sc_card_add_rsa_alg(card, 2048, flags, 0);
86 	_sc_card_add_rsa_alg(card, 3072, flags, 0);
87 	card->caps |= SC_CARD_CAP_APDU_EXT;
88 	return SC_SUCCESS;
89 }
90 
91 
masktech_finish(sc_card_t * card)92 static int masktech_finish(sc_card_t *card)
93 {
94 	/* free the private data */
95 	if (card->drv_data) {
96 		free(card->drv_data);
97 		card->drv_data = NULL;
98 	}
99 	return 0;
100 }
101 
masktech_set_security_env(sc_card_t * card,const sc_security_env_t * env,int se_num)102 static int masktech_set_security_env(sc_card_t *card,
103                                      const sc_security_env_t *env,
104                                      int se_num)
105 {
106 	struct masktech_private_data *private_data;
107 	sc_log(card->ctx,  "masktech_set_security_env(), keyRef = 0x%0x, algo = 0x%0x\n",
108 		 *env->key_ref, env->algorithm_flags);
109 
110 	private_data = (struct masktech_private_data *) card->drv_data;
111 	if (!private_data)
112 		return SC_ERROR_INTERNAL;
113 
114 	/* save the key reference */
115 	if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT) {
116 		if (env->key_ref_len != 1) {
117 			sc_log(card->ctx,  "Invalid key reference supplied.\n");
118 			return SC_ERROR_NOT_SUPPORTED;
119 		}
120 		private_data->rsa_key_ref = env->key_ref[0];
121 	}
122 
123 	return iso_ops->set_security_env(card, env, se_num);
124 }
125 
masktech_compute_signature(sc_card_t * card,const u8 * data,size_t datalen,u8 * out,size_t outlen)126 static int masktech_compute_signature(sc_card_t *card,
127                                       const u8 * data,
128                                       size_t datalen,
129                                       u8 * out,
130                                       size_t outlen)
131 {
132 
133 	struct masktech_private_data *private_data;
134 	u8 sha256hash[32];
135 	static const u8 hdr_sha256[] = {
136 		0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
137 		0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
138 	};
139 	assert(card != NULL && data != NULL && out != NULL);
140 	sc_log(card->ctx,  "masktech_compute_signature()\n");
141 
142 	/* retrieve the key reference */
143 	private_data = (struct masktech_private_data *) card->drv_data;
144 	if (!private_data)
145 		return SC_ERROR_INTERNAL;
146 
147 	if (private_data->rsa_key_ref == 0x88)
148 	{
149 		/* for this key reference, the card supports only SHA256 hash and the hash is computed using a digest info */
150 		/* check that it is a SHA256 with digest info*/
151 		if ((datalen != sizeof(hdr_sha256) + 32) || (memcmp(hdr_sha256, data, sizeof(hdr_sha256)) != 0))
152 		{
153 			sc_log(card->ctx,  "It is not a SHA256 with digestinfo\n");
154 			return SC_ERROR_NOT_SUPPORTED;
155 		}
156 		/* extract the SHA-256 hash */
157 		memcpy(sha256hash, (u8 *)(data+(datalen-32)), 32);//only last 32 byte => sha256
158 		/* default ISO 7816 functions */
159 		return iso_ops->compute_signature(card, sha256hash, 32, out, outlen);
160 	}
161 	else
162 	{
163 		/* default ISO 7816 functions */
164 		return iso_ops->compute_signature(card, data, datalen, out, outlen);
165 	}
166 }
167 
masktech_decipher(sc_card_t * card,const u8 * crgram,size_t crgram_len,u8 * out,size_t outlen)168 static int masktech_decipher(sc_card_t *card,
169                              const u8 * crgram,
170                              size_t crgram_len,
171                              u8 * out,
172                              size_t outlen)
173 {
174 	int r;
175 	sc_apdu_t apdu;
176 	u8 rbuf[SC_MAX_EXT_APDU_BUFFER_SIZE];
177 
178 	assert(card != NULL && crgram != NULL && out != NULL);
179 	sc_log(card->ctx,  "masktech_decipher()\n");
180 
181 	if (crgram_len > SC_MAX_EXT_APDU_BUFFER_SIZE) {
182 		SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
183 	}
184 
185 	sc_format_apdu(card, &apdu, SC_APDU_CASE_4_EXT, 0x2A, 0x80, 0x86);
186 	apdu.resp = rbuf;
187 	apdu.resplen = sizeof(rbuf);
188 	/* the card doesn't support anything else here (+1 / -1 is not working) */
189 	apdu.le = 65536;
190 
191 	apdu.data = crgram;
192 	apdu.lc = crgram_len;
193 	apdu.datalen = crgram_len;
194 
195 	r = sc_transmit_apdu(card, &apdu);
196 	LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
197 	if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
198 		size_t len = apdu.resplen > outlen ? outlen : apdu.resplen;
199 
200 		memcpy(out, apdu.resp, len);
201 		SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, len);
202 	}
203 	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2));
204 }
205 
206 /* unblock pin cmd */
masktech_pin_unblock(sc_card_t * card,struct sc_pin_cmd_data * data,int * tries_left)207 static int masktech_pin_unblock(sc_card_t *card,
208                             struct sc_pin_cmd_data *data,
209                             int *tries_left)
210 {
211 	int rv = 0;
212 	struct sc_pin_cmd_data verify_data;
213 	struct sc_pin_cmd_data reset_data;
214 
215 	/* Build a SC_PIN_CMD_VERIFY APDU on PUK */
216 	memset(&verify_data, 0, sizeof(verify_data));
217 	verify_data.cmd = SC_PIN_CMD_VERIFY;
218 	verify_data.pin_type = 1;
219 	verify_data.pin_reference = 0x83;
220 	verify_data.pin1 = data->pin1;
221 	verify_data.flags = data->flags;
222 	verify_data.pin1.prompt = data->pin1.prompt;
223 
224 	rv = iso_ops->pin_cmd(card, &verify_data, tries_left);
225 	LOG_TEST_RET(card->ctx, rv, "APDU transmit failed - verify unblock PIN");
226 
227 	/* Build a SC_PIN_CMD_UNBLOCK APDU */
228 	memset(&reset_data, 0, sizeof(reset_data));
229 	reset_data.cmd = SC_PIN_CMD_UNBLOCK;
230 	reset_data.pin_type = 1;
231 	reset_data.pin_reference = 0x91;
232 	/* pin1 is set to null on purpose and flag set to implicit change
233 	 => if there is a pinpad reader, do not ask for pin1 */
234 	reset_data.pin2 = data->pin2;
235 	reset_data.flags = data->flags | SC_PIN_CMD_IMPLICIT_CHANGE;
236 	reset_data.pin2.prompt = data->pin2.prompt;
237 
238 	rv = iso_ops->pin_cmd(card, &reset_data, tries_left);
239 	LOG_TEST_RET(card->ctx, rv, "APDU transmit failed - reset unblock PIN");
240 
241 	return 0;
242 }
243 
masktech_pin_change(sc_card_t * card,struct sc_pin_cmd_data * data,int * tries_left)244 static int masktech_pin_change(sc_card_t *card,
245                             struct sc_pin_cmd_data *data,
246                             int *tries_left)
247 {
248 	int rv = 0;
249 	struct sc_pin_cmd_data verify_data;
250 	struct sc_pin_cmd_data change_data;
251 
252 	/* Build a SC_PIN_CMD_VERIFY APDU */
253 	memset(&verify_data, 0, sizeof(verify_data));
254 	verify_data.cmd = SC_PIN_CMD_VERIFY;
255 	verify_data.pin_type = 1;
256 	verify_data.pin_reference = data->pin_reference;
257 	verify_data.pin1 = data->pin1;
258 	verify_data.flags = data->flags;
259 	verify_data.pin1.prompt = data->pin1.prompt;
260 
261 	rv = iso_ops->pin_cmd(card, &verify_data, tries_left);
262 	LOG_TEST_RET(card->ctx, rv, "APDU transmit failed - verify change PIN");
263 
264 	/* Build a SC_PIN_CMD_CHANGE APDU */
265 	memset(&change_data, 0, sizeof(change_data));
266 	change_data.cmd = SC_PIN_CMD_CHANGE;
267 	change_data.pin_type = 1;
268 	change_data.pin_reference = data->pin_reference;
269 	/* pin1 is set to null on purpose and flag set to implicit change
270 	 => if there is a pinpad reader, do not ask for pin1 */
271 	change_data.pin2 = data->pin2;
272 	change_data.flags = data->flags | SC_PIN_CMD_IMPLICIT_CHANGE;
273 	change_data.pin2.prompt = data->pin2.prompt;
274 
275 	rv = iso_ops->pin_cmd(card, &change_data, tries_left);
276 	LOG_TEST_RET(card->ctx, rv, "APDU transmit failed - change PIN");
277 
278 	return 0;
279 }
280 
masktech_pin_cmd(sc_card_t * card,struct sc_pin_cmd_data * data,int * tries_left)281 static int masktech_pin_cmd(sc_card_t *card,
282                             struct sc_pin_cmd_data *data,
283                             int *tries_left)
284 {
285 	int       rv;
286 	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
287 
288 	switch(data->cmd)
289 	{
290 	case SC_PIN_CMD_UNBLOCK:
291 		rv = masktech_pin_unblock(card, data, tries_left);
292 		break;
293 	case SC_PIN_CMD_CHANGE:
294 		rv = masktech_pin_change(card, data, tries_left);
295 		break;
296 	default:
297 		rv = iso_ops->pin_cmd(card, data, tries_left);
298 		break;
299 	}
300 	return rv;
301 
302 
303 }
304 
masktech_get_serialnr(sc_card_t * card,sc_serial_number_t * serial)305 static int masktech_get_serialnr(sc_card_t * card, sc_serial_number_t * serial)
306 {
307 	struct sc_apdu apdu;
308 	unsigned char apdu_resp[SC_MAX_APDU_BUFFER_SIZE-2];
309 	int rv;
310 
311 	if (!serial)
312 		LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
313 
314 	/* Get smart card serial number */
315 	card->cla = 0x80;
316 	sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x08, 0x00, 0x00);
317 	apdu.resplen = sizeof(apdu_resp);
318 	apdu.resp = apdu_resp;
319 
320 	rv = sc_transmit_apdu(card, &apdu);
321 	card->cla = 0x00;
322 
323 	LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
324 
325 	if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00)
326 		return SC_ERROR_INTERNAL;
327 
328 	if (SC_MAX_SERIALNR < apdu.resplen)
329 	{
330 		LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
331 	}
332 	/* cache serial number */
333 	card->serialnr.len = apdu.resplen;
334 	memcpy(card->serialnr.value, apdu.resp, card->serialnr.len);
335 
336 	/* copy and return serial number */
337 	if (serial)
338 		memcpy(serial, &card->serialnr, sizeof(*serial));
339 
340 	LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
341 }
342 
343 
masktech_card_ctl(sc_card_t * card,unsigned long cmd,void * ptr)344 static int masktech_card_ctl(sc_card_t * card, unsigned long cmd, void *ptr)
345 {
346 	sc_log(card->ctx,  "masktech_card_ctl()\n");
347 	switch (cmd) {
348 		case SC_CARDCTL_GET_SERIALNR:
349 			return masktech_get_serialnr(card, (sc_serial_number_t *) ptr);
350 		default:
351 			return SC_ERROR_NOT_SUPPORTED;
352 	}
353 }
354 
sc_get_driver(void)355 static struct sc_card_driver *sc_get_driver(void)
356 {
357 
358 	if (iso_ops == NULL)
359 		iso_ops = sc_get_iso7816_driver()->ops;
360 
361 	masktech_ops = *iso_ops;
362 
363 	masktech_ops.match_card = masktech_match_card;
364 	masktech_ops.init = masktech_init;
365 	masktech_ops.finish = masktech_finish;
366 	masktech_ops.set_security_env = masktech_set_security_env;
367 	masktech_ops.compute_signature = masktech_compute_signature;
368 	masktech_ops.decipher = masktech_decipher;
369 	masktech_ops.pin_cmd = masktech_pin_cmd;
370 	masktech_ops.card_ctl = masktech_card_ctl;
371 	return &masktech_drv;
372 }
373 
sc_get_masktech_driver(void)374 struct sc_card_driver *sc_get_masktech_driver(void)
375 {
376 	return sc_get_driver();
377 }
378