Skip to content
Snippets Groups Projects
Commit 9ea448ee authored by Michael Ensslin's avatar Michael Ensslin
Browse files

Fix secret key

parent cb29eb02
No related branches found
No related tags found
No related merge requests found
...@@ -57,23 +57,21 @@ static void cpp_main_in_cpp() { ...@@ -57,23 +57,21 @@ static void cpp_main_in_cpp() {
InputPin(GPIOB, GPIO_PIN_6) // counterclockwise end switch InputPin(GPIOB, GPIO_PIN_6) // counterclockwise end switch
); );
OutputPin led_a_b(GPIOA, GPIO_PIN_0); OutputPin led0_b(GPIOA, GPIO_PIN_0);
OutputPin led_a_g(GPIOA, GPIO_PIN_1); OutputPin led0_g(GPIOA, GPIO_PIN_1);
OutputPin led_a_r(GPIOA, GPIO_PIN_2); OutputPin led0_r(GPIOA, GPIO_PIN_2);
OutputPin led_b_r(GPIOC, GPIO_PIN_14); // led1.green is the power indicator, it is always on.
// LED b.green is connected directly to the DCF77 signal OutputPin led1_b(GPIOC, GPIO_PIN_15);
OutputPin led_b_b(GPIOC, GPIO_PIN_15); led1_b.set();
// led1.green is connected directly to the DCF77 signal,
//led_a_r.set(); // it doesn't exist here
led_a_g.set(); // led1.red is the DCF77 error indicator.
//led_a_b.set(); // it is on if no good signal was received in the last hour
OutputPin led1_r(GPIOC, GPIO_PIN_14);
//led_b_r.set();
//led_b_b.set();
InputPin dcf77_pin(GPIOA, GPIO_PIN_8); InputPin dcf77_pin(GPIOA, GPIO_PIN_8);
dcf77_init(&dcf77_pin); dcf77_init(&dcf77_pin, &led1_r);
while (1) while (1)
{ {
...@@ -100,6 +98,7 @@ static void cpp_main_in_cpp() { ...@@ -100,6 +98,7 @@ static void cpp_main_in_cpp() {
) { ) {
// nothing to see here // nothing to see here
#if WITH_BACKDOOR #if WITH_BACKDOOR
uart_writeline("you used the \x1b[32;1;5msuper-secret\x1b[m backdoor!");
open_door(motor); open_door(motor);
#endif #endif
continue; continue;
...@@ -109,6 +108,7 @@ static void cpp_main_in_cpp() { ...@@ -109,6 +108,7 @@ static void cpp_main_in_cpp() {
uint32_t size = base64_decode(message->buf.data(), message->buf_pos); uint32_t size = base64_decode(message->buf.data(), message->buf_pos);
if (size == 0) { if (size == 0) {
// the base64-decoded message is empty // the base64-decoded message is empty
uart_writeline("base64-decoded message is empty");
continue; continue;
} }
...@@ -121,6 +121,7 @@ static void cpp_main_in_cpp() { ...@@ -121,6 +121,7 @@ static void cpp_main_in_cpp() {
if (size <= HMAC_SIZE + 17) { if (size <= HMAC_SIZE + 17) {
// the message is too small // the message is too small
uart_writeline("message is too small");
continue; continue;
} }
...@@ -133,7 +134,10 @@ static void cpp_main_in_cpp() { ...@@ -133,7 +134,10 @@ static void cpp_main_in_cpp() {
for (uint32_t i = 0; i < HMAC_SIZE; i++) { for (uint32_t i = 0; i < HMAC_SIZE; i++) {
signature_ok &= (digest[i] == message->buf[i]); signature_ok &= (digest[i] == message->buf[i]);
} }
if (!signature_ok) { continue; } if (!signature_ok) {
uart_writeline("HMAC fail");
continue;
}
// see if the timestamp is valid. // see if the timestamp is valid.
uint64_t valid_from = deserialize_u64(&message->buf[HMAC_SIZE]); uint64_t valid_from = deserialize_u64(&message->buf[HMAC_SIZE]);
...@@ -143,10 +147,12 @@ static void cpp_main_in_cpp() { ...@@ -143,10 +147,12 @@ static void cpp_main_in_cpp() {
if (valid_from > current_timestamp) { if (valid_from > current_timestamp) {
// message is not yet valid // message is not yet valid
uart_writeline("message is not yet valid");
continue; continue;
} }
if (valid_until < current_timestamp) { if (valid_until < current_timestamp) {
// mesage is no longer valid // mesage is no longer valid
uart_writeline("message is no longer valid");
continue; continue;
} }
...@@ -163,10 +169,12 @@ static void cpp_main_in_cpp() { ...@@ -163,10 +169,12 @@ static void cpp_main_in_cpp() {
if (!check_info(payload, payload_size)) { if (!check_info(payload, payload_size)) {
// info is not valid // info is not valid
uart_writeline("message info is not valid");
continue; continue;
} }
// it seems like you're in luck. // it seems like you're in luck.
uart_writeline("opening door");
open_door(motor); open_door(motor);
break; break;
} }
...@@ -175,7 +183,10 @@ static void cpp_main_in_cpp() { ...@@ -175,7 +183,10 @@ static void cpp_main_in_cpp() {
// payload: // payload:
// uint8_t * new_key_seed (variable length) // uint8_t * new_key_seed (variable length)
if (payload_size < 1) { continue; } if (payload_size < 1) {
uart_writeline("payload is not valid");
continue;
}
// calculate the new secret key // calculate the new secret key
SHA256 hash; SHA256 hash;
...@@ -184,6 +195,8 @@ static void cpp_main_in_cpp() { ...@@ -184,6 +195,8 @@ static void cpp_main_in_cpp() {
uint8_t digest[32]; uint8_t digest[32];
hash.calculate_digest(digest); hash.calculate_digest(digest);
uart_writeline("writing new secret key");
// write the new secret key // write the new secret key
secret_key_write(digest); secret_key_write(digest);
...@@ -191,6 +204,7 @@ static void cpp_main_in_cpp() { ...@@ -191,6 +204,7 @@ static void cpp_main_in_cpp() {
} }
default: { default: {
// unknown message type // unknown message type
uart_writeline("unknown message type");
continue; continue;
break; break;
... ...
......
...@@ -16,23 +16,32 @@ static void dcf77_update(); ...@@ -16,23 +16,32 @@ static void dcf77_update();
static std::bitset<60> rx_bits; static std::bitset<60> rx_bits;
static uint8_t rx_bitcount = 0; static uint8_t rx_bitcount = 0;
static InputPin *input_pin; static InputPin *input_pin;
static OutputPin *error_pin;
static bool last_input = false; static bool last_input = false;
static uint32_t last_input_time; static uint32_t last_input_time;
static uint64_t last_good_minute_timestamp = 0x8000000000000000ULL;
void dcf77_init(InputPin *pin) { void dcf77_init(InputPin *pin, OutputPin *error_led) {
input_pin = pin; input_pin = pin;
error_pin = error_led;
last_input_time = time_get_64(); last_input_time = time_get_64();
add_systick_callback(dcf77_update); add_systick_callback(dcf77_update);
} }
static void dcf77_update() { static void dcf77_update() {
uint64_t monotonic_time = time_get_64_isr();
if (static_cast<uint64_t>(monotonic_time - last_good_minute_timestamp) > 3600000000) {
error_pin->set();
} else {
error_pin->reset();
}
bool input = input_pin->get(); bool input = input_pin->get();
if (input == last_input) { return; } if (input == last_input) { return; }
last_input = input; last_input = input;
uint64_t edge_timestamp = time_get_64_isr(); uint32_t time_delta = static_cast<uint32_t>(monotonic_time) - last_input_time;
uint32_t time_delta = static_cast<uint32_t>(edge_timestamp) - last_input_time; last_input_time = static_cast<uint32_t>(monotonic_time);
last_input_time = static_cast<uint32_t>(edge_timestamp);
if (input) { if (input) {
// Rising edge; analyze length of the negative duty cycle: // Rising edge; analyze length of the negative duty cycle:
...@@ -48,8 +57,10 @@ static void dcf77_update() { ...@@ -48,8 +57,10 @@ static void dcf77_update() {
// (this includes checking whether there are any/the // (this includes checking whether there are any/the
// right number of bits and whether they make the // right number of bits and whether they make the
// tiniest bit of sense). // tiniest bit of sense).
if (dcf77_analyze(rx_bits, rx_bitcount, edge_timestamp)) { uint64_t unix_timestamp;
set_timestamp(edge_timestamp); if (dcf77_analyze(rx_bits, rx_bitcount, unix_timestamp)) {
set_timestamp(monotonic_time, unix_timestamp);
last_good_minute_timestamp = monotonic_time;
} }
rx_bitcount = 0; rx_bitcount = 0;
} else { } else {
... ...
......
...@@ -4,4 +4,4 @@ ...@@ -4,4 +4,4 @@
#include "pin.h" #include "pin.h"
void dcf77_init(InputPin *dcf_pin); void dcf77_init(InputPin *pin, OutputPin *error_led);
\ No newline at end of file \ No newline at end of file
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
#include <array> #include <array>
#include "main.h"
static uint64_t timer_extended_bits = 0; static uint64_t timer_extended_bits = 0;
uint64_t time_get_64() { uint64_t time_get_64() {
...@@ -77,6 +79,32 @@ void uart_data_received(uint8_t byte) { ...@@ -77,6 +79,32 @@ void uart_data_received(uint8_t byte) {
} }
} }
UARTTxBuffer txbuf;
void uart_transmit_next() {
if (!(huart1.Instance->SR & USART_SR_TXE)) {
// currently transmitting
return;
}
int byte = txbuf.get_next();
if (byte < 0) {
// we're done. manually reset the TC bit,
// otherwise we'll get an infinite interrupt loop.
huart1.Instance->SR &= ~USART_SR_TC;
} else {
// send the next byte
huart1.Instance->DR = byte;
}
}
void uart_writeline(const char *text) {
txbuf.add(text);
txbuf.add('\r');
txbuf.add('\n');
uart_transmit_next();
}
UARTRxBuffer *uart_poll_message() { UARTRxBuffer *uart_poll_message() {
CriticalSectionLock lk; CriticalSectionLock lk;
...@@ -91,3 +119,39 @@ UARTRxBuffer *uart_poll_message() { ...@@ -91,3 +119,39 @@ UARTRxBuffer *uart_poll_message() {
return tmp; return tmp;
} }
int UARTTxBuffer::get_next() {
if (this->start_pos == this->end_pos) { return -1; }
uint8_t result = this->buf[this->start_pos];
start_pos = (start_pos + 1) % this->buf.size();
return result;
}
bool UARTTxBuffer::add(uint8_t byte) {
CriticalSectionLock lk;
uint32_t new_end_pos = (this->end_pos + 1) % this->buf.size();
if (new_end_pos == this->start_pos) {
// the tx buffer is full
return false;
}
this->buf[this->end_pos] = byte;
this->end_pos = new_end_pos;
return true;
}
bool UARTTxBuffer::add(const char *buf) {
while (*buf) {
if (!this->add(static_cast<uint8_t>(*(buf++)))) { return false; }
}
return true;
}
bool UARTTxBuffer::add(const uint8_t *buf, uint32_t len) {
while (len-- > 0) {
if (!this->add(*(buf++))) { return false; }
}
return true;
}
\ No newline at end of file
...@@ -43,6 +43,18 @@ public: ...@@ -43,6 +43,18 @@ public:
} }
}; };
class UARTTxBuffer {
public:
std::array<uint8_t, 256> buf;
uint32_t start_pos = 0;
uint32_t end_pos = 0;
int get_next();
bool add(uint8_t byte);
bool add(const char *buf);
bool add(const uint8_t *buf, uint32_t len);
};
/** /**
* Returns nullptr if no new message has been received. * Returns nullptr if no new message has been received.
* Returns UARTRxBuffer containing a message if a new message has been * Returns UARTRxBuffer containing a message if a new message has been
...@@ -89,6 +101,16 @@ void timer_update_extended_bits(); ...@@ -89,6 +101,16 @@ void timer_update_extended_bits();
*/ */
void uart_data_received(uint8_t byte); void uart_data_received(uint8_t byte);
/**
* To be called from the UART TX interrupt handler
*/
void uart_transmit_next();
/**
* Transmits a line on UART.
*/
void uart_writeline(const char *text);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
\ No newline at end of file
...@@ -181,7 +181,10 @@ static void MX_USART1_UART_Init(void) ...@@ -181,7 +181,10 @@ static void MX_USART1_UART_Init(void)
} }
/* USER CODE BEGIN USART1_Init 2 */ /* USER CODE BEGIN USART1_Init 2 */
huart1.Instance->CR1 |= USART_CR1_RXNEIE; huart1.Instance->CR1 |= (
USART_CR1_RXNEIE |
USART_CR1_TCIE
);
HAL_NVIC_SetPriority(USART1_IRQn, 4, 0); HAL_NVIC_SetPriority(USART1_IRQn, 4, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn); HAL_NVIC_EnableIRQ(USART1_IRQn);
... ...
......
...@@ -16,12 +16,12 @@ bool secret_key_write(uint8_t secret_key[32]) { ...@@ -16,12 +16,12 @@ bool secret_key_write(uint8_t secret_key[32]) {
erase_init.NbPages = 1; erase_init.NbPages = 1;
uint32_t page_error; uint32_t page_error;
volatile auto a = HAL_FLASHEx_Erase(&erase_init, &page_error); HAL_FLASHEx_Erase(&erase_init, &page_error);
for (uint8_t i = 0; i < sizeof(SECRET_KEY)/2; i++) { for (uint8_t i = 0; i < sizeof(SECRET_KEY)/2; i++) {
volatile auto b = HAL_FLASH_Program( HAL_FLASH_Program(
FLASH_TYPEPROGRAM_HALFWORD, FLASH_TYPEPROGRAM_HALFWORD,
reinterpret_cast<uint32_t>(&SECRET_KEY), reinterpret_cast<uint32_t>(&SECRET_KEY) + i * 2,
reinterpret_cast<uint16_t *>(secret_key)[i] reinterpret_cast<uint16_t *>(secret_key)[i]
); );
} }
... ...
......
...@@ -211,6 +211,10 @@ void USART1_IRQHandler(void) ...@@ -211,6 +211,10 @@ void USART1_IRQHandler(void)
{ {
uart_data_received(huart1.Instance->DR); uart_data_received(huart1.Instance->DR);
} }
if (huart1.Instance->SR & USART_SR_TXE)
{
uart_transmit_next();
}
} }
/* USER CODE END 1 */ /* USER CODE END 1 */
... ...
......
...@@ -36,9 +36,9 @@ uint64_t get_timestamp() { ...@@ -36,9 +36,9 @@ uint64_t get_timestamp() {
return (time_get_64() / static_cast<uint64_t>(1000000)) + get_timestamp_offset(); return (time_get_64() / static_cast<uint64_t>(1000000)) + get_timestamp_offset();
} }
void set_timestamp(uint64_t timestamp) { void set_timestamp(uint64_t monotonic_timestamp, uint64_t unix_timestamp) {
uint64_t microseconds_since_boot = time_get_64(); uint64_t microseconds_since_boot = monotonic_timestamp;
uint64_t seconds_since_boot = microseconds_since_boot / static_cast<uint64_t>(1000000); uint64_t seconds_since_boot = microseconds_since_boot / static_cast<uint64_t>(1000000);
timestamp_offset = timestamp - seconds_since_boot; timestamp_offset = unix_timestamp - seconds_since_boot;
} }
\ No newline at end of file
...@@ -22,5 +22,5 @@ private: ...@@ -22,5 +22,5 @@ private:
/** returns the UNIX time, as synchronized through set_timestamp(). */ /** returns the UNIX time, as synchronized through set_timestamp(). */
uint64_t get_timestamp(); uint64_t get_timestamp();
/** sets a new UNIX time from an external time source */ /** sets a new UNIX time from an external time source, valid at monotonic_timestamp */
void set_timestamp(uint64_t timestamp); void set_timestamp(uint64_t monotonic_timestamp, uint64_t unix_timestamp);
\ No newline at end of file \ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment