1 /*-
2 * Free/Libre Near Field Communication (NFC) library
3 *
4 * Libnfc historical contributors:
5 * Copyright (C) 2009 Roel Verdult
6 * Copyright (C) 2009-2013 Romuald Conty
7 * Copyright (C) 2010-2012 Romain Tartière
8 * Copyright (C) 2010-2013 Philippe Teuwen
9 * Copyright (C) 2012-2013 Ludovic Rousseau
10 * See AUTHORS file for a more comprehensive list of contributors.
11 * Additional contributors of this file:
12 *
13 * This program is free software: you can redistribute it and/or modify it
14 * under the terms of the GNU Lesser General Public License as published by the
15 * Free Software Foundation, either version 3 of the License, or (at your
16 * option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful, but WITHOUT
19 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
21 * more details.
22 *
23 * You should have received a copy of the GNU Lesser General Public License
24 * along with this program. If not, see <http://www.gnu.org/licenses/>
25 */
26
27 /**
28 * @file acr122_pcsc.c
29 * @brief Driver for ACR122 devices (e.g. Tikitag, Touchatag, ACS ACR122) behind PC/SC
30 */
31
32 #ifdef HAVE_CONFIG_H
33 # include "config.h"
34 #endif // HAVE_CONFIG_H
35
36 #include <inttypes.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <stddef.h>
40 #include <string.h>
41
42 #include <nfc/nfc.h>
43
44 #include "chips/pn53x.h"
45 #include "drivers/acr122_pcsc.h"
46 #include "nfc-internal.h"
47
48 // Bus
49 #ifdef __APPLE__
50 #include <PCSC/winscard.h>
51 #include <PCSC/wintypes.h>
52 #else
53 #include <winscard.h>
54 #endif
55
56 #define ACR122_PCSC_DRIVER_NAME "acr122_pcsc"
57
58 #if defined (_WIN32)
59 # define IOCTL_CCID_ESCAPE_SCARD_CTL_CODE SCARD_CTL_CODE(3500)
60 #elif defined(__APPLE__)
61 # define IOCTL_CCID_ESCAPE_SCARD_CTL_CODE (((0x31) << 16) | ((3500) << 2))
62 #elif defined (__FreeBSD__) || defined (__OpenBSD__)
63 # define IOCTL_CCID_ESCAPE_SCARD_CTL_CODE (((0x31) << 16) | ((3500) << 2))
64 #elif defined (__linux__)
65 # include <reader.h>
66 // Escape IOCTL tested successfully:
67 # define IOCTL_CCID_ESCAPE_SCARD_CTL_CODE SCARD_CTL_CODE(1)
68 #else
69 # error "Can't determine serial string for your system"
70 #endif
71
72 #include <nfc/nfc.h>
73
74 #define SCARD_OPERATION_SUCCESS 0x61
75 #define SCARD_OPERATION_ERROR 0x63
76
77 #ifndef SCARD_PROTOCOL_UNDEFINED
78 # define SCARD_PROTOCOL_UNDEFINED SCARD_PROTOCOL_UNSET
79 #endif
80
81 #define FIRMWARE_TEXT "ACR122U" // Tested on: ACR122U101(ACS), ACR122U102(Tikitag), ACR122U203(ACS)
82
83 #define ACR122_PCSC_WRAP_LEN 6
84 #define ACR122_PCSC_COMMAND_LEN 266
85 #define ACR122_PCSC_RESPONSE_LEN 268
86
87 #define LOG_GROUP NFC_LOG_GROUP_DRIVER
88 #define LOG_CATEGORY "libnfc.driver.acr122_pcsc"
89
90 // Internal data struct
91 const struct pn53x_io acr122_pcsc_io;
92
93 // Prototypes
94 char *acr122_pcsc_firmware(nfc_device *pnd);
95
96 const char *supported_devices[] = {
97 "ACS ACR122", // ACR122U & Touchatag, last version
98 "ACS ACR 38U-CCID", // Touchatag, early version
99 "ACS ACR38U-CCID", // Touchatag, early version, under MacOSX
100 "ACS AET65", // Touchatag using CCID driver version >= 1.4.6
101 " CCID USB", // ??
102 NULL
103 };
104
105 struct acr122_pcsc_data {
106 SCARDHANDLE hCard;
107 SCARD_IO_REQUEST ioCard;
108 uint8_t abtRx[ACR122_PCSC_RESPONSE_LEN];
109 size_t szRx;
110 };
111
112 #define DRIVER_DATA(pnd) ((struct acr122_pcsc_data*)(pnd->driver_data))
113
114 static SCARDCONTEXT _SCardContext;
115 static int _iSCardContextRefCount = 0;
116
117 static SCARDCONTEXT *
acr122_pcsc_get_scardcontext(void)118 acr122_pcsc_get_scardcontext(void)
119 {
120 if (_iSCardContextRefCount == 0) {
121 if (SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &_SCardContext) != SCARD_S_SUCCESS)
122 return NULL;
123 }
124 _iSCardContextRefCount++;
125
126 return &_SCardContext;
127 }
128
129 static void
acr122_pcsc_free_scardcontext(void)130 acr122_pcsc_free_scardcontext(void)
131 {
132 if (_iSCardContextRefCount) {
133 _iSCardContextRefCount--;
134 if (!_iSCardContextRefCount) {
135 SCardReleaseContext(_SCardContext);
136 }
137 }
138 }
139
140 #define PCSC_MAX_DEVICES 16
141 /**
142 * @brief List opened devices
143 *
144 * Probe PCSC to find ACR122 devices (ACR122U and Touchatag/Tikitag).
145 *
146 * @param connstring array of nfc_connstring where found device's connection strings will be stored.
147 * @param connstrings_len size of connstrings array.
148 * @return number of devices found.
149 */
150 static size_t
acr122_pcsc_scan(const nfc_context * context,nfc_connstring connstrings[],const size_t connstrings_len)151 acr122_pcsc_scan(const nfc_context *context, nfc_connstring connstrings[], const size_t connstrings_len)
152 {
153 (void) context;
154 size_t szPos = 0;
155 char acDeviceNames[256 + 64 * PCSC_MAX_DEVICES];
156 size_t szDeviceNamesLen = sizeof(acDeviceNames);
157 SCARDCONTEXT *pscc;
158 int i;
159
160 // Clear the reader list
161 memset(acDeviceNames, '\0', szDeviceNamesLen);
162
163 // Test if context succeeded
164 if (!(pscc = acr122_pcsc_get_scardcontext())) {
165 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_INFO, "Warning: %s", "PCSC context not found (make sure PCSC daemon is running).");
166 return 0;
167 }
168 // Retrieve the string array of all available pcsc readers
169 DWORD dwDeviceNamesLen = szDeviceNamesLen;
170 if (SCardListReaders(*pscc, NULL, acDeviceNames, &dwDeviceNamesLen) != SCARD_S_SUCCESS)
171 return 0;
172
173 size_t device_found = 0;
174 while ((acDeviceNames[szPos] != '\0') && (device_found < connstrings_len)) {
175 bool bSupported = false;
176 for (i = 0; supported_devices[i] && !bSupported; i++) {
177 int l = strlen(supported_devices[i]);
178 bSupported = 0 == strncmp(supported_devices[i], acDeviceNames + szPos, l);
179 }
180
181 if (bSupported) {
182 // Supported ACR122 device found
183 snprintf(connstrings[device_found], sizeof(nfc_connstring), "%s:%s", ACR122_PCSC_DRIVER_NAME, acDeviceNames + szPos);
184 device_found++;
185 } else {
186 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "PCSC device [%s] is not NFC capable or not supported by libnfc.", acDeviceNames + szPos);
187 }
188
189 // Find next device name position
190 while (acDeviceNames[szPos++] != '\0');
191 }
192 acr122_pcsc_free_scardcontext();
193
194 return device_found;
195 }
196
197 struct acr122_pcsc_descriptor {
198 char *pcsc_device_name;
199 };
200
201 static nfc_device *
acr122_pcsc_open(const nfc_context * context,const nfc_connstring connstring)202 acr122_pcsc_open(const nfc_context *context, const nfc_connstring connstring)
203 {
204 struct acr122_pcsc_descriptor ndd;
205 int connstring_decode_level = connstring_decode(connstring, ACR122_PCSC_DRIVER_NAME, "pcsc", &ndd.pcsc_device_name, NULL);
206
207 if (connstring_decode_level < 1) {
208 return NULL;
209 }
210
211 nfc_connstring fullconnstring;
212 if (connstring_decode_level == 1) {
213 // Device was not specified, take the first one we can find
214 size_t szDeviceFound = acr122_pcsc_scan(context, &fullconnstring, 1);
215 if (szDeviceFound < 1)
216 return NULL;
217 connstring_decode_level = connstring_decode(fullconnstring, ACR122_PCSC_DRIVER_NAME, "pcsc", &ndd.pcsc_device_name, NULL);
218 if (connstring_decode_level < 2) {
219 return NULL;
220 }
221 } else {
222 memcpy(fullconnstring, connstring, sizeof(nfc_connstring));
223 }
224 if (strlen(ndd.pcsc_device_name) < 5) { // We can assume it's a reader ID as pcsc_name always ends with "NN NN"
225 // Device was not specified, only ID, retrieve it
226 size_t index;
227 if (sscanf(ndd.pcsc_device_name, "%4" SCNuPTR, &index) != 1) {
228 free(ndd.pcsc_device_name);
229 return NULL;
230 }
231 nfc_connstring *ncs = malloc(sizeof(nfc_connstring) * (index + 1));
232 if (!ncs) {
233 perror("malloc");
234 free(ndd.pcsc_device_name);
235 return NULL;
236 }
237 size_t szDeviceFound = acr122_pcsc_scan(context, ncs, index + 1);
238 if (szDeviceFound < index + 1) {
239 free(ncs);
240 free(ndd.pcsc_device_name);
241 return NULL;
242 }
243 strncpy(fullconnstring, ncs[index], sizeof(nfc_connstring));
244 fullconnstring[sizeof(nfc_connstring) - 1] = '\0';
245 free(ncs);
246 connstring_decode_level = connstring_decode(fullconnstring, ACR122_PCSC_DRIVER_NAME, "pcsc", &ndd.pcsc_device_name, NULL);
247
248 if (connstring_decode_level < 2) {
249 free(ndd.pcsc_device_name);
250 return NULL;
251 }
252 }
253
254 char *pcFirmware;
255 nfc_device *pnd = nfc_device_new(context, fullconnstring);
256 if (!pnd) {
257 perror("malloc");
258 goto error;
259 }
260 pnd->driver_data = malloc(sizeof(struct acr122_pcsc_data));
261 if (!pnd->driver_data) {
262 perror("malloc");
263 goto error;
264 }
265
266 // Alloc and init chip's data
267 if (pn53x_data_new(pnd, &acr122_pcsc_io) == NULL) {
268 perror("malloc");
269 goto error;
270 }
271
272 SCARDCONTEXT *pscc;
273
274 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Attempt to open %s", ndd.pcsc_device_name);
275 // Test if context succeeded
276 if (!(pscc = acr122_pcsc_get_scardcontext()))
277 goto error;
278 // Test if we were able to connect to the "emulator" card
279 if (SCardConnect(*pscc, ndd.pcsc_device_name, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &(DRIVER_DATA(pnd)->hCard), (void *) & (DRIVER_DATA(pnd)->ioCard.dwProtocol)) != SCARD_S_SUCCESS) {
280 // Connect to ACR122 firmware version >2.0
281 if (SCardConnect(*pscc, ndd.pcsc_device_name, SCARD_SHARE_DIRECT, 0, &(DRIVER_DATA(pnd)->hCard), (void *) & (DRIVER_DATA(pnd)->ioCard.dwProtocol)) != SCARD_S_SUCCESS) {
282 // We can not connect to this device.
283 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "PCSC connect failed");
284 goto error;
285 }
286 }
287 // Configure I/O settings for card communication
288 DRIVER_DATA(pnd)->ioCard.cbPciLength = sizeof(SCARD_IO_REQUEST);
289
290 // Retrieve the current firmware version
291 pcFirmware = acr122_pcsc_firmware(pnd);
292 if (strstr(pcFirmware, FIRMWARE_TEXT) != NULL) {
293
294 // Done, we found the reader we are looking for
295 snprintf(pnd->name, sizeof(pnd->name), "%s / %s", ndd.pcsc_device_name, pcFirmware);
296
297 // 50: empirical tuning on Touchatag
298 // 46: empirical tuning on ACR122U
299 CHIP_DATA(pnd)->timer_correction = 50;
300
301 pnd->driver = &acr122_pcsc_driver;
302
303 pn53x_init(pnd);
304
305 free(ndd.pcsc_device_name);
306 return pnd;
307 }
308
309 error:
310 free(ndd.pcsc_device_name);
311 nfc_device_free(pnd);
312 return NULL;
313 }
314
315 static void
acr122_pcsc_close(nfc_device * pnd)316 acr122_pcsc_close(nfc_device *pnd)
317 {
318 pn53x_idle(pnd);
319
320 SCardDisconnect(DRIVER_DATA(pnd)->hCard, SCARD_LEAVE_CARD);
321 acr122_pcsc_free_scardcontext();
322
323 pn53x_data_free(pnd);
324 nfc_device_free(pnd);
325 }
326
327 static int
acr122_pcsc_send(nfc_device * pnd,const uint8_t * pbtData,const size_t szData,int timeout)328 acr122_pcsc_send(nfc_device *pnd, const uint8_t *pbtData, const size_t szData, int timeout)
329 {
330 // FIXME: timeout is not handled
331 (void) timeout;
332
333 // Make sure the command does not overflow the send buffer
334 if (szData > ACR122_PCSC_COMMAND_LEN) {
335 pnd->last_error = NFC_EINVARG;
336 return pnd->last_error;
337 }
338
339 // Prepare and transmit the send buffer
340 const size_t szTxBuf = szData + 6;
341 uint8_t abtTxBuf[ACR122_PCSC_WRAP_LEN + ACR122_PCSC_COMMAND_LEN] = { 0xFF, 0x00, 0x00, 0x00, szData + 1, 0xD4 };
342 memcpy(abtTxBuf + ACR122_PCSC_WRAP_LEN, pbtData, szData);
343 LOG_HEX(NFC_LOG_GROUP_COM, "TX", abtTxBuf, szTxBuf);
344
345 DRIVER_DATA(pnd)->szRx = 0;
346
347 DWORD dwRxLen = sizeof(DRIVER_DATA(pnd)->abtRx);
348
349 if (DRIVER_DATA(pnd)->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED) {
350 /*
351 * In this communication mode, we directly have the response from the
352 * PN532. Save it in the driver data structure so that it can be retrieved
353 * in ac122_receive().
354 *
355 * Some devices will never enter this state (e.g. Touchatag) but are still
356 * supported through SCardTransmit calls (see bellow).
357 *
358 * This state is generaly reached when the ACR122 has no target in it's
359 * field.
360 */
361 if (SCardControl(DRIVER_DATA(pnd)->hCard, IOCTL_CCID_ESCAPE_SCARD_CTL_CODE, abtTxBuf, szTxBuf, DRIVER_DATA(pnd)->abtRx, ACR122_PCSC_RESPONSE_LEN, &dwRxLen) != SCARD_S_SUCCESS) {
362 pnd->last_error = NFC_EIO;
363 return pnd->last_error;
364 }
365 } else {
366 /*
367 * In T=0 mode, we receive an acknoledge from the MCU, in T=1 mode, we
368 * receive the response from the PN532.
369 */
370 if (SCardTransmit(DRIVER_DATA(pnd)->hCard, &(DRIVER_DATA(pnd)->ioCard), abtTxBuf, szTxBuf, NULL, DRIVER_DATA(pnd)->abtRx, &dwRxLen) != SCARD_S_SUCCESS) {
371 pnd->last_error = NFC_EIO;
372 return pnd->last_error;
373 }
374 }
375
376 if (DRIVER_DATA(pnd)->ioCard.dwProtocol == SCARD_PROTOCOL_T0) {
377 /*
378 * Check the MCU response
379 */
380
381 // Make sure we received the byte-count we expected
382 if (dwRxLen != 2) {
383 pnd->last_error = NFC_EIO;
384 return pnd->last_error;
385 }
386 // Check if the operation was successful, so an answer is available
387 if (DRIVER_DATA(pnd)->abtRx[0] == SCARD_OPERATION_ERROR) {
388 pnd->last_error = NFC_EIO;
389 return pnd->last_error;
390 }
391 } else {
392 DRIVER_DATA(pnd)->szRx = dwRxLen;
393 }
394
395 return NFC_SUCCESS;
396 }
397
398 static int
acr122_pcsc_receive(nfc_device * pnd,uint8_t * pbtData,const size_t szData,int timeout)399 acr122_pcsc_receive(nfc_device *pnd, uint8_t *pbtData, const size_t szData, int timeout)
400 {
401 // FIXME: timeout is not handled
402 (void) timeout;
403
404 int len;
405 uint8_t abtRxCmd[5] = { 0xFF, 0xC0, 0x00, 0x00 };
406
407 if (DRIVER_DATA(pnd)->ioCard.dwProtocol == SCARD_PROTOCOL_T0) {
408 /*
409 * Retrieve the PN532 response.
410 */
411 DWORD dwRxLen = sizeof(DRIVER_DATA(pnd)->abtRx);
412 abtRxCmd[4] = DRIVER_DATA(pnd)->abtRx[1];
413 if (SCardTransmit(DRIVER_DATA(pnd)->hCard, &(DRIVER_DATA(pnd)->ioCard), abtRxCmd, sizeof(abtRxCmd), NULL, DRIVER_DATA(pnd)->abtRx, &dwRxLen) != SCARD_S_SUCCESS) {
414 pnd->last_error = NFC_EIO;
415 return pnd->last_error;
416 }
417 DRIVER_DATA(pnd)->szRx = dwRxLen;
418 } else {
419 /*
420 * We already have the PN532 answer, it was saved by acr122_pcsc_send().
421 */
422 }
423 LOG_HEX(NFC_LOG_GROUP_COM, "RX", DRIVER_DATA(pnd)->abtRx, DRIVER_DATA(pnd)->szRx);
424
425 // Make sure we have an emulated answer that fits the return buffer
426 if (DRIVER_DATA(pnd)->szRx < 4 || (DRIVER_DATA(pnd)->szRx - 4) > szData) {
427 pnd->last_error = NFC_EIO;
428 return pnd->last_error;
429 }
430 // Wipe out the 4 APDU emulation bytes: D5 4B .. .. .. 90 00
431 len = DRIVER_DATA(pnd)->szRx - 4;
432 memcpy(pbtData, DRIVER_DATA(pnd)->abtRx + 2, len);
433
434 return len;
435 }
436
437 char *
acr122_pcsc_firmware(nfc_device * pnd)438 acr122_pcsc_firmware(nfc_device *pnd)
439 {
440 uint8_t abtGetFw[5] = { 0xFF, 0x00, 0x48, 0x00, 0x00 };
441 uint32_t uiResult;
442
443 static char abtFw[11];
444 DWORD dwFwLen = sizeof(abtFw);
445 memset(abtFw, 0x00, sizeof(abtFw));
446 if (DRIVER_DATA(pnd)->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED) {
447 uiResult = SCardControl(DRIVER_DATA(pnd)->hCard, IOCTL_CCID_ESCAPE_SCARD_CTL_CODE, abtGetFw, sizeof(abtGetFw), (uint8_t *) abtFw, dwFwLen - 1, &dwFwLen);
448 } else {
449 uiResult = SCardTransmit(DRIVER_DATA(pnd)->hCard, &(DRIVER_DATA(pnd)->ioCard), abtGetFw, sizeof(abtGetFw), NULL, (uint8_t *) abtFw, &dwFwLen);
450 }
451
452 if (uiResult != SCARD_S_SUCCESS) {
453 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "No ACR122 firmware received, Error: %08x", uiResult);
454 }
455
456 return abtFw;
457 }
458
459 #if 0
460 bool
461 acr122_pcsc_led_red(nfc_device *pnd, bool bOn)
462 {
463 uint8_t abtLed[9] = { 0xFF, 0x00, 0x40, 0x05, 0x04, 0x00, 0x00, 0x00, 0x00 };
464 uint8_t abtBuf[2];
465 DWORD dwBufLen = sizeof(abtBuf);
466 (void) bOn;
467 if (DRIVER_DATA(pnd)->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED) {
468 return (SCardControl(DRIVER_DATA(pnd)->hCard, IOCTL_CCID_ESCAPE_SCARD_CTL_CODE, abtLed, sizeof(abtLed), abtBuf, dwBufLen, &dwBufLen) == SCARD_S_SUCCESS);
469 } else {
470 return (SCardTransmit(DRIVER_DATA(pnd)->hCard, &(DRIVER_DATA(pnd)->ioCard), abtLed, sizeof(abtLed), NULL, abtBuf, &dwBufLen) == SCARD_S_SUCCESS);
471 }
472 }
473 #endif
474
475 const struct pn53x_io acr122_pcsc_io = {
476 .send = acr122_pcsc_send,
477 .receive = acr122_pcsc_receive,
478 };
479
480 const struct nfc_driver acr122_pcsc_driver = {
481 .name = ACR122_PCSC_DRIVER_NAME,
482 .scan = acr122_pcsc_scan,
483 .open = acr122_pcsc_open,
484 .close = acr122_pcsc_close,
485 .strerror = pn53x_strerror,
486
487 .initiator_init = pn53x_initiator_init,
488 .initiator_init_secure_element = NULL, // No secure-element support
489 .initiator_select_passive_target = pn53x_initiator_select_passive_target,
490 .initiator_poll_target = pn53x_initiator_poll_target,
491 .initiator_select_dep_target = pn53x_initiator_select_dep_target,
492 .initiator_deselect_target = pn53x_initiator_deselect_target,
493 .initiator_transceive_bytes = pn53x_initiator_transceive_bytes,
494 .initiator_transceive_bits = pn53x_initiator_transceive_bits,
495 .initiator_transceive_bytes_timed = pn53x_initiator_transceive_bytes_timed,
496 .initiator_transceive_bits_timed = pn53x_initiator_transceive_bits_timed,
497 .initiator_target_is_present = pn53x_initiator_target_is_present,
498
499 .target_init = pn53x_target_init,
500 .target_send_bytes = pn53x_target_send_bytes,
501 .target_receive_bytes = pn53x_target_receive_bytes,
502 .target_send_bits = pn53x_target_send_bits,
503 .target_receive_bits = pn53x_target_receive_bits,
504
505 .device_set_property_bool = pn53x_set_property_bool,
506 .device_set_property_int = pn53x_set_property_int,
507 .get_supported_modulation = pn53x_get_supported_modulation,
508 .get_supported_baud_rate = pn53x_get_supported_baud_rate,
509 .device_get_information_about = pn53x_get_information_about,
510
511 .abort_command = NULL, // Abort is not supported in this driver
512 .idle = pn53x_idle,
513 /* Even if PN532, PowerDown is not recommended on those devices */
514 .powerdown = NULL,
515 };
516
517