STM32

HMAC을 활용한 안전한 부팅 과정 구현

임베디드 친구 2025. 2. 26. 15:49
728x90
반응형

HMAC을 활용한 안전한 부팅 과정 구현

안녕하세요. "소프트웨어 공장" 블로그를 방문해주셔서 감사합니다. 이번 포스팅에서는 STM32F429 마이크로컨트롤러를 기반으로 HMAC(Hash-based Message Authentication Code) 을 이용해 펌웨어 무결성을 검증하는 안전한 부팅 과정을 구현하는 방법을 상세히 설명드리겠습니다.

펌웨어 무결성 검증은 시스템의 신뢰성을 보장하고, 악성 코드나 무단 변경된 펌웨어로부터 장치를 보호하는 중요한 보안 기능입니다. 특히, 부팅 과정에서 HMAC을 활용하면 신뢰할 수 있는 펌웨어만 실행되도록 보장할 수 있습니다.

이 포스팅에서는 다음과 같은 순서로 진행됩니다.

  1. HMAC의 개념과 필요성
  2. STM32F429에서 HMAC 모듈 활용 방법
  3. 안전한 부팅 과정 설계
  4. 예제 코드와 실습
  5. 테스트 및 검증
  6. 결론

1. HMAC의 개념과 필요성

HMAC이란?

HMAC(Hash-based Message Authentication Code)은 해시 함수를 기반으로 하는 메시지 인증 코드입니다. 특정 비밀 키와 메시지를 함께 처리하여 무결성과 인증성을 동시에 검증할 수 있습니다. HMAC의 주요 특징은 다음과 같습니다.

  • 무결성 보장: 메시지가 전송 과정에서 변경되지 않았음을 확인할 수 있습니다.
  • 인증성 확보: 검증 과정에서 올바른 키를 가진 주체만이 메시지의 진위를 확인할 수 있습니다.
  • 충돌 회피: 일반적인 해시 함수보다 안전성이 강화된 구조입니다.

펌웨어 무결성 검증에서 HMAC의 필요성

임베디드 시스템의 펌웨어는 여러 가지 공격에 노출될 수 있습니다. 공격자는 악성 코드를 삽입하거나, 원본 펌웨어를 무단으로 수정하는 방법으로 시스템을 손상시킬 수 있습니다. 이러한 상황을 방지하기 위해 HMAC을 활용하면 다음과 같은 보안 이점을 얻을 수 있습니다.

  1. 신뢰성 있는 부팅: 부팅 시 펌웨어의 HMAC 값을 검증하고, 무결성이 확인된 경우에만 시스템이 정상적으로 실행됩니다.
  2. 무단 변경 방지: HMAC 키는 비밀 정보로 보호되므로, 원본 키를 알지 못하면 유효한 HMAC 값을 생성할 수 없습니다.
  3. 성능과 보안의 균형: HMAC은 비교적 연산 비용이 낮아 임베디드 환경에서도 효과적으로 사용할 수 있습니다.

2. STM32F429에서 HMAC 모듈 활용 방법

STM32F429는 ARM Cortex-M4 기반의 마이크로컨트롤러로, 다양한 보안 기능을 제공합니다. HMAC은 직접 하드웨어로 지원되지는 않지만, STM32Cube HAL 라이브러리를 활용하여 소프트웨어적으로 구현할 수 있습니다.

준비 사항

  • STM32F429 보드 (예: Nucleo-F429ZI)
  • STM32CubeIDE 설치 완료
  • STM32CubeMX 프로젝트 설정 완료 (이전 포스팅 참고)

HMAC 구현 방법

STM32에서 HMAC을 구현하려면 HASH 모듈SHA-256 알고리즘을 조합하여 다음과 같은 절차로 처리합니다.

  1. 키 준비: HMAC을 위한 비밀 키를 생성하고 안전하게 보관합니다.
  2. 메시지 처리: 펌웨어 바이너리를 메시지로 간주하고 HMAC 연산을 수행합니다.
  3. HMAC 생성: SHA-256 기반으로 HMAC 값을 생성합니다.
  4. 검증: 부팅 시 원본 HMAC과 비교하여 무결성을 확인합니다.

다음은 STM32Cube HAL을 활용한 HMAC 연산 예제입니다.

#include "main.h"
#include "string.h"
#include "stm32f4xx_hal.h"

#define HMAC_KEY "MySecretKey12345"

static uint8_t message[] = "This is a firmware image example.";
static uint8_t hmac_output[32];

void Generate_HMAC_SHA256(uint8_t *input, uint32_t length, uint8_t *output)
{
    HASH_HandleTypeDef hhash;
    HAL_HASH_Init(&hhash);

    HAL_HASH_SHA256_Start(&hhash, input, length, output, HAL_MAX_DELAY);
    HAL_HASH_DeInit(&hhash);
}

int main(void)
{
    HAL_Init();
    SystemClock_Config();

    printf("HMAC 생성 중...\n");
    Generate_HMAC_SHA256(message, sizeof(message) - 1, hmac_output);

    printf("HMAC 결과:\n");
    for (int i = 0; i < 32; i++) {
        printf("%02X", hmac_output[i]);
    }
    printf("\n");

    while (1)
    {
    }
}

3. 안전한 부팅 과정 설계

안전한 부팅을 구현하기 위해 다음과 같은 단계를 따릅니다.

  1. 펌웨어 HMAC 생성: 펌웨어를 빌드한 후 HMAC 값을 생성하고, 이를 부팅 로더와 함께 저장합니다.
  2. 부팅 시 검증: 부팅 시 펌웨어의 HMAC 값을 재생성하고, 저장된 HMAC과 비교합니다.
  3. 검증 실패 시 동작: 무결성 검증에 실패하면 부팅을 중단하고 오류를 알립니다.

부트로더와 펌웨어 분리

안전한 부팅을 위해 부트로더펌웨어를 분리하는 것이 좋습니다. 부트로더는 HMAC 검증을 수행하고, 성공 시에만 펌웨어를 실행하도록 구성합니다.

4. 예제 코드와 실습

다음은 간단한 부트로더 코드 예제입니다.

#include "main.h"

#define HMAC_KEY "MySecretKey12345"
#define FIRMWARE_START_ADDRESS 0x08008000

uint8_t expected_hmac[32] = { /* 사전에 생성된 HMAC 값 */ };
uint8_t calculated_hmac[32];

void Verify_Firmware_Integrity(void)
{
    uint8_t *firmware = (uint8_t *)FIRMWARE_START_ADDRESS;
    Generate_HMAC_SHA256(firmware, 0x20000, calculated_hmac);

    if (memcmp(expected_hmac, calculated_hmac, 32) == 0)
    {
        printf("펌웨어 무결성 검증 성공\n");
        Jump_To_Firmware();
    }
    else
    {
        printf("무결성 검증 실패! 부팅 중단\n");
        while (1);
    }
}

5. 테스트 및 검증

안전한 부팅 과정이 제대로 동작하는지 확인하기 위해 다음과 같이 테스트를 진행합니다.

  1. 정상 펌웨어 테스트: 올바른 HMAC 값과 함께 부팅을 시도하고, 무결성 검증이 성공하는지 확인합니다.
  2. 변조된 펌웨어 테스트: 펌웨어를 변경한 후 부팅을 시도하고, 검증 실패 시 부팅이 차단되는지 확인합니다.
  3. 예외 상황 처리: 키 손실, 플래시 오류 등 다양한 시나리오를 테스트합니다.

6. 결론

이번 포스팅에서는 STM32F429에서 HMAC을 활용하여 안전한 부팅 과정을 구현하는 방법을 상세히 설명했습니다. HMAC을 적용함으로써 무단 변경된 펌웨어의 실행을 효과적으로 차단하고, 시스템의 무결성을 보호할 수 있습니다.

반응형