mirror of
https://github.com/polhenarejos/pico-keys-sdk.git
synced 2026-08-27 15:07:06 +01:00
@@ -342,6 +342,7 @@ list(APPEND PICOKEYS_SOURCES
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/button.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/led/led.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/signal.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/audit.c
|
||||
)
|
||||
|
||||
if(ESP_PLATFORM)
|
||||
|
||||
@@ -34,9 +34,16 @@ extern bool app_exists(const uint8_t *aid, size_t aid_len);
|
||||
extern int register_app(int (*)(app_t *, uint8_t), const uint8_t *);
|
||||
extern int select_app(const uint8_t *aid, size_t aid_len);
|
||||
|
||||
typedef enum {
|
||||
CMD_FLAG_NONE = 0x00,
|
||||
CMD_FLAG_AUDIT_LOG = 0x01,
|
||||
CMD_FLAG_CRITICAL = 0x02,
|
||||
} cmd_flags_t;
|
||||
|
||||
typedef struct cmd {
|
||||
uint8_t ins;
|
||||
int (*cmd_handler)(void);
|
||||
cmd_flags_t flags;
|
||||
} cmd_t;
|
||||
|
||||
extern uint8_t num_apps;
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "picokeys.h"
|
||||
#include "signal.h"
|
||||
#include "audit.h"
|
||||
|
||||
void audit_entry_set_current_event(uint16_t event) {
|
||||
signal_audit_evt_data_t data = {.cmd = AUDIT_CMD_EVT, .value = event};
|
||||
signal_emit_param(SIGNAL_AUDIT_EVT, &data);
|
||||
}
|
||||
|
||||
void audit_log_current_entry_with_result(uint16_t result) {
|
||||
signal_audit_evt_data_t data = {.cmd = AUDIT_CMD_LOG, .value = result};
|
||||
signal_emit_param(SIGNAL_AUDIT_EVT, &data);
|
||||
}
|
||||
|
||||
void audit_entry_set_current_flags(audit_entry_flags_t flags) {
|
||||
signal_audit_evt_data_t data = {.cmd = AUDIT_CMD_SET_FLAGS, .value = flags};
|
||||
signal_emit_param(SIGNAL_AUDIT_EVT, &data);
|
||||
}
|
||||
void audit_entry_set_current_object(uint16_t object_id) {
|
||||
signal_audit_evt_data_t data = {.cmd = AUDIT_CMD_SET_OBJECT, .value = object_id};
|
||||
signal_emit_param(SIGNAL_AUDIT_EVT, &data);
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _AUDIT_H_
|
||||
#define _AUDIT_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
static const uint8_t SIGNAL_AUDIT_EVT = 10;
|
||||
#define AUDIT_EVT_APP_EVT 0x8000
|
||||
|
||||
typedef enum {
|
||||
AUDIT_EVT_LOG_READ = 0x0001,
|
||||
AUDIT_EVT_LOG_CLEARED,
|
||||
AUDIT_EVT_FIRMWARE_UPDATE,
|
||||
AUDIT_EVT_INIT,
|
||||
AUDIT_EVT_POWER_UP,
|
||||
AUDIT_EVT_SET_RTC,
|
||||
} audit_evt_t;
|
||||
|
||||
typedef enum {
|
||||
AUDIT_EF_SUCCESS = 0x0001,
|
||||
AUDIT_EF_FAIL = 0x0002,
|
||||
AUDIT_EF_DENIED = 0x0004,
|
||||
|
||||
AUDIT_EF_USER = 0x0010,
|
||||
AUDIT_EF_ADMIN = 0x0020,
|
||||
|
||||
AUDIT_EF_CRITICAL = 0x0100,
|
||||
AUDIT_EF_TIME_UNSYNCED = 0x0200,
|
||||
} audit_entry_flags_t;
|
||||
|
||||
typedef enum {
|
||||
AUDIT_CMD_EVT = 1,
|
||||
AUDIT_CMD_SET_OBJECT = 2,
|
||||
AUDIT_CMD_SET_FLAGS = 3,
|
||||
AUDIT_CMD_LOG = 4
|
||||
} audit_cmd_t;
|
||||
|
||||
typedef struct {
|
||||
audit_cmd_t cmd;
|
||||
uint16_t value;
|
||||
} signal_audit_evt_data_t;
|
||||
|
||||
extern void audit_entry_set_current_event(uint16_t event);
|
||||
extern void audit_entry_set_current_flags(audit_entry_flags_t flags);
|
||||
extern void audit_entry_set_current_object(uint16_t object_id);
|
||||
extern void audit_log_current_entry_with_result(uint16_t res);
|
||||
|
||||
#endif // _AUDIT_H_
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "pico_time.h"
|
||||
#include "serial.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "signal.h"
|
||||
|
||||
app_t apps[16];
|
||||
uint8_t num_apps = 0;
|
||||
@@ -222,6 +223,7 @@ int main(void) {
|
||||
#if defined(PICO_RP2350) || defined(ENABLE_EMULATION)
|
||||
plugin_init();
|
||||
#endif
|
||||
signal_emit(SIGNAL_INIT);
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
xTaskCreatePinnedToCore(core0_loop, "core0", 4096*ITF_TOTAL*2, NULL, CONFIG_TINYUSB_TASK_PRIORITY - 1, &hcore0, ESP32_CORE0);
|
||||
|
||||
@@ -1,16 +1,25 @@
|
||||
/*
|
||||
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
|
||||
* Copyright (c) 2026 Pol Henarejos.
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PICOKEYS_PLUGIN_API_H
|
||||
#define PICOKEYS_PLUGIN_API_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "signal.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define PICOKEYS_PLUGIN_EXPORT __declspec(dllexport)
|
||||
@@ -47,16 +56,17 @@ typedef struct pk_plugin_imports {
|
||||
uint32_t abi_version;
|
||||
uint32_t struct_size;
|
||||
int (*printf)(const char *fmt, ...);
|
||||
int (*signal_add)(uint8_t code, signal_flag_t flags, signal_handler_t handler);
|
||||
} pk_plugin_imports_t;
|
||||
|
||||
typedef void (*pk_plugin_hello_fn)(const pk_plugin_imports_t *imports);
|
||||
typedef void (*pk_plugin_init_fn)(const pk_plugin_imports_t *imports);
|
||||
|
||||
typedef struct pk_plugin_header {
|
||||
uint32_t magic;
|
||||
uint32_t abi_version;
|
||||
uint32_t header_size;
|
||||
uint32_t image_size;
|
||||
pk_plugin_hello_fn hello;
|
||||
pk_plugin_init_fn init;
|
||||
} pk_plugin_header_t;
|
||||
|
||||
void plugin_init(void);
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
/*
|
||||
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
|
||||
* Copyright (c) 2026 Pol Henarejos.
|
||||
* Copyright (c) 2022 Pol Henarejos.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "picokeys_plugin_api.h"
|
||||
#include "signal.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
@@ -68,7 +77,7 @@ static const pk_plugin_header_t *pk_plugin_get_valid(void) {
|
||||
(unsigned long)plugin->abi_version,
|
||||
(unsigned long)plugin->header_size,
|
||||
(unsigned long)plugin->image_size,
|
||||
(void *)plugin->hello);
|
||||
(void *)plugin->init);
|
||||
if (plugin->magic != PICOKEYS_PLUGIN_MAGIC) {
|
||||
printf("Plugin rejected: bad magic\n");
|
||||
return NULL;
|
||||
@@ -81,7 +90,7 @@ static const pk_plugin_header_t *pk_plugin_get_valid(void) {
|
||||
printf("Plugin rejected: short header\n");
|
||||
return NULL;
|
||||
}
|
||||
if (!plugin->hello) {
|
||||
if (!plugin->init) {
|
||||
printf("Plugin rejected: missing entry point\n");
|
||||
return NULL;
|
||||
}
|
||||
@@ -108,7 +117,7 @@ static const pk_plugin_header_t *pk_plugin_get_valid(void) {
|
||||
(unsigned long)plugin->abi_version,
|
||||
(unsigned long)plugin->header_size,
|
||||
(unsigned long)plugin->image_size,
|
||||
(unsigned long)(uintptr_t)plugin->hello);
|
||||
(unsigned long)(uintptr_t)plugin->init);
|
||||
if (plugin->magic != PICOKEYS_PLUGIN_MAGIC) {
|
||||
printf("Plugin rejected: bad magic\n");
|
||||
return NULL;
|
||||
@@ -126,8 +135,8 @@ static const pk_plugin_header_t *pk_plugin_get_valid(void) {
|
||||
printf("Plugin rejected: bad image size\n");
|
||||
return NULL;
|
||||
}
|
||||
if (!plugin->hello || !pk_plugin_ptr_in_range((const void *)plugin->hello)) {
|
||||
printf("Plugin rejected: hello pointer out of range\n");
|
||||
if (!plugin->init || !pk_plugin_ptr_in_range((const void *)plugin->init)) {
|
||||
printf("Plugin rejected: init pointer out of range\n");
|
||||
return NULL;
|
||||
}
|
||||
return plugin;
|
||||
@@ -145,8 +154,7 @@ void plugin_init(void) {
|
||||
.abi_version = PICOKEYS_PLUGIN_ABI_VERSION,
|
||||
.struct_size = sizeof(imports),
|
||||
.printf = printf,
|
||||
.signal_add = signal_add,
|
||||
};
|
||||
printf("Calling plugin hello function\n");
|
||||
plugin->hello(&imports);
|
||||
printf("Plugin hello function returned\n");
|
||||
plugin->init(&imports);
|
||||
}
|
||||
|
||||
+18
-7
@@ -31,6 +31,7 @@
|
||||
#include "random.h"
|
||||
#include "crypto_utils.h"
|
||||
#include "usb.h"
|
||||
#include "audit.h"
|
||||
|
||||
#ifdef PICO_PLATFORM
|
||||
extern char __flash_binary_start;
|
||||
@@ -257,6 +258,7 @@ static int cmd_write(void) {
|
||||
#endif
|
||||
}
|
||||
else if (p1 == 0x2) { // SET TIME
|
||||
audit_entry_set_current_event(AUDIT_EVT_SET_RTC);
|
||||
time_t tv_sec = 0;
|
||||
if (p2 != 0x1 && p2 != 0x2) {
|
||||
return SW_INCORRECT_P1P2();
|
||||
@@ -405,16 +407,17 @@ static int cmd_reboot_bootsel(void) {
|
||||
#define INS_REBOOT_BOOTSEL 0x1F
|
||||
|
||||
static const cmd_t cmds[] = {
|
||||
{ INS_KEYDEV_SIGN, cmd_keydev_sign },
|
||||
{ INS_WRITE, cmd_write },
|
||||
{ INS_KEYDEV_SIGN, cmd_keydev_sign, CMD_FLAG_AUDIT_LOG },
|
||||
{ INS_WRITE, cmd_write, CMD_FLAG_AUDIT_LOG | CMD_FLAG_CRITICAL },
|
||||
#if defined(PICO_RP2350) || defined(ESP_PLATFORM)
|
||||
{ INS_SECURE, cmd_secure },
|
||||
{ INS_SECURE, cmd_secure, CMD_FLAG_AUDIT_LOG | CMD_FLAG_CRITICAL },
|
||||
#endif
|
||||
{ INS_READ, cmd_read },
|
||||
{ INS_READ, cmd_read, CMD_FLAG_NONE },
|
||||
#ifdef PICO_PLATFORM
|
||||
{ INS_REBOOT_BOOTSEL, cmd_reboot_bootsel },
|
||||
{ INS_REBOOT_BOOTSEL, cmd_reboot_bootsel, CMD_FLAG_NONE },
|
||||
#endif
|
||||
{ 0x00, 0x0 }
|
||||
|
||||
{ 0x00, 0x00, CMD_FLAG_NONE } // End of table
|
||||
};
|
||||
|
||||
static int rescue_process_apdu(void) {
|
||||
@@ -423,9 +426,17 @@ static int rescue_process_apdu(void) {
|
||||
}
|
||||
for (const cmd_t *cmd = cmds; cmd->ins != 0x00; cmd++) {
|
||||
if (cmd->ins == INS(apdu)) {
|
||||
audit_entry_set_current_event(AUDIT_EVT_APP_EVT | INS(apdu));
|
||||
audit_entry_set_current_object(make_uint16_be(P1(apdu), P2(apdu)));
|
||||
int r = cmd->cmd_handler();
|
||||
if (cmd->flags & CMD_FLAG_AUDIT_LOG) {
|
||||
if (cmd->flags & CMD_FLAG_CRITICAL) {
|
||||
audit_entry_set_current_flags(AUDIT_EF_CRITICAL);
|
||||
}
|
||||
audit_log_current_entry_with_result(r);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
}
|
||||
return SW_INS_NOT_SUPPORTED();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user