Kévin Redon | 45ad62d | 2018-06-07 18:56:41 +0200 | [diff] [blame] | 1 | /* |
| 2 | * (C) 2010-2017 by Harald Welte <hwelte@sysmocom.de> |
| 3 | * (C) 2018 by Kevin Redon <kredon@sysmocom.de> |
| 4 | * All Rights Reserved |
Christina Quast | a90eefa | 2015-02-24 17:52:29 +0100 | [diff] [blame] | 5 | * |
Kévin Redon | 45ad62d | 2018-06-07 18:56:41 +0200 | [diff] [blame] | 6 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU Affero General Public License as published by |
| 8 | * the Free Software Foundation; either version 3 of the License, or |
| 9 | * (at your option) any later version. |
Christina Quast | a90eefa | 2015-02-24 17:52:29 +0100 | [diff] [blame] | 10 | * |
Kévin Redon | 45ad62d | 2018-06-07 18:56:41 +0200 | [diff] [blame] | 11 | * This program is distributed in the hope that it will be useful, |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | * GNU Affero General Public License for more details. |
Christina Quast | a90eefa | 2015-02-24 17:52:29 +0100 | [diff] [blame] | 15 | * |
Kévin Redon | 45ad62d | 2018-06-07 18:56:41 +0200 | [diff] [blame] | 16 | * You should have received a copy of the GNU Affero General Public License |
| 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
Christina Quast | a90eefa | 2015-02-24 17:52:29 +0100 | [diff] [blame] | 18 | * |
Christina Quast | a90eefa | 2015-02-24 17:52:29 +0100 | [diff] [blame] | 19 | */ |
Kévin Redon | d7a6de5 | 2018-06-11 13:46:35 +0200 | [diff] [blame^] | 20 | /* This code implement the Sniffer mode to sniff the communication between a SIM card and a phone. |
| 21 | * For historical reasons (i.e. SIMtrace hardware) the USART peripheral connected to the SIM card is used. |
| 22 | */ |
Kévin Redon | 36abece | 2018-06-04 16:30:01 +0200 | [diff] [blame] | 23 | #include "board.h" |
| 24 | #include "simtrace.h" |
| 25 | |
Harald Welte | 2fb5996 | 2016-02-28 12:34:26 +0100 | [diff] [blame] | 26 | #ifdef HAVE_SNIFFER |
| 27 | |
Christina Quast | a90eefa | 2015-02-24 17:52:29 +0100 | [diff] [blame] | 28 | /*------------------------------------------------------------------------------ |
| 29 | * Headers |
| 30 | *------------------------------------------------------------------------------*/ |
| 31 | |
Christina Quast | a90eefa | 2015-02-24 17:52:29 +0100 | [diff] [blame] | 32 | #include <string.h> |
| 33 | |
| 34 | /*------------------------------------------------------------------------------ |
| 35 | * Internal definitions |
| 36 | *------------------------------------------------------------------------------*/ |
| 37 | |
| 38 | /** Maximum ucSize in bytes of the smartcard answer to a command.*/ |
| 39 | #define MAX_ANSWER_SIZE 10 |
| 40 | |
Kévin Redon | d7a6de5 | 2018-06-11 13:46:35 +0200 | [diff] [blame^] | 41 | /*! Maximum Answer-To-Reset (ATR) size in bytes ucSize in bytes |
| 42 | * @note defined in ISO/IEC 7816-3:2006(E) section 8.2.1 as 32, on top the initial character TS of section 8.1 |
| 43 | * @remark technical there is no size limitation since Yi present in T0,TDi will indicate if more interface bytes are present, including TDi+i |
| 44 | */ |
| 45 | #define MAX_ATR_SIZE 33 |
| 46 | |
| 47 | /*! ISO 7816-3 states relevant to the sniff mode */ |
| 48 | enum iso7816_3_sniff_state { |
| 49 | ISO7816_S_RESET, /*!< in Reset */ |
| 50 | ISO7816_S_WAIT_ATR, /*!< waiting for ATR to start */ |
| 51 | ISO7816_S_IN_ATR, /*!< while we are receiving the ATR */ |
| 52 | ISO7816_S_WAIT_APDU, /*!< waiting for start of new APDU */ |
| 53 | ISO7816_S_IN_APDU, /*!< inside a single APDU */ |
| 54 | ISO7816_S_IN_PTS, /*!< while we are inside the PTS / PSS */ |
| 55 | }; |
| 56 | |
| 57 | /*! Answer-To-Reset (ATR) sub-states of ISO7816_S_IN_ATR |
| 58 | * @note defined in ISO/IEC 7816-3:2006(E) section 8 |
| 59 | */ |
| 60 | enum atr_sniff_state { |
| 61 | ATR_S_WAIT_TS, /*!< initial byte */ |
| 62 | ATR_S_WAIT_T0, /*!< format byte */ |
| 63 | ATR_S_WAIT_TA, /*!< first sub-group interface byte */ |
| 64 | ATR_S_WAIT_TB, /*!< second sub-group interface byte */ |
| 65 | ATR_S_WAIT_TC, /*!< third sub-group interface byte */ |
| 66 | ATR_S_WAIT_TD, /*!< fourth sub-group interface byte */ |
| 67 | ATR_S_WAIT_HIST, /*!< historical byte */ |
| 68 | ATR_S_WAIT_TCK, /*!< check byte */ |
| 69 | ATR_S_DONE, /*!< to indicated all ATR bytes have been received */ |
| 70 | }; |
Kévin Redon | 45ad62d | 2018-06-07 18:56:41 +0200 | [diff] [blame] | 71 | |
Christina Quast | a90eefa | 2015-02-24 17:52:29 +0100 | [diff] [blame] | 72 | /*------------------------------------------------------------------------------ |
| 73 | * Internal variables |
| 74 | *------------------------------------------------------------------------------*/ |
Kévin Redon | d7a6de5 | 2018-06-11 13:46:35 +0200 | [diff] [blame^] | 75 | |
| 76 | /* note: the sniffer code is currently designed to support only one sniffing interface, but the hardware would support a second one. |
| 77 | * to support a second sniffer interface the code should be restructured to use handles. |
| 78 | */ |
| 79 | /* Pin configurations */ |
| 80 | /* Pin configuration to sniff communication (using USART connection card) */ |
Kévin Redon | ee62a9d | 2018-06-11 13:42:23 +0200 | [diff] [blame] | 81 | static const Pin pins_sniff[] = { PINS_SIM_SNIFF }; |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 82 | static const Pin pins_bus[] = { PINS_BUS_SNIFF }; |
Kévin Redon | d7a6de5 | 2018-06-11 13:46:35 +0200 | [diff] [blame^] | 83 | static const Pin pins_power[] = { PINS_PWR_SNIFF }; |
Kévin Redon | 45ad62d | 2018-06-07 18:56:41 +0200 | [diff] [blame] | 84 | static const Pin pins_tc[] = { PINS_TC }; |
Kévin Redon | d7a6de5 | 2018-06-11 13:46:35 +0200 | [diff] [blame^] | 85 | /* USART related variables */ |
Kévin Redon | 45ad62d | 2018-06-07 18:56:41 +0200 | [diff] [blame] | 86 | /* USART peripheral used to sniff communication */ |
| 87 | static struct Usart_info sniff_usart = { |
| 88 | .base = USART_SIM, |
| 89 | .id = ID_USART_SIM, |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 90 | .state = USART_RCV, |
| 91 | }; |
Kévin Redon | 7b73462 | 2018-06-06 16:13:48 +0200 | [diff] [blame] | 92 | /* Ring buffer to store sniffer communication data */ |
| 93 | static struct ringbuf sniff_buffer; |
| 94 | |
| 95 | /*------------------------------------------------------------------------------ |
Kévin Redon | 7b73462 | 2018-06-06 16:13:48 +0200 | [diff] [blame] | 96 | * Internal functions |
| 97 | *------------------------------------------------------------------------------*/ |
Kévin Redon | 36abece | 2018-06-04 16:30:01 +0200 | [diff] [blame] | 98 | |
Kévin Redon | 45ad62d | 2018-06-07 18:56:41 +0200 | [diff] [blame] | 99 | static void check_sniffed_data(void) |
Kévin Redon | 36abece | 2018-06-04 16:30:01 +0200 | [diff] [blame] | 100 | { |
Kévin Redon | 7b73462 | 2018-06-06 16:13:48 +0200 | [diff] [blame] | 101 | /* Display sniffed data */ |
| 102 | while (!rbuf_is_empty(&sniff_buffer)) { |
| 103 | uint8_t byte = rbuf_read(&sniff_buffer); |
| 104 | TRACE_INFO_WP("0x%02x ", byte); |
| 105 | } |
Kévin Redon | 36abece | 2018-06-04 16:30:01 +0200 | [diff] [blame] | 106 | } |
| 107 | |
Kévin Redon | d7a6de5 | 2018-06-11 13:46:35 +0200 | [diff] [blame^] | 108 | /*! Interrupt Service Routine called on USART activity */ |
| 109 | void Sniffer_usart_irq(void) |
| 110 | { |
| 111 | /* Read channel status register */ |
| 112 | uint32_t csr = sniff_usart.base->US_CSR & sniff_usart.base->US_IMR; |
| 113 | /* Verify if character has been received */ |
| 114 | if (csr & US_CSR_RXRDY) { |
| 115 | /* Read communication data byte between phone and SIM */ |
| 116 | uint8_t byte = sniff_usart.base->US_RHR; |
| 117 | /* Store sniffed data into buffer (also clear interrupt */ |
| 118 | rbuf_write(&sniff_buffer, byte); |
| 119 | } |
| 120 | } |
| 121 | |
| 122 | /*------------------------------------------------------------------------------ |
| 123 | * Global functions |
| 124 | *------------------------------------------------------------------------------*/ |
| 125 | |
| 126 | void Sniffer_usart1_irq(void) |
| 127 | { |
| 128 | if (ID_USART1==sniff_usart.id) { |
| 129 | Sniffer_usart_irq(); |
| 130 | } |
| 131 | } |
| 132 | |
| 133 | void Sniffer_usart0_irq(void) |
| 134 | { |
| 135 | if (ID_USART0==sniff_usart.id) { |
| 136 | Sniffer_usart_irq(); |
| 137 | } |
| 138 | } |
| 139 | |
Christina Quast | a90eefa | 2015-02-24 17:52:29 +0100 | [diff] [blame] | 140 | /*----------------------------------------------------------------------------- |
Christina Quast | d2b05f0 | 2015-02-25 18:44:24 +0100 | [diff] [blame] | 141 | * Initialization routine |
Christina Quast | a90eefa | 2015-02-24 17:52:29 +0100 | [diff] [blame] | 142 | *-----------------------------------------------------------------------------*/ |
Christina Quast | a90eefa | 2015-02-24 17:52:29 +0100 | [diff] [blame] | 143 | |
Harald Welte | ed75c62 | 2017-11-28 21:23:12 +0100 | [diff] [blame] | 144 | /* Called during USB enumeration after device is enumerated by host */ |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 145 | void Sniffer_configure(void) |
Christina Quast | a90eefa | 2015-02-24 17:52:29 +0100 | [diff] [blame] | 146 | { |
Kévin Redon | 36abece | 2018-06-04 16:30:01 +0200 | [diff] [blame] | 147 | TRACE_INFO("Sniffer config\n\r"); |
Christina Quast | a90eefa | 2015-02-24 17:52:29 +0100 | [diff] [blame] | 148 | } |
Christina Quast | fb524b9 | 2015-02-27 13:39:45 +0100 | [diff] [blame] | 149 | |
Harald Welte | ed75c62 | 2017-11-28 21:23:12 +0100 | [diff] [blame] | 150 | /* called when *different* configuration is set by host */ |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 151 | void Sniffer_exit(void) |
Christina Quast | fb524b9 | 2015-02-27 13:39:45 +0100 | [diff] [blame] | 152 | { |
Kévin Redon | 36abece | 2018-06-04 16:30:01 +0200 | [diff] [blame] | 153 | TRACE_INFO("Sniffer exit\n\r"); |
Kévin Redon | 45ad62d | 2018-06-07 18:56:41 +0200 | [diff] [blame] | 154 | USART_DisableIt(sniff_usart.base, US_IER_RXRDY); |
| 155 | /* NOTE: don't forget to set the IRQ according to the USART peripheral used */ |
| 156 | NVIC_DisableIRQ(USART0_IRQn); |
| 157 | USART_SetReceiverEnabled(sniff_usart.base, 0); |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 158 | } |
| 159 | |
Kévin Redon | 36abece | 2018-06-04 16:30:01 +0200 | [diff] [blame] | 160 | /* called when *Sniffer* configuration is set by host */ |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 161 | void Sniffer_init(void) |
| 162 | { |
Kévin Redon | 36abece | 2018-06-04 16:30:01 +0200 | [diff] [blame] | 163 | TRACE_INFO("Sniffer Init\n\r"); |
Kévin Redon | 7b73462 | 2018-06-06 16:13:48 +0200 | [diff] [blame] | 164 | |
Kévin Redon | 45ad62d | 2018-06-07 18:56:41 +0200 | [diff] [blame] | 165 | /* Configure pins to sniff communication between phone and card */ |
| 166 | PIO_Configure(pins_sniff, PIO_LISTSIZE(pins_sniff)); |
| 167 | /* Configure pins to connect phone to card */ |
| 168 | PIO_Configure(pins_bus, PIO_LISTSIZE(pins_bus)); |
| 169 | /* Configure pins to forward phone power to card */ |
| 170 | PIO_Configure(pins_power, PIO_LISTSIZE(pins_power)); |
| 171 | |
Kévin Redon | 7b73462 | 2018-06-06 16:13:48 +0200 | [diff] [blame] | 172 | /* Clear ring buffer containing the sniffed data */ |
| 173 | rbuf_reset(&sniff_buffer); |
Kévin Redon | 45ad62d | 2018-06-07 18:56:41 +0200 | [diff] [blame] | 174 | /* Configure USART to as ISO-7816 slave communication to sniff communication */ |
| 175 | ISO7816_Init(&sniff_usart, CLK_SLAVE); |
| 176 | /* Only receive data when sniffing */ |
| 177 | USART_SetReceiverEnabled(sniff_usart.base, 1); |
| 178 | /* Enable interrupt to indicate when data has been received */ |
| 179 | USART_EnableIt(sniff_usart.base, US_IER_RXRDY); |
Kévin Redon | d7a6de5 | 2018-06-11 13:46:35 +0200 | [diff] [blame^] | 180 | /* Enable interrupt requests for the USART peripheral */ |
| 181 | NVIC_EnableIRQ(IRQ_USART_SIM); |
| 182 | |
| 183 | /* TODO configure RST pin ISR */ |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 184 | } |
| 185 | |
Harald Welte | ed75c62 | 2017-11-28 21:23:12 +0100 | [diff] [blame] | 186 | /* main (idle/busy) loop of this USB configuration */ |
Harald Welte | 7dd3dfd | 2016-03-03 12:32:04 +0100 | [diff] [blame] | 187 | void Sniffer_run(void) |
| 188 | { |
Kévin Redon | 45ad62d | 2018-06-07 18:56:41 +0200 | [diff] [blame] | 189 | check_sniffed_data(); |
Christina Quast | fb524b9 | 2015-02-27 13:39:45 +0100 | [diff] [blame] | 190 | } |
Harald Welte | 2fb5996 | 2016-02-28 12:34:26 +0100 | [diff] [blame] | 191 | #endif /* HAVE_SNIFFER */ |