Compare commits

..

6 Commits

Author SHA1 Message Date
8955a1ccf4 default up to enabled 2019-09-17 00:06:45 +08:00
16f07bfc95 allow in bootloader as well 2019-09-16 17:12:09 +08:00
0945ad264c add get_version command to hid 2019-09-16 17:00:30 +08:00
b20ca7c5f7 delete old code 2019-09-16 17:00:13 +08:00
bc73ce8d21 allow get_assertion with disabled UP 2019-09-16 16:25:58 +08:00
2051ddb180 properly check the rpId in request 2019-09-16 15:33:38 +08:00
37 changed files with 186 additions and 446 deletions

View File

@ -187,16 +187,6 @@
"contributions": [ "contributions": [
"bug" "bug"
] ]
},
{
"login": "jolo1581",
"name": "Jan A.",
"avatar_url": "https://avatars1.githubusercontent.com/u/53423977?v=4",
"profile": "https://github.com/jolo1581",
"contributions": [
"code",
"doc"
]
} }
], ],
"contributorsPerLine": 7, "contributorsPerLine": 7,

View File

@ -39,7 +39,7 @@ INCLUDES += -I./crypto/cifra/src
CFLAGS += $(INCLUDES) CFLAGS += $(INCLUDES)
# for crypto/tiny-AES-c # for crypto/tiny-AES-c
CFLAGS += -DAES256=1 -DAPP_CONFIG=\"app.h\" -DSOLO_EXPERIMENTAL=1 CFLAGS += -DAES256=1 -DAPP_CONFIG=\"app.h\"
name = main name = main

View File

@ -136,7 +136,6 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<td align="center"><a href="http://blogs.gnome.org/hughsie/"><img src="https://avatars0.githubusercontent.com/u/151380?v=4" width="100px;" alt="Richard Hughes"/><br /><sub><b>Richard Hughes</b></sub></a><br /><a href="#ideas-hughsie" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/solokeys/solo/commits?author=hughsie" title="Code">💻</a> <a href="#infra-hughsie" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#tool-hughsie" title="Tools">🔧</a></td> <td align="center"><a href="http://blogs.gnome.org/hughsie/"><img src="https://avatars0.githubusercontent.com/u/151380?v=4" width="100px;" alt="Richard Hughes"/><br /><sub><b>Richard Hughes</b></sub></a><br /><a href="#ideas-hughsie" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/solokeys/solo/commits?author=hughsie" title="Code">💻</a> <a href="#infra-hughsie" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#tool-hughsie" title="Tools">🔧</a></td>
<td align="center"><a href="http://www.schulz.dk"><img src="https://avatars1.githubusercontent.com/u/1150049?v=4" width="100px;" alt="Kim Schulz"/><br /><sub><b>Kim Schulz</b></sub></a><br /><a href="#business-kimusan" title="Business development">💼</a> <a href="#ideas-kimusan" title="Ideas, Planning, & Feedback">🤔</a></td> <td align="center"><a href="http://www.schulz.dk"><img src="https://avatars1.githubusercontent.com/u/1150049?v=4" width="100px;" alt="Kim Schulz"/><br /><sub><b>Kim Schulz</b></sub></a><br /><a href="#business-kimusan" title="Business development">💼</a> <a href="#ideas-kimusan" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center"><a href="https://github.com/oplik0"><img src="https://avatars2.githubusercontent.com/u/25460763?v=4" width="100px;" alt="Jakub"/><br /><sub><b>Jakub</b></sub></a><br /><a href="https://github.com/solokeys/solo/issues?q=author%3Aoplik0" title="Bug reports">🐛</a></td> <td align="center"><a href="https://github.com/oplik0"><img src="https://avatars2.githubusercontent.com/u/25460763?v=4" width="100px;" alt="Jakub"/><br /><sub><b>Jakub</b></sub></a><br /><a href="https://github.com/solokeys/solo/issues?q=author%3Aoplik0" title="Bug reports">🐛</a></td>
<td align="center"><a href="https://github.com/jolo1581"><img src="https://avatars1.githubusercontent.com/u/53423977?v=4" width="100px;" alt="Jan A."/><br /><sub><b>Jan A.</b></sub></a><br /><a href="https://github.com/solokeys/solo/commits?author=jolo1581" title="Code">💻</a> <a href="https://github.com/solokeys/solo/commits?author=jolo1581" title="Documentation">📖</a></td>
</tr> </tr>
</table> </table>
@ -170,7 +169,7 @@ You can buy Solo, Solo Tap, and Solo for Hackers at [solokeys.com](https://solok
<br/> <br/>
[![License](https://img.shields.io/github/license/solokeys/solo.svg)](https://github.com/solokeys/solo/blob/master/LICENSE) [![License](https://img.shields.io/github/license/solokeys/solo.svg)](https://github.com/solokeys/solo/blob/master/LICENSE)
[![All Contributors](https://img.shields.io/badge/all_contributors-20-orange.svg?style=flat-square)](#contributors) [![All Contributors](https://img.shields.io/badge/all_contributors-19-orange.svg?style=flat-square)](#contributors)
[![Build Status](https://travis-ci.com/solokeys/solo.svg?branch=master)](https://travis-ci.com/solokeys/solo) [![Build Status](https://travis-ci.com/solokeys/solo.svg?branch=master)](https://travis-ci.com/solokeys/solo)
[![Discourse Users](https://img.shields.io/discourse/https/discourse.solokeys.com/users.svg)](https://discourse.solokeys.com) [![Discourse Users](https://img.shields.io/discourse/https/discourse.solokeys.com/users.svg)](https://discourse.solokeys.com)
[![Keybase Chat](https://img.shields.io/badge/chat-on%20keybase-brightgreen.svg)](https://keybase.io/team/solokeys.public) [![Keybase Chat](https://img.shields.io/badge/chat-on%20keybase-brightgreen.svg)](https://keybase.io/team/solokeys.public)

View File

@ -1 +1 @@
2.5.3 2.5.2

View File

@ -18,7 +18,7 @@ Further progress is tracked in: <https://github.com/solokeys/solo/issues/144>.
If you still need to setup a rule, a simple way to do it is: If you still need to setup a rule, a simple way to do it is:
``` ```
git clone https://github.com/solokeys/solo.git git clone git@github.com:solokeys/solo.git
cd solo/udev cd solo/udev
make setup make setup
``` ```

View File

@ -1761,28 +1761,11 @@ static void ctap_state_init()
printf1(TAG_STOR, "Generated PIN SALT: "); printf1(TAG_STOR, "Generated PIN SALT: ");
dump_hex1(TAG_STOR, STATE.PIN_SALT, sizeof STATE.PIN_SALT); dump_hex1(TAG_STOR, STATE.PIN_SALT, sizeof STATE.PIN_SALT);
} }
/** Overwrite master secret from external source.
* @param keybytes an array of KEY_SPACE_BYTES length.
*
* This function should only be called from a privilege mode.
*/
void ctap_load_external_keys(uint8_t * keybytes){
memmove(STATE.key_space, keybytes, KEY_SPACE_BYTES);
authenticator_write_state(&STATE, 0);
authenticator_write_state(&STATE, 1);
crypto_load_master_secret(STATE.key_space);
}
#include "version.h"
void ctap_init() void ctap_init()
{ {
printf1(TAG_ERR,"Current firmware version address: %p\r\n", &firmware_version);
printf1(TAG_ERR,"Current firmware version: %d.%d.%d.%d (%02x.%02x.%02x.%02x)\r\n",
firmware_version.major, firmware_version.minor, firmware_version.patch, firmware_version.reserved,
firmware_version.major, firmware_version.minor, firmware_version.patch, firmware_version.reserved
);
crypto_ecc256_init(); crypto_ecc256_init();
authenticator_read_state(&STATE); authenticator_read_state(&STATE);

View File

@ -361,6 +361,4 @@ extern uint8_t KEY_AGREEMENT_PUB[64];
void lock_device_permanently(); void lock_device_permanently();
void ctap_load_external_keys(uint8_t * keybytes);
#endif #endif

View File

@ -539,14 +539,11 @@ extern void _check_ret(CborError ret, int line, const char * filename);
#define check_hardcore(r) _check_ret(r,__LINE__, __FILE__);\ #define check_hardcore(r) _check_ret(r,__LINE__, __FILE__);\
if ((r) != CborNoError) exit(1); if ((r) != CborNoError) exit(1);
uint8_t ctaphid_custom_command(int len, CTAP_RESPONSE * ctap_resp, CTAPHID_WRITE_BUFFER * wb);
uint8_t ctaphid_handle_packet(uint8_t * pkt_raw) uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
{ {
uint8_t cmd = 0; uint8_t cmd;
uint32_t cid; uint32_t cid;
int len = 0; int len;
#ifndef DISABLE_CTAPHID_CBOR #ifndef DISABLE_CTAPHID_CBOR
int status; int status;
#endif #endif
@ -556,10 +553,6 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
CTAP_RESPONSE ctap_resp; CTAP_RESPONSE ctap_resp;
int bufstatus = ctaphid_buffer_packet(pkt_raw, &cmd, &cid, &len); int bufstatus = ctaphid_buffer_packet(pkt_raw, &cmd, &cid, &len);
ctaphid_write_buffer_init(&wb);
wb.cid = cid;
wb.cmd = cmd;
if (bufstatus == HID_IGNORE) if (bufstatus == HID_IGNORE)
{ {
@ -595,6 +588,9 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
case CTAPHID_PING: case CTAPHID_PING:
printf1(TAG_HID,"CTAPHID_PING\n"); printf1(TAG_HID,"CTAPHID_PING\n");
ctaphid_write_buffer_init(&wb);
wb.cid = cid;
wb.cmd = CTAPHID_PING;
wb.bcnt = len; wb.bcnt = len;
timestamp(); timestamp();
ctaphid_write(&wb, ctap_buffer, len); ctaphid_write(&wb, ctap_buffer, len);
@ -607,9 +603,13 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
case CTAPHID_WINK: case CTAPHID_WINK:
printf1(TAG_HID,"CTAPHID_WINK\n"); printf1(TAG_HID,"CTAPHID_WINK\n");
ctaphid_write_buffer_init(&wb);
device_wink(); device_wink();
wb.cid = cid;
wb.cmd = CTAPHID_WINK;
ctaphid_write(&wb,NULL,0); ctaphid_write(&wb,NULL,0);
break; break;
@ -634,6 +634,9 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
ctap_response_init(&ctap_resp); ctap_response_init(&ctap_resp);
status = ctap_request(ctap_buffer, len, &ctap_resp); status = ctap_request(ctap_buffer, len, &ctap_resp);
ctaphid_write_buffer_init(&wb);
wb.cid = cid;
wb.cmd = CTAPHID_CBOR;
wb.bcnt = (ctap_resp.length+1); wb.bcnt = (ctap_resp.length+1);
@ -664,6 +667,9 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
ctap_response_init(&ctap_resp); ctap_response_init(&ctap_resp);
u2f_request((struct u2f_request_apdu*)ctap_buffer, &ctap_resp); u2f_request((struct u2f_request_apdu*)ctap_buffer, &ctap_resp);
ctaphid_write_buffer_init(&wb);
wb.cid = cid;
wb.cmd = CTAPHID_MSG;
wb.bcnt = (ctap_resp.length); wb.bcnt = (ctap_resp.length);
ctaphid_write(&wb, ctap_resp.data, ctap_resp.length); ctaphid_write(&wb, ctap_resp.data, ctap_resp.length);
@ -674,14 +680,76 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
printf1(TAG_HID,"CTAPHID_CANCEL\n"); printf1(TAG_HID,"CTAPHID_CANCEL\n");
is_busy = 0; is_busy = 0;
break; break;
#if defined(IS_BOOTLOADER)
case CTAPHID_BOOT:
printf1(TAG_HID,"CTAPHID_BOOT\n");
ctap_response_init(&ctap_resp);
u2f_set_writeback_buffer(&ctap_resp);
is_busy = bootloader_bridge(len, ctap_buffer);
ctaphid_write_buffer_init(&wb);
wb.cid = cid;
wb.cmd = CTAPHID_BOOT;
wb.bcnt = (ctap_resp.length + 1);
ctaphid_write(&wb, &is_busy, 1);
ctaphid_write(&wb, ctap_resp.data, ctap_resp.length);
ctaphid_write(&wb, NULL, 0);
is_busy = 0;
break;
#endif
#if defined(SOLO_HACKER)
case CTAPHID_ENTERBOOT:
printf1(TAG_HID,"CTAPHID_ENTERBOOT\n");
boot_solo_bootloader();
ctaphid_write_buffer_init(&wb);
wb.cid = cid;
wb.cmd = CTAPHID_ENTERBOOT;
wb.bcnt = 0;
ctaphid_write(&wb, NULL, 0);
is_busy = 0;
break;
case CTAPHID_ENTERSTBOOT:
printf1(TAG_HID,"CTAPHID_ENTERBOOT\n");
boot_st_bootloader();
break;
#endif
#if !defined(IS_BOOTLOADER)
case CTAPHID_GETRNG:
printf1(TAG_HID,"CTAPHID_GETRNG\n");
ctap_response_init(&ctap_resp);
ctaphid_write_buffer_init(&wb);
wb.cid = cid;
wb.cmd = CTAPHID_GETRNG;
wb.bcnt = ctap_buffer[0];
if (!wb.bcnt)
wb.bcnt = 57;
memset(ctap_buffer,0,wb.bcnt);
ctap_generate_rng(ctap_buffer, wb.bcnt);
ctaphid_write(&wb, &ctap_buffer, wb.bcnt);
ctaphid_write(&wb, NULL, 0);
is_busy = 0;
break;
#endif
case CTAPHID_GETVERSION:
printf1(TAG_HID,"CTAPHID_GETVERSION\n");
ctap_response_init(&ctap_resp);
ctaphid_write_buffer_init(&wb);
wb.cid = cid;
wb.cmd = CTAPHID_GETVERSION;
wb.bcnt = 3;
ctap_buffer[0] = SOLO_VERSION_MAJ;
ctap_buffer[1] = SOLO_VERSION_MIN;
ctap_buffer[2] = SOLO_VERSION_PATCH;
ctaphid_write(&wb, &ctap_buffer, 3);
ctaphid_write(&wb, NULL, 0);
is_busy = 0;
break;
default: default:
if (ctaphid_custom_command(len, &ctap_resp, &wb) != 0){ printf2(TAG_ERR,"error, unimplemented HID cmd: %02x\r\n", buffer_cmd());
is_busy = 0; ctaphid_send_error(cid, CTAP1_ERR_INVALID_COMMAND);
}else{ break;
printf2(TAG_ERR, "error, unimplemented HID cmd: %02x\r\n", buffer_cmd());
ctaphid_send_error(cid, CTAP1_ERR_INVALID_COMMAND);
}
} }
cid_del(cid); cid_del(cid);
buffer_reset(); buffer_reset();
@ -691,112 +759,3 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
else return 0; else return 0;
} }
uint8_t ctaphid_custom_command(int len, CTAP_RESPONSE * ctap_resp, CTAPHID_WRITE_BUFFER * wb)
{
ctap_response_init(ctap_resp);
#if !defined(IS_BOOTLOADER) && (defined(SOLO_HACKER) || defined(SOLO_EXPERIMENTAL))
uint32_t param;
#endif
#if defined(IS_BOOTLOADER)
uint8_t is_busy;
#endif
switch(wb->cmd)
{
#if defined(IS_BOOTLOADER)
case CTAPHID_BOOT:
printf1(TAG_HID,"CTAPHID_BOOT\n");
u2f_set_writeback_buffer(ctap_resp);
is_busy = bootloader_bridge(len, ctap_buffer);
ctaphid_write(wb, &is_busy, 1);
ctaphid_write(wb, ctap_resp->data, ctap_resp->length);
ctaphid_write(wb, NULL, 0);
return 1;
#endif
#if defined(SOLO_HACKER)
case CTAPHID_ENTERBOOT:
printf1(TAG_HID,"CTAPHID_ENTERBOOT\n");
boot_solo_bootloader();
wb->bcnt = 0;
ctaphid_write(wb, NULL, 0);
return 1;
case CTAPHID_ENTERSTBOOT:
printf1(TAG_HID,"CTAPHID_ENTERBOOT\n");
boot_st_bootloader();
return 1;
#endif
#if !defined(IS_BOOTLOADER)
case CTAPHID_GETRNG:
printf1(TAG_HID,"CTAPHID_GETRNG\n");
wb->bcnt = ctap_buffer[0];
if (!wb->bcnt)
wb->bcnt = 57;
memset(ctap_buffer,0,wb->bcnt);
ctap_generate_rng(ctap_buffer, wb->bcnt);
ctaphid_write(wb, ctap_buffer, wb->bcnt);
ctaphid_write(wb, NULL, 0);
return 1;
break;
#endif
case CTAPHID_GETVERSION:
printf1(TAG_HID,"CTAPHID_GETVERSION\n");
wb->bcnt = 3;
ctap_buffer[0] = SOLO_VERSION_MAJ;
ctap_buffer[1] = SOLO_VERSION_MIN;
ctap_buffer[2] = SOLO_VERSION_PATCH;
ctaphid_write(wb, ctap_buffer, 3);
ctaphid_write(wb, NULL, 0);
return 1;
break;
#if !defined(IS_BOOTLOADER) && (defined(SOLO_HACKER) || defined(SOLO_EXPERIMENTAL))
case CTAPHID_LOADKEY:
/**
* Load external key. Useful for enabling backups.
* bytes: 4 96
* payload: | counter_increase (BE) | master_key |
*
* Counter should be increased by a large amount, e.g. (0x10000000)
* to outdo any previously lost/broken keys.
*/
printf1(TAG_HID,"CTAPHID_LOADKEY\n");
if (len != 100)
{
printf2(TAG_ERR,"Error, invalid length.\n");
ctaphid_send_error(wb->cid, CTAP1_ERR_INVALID_LENGTH);
return 1;
}
// Ask for THREE button presses
if (ctap_user_presence_test(8000) > 0)
if (ctap_user_presence_test(8000) > 0)
if (ctap_user_presence_test(8000) > 0)
{
ctap_load_external_keys(ctap_buffer + 4);
param = ctap_buffer[3];
param |= ctap_buffer[2] << 8;
param |= ctap_buffer[1] << 16;
param |= ctap_buffer[0] << 24;
ctap_atomic_count(param);
wb->bcnt = 0;
ctaphid_write(wb, NULL, 0);
return 1;
}
printf2(TAG_ERR, "Error, invalid length.\n");
ctaphid_send_error(wb->cid, CTAP2_ERR_OPERATION_DENIED);
return 1;
#endif
}
return 0;
}

View File

@ -29,7 +29,6 @@
#define CTAPHID_ENTERSTBOOT (TYPE_INIT | 0x52) #define CTAPHID_ENTERSTBOOT (TYPE_INIT | 0x52)
#define CTAPHID_GETRNG (TYPE_INIT | 0x60) #define CTAPHID_GETRNG (TYPE_INIT | 0x60)
#define CTAPHID_GETVERSION (TYPE_INIT | 0x61) #define CTAPHID_GETVERSION (TYPE_INIT | 0x61)
#define CTAPHID_LOADKEY (TYPE_INIT | 0x62)
// reserved for debug, not implemented except for HACKER and DEBUG_LEVEl > 0 // reserved for debug, not implemented except for HACKER and DEBUG_LEVEl > 0
#define CTAPHID_PROBE (TYPE_INIT | 0x70) #define CTAPHID_PROBE (TYPE_INIT | 0x70)

View File

@ -61,8 +61,8 @@ int ctap_user_presence_test(uint32_t delay);
int ctap_generate_rng(uint8_t * dst, size_t num); int ctap_generate_rng(uint8_t * dst, size_t num);
// Increment atomic counter and return it. // Increment atomic counter and return it.
// @param amount the amount to increase the counter by. // Must support two counters, @sel selects counter0 or counter1.
uint32_t ctap_atomic_count(uint32_t amount); uint32_t ctap_atomic_count(int sel);
// Verify the user // Verify the user
// return 1 if user is verified, 0 if not // return 1 if user is verified, 0 if not

View File

@ -1,13 +0,0 @@
#include "version.h"
const version_t firmware_version __attribute__ ((section (".flag"))) __attribute__ ((__used__)) = {
.major = SOLO_VERSION_MAJ,
.minor = SOLO_VERSION_MIN,
.patch = SOLO_VERSION_PATCH,
.reserved = 0
};
// from tinycbor, for a quick static_assert
#include <compilersupport_p.h>
cbor_static_assert(sizeof(version_t) == 4);

View File

@ -17,23 +17,5 @@
#define SOLO_VERSION __STR(SOLO_VERSION_MAJ) "." __STR(SOLO_VERSION_MIN) "." __STR(SOLO_VERSION_PATCH) #define SOLO_VERSION __STR(SOLO_VERSION_MAJ) "." __STR(SOLO_VERSION_MIN) "." __STR(SOLO_VERSION_PATCH)
#endif #endif
#include <stdint.h>
#include <stdbool.h>
typedef struct {
union{
uint32_t raw;
struct {
uint8_t major;
uint8_t minor;
uint8_t patch;
uint8_t reserved;
};
};
} version_t;
bool is_newer(const version_t* const newer, const version_t* const older);
const version_t firmware_version ;
#endif #endif

View File

@ -313,11 +313,20 @@ int ctap_user_verification(uint8_t arg)
} }
uint32_t ctap_atomic_count(uint32_t amount) uint32_t ctap_atomic_count(int sel)
{ {
static uint32_t counter1 = 25; static uint32_t counter1 = 25;
counter1 += amount; /*return 713;*/
return counter1; if (sel == 0)
{
printf1(TAG_RED,"counter1: %d\n", counter1);
return counter1++;
}
else
{
printf2(TAG_ERR,"counter2 not imple\n");
exit(1);
}
} }
int ctap_generate_rng(uint8_t * dst, size_t num) int ctap_generate_rng(uint8_t * dst, size_t num)

View File

@ -90,7 +90,8 @@ flash_dfu: solo.hex bootloader.hex
# STM32_Programmer_CLI -c port=usb1 -halt -e all --readunprotect # STM32_Programmer_CLI -c port=usb1 -halt -e all --readunprotect
STM32_Programmer_CLI -c port=usb1 -halt -rdu -d all.hex STM32_Programmer_CLI -c port=usb1 -halt -rdu -d all.hex
flashboot: bootloader.hex flashboot: solo.hex bootloader.hex
$(VENV) $(merge_hex) solo.hex bootloader.hex all.hex
STM32_Programmer_CLI -c port=SWD -halt -e all --readunprotect STM32_Programmer_CLI -c port=SWD -halt -e all --readunprotect
STM32_Programmer_CLI -c port=SWD -halt -d bootloader.hex -rst STM32_Programmer_CLI -c port=SWD -halt -d bootloader.hex -rst

View File

@ -19,12 +19,6 @@
#include "ctap_errors.h" #include "ctap_errors.h"
#include "log.h" #include "log.h"
volatile version_t current_firmware_version __attribute__ ((section (".flag2"))) __attribute__ ((__used__)) = {
.major = SOLO_VERSION_MAJ,
.minor = SOLO_VERSION_MIN,
.patch = SOLO_VERSION_PATCH,
.reserved = 0
};
extern uint8_t REBOOT_FLAG; extern uint8_t REBOOT_FLAG;
@ -62,6 +56,8 @@ static void erase_application()
} }
} }
#define LAST_ADDR (APPLICATION_END_ADDR-2048 + 8)
#define LAST_PAGE (APPLICATION_END_PAGE-1)
static void disable_bootloader() static void disable_bootloader()
{ {
// Clear last 4 bytes of the last application page-1, which is 108th // Clear last 4 bytes of the last application page-1, which is 108th
@ -106,38 +102,6 @@ int is_bootloader_disabled()
uint32_t * auth = (uint32_t *)(AUTH_WORD_ADDR+4); uint32_t * auth = (uint32_t *)(AUTH_WORD_ADDR+4);
return *auth == 0; return *auth == 0;
} }
uint8_t * last_written_app_address;
#include "version.h"
bool is_firmware_version_newer_or_equal()
{
printf1(TAG_BOOT,"Current firmware version: %u.%u.%u.%u (%02x.%02x.%02x.%02x)\r\n",
current_firmware_version.major, current_firmware_version.minor, current_firmware_version.patch, current_firmware_version.reserved,
current_firmware_version.major, current_firmware_version.minor, current_firmware_version.patch, current_firmware_version.reserved
);
volatile version_t * new_version = ((volatile version_t *) last_written_app_address);
printf1(TAG_BOOT,"Uploaded firmware version: %u.%u.%u.%u (%02x.%02x.%02x.%02x)\r\n",
new_version->major, new_version->minor, new_version->patch, new_version->reserved,
new_version->major, new_version->minor, new_version->patch, new_version->reserved
);
const bool allowed = is_newer((const version_t *)new_version, (const version_t *)&current_firmware_version) || current_firmware_version.raw == 0xFFFFFFFF;
if (allowed){
printf1(TAG_BOOT, "Update allowed, setting new firmware version as current.\r\n");
// current_firmware_version.raw = new_version.raw;
uint8_t page[PAGE_SIZE];
memmove(page, (uint8_t*)BOOT_VERSION_ADDR, PAGE_SIZE);
memmove(page, (version_t *)new_version, 4);
printf1(TAG_BOOT, "Writing\r\n");
flash_erase_page(BOOT_VERSION_PAGE);
flash_write(BOOT_VERSION_ADDR, page, PAGE_SIZE);
printf1(TAG_BOOT, "Finish\r\n");
} else {
printf1(TAG_BOOT, "Firmware older - update not allowed.\r\n");
}
return allowed;
}
/** /**
* Execute bootloader commands * Execute bootloader commands
@ -161,7 +125,10 @@ int bootloader_bridge(int klen, uint8_t * keyh)
return CTAP1_ERR_INVALID_LENGTH; return CTAP1_ERR_INVALID_LENGTH;
} }
#ifndef SOLO_HACKER #ifndef SOLO_HACKER
extern uint8_t *pubkey_boot; uint8_t * pubkey = (uint8_t*)"\xd2\xa4\x2f\x8f\xb2\x31\x1c\xc1\xf7\x0c\x7e\x64\x32\xfb\xbb\xb4\xa3\xdd\x32\x20"
"\x0f\x1b\x88\x9c\xda\x62\xc2\x83\x25\x93\xdd\xb8\x75\x9d\xf9\x86\xee\x03\x6c\xce"
"\x34\x47\x71\x36\xb3\xb2\xad\x6d\x12\xb7\xbe\x49\x3e\x20\xa4\x61\xac\xc7\x71\xc7"
"\x1f\xa8\x14\xf2";
const struct uECC_Curve_t * curve = NULL; const struct uECC_Curve_t * curve = NULL;
#endif #endif
@ -198,11 +165,12 @@ int bootloader_bridge(int klen, uint8_t * keyh)
} }
// Do the actual write // Do the actual write
flash_write((uint32_t)ptr,req->payload, len); flash_write((uint32_t)ptr,req->payload, len);
last_written_app_address = (uint8_t *)ptr + len - 8 + 4;
break; break;
case BootDone: case BootDone:
// Writing to flash finished. Request code validation. // Writing to flash finished. Request code validation.
printf1(TAG_BOOT, "BootDone: \r\n"); printf1(TAG_BOOT, "BootDone: ");
#ifndef SOLO_HACKER #ifndef SOLO_HACKER
if (len != 64) if (len != 64)
{ {
@ -217,23 +185,17 @@ int bootloader_bridge(int klen, uint8_t * keyh)
crypto_sha256_final(hash); crypto_sha256_final(hash);
curve = uECC_secp256r1(); curve = uECC_secp256r1();
// Verify incoming signature made over the SHA256 hash // Verify incoming signature made over the SHA256 hash
if ( if (! uECC_verify(pubkey,
!uECC_verify(pubkey_boot, hash, 32, req->payload, curve) hash,
) 32,
req->payload,
curve))
{ {
printf1(TAG_BOOT, "Signature invalid\r\n");
return CTAP2_ERR_OPERATION_DENIED; return CTAP2_ERR_OPERATION_DENIED;
} }
if (!is_firmware_version_newer_or_equal()){
printf1(TAG_BOOT, "Firmware older - update not allowed.\r\n");
printf1(TAG_BOOT, "Rebooting...\r\n");
REBOOT_FLAG = 1;
return CTAP2_ERR_OPERATION_DENIED;
}
#endif #endif
// Set the application validated, and mark for reboot. // Set the application validated, and mark for reboot.
authorize_application(); authorize_application();
REBOOT_FLAG = 1; REBOOT_FLAG = 1;
break; break;
case BootCheck: case BootCheck:
@ -256,7 +218,6 @@ int bootloader_bridge(int klen, uint8_t * keyh)
break; break;
case BootReboot: case BootReboot:
printf1(TAG_BOOT, "BootReboot.\r\n"); printf1(TAG_BOOT, "BootReboot.\r\n");
printf1(TAG_BOOT, "Application authorized: %d.\r\n", is_authorized_to_boot());
REBOOT_FLAG = 1; REBOOT_FLAG = 1;
break; break;
case BootDisable: case BootDisable:
@ -316,10 +277,3 @@ void bootloader_heartbeat()
led_rgb(((val * g)<<8) | ((val*r) << 16) | (val*b)); led_rgb(((val * g)<<8) | ((val*r) << 16) | (val*b));
} }
uint32_t ctap_atomic_count(uint32_t amount)
{
static uint32_t count = 1000;
count += (amount + 1);
return count;
}

View File

@ -138,14 +138,6 @@ int main()
printf1(TAG_GEN,"recv'ing hid msg \n"); printf1(TAG_GEN,"recv'ing hid msg \n");
extern volatile version_t current_firmware_version;
printf1(TAG_BOOT,"Current firmware version address: %p\r\n", &current_firmware_version);
printf1(TAG_BOOT,"Current firmware version: %d.%d.%d.%d (%02x.%02x.%02x.%02x)\r\n",
current_firmware_version.major, current_firmware_version.minor, current_firmware_version.patch, current_firmware_version.reserved,
current_firmware_version.major, current_firmware_version.minor, current_firmware_version.patch, current_firmware_version.reserved
);
dump_hex1(TAG_BOOT, (uint8_t*)(&current_firmware_version) - 16, 32);
while(1) while(1)
{ {

View File

@ -1,6 +0,0 @@
#include "stdint.h"
uint8_t * pubkey_boot = (uint8_t*)"\xd2\xa4\x2f\x8f\xb2\x31\x1c\xc1\xf7\x0c\x7e\x64\x32\xfb\xbb\xb4\xa3\xdd\x32\x20"
"\x0f\x1b\x88\x9c\xda\x62\xc2\x83\x25\x93\xdd\xb8\x75\x9d\xf9\x86\xee\x03\x6c\xce"
"\x34\x47\x71\x36\xb3\xb2\xad\x6d\x12\xb7\xbe\x49\x3e\x20\xa4\x61\xac\xc7\x71\xc7"
"\x1f\xa8\x14\xf2";

View File

@ -1,8 +0,0 @@
#include "version.h"
// FIXME test version check function
bool is_newer(const version_t* const newer, const version_t* const older){
return (newer->major > older->major) ||
(newer->major == older->major && newer->minor > older->minor) ||
(newer->major == older->major && newer->minor == older->minor && newer->patch >= older->patch);
}

View File

@ -10,7 +10,6 @@ SRC += $(DRIVER_LIBS) $(USB_LIB)
SRC += ../../fido2/apdu.c ../../fido2/util.c ../../fido2/u2f.c ../../fido2/test_power.c SRC += ../../fido2/apdu.c ../../fido2/util.c ../../fido2/u2f.c ../../fido2/test_power.c
SRC += ../../fido2/stubs.c ../../fido2/log.c ../../fido2/ctaphid.c ../../fido2/ctap.c SRC += ../../fido2/stubs.c ../../fido2/log.c ../../fido2/ctaphid.c ../../fido2/ctap.c
SRC += ../../fido2/ctap_parse.c ../../fido2/main.c SRC += ../../fido2/ctap_parse.c ../../fido2/main.c
SRC += ../../fido2/version.c
SRC += ../../fido2/data_migration.c SRC += ../../fido2/data_migration.c
SRC += ../../fido2/extensions/extensions.c ../../fido2/extensions/solo.c SRC += ../../fido2/extensions/extensions.c ../../fido2/extensions/solo.c
SRC += ../../fido2/extensions/wallet.c SRC += ../../fido2/extensions/wallet.c
@ -71,7 +70,6 @@ all: $(TARGET).elf
%.elf: $(OBJ) %.elf: $(OBJ)
$(CC) $^ $(HW) $(LDFLAGS) -o $@ $(CC) $^ $(HW) $(LDFLAGS) -o $@
@echo "Built version: $(VERSION_FLAGS)"
%.hex: %.elf %.hex: %.elf
$(SZ) $^ $(SZ) $^

View File

@ -2,7 +2,6 @@ include build/common.mk
# ST related # ST related
SRC = bootloader/main.c bootloader/bootloader.c SRC = bootloader/main.c bootloader/bootloader.c
SRC += bootloader/pubkey_bootloader.c bootloader/version_check.c
SRC += src/init.c src/redirect.c src/flash.c src/rng.c src/led.c src/device.c SRC += src/init.c src/redirect.c src/flash.c src/rng.c src/led.c src/device.c
SRC += src/fifo.c src/crypto.c src/attestation.c src/sense.c SRC += src/fifo.c src/crypto.c src/attestation.c src/sense.c
SRC += src/startup_stm32l432xx.s src/system_stm32l4xx.c SRC += src/startup_stm32l432xx.s src/system_stm32l4xx.c
@ -66,7 +65,6 @@ all: $(TARGET).elf
%.elf: $(OBJ) %.elf: $(OBJ)
$(CC) $^ $(HW) $(LDFLAGS) -o $@ $(CC) $^ $(HW) $(LDFLAGS) -o $@
arm-none-eabi-size $@
%.hex: %.elf %.hex: %.elf
$(CP) -O ihex $^ $(TARGET).hex $(CP) -O ihex $^ $(TARGET).hex

View File

@ -12,17 +12,9 @@ _estack = 0x2000c000;
_MIN_STACK_SIZE = 0x400; _MIN_STACK_SIZE = 0x400;
/*
flash_cfg is for storing bootloader data, like last used firmware version.
bootloader_configuration should be equal to (APPLICATION_END_PAGE) page address, from targets/stm32l432/src/memory_layout.h:30; and equal to flash_cfg origin
*/
bootloader_configuration = 0x08000000 + 216*1024+8;
MEMORY MEMORY
{ {
flash (rx) : ORIGIN = 0x08000000, LENGTH = 20K flash (rx) : ORIGIN = 0x08000000, LENGTH = 20K
flash_cfg (rx) : ORIGIN = 0x08000000 + 216*1024+8, LENGTH = 2K-8
ram (xrw) : ORIGIN = 0x20000000, LENGTH = 48K ram (xrw) : ORIGIN = 0x20000000, LENGTH = 48K
sram2 (rw) : ORIGIN = 0x10000000, LENGTH = 16K sram2 (rw) : ORIGIN = 0x10000000, LENGTH = 16K
} }
@ -47,11 +39,6 @@ SECTIONS
_etext = .; _etext = .;
} >flash } >flash
.flag2 bootloader_configuration :
{
KEEP(*(.flag2)) ;
} > flash_cfg
_sidata = LOADADDR(.data); _sidata = LOADADDR(.data);
.data : .data :

View File

@ -12,17 +12,9 @@ _estack = 0x2000c000;
_MIN_STACK_SIZE = 0x400; _MIN_STACK_SIZE = 0x400;
/*
flash_cfg is for storing bootloader data, like last used firmware version.
bootloader_configuration should be equal to (APPLICATION_END_PAGE) page address, from targets/stm32l432/src/memory_layout.h:30; and equal to flash_cfg origin
*/
bootloader_configuration = 0x08000000 + 216*1024+8;
MEMORY MEMORY
{ {
flash (rx) : ORIGIN = 0x08000000, LENGTH = 32K flash (rx) : ORIGIN = 0x08000000, LENGTH = 32K
flash_cfg (rx) : ORIGIN = 0x08000000 + 216*1024+8, LENGTH = 2K-8
ram (xrw) : ORIGIN = 0x20000000, LENGTH = 48K ram (xrw) : ORIGIN = 0x20000000, LENGTH = 48K
sram2 (rw) : ORIGIN = 0x10000000, LENGTH = 16K sram2 (rw) : ORIGIN = 0x10000000, LENGTH = 16K
} }
@ -47,11 +39,6 @@ SECTIONS
_etext = .; _etext = .;
} >flash } >flash
.flag2 bootloader_configuration :
{
KEEP(*(.flag2)) ;
} > flash_cfg
_sidata = LOADADDR(.data); _sidata = LOADADDR(.data);
.data : .data :

View File

@ -13,21 +13,14 @@ _estack = 0x2000c000;
_MIN_STACK_SIZE = 0x400; _MIN_STACK_SIZE = 0x400;
/* /*
len | 20 KB/10p| 196KB-8-8/98p | 2kB/1p | 38 KB/19p | Memory layout of device:
pos | 0->20 KB | 20->216KB-8-8 | 216kB -> 218 kB | 218->256 KB | 20 KB 198KB-8 38 KB
posp | 0-10 | 10-113 | 113-114 | 113-128 | | bootloader | application | secrets/data |
desc | bootloader | application | bootloader data | secrets/data |
Last 8 bytes in application space are occupied by bootloader flags - app
authorization and bootloader activation flag.
*/ */
/* Current firmware version number is concatenated to the firmware code - see .flag marker */
/* flash length is (APPLICATION_END_PAGE-20*1024), where 20K is bootloader */
MEMORY MEMORY
{ {
flash (rx) : ORIGIN = 0x08000000 + 20K, LENGTH = 216K - 20K - 8 flash (rx) : ORIGIN = 0x08005000, LENGTH = 198K - 8
ram (xrw) : ORIGIN = 0x20000000, LENGTH = 48K ram (xrw) : ORIGIN = 0x20000000, LENGTH = 48K
sram2 (rw) : ORIGIN = 0x10000000, LENGTH = 16K sram2 (rw) : ORIGIN = 0x10000000, LENGTH = 16K
} }
@ -63,12 +56,6 @@ SECTIONS
_edata = .; _edata = .;
} >ram AT> flash } >ram AT> flash
.flag :
{
. = ALIGN(8);
KEEP(*(.flag)) ;
} > flash
.bss : .bss :
{ {
. = ALIGN(4); . = ALIGN(4);

View File

@ -12,22 +12,9 @@ _estack = 0x2000c000;
_MIN_STACK_SIZE = 0x400; _MIN_STACK_SIZE = 0x400;
/*
len | 32 KB/16p| 184KB-8-8/92p | 2kB/1p | 38 KB/19p |
pos | 0->32 KB | 32->216KB-8-8 | 216kB -> 218 kB | 218->256 KB |
posp | 0-16 | 16-113 | 113-114 | 113-128 |
desc | bootloader | application | bootloader data | secrets/data |
Last 8 bytes in application space are occupied by bootloader flags - app
authorization and bootloader activation flag.
*/
/* Current firmware version number is concatenated to the firmware code - see .flag marker */
/* flash length is (APPLICATION_END_PAGE-20*1024), where 20K is bootloader */
MEMORY MEMORY
{ {
flash (rx) : ORIGIN = 0x08000000 + 20K + 12K, LENGTH = 216K - 20K - 12K - 8 flash (rx) : ORIGIN = 0x08008000, LENGTH = 186K - 8
ram (xrw) : ORIGIN = 0x20000000, LENGTH = 48K ram (xrw) : ORIGIN = 0x20000000, LENGTH = 48K
sram2 (rw) : ORIGIN = 0x10000000, LENGTH = 16K sram2 (rw) : ORIGIN = 0x10000000, LENGTH = 16K
} }
@ -63,12 +50,6 @@ SECTIONS
_edata = .; _edata = .;
} >ram AT> flash } >ram AT> flash
.flag :
{
. = ALIGN(8);
KEEP(*(.flag)) ;
} > flash
.bss : .bss :
{ {
. = ALIGN(4); . = ALIGN(4);

View File

@ -8,25 +8,21 @@
#include "device.h" #include "device.h"
#include "nfc.h" #include "nfc.h"
static void flush_rx(void) static void flush_rx()
{ {
while(LL_SPI_IsActiveFlag_RXNE(SPI1) != 0) while(LL_SPI_IsActiveFlag_RXNE(SPI1) != 0)
{ {
LL_SPI_ReceiveData8(SPI1); LL_SPI_ReceiveData8(SPI1);
} }
} }
static void wait_for_tx()
static void wait_for_tx(void)
{ {
// while (LL_SPI_IsActiveFlag_BSY(SPI1) == 1) // while (LL_SPI_IsActiveFlag_BSY(SPI1) == 1)
// ; // ;
while(LL_SPI_GetTxFIFOLevel(SPI1) != LL_SPI_TX_FIFO_EMPTY) while(LL_SPI_GetTxFIFOLevel(SPI1) != LL_SPI_TX_FIFO_EMPTY)
; ;
} }
static void wait_for_rx()
static void wait_for_rx(void)
{ {
while(LL_SPI_IsActiveFlag_RXNE(SPI1) == 0) while(LL_SPI_IsActiveFlag_RXNE(SPI1) == 0)
; ;
@ -274,7 +270,7 @@ void ams_print_int1(uint8_t int0)
#endif #endif
} }
int ams_init(void) int ams_init()
{ {
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);
@ -296,7 +292,7 @@ int ams_init(void)
return 0; return 0;
} }
void ams_configure(void) void ams_configure()
{ {
// Should not be used during passive operation. // Should not be used during passive operation.
uint8_t block[4]; uint8_t block[4];

View File

@ -39,8 +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)
int ams_init(void); int ams_init();
void ams_configure(void); 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

@ -61,13 +61,12 @@ static uint8_t master_secret[64];
static uint8_t transport_secret[32]; static uint8_t transport_secret[32];
void crypto_sha256_init(void) void crypto_sha256_init()
{ {
sha256_init(&sha256_ctx); sha256_init(&sha256_ctx);
} }
void crypto_sha512_init(void) void crypto_sha512_init() {
{
cf_sha512_init(&sha512_ctx); cf_sha512_init(&sha512_ctx);
} }
@ -80,7 +79,7 @@ void crypto_load_master_secret(uint8_t * key)
memmove(transport_secret, key+64, 32); memmove(transport_secret, key+64, 32);
} }
void crypto_reset_master_secret(void) void crypto_reset_master_secret()
{ {
memset(master_secret, 0, 64); memset(master_secret, 0, 64);
memset(transport_secret, 0, 32); memset(transport_secret, 0, 32);
@ -108,8 +107,7 @@ void crypto_sha256_final(uint8_t * hash)
sha256_final(&sha256_ctx, hash); sha256_final(&sha256_ctx, hash);
} }
void crypto_sha512_final(uint8_t * hash) void crypto_sha512_final(uint8_t * hash) {
{
// NB: there is also cf_sha512_digest // NB: there is also cf_sha512_digest
cf_sha512_digest_final(&sha512_ctx, hash); cf_sha512_digest_final(&sha512_ctx, hash);
} }
@ -185,14 +183,14 @@ void crypto_sha256_hmac_final(uint8_t * key, uint32_t klen, uint8_t * hmac)
} }
void crypto_ecc256_init(void) void crypto_ecc256_init()
{ {
uECC_set_rng((uECC_RNG_Function)ctap_generate_rng); uECC_set_rng((uECC_RNG_Function)ctap_generate_rng);
_es256_curve = uECC_secp256r1(); _es256_curve = uECC_secp256r1();
} }
void crypto_ecc256_load_attestation_key(void) void crypto_ecc256_load_attestation_key()
{ {
static uint8_t _key [32]; static uint8_t _key [32];
memmove(_key, (uint8_t*)ATTESTATION_KEY_ADDR, 32); memmove(_key, (uint8_t*)ATTESTATION_KEY_ADDR, 32);

View File

@ -34,7 +34,7 @@
#define LOW_FREQUENCY 1 #define LOW_FREQUENCY 1
#define HIGH_FREQUENCY 0 #define HIGH_FREQUENCY 0
void wait_for_usb_tether(void); void wait_for_usb_tether();
uint32_t __90_ms = 0; uint32_t __90_ms = 0;
@ -48,12 +48,12 @@ static bool isLowFreq = 0;
static bool _up_disabled = false; static bool _up_disabled = false;
// #define IS_BUTTON_PRESSED() (0 == (LL_GPIO_ReadInputPort(SOLO_BUTTON_PORT) & SOLO_BUTTON_PIN)) // #define IS_BUTTON_PRESSED() (0 == (LL_GPIO_ReadInputPort(SOLO_BUTTON_PORT) & SOLO_BUTTON_PIN))
static int is_physical_button_pressed(void) static int is_physical_button_pressed()
{ {
return (0 == (LL_GPIO_ReadInputPort(SOLO_BUTTON_PORT) & SOLO_BUTTON_PIN)); return (0 == (LL_GPIO_ReadInputPort(SOLO_BUTTON_PORT) & SOLO_BUTTON_PIN));
} }
static int is_touch_button_pressed(void) static int is_touch_button_pressed()
{ {
int is_pressed = (tsc_read_button(0) || tsc_read_button(1)); int is_pressed = (tsc_read_button(0) || tsc_read_button(1));
#ifndef IS_BOOTLOADER #ifndef IS_BOOTLOADER
@ -69,7 +69,7 @@ static int is_touch_button_pressed(void)
int (*IS_BUTTON_PRESSED)() = is_physical_button_pressed; int (*IS_BUTTON_PRESSED)() = is_physical_button_pressed;
static void edge_detect_touch_button(void) static void edge_detect_touch_button()
{ {
static uint8_t last_touch = 0; static uint8_t last_touch = 0;
uint8_t current_touch = 0; uint8_t current_touch = 0;
@ -92,13 +92,12 @@ static void edge_detect_touch_button(void)
} }
void device_disable_up(bool disable) void device_disable_up(bool disable) {
{
_up_disabled = disable; _up_disabled = disable;
} }
// Timer6 overflow handler. happens every ~90ms. // Timer6 overflow handler. happens every ~90ms.
void TIM6_DAC_IRQHandler(void) void TIM6_DAC_IRQHandler()
{ {
// timer is only 16 bits, so roll it over here // timer is only 16 bits, so roll it over here
TIM6->SR = 0; TIM6->SR = 0;
@ -143,7 +142,7 @@ void USB_IRQHandler(void)
HAL_PCD_IRQHandler(&hpcd); HAL_PCD_IRQHandler(&hpcd);
} }
uint32_t millis(void) uint32_t millis()
{ {
return (((uint32_t)TIM6->CNT) + (__90_ms * 90)); return (((uint32_t)TIM6->CNT) + (__90_ms * 90));
} }
@ -161,7 +160,7 @@ void device_set_status(uint32_t status)
__device_status = status; __device_status = status;
} }
int device_is_button_pressed(void) int device_is_button_pressed()
{ {
return IS_BUTTON_PRESSED(); return IS_BUTTON_PRESSED();
} }
@ -172,13 +171,12 @@ void delay(uint32_t ms)
while ((millis() - time) < ms) while ((millis() - time) < ms)
; ;
} }
void device_reboot()
void device_reboot(void)
{ {
NVIC_SystemReset(); NVIC_SystemReset();
} }
void device_init_button(void) void device_init_button()
{ {
if (tsc_sensor_exists()) if (tsc_sensor_exists())
{ {
@ -228,12 +226,12 @@ void device_init(int argc, char *argv[])
} }
int device_is_nfc(void) int device_is_nfc()
{ {
return _NFC_status; return _NFC_status;
} }
void wait_for_usb_tether(void) void wait_for_usb_tether()
{ {
while (USBD_OK != CDC_Transmit_FS((uint8_t*)"tethered\r\n", 10) ) while (USBD_OK != CDC_Transmit_FS((uint8_t*)"tethered\r\n", 10) )
; ;
@ -244,7 +242,7 @@ void wait_for_usb_tether(void)
; ;
} }
void usbhid_init(void) void usbhid_init()
{ {
if (!isLowFreq) if (!isLowFreq)
{ {
@ -294,12 +292,12 @@ void ctaphid_write_block(uint8_t * data)
} }
void usbhid_close(void) void usbhid_close()
{ {
} }
void main_loop_delay(void) void main_loop_delay()
{ {
} }
@ -309,14 +307,13 @@ static uint32_t winkt1 = 0;
#ifdef LED_WINK_VALUE #ifdef LED_WINK_VALUE
static uint32_t winkt2 = 0; static uint32_t winkt2 = 0;
#endif #endif
void device_wink()
void device_wink(void)
{ {
wink_time = 10; wink_time = 10;
winkt1 = 0; winkt1 = 0;
} }
void heartbeat(void) void heartbeat()
{ {
static int state = 0; static int state = 0;
static uint32_t val = (LED_MAX_SCALER - LED_MIN_SCALER)/2; static uint32_t val = (LED_MAX_SCALER - LED_MIN_SCALER)/2;
@ -385,7 +382,7 @@ void authenticator_read_backup_state(AuthenticatorState * a)
} }
// Return 1 yes backup is init'd, else 0 // Return 1 yes backup is init'd, else 0
int authenticator_is_backup_initialized(void) int authenticator_is_backup_initialized()
{ {
uint8_t header[16]; uint8_t header[16];
uint32_t * ptr = (uint32_t *)flash_addr(STATE2_PAGE); uint32_t * ptr = (uint32_t *)flash_addr(STATE2_PAGE);
@ -410,8 +407,7 @@ void authenticator_write_state(AuthenticatorState * a, int backup)
} }
} }
#if !defined(IS_BOOTLOADER) uint32_t ctap_atomic_count(int sel)
uint32_t ctap_atomic_count(uint32_t amount)
{ {
int offset = 0; int offset = 0;
uint32_t * ptr = (uint32_t *)flash_addr(COUNTER1_PAGE); uint32_t * ptr = (uint32_t *)flash_addr(COUNTER1_PAGE);
@ -426,12 +422,10 @@ uint32_t ctap_atomic_count(uint32_t amount)
uint32_t lastc = 0; uint32_t lastc = 0;
if (amount == 0) if (sel != 0)
{ {
// Use a random count [1-16]. printf2(TAG_ERR,"counter2 not imple\n");
uint8_t rng[1]; exit(1);
ctap_generate_rng(rng, 1);
amount = (rng[0] & 0x0f) + 1;
} }
for (offset = 0; offset < PAGE_SIZE/4; offset += 2) // wear-level the flash for (offset = 0; offset < PAGE_SIZE/4; offset += 2) // wear-level the flash
@ -464,7 +458,7 @@ uint32_t ctap_atomic_count(uint32_t amount)
return lastc; return lastc;
} }
lastc += amount; lastc++;
if (lastc/256 > erases) if (lastc/256 > erases)
{ {
@ -502,10 +496,10 @@ uint32_t ctap_atomic_count(uint32_t amount)
return lastc; return lastc;
} }
#endif
void device_manage(void)
void device_manage()
{ {
#if NON_BLOCK_PRINTING #if NON_BLOCK_PRINTING
int i = 10; int i = 10;
@ -531,7 +525,7 @@ void device_manage(void)
#endif #endif
} }
static int handle_packets(void) static int handle_packets()
{ {
static uint8_t hidmsg[HID_PACKET_SIZE]; static uint8_t hidmsg[HID_PACKET_SIZE];
memset(hidmsg,0, sizeof(hidmsg)); memset(hidmsg,0, sizeof(hidmsg));
@ -567,7 +561,6 @@ static int wait_for_button_activate(uint32_t wait)
} while (!IS_BUTTON_PRESSED()); } while (!IS_BUTTON_PRESSED());
return 0; return 0;
} }
static int wait_for_button_release(uint32_t wait) static int wait_for_button_release(uint32_t wait)
{ {
int ret; int ret;
@ -661,7 +654,7 @@ int ctap_user_verification(uint8_t arg)
return 1; return 1;
} }
void ctap_reset_rk(void) void ctap_reset_rk()
{ {
int i; int i;
printf1(TAG_GREEN, "resetting RK \r\n"); printf1(TAG_GREEN, "resetting RK \r\n");
@ -671,7 +664,7 @@ void ctap_reset_rk(void)
} }
} }
uint32_t ctap_rk_size(void) uint32_t ctap_rk_size()
{ {
return RK_NUM_PAGES * (PAGE_SIZE / sizeof(CTAP_residentKey)); return RK_NUM_PAGES * (PAGE_SIZE / sizeof(CTAP_residentKey));
} }
@ -733,7 +726,7 @@ void ctap_overwrite_rk(int index,CTAP_residentKey * rk)
} }
} }
void boot_st_bootloader(void) void boot_st_bootloader()
{ {
__disable_irq(); __disable_irq();
@ -745,7 +738,7 @@ void boot_st_bootloader(void)
; ;
} }
void boot_solo_bootloader(void) void boot_solo_bootloader()
{ {
LL_IWDG_Enable(IWDG); LL_IWDG_Enable(IWDG);

View File

@ -14,12 +14,12 @@
#include "log.h" #include "log.h"
#include "device.h" #include "device.h"
static void flash_lock(void) static void flash_lock()
{ {
FLASH->CR |= (1U<<31); FLASH->CR |= (1U<<31);
} }
static void flash_unlock(void) static void flash_unlock()
{ {
if (FLASH->CR & FLASH_CR_LOCK) if (FLASH->CR & FLASH_CR_LOCK)
{ {

View File

@ -699,7 +699,7 @@ void SystemClock_Config_LF20(void)
SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_PWREN); SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_PWREN);
} }
void init_usb(void) void init_usb()
{ {
// enable USB power // enable USB power
SET_BIT(PWR->CR2, PWR_CR2_USV); SET_BIT(PWR->CR2, PWR_CR2_USV);

View File

@ -22,7 +22,7 @@
#ifndef _INIT_H_ #ifndef _INIT_H_
#define _INIT_H_ #define _INIT_H_
void init_usb(void); void init_usb();
void init_gpio(void); void init_gpio(void);
void init_debug_uart(void); void init_debug_uart(void);
void init_pwm(void); void init_pwm(void);

View File

@ -57,11 +57,10 @@ void TIM6_DAC_IRQHandler()
__90_ms += 1; __90_ms += 1;
} }
uint32_t millis(void) uint32_t millis()
{ {
return (((uint32_t)TIM6->CNT) + (__90_ms * 90)); return (((uint32_t)TIM6->CNT) + (__90_ms * 90));
} }
void _Error_Handler(char *file, int line) void _Error_Handler(char *file, int line)
{ {
while(1) while(1)

View File

@ -37,33 +37,10 @@
// End of application code. Leave some extra room for future data storage. // End of application code. Leave some extra room for future data storage.
// NOT included in application // NOT included in application
#define APPLICATION_END_PAGE ((PAGES - 20)) #define APPLICATION_END_PAGE ((PAGES - 19))
#define APPLICATION_END_ADDR ((0x08000000 + ((APPLICATION_END_PAGE)*PAGE_SIZE))-8) #define APPLICATION_END_ADDR ((0x08000000 + ((APPLICATION_END_PAGE)*PAGE_SIZE))-8)
// Bootloader state. // Bootloader state.
#define AUTH_WORD_ADDR (APPLICATION_END_ADDR) #define AUTH_WORD_ADDR (APPLICATION_END_ADDR)
#define LAST_ADDR (APPLICATION_END_ADDR-2048 + 8)
#define BOOT_VERSION_PAGE (APPLICATION_END_PAGE)
#define BOOT_VERSION_ADDR (0x08000000 + BOOT_VERSION_PAGE*FLASH_PAGE_SIZE + 8)
#define LAST_PAGE (APPLICATION_END_PAGE-1)
struct flash_memory_st{
uint8_t bootloader[APPLICATION_START_PAGE*2*1024];
uint8_t application[(APPLICATION_END_PAGE-APPLICATION_START_PAGE)*2*1024-8];
uint8_t auth_word[4];
uint8_t bootloader_disabled[4];
// place for more user data
uint8_t _reserved_application_end_mark[8];
uint8_t bootloader_data[2*1024-8];
uint8_t user_data[38*1024];
} __attribute__((packed));
typedef struct flash_memory_st flash_memory_st;
#include <assert.h>
static_assert(sizeof(flash_memory_st) == 256*1024, "Data structure doesn't match flash size");
#endif #endif

View File

@ -359,7 +359,7 @@ static uint32_t WTX_timer;
bool WTX_process(int read_timeout); bool WTX_process(int read_timeout);
void WTX_clear(void) void WTX_clear()
{ {
WTX_sent = false; WTX_sent = false;
WTX_fail = false; WTX_fail = false;
@ -374,7 +374,7 @@ bool WTX_on(int WTX_time)
return true; return true;
} }
bool WTX_off(void) bool WTX_off()
{ {
WTX_timer = 0; WTX_timer = 0;
@ -398,7 +398,7 @@ bool WTX_off(void)
return true; return true;
} }
void WTX_timer_exec(void) void WTX_timer_exec()
{ {
// condition: (timer on) or (not expired[300ms]) // condition: (timer on) or (not expired[300ms])
if ((WTX_timer == 0) || WTX_timer + 300 > millis()) if ((WTX_timer == 0) || WTX_timer + 300 > millis())
@ -856,7 +856,7 @@ void nfc_process_iblock(uint8_t * buf, int len)
static uint8_t ibuf[1024]; static uint8_t ibuf[1024];
static int ibuflen = 0; static int ibuflen = 0;
void clear_ibuf(void) void clear_ibuf()
{ {
ibuflen = 0; ibuflen = 0;
memset(ibuf, 0, sizeof(ibuf)); memset(ibuf, 0, sizeof(ibuf));
@ -969,7 +969,7 @@ void nfc_process_block(uint8_t * buf, unsigned int len)
} }
} }
int nfc_loop(void) int nfc_loop()
{ {
uint8_t buf[32]; uint8_t buf[32];
AMS_DEVICE ams; AMS_DEVICE ams;

View File

@ -6,9 +6,9 @@
#include "apdu.h" #include "apdu.h"
// Return number of bytes read if any. // Return number of bytes read if any.
int nfc_loop(void); int nfc_loop();
int nfc_init(void); int nfc_init();
typedef struct typedef struct
{ {
@ -61,6 +61,6 @@ typedef enum
APP_FIDO, APP_FIDO,
} APPLETS; } APPLETS;
void WTX_timer_exec(void); void WTX_timer_exec();
#endif #endif

View File

@ -8,7 +8,7 @@
#define ELECTRODE_0 TSC_GROUP2_IO1 #define ELECTRODE_0 TSC_GROUP2_IO1
#define ELECTRODE_1 TSC_GROUP2_IO2 #define ELECTRODE_1 TSC_GROUP2_IO2
void tsc_init(void) void tsc_init()
{ {
LL_GPIO_InitTypeDef GPIO_InitStruct; LL_GPIO_InitTypeDef GPIO_InitStruct;
// Enable TSC clock // Enable TSC clock
@ -74,7 +74,7 @@ void tsc_set_electrode(uint32_t channel_ids)
TSC->IOCCR = (channel_ids); TSC->IOCCR = (channel_ids);
} }
void tsc_start_acq(void) void tsc_start_acq()
{ {
TSC->CR &= ~(TSC_CR_START); TSC->CR &= ~(TSC_CR_START);
@ -86,7 +86,7 @@ void tsc_start_acq(void)
TSC->CR |= TSC_CR_START; TSC->CR |= TSC_CR_START;
} }
void tsc_wait_on_acq(void) void tsc_wait_on_acq()
{ {
while ( ! (TSC->ISR & TSC_FLAG_EOA) ) while ( ! (TSC->ISR & TSC_FLAG_EOA) )
; ;
@ -117,7 +117,7 @@ uint32_t tsc_read_button(uint32_t index)
return tsc_read(1) < 45; return tsc_read(1) < 45;
} }
int tsc_sensor_exists(void) int tsc_sensor_exists()
{ {
static uint8_t does = 0; static uint8_t does = 0;
if (does) return 1; if (does) return 1;

View File

@ -3,9 +3,9 @@
#include <stdint.h> #include <stdint.h>
void tsc_init(void); void tsc_init();
int tsc_sensor_exists(void); int tsc_sensor_exists();
// Read button0 or button1 // Read button0 or button1
// Returns 1 if pressed, 0 if not. // Returns 1 if pressed, 0 if not.