cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

se.c (12161B)


      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
     48static 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
     67static 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);
     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
     86static 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(&info->se_info.req_completion);
    120	r = nfc_hci_send_event(hdev, ST21NFCA_DEVICE_MGNT_GATE, se_event,
    121			       NULL, 0);
    122	if (r < 0)
    123		return r;
    124
    125	mod_timer(&info->se_info.se_active_timer, 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(&info->se_info.req_completion);
    131
    132	r = nfc_hci_get_param(hdev, NFC_HCI_ADMIN_GATE,
    133			NFC_HCI_ADMIN_HOST_LIST,
    134			&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(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
    152int 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(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(hdev->ndev, ST21NFCA_ESE_HOST_ID, NFC_SE_EMBEDDED);
    167		se_count++;
    168	}
    169
    170	return !se_count;
    171}
    172EXPORT_SYMBOL(st21nfca_hci_discover_se);
    173
    174int 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, 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(hdev->ndev, se_idx);
    196		return r;
    197	}
    198
    199	return 0;
    200}
    201EXPORT_SYMBOL(st21nfca_hci_enable_se);
    202
    203int 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}
    218EXPORT_SYMBOL(st21nfca_hci_disable_se);
    219
    220int 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(&info->se_info.bwi_timer, jiffies +
    233			  msecs_to_jiffies(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					apdu, apdu_length);
    238	default:
    239		return -ENODEV;
    240	}
    241}
    242EXPORT_SYMBOL(st21nfca_hci_se_io);
    243
    244static void st21nfca_se_wt_work(struct work_struct *work)
    245{
    246	/*
    247	 * No answer from the secure element
    248	 * within the defined timeout.
    249	 * Let's send a reset request as recovery procedure.
    250	 * According to the situation, we first try to send a software reset
    251	 * to the secure element. If the next command is still not
    252	 * answering in time, we send to the CLF a secure element hardware
    253	 * reset request.
    254	 */
    255	/* hardware reset managed through VCC_UICC_OUT power supply */
    256	u8 param = 0x01;
    257	struct st21nfca_hci_info *info = container_of(work,
    258						struct st21nfca_hci_info,
    259						se_info.timeout_work);
    260
    261	info->se_info.bwi_active = false;
    262
    263	if (!info->se_info.xch_error) {
    264		info->se_info.xch_error = true;
    265		nfc_hci_send_event(info->hdev, ST21NFCA_APDU_READER_GATE,
    266				ST21NFCA_EVT_SE_SOFT_RESET, NULL, 0);
    267	} else {
    268		info->se_info.xch_error = false;
    269		nfc_hci_send_event(info->hdev, ST21NFCA_DEVICE_MGNT_GATE,
    270				ST21NFCA_EVT_SE_HARD_RESET, &param, 1);
    271	}
    272	info->se_info.cb(info->se_info.cb_context, NULL, 0, -ETIME);
    273}
    274
    275static void st21nfca_se_wt_timeout(struct timer_list *t)
    276{
    277	struct st21nfca_hci_info *info = from_timer(info, t, se_info.bwi_timer);
    278
    279	schedule_work(&info->se_info.timeout_work);
    280}
    281
    282static void st21nfca_se_activation_timeout(struct timer_list *t)
    283{
    284	struct st21nfca_hci_info *info = from_timer(info, t,
    285						    se_info.se_active_timer);
    286
    287	info->se_info.se_active = false;
    288
    289	complete(&info->se_info.req_completion);
    290}
    291
    292/*
    293 * Returns:
    294 * <= 0: driver handled the event, skb consumed
    295 *    1: driver does not handle the event, please do standard processing
    296 */
    297int st21nfca_connectivity_event_received(struct nfc_hci_dev *hdev, u8 host,
    298				u8 event, struct sk_buff *skb)
    299{
    300	int r = 0;
    301	struct device *dev = &hdev->ndev->dev;
    302	struct nfc_evt_transaction *transaction;
    303	u32 aid_len;
    304	u8 params_len;
    305
    306	pr_debug("connectivity gate event: %x\n", event);
    307
    308	switch (event) {
    309	case ST21NFCA_EVT_CONNECTIVITY:
    310		r = nfc_se_connectivity(hdev->ndev, host);
    311	break;
    312	case ST21NFCA_EVT_TRANSACTION:
    313		/* According to specification etsi 102 622
    314		 * 11.2.2.4 EVT_TRANSACTION Table 52
    315		 * Description	Tag	Length
    316		 * AID		81	5 to 16
    317		 * PARAMETERS	82	0 to 255
    318		 *
    319		 * The key differences are aid storage length is variably sized
    320		 * in the packet, but fixed in nfc_evt_transaction, and that the aid_len
    321		 * is u8 in the packet, but u32 in the structure, and the tags in
    322		 * the packet are not included in nfc_evt_transaction.
    323		 *
    324		 * size in bytes: 1          1       5-16 1             1           0-255
    325		 * offset:        0          1       2    aid_len + 2   aid_len + 3 aid_len + 4
    326		 * member name:   aid_tag(M) aid_len aid  params_tag(M) params_len  params
    327		 * example:       0x81       5-16    X    0x82 0-255    X
    328		 */
    329		if (skb->len < 2 || skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG)
    330			return -EPROTO;
    331
    332		aid_len = skb->data[1];
    333
    334		if (skb->len < aid_len + 4 || aid_len > sizeof(transaction->aid))
    335			return -EPROTO;
    336
    337		params_len = skb->data[aid_len + 3];
    338
    339		/* Verify PARAMETERS tag is (82), and final check that there is enough
    340		 * space in the packet to read everything.
    341		 */
    342		if ((skb->data[aid_len + 2] != NFC_EVT_TRANSACTION_PARAMS_TAG) ||
    343		    (skb->len < aid_len + 4 + params_len))
    344			return -EPROTO;
    345
    346		transaction = devm_kzalloc(dev, sizeof(*transaction) + params_len, GFP_KERNEL);
    347		if (!transaction)
    348			return -ENOMEM;
    349
    350		transaction->aid_len = aid_len;
    351		transaction->params_len = params_len;
    352
    353		memcpy(transaction->aid, &skb->data[2], aid_len);
    354		memcpy(transaction->params, &skb->data[aid_len + 4], params_len);
    355
    356		r = nfc_se_transaction(hdev->ndev, host, transaction);
    357	break;
    358	default:
    359		nfc_err(&hdev->ndev->dev, "Unexpected event on connectivity gate\n");
    360		return 1;
    361	}
    362	kfree_skb(skb);
    363	return r;
    364}
    365EXPORT_SYMBOL(st21nfca_connectivity_event_received);
    366
    367int st21nfca_apdu_reader_event_received(struct nfc_hci_dev *hdev,
    368					u8 event, struct sk_buff *skb)
    369{
    370	int r = 0;
    371	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
    372
    373	pr_debug("apdu reader gate event: %x\n", event);
    374
    375	switch (event) {
    376	case ST21NFCA_EVT_TRANSMIT_DATA:
    377		del_timer_sync(&info->se_info.bwi_timer);
    378		cancel_work_sync(&info->se_info.timeout_work);
    379		info->se_info.bwi_active = false;
    380		r = nfc_hci_send_event(hdev, ST21NFCA_DEVICE_MGNT_GATE,
    381				ST21NFCA_EVT_SE_END_OF_APDU_TRANSFER, NULL, 0);
    382		if (r < 0)
    383			goto exit;
    384
    385		info->se_info.cb(info->se_info.cb_context,
    386			skb->data, skb->len, 0);
    387		break;
    388	case ST21NFCA_EVT_WTX_REQUEST:
    389		mod_timer(&info->se_info.bwi_timer, jiffies +
    390				msecs_to_jiffies(info->se_info.wt_timeout));
    391		break;
    392	default:
    393		nfc_err(&hdev->ndev->dev, "Unexpected event on apdu reader gate\n");
    394		return 1;
    395	}
    396
    397exit:
    398	kfree_skb(skb);
    399	return r;
    400}
    401EXPORT_SYMBOL(st21nfca_apdu_reader_event_received);
    402
    403void st21nfca_se_init(struct nfc_hci_dev *hdev)
    404{
    405	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
    406
    407	init_completion(&info->se_info.req_completion);
    408	INIT_WORK(&info->se_info.timeout_work, st21nfca_se_wt_work);
    409	/* initialize timers */
    410	timer_setup(&info->se_info.bwi_timer, st21nfca_se_wt_timeout, 0);
    411	info->se_info.bwi_active = false;
    412
    413	timer_setup(&info->se_info.se_active_timer,
    414		    st21nfca_se_activation_timeout, 0);
    415	info->se_info.se_active = false;
    416
    417	info->se_info.count_pipes = 0;
    418	info->se_info.expected_pipes = 0;
    419
    420	info->se_info.xch_error = false;
    421
    422	info->se_info.wt_timeout =
    423			ST21NFCA_BWI_TO_TIMEOUT(ST21NFCA_ATR_DEFAULT_BWI);
    424}
    425EXPORT_SYMBOL(st21nfca_se_init);
    426
    427void st21nfca_se_deinit(struct nfc_hci_dev *hdev)
    428{
    429	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
    430
    431	if (info->se_info.bwi_active)
    432		del_timer_sync(&info->se_info.bwi_timer);
    433	if (info->se_info.se_active)
    434		del_timer_sync(&info->se_info.se_active_timer);
    435
    436	cancel_work_sync(&info->se_info.timeout_work);
    437	info->se_info.bwi_active = false;
    438	info->se_info.se_active = false;
    439}
    440EXPORT_SYMBOL(st21nfca_se_deinit);