autodetect passive nfc operation or usb operation
This commit is contained in:
parent
e2ca7f52db
commit
e8d0ad5e7c
@ -1536,7 +1536,7 @@ static void ctap_state_init()
|
|||||||
ctap_reset_rk();
|
ctap_reset_rk();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ctap_init(int init_pin)
|
void ctap_init()
|
||||||
{
|
{
|
||||||
crypto_ecc256_init();
|
crypto_ecc256_init();
|
||||||
|
|
||||||
@ -1591,7 +1591,7 @@ void ctap_init(int init_pin)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (init_pin)
|
if (! device_is_nfc())
|
||||||
{
|
{
|
||||||
crypto_ecc256_make_key_pair(KEY_AGREEMENT_PUB, KEY_AGREEMENT_PRIV);
|
crypto_ecc256_make_key_pair(KEY_AGREEMENT_PUB, KEY_AGREEMENT_PRIV);
|
||||||
}
|
}
|
||||||
|
@ -267,7 +267,7 @@ uint8_t ctap_request(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp);
|
|||||||
int ctap_encode_der_sig(uint8_t const * const in_sigbuf, uint8_t * const out_sigder);
|
int ctap_encode_der_sig(uint8_t const * const in_sigbuf, uint8_t * const out_sigder);
|
||||||
|
|
||||||
// Run ctap related power-up procedures (init pinToken, generate shared secret)
|
// Run ctap related power-up procedures (init pinToken, generate shared secret)
|
||||||
void ctap_init(int init_pin);
|
void ctap_init();
|
||||||
|
|
||||||
// Resets state between different accesses of different applications
|
// Resets state between different accesses of different applications
|
||||||
void ctap_reset_state();
|
void ctap_reset_state();
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
|
#include "nfc.h"
|
||||||
|
|
||||||
static void flush_rx()
|
static void flush_rx()
|
||||||
{
|
{
|
||||||
@ -269,11 +270,8 @@ void ams_print_int1(uint8_t int0)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ams_init()
|
||||||
bool ams_init()
|
|
||||||
{
|
{
|
||||||
uint8_t block[4];
|
|
||||||
|
|
||||||
LL_GPIO_SetPinMode(SOLO_AMS_CS_PORT,SOLO_AMS_CS_PIN,LL_GPIO_MODE_OUTPUT);
|
LL_GPIO_SetPinMode(SOLO_AMS_CS_PORT,SOLO_AMS_CS_PIN,LL_GPIO_MODE_OUTPUT);
|
||||||
LL_GPIO_SetOutputPin(SOLO_AMS_CS_PORT,SOLO_AMS_CS_PIN);
|
LL_GPIO_SetOutputPin(SOLO_AMS_CS_PORT,SOLO_AMS_CS_PIN);
|
||||||
|
|
||||||
@ -284,85 +282,85 @@ bool ams_init()
|
|||||||
|
|
||||||
// delay(10);
|
// delay(10);
|
||||||
SELECT();
|
SELECT();
|
||||||
delay(2);
|
delay(1);
|
||||||
|
}
|
||||||
|
|
||||||
// Needs to be disabled for passive operation
|
void ams_configure()
|
||||||
if (0)
|
{
|
||||||
// if (1)
|
// Should not be used during passive operation.
|
||||||
|
uint8_t block[4];
|
||||||
|
|
||||||
|
// check connection
|
||||||
|
uint8_t productType = ams_read_reg(AMS_REG_PRODUCT_TYPE);
|
||||||
|
if (productType != 0x14)
|
||||||
{
|
{
|
||||||
// check connection
|
printf1(TAG_ERR, "Have wrong product type [0x%02x]. AMS3956 connection error.\n", productType);
|
||||||
uint8_t productType = ams_read_reg(AMS_REG_PRODUCT_TYPE);
|
}
|
||||||
if (productType != 0x14)
|
|
||||||
{
|
|
||||||
printf1(TAG_NFC, "Have wrong product type [0x%02x]. AMS3956 connection error.\n", productType);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf1(TAG_NFC,"AMS3956 product type 0x%02x.\n", productType);
|
printf1(TAG_NFC,"AMS3956 product type 0x%02x.\n", productType);
|
||||||
|
|
||||||
ams_read_eeprom_block(AMS_CONFIG_UID_ADDR, block);
|
ams_read_eeprom_block(AMS_CONFIG_UID_ADDR, block);
|
||||||
printf1(TAG_NFC,"UID: 3F 14 02 - "); dump_hex1(TAG_NFC,block,4);
|
printf1(TAG_NFC,"UID: 3F 14 02 - "); dump_hex1(TAG_NFC,block,4);
|
||||||
|
|
||||||
|
ams_read_eeprom_block(AMS_CONFIG_BLOCK0_ADDR, block);
|
||||||
|
printf1(TAG_NFC,"conf0: "); dump_hex1(TAG_NFC,block,4);
|
||||||
|
|
||||||
|
uint8_t sense1 = 0x44;
|
||||||
|
uint8_t sense2 = 0x00;
|
||||||
|
uint8_t selr = 0x20; // SAK
|
||||||
|
|
||||||
|
if(block[0] != sense1 || block[1] != sense2 || block[2] != selr)
|
||||||
|
{
|
||||||
|
printf1(TAG_NFC,"Writing config block 0\r\n");
|
||||||
|
block[0] = sense1;
|
||||||
|
block[1] = sense2;
|
||||||
|
block[2] = selr;
|
||||||
|
block[3] = 0x00;
|
||||||
|
|
||||||
|
ams_write_eeprom_block(AMS_CONFIG_BLOCK0_ADDR, block);
|
||||||
|
UNSELECT();
|
||||||
|
delay(10);
|
||||||
|
SELECT();
|
||||||
|
delay(10);
|
||||||
|
|
||||||
ams_read_eeprom_block(AMS_CONFIG_BLOCK0_ADDR, block);
|
ams_read_eeprom_block(AMS_CONFIG_BLOCK0_ADDR, block);
|
||||||
printf1(TAG_NFC,"conf0: "); dump_hex1(TAG_NFC,block,4);
|
printf1(TAG_NFC,"conf0: "); dump_hex1(TAG_NFC,block,4);
|
||||||
|
|
||||||
uint8_t sense1 = 0x44;
|
|
||||||
uint8_t sense2 = 0x00;
|
|
||||||
uint8_t selr = 0x20; // SAK
|
|
||||||
|
|
||||||
if(block[0] != sense1 || block[1] != sense2 || block[2] != selr)
|
|
||||||
{
|
|
||||||
printf1(TAG_NFC,"Writing config block 0\r\n");
|
|
||||||
block[0] = sense1;
|
|
||||||
block[1] = sense2;
|
|
||||||
block[2] = selr;
|
|
||||||
block[3] = 0x00;
|
|
||||||
|
|
||||||
ams_write_eeprom_block(AMS_CONFIG_BLOCK0_ADDR, block);
|
|
||||||
UNSELECT();
|
|
||||||
delay(10);
|
|
||||||
SELECT();
|
|
||||||
delay(10);
|
|
||||||
|
|
||||||
ams_read_eeprom_block(AMS_CONFIG_BLOCK0_ADDR, block);
|
|
||||||
printf1(TAG_NFC,"conf0: "); dump_hex1(TAG_NFC,block,4);
|
|
||||||
}
|
|
||||||
|
|
||||||
ams_read_eeprom_block(AMS_CONFIG_BLOCK1_ADDR, block);
|
|
||||||
printf1(TAG_NFC,"conf1: "); dump_hex1(TAG_NFC,block,4);
|
|
||||||
|
|
||||||
uint8_t ic_cfg1 = AMS_CFG1_OUTPUT_RESISTANCE_100 | AMS_CFG1_VOLTAGE_LEVEL_2V0;
|
|
||||||
uint8_t ic_cfg2 = AMS_CFG2_TUN_MOD;
|
|
||||||
|
|
||||||
if (block[0] != ic_cfg1 || block[1] != ic_cfg2)
|
|
||||||
{
|
|
||||||
|
|
||||||
printf1(TAG_NFC,"Writing config block 1\r\n");
|
|
||||||
|
|
||||||
ams_write_reg(AMS_REG_IC_CONF1,ic_cfg1);
|
|
||||||
ams_write_reg(AMS_REG_IC_CONF2,ic_cfg2);
|
|
||||||
|
|
||||||
// set IC_CFG1
|
|
||||||
block[0] = ic_cfg1;
|
|
||||||
|
|
||||||
// set IC_CFG2
|
|
||||||
block[1] = ic_cfg2;
|
|
||||||
|
|
||||||
// mask interrupt bits
|
|
||||||
block[2] = 0x80;
|
|
||||||
block[3] = 0;
|
|
||||||
|
|
||||||
ams_write_eeprom_block(AMS_CONFIG_BLOCK1_ADDR, block);
|
|
||||||
|
|
||||||
UNSELECT();
|
|
||||||
delay(10);
|
|
||||||
SELECT();
|
|
||||||
delay(10);
|
|
||||||
|
|
||||||
ams_read_eeprom_block(0x7F, block);
|
|
||||||
printf1(TAG_NFC,"conf1: "); dump_hex1(TAG_NFC,block,4);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
ams_read_eeprom_block(AMS_CONFIG_BLOCK1_ADDR, block);
|
||||||
|
printf1(TAG_NFC,"conf1: "); dump_hex1(TAG_NFC,block,4);
|
||||||
|
|
||||||
|
uint8_t ic_cfg1 = AMS_CFG1_OUTPUT_RESISTANCE_100 | AMS_CFG1_VOLTAGE_LEVEL_2V0;
|
||||||
|
uint8_t ic_cfg2 = AMS_CFG2_TUN_MOD;
|
||||||
|
|
||||||
|
if (block[0] != ic_cfg1 || block[1] != ic_cfg2)
|
||||||
|
{
|
||||||
|
|
||||||
|
printf1(TAG_NFC,"Writing config block 1\r\n");
|
||||||
|
|
||||||
|
ams_write_reg(AMS_REG_IC_CONF1,ic_cfg1);
|
||||||
|
ams_write_reg(AMS_REG_IC_CONF2,ic_cfg2);
|
||||||
|
|
||||||
|
// set IC_CFG1
|
||||||
|
block[0] = ic_cfg1;
|
||||||
|
|
||||||
|
// set IC_CFG2
|
||||||
|
block[1] = ic_cfg2;
|
||||||
|
|
||||||
|
// mask interrupt bits
|
||||||
|
block[2] = 0x80;
|
||||||
|
block[3] = 0;
|
||||||
|
|
||||||
|
ams_write_eeprom_block(AMS_CONFIG_BLOCK1_ADDR, block);
|
||||||
|
|
||||||
|
UNSELECT();
|
||||||
|
delay(10);
|
||||||
|
SELECT();
|
||||||
|
delay(10);
|
||||||
|
|
||||||
|
ams_read_eeprom_block(0x7F, block);
|
||||||
|
printf1(TAG_NFC,"conf1: "); dump_hex1(TAG_NFC,block,4);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,8 @@ typedef union
|
|||||||
#define SELECT() LL_GPIO_ResetOutputPin(SOLO_AMS_CS_PORT,SOLO_AMS_CS_PIN)
|
#define SELECT() LL_GPIO_ResetOutputPin(SOLO_AMS_CS_PORT,SOLO_AMS_CS_PIN)
|
||||||
#define UNSELECT() LL_GPIO_SetOutputPin(SOLO_AMS_CS_PORT,SOLO_AMS_CS_PIN)
|
#define UNSELECT() LL_GPIO_SetOutputPin(SOLO_AMS_CS_PORT,SOLO_AMS_CS_PIN)
|
||||||
|
|
||||||
bool ams_init();
|
void ams_init();
|
||||||
|
void ams_configure();
|
||||||
|
|
||||||
void ams_read_buffer(uint8_t * data, int len);
|
void ams_read_buffer(uint8_t * data, int len);
|
||||||
void ams_write_buffer(uint8_t * data, int len);
|
void ams_write_buffer(uint8_t * data, int len);
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
// #define DISABLE_CTAPHID_WINK
|
// #define DISABLE_CTAPHID_WINK
|
||||||
// #define DISABLE_CTAPHID_CBOR
|
// #define DISABLE_CTAPHID_CBOR
|
||||||
|
|
||||||
// #define ENABLE_SERIAL_PRINTING
|
#define ENABLE_SERIAL_PRINTING
|
||||||
|
|
||||||
#if defined(SOLO_HACKER)
|
#if defined(SOLO_HACKER)
|
||||||
#define SOLO_PRODUCT_NAME "Solo Hacker " SOLO_VERSION
|
#define SOLO_PRODUCT_NAME "Solo Hacker " SOLO_VERSION
|
||||||
|
@ -60,7 +60,7 @@ void TIM6_DAC_IRQHandler()
|
|||||||
}
|
}
|
||||||
#ifndef IS_BOOTLOADER
|
#ifndef IS_BOOTLOADER
|
||||||
// NFC sending WTX if needs
|
// NFC sending WTX if needs
|
||||||
if (haveNFC)
|
if (device_is_nfc())
|
||||||
{
|
{
|
||||||
WTX_timer_exec();
|
WTX_timer_exec();
|
||||||
}
|
}
|
||||||
@ -113,26 +113,32 @@ void device_init()
|
|||||||
hw_init(LOW_FREQUENCY);
|
hw_init(LOW_FREQUENCY);
|
||||||
isLowFreq = 1;
|
isLowFreq = 1;
|
||||||
|
|
||||||
printf1(TAG_NFC,"PWR->CR1: %04x\r\n", LL_PWR_GetRegulVoltageScaling());
|
haveNFC = nfc_init();
|
||||||
|
|
||||||
// hw_init(HIGH_FREQUENCY);
|
if (haveNFC)
|
||||||
// isLowFreq = 0;
|
{
|
||||||
|
printf1(TAG_NFC, "Have NFC\r\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf1(TAG_NFC, "Have NO NFC\r\n");
|
||||||
|
hw_init(HIGH_FREQUENCY);
|
||||||
|
|
||||||
|
isLowFreq = 0;
|
||||||
|
}
|
||||||
|
|
||||||
usbhid_init();
|
usbhid_init();
|
||||||
|
|
||||||
ctaphid_init();
|
ctaphid_init();
|
||||||
|
|
||||||
ctap_init( 0 );
|
ctap_init( !haveNFC );
|
||||||
|
|
||||||
#ifndef IS_BOOTLOADER
|
|
||||||
#if BOOT_TO_DFU
|
#if BOOT_TO_DFU
|
||||||
flash_option_bytes_init(1);
|
flash_option_bytes_init(1);
|
||||||
#else
|
#else
|
||||||
flash_option_bytes_init(0);
|
flash_option_bytes_init(0);
|
||||||
#endif
|
#endif
|
||||||
printf1(TAG_GEN,"init nfc\n");
|
|
||||||
haveNFC = nfc_init();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -430,7 +436,7 @@ void device_manage()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifndef IS_BOOTLOADER
|
#ifndef IS_BOOTLOADER
|
||||||
if(haveNFC)
|
// if(device_is_nfc())
|
||||||
nfc_loop();
|
nfc_loop();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -808,6 +808,8 @@ void init_debug_uart(void)
|
|||||||
/* Peripheral clock enable */
|
/* Peripheral clock enable */
|
||||||
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1);
|
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1);
|
||||||
|
|
||||||
|
|
||||||
|
LL_USART_DeInit(USART1);
|
||||||
/**USART1 GPIO Configuration
|
/**USART1 GPIO Configuration
|
||||||
PB6 ------> USART1_TX
|
PB6 ------> USART1_TX
|
||||||
PB7 ------> USART1_RX
|
PB7 ------> USART1_RX
|
||||||
|
@ -57,8 +57,23 @@ void nfc_state_init()
|
|||||||
|
|
||||||
bool nfc_init()
|
bool nfc_init()
|
||||||
{
|
{
|
||||||
|
uint32_t t1;
|
||||||
nfc_state_init();
|
nfc_state_init();
|
||||||
return ams_init();
|
ams_init();
|
||||||
|
|
||||||
|
// Detect if we are powered by NFC field by listening for a message for
|
||||||
|
// first 25 ms.
|
||||||
|
t1 = millis();
|
||||||
|
while ((millis() - t1) < 25)
|
||||||
|
{
|
||||||
|
if (nfc_loop() > 0)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Under USB power. Configure AMS chip.
|
||||||
|
ams_configure();
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_int0(uint8_t int0)
|
void process_int0(uint8_t int0)
|
||||||
@ -699,88 +714,86 @@ void nfc_process_block(uint8_t * buf, unsigned int len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nfc_loop()
|
int nfc_loop()
|
||||||
{
|
{
|
||||||
uint8_t buf[32];
|
uint8_t buf[32];
|
||||||
AMS_DEVICE ams;
|
AMS_DEVICE ams;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
|
|
||||||
if (1)
|
read_reg_block(&ams);
|
||||||
|
uint8_t state = AMS_STATE_MASK & ams.regs.rfid_status;
|
||||||
|
|
||||||
|
if (state != AMS_STATE_SELECTED && state != AMS_STATE_SELECTEDX)
|
||||||
{
|
{
|
||||||
read_reg_block(&ams);
|
// delay(1); // sleep ?
|
||||||
uint8_t state = AMS_STATE_MASK & ams.regs.rfid_status;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (state != AMS_STATE_SELECTED && state != AMS_STATE_SELECTEDX)
|
if (ams.regs.rfid_status)
|
||||||
{
|
{
|
||||||
// delay(1); // sleep ?
|
// if (state != AMS_STATE_SENSE)
|
||||||
return;
|
// printf1(TAG_NFC," %s x%02x\r\n", ams_get_state_string(ams.regs.rfid_status), state);
|
||||||
}
|
}
|
||||||
|
if (ams.regs.int0 & AMS_INT_INIT)
|
||||||
|
{
|
||||||
|
nfc_state_init();
|
||||||
|
}
|
||||||
|
if (ams.regs.int1)
|
||||||
|
{
|
||||||
|
// ams_print_int1(ams.regs.int1);
|
||||||
|
}
|
||||||
|
|
||||||
if (ams.regs.rfid_status)
|
if ((ams.regs.int0 & AMS_INT_RXE))
|
||||||
|
{
|
||||||
|
if (ams.regs.buffer_status2)
|
||||||
{
|
{
|
||||||
// if (state != AMS_STATE_SENSE)
|
if (ams.regs.buffer_status2 & AMS_BUF_INVALID)
|
||||||
// printf1(TAG_NFC," %s x%02x\r\n", ams_get_state_string(ams.regs.rfid_status), state);
|
|
||||||
}
|
|
||||||
if (ams.regs.int0 & AMS_INT_INIT)
|
|
||||||
{
|
|
||||||
nfc_state_init();
|
|
||||||
}
|
|
||||||
if (ams.regs.int1)
|
|
||||||
{
|
|
||||||
// ams_print_int1(ams.regs.int1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ams.regs.int0 & AMS_INT_RXE))
|
|
||||||
{
|
|
||||||
if (ams.regs.buffer_status2)
|
|
||||||
{
|
{
|
||||||
if (ams.regs.buffer_status2 & AMS_BUF_INVALID)
|
printf1(TAG_NFC,"Buffer being updated!\r\n");
|
||||||
{
|
}
|
||||||
printf1(TAG_NFC,"Buffer being updated!\r\n");
|
else
|
||||||
}
|
{
|
||||||
else
|
len = ams.regs.buffer_status2 & AMS_BUF_LEN_MASK;
|
||||||
{
|
ams_read_buffer(buf, len);
|
||||||
len = ams.regs.buffer_status2 & AMS_BUF_LEN_MASK;
|
|
||||||
ams_read_buffer(buf, len);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (len)
|
if (len)
|
||||||
|
{
|
||||||
|
|
||||||
|
// ISO 14443-3
|
||||||
|
switch(buf[0])
|
||||||
{
|
{
|
||||||
|
case NFC_CMD_REQA:
|
||||||
|
printf1(TAG_NFC, "NFC_CMD_REQA\r\n");
|
||||||
|
break;
|
||||||
|
case NFC_CMD_WUPA:
|
||||||
|
printf1(TAG_NFC, "NFC_CMD_WUPA\r\n");
|
||||||
|
break;
|
||||||
|
case NFC_CMD_HLTA:
|
||||||
|
printf1(TAG_NFC, "HLTA/Halt\r\n");
|
||||||
|
break;
|
||||||
|
case NFC_CMD_RATS:
|
||||||
|
|
||||||
// ISO 14443-3
|
answer_rats(buf[1]);
|
||||||
switch(buf[0])
|
|
||||||
{
|
|
||||||
case NFC_CMD_REQA:
|
|
||||||
printf1(TAG_NFC, "NFC_CMD_REQA\r\n");
|
|
||||||
break;
|
|
||||||
case NFC_CMD_WUPA:
|
|
||||||
printf1(TAG_NFC, "NFC_CMD_WUPA\r\n");
|
|
||||||
break;
|
|
||||||
case NFC_CMD_HLTA:
|
|
||||||
printf1(TAG_NFC, "HLTA/Halt\r\n");
|
|
||||||
break;
|
|
||||||
case NFC_CMD_RATS:
|
|
||||||
|
|
||||||
answer_rats(buf[1]);
|
NFC_STATE.block_num = 1;
|
||||||
|
clear_ibuf();
|
||||||
|
WTX_clear();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
|
||||||
NFC_STATE.block_num = 1;
|
// ISO 14443-4
|
||||||
clear_ibuf();
|
nfc_process_block(buf,len);
|
||||||
WTX_clear();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
|
|
||||||
// ISO 14443-4
|
|
||||||
nfc_process_block(buf,len);
|
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,9 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "apdu.h"
|
#include "apdu.h"
|
||||||
|
|
||||||
void nfc_loop();
|
// Return number of bytes read if any.
|
||||||
|
int nfc_loop();
|
||||||
|
|
||||||
bool nfc_init();
|
bool nfc_init();
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
Loading…
x
Reference in New Issue
Block a user