Add set/get RTC.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos
2026-01-19 16:36:21 +01:00
parent f108eebb93
commit 8a0ef0b30c

View File

@@ -22,13 +22,23 @@
#ifdef PICO_PLATFORM
#include "pico/bootrom.h"
#include "hardware/watchdog.h"
#include "pico/aon_timer.h"
#else
#include <sys/time.h>
#include <time.h>
#endif
#include "mbedtls/ecdsa.h"
#include "mbedtls/sha256.h"
#include "random.h"
#ifdef PICO_PLATFORM
extern char __flash_binary_start;
extern char __flash_binary_end;
#endif
int rescue_process_apdu();
int rescue_unload();
bool set_rtc = false;
const uint8_t rescue_aid[] = {
8,
@@ -172,7 +182,9 @@ int cmd_write() {
return SW_WRONG_LENGTH();
}
if (P1(apdu) == 0x1) { // PHY
uint8_t p1 = P1(apdu), p2 = P2(apdu);
if (p1 == 0x1) { // PHY
#ifndef ENABLE_EMULATION
int ret = phy_unserialize_data(apdu.data, (uint16_t)apdu.nc, &phy_data);
if (ret == PICOKEY_OK) {
@@ -182,6 +194,41 @@ int cmd_write() {
}
#endif
}
else if (p1 == 0x2) { // SET TIME
time_t tv_sec = 0;
if (p2 != 0x1 && p2 != 0x2) {
return SW_INCORRECT_P1P2();
}
if (p2 == 0x1) {
if (apdu.nc != 8) {
return SW_WRONG_LENGTH();
}
struct tm tm;
tm.tm_year = get_uint16_t_be(apdu.data) - 1900;
tm.tm_mon = apdu.data[2];
tm.tm_mday = apdu.data[3];
tm.tm_wday = apdu.data[4];
tm.tm_hour = apdu.data[5];
tm.tm_min = apdu.data[6];
tm.tm_sec = apdu.data[7];
tv_sec = mktime(&tm);
}
else if (p2 == 0x2) {
if (apdu.nc != 4) {
return SW_WRONG_LENGTH();
}
uint32_t t = (apdu.data[0] << 24) | (apdu.data[1] << 16) | (apdu.data[2] << 8) | apdu.data[3];
tv_sec = (time_t)t;
}
#ifdef PICO_PLATFORM
struct timespec tv = {.tv_sec = tv_sec, .tv_nsec = 0};
aon_timer_set_time(&tv);
#else
struct timeval tv = {.tv_sec = tv_sec, .tv_usec = 0};
settimeofday(&tv, NULL);
#endif
set_rtc = true;
}
led_3_blinks();
return SW_OK();
}
@@ -191,7 +238,7 @@ int cmd_read() {
return SW_WRONG_LENGTH();
}
uint8_t p1 = P1(apdu);
uint8_t p1 = P1(apdu), p2 = P2(apdu);
if (p1 == 0x1) { // PHY
#ifndef ENABLE_EMULATION
uint16_t len = 0;
@@ -210,6 +257,12 @@ int cmd_read() {
res_APDU_size += put_uint32_t_be(total, res_APDU + res_APDU_size);
res_APDU_size += put_uint32_t_be(nfiles, res_APDU + res_APDU_size);
res_APDU_size += put_uint32_t_be(size, res_APDU + res_APDU_size);
#ifdef PICO_PLATFORM
uintptr_t start = (uintptr_t) &__flash_binary_start;
uintptr_t end = (uintptr_t) &__flash_binary_end;
uint32_t fw_size = (uint32_t)(end - start);
res_APDU_size += put_uint32_t_be(fw_size, res_APDU + res_APDU_size);
#endif
}
else if (p1 == 0x3) { // OTP SECURE BOOT STATUS
res_APDU_size = 0;
@@ -220,6 +273,35 @@ int cmd_read() {
res_APDU[res_APDU_size++] = locked ? 0x1 : 0x0;
res_APDU[res_APDU_size++] = bootkey;
}
else if (p1 == 0x4) { // GET TIME
if (p2 != 0x1 && p2 != 0x2) {
return SW_INCORRECT_P1P2();
}
if (!set_rtc) {
return SW_CONDITIONS_NOT_SATISFIED();
}
res_APDU_size = 0;
#ifdef PICO_PLATFORM
struct timespec tv;
aon_timer_get_time(&tv);
#else
struct timeval tv;
gettimeofday(&tv, NULL);
#endif
if (p2 == 0x1) {
struct tm *tm = localtime(&tv.tv_sec);
res_APDU_size += put_uint16_t_be(tm->tm_year + 1900, res_APDU);
res_APDU[res_APDU_size++] = tm->tm_mon;
res_APDU[res_APDU_size++] = tm->tm_mday;
res_APDU[res_APDU_size++] = tm->tm_wday;
res_APDU[res_APDU_size++] = tm->tm_hour;
res_APDU[res_APDU_size++] = tm->tm_min;
res_APDU[res_APDU_size++] = tm->tm_sec;
}
else if (p2 == 0x2) {
res_APDU_size += put_uint32_t_be((uint32_t)tv.tv_sec, res_APDU);
}
}
return SW_OK();
}