시큐어부트(Secure Boot)

시큐어부트(Secure Boot)는 말 그대로 안전한 부팅을 의미합니다. 시큐어 부팅은 ROM으로부터 시작되는 부팅의 시작부터 파일 시스템이 얹어지는 부팅 완료까지 안전하게 부팅을 하는 절차입니다. 주로 세 단계의 인증을 거치게 됩니다. 맨 처음 부팅의 시작인 부트로더들의 인증, 그리고 부트로더에 의해 커널 이미지가 올라오게 되면 커널 이미지를 인증, 이후 커널에 의해 파일 시스템이 마운트되기 전에 파일 시스템의 인증을 거치게 됩니다. 

결론은 부트 로더 인증 -> 커널 인증 -> 파일 시스템 인증 순으로 이어지게 된다는 것이죠. 

부트 로더 인증

임베디드 시스템에서 Boot Loader는 한 가지만 존재하지 않습니다. ROM에서 시작되는 부트 로더1부터 시작해 부트로더2, 부트로더 3 등이 있으며, 여기서도 부트로더 순서대로 인증하는 CoT(Chain Of Trust)라는 기술이 존재하지만 이 포스팅에는 부트로더와 다른 Firmware 이미지들을 한 꺼번에 인증하는 FIP 인증을 다룹니다.

FIP(Firmware Image Package)라고하는 펌웨어 이미지 바이너리를 인증합니다. FIP는 단순히 부트로더들의 모임이라고 생각하시면 되고, FIP를 서명한 서명값이 FIP끝에 달리게 됩니다. 이때 인증은 각 SoC 업체의 Firmware를 사용하여 인증을 하게 되는데요. NXP사의 s32g 칩의 경우에는 HSE(Hardware Security Engine)이라는 펌웨어가 그 역할을 하게 되지요. 

 

인증을 하는 경우에는 공개키가 있어야겠죠? 이 공개키는 어딘가에 저장이 되어야하는데 nxp s32g의 경우 FAT 파일 시스템을 통해서 특정 파티션에 저장하고 있습니다.

커널 인증 

부트로더 인증이 되었다면 그 이후 커널 인증을 거쳐야합니다. 커널 인증은 커널이 변조되었는지 아닌지를 판별하게 됩니다. 커널 인증을 하는 대표적인 방법은 Verified Boot라는 건데요. U-boot에서 사용하는 커널 인증 방법으로 FIT(Flattened Image Tree)를 이용합니다. 이 FIT는 아래와 같은 형식의 .its라는 파일을 가지고 생성되어 집니다. its는 FIT에 대한 정보를 갖고 있는 소스 파일입니다. 

/dts-v1/;
/ {
    description = "Verified boot FIT Image";
    #address-cells = <2>;
    images {
        kernel-1 {
            description = "FIT kernel Image";
            data = /incbin/("Image");
            type = "kernel";
            arch = "arm64";
            os = "linux";
            compression = "none";
            load =  <0x00080000>;
            entry = <0x00080000>;
            hash@1 {
                algo = "sha256";
            };
        };
        tee-1 {
            description = "Arm Trusted Firmware";
            data = /incbin/("optee.bin");
            type = "standalone";
            arch = "arm64";
            compression = "none";
            load =  <0x08400000>;
            entry = <0x08400000>;
            hash@1 {
                algo = "sha256";
            };
        };
        fdt-1 {
            description = "FIT device tree";
            data = /incbin/("fit-linux-kernel.dtb");
            type = "flat_dt";
            arch = "arm64";
            compression = "none";
            hash@1 {
                algo = "sha256";
            };
        };
    };
    configurations {
        default = "config-1";
        config-1 {
            description = "verified boot FIT configuration";
            kernel = "kernel-1";
            loadables = "tee-1";
            fdt = "fdt-1";
            signature-1 {
                algo = "sha256,rsa2048";
                key-name-hint = "dev";
                sign-images = "fdt", "kernel", "loadables";
            };
        };
    };
};

마지막 configurations에서 signature-1을 보시면 FIT 인증을 위한 정보들이 저장이 됩니다. 이 its를 가지고 mkimage라는 u-boot의 툴을 통해서 FIT를 아래와 같은 방법으로 만들어냅니다.

./u-boot/tools/mkimage -f fit-image.its -K u-boot.dtb -k keys -r image.fit
  • -f : its의 파일 이름
  • -K : 그렇다면 공개키는 어디 있을까요? 공개키는 앞서 인증한 FIP의 커널을 부팅하는 부터로더인 U-boot의 dtb에 존재합니다. 그 dtb 파일의 이름을 -K 옵션으로 정해주면 이 dtb 파일에 공개키가 삽입이 됩니다. 
  • -k : 서명할 키와 인증서가 있는 디렉토리를 정해줍니다. keys라는 디렉토리에 위치해있으며 openssl이든 다른 키 생성 툴이든 사용하여 키와 인증서를 만들어야합니다. 위의 예시에는 키에 대한 정보(key-name-hint)가 dev입니다.
  • -r : 인증이 필수라는 뜻으로 인증을 강제합니다. 이 옵션을 정해줌으로써 인증이 실패한 커널은 부팅하지 않습니다. 
  • image.fit : 최종적으로 나오는 fit 이미지의 이름을 정해줍니다. input이 아닙니다.

 

이 FIT 이미지는 U-boot의 bootm 부팅 커맨드로만 동작이 가능하며 u-boot에서 iminfo 라는 명령을 통해서 이미지의 정보를 확인할 수도 있습니다.

자세한 사용 방법은 아래를 참고하시면 될 것 같네요.

https://blog.crysys.hu/2018/06/verified-boot-on-the-raspberry-pi/

 

Verified boot on the Raspberry Pi – CrySyS Blog

This blog post, written by István Telek, is the third post in a series of blog posts on transforming the Raspberry Pi into a security enhanced IoT platform. It describes how you can implement a verified boot process on the Raspberry pi. Introduction Secur

blog.crysys.hu

 

파일 시스템 인증

자, 이제 마지막 인증 과정입니다. 바로 실제 데이터들이 존재하는 파일 시스템을 마운트하기전 파일 시스템을 인증하는 과정이 필요하게 되지요. 파일 시스템을 인증하는 대표적인 기술로 사용되는 것이 dm-verity라는 기술입니다. dm-verity는 파일 시스템 이미지의 원본 블록 을 1차로 나온 Hash 데이터를 다시 2차 Hash를 가하고, 이후 n 번의 Hash를 가하게 되면 결국 마지막 나오는 hash값을 갖고 파일 시스템의 무결성을 검증합니다. 하지만 인증을 위해서는 이 hash값을 서명해야됩니다. 결국 우리는 파일 시스템 원본 이미지 + 해쉬 블록을 미리 생성하고, root hash까지 미리 생성하여 안전하게 보관해야합니다. 이때 hash가 계산되는 모습을 보면 트리 형태로 보여지는데 이를 merkle Tree 라고합니다. 결과적으로 나온 root hash는 노출되어서는 안돼요. 부팅이 되고 마운트될때 파일 시스템의 이미지를 root hash로 만들어서 갖고 있는 root hash와 같다면 인증에 성공합니다.

https://www.timesys.com/security/dm-verity-without-an-initramfs/

한가지 중요한 것은 파일 시스템의 쓰기가 발생하면 안된다는 점입니다. 쓰기가 일어나면 인증은 다음 부팅때 당연히 실패합니다. 그래서 파일 시스템은 read-only 파일 시스템에서만 dm-verity가 사용이 가능합니다. 이 dm-verity에 관한 내용과 파일 시스템 인증에 관한 방법은 아래의 페이지에서 세세하게 다루고 있으니 이 페이지를 참고하시기 바랍니다.

https://www.timesys.com/security/dm-verity-without-an-initramfs/

 

DM-Verity Without an Initramfs - Timesys

Learn how you can implement file system verification on your embedded system without the use of an initramfs. This can significantly save boot time and storage requirements in many situations.

www.timesys.com

 

이상으로 시큐어부팅에 관한 포스팅을 마치도록 하겠습니다.

반응형

'컴퓨터 > 보안 기술' 카테고리의 다른 글

[사이버 보안] dm-verity 개념과 실습(Manual)  (1) 2023.05.18
블로그 이미지

REAKWON

와나진짜

,