diff --git a/picokeys_sdk_import.cmake b/picokeys_sdk_import.cmake
index 1c33f43..78dfa11 100644
--- a/picokeys_sdk_import.cmake
+++ b/picokeys_sdk_import.cmake
@@ -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)
diff --git a/src/apdu.h b/src/apdu.h
index f0c8375..5874f49 100644
--- a/src/apdu.h
+++ b/src/apdu.h
@@ -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;
diff --git a/src/audit.c b/src/audit.c
new file mode 100644
index 0000000..9fd0fee
--- /dev/null
+++ b/src/audit.c
@@ -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 .
+ */
+
+#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);
+}
diff --git a/src/audit.h b/src/audit.h
new file mode 100644
index 0000000..a08a146
--- /dev/null
+++ b/src/audit.h
@@ -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 .
+ */
+
+#ifndef _AUDIT_H_
+#define _AUDIT_H_
+
+#include
+
+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_
diff --git a/src/main.c b/src/main.c
index bd9daf2..b59f923 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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);
diff --git a/src/plugin/picokeys_plugin_api.h b/src/plugin/picokeys_plugin_api.h
index 6e41ff5..d38644b 100644
--- a/src/plugin/picokeys_plugin_api.h
+++ b/src/plugin/picokeys_plugin_api.h
@@ -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 .
*/
#ifndef PICOKEYS_PLUGIN_API_H
#define PICOKEYS_PLUGIN_API_H
#include
+#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);
diff --git a/src/plugin/plugin_loader.c b/src/plugin/plugin_loader.c
index c655478..3457d04 100644
--- a/src/plugin/plugin_loader.c
+++ b/src/plugin/plugin_loader.c
@@ -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 .
*/
#include "picokeys_plugin_api.h"
+#include "signal.h"
#include
#include
@@ -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);
}
diff --git a/src/rescue.c b/src/rescue.c
index 8b56aef..d6d1fa2 100644
--- a/src/rescue.c
+++ b/src/rescue.c
@@ -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();
-}
+}
\ No newline at end of file