nRF52

nRF52840 보안 부트로더 구현: SHA-256 및 ECDSA 펌웨어 무결성 검증 가이드

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

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

반응형