TAI64N ハードウェア実装追加
- SE050 モノトニックカウンタ使用 - リプレイ防止用タイムスタンプ - テスト実装済み
This commit is contained in:
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user