1 // //-----------------------------------------------------------------------------
2 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // See LICENSE.txt for the text of the license.
15 //-----------------------------------------------------------------------------
16 // The main i2c code, for communications with smart card module
17 //-----------------------------------------------------------------------------
20 #include "proxmark3_arm.h"
28 #define GPIO_RST AT91C_PIO_PA1
29 #define GPIO_SCL AT91C_PIO_PA5
30 #define GPIO_SDA AT91C_PIO_PA7
32 #define SCL_H HIGH(GPIO_SCL)
33 #define SCL_L LOW(GPIO_SCL)
34 #define SDA_H HIGH(GPIO_SDA)
35 #define SDA_L LOW(GPIO_SDA)
37 #define SCL_read ((AT91C_BASE_PIOA->PIO_PDSR & GPIO_SCL) == GPIO_SCL)
38 #define SDA_read ((AT91C_BASE_PIOA->PIO_PDSR & GPIO_SDA) == GPIO_SDA)
40 #define I2C_ERROR "I2C_WaitAck Error"
42 // Direct use the loop to delay. 6 instructions loop, Masterclock 48MHz,
43 // delay=1 is about 200kbps
45 // I2CSpinDelayClk(4) = 12.31us
46 // I2CSpinDelayClk(1) = 3.07us
47 static volatile uint32_t c
;
48 static void __attribute__((optimize("O0"))) I2CSpinDelayClk(uint16_t delay
) {
49 for (c
= delay
* 2; c
; c
--) {};
52 #define I2C_DELAY_1CLK I2CSpinDelayClk(1)
53 #define I2C_DELAY_2CLK I2CSpinDelayClk(2)
54 #define I2C_DELAY_XCLK(x) I2CSpinDelayClk((x))
56 // try i2c bus recovery at 100kHz = 5us high, 5us low
57 void I2C_recovery(void) {
59 DbpString("Performing i2c bus recovery");
65 //9nth cycle acts as NACK
66 for (int i
= 0; i
< 10; i
++) {
73 //a STOP signal (SDA from low to high while CLK is high)
82 bool isok
= (SCL_read
&& SDA_read
);
84 DbpString("I2C bus recovery error: SDA still LOW");
86 DbpString("I2C bus recovery error: SCL still LOW");
88 DbpString("I2C bus recovery complete");
91 void I2C_init(bool has_ticks
) {
92 // Configure reset pin, close up pull up, push-pull output, default high
93 AT91C_BASE_PIOA
->PIO_PPUDR
= GPIO_RST
;
94 AT91C_BASE_PIOA
->PIO_MDDR
= GPIO_RST
;
96 // Configure I2C pin, open up, open leakage
97 AT91C_BASE_PIOA
->PIO_PPUER
|= (GPIO_SCL
| GPIO_SDA
);
98 AT91C_BASE_PIOA
->PIO_MDER
|= (GPIO_SCL
| GPIO_SDA
);
100 // default three lines all pull up
101 AT91C_BASE_PIOA
->PIO_SODR
|= (GPIO_SCL
| GPIO_SDA
| GPIO_RST
);
103 AT91C_BASE_PIOA
->PIO_OER
|= (GPIO_SCL
| GPIO_SDA
| GPIO_RST
);
104 AT91C_BASE_PIOA
->PIO_PER
|= (GPIO_SCL
| GPIO_SDA
| GPIO_RST
);
110 bool isok
= (SCL_read
&& SDA_read
);
115 // set the reset state
116 void I2C_SetResetStatus(uint8_t LineRST
, uint8_t LineSCK
, uint8_t LineSDA
) {
133 // Reset the SIM_Adapter, then enter the main program
134 // Note: the SIM_Adapter will not enter the main program after power up. Please run this function before use SIM_Adapter.
135 void I2C_Reset_EnterMainProgram(void) {
138 I2C_SetResetStatus(0, 0, 0);
140 I2C_SetResetStatus(1, 0, 0);
142 I2C_SetResetStatus(1, 1, 1);
146 // Reset the SIM_Adapter, then enter the bootloader program
147 // Reserve for firmware update.
148 void I2C_Reset_EnterBootloader(void) {
151 I2C_SetResetStatus(0, 1, 1);
153 I2C_SetResetStatus(1, 1, 1);
157 // Wait for the clock to go High.
158 static bool WaitSCL_H_delay(uint32_t delay
) {
168 // 5000 * 3.07us = 15350 us = 15.35 ms
169 // 15000 * 3.07us = 46050 us = 46.05 ms
170 static bool WaitSCL_H(void) {
171 return WaitSCL_H_delay(5000);
174 static bool WaitSCL_L_delay(uint32_t delay
) {
176 if (SCL_read
== false) {
184 // 5000 * 3.07us = 15350us. 15.35ms
185 // 15000 * 3.07us = 46050us. 46.05ms
186 static bool WaitSCL_L(void) {
187 return WaitSCL_L_delay(5000);
190 // Wait max 1800ms or until SCL goes LOW.
191 // It timeout reading response from card
192 // Which ever comes first
193 static bool WaitSCL_L_timeout(void) {
194 volatile uint32_t delay
= 1200;
197 if (SCL_read
== false)
205 static bool I2C_Start(void) {
212 if (WaitSCL_H() == false) {
218 if (SCL_read
== false) {
222 if (SDA_read
== false) {
231 static bool I2C_WaitForSim(uint32_t wait
) {
233 // wait for data from card
234 if (WaitSCL_L_timeout() == false) {
238 // 8051 speaks with smart card.
239 // 1000*50*3.07 = 153.5ms
240 // 1000*110*3.07 = 337.7ms (337700)
241 // 4 560 000 * 3.07 = 13999,2ms (13999200)
242 // 1byte transfer == 1ms with max frame being 256bytes
244 // fct WaitSCL_H_delay uses a I2C_DELAY_1CLK in the loop with "wait" as number of iterations.
245 // I2C_DELAY_1CLK == I2CSpinDelayClk(1) = 3.07us
246 return WaitSCL_H_delay(wait
);
250 static void I2C_Stop(void) {
258 if (WaitSCL_H() == false) {
270 static void I2C_Ack(void) {
278 if (WaitSCL_H() == false) {
287 static void I2C_NoAck(void) {
295 if (WaitSCL_H() == false) {
303 static bool I2C_WaitAck(void) {
310 if (WaitSCL_H() == false) {
324 static void I2C_SendByte(uint8_t data
) {
343 if (WaitSCL_H() == false) {
352 static int16_t I2C_ReadByte(void) {
353 uint8_t bits
= 8, b
= 0;
360 if (WaitSCL_L() == false) {
366 if (WaitSCL_H() == false) {
379 // Sends one byte (command to be written, SlaveDevice address)
380 bool I2C_WriteCmd(uint8_t device_cmd
, uint8_t device_address
) {
383 if (I2C_Start() == false) {
387 I2C_SendByte(device_address
& 0xFE);
388 if (I2C_WaitAck() == false) {
392 I2C_SendByte(device_cmd
);
393 if (I2C_WaitAck() == false) {
404 if (g_dbglevel
> 3) DbpString(I2C_ERROR
);
411 // Sends 1 byte data (data to be written, command to be written , SlaveDevice address)
412 bool I2C_WriteByte(uint8_t data
, uint8_t device_cmd
, uint8_t device_address
) {
415 if (I2C_Start() == false) {
419 I2C_SendByte(device_address
& 0xFE);
420 if (I2C_WaitAck() == false) {
424 I2C_SendByte(device_cmd
);
425 if (I2C_WaitAck() == false) {
430 if (I2C_WaitAck() == false) {
439 if (g_dbglevel
> 3) DbpString(I2C_ERROR
);
445 // Sends array of data (array, length, command to be written , SlaveDevice address)
446 // len = uint16 because we need to write up to 256 bytes
447 bool I2C_BufferWrite(const uint8_t *data
, uint16_t len
, uint8_t device_cmd
, uint8_t device_address
) {
450 if (I2C_Start() == false) {
454 I2C_SendByte(device_address
& 0xFE);
455 if (I2C_WaitAck() == false) {
459 I2C_SendByte(device_cmd
);
460 if (I2C_WaitAck() == false) {
467 if (I2C_WaitAck() == false)
482 if (g_dbglevel
> 3) DbpString(I2C_ERROR
);
488 // read one array of data (Data array, Readout length, command to be written , SlaveDevice address ).
489 // len = uint16 because we need to read up to 256bytes
490 int16_t I2C_BufferRead(uint8_t *data
, uint16_t len
, uint8_t device_cmd
, uint8_t device_address
) {
493 if (data
== NULL
|| len
== 0) {
497 // uint8_t *pd = data;
499 // extra wait 500us (514us measured)
500 // 200us (xx measured)
506 if (I2C_Start() == false) {
510 // 0xB0 / 0xC0 == i2c write
511 I2C_SendByte(device_address
& 0xFE);
512 if (I2C_WaitAck() == false) {
516 I2C_SendByte(device_cmd
);
517 if (I2C_WaitAck() == false) {
521 // 0xB1 / 0xC1 == i2c read
523 I2C_SendByte(device_address
| 1);
524 if (I2C_WaitAck() == false) {
533 if (g_dbglevel
> 3) DbpString(I2C_ERROR
);
537 uint16_t readcount
= 0;
538 uint16_t recv_len
= 0;
542 int16_t tmp
= I2C_ReadByte();
547 *data
= (uint8_t)tmp
& 0xFF;
551 // Starting firmware v4 the length is encoded on the first two bytes.
555 recv_len
= (*data
) << 8;
563 if (recv_len
> 0x0200) {
570 // Adjust len if needed
571 if (len
> recv_len
) {
577 // Data byte received
585 // acknowledgements. After last byte send NACK.
595 // Dbprintf("rec len... %u readcount... %u", recv_len, readcount);
596 // Dbhexdump(readcount, pd, false);
602 // return bytecount - bytes encoding length
603 return readcount
- 2;
606 int16_t I2C_ReadFW(uint8_t *data
, uint8_t len
, uint8_t msb
, uint8_t lsb
, uint8_t device_address
) {
607 //START, 0xB0, 0x00, 0x00, START, 0xB1, xx, yy, zz, ......, STOP
609 uint8_t readcount
= 0;
613 if (I2C_Start() == false) {
617 // 0xB0 / 0xC0 i2c write
618 I2C_SendByte(device_address
& 0xFE);
619 if (I2C_WaitAck() == false)
623 if (I2C_WaitAck() == false) {
628 if (I2C_WaitAck() == false) {
632 // 0xB1 / 0xC1 i2c read
634 I2C_SendByte(device_address
| 1);
635 if (I2C_WaitAck() == false) {
644 if (g_dbglevel
> 3) DbpString(I2C_ERROR
);
651 int16_t tmp
= I2C_ReadByte();
656 *data
= (uint8_t)tmp
& 0xFF;
662 // acknowledgements. After last byte send NACK.
673 bool I2C_WriteFW(const uint8_t *data
, uint8_t len
, uint8_t msb
, uint8_t lsb
, uint8_t device_address
) {
674 //START, 0xB0, 0x00, 0x00, xx, yy, zz, ......, STOP
678 if (I2C_Start() == false) {
683 I2C_SendByte(device_address
& 0xFE);
684 if (I2C_WaitAck() == false) {
689 if (I2C_WaitAck() == false) {
694 if (I2C_WaitAck() == false) {
700 if (I2C_WaitAck() == false) {
716 if (g_dbglevel
> 3) DbpString(I2C_ERROR
);
722 void I2C_print_status(void) {
723 DbpString(_CYAN_("Smart card module (ISO 7816)"));
725 uint8_t major
, minor
;
726 if (I2C_get_version(&major
, &minor
) == PM3_SUCCESS
) {
728 Dbprintf(" version................. v%d.%02d ( %s )"
731 , ((major
== 4) && (minor
== 42)) ? _GREEN_("ok") : _RED_("Outdated")
734 DbpString(" version................. ( " _RED_("fail") " )");
738 int I2C_get_version(uint8_t *major
, uint8_t *minor
) {
739 uint8_t resp
[] = {0, 0, 0, 0};
740 I2C_Reset_EnterMainProgram();
741 uint8_t len
= I2C_BufferRead(resp
, sizeof(resp
), I2C_DEVICE_CMD_GETVERSION
, I2C_DEVICE_ADDRESS_MAIN
);
747 return PM3_EDEVNOTSUPP
;
750 // Will read response from smart card module, retries 3 times to get the data.
751 bool sc_rx_bytes(uint8_t *dest
, uint16_t *destlen
, uint32_t wait
) {
757 I2C_WaitForSim(wait
);
759 len
= I2C_BufferRead(dest
, *destlen
, I2C_DEVICE_CMD_READ
, I2C_DEVICE_ADDRESS_MAIN
);
765 } else if (len
== 1) {
780 bool GetATR(smart_card_atr_t
*card_ptr
, bool verbose
) {
782 if (card_ptr
== NULL
) {
787 card_ptr
->atr_len
= 0;
788 memset(card_ptr
->atr
, 0, sizeof(card_ptr
->atr
));
791 // start [C0 01] stop start C1 len aa bb cc stop]
792 I2C_WriteCmd(I2C_DEVICE_CMD_GENERATE_ATR
, I2C_DEVICE_ADDRESS_MAIN
);
794 // wait for sim card to answer.
795 // 1byte = 1ms , max frame 256bytes. Should wait 256ms atleast just in case.
796 if (I2C_WaitForSim(SIM_WAIT_DELAY
) == false) {
800 // read bytes from module
801 uint16_t len
= sizeof(card_ptr
->atr
);
802 if (sc_rx_bytes(card_ptr
->atr
, &len
, SIM_WAIT_DELAY
) == false) {
806 if (len
> sizeof(card_ptr
->atr
)) {
807 len
= sizeof(card_ptr
->atr
);
811 if ((card_ptr
->atr
[1] & 0x10) == 0x10) pos_td
++;
812 if ((card_ptr
->atr
[1] & 0x20) == 0x20) pos_td
++;
813 if ((card_ptr
->atr
[1] & 0x40) == 0x40) pos_td
++;
815 // T0 indicate presence T=0 vs T=1. T=1 has checksum TCK
816 if ((card_ptr
->atr
[1] & 0x80) == 0x80) {
820 // 1 == T1 , presence of checksum TCK
821 if ((card_ptr
->atr
[pos_td
] & 0x01) == 0x01) {
824 // xor property. will be zero when xored with chksum.
825 for (uint16_t i
= 1; i
< len
; ++i
)
826 chksum
^= card_ptr
->atr
[i
];
829 if (g_dbglevel
> 2) DbpString("Wrong ATR checksum");
834 card_ptr
->atr_len
= (uint8_t)(len
& 0xff);
836 LogTrace(card_ptr
->atr
, card_ptr
->atr_len
, 0, 0, NULL
, false);
842 void SmartCardAtr(void) {
845 I2C_Reset_EnterMainProgram();
846 smart_card_atr_t card
;
847 if (GetATR(&card
, true)) {
848 reply_ng(CMD_SMART_ATR
, PM3_SUCCESS
, (uint8_t *)&card
, sizeof(smart_card_atr_t
));
850 reply_ng(CMD_SMART_ATR
, PM3_ETIMEOUT
, NULL
, 0);
857 void SmartCardRaw(const smart_card_raw_t
*p
) {
861 uint8_t *resp
= BigBuf_malloc(ISO7816_MAX_FRAME
);
862 // check if alloacted...
863 smartcard_command_t flags
= p
->flags
;
865 if ((flags
& SC_CLEARLOG
) == SC_CLEARLOG
)
868 if ((flags
& SC_LOG
) == SC_LOG
)
873 if ((flags
& SC_CONNECT
) == SC_CONNECT
) {
875 I2C_Reset_EnterMainProgram();
877 if ((flags
& SC_SELECT
) == SC_SELECT
) {
878 smart_card_atr_t card
;
879 bool gotATR
= GetATR(&card
, true);
880 //reply_old(CMD_ACK, gotATR, sizeof(smart_card_atr_t), 0, &card, sizeof(smart_card_atr_t));
881 if (gotATR
== false) {
882 reply_ng(CMD_SMART_RAW
, PM3_ESOFT
, NULL
, 0);
888 if (((flags
& SC_RAW
) == SC_RAW
) || ((flags
& SC_RAW_T0
) == SC_RAW_T0
)) {
890 uint32_t wait
= SIM_WAIT_DELAY
;
891 if ((flags
& SC_WAIT
) == SC_WAIT
) {
892 wait
= (uint32_t)((p
->wait_delay
* 1000) / 3.07);
895 LogTrace(p
->data
, p
->len
, 0, 0, NULL
, true);
897 bool res
= I2C_BufferWrite(
900 (((flags
& SC_RAW_T0
) == SC_RAW_T0
) ? I2C_DEVICE_CMD_SEND_T0
: I2C_DEVICE_CMD_SEND
),
901 I2C_DEVICE_ADDRESS_MAIN
904 if (res
== false && g_dbglevel
> 3) {
905 DbpString(I2C_ERROR
);
906 reply_ng(CMD_SMART_RAW
, PM3_ESOFT
, NULL
, 0);
910 // read bytes from module
911 len
= ISO7816_MAX_FRAME
;
912 res
= sc_rx_bytes(resp
, &len
, wait
);
914 LogTrace(resp
, len
, 0, 0, NULL
, false);
920 reply_ng(CMD_SMART_RAW
, PM3_SUCCESS
, resp
, len
);
928 void SmartCardUpgrade(uint64_t arg0
) {
932 #define I2C_BLOCK_SIZE 128
933 // write. Sector0, with 11,22,33,44
934 // erase is 128bytes, and takes 50ms to execute
936 I2C_Reset_EnterBootloader();
939 uint16_t length
= arg0
, pos
= 0;
940 const uint8_t *fwdata
= BigBuf_get_addr();
941 uint8_t *verfiydata
= BigBuf_malloc(I2C_BLOCK_SIZE
);
945 uint8_t msb
= (pos
>> 8) & 0xFF;
946 uint8_t lsb
= pos
& 0xFF;
948 Dbprintf("FW %02X%02X", msb
, lsb
);
950 size_t size
= MIN(I2C_BLOCK_SIZE
, length
);
953 int16_t res
= I2C_WriteFW(fwdata
+ pos
, size
, msb
, lsb
, I2C_DEVICE_ADDRESS_BOOT
);
955 DbpString("Writing failed");
960 // writing takes time.
964 res
= I2C_ReadFW(verfiydata
, size
, msb
, lsb
, I2C_DEVICE_ADDRESS_BOOT
);
966 DbpString("Reading back failed");
972 if (0 != memcmp(fwdata
+ pos
, verfiydata
, size
)) {
973 DbpString("not equal data");
982 reply_ng(CMD_SMART_UPGRADE
, (isOK
) ? PM3_SUCCESS
: PM3_ESOFT
, NULL
, 0);
987 void SmartCardSetBaud(uint64_t arg0
) {
990 void SmartCardSetClock(uint64_t arg0
) {
993 I2C_Reset_EnterMainProgram();
995 // start [C0 05 xx] stop
996 I2C_WriteByte(arg0
, I2C_DEVICE_CMD_SIM_CLC
, I2C_DEVICE_ADDRESS_MAIN
);
997 reply_ng(CMD_SMART_SETCLOCK
, PM3_SUCCESS
, NULL
, 0);