TAI64N ハードウェア実装追加

- SE050 モノトニックカウンタ使用
- リプレイ防止用タイムスタンプ
- テスト実装済み
This commit is contained in:
km
2026-03-27 05:26:46 +09:00
parent f23542f06c
commit 344f86b07f
4 changed files with 317 additions and 1 deletions
+121
View File
@@ -0,0 +1,121 @@
/**
* @file se050_tai64n_hw.c
* @brief TAI64N using SE050 Hardware Monotonic Counter
*/
#include "se050_tai64n_hw.h"
#include <string.h>
/* SE050 API - defined in test file or linked from SE050 library */
extern int Se05x_API_ReadCounter(void *session, uint32_t obj_id, uint32_t *counter);
extern int Se05x_API_IncrementCounter(void *session, uint32_t obj_id);
#define TAI64N_BASE_UPPER 0x40000000ULL
static void store64_be(uint8_t *out, uint64_t val)
{
out[0] = (uint8_t)(val >> 56);
out[1] = (uint8_t)(val >> 48);
out[2] = (uint8_t)(val >> 40);
out[3] = (uint8_t)(val >> 32);
out[4] = (uint8_t)(val >> 24);
out[5] = (uint8_t)(val >> 16);
out[6] = (uint8_t)(val >> 8);
out[7] = (uint8_t)(val);
}
static uint32_t load32_be(const uint8_t *in)
{
return ((uint32_t)in[0] << 24) |
((uint32_t)in[1] << 16) |
((uint32_t)in[2] << 8) |
((uint32_t)in[3]);
}
int se050_tai64n_hw_read_counter(void *session, uint32_t *counter)
{
if (!session || !counter) {
return -1;
}
/* SE050 API call to read monotonic counter */
/* This uses the actual SE050 hardware counter */
uint32_t obj_id = SE050_MONOTONIC_COUNTER_ID;
int status = Se05x_API_ReadCounter(session, obj_id, counter);
if (status != 0) {
return -1;
}
return 0;
}
int se050_tai64n_hw_increment(void *session)
{
if (!session) {
return -1;
}
/* SE050 API call to increment counter */
uint32_t obj_id = SE050_MONOTONIC_COUNTER_ID;
int status = Se05x_API_IncrementCounter(session, obj_id);
if (status != 0) {
return -1;
}
return 0;
}
int se050_tai64n_hw_now(void *session, uint8_t out[12])
{
uint32_t counter;
uint64_t tai64_upper;
uint32_t unix_sec;
if (!session || !out) {
return -1;
}
/* Read SE050 monotonic counter */
if (se050_tai64n_hw_read_counter(session, &counter) != 0) {
return -1;
}
/* Use counter as lower 32 bits of nanoseconds */
/* Upper 32 bits: TAI base + approximate Unix seconds */
unix_sec = counter / 1000000000UL; /* Approximate seconds from counter */
tai64_upper = TAI64N_BASE_UPPER + unix_sec;
/* Encode as TAI64N: 64-bit TAI + 32-bit nanoseconds */
store64_be(out, tai64_upper << 32);
store64_be(out + 8, counter);
return 0;
}
int se050_tai64n_hw_check_window(const uint8_t timestamp[12],
const uint8_t current[12],
uint32_t window)
{
uint32_t ts_counter, curr_counter;
int32_t diff;
if (!timestamp || !current) {
return -1;
}
/* Compare monotonic counter values (lower 32 bits) */
ts_counter = load32_be(timestamp + 8);
curr_counter = load32_be(current + 8);
/* Check if within window (counter difference) */
diff = (int32_t)(curr_counter - ts_counter);
if (diff < 0) diff = -diff;
/* Window in counter units (assuming ~1 increment per nanosecond) */
/* For practical use: window in seconds * 1000000000 */
uint32_t window_units = window * 1000000000UL;
return (diff <= (int32_t)window_units) ? 1 : 0;
}