kopia lustrzana https://github.com/conorpp/u2f-zero
added eeprom read/write
rodzic
291ea274dd
commit
a84275451e
|
@ -21,13 +21,73 @@
|
|||
#define ATECC_RNG_P2 0
|
||||
|
||||
#define ATECC_CMD_SHA 0x47
|
||||
// P1
|
||||
#define ATECC_SHA_START 0x0
|
||||
#define ATECC_SHA_UPDATE 0x1
|
||||
#define ATECC_SHA_END 0x2
|
||||
|
||||
#define ATECC_CMD_READ 0x02
|
||||
// P1
|
||||
#define ATECC_RW_CONFIG 0x00
|
||||
#define ATECC_RW_OTP 0x01
|
||||
#define ATECC_RW_DATA 0x02
|
||||
#define ATECC_RW_EXT 0x80
|
||||
// P2 read addr
|
||||
|
||||
#define ATECC_CMD_WRITE 0x12
|
||||
// P1 same for read
|
||||
// P2 write addr
|
||||
|
||||
#define ATECC_EEPROM_SLOT(x) (0x5 + ((x)>>1))
|
||||
#define ATECC_EEPROM_SLOT_OFFSET(x) ( (x) & 1 ? 2 : 0 )
|
||||
#define ATECC_EEPROM_SLOT_SIZE 0x2
|
||||
|
||||
#define ATECC_EEPROM_KEY(x) (24 + ((x)>>1))
|
||||
#define ATECC_EEPROM_KEY_OFFSET(x) ( (x) & 1 ? 2 : 0 )
|
||||
#define ATECC_EEPROM_KEY_SIZE 0x2
|
||||
|
||||
struct atecc_response
|
||||
{
|
||||
// length of payload
|
||||
uint8_t len;
|
||||
// payload
|
||||
uint8_t* buf;
|
||||
};
|
||||
|
||||
struct atecc_slot_config
|
||||
{
|
||||
uint8_t readkey : 4;
|
||||
uint8_t nomac : 1;
|
||||
uint8_t limiteduse : 1;
|
||||
uint8_t encread : 1;
|
||||
uint8_t secret : 1;
|
||||
uint8_t writekey : 4;
|
||||
uint8_t writeconfig : 4;
|
||||
};
|
||||
|
||||
struct atecc_key_config
|
||||
{
|
||||
uint8_t private : 1;
|
||||
uint8_t pubinfo : 1;
|
||||
uint8_t keytype : 3;
|
||||
uint8_t lockable : 1;
|
||||
uint8_t reqrandom : 1;
|
||||
uint8_t reqauth : 1;
|
||||
uint8_t authkey : 4;
|
||||
uint8_t intrusiondisable : 1;
|
||||
uint8_t rfu : 1;
|
||||
uint8_t x509id : 2;
|
||||
};
|
||||
|
||||
void atecc_send(uint8_t cmd, uint8_t p1, uint16_t p2,
|
||||
uint8_t * buf, uint8_t len);
|
||||
|
||||
uint8_t atecc_recv(uint8_t * buf, uint8_t buflen);
|
||||
uint8_t atecc_recv(uint8_t * buf, uint8_t buflen, struct atecc_response* res);
|
||||
|
||||
uint8_t atecc_send_recv(uint8_t cmd, uint8_t p1, uint16_t p2,
|
||||
uint8_t* tx, uint8_t txlen, uint8_t * rx,
|
||||
uint8_t rxlen, struct atecc_response* res);
|
||||
|
||||
int8_t atecc_write_eeprom(uint8_t base, uint8_t offset, uint8_t* srcbuf, uint8_t len);
|
||||
|
||||
#endif /* ATECC508A_H_ */
|
||||
|
|
|
@ -31,7 +31,7 @@ void atecc_send(uint8_t cmd, uint8_t p1, uint16_t p2,
|
|||
|
||||
#define PKT_CRC(buf, pkt_len) (htole16(*((uint16_t*)(buf+pkt_len-2))))
|
||||
|
||||
uint8_t atecc_recv(uint8_t * buf, uint8_t buflen)
|
||||
uint8_t atecc_recv(uint8_t * buf, uint8_t buflen, struct atecc_response* res)
|
||||
{
|
||||
data uint8_t pkt_len;
|
||||
smb_init_crc();
|
||||
|
@ -52,9 +52,48 @@ uint8_t atecc_recv(uint8_t * buf, uint8_t buflen)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
if (res != NULL)
|
||||
{
|
||||
res->len = pkt_len - 3;
|
||||
res->buf = buf+1;
|
||||
}
|
||||
return pkt_len;
|
||||
|
||||
fail:
|
||||
u2f_print("crc failed %x\r\n",SMB.crc );
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t atecc_send_recv(uint8_t cmd, uint8_t p1, uint16_t p2,
|
||||
uint8_t* tx, uint8_t txlen, uint8_t * rx,
|
||||
uint8_t rxlen, struct atecc_response* res)
|
||||
{
|
||||
do{
|
||||
atecc_send(cmd, p1, p2, tx, txlen);
|
||||
}while(atecc_recv(rx,rxlen, res) < 0);
|
||||
}
|
||||
|
||||
int8_t atecc_write_eeprom(uint8_t base, uint8_t offset, uint8_t* srcbuf, uint8_t len)
|
||||
{
|
||||
uint8_t buf[7];
|
||||
struct atecc_response res;
|
||||
|
||||
uint8_t * dstbuf = srcbuf;
|
||||
if (offset + len > 4)
|
||||
return -1;
|
||||
if (len < 4)
|
||||
{
|
||||
atecc_send_recv(ATECC_CMD_READ,
|
||||
ATECC_RW_CONFIG, base, NULL, 0,
|
||||
buf, sizeof(buf), &res);
|
||||
|
||||
dstbuf = res.buf;
|
||||
memmove(res.buf + offset, srcbuf, len);
|
||||
}
|
||||
|
||||
atecc_send_recv(ATECC_CMD_WRITE,
|
||||
ATECC_RW_CONFIG, base, dstbuf, 4,
|
||||
buf, sizeof(buf), &res);
|
||||
|
||||
return res.buf[0] == 0 ? 0 : -1;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
|
||||
#ifdef ENABLE_TESTS
|
||||
#define TEST_SHA
|
||||
|
||||
|
||||
static void PRINT(const char * fmt, ...)
|
||||
{
|
||||
|
@ -63,18 +63,156 @@ static int test_sha()
|
|||
#define test_sha(x)
|
||||
#endif
|
||||
|
||||
#ifdef TEST_EEPROM
|
||||
|
||||
static void slot_dump(void* slot)
|
||||
{
|
||||
struct atecc_slot_config* a = (struct atecc_slot_config*) slot;
|
||||
flush_messages();
|
||||
u2f_print(" readkey %bx\r\n", a->readkey);
|
||||
if (a->nomac) u2f_print(" nomac\r\n");
|
||||
flush_messages();
|
||||
if (a->limiteduse) u2f_print(" limiteduse\r\n");
|
||||
if (a->encread) u2f_print(" encread\r\n");
|
||||
flush_messages();
|
||||
if (a->secret) u2f_print(" secret\r\n");
|
||||
u2f_print(" writekey %bx\r\n", a->writekey);
|
||||
flush_messages();
|
||||
u2f_print(" writeconfig %bx\r\n", a->writeconfig);
|
||||
flush_messages();
|
||||
}
|
||||
|
||||
static void key_dump(void* slot)
|
||||
{
|
||||
struct atecc_key_config* a = (struct atecc_slot_config*) slot;
|
||||
flush_messages();
|
||||
|
||||
if (a->private) u2f_print(" private\r\n");
|
||||
if (a->pubinfo) u2f_print(" pubinfo\r\n");
|
||||
flush_messages();
|
||||
u2f_print(" keytype %bx\r\n", a->keytype);
|
||||
if (a->lockable) u2f_print(" lockable\r\n");
|
||||
flush_messages();
|
||||
if (a->reqrandom) u2f_print(" reqrandom\r\n");
|
||||
if (a->reqauth) u2f_print(" reqauth\r\n");
|
||||
flush_messages();
|
||||
u2f_print(" authkey %bx\r\n", a->authkey);
|
||||
if (a->intrusiondisable) u2f_print(" intrusiondisable\r\n");
|
||||
flush_messages();
|
||||
if (a->rfu) u2f_print(" rfu\r\n");
|
||||
u2f_print(" x509id %bx\r\n", a->x509id);
|
||||
flush_messages();
|
||||
}
|
||||
|
||||
static int test_eeprom()
|
||||
{
|
||||
uint8_t buf[7];
|
||||
uint16_t c1,c2,c3,c4;
|
||||
|
||||
struct atecc_response res;
|
||||
struct atecc_slot_config slotconfig;
|
||||
struct atecc_key_config keyconfig;
|
||||
|
||||
memset(&slotconfig, 0, sizeof(struct atecc_slot_config));
|
||||
memset(&keyconfig, 0, sizeof(struct atecc_key_config));
|
||||
|
||||
slotconfig.secret = 1;
|
||||
slotconfig.writeconfig = 0xA;
|
||||
slotconfig.readkey = 0x3;
|
||||
|
||||
|
||||
if (atecc_write_eeprom(ATECC_EEPROM_SLOT(0), ATECC_EEPROM_SLOT_OFFSET(0), &slotconfig, ATECC_EEPROM_SLOT_SIZE) != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
slotconfig.writeconfig = 0x3;
|
||||
|
||||
if (atecc_write_eeprom(ATECC_EEPROM_SLOT(1), ATECC_EEPROM_SLOT_OFFSET(1), &slotconfig, ATECC_EEPROM_SLOT_SIZE) != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
keyconfig.private = 1;
|
||||
keyconfig.pubinfo = 1;
|
||||
keyconfig.keytype = 0x4;
|
||||
keyconfig.lockable = 1;
|
||||
|
||||
if (atecc_write_eeprom(ATECC_EEPROM_KEY(0), ATECC_EEPROM_KEY_OFFSET(0), &keyconfig, ATECC_EEPROM_KEY_SIZE) != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
keyconfig.keytype = 0x3;
|
||||
|
||||
if (atecc_write_eeprom(ATECC_EEPROM_KEY(1), ATECC_EEPROM_KEY_OFFSET(1), &keyconfig, ATECC_EEPROM_KEY_SIZE) != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
atecc_send_recv(ATECC_CMD_READ,
|
||||
ATECC_RW_CONFIG, 5,NULL,0,
|
||||
buf,sizeof(buf), &res);
|
||||
|
||||
u2f_print("-- slot 0 --\r\n");
|
||||
dump_hex(res.buf,2);
|
||||
slot_dump(res.buf);
|
||||
|
||||
u2f_print("-- slot 1 --\r\n");
|
||||
dump_hex(res.buf+2,2);
|
||||
slot_dump(res.buf+2);
|
||||
|
||||
if (*(uint16_t*)(res.buf ) != 0x83a0 || *(uint16_t*)(res.buf + 2) != 0x8330)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
atecc_send_recv(ATECC_CMD_READ,
|
||||
ATECC_RW_CONFIG, 24,NULL,0,
|
||||
buf,sizeof(buf), &res);
|
||||
|
||||
u2f_print("-- key 0 --\r\n");
|
||||
dump_hex(res.buf,2);
|
||||
key_dump(res.buf);
|
||||
|
||||
u2f_print("-- key 1 --\r\n");
|
||||
dump_hex(res.buf+2,2);
|
||||
key_dump(res.buf+2);
|
||||
|
||||
if (*(uint16_t*)(res.buf ) != 0x3300 || *(uint16_t*)(res.buf+2) != 0x2f00)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define test_eeprom(x)
|
||||
#endif
|
||||
|
||||
void run_tests()
|
||||
{
|
||||
int rc;
|
||||
|
||||
#ifdef SHA_TEST
|
||||
PRINT("--- STARTING SHA TEST ---\r\n");
|
||||
rc = test_sha();
|
||||
if (rc == 0)
|
||||
PRINT("--- SHA TEST SUCCESS ---\r\n");
|
||||
else
|
||||
PRINT("--- SHA TEST FAILED %d ---\r\n",rc);
|
||||
#endif
|
||||
|
||||
#ifdef TEST_EEPROM
|
||||
PRINT("--- STARTING EEPROM TEST ---\r\n");
|
||||
rc = test_eeprom();
|
||||
if (rc == 0)
|
||||
PRINT("--- EEPROM TEST SUCCESS ---\r\n");
|
||||
else
|
||||
PRINT("--- EEPROM TEST FAILED %d ---\r\n",rc);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -8,7 +8,10 @@
|
|||
#ifndef TESTS_H_
|
||||
#define TESTS_H_
|
||||
|
||||
// #define ENABLE_TESTS
|
||||
//#define ENABLE_TESTS
|
||||
|
||||
//#define TEST_SHA
|
||||
//#define TEST_EEPROM
|
||||
|
||||
#ifdef ENABLE_TESTS
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue