1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (C) 2014 STMicroelectronics SAS. All rights reserved. |
4 | */ |
5 | |
6 | #include <net/nfc/hci.h> |
7 | |
8 | #include "st21nfca.h" |
9 | |
10 | #define ST21NFCA_EVT_UICC_ACTIVATE 0x10 |
11 | #define ST21NFCA_EVT_UICC_DEACTIVATE 0x13 |
12 | #define ST21NFCA_EVT_SE_HARD_RESET 0x20 |
13 | #define ST21NFCA_EVT_SE_SOFT_RESET 0x11 |
14 | #define ST21NFCA_EVT_SE_END_OF_APDU_TRANSFER 0x21 |
15 | #define ST21NFCA_EVT_SE_ACTIVATE 0x22 |
16 | #define ST21NFCA_EVT_SE_DEACTIVATE 0x23 |
17 | |
18 | #define ST21NFCA_EVT_TRANSMIT_DATA 0x10 |
19 | #define ST21NFCA_EVT_WTX_REQUEST 0x11 |
20 | |
21 | #define ST21NFCA_EVT_CONNECTIVITY 0x10 |
22 | #define ST21NFCA_EVT_TRANSACTION 0x12 |
23 | |
24 | #define ST21NFCA_SE_TO_HOT_PLUG 1000 |
25 | /* Connectivity pipe only */ |
26 | #define ST21NFCA_SE_COUNT_PIPE_UICC 0x01 |
27 | /* Connectivity + APDU Reader pipe */ |
28 | #define ST21NFCA_SE_COUNT_PIPE_EMBEDDED 0x02 |
29 | |
30 | #define ST21NFCA_SE_MODE_OFF 0x00 |
31 | #define ST21NFCA_SE_MODE_ON 0x01 |
32 | |
33 | #define ST21NFCA_PARAM_ATR 0x01 |
34 | #define ST21NFCA_ATR_DEFAULT_BWI 0x04 |
35 | |
36 | /* |
37 | * WT = 2^BWI/10[s], convert into msecs and add a secure |
38 | * room by increasing by 2 this timeout |
39 | */ |
40 | #define ST21NFCA_BWI_TO_TIMEOUT(x) ((1 << x) * 200) |
41 | #define ST21NFCA_ATR_GET_Y_FROM_TD(x) (x >> 4) |
42 | |
43 | /* If TA is present bit 0 is set */ |
44 | #define ST21NFCA_ATR_TA_PRESENT(x) (x & 0x01) |
45 | /* If TB is present bit 1 is set */ |
46 | #define ST21NFCA_ATR_TB_PRESENT(x) (x & 0x02) |
47 | |
48 | static u8 st21nfca_se_get_bwi(struct nfc_hci_dev *hdev) |
49 | { |
50 | int i; |
51 | u8 td; |
52 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); |
53 | |
54 | /* Bits 8 to 5 of the first TB for T=1 encode BWI from zero to nine */ |
55 | for (i = 1; i < ST21NFCA_ESE_MAX_LENGTH; i++) { |
56 | td = ST21NFCA_ATR_GET_Y_FROM_TD(info->se_info.atr[i]); |
57 | if (ST21NFCA_ATR_TA_PRESENT(td)) |
58 | i++; |
59 | if (ST21NFCA_ATR_TB_PRESENT(td)) { |
60 | i++; |
61 | return info->se_info.atr[i] >> 4; |
62 | } |
63 | } |
64 | return ST21NFCA_ATR_DEFAULT_BWI; |
65 | } |
66 | |
67 | static void st21nfca_se_get_atr(struct nfc_hci_dev *hdev) |
68 | { |
69 | int r; |
70 | struct sk_buff *skb; |
71 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); |
72 | |
73 | r = nfc_hci_get_param(hdev, ST21NFCA_APDU_READER_GATE, |
74 | ST21NFCA_PARAM_ATR, skb: &skb); |
75 | if (r < 0) |
76 | return; |
77 | |
78 | if (skb->len <= ST21NFCA_ESE_MAX_LENGTH) { |
79 | memcpy(info->se_info.atr, skb->data, skb->len); |
80 | info->se_info.wt_timeout = |
81 | ST21NFCA_BWI_TO_TIMEOUT(st21nfca_se_get_bwi(hdev)); |
82 | } |
83 | kfree_skb(skb); |
84 | } |
85 | |
86 | static int st21nfca_hci_control_se(struct nfc_hci_dev *hdev, u32 se_idx, |
87 | u8 state) |
88 | { |
89 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); |
90 | int r, i; |
91 | struct sk_buff *sk_host_list; |
92 | u8 se_event, host_id; |
93 | |
94 | switch (se_idx) { |
95 | case NFC_HCI_UICC_HOST_ID: |
96 | se_event = (state == ST21NFCA_SE_MODE_ON ? |
97 | ST21NFCA_EVT_UICC_ACTIVATE : |
98 | ST21NFCA_EVT_UICC_DEACTIVATE); |
99 | |
100 | info->se_info.count_pipes = 0; |
101 | info->se_info.expected_pipes = ST21NFCA_SE_COUNT_PIPE_UICC; |
102 | break; |
103 | case ST21NFCA_ESE_HOST_ID: |
104 | se_event = (state == ST21NFCA_SE_MODE_ON ? |
105 | ST21NFCA_EVT_SE_ACTIVATE : |
106 | ST21NFCA_EVT_SE_DEACTIVATE); |
107 | |
108 | info->se_info.count_pipes = 0; |
109 | info->se_info.expected_pipes = ST21NFCA_SE_COUNT_PIPE_EMBEDDED; |
110 | break; |
111 | default: |
112 | return -EINVAL; |
113 | } |
114 | |
115 | /* |
116 | * Wait for an EVT_HOT_PLUG in order to |
117 | * retrieve a relevant host list. |
118 | */ |
119 | reinit_completion(x: &info->se_info.req_completion); |
120 | r = nfc_hci_send_event(hdev, ST21NFCA_DEVICE_MGNT_GATE, event: se_event, |
121 | NULL, param_len: 0); |
122 | if (r < 0) |
123 | return r; |
124 | |
125 | mod_timer(timer: &info->se_info.se_active_timer, expires: jiffies + |
126 | msecs_to_jiffies(ST21NFCA_SE_TO_HOT_PLUG)); |
127 | info->se_info.se_active = true; |
128 | |
129 | /* Ignore return value and check in any case the host_list */ |
130 | wait_for_completion_interruptible(x: &info->se_info.req_completion); |
131 | |
132 | r = nfc_hci_get_param(hdev, NFC_HCI_ADMIN_GATE, |
133 | NFC_HCI_ADMIN_HOST_LIST, |
134 | skb: &sk_host_list); |
135 | if (r < 0) |
136 | return r; |
137 | |
138 | for (i = 0; i < sk_host_list->len && |
139 | sk_host_list->data[i] != se_idx; i++) |
140 | ; |
141 | host_id = sk_host_list->data[i]; |
142 | kfree_skb(skb: sk_host_list); |
143 | |
144 | if (state == ST21NFCA_SE_MODE_ON && host_id == se_idx) |
145 | return se_idx; |
146 | else if (state == ST21NFCA_SE_MODE_OFF && host_id != se_idx) |
147 | return se_idx; |
148 | |
149 | return -1; |
150 | } |
151 | |
152 | int st21nfca_hci_discover_se(struct nfc_hci_dev *hdev) |
153 | { |
154 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); |
155 | int se_count = 0; |
156 | |
157 | if (test_bit(ST21NFCA_FACTORY_MODE, &hdev->quirks)) |
158 | return 0; |
159 | |
160 | if (info->se_status->is_uicc_present) { |
161 | nfc_add_se(dev: hdev->ndev, NFC_HCI_UICC_HOST_ID, NFC_SE_UICC); |
162 | se_count++; |
163 | } |
164 | |
165 | if (info->se_status->is_ese_present) { |
166 | nfc_add_se(dev: hdev->ndev, ST21NFCA_ESE_HOST_ID, NFC_SE_EMBEDDED); |
167 | se_count++; |
168 | } |
169 | |
170 | return !se_count; |
171 | } |
172 | EXPORT_SYMBOL(st21nfca_hci_discover_se); |
173 | |
174 | int st21nfca_hci_enable_se(struct nfc_hci_dev *hdev, u32 se_idx) |
175 | { |
176 | int r; |
177 | |
178 | /* |
179 | * According to upper layer, se_idx == NFC_SE_UICC when |
180 | * info->se_status->is_uicc_enable is true should never happen. |
181 | * Same for eSE. |
182 | */ |
183 | r = st21nfca_hci_control_se(hdev, se_idx, ST21NFCA_SE_MODE_ON); |
184 | if (r == ST21NFCA_ESE_HOST_ID) { |
185 | st21nfca_se_get_atr(hdev); |
186 | r = nfc_hci_send_event(hdev, ST21NFCA_APDU_READER_GATE, |
187 | ST21NFCA_EVT_SE_SOFT_RESET, NULL, param_len: 0); |
188 | if (r < 0) |
189 | return r; |
190 | } else if (r < 0) { |
191 | /* |
192 | * The activation tentative failed, the secure element |
193 | * is not connected. Remove from the list. |
194 | */ |
195 | nfc_remove_se(dev: hdev->ndev, se_idx); |
196 | return r; |
197 | } |
198 | |
199 | return 0; |
200 | } |
201 | EXPORT_SYMBOL(st21nfca_hci_enable_se); |
202 | |
203 | int st21nfca_hci_disable_se(struct nfc_hci_dev *hdev, u32 se_idx) |
204 | { |
205 | int r; |
206 | |
207 | /* |
208 | * According to upper layer, se_idx == NFC_SE_UICC when |
209 | * info->se_status->is_uicc_enable is true should never happen |
210 | * Same for eSE. |
211 | */ |
212 | r = st21nfca_hci_control_se(hdev, se_idx, ST21NFCA_SE_MODE_OFF); |
213 | if (r < 0) |
214 | return r; |
215 | |
216 | return 0; |
217 | } |
218 | EXPORT_SYMBOL(st21nfca_hci_disable_se); |
219 | |
220 | int st21nfca_hci_se_io(struct nfc_hci_dev *hdev, u32 se_idx, |
221 | u8 *apdu, size_t apdu_length, |
222 | se_io_cb_t cb, void *cb_context) |
223 | { |
224 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); |
225 | |
226 | pr_debug("se_io %x\n" , se_idx); |
227 | |
228 | switch (se_idx) { |
229 | case ST21NFCA_ESE_HOST_ID: |
230 | info->se_info.cb = cb; |
231 | info->se_info.cb_context = cb_context; |
232 | mod_timer(timer: &info->se_info.bwi_timer, expires: jiffies + |
233 | msecs_to_jiffies(m: info->se_info.wt_timeout)); |
234 | info->se_info.bwi_active = true; |
235 | return nfc_hci_send_event(hdev, ST21NFCA_APDU_READER_GATE, |
236 | ST21NFCA_EVT_TRANSMIT_DATA, |
237 | param: apdu, param_len: apdu_length); |
238 | default: |
239 | /* Need to free cb_context here as at the moment we can't |
240 | * clearly indicate to the caller if the callback function |
241 | * would be called (and free it) or not. In both cases a |
242 | * negative value may be returned to the caller. |
243 | */ |
244 | kfree(objp: cb_context); |
245 | return -ENODEV; |
246 | } |
247 | } |
248 | EXPORT_SYMBOL(st21nfca_hci_se_io); |
249 | |
250 | static void st21nfca_se_wt_work(struct work_struct *work) |
251 | { |
252 | /* |
253 | * No answer from the secure element |
254 | * within the defined timeout. |
255 | * Let's send a reset request as recovery procedure. |
256 | * According to the situation, we first try to send a software reset |
257 | * to the secure element. If the next command is still not |
258 | * answering in time, we send to the CLF a secure element hardware |
259 | * reset request. |
260 | */ |
261 | /* hardware reset managed through VCC_UICC_OUT power supply */ |
262 | u8 param = 0x01; |
263 | struct st21nfca_hci_info *info = container_of(work, |
264 | struct st21nfca_hci_info, |
265 | se_info.timeout_work); |
266 | |
267 | info->se_info.bwi_active = false; |
268 | |
269 | if (!info->se_info.xch_error) { |
270 | info->se_info.xch_error = true; |
271 | nfc_hci_send_event(hdev: info->hdev, ST21NFCA_APDU_READER_GATE, |
272 | ST21NFCA_EVT_SE_SOFT_RESET, NULL, param_len: 0); |
273 | } else { |
274 | info->se_info.xch_error = false; |
275 | nfc_hci_send_event(hdev: info->hdev, ST21NFCA_DEVICE_MGNT_GATE, |
276 | ST21NFCA_EVT_SE_HARD_RESET, param: ¶m, param_len: 1); |
277 | } |
278 | info->se_info.cb(info->se_info.cb_context, NULL, 0, -ETIME); |
279 | } |
280 | |
281 | static void st21nfca_se_wt_timeout(struct timer_list *t) |
282 | { |
283 | struct st21nfca_hci_info *info = from_timer(info, t, se_info.bwi_timer); |
284 | |
285 | schedule_work(work: &info->se_info.timeout_work); |
286 | } |
287 | |
288 | static void st21nfca_se_activation_timeout(struct timer_list *t) |
289 | { |
290 | struct st21nfca_hci_info *info = from_timer(info, t, |
291 | se_info.se_active_timer); |
292 | |
293 | info->se_info.se_active = false; |
294 | |
295 | complete(&info->se_info.req_completion); |
296 | } |
297 | |
298 | /* |
299 | * Returns: |
300 | * <= 0: driver handled the event, skb consumed |
301 | * 1: driver does not handle the event, please do standard processing |
302 | */ |
303 | int st21nfca_connectivity_event_received(struct nfc_hci_dev *hdev, u8 host, |
304 | u8 event, struct sk_buff *skb) |
305 | { |
306 | int r = 0; |
307 | struct device *dev = &hdev->ndev->dev; |
308 | struct nfc_evt_transaction *transaction; |
309 | u32 aid_len; |
310 | u8 params_len; |
311 | |
312 | pr_debug("connectivity gate event: %x\n" , event); |
313 | |
314 | switch (event) { |
315 | case ST21NFCA_EVT_CONNECTIVITY: |
316 | r = nfc_se_connectivity(dev: hdev->ndev, se_idx: host); |
317 | break; |
318 | case ST21NFCA_EVT_TRANSACTION: |
319 | /* According to specification etsi 102 622 |
320 | * 11.2.2.4 EVT_TRANSACTION Table 52 |
321 | * Description Tag Length |
322 | * AID 81 5 to 16 |
323 | * PARAMETERS 82 0 to 255 |
324 | * |
325 | * The key differences are aid storage length is variably sized |
326 | * in the packet, but fixed in nfc_evt_transaction, and that the aid_len |
327 | * is u8 in the packet, but u32 in the structure, and the tags in |
328 | * the packet are not included in nfc_evt_transaction. |
329 | * |
330 | * size in bytes: 1 1 5-16 1 1 0-255 |
331 | * offset: 0 1 2 aid_len + 2 aid_len + 3 aid_len + 4 |
332 | * member name: aid_tag(M) aid_len aid params_tag(M) params_len params |
333 | * example: 0x81 5-16 X 0x82 0-255 X |
334 | */ |
335 | if (skb->len < 2 || skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG) |
336 | return -EPROTO; |
337 | |
338 | aid_len = skb->data[1]; |
339 | |
340 | if (skb->len < aid_len + 4 || aid_len > sizeof(transaction->aid)) |
341 | return -EPROTO; |
342 | |
343 | params_len = skb->data[aid_len + 3]; |
344 | |
345 | /* Verify PARAMETERS tag is (82), and final check that there is enough |
346 | * space in the packet to read everything. |
347 | */ |
348 | if ((skb->data[aid_len + 2] != NFC_EVT_TRANSACTION_PARAMS_TAG) || |
349 | (skb->len < aid_len + 4 + params_len)) |
350 | return -EPROTO; |
351 | |
352 | transaction = devm_kzalloc(dev, size: sizeof(*transaction) + params_len, GFP_KERNEL); |
353 | if (!transaction) |
354 | return -ENOMEM; |
355 | |
356 | transaction->aid_len = aid_len; |
357 | transaction->params_len = params_len; |
358 | |
359 | memcpy(transaction->aid, &skb->data[2], aid_len); |
360 | memcpy(transaction->params, &skb->data[aid_len + 4], params_len); |
361 | |
362 | r = nfc_se_transaction(dev: hdev->ndev, se_idx: host, evt_transaction: transaction); |
363 | break; |
364 | default: |
365 | nfc_err(&hdev->ndev->dev, "Unexpected event on connectivity gate\n" ); |
366 | return 1; |
367 | } |
368 | kfree_skb(skb); |
369 | return r; |
370 | } |
371 | EXPORT_SYMBOL(st21nfca_connectivity_event_received); |
372 | |
373 | int st21nfca_apdu_reader_event_received(struct nfc_hci_dev *hdev, |
374 | u8 event, struct sk_buff *skb) |
375 | { |
376 | int r = 0; |
377 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); |
378 | |
379 | pr_debug("apdu reader gate event: %x\n" , event); |
380 | |
381 | switch (event) { |
382 | case ST21NFCA_EVT_TRANSMIT_DATA: |
383 | del_timer_sync(timer: &info->se_info.bwi_timer); |
384 | cancel_work_sync(work: &info->se_info.timeout_work); |
385 | info->se_info.bwi_active = false; |
386 | r = nfc_hci_send_event(hdev, ST21NFCA_DEVICE_MGNT_GATE, |
387 | ST21NFCA_EVT_SE_END_OF_APDU_TRANSFER, NULL, param_len: 0); |
388 | if (r < 0) |
389 | goto exit; |
390 | |
391 | info->se_info.cb(info->se_info.cb_context, |
392 | skb->data, skb->len, 0); |
393 | break; |
394 | case ST21NFCA_EVT_WTX_REQUEST: |
395 | mod_timer(timer: &info->se_info.bwi_timer, expires: jiffies + |
396 | msecs_to_jiffies(m: info->se_info.wt_timeout)); |
397 | break; |
398 | default: |
399 | nfc_err(&hdev->ndev->dev, "Unexpected event on apdu reader gate\n" ); |
400 | return 1; |
401 | } |
402 | |
403 | exit: |
404 | kfree_skb(skb); |
405 | return r; |
406 | } |
407 | EXPORT_SYMBOL(st21nfca_apdu_reader_event_received); |
408 | |
409 | void st21nfca_se_init(struct nfc_hci_dev *hdev) |
410 | { |
411 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); |
412 | |
413 | init_completion(x: &info->se_info.req_completion); |
414 | INIT_WORK(&info->se_info.timeout_work, st21nfca_se_wt_work); |
415 | /* initialize timers */ |
416 | timer_setup(&info->se_info.bwi_timer, st21nfca_se_wt_timeout, 0); |
417 | info->se_info.bwi_active = false; |
418 | |
419 | timer_setup(&info->se_info.se_active_timer, |
420 | st21nfca_se_activation_timeout, 0); |
421 | info->se_info.se_active = false; |
422 | |
423 | info->se_info.count_pipes = 0; |
424 | info->se_info.expected_pipes = 0; |
425 | |
426 | info->se_info.xch_error = false; |
427 | |
428 | info->se_info.wt_timeout = |
429 | ST21NFCA_BWI_TO_TIMEOUT(ST21NFCA_ATR_DEFAULT_BWI); |
430 | } |
431 | EXPORT_SYMBOL(st21nfca_se_init); |
432 | |
433 | void st21nfca_se_deinit(struct nfc_hci_dev *hdev) |
434 | { |
435 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); |
436 | |
437 | if (info->se_info.bwi_active) |
438 | del_timer_sync(timer: &info->se_info.bwi_timer); |
439 | if (info->se_info.se_active) |
440 | del_timer_sync(timer: &info->se_info.se_active_timer); |
441 | |
442 | cancel_work_sync(work: &info->se_info.timeout_work); |
443 | info->se_info.bwi_active = false; |
444 | info->se_info.se_active = false; |
445 | } |
446 | EXPORT_SYMBOL(st21nfca_se_deinit); |
447 | |