autodetect passive nfc operation or usb operation

This commit is contained in:
Conor Patrick 2019-02-26 15:04:23 -05:00
parent e2ca7f52db
commit e8d0ad5e7c
9 changed files with 175 additions and 153 deletions

View File

@ -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);
} }

View File

@ -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();

View File

@ -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);
}
} }

View File

@ -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);

View File

@ -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

View File

@ -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
} }

View File

@ -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

View File

@ -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;
} }

View File

@ -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