nRF52

nRF52 SDK를 활용한 부트로더 단계에서 펌웨어 무결성을 검증하는 방법

임베디드 친구 2025. 2. 20. 16:01
728x90
반응형

nRF52 SDK를 활용한 부트로더 단계에서 펌웨어 무결성을 검증하는 방법

nRF52840과 같은 nRF52 시리즈를 활용한 임베디드 시스템에서 펌웨어 무결성 검증은 시스템 보안을 강화하고, 악성 코드나 손상된 펌웨어가 실행되는 것을 방지하는 중요한 단계입니다. 이 글에서는 nRF52 SDK를 활용해 부트로더 단계에서 펌웨어의 무결성을 검증하는 방법을 자세히 살펴보겠습니다.

1. 펌웨어 무결성 검증의 필요성

펌웨어 무결성 검증은 다음과 같은 이유로 중요합니다.

  • 보안 강화: 악성 코드가 펌웨어에 주입되는 것을 방지합니다.
  • 데이터 보호: 손상된 펌웨어가 실행되지 않도록 하여 사용자 데이터를 보호합니다.
  • 시스템 안정성: 무결성을 확인하여 시스템 충돌과 오작동을 예방합니다.

펌웨어 무결성을 검증하는 일반적인 방법은 해시(Hash) 기반 검증디지털 서명(Digital Signature)입니다. 이번 포스팅에서는 SHA-256 해시 알고리즘ECDSA 서명 검증을 중심으로 설명하겠습니다.


2. 무결성 검증 방법 개요

nRF52 SDK에서는 부트로더 단계에서 다음과 같은 과정을 통해 무결성을 검증할 수 있습니다.

  1. 펌웨어 이미지와 함께 SHA-256 해시와 ECDSA 서명을 생성합니다.
  2. 부트로더에서 펌웨어를 로딩할 때 해시 값을 검증합니다.
  3. ECDSA 서명을 통해 펌웨어의 무결성과 인증을 확인합니다.
  4. 검증에 실패하면 펌웨어 실행을 중단하고 안전 모드로 진입합니다.

아래에서 이 과정을 구현하는 방법을 상세히 살펴보겠습니다.


3. 환경 설정

무결성 검증을 위한 환경 설정은 다음과 같이 진행됩니다.

3.1 SDK 및 도구 준비

  • nRF52 SDK: 최신 버전을 Nordic Semiconductor 공식 사이트에서 다운로드합니다.
  • nRF Command Line Tools: 펌웨어 빌드와 디버깅을 위해 설치합니다.
  • OpenSSL: SHA-256 해시 생성과 ECDSA 서명 및 검증에 필요합니다.
# Ubuntu 또는 WSL 환경에서 OpenSSL 설치
sudo apt update
sudo apt install openssl

3.2 부트로더 프로젝트 생성

  1. nRF52 SDK의 예제 경로에서 Secure Bootloader 예제를 복사합니다.
    cd ~/nRF5_SDK_xx/examples/dfu/secure_bootloader/pca10056
  2. 프로젝트 설정 파일을 수정해 무결성 검증 기능을 활성화합니다.

4. SHA-256 해시 생성 및 검증

펌웨어 빌드 후 해시를 생성하고, 부트로더에서 검증하는 과정을 설명합니다.

4.1 펌웨어 해시 생성

펌웨어 바이너리 파일(app.hex 또는 app.bin)에 대해 SHA-256 해시를 생성합니다.

# 펌웨어 바이너리에서 해시 생성
openssl dgst -sha256 -binary app.bin > app.hash

4.2 부트로더에서 해시 검증 코드 작성

nRF52 SDK의 부트로더 코드에 SHA-256 검증 기능을 추가합니다.

bootloader.c 파일에 다음과 같이 코드를 추가합니다.

#include "nrf_crypto.h"
#include "nrf_error.h"

#define FIRMWARE_START_ADDR  0x26000
#define FIRMWARE_SIZE        0x10000

// 펌웨어 해시 검증 함수
bool verify_firmware_hash(uint8_t *expected_hash)
{
    uint8_t calculated_hash[32];
    uint32_t err_code;

    err_code = nrf_crypto_hash_calculate(
        NRF_CRYPTO_HASH_ALG_SHA256,
        (uint8_t *)FIRMWARE_START_ADDR,
        FIRMWARE_SIZE,
        calculated_hash
    );

    if (err_code != NRF_SUCCESS)
    {
        NRF_LOG_ERROR("해시 계산 실패: %d", err_code);
        return false;
    }

    if (memcmp(calculated_hash, expected_hash, 32) == 0)
    {
        NRF_LOG_INFO("펌웨어 해시 검증 성공");
        return true;
    }
    else
    {
        NRF_LOG_ERROR("펌웨어 해시 검증 실패");
        return false;
    }
}

5. ECDSA 서명을 통한 무결성 및 인증 검증

SHA-256 해시만으로는 데이터 무결성을 검증할 수 있지만, 무결성과 인증을 동시에 보장하려면 ECDSA 서명을 사용해야 합니다.

5.1 ECDSA 키 생성

개인 키와 공개 키를 생성합니다.

# 개인 키 생성
openssl ecparam -genkey -name prime256v1 -out private_key.pem

# 공개 키 추출
openssl ec -in private_key.pem -pubout -out public_key.pem

5.2 펌웨어에 서명

펌웨어 해시에 ECDSA 서명을 생성합니다.

# 펌웨어 해시에 서명
openssl dgst -sha256 -sign private_key.pem -out app.sig app.bin

5.3 부트로더에서 서명 검증 코드 작성

bootloader.c 파일에 다음과 같이 코드를 추가합니다.

#include "nrf_crypto_ecdsa.h"

// 펌웨어 서명 검증 함수
bool verify_firmware_signature(uint8_t *hash, uint8_t *signature)
{
    nrf_crypto_ecdsa_verify_context_t verify_context;
    uint32_t err_code;

    err_code = nrf_crypto_ecdsa_verify(
        &verify_context,
        hash,
        32,
        signature,
        NRF_CRYPTO_ECDSA_SECP256R1
    );

    if (err_code == NRF_SUCCESS)
    {
        NRF_LOG_INFO("펌웨어 서명 검증 성공");
        return true;
    }
    else
    {
        NRF_LOG_ERROR("펌웨어 서명 검증 실패: %d", err_code);
        return false;
    }
}

6. 검증 결과에 따른 동작 처리

부트로더에서 무결성 검증 결과에 따라 다음과 같이 동작하도록 설정합니다.

  1. 성공 시: 펌웨어를 실행합니다.
  2. 실패 시: 안전 모드로 진입하거나 이전 펌웨어로 롤백합니다.

main.c 파일에서 다음과 같이 처리합니다.

void bootloader_start(void)
{
    uint8_t expected_hash[32];
    uint8_t signature[64];

    // 저장된 해시와 서명을 불러옵니다.
    load_expected_hash(expected_hash);
    load_signature(signature);

    if (verify_firmware_hash(expected_hash) && verify_firmware_signature(expected_hash, signature))
    {
        NRF_LOG_INFO("펌웨어 무결성 검증 성공. 실행합니다.");
        start_application();
    }
    else
    {
        NRF_LOG_ERROR("펌웨어 무결성 검증 실패. 안전 모드로 진입합니다.");
        enter_safe_mode();
    }
}

7. 빌드 및 테스트

  1. 펌웨어를 빌드하고 서명을 생성합니다.
nrfutil pkg generate --application app.hex --application-version 1 --hw-version 52 --sd-req 0x00 --key-file private_key.pem app_dfu_package.zip
  1. 펌웨어를 플래시에 업로드하고, 부트로더 로그를 확인합니다.
nrfjprog --eraseall
nrfjprog --program secure_bootloader.hex
nrfjprog --program app.hex
nrfjprog --reset

8. 결론

이번 포스팅에서는 nRF52 SDK를 활용해 부트로더 단계에서 펌웨어 무결성을 검증하는 방법을 알아보았습니다. 주요 과정은 다음과 같습니다.

  1. SHA-256 해시를 통해 펌웨어 무결성 검증
  2. ECDSA 서명을 활용한 무결성과 인증 검증
  3. 검증 실패 시 안전 모드로 진입

이 방법을 적용하면 nRF52840 기반의 임베디드 시스템에서 보다 안전하게 펌웨어를 관리할 수 있습니다. 프로젝트에 따라 무결성 검증 수준을 조정하고, 필요하면 암호화 기능도 함께 적용하는 것을 권장합니다.

728x90
반응형