Arduino_CAN
로딩중...
검색중...
일치하는것 없음
minimac.h 파일 참조

Mini-MAC 프로토콜 구현용 헤더 파일 더 자세히 ...

#include <Arduino.h>
#include <EEPROM.h>
#include <MD5.h>
minimac.h에 대한 include 의존 그래프
이 그래프는 이 파일을 직/간접적으로 include 하는 파일들을 보여줍니다.:

이 파일의 소스 코드 페이지로 가기

데이터 구조

struct  MiniMacHist
 과거 페이로드를 저장하기 위한 구조체 더 자세히 ...
 

매크로

#define MINIMAC_KEY_LEN   16
 Mini-MAC HMAC 키 길이 (16바이트, 128비트)
 
#define MINIMAC_TAG_LEN   4
 Mini-MAC 다이제스트에서 사용할 태그 길이 (4바이트, 32비트)
 
#define MINIMAC_HIST_LEN   5
 메시지 히스토리 최대 개수 (λ = 5)
 
#define MINIMAC_MAX_DATA   8
 CAN 데이터 필드 최대 길이 (8바이트)
 

함수

void minimac_init (uint16_t can_id, const uint8_t *key)
 Mini-MAC 프로토콜 초기화
 
uint8_t minimac_sign (uint8_t *data, uint8_t payload_len)
 송신 전 페이로드에 Mini-MAC 태그 생성 및 붙이기
 
bool minimac_verify (const uint8_t *data, uint8_t payload_len, const uint8_t *tag)
 수신 후 Mini-MAC 태그 검증 및 내부 상태 갱신
 

상세한 설명

Mini-MAC 프로토콜 구현용 헤더 파일

Mini-MAC은 CAN 버스 환경에서 경량화된 메시지 인증과 재생 공격 방어를 제공하는 HMAC 기반 프로토콜입니다. 본 헤더에는 키/태그 길이, 메시지 히스토리 정의와 초기화·서명·검증 함수의 인터페이스가 포함되어 있습니다.

minimac.h 파일에서 정의되었습니다.

매크로 문서화

◆ MINIMAC_HIST_LEN

#define MINIMAC_HIST_LEN   5

메시지 히스토리 최대 개수 (λ = 5)

minimac.h 파일의 30 번째 라인에서 정의되었습니다.

◆ MINIMAC_KEY_LEN

#define MINIMAC_KEY_LEN   16

Mini-MAC HMAC 키 길이 (16바이트, 128비트)

< ArduinoMD5 라이브러리 사용

minimac.h 파일의 20 번째 라인에서 정의되었습니다.

◆ MINIMAC_MAX_DATA

#define MINIMAC_MAX_DATA   8

CAN 데이터 필드 최대 길이 (8바이트)

minimac.h 파일의 35 번째 라인에서 정의되었습니다.

◆ MINIMAC_TAG_LEN

#define MINIMAC_TAG_LEN   4

Mini-MAC 다이제스트에서 사용할 태그 길이 (4바이트, 32비트)

minimac.h 파일의 25 번째 라인에서 정의되었습니다.

함수 문서화

◆ minimac_init()

void minimac_init ( uint16_t can_id,
const uint8_t * key )

Mini-MAC 프로토콜 초기화

매개변수
can_id보호할 CAN 메시지 식별자 (16비트)
key그룹 키 (128비트, 16바이트)

EEPROM에서 이전 상태를 불러오고, 유효하지 않으면 내부 카운터와 히스토리를 초기화하여 fresh 상태로 설정합니다.

Mini-MAC 프로토콜 초기화

매개변수
can_id보호할 CAN 메시지 식별자 (16비트)
keyMini-MAC HMAC 키 (128비트, 16바이트)

Serial 포트를 115200bps로 초기화하고, mm_id와 mm_key 전역 변수에 인자를 설정한다. EEPROM에서 이전에 저장된 mm_counter와 메시지 히스토리를 불러오되(load_state()), 저장된 시그니처가 없으면 fresh 상태로 간주하여 mm_counter와 mm_hist_cnt를 0으로 초기화한 뒤(save_state()), EEPROM에 초기 상태를 기록한다. 디버그용으로 Serial.print를 통해 초기화 과정을 출력한다.

minimac.cpp 파일의 241 번째 라인에서 정의되었습니다.

241 {
242 /* Serial 초기화: 디버그 출력용 */
243 Serial.begin(115200);
244 while (!Serial)
245 /* 시리얼 포트가 준비될 때까지 대기 */;
246 Serial.println("[DBG] minimac_init()");
247
248 /* (1) CAN ID 설정: 보호할 그룹 식별자 */
249 mm_id = can_id;
250
251 /* (2) 그룹 키 복사: 16바이트 비밀키 */
252 memcpy(mm_key, key, MINIMAC_KEY_LEN);
253
254 /* (3) EEPROM에서 이전 상태 불러오기 */
255 if (!load_state()) {
256 /* EEPROM에 유효한 시그니처 없음: fresh 초기화 */
257 Serial.println("[DBG] minimac_init: no EEPROM state, initialize fresh");
258
259 /* (3a) 카운터 초기화 */
260 mm_counter = 0;
261
262 /* (3b) 히스토리 개수 초기화 */
263 mm_hist_cnt = 0;
264
265 /* (3c) 초기 상태 EEPROM에 저장 */
266 save_state();
267 }
268}
static void save_state(void)
Mini-MAC 상태를 EEPROM에 저장
Definition minimac.cpp:200
static uint64_t mm_counter
64비트 메시지 카운터
Definition minimac.cpp:16
static uint8_t mm_hist_cnt
히스토리 항목 수 (≤ λ)
Definition minimac.cpp:18
static uint16_t mm_id
보호할 CAN ID, 그룹 키, 카운터, 메시지 히스토리
Definition minimac.cpp:14
static uint8_t mm_key[16]
공유 그룹 키
Definition minimac.cpp:15
#define MINIMAC_KEY_LEN
Mini-MAC HMAC 키 길이 (16바이트, 128비트)
Definition minimac.h:20
static bool load_state(void)
EEPROM에서 Mini-MAC 상태 불러오기
Definition minimac.cpp:160

◆ minimac_sign()

uint8_t minimac_sign ( uint8_t * data,
uint8_t payload_len )

송신 전 페이로드에 Mini-MAC 태그 생성 및 붙이기

매개변수
data서명할 페이로드 버퍼
payload_len페이로드 길이(바이트)
반환값
전체 데이터 길이 (payload_len + MINIMAC_TAG_LEN)

data[0..payload_len-1] 구간을 포함해 HMAC-MD5를 수행하고, 상위 4바이트를 태그로 data[payload_len..]에 덧붙입니다. 내부 카운터와 히스토리를 갱신한 후 EEPROM에 저장합니다.

송신 전 페이로드에 Mini-MAC 태그 생성 및 붙이기

매개변수
data서명할 페이로드 버퍼, 호출 후 buf[payload_len..] 위치에 태그가 덧붙여짐
payload_len페이로드 길이(Byte)
반환값
전체 전송 길이 (payload_len + MINIMAC_TAG_LEN)

전달받은 페이로드(data, payload_len)를 바탕으로 HMAC-MD5 다이제스트를 계산하여 상위 4바이트(tag)를 data 뒤에 덧붙인다. 이후 메시지 히스토리(mm_hist)와 메시지 카운터(mm_counter)를 갱신하고 EEPROM에 저장(save_state)한다.

minimac.cpp 파일의 282 번째 라인에서 정의되었습니다.

282 {
283 /* 디버그: 함수 진입 */
284 Serial.println("[DBG] minimac_sign()");
285
286 /* (1) HMAC 입력 구성 및 다이제스트 계산 */
287 unsigned char digest[16];
288 compute_digest(data, payload_len, digest);
289
290 /* (2) 디버그: 생성된 다이제스트의 태그 부분 출력 */
291 Serial.print("[DBG] sign: tag = ");
293
294 /* (3) 태그(4바이트) 붙이기 */
295 memcpy(data + payload_len, digest, MINIMAC_TAG_LEN);
296 uint8_t total = payload_len + MINIMAC_TAG_LEN;
297
298 /* (4) 메시지 히스토리 순환 버퍼 관리 */
300 Serial.println("[DBG] sign: history full, dropping oldest");
301 /* 가장 오래된 히스토리 항목 삭제 */
302 for (uint8_t i = 1; i < mm_hist_cnt; i++)
303 mm_hist[i - 1] = mm_hist[i];
304 mm_hist_cnt--;
305 }
306 /* 새로운 페이로드를 히스토리에 추가 */
307 mm_hist[mm_hist_cnt].len = payload_len;
308 memcpy(mm_hist[mm_hist_cnt].data, data, payload_len);
309 mm_hist_cnt++;
310 Serial.print("[DBG] sign: new history_count = ");
311 Serial.println(mm_hist_cnt);
312
313 /* (5) 카운터 증가 및 디버그 출력 */
314 mm_counter++;
315 Serial.print("[DBG] sign: new counter = ");
317 Serial.println();
318
319 /* (6) EEPROM에 상태 저장 */
320 save_state();
321
322 return total;
323}
static MiniMacHist mm_hist[5]
최근 λ개 메시지 히스토리
Definition minimac.cpp:17
static void compute_digest(const uint8_t *data, uint8_t len, unsigned char digest[16])
Mini-MAC용 HMAC-MD5 다이제스트 계산
Definition minimac.cpp:65
#define MINIMAC_HIST_LEN
메시지 히스토리 최대 개수 (λ = 5)
Definition minimac.h:30
#define MINIMAC_TAG_LEN
Mini-MAC 다이제스트에서 사용할 태그 길이 (4바이트, 32비트)
Definition minimac.h:25
static void debug_print_hex(const uint8_t *buf, uint16_t len)
디버깅용: 바이트 배열을 16진수로 출력
Definition minimac.cpp:25
static void print_u64(uint64_t v)
디버깅용: 64비트 부호 없는 정수를 10진수 문자열로 변환해 출력
Definition minimac.cpp:39

◆ minimac_verify()

bool minimac_verify ( const uint8_t * data,
uint8_t payload_len,
const uint8_t * tag )

수신 후 Mini-MAC 태그 검증 및 내부 상태 갱신

매개변수
data검증할 페이로드 버퍼
payload_len페이로드 길이(바이트)
tag수신된 태그 버퍼 (MINIMAC_TAG_LEN 바이트)
반환값
true 검증 성공 (내부 상태 갱신 및 EEPROM 저장)
false 검증 실패 (TAG 불일치)

data와 tag를 이용해 HMAC-MD5 다이제스트를 재계산하고, 다이제스트 상위 4바이트와 비교합니다. 성공 시 내부 카운터와 히스토리를 업데이트합니다.

수신 후 Mini-MAC 태그 검증 및 내부 상태 갱신

매개변수
data검증할 페이로드 버퍼
payload_len페이로드 길이(Byte)
tag수신된 태그 버퍼 (MINIMAC_TAG_LEN 바이트)
반환값
true 검증 성공 및 내부 상태 갱신
false 검증 실패 (TAG 불일치)

data와 tag를 기반으로 HMAC-MD5 다이제스트를 재계산하여 수신된 tag와 비교한다. 검증 성공 시 메시지 히스토리(mm_hist)와 카운터(mm_counter)를 갱신하고 EEPROM에 저장(save_state)한 뒤 true를 반환한다. 실패 시 false 반환하며 상태는 갱신되지 않음.

minimac.cpp 파일의 338 번째 라인에서 정의되었습니다.

339 {
340 /* 디버그: 함수 진입 */
341 Serial.println("[DBG] minimac_verify()");
342
343 /* (1) HMAC 입력 구성 및 다이제스트 재계산 */
344 unsigned char digest[16];
345 compute_digest(data, payload_len, digest);
346
347 /* (2) 디버그: 기대 태그(expected) 및 수신 태그(received) 출력 */
348 Serial.print("[DBG] verify: expected tag = ");
350 Serial.print("[DBG] verify: recv tag = ");
352
353 /* (3) 태그 비교: 불일치 시 실패 처리 */
354 if (memcmp(digest, tag, MINIMAC_TAG_LEN) != 0) {
355 Serial.println("[DBG] verify: FAILED");
356 return false;
357 }
358
359 /* (4) 히스토리 순환 버퍼 관리 (가득 찼다면 가장 오래된 항목 삭제) */
361 Serial.println("[DBG] verify: history full, dropping oldest");
362 for (uint8_t i = 1; i < mm_hist_cnt; i++)
363 mm_hist[i - 1] = mm_hist[i];
364 mm_hist_cnt--;
365 }
366
367 /* (5) 성공 페이로드를 히스토리에 추가 */
368 mm_hist[mm_hist_cnt].len = payload_len;
369 memcpy(mm_hist[mm_hist_cnt].data, data, payload_len);
370 mm_hist_cnt++;
371 Serial.print("[DBG] verify: new history_count = ");
372 Serial.println(mm_hist_cnt);
373
374 /* (6) 카운터 증가 및 디버그 출력 */
375 mm_counter++;
376 Serial.print("[DBG] verify: new counter = ");
378 Serial.println();
379
380 /* (7) EEPROM에 상태 저장 */
381 save_state();
382
383 Serial.println("[DBG] verify: SUCCESS");
384 return true;
385}