Secure Boot 심화

UEFI Secure Boot 신뢰 체인, Authenticode 서명 구조, SBAT 폐기 메커니즘, 커널 모듈 서명, IMA/EVM, TPM Measured Boot, dm-verity — 부트에서 런타임까지의 무결성 보장 체계를 소스 코드 수준에서 분석합니다.

관련 표준: UEFI 2.10 (Secure Boot 프로토콜), X.509 / RFC 5280 (인증서), TPM 2.0 (Measured Boot), FIPS 140-3 (암호 모듈 인증) — 부팅 무결성 보장 체계의 핵심 규격입니다. 종합 목록은 참고자료 — 표준 & 규격 섹션을 참고하세요.
참고: Secure Boot의 기초적인 키 계층, Shim/MOK 개요는 UEFI 심화 — Secure Boot 섹션을 참조하세요. 이 페이지에서는 내부 구현, 서명 형식, 폐기 메커니즘, 커널 보안 인프라를 심층적으로 다룹니다.

1. Secure Boot 아키텍처 개요

UEFI Secure Boot는 플랫폼 펌웨어가 부팅 과정에서 실행하는 모든 EFI 바이너리의 디지털 서명을 검증하여, 신뢰할 수 없는 코드의 실행을 차단하는 보안 메커니즘입니다. 이 검증은 PKI(Public Key Infrastructure) 기반의 신뢰 체인(Chain of Trust)으로 구현됩니다.

Platform Key (PK) 서명 Key Exchange Key (KEK) 업데이트 권한 업데이트 권한 db (Signature Database) dbx (Forbidden Signatures) UEFI 서명 검증 엔진 Shim (MS 서명) GRUB2 (배포판 서명) Kernel (배포판 서명) Modules (모듈 서명) MOK 검증 서명 검증 런타임 검증 Runtime Integrity: IMA/EVM + dm-verity + Lockdown LSM
Secure Boot 신뢰 체인 — PK에서 런타임 무결성까지의 검증 흐름

Secure Boot UEFI 변수

Secure Boot의 핵심은 NVRAM에 저장된 인증된(authenticated) UEFI 변수들입니다:

변수GUID역할업데이트 권한
PK (Platform Key)EFI_GLOBAL_VARIABLE신뢰 체인의 루트. 1개만 존재물리적 접근 + 현재 PK 소유자
KEK (Key Exchange Key)EFI_GLOBAL_VARIABLEdb/dbx 업데이트 권한 부여PK 소유자
db (Signature DB)EFI_IMAGE_SECURITY_DATABASE허용된 서명/해시 목록KEK 소유자
dbx (Forbidden DB)EFI_IMAGE_SECURITY_DATABASE폐기된 서명/해시 목록KEK 소유자
dbt (Timestamp DB)EFI_IMAGE_SECURITY_DATABASE타임스탬프 서명 검증용KEK 소유자
SecureBootEFI_GLOBAL_VARIABLE활성 상태 (0/1, 읽기 전용)펌웨어
SetupModeEFI_GLOBAL_VARIABLESetup 모드 (PK 미설치 시 1)펌웨어

EFI_VARIABLE_AUTHENTICATION_2 구조체

Secure Boot 변수(db, dbx, KEK 등)는 인증된 업데이트만 허용합니다. 변수를 수정하려면 EFI_VARIABLE_AUTHENTICATION_2 래퍼로 감싸야 합니다:

typedef struct {
    EFI_TIME                    TimeStamp;    /* 재전송 방지용 타임스탬프 */
    WIN_CERTIFICATE_UEFI_GUID   AuthInfo;     /* PKCS#7 서명 래퍼 */
} EFI_VARIABLE_AUTHENTICATION_2;

typedef struct {
    UINT32    dwLength;          /* 인증서 전체 크기 */
    UINT16    wRevision;         /* WIN_CERT_REVISION = 0x0200 */
    UINT16    wCertificateType;  /* WIN_CERT_TYPE_EFI_GUID */
    EFI_GUID  CertType;          /* EFI_CERT_TYPE_PKCS7_GUID */
    UINT8     CertData[1];       /* DER 인코딩된 PKCS#7 SignedData */
} WIN_CERTIFICATE_UEFI_GUID;
재전송 방지(Replay Protection): TimeStamp 필드는 단조 증가해야 합니다. 펌웨어는 이전 타임스탬프보다 작거나 같은 업데이트를 거부합니다. 공격자가 이전의 합법적인 서명을 재사용하여 보안 데이터베이스를 다운그레이드하는 것을 방지합니다.

2. Authenticode 서명 형식

UEFI 실행 파일(shimx64.efi, grubx64.efi, vmlinuz.efi)은 PE/COFF(Portable Executable) 형식이며, Authenticode 서명으로 무결성이 검증됩니다.

PE/COFF 서명 구조

/*
 * PE 파일의 Authenticode 서명 위치:
 *
 * ┌─────────────────────────────┐
 * │ DOS Header (MZ)             │
 * ├─────────────────────────────┤
 * │ PE Signature ("PE\0\0")     │
 * ├─────────────────────────────┤
 * │ COFF Header                 │
 * ├─────────────────────────────┤
 * │ Optional Header             │
 * │   ├─ Data Directory[4]      │◄── Certificate Table 엔트리
 * │   │   ├─ VirtualAddress ─────────► 서명 데이터 오프셋
 * │   │   └─ Size ──────────────────► 서명 데이터 크기
 * ├─────────────────────────────┤
 * │ Sections (.text, .data ...) │
 * ├─────────────────────────────┤
 * │ WIN_CERTIFICATE             │◄── Authenticode 서명
 * │   ├─ dwLength               │
 * │   ├─ wRevision (0x0200)     │
 * │   ├─ wCertificateType       │    WIN_CERT_TYPE_PKCS_SIGNED_DATA
 * │   └─ bCertificate[]         │    PKCS#7 SignedData (DER)
 * └─────────────────────────────┘
 */

Authenticode 해시 계산

Authenticode 해시는 일반적인 파일 해시와 다릅니다. 서명 자체와 체크섬 필드를 제외하고 해시를 계산합니다:

/* Authenticode 해시에서 제외되는 영역:
 * 1. PE Optional Header의 Checksum 필드 (4 bytes)
 * 2. Data Directory[4] Certificate Table 엔트리 (8 bytes)
 * 3. WIN_CERTIFICATE 영역 전체 (서명 데이터)
 *
 * 나머지 모든 바이트가 해시에 포함됨
 */

# sbsign으로 커널 서명
$ sbsign --key db.key --cert db.crt --output vmlinuz.signed vmlinuz.efi

# 서명 검증
$ sbverify --cert db.crt vmlinuz.signed
Signature verification OK

# Authenticode 해시 확인
$ pesign -i vmlinuz.signed -h -P
# SHA-256 해시 출력

# 서명 정보 상세 출력
$ pesign -i vmlinuz.signed -S
---------------------------------------------
certificate address is 0x...
Content was not encrypted.
Content is a detached PKCS#7 signature
Signing time: ...
Signer's common name: My Secure Boot Key
...

서명 도구 비교

도구용도특징
sbsignPE 바이너리 Authenticode 서명sbsigntool 패키지, OpenSSL 기반
sbverifyAuthenticode 서명 검증sbsigntool 패키지
pesignPE 서명/검증/해시NSS 기반, Red Hat 계열
osslsigncodeAuthenticode 서명 (범용)OpenSSL 기반, 타임스탬프 지원
sign-file커널 모듈 서명 (PKCS#7)커널 빌드 시스템 내장
kmodsign커널 모듈 서명 (레거시)sign-file의 이전 이름

3. 폐기 메커니즘: dbx와 SBAT

취약점이 발견된 부트로더나 커널을 차단하려면 폐기(revocation) 메커니즘이 필요합니다. UEFI는 두 가지 방식을 제공합니다.

dbx (전통적 방식)

dbx는 차단할 바이너리의 해시 또는 서명 인증서를 기록합니다:

# dbx 현재 내용 확인
$ efi-readvar -v dbx
Variable dbx, length 13588
dbx: List 0, type SHA256
    Hash: a4:6f:0c:2e:...  # 차단된 바이너리 해시

# dbx 업데이트 (KEK로 서명된 업데이트 적용)
$ efi-updatevar -f dbx-update.auth dbx

# dbx에 새 해시 추가 (Linux fwupd 사용)
$ fwupdmgr get-updates
$ fwupdmgr update
dbx의 한계: dbx는 개별 바이너리의 SHA-256 해시를 저장합니다. 취약한 GRUB2 버전이 수십 개라면 수십 개의 해시를 모두 dbx에 추가해야 합니다. 이는 NVRAM 용량 제한(일반적으로 32~128KB)과 충돌하며, 2020년 "BootHole" 취약점(CVE-2020-10713) 이후 확장성 문제가 심각해졌습니다.

SBAT (Secure Boot Advanced Targeting)

SBAT는 dbx의 확장성 문제를 해결하기 위해 도입된 세대 기반(generation-based) 폐기 메커니즘입니다. 개별 해시 대신 컴포넌트의 보안 세대 번호를 비교합니다.

/* SBAT 메타데이터 (.sbat 섹션, CSV 형식)
 *
 * shimx64.efi의 .sbat 섹션 예시:
 */
sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
shim,4,UEFI shim,shim,1,https://github.com/rhboot/shim
shim.ubuntu,2,Canonical Ltd.,shim,15.8,https://launchpad.net/ubuntu/+source/shim

/* GRUB2의 .sbat 섹션 예시: */
sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
grub,4,Free Software Foundation,grub,2.12,https://www.gnu.org/software/grub/
grub.ubuntu,2,Canonical Ltd.,grub2,2.12-1ubuntu1,https://launchpad.net/ubuntu/+source/grub2

SBAT 폐기 정책은 SbatLevel UEFI 변수에 저장됩니다:

# SbatLevel 확인
$ mokutil --list-sbat-revocations
sbat,1,2023022100
shim,2
grub,3
grub.debian,4

# 해석: grub 컴포넌트의 세대 번호가 3 미만인 바이너리는 실행 거부
# → grub 세대 1, 2인 모든 배포판의 GRUB2가 한꺼번에 차단됨

SBAT vs dbx 비교

특성dbx (해시 기반)SBAT (세대 기반)
식별 방식SHA-256 해시컴포넌트명 + 세대 번호
NVRAM 사용량차단 바이너리 수 × 32B컴포넌트 수 × ~50B (고정)
확장성NVRAM 제한에 빠르게 도달우수 (컴포넌트 단위)
세분화개별 바이너리배포판별 컴포넌트
적용 대상모든 EFI 바이너리.sbat 섹션이 있는 바이너리
업데이트KEK 서명 필요SbatLevel 변수 업데이트

4. Shim과 MOK 인프라

대부분의 Linux 배포판은 Microsoft UEFI CA가 서명한 Shim 부트로더를 1단계로 사용합니다. Shim은 자체 키 데이터베이스(MOK)를 관리하여 배포판별 2단계 부트로더와 커널을 검증합니다.

Shim 검증 로직

/*
 * shim의 EFI 바이너리 검증 순서 (verify_buffer 함수):
 *
 * 1. dbx (UEFI 폐기 목록) 확인 → 해시/인증서 매치 시 거부
 * 2. SBAT 검증 → SbatLevel 미달 시 거부
 * 3. db (UEFI 허용 목록) 검증 → 매치 시 허용
 * 4. MOK (Machine Owner Key) 검증 → 매치 시 허용
 * 5. shim 내장 인증서 검증 → 매치 시 허용
 * 6. 모두 실패 → 거부
 */

/* shim 소스 코드에서의 핵심 검증 흐름 (간략화): */
static EFI_STATUS
verify_buffer(char *data, int datasize,
              PE_COFF_LOADER_IMAGE_CONTEXT *context)
{
    /* Step 1: dbx 확인 (차단 목록) */
    if (check_denylist(context, data, datasize) == FOUND)
        return EFI_ACCESS_DENIED;

    /* Step 2: SBAT 확인 */
    if (verify_sbat_section(data, datasize) != EFI_SUCCESS)
        return EFI_SECURITY_VIOLATION;

    /* Step 3-5: 허용 목록 순서대로 확인 */
    if (check_allowlist(context, data, datasize) == FOUND)
        return EFI_SUCCESS;

    return EFI_ACCESS_DENIED;
}

MOK 관리

# 자체 서명 키 생성
$ openssl req -new -x509 -newkey rsa:2048 -keyout MOK.key \
    -out MOK.crt -nodes -days 3650 \
    -subj "/CN=My Secure Boot MOK"

# DER 형식으로 변환 (MOK 등록에 필요)
$ openssl x509 -in MOK.crt -outform DER -out MOK.der

# MOK 등록 요청 (다음 부팅 시 MokManager에서 확인)
$ mokutil --import MOK.der
# 비밀번호 입력 → 재부팅 시 MokManager UI에서 동일 비밀번호 입력

# 등록된 MOK 목록 확인
$ mokutil --list-enrolled
[key 1]
SHA1 Fingerprint: ab:cd:ef:...
Subject: CN = My Secure Boot MOK
Issuer:  CN = My Secure Boot MOK

# MOK 삭제
$ mokutil --delete MOK.der

# Secure Boot 상태 확인
$ mokutil --sb-state
SecureBoot enabled
SecureBoot validation is enabled in shim

MOK UEFI 변수

변수설명
MokList등록된 MOK 인증서/해시 목록
MokListXMOK 차단 목록 (dbx의 MOK 버전)
MokNew다음 부팅에 등록할 MOK (임시)
MokDel다음 부팅에 삭제할 MOK (임시)
MokSBStateShim 수준의 Secure Boot 활성/비활성
SbatLevelSBAT 폐기 정책

5. 커널 모듈 서명

Secure Boot 환경에서 커널 모듈은 로드 시 서명이 검증됩니다. 서명 정책은 CONFIG_MODULE_SIG 관련 설정으로 제어합니다.

커널 설정

# 모듈 서명 관련 커널 설정 (Security options → Module signature verification)
CONFIG_MODULE_SIG=y            # 모듈 서명 검증 활성화
CONFIG_MODULE_SIG_FORCE=y      # 서명 없는 모듈 로드 거부 (Secure Boot 시 필수)
CONFIG_MODULE_SIG_ALL=y        # 빌드 시 모든 모듈 자동 서명

# 서명 해시 알고리즘 선택
CONFIG_MODULE_SIG_SHA256=y     # SHA-256 (기본)
# CONFIG_MODULE_SIG_SHA384=y
# CONFIG_MODULE_SIG_SHA512=y

# 서명 키 경로
CONFIG_MODULE_SIG_KEY="certs/signing_key.pem"     # 서명용 개인키
CONFIG_SYSTEM_TRUSTED_KEYRING=y                   # 시스템 신뢰 키링
CONFIG_SYSTEM_TRUSTED_KEYS="certs/signing_key.pem" # 빌트인 인증서

# 추가 신뢰 키 소스
CONFIG_SECONDARY_TRUSTED_KEYRING=y                # 런타임 추가 키링
CONFIG_INTEGRITY_PLATFORM_KEYRING=y               # 플랫폼(Secure Boot) 키링

sign-file 도구

# 커널 빌드 시 자동으로 호출되는 모듈 서명 명령
$ scripts/sign-file sha256 \
    certs/signing_key.pem \
    certs/signing_key.x509 \
    drivers/my_driver.ko

# sign-file 내부 동작:
# 1. 모듈 ELF 바이너리 전체를 SHA-256으로 해시
# 2. 개인키로 PKCS#7 서명 생성
# 3. 서명을 모듈 파일 끝에 추가 (append)
# 4. module_signature 구조체를 맨 끝에 추가

모듈 서명 구조

/* include/linux/module_signature.h */
struct module_signature {
    u8    algo;          /* 공개키 알고리즘 (RSA, ECDSA ...) */
    u8    hash;          /* 해시 알고리즘 (SHA-256, SHA-512 ...) */
    u8    id_type;       /* 키 식별 타입 (PKEY_ID_PKCS7) */
    u8    signer_len;    /* 서명자 이름 길이 (PKCS#7에서는 0) */
    u8    key_id_len;    /* 키 ID 길이 (PKCS#7에서는 0) */
    u8    __pad[3];      /* 패딩 */
    __be32 sig_len;       /* 서명 데이터 길이 (빅 엔디안) */
};

/*
 * 모듈 파일 레이아웃:
 *
 * ┌─────────────────────┐
 * │ ELF 바이너리 데이터  │  ← 해시 대상
 * ├─────────────────────┤
 * │ PKCS#7 서명 데이터   │  ← sig_len 바이트
 * ├─────────────────────┤
 * │ module_signature     │  ← 12 바이트 (고정)
 * ├─────────────────────┤
 * │ MAGIC: "~Module      │
 * │  signature appended~"│  ← 28 바이트 매직 문자열
 * └─────────────────────┘
 */

모듈 서명 검증 흐름

/* kernel/module/signing.c - mod_verify_sig() 간략화 */
int mod_verify_sig(const void *mod, struct load_info *info)
{
    struct module_signature ms;
    size_t sig_len, modlen = info->len;

    /* 매직 문자열 확인 */
    if (memcmp(mod + modlen - 28,
              "~Module signature appended~\n", 28) != 0)
        return -ENODATA;  /* 서명 없음 */

    /* module_signature 구조체 읽기 */
    memcpy(&ms, mod + modlen - 28 - sizeof(ms), sizeof(ms));
    sig_len = be32_to_cpu(ms.sig_len);

    /* PKCS#7 서명 검증 (시스템 키링의 인증서 사용) */
    return verify_pkcs7_signature(
        mod,                       /* 서명 대상 데이터 */
        modlen - sig_len - 28 - sizeof(ms), /* 데이터 길이 */
        mod + modlen - 28 - sizeof(ms) - sig_len,
        sig_len,
        VERIFY_USE_SECONDARY_KEYRING,  /* .secondary_trusted_keys */
        VERIFYING_MODULE_SIGNATURE,
        NULL, NULL);
}

/*
 * 키링 검색 순서:
 * 1. .builtin_trusted_keys  (커널 빌드 시 내장된 인증서)
 * 2. .secondary_trusted_keys (런타임 추가, MOK에서 import된 키)
 * 3. .platform_keyring       (UEFI Secure Boot db에서 가져온 키)
 */

모듈 서명 실무 명령

# 모듈 서명 확인
$ modinfo drivers/my_driver.ko | grep sig
sig_id:         PKCS#7
signer:         Build time autogenerated kernel key
sig_key:        AB:CD:12:34:...
sig_hashalgo:   sha256

# 서명 유효성 검증 (kmod 도구)
$ modprobe --dump-modversions drivers/my_driver.ko

# 시스템 키링 확인
$ keyctl list %:.builtin_trusted_keys
1 key in keyring:
 123456789: ---lswrv     0     0 asymmetri: Build time autogenerated kernel key: ab:cd:...

$ keyctl list %:.secondary_trusted_keys
2 keys in keyring:
 234567890: ---lswrv     0     0 asymmetri: My Secure Boot MOK: 12:34:...

# DKMS 모듈 자동 서명 (MOK 키 사용)
# /etc/dkms/framework.conf:
# sign_tool="/etc/dkms/sign_helper.sh"
# mok_signing_key="/var/lib/shim-signed/mok/MOK.priv"
# mok_certificate="/var/lib/shim-signed/mok/MOK.der"

6. Kernel Lockdown LSM

Secure Boot의 신뢰 체인은 커널이 부팅된 후에도 유지되어야 합니다. Lockdown LSM은 커널 무결성을 우회할 수 있는 사용자 공간의 인터페이스를 제한합니다.

Lockdown 레벨

레벨설정값제한 범위
noneLOCK_NONE제한 없음 (Secure Boot 비활성 시)
integrityLOCK_INTEGRITY커널 이미지 수정 차단
confidentialityLOCK_CONFIDENTIALITYintegrity + 커널 정보 유출 차단

Lockdown 제한 항목

/* security/lockdown/lockdown.c - Lockdown이 차단하는 기능들 */

/* integrity 레벨에서 차단: */
LOCKDOWN_MODULE_SIGNATURE,          /* 서명 없는 모듈 로드 */
LOCKDOWN_DEV_MEM,                   /* /dev/mem, /dev/kmem 쓰기 */
LOCKDOWN_EFI_TEST,                  /* EFI 테스트 모드 변수 */
LOCKDOWN_KEXEC,                     /* 서명 없는 kexec 이미지 */
LOCKDOWN_HIBERNATION,               /* 하이버네이션 (이미지 변조 가능) */
LOCKDOWN_PCI_ACCESS,                /* PCI BAR 직접 접근 */
LOCKDOWN_IOPORT,                    /* I/O 포트 직접 접근 */
LOCKDOWN_MSR,                       /* MSR 쓰기 (/dev/cpu/*/msr) */
LOCKDOWN_ACPI_TABLES,               /* 커스텀 ACPI 테이블 로드 */
LOCKDOWN_DEVICE_TREE,               /* 디바이스 트리 오버레이 */
LOCKDOWN_PCMCIA_CIS,                /* PCMCIA CIS 오버라이드 */
LOCKDOWN_TIOCSSERIAL,               /* 시리얼 포트 I/O 변경 */
LOCKDOWN_MODULE_PARAMETERS,         /* 위험한 모듈 파라미터 */
LOCKDOWN_MMIOTRACE,                 /* MMIO 트레이싱 */
LOCKDOWN_DEBUGFS,                   /* debugfs 접근 */
LOCKDOWN_XMON_WR,                   /* PowerPC xmon 쓰기 */
LOCKDOWN_BPF_WRITE_USER,            /* BPF 사용자 메모리 쓰기 */
LOCKDOWN_DBG_WRITE_KERNEL,          /* /proc/kcore 등 커널 메모리 쓰기 */

/* confidentiality 레벨에서 추가 차단: */
LOCKDOWN_KPROBES,                   /* kprobes 사용 */
LOCKDOWN_TRACEFS,                   /* tracefs (ftrace) 접근 */
LOCKDOWN_PERF,                      /* perf 하드웨어 이벤트 */
LOCKDOWN_XMON_RW,                   /* PowerPC xmon 읽기/쓰기 */
LOCKDOWN_DBG_READ_KERNEL,           /* /proc/kcore 등 커널 메모리 읽기 */
LOCKDOWN_BPF_READ_KERNEL,           /* BPF 커널 메모리 읽기 */

Lockdown 상태 확인 및 제어

# Lockdown 상태 확인
$ cat /sys/kernel/security/lockdown
none [integrity] confidentiality

# dmesg에서 Lockdown 메시지
$ dmesg | grep -i lockdown
Lockdown: Kernel is locked down from EFI Secure Boot mode; see man kernel_lockdown.7
Lockdown: debugfs: restricted; see man kernel_lockdown.7
Lockdown: tracefs: restricted; see man kernel_lockdown.7

# 커널 커맨드라인에서 Lockdown 설정
# lockdown=integrity    (integrity 모드 강제)
# lockdown=confidentiality (confidentiality 모드 강제)

# 커널 설정
CONFIG_SECURITY_LOCKDOWN_LSM=y
CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y
CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT=y  # Secure Boot 시 자동 integrity
디버깅 제약: Lockdown integrity 모드에서는 /dev/mem, debugfs, MSR 접근이 차단됩니다. Secure Boot 환경에서 커널 디버깅이 필요하면 lockdown=none 커맨드라인을 사용하거나, Secure Boot를 일시적으로 비활성화해야 합니다. Confidentiality 모드에서는 ftrace, perf, kprobes까지 차단되어 성능 프로파일링도 불가합니다.

7. IMA/EVM — 런타임 무결성 검증

IMA(Integrity Measurement Architecture)와 EVM(Extended Verification Module)은 부팅 이후 파일 시스템 수준에서 무결성을 보장합니다. Secure Boot가 부팅 체인의 무결성을 보장하면, IMA는 런타임 파일 접근의 무결성을 보장합니다.

IMA 아키텍처

/*
 * IMA 서브시스템 구조:
 *
 * ┌──────────────┐     ┌──────────────┐     ┌──────────────┐
 * │  IMA-Measure │     │  IMA-Appraise│     │  IMA-Audit   │
 * │  (측정)       │     │  (평가)       │     │  (감사)       │
 * └──────┬───────┘     └──────┬───────┘     └──────┬───────┘
 *        │                    │                    │
 *        └────────────┬───────┴────────────────────┘
 *                     │
 *              ┌──────┴──────┐
 *              │  IMA Policy │  ← 어떤 파일을 검증할지 정책
 *              └──────┬──────┘
 *                     │
 *              ┌──────┴──────┐
 *              │  LSM Hook   │  ← file_mmap, bprm_check 등
 *              └──────┬──────┘
 *                     │
 *              ┌──────┴──────┐
 *              │  측정 목록    │  ← /sys/kernel/security/ima/ascii_runtime_measurements
 *              └──────┬──────┘
 *                     │
 *              ┌──────┴──────┐
 *              │  TPM PCR 10 │  ← 측정값 확장 (원격 증명용)
 *              └─────────────┘
 */

IMA 동작 모드

모드설명용도
measure파일 해시를 측정 목록에 기록 + TPM PCR 확장원격 증명(Remote Attestation)
appraise파일의 IMA 확장 속성과 실제 해시 비교로컬 무결성 강제
audit감사 로그에 해시 기록감사 추적
hash확장 속성에 해시만 저장 (서명 없음)IMA appraise 사전 준비

IMA 정책

# 커널 커맨드라인 IMA 옵션
ima_policy=tcb                # 기본 TCB 정책 (실행 파일, 라이브러리, 모듈)
ima_policy=appraise_tcb       # TCB + appraise 모드
ima_policy=secure_boot        # Secure Boot 연동 정책
ima_appraise=enforce          # appraise 실패 시 파일 접근 거부
ima_appraise=log              # appraise 실패 시 로그만 기록

# 런타임 정책 파일 (/etc/ima/ima-policy 또는 securityfs)
# 정책 형식: action condition [condition ...]

# 실행되는 모든 파일 측정
measure func=BPRM_CHECK

# root가 실행하는 파일의 서명 검증 강제
appraise func=BPRM_CHECK uid=0 appraise_type=imasig

# 커널 모듈 로드 시 서명 검증
appraise func=MODULE_CHECK appraise_type=imasig

# 펌웨어 로드 시 서명 검증
appraise func=FIRMWARE_CHECK appraise_type=imasig

# kexec 커널 이미지 서명 검증
appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig

# 특정 라벨의 파일만 측정 (SELinux 연동)
measure func=FILE_MMAP obj_type=lib_t

# 정책 로드 (securityfs)
$ cat /etc/ima/ima-policy > /sys/kernel/security/ima/policy

IMA 확장 속성

# IMA 확장 속성 확인
$ getfattr -m ^security -d /sbin/init
security.ima=0x...    # IMA 서명 또는 해시
security.evm=0x...    # EVM HMAC 또는 서명

# IMA 서명 설정 (evmctl 사용)
$ evmctl ima_sign -k /path/to/private_key.pem /sbin/init

# IMA 해시 설정
$ evmctl ima_hash /sbin/init

# 측정 목록 확인
$ cat /sys/kernel/security/ima/ascii_runtime_measurements
10 abc123... ima-sig sha256:def456... /sbin/init

# 위반 목록 확인
$ cat /sys/kernel/security/ima/violations
0

EVM (Extended Verification Module)

EVM은 IMA 확장 속성 자체의 무결성을 보호합니다. 공격자가 security.ima 속성을 위변조하는 것을 방지합니다:

/*
 * EVM 보호 대상 확장 속성:
 * - security.ima     (IMA 해시/서명)
 * - security.selinux (SELinux 라벨)
 * - security.SMACK64 (SMACK 라벨)
 * - security.capability (파일 capability)
 *
 * EVM은 이 속성들의 HMAC 또는 디지털 서명을
 * security.evm에 저장하여 변조를 감지합니다.
 */

# EVM 초기화 (HMAC 모드 — TPM 기반 키)
$ echo 1 > /sys/kernel/security/evm

# EVM 서명 모드 (공개키 기반)
$ evmctl sign -k /path/to/evm-key.pem /sbin/init

# 커널 설정
CONFIG_EVM=y
CONFIG_EVM_ATTR_FSUUID=y          # 파일시스템 UUID도 HMAC에 포함
CONFIG_EVM_ADD_XATTRS=y           # 추가 xattr을 EVM 보호에 포함

8. TPM과 Measured Boot

Secure Boot(검증 부팅)과 Measured Boot(측정 부팅)는 상호 보완적인 메커니즘입니다. Secure Boot는 신뢰할 수 없는 코드의 실행을 차단하고, Measured Boot는 실행된 코드의 해시를 기록하여 사후 검증을 가능하게 합니다.

TPM PCR (Platform Configuration Register)

/*
 * TPM PCR 할당 (TCG PC Client 규격):
 *
 * PCR  0: SRTM, BIOS, 호스트 플랫폼 Extension, 임베디드 옵션 ROM
 * PCR  1: 호스트 플랫폼 설정
 * PCR  2: 옵션 ROM 코드
 * PCR  3: 옵션 ROM 설정 및 데이터
 * PCR  4: IPL 코드 (부트로더), MBR
 * PCR  5: IPL 코드 설정 및 데이터
 * PCR  6: 상태 전이 및 Wake 이벤트
 * PCR  7: Secure Boot 정책 — PK, KEK, db, dbx,
 *         SecureBoot 변수, 부트 관리자 측정
 * PCR  8-15: OS 정의 — Linux에서는:
 * PCR  8: GRUB2 커맨드라인/설정
 * PCR  9: GRUB2에서 로드한 파일 (커널, initrd)
 * PCR 10: IMA 측정 목록
 * PCR 11-13: (배포판별 정의)
 * PCR 14: MOK 인증서/키
 */

# TPM PCR 값 읽기
$ tpm2_pcrread sha256:0,1,4,7,10
  sha256:
    0 : 0x3A5F...   # BIOS 측정
    1 : 0xA2B1...   # 플랫폼 설정
    4 : 0xF1E2...   # 부트로더 측정
    7 : 0xC3D4...   # Secure Boot 정책
   10 : 0xE5F6...   # IMA 측정

# PCR 확장(Extend) 원리:
# PCR_new = Hash(PCR_old || measurement)
# → 한번 확장되면 이전 값으로 되돌릴 수 없음 (단방향)
# → 부팅 체인의 모든 측정이 누적된 해시로 표현됨

TCG 이벤트 로그

# 이벤트 로그 확인 (개별 측정 이벤트)
$ tpm2_eventlog /sys/kernel/security/tpm0/binary_bios_measurements
---
- EventNum: 0
  PCRIndex: 0
  EventType: EV_S_CRTM_VERSION
  DigestCount: 1
  Digests:
  - AlgorithmId: sha256
    Digest: "3a5f..."
  Event: ...

- EventNum: 15
  PCRIndex: 7
  EventType: EV_EFI_VARIABLE_DRIVER_CONFIG
  Digests:
  - AlgorithmId: sha256
    Digest: "c3d4..."
  Event:
    UnicodeName: SecureBoot
    VariableData: 01    # Secure Boot 활성

# 커널에서 이벤트 로그 접근
$ ls /sys/kernel/security/tpm0/
binary_bios_measurements   # 바이너리 형식
ascii_bios_measurements    # 텍스트 형식

원격 증명 (Remote Attestation)

/*
 * 원격 증명 흐름:
 *
 * 1. 검증 서버(Verifier)가 난스(nonce)를 전송
 * 2. 클라이언트가 TPM에 Quote 요청:
 *    - TPM이 PCR 값들에 AIK(Attestation Identity Key)로 서명
 *    - 난스를 포함하여 재전송 공격 방지
 * 3. Quote + 이벤트 로그를 검증 서버에 전송
 * 4. 검증 서버가:
 *    a. AIK 서명 검증
 *    b. 이벤트 로그를 재연하여 PCR 값 재계산
 *    c. 재계산된 PCR과 Quote의 PCR 비교
 *    d. 개별 이벤트를 알려진 양호값(golden values)과 비교
 */

# TPM Quote 생성
$ tpm2_createak -C 0x81010001 -c ak.ctx -G rsa -g sha256
$ tpm2_quote -c ak.ctx -l sha256:0,1,4,7,10 \
    -q "nonce_from_verifier" -m quote.msg -s quote.sig

# IMA 측정 목록 (원격 증명에 사용)
$ head -5 /sys/kernel/security/ima/ascii_runtime_measurements
10 a1b2c3... ima-ng sha256:d4e5f6... /sbin/init
10 b2c3d4... ima-ng sha256:e5f6a7... /usr/lib64/ld-linux-x86-64.so.2
10 c3d4e5... ima-ng sha256:f6a7b8... /usr/lib64/libc.so.6

9. dm-verity — 블록 장치 무결성

dm-verity는 device-mapper 타겟으로, 블록 장치 전체의 무결성을 Merkle 트리(해시 트리)로 검증합니다. 읽기 전용 파일시스템의 변조를 런타임에 탐지합니다.

Merkle 트리 구조

/*
 * dm-verity Merkle 트리:
 *
 *                 ┌─────────┐
 *                 │Root Hash│  ← 커널 커맨드라인 또는 서명된 메타데이터
 *                 └────┬────┘
 *            ┌─────────┴─────────┐
 *        ┌───┴───┐           ┌───┴───┐
 *        │ Hash  │           │ Hash  │  ← 상위 해시 노드
 *        └───┬───┘           └───┬───┘
 *      ┌─────┴─────┐      ┌─────┴─────┐
 *   ┌──┴──┐     ┌──┴──┐┌──┴──┐     ┌──┴──┐
 *   │H(B0)│     │H(B1)││H(B2)│     │H(B3)│  ← 리프 해시
 *   └──┬──┘     └──┬──┘└──┬──┘     └──┬──┘
 *   ┌──┴──┐     ┌──┴──┐┌──┴──┐     ┌──┴──┐
 *   │  B0 │     │  B1 ││  B2 │     │  B3 │  ← 데이터 블록 (4KB)
 *   └─────┘     └─────┘└─────┘     └─────┘
 *
 * 읽기 요청 시:
 * 1. 데이터 블록 읽기
 * 2. 블록 해시 계산
 * 3. Merkle 트리를 따라 루트까지 검증
 * 4. 불일치 시 I/O 오류 반환 또는 시스템 재시작
 */

dm-verity 설정

# 해시 트리 생성
$ veritysetup format /dev/sda2 /dev/sda3
VERITY header information for /dev/sda3
UUID:            a1b2c3d4-...
Hash type:       1
Data blocks:     262144
Data block size: 4096
Hash block size: 4096
Hash algorithm:  sha256
Salt:            abc123...
Root hash:       5f8c3d2a1b4e7f9c0d6a3b8e5f2c1d4a7b0e3f6c9d2a5b8e1f4c7d0a3b6e9f

# verity 장치 활성화
$ veritysetup open /dev/sda2 verified-root /dev/sda3 \
    5f8c3d2a1b4e7f9c0d6a3b8e5f2c1d4a7b0e3f6c9d2a5b8e1f4c7d0a3b6e9f

# 마운트
$ mount /dev/mapper/verified-root /mnt -o ro

# 커널 커맨드라인에서 root dm-verity 설정
# root=/dev/dm-0
# dm-mod.create="verified-root,,,ro,0 262144 verity 1 /dev/sda2 /dev/sda3 4096 4096 262144 1 sha256 ROOT_HASH SALT"

# 커널 설정
CONFIG_DM_VERITY=y
CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y  # 루트 해시 서명 검증
CONFIG_DM_VERITY_FEC=y                  # Forward Error Correction
Android Verified Boot (AVB): Android는 dm-verity를 핵심으로 사용하여 system, vendor 파티션의 무결성을 보장합니다. AVB의 VBMeta 구조에 루트 해시가 서명되어 포함되며, 부트로더가 VBMeta의 서명을 검증한 후 커널에 루트 해시를 전달합니다.

AVB(Android Verified Boot) 상세

AVB 2.0은 Android 8.0+에서 사용되는 검증 부팅 체계로, 부트로더에서 커널까지의 신뢰 체인(chain of trust)을 구축한다. 핵심 구성 요소는 vbmeta 파티션으로, RSA/ECDSA 서명된 메타데이터에 각 파티션의 해시(hash descriptor) 또는 해시 트리 루트(hashtree descriptor)를 포함한다.

/* VBMeta 구조 (avb_vbmeta_image_header) */
┌───────────────────────┐
│ Header (256B)          │ magic: "AVB0", algorithm, key 크기
├───────────────────────┤
│ Authentication Block   │ hash + signature (RSA-4096/ECDSA)
├───────────────────────┤
│ Auxiliary Block        │ descriptors:
│  ├ hash_descriptor     │   boot, init_boot (전체 해시)
│  ├ hashtree_descriptor │   system, vendor (해시 트리 루트)
│  ├ chain_descriptor    │   vbmeta_system → 체인 검증
│  └ property_descriptor │   OS version, security patch level
└───────────────────────┘

# 롤백 보호: 각 파티션의 rollback_index가 하드웨어 보호 저장소에 기록
# 이전 버전 이미지 플래시 시 부팅 거부 → 다운그레이드 공격 차단

# 검증 모드:
# - Locked + Verified: 정상 부팅 (서명 검증 필수)
# - Locked + Corrupted: 부팅 거부
# - Unlocked: 개발용 (WARNING 화면 표시)

AVB와 dm-verity 연동, A/B 파티션 구조, 부팅 흐름 등 종합 내용은 Android 커널 — AVB를 참고하라.

10. kexec 서명 검증

kexec는 재부팅 없이 새 커널을 로드하는 메커니즘입니다. Secure Boot 환경에서는 kexec로 로드하는 커널 이미지에도 서명 검증이 필요합니다.

# 서명된 kexec (Secure Boot 환경에서 허용)
$ kexec -l /boot/vmlinuz-signed --initrd=/boot/initrd.img \
    --command-line="root=/dev/sda1" --kexec-file-syscall

# kexec_file_load() 시스템 콜에서의 서명 검증:
# 1. PE 헤더 파싱 (bzImage는 PE/COFF 형식)
# 2. Authenticode 서명 추출
# 3. 시스템 키링(.builtin_trusted_keys, .platform_keyring)으로 검증
# 4. IMA 정책에 의한 추가 검증 (func=KEXEC_KERNEL_CHECK)
/* arch/x86/kernel/kexec-bzimage64.c - 서명 검증 흐름 */
static int bzImage64_verify_sig(const char *kernel, unsigned long kernel_len)
{
    return verify_pefile_signature(
        kernel, kernel_len,
        VERIFY_USE_SECONDARY_KEYRING,  /* 보조 키링 검색 */
        VERIFYING_KEXEC_PE_SIGNATURE); /* 용도 표시 */
}

/* 관련 커널 설정 */
CONFIG_KEXEC_FILE=y               # kexec_file_load() 시스템 콜
CONFIG_KEXEC_SIG=y                # kexec 서명 검증 활성화
CONFIG_KEXEC_SIG_FORCE=y          # 서명 없으면 kexec 거부
CONFIG_KEXEC_BZIMAGE_VERIFY_SIG=y # bzImage 서명 검증

11. 커스텀 키 관리

기업 환경이나 임베디드 시스템에서는 OEM/벤더 키 대신 자체 Secure Boot 키를 사용하여 완전한 신뢰 체인을 구축할 수 있습니다.

커스텀 PK 등록

# 1. 키 생성 (RSA 2048 또는 4096)
# PK (Platform Key)
$ openssl req -new -x509 -newkey rsa:4096 -keyout PK.key \
    -out PK.crt -nodes -days 3650 \
    -subj "/CN=My Platform Key"

# KEK (Key Exchange Key)
$ openssl req -new -x509 -newkey rsa:4096 -keyout KEK.key \
    -out KEK.crt -nodes -days 3650 \
    -subj "/CN=My Key Exchange Key"

# db (Signature Database Key)
$ openssl req -new -x509 -newkey rsa:4096 -keyout db.key \
    -out db.crt -nodes -days 3650 \
    -subj "/CN=My Signature Database Key"

# 2. EFI Signature List (ESL) 형식으로 변환
$ cert-to-efi-sig-list PK.crt PK.esl
$ cert-to-efi-sig-list KEK.crt KEK.esl
$ cert-to-efi-sig-list db.crt db.esl

# 3. 인증된 업데이트 파일 생성 (EFI_VARIABLE_AUTHENTICATION_2)
$ sign-efi-sig-list -k PK.key -c PK.crt PK PK.esl PK.auth
$ sign-efi-sig-list -k PK.key -c PK.crt KEK KEK.esl KEK.auth
$ sign-efi-sig-list -k KEK.key -c KEK.crt db db.esl db.auth

# 4. UEFI Setup Mode에서 키 등록
# (Setup Mode: PK가 없는 상태 → 누구나 변수 수정 가능)
$ efi-updatevar -f db.auth db        # db 먼저
$ efi-updatevar -f KEK.auth KEK      # KEK 다음
$ efi-updatevar -f PK.auth PK        # PK 마지막 (Setup Mode 종료)

# 5. 커널/부트로더를 자체 키로 서명
$ sbsign --key db.key --cert db.crt \
    --output vmlinuz.signed vmlinuz
$ sbsign --key db.key --cert db.crt \
    --output grubx64.efi.signed grubx64.efi
주의 — PK 등록 순서: PK를 마지막에 등록해야 합니다. PK가 등록되면 Setup Mode가 종료되고, 이후 모든 변수 수정은 해당 레벨의 키 서명이 필요합니다. db를 먼저 등록하지 않으면, PK 등록 후 db를 수정할 키가 없는 상태가 됩니다.

키 교체 (Key Rotation)

# db 키 교체 시나리오:
# 1. 새 db 키 생성
$ openssl req -new -x509 -newkey rsa:4096 -keyout db-new.key \
    -out db-new.crt -nodes -days 3650 \
    -subj "/CN=My New DB Key 2026"

# 2. 새 키를 db에 추가 (기존 키 유지, append 모드)
$ cert-to-efi-sig-list db-new.crt db-new.esl
$ sign-efi-sig-list -a -k KEK.key -c KEK.crt db db-new.esl db-append.auth
$ efi-updatevar -a -f db-append.auth db

# 3. 새 키로 커널/부트로더 재서명
$ sbsign --key db-new.key --cert db-new.crt --output vmlinuz.signed vmlinuz

# 4. 검증 후 구 키 제거 (선택)
# → 새 db를 만들어 덮어씀 (구 키 미포함)

# PK 교체:
# 현재 PK로 새 PK를 서명하여 업데이트
$ sign-efi-sig-list -k PK-old.key -c PK-old.crt PK PK-new.esl PK-new.auth
$ efi-updatevar -f PK-new.auth PK

12. 커널 내부 구현

소스 트리 구조

경로설명
security/integrity/IMA/EVM 프레임워크
security/integrity/ima/IMA 핵심 구현 (정책, 측정, 검증)
security/integrity/evm/EVM 구현 (HMAC/서명)
security/integrity/platform_certs/UEFI db/MOK에서 키 로드
security/lockdown/Lockdown LSM
certs/빌드 시 인증서 처리, system_keyring
crypto/asymmetric_keys/비대칭키, PKCS#7, X.509 파서
kernel/module/signing.c모듈 서명 검증
drivers/firmware/efi/UEFI 런타임, efivars, Secure Boot 감지
include/linux/verification.h서명 검증 API

플랫폼 키링 로드

/* security/integrity/platform_certs/load_uefi.c
 *
 * Secure Boot db에서 인증서를 로드하여 .platform_keyring에 추가
 * 커널 초기화 시 자동으로 호출됨
 */
static int __init load_uefi_certs(void)
{
    efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID;
    efi_guid_t mok_var = EFI_SHIM_LOCK_GUID;
    void *db = NULL, *dbx = NULL, *mok = NULL;
    unsigned long dbsize, dbxsize, moksize;

    /* UEFI db 변수에서 인증서 로드 → .platform_keyring */
    db = get_cert_list(L"db", &secure_var, &dbsize);
    if (db) {
        add_to_platform_keyring("UEFI:db", db, dbsize);
        kfree(db);
    }

    /* UEFI dbx 변수에서 폐기 목록 로드 → .blacklist_keyring */
    dbx = get_cert_list(L"dbx", &secure_var, &dbxsize);
    if (dbx) {
        add_to_blacklist_keyring("UEFI:dbx", dbx, dbxsize);
        kfree(dbx);
    }

    /* Shim MOK 변수에서 인증서 로드 → .platform_keyring */
    mok = get_cert_list(L"MokListRT", &mok_var, &moksize);
    if (mok) {
        add_to_platform_keyring("UEFI:MokListRT", mok, moksize);
        kfree(mok);
    }

    return 0;
}
late_initcall(load_uefi_certs);

키링 계층 구조

/*
 * Linux 커널 키링 계층:
 *
 * .builtin_trusted_keys        ← 커널 빌드 시 내장 (CONFIG_SYSTEM_TRUSTED_KEYS)
 *   │                             자기 서명 인증서 또는 CA 인증서
 *   │
 *   ├── .secondary_trusted_keys ← 런타임 추가 가능 (builtin으로 서명된 키만)
 *   │     ├── MOK 인증서         ← Shim에서 전달
 *   │     └── IMA 키             ← IMA 정책에 의해 추가
 *   │
 *   ├── .platform_keyring       ← UEFI db + MokListRT에서 자동 로드
 *   │                             모듈/kexec 검증에 사용
 *   │
 *   ├── .blacklist_keyring      ← UEFI dbx에서 자동 로드
 *   │                             차단할 키/해시
 *   │
 *   └── .ima_keyring            ← IMA appraise용 공개키
 *                                  (CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY)
 */

# 키링 내용 확인
$ keyctl show %:.builtin_trusted_keys
Keyring
 123456 ---lswrv 0 0 asymmetric: Build time autogenerated kernel key: ab:cd:...

$ keyctl show %:.platform_keyring
Keyring
 234567 ---lswrv 0 0 asymmetric: Microsoft Corporation UEFI CA 2011: ...
 345678 ---lswrv 0 0 asymmetric: Canonical Ltd. Secure Boot Signing: ...

$ keyctl show %:.blacklist_keyring
Keyring
 456789 ---lswrv 0 0 blacklist: tbs:abc123...

13. 트러블슈팅

일반적인 문제와 해결

증상원인해결
부팅 시 "Security Violation"서명되지 않은 부트로더/커널db에 등록된 키로 서명, 또는 MOK 등록
modprobe: ERROR: could not insert module: Required key not available모듈 서명 누락 또는 키 불일치sign-file로 모듈 서명, 또는 MOK에 키 등록
Lockdown: debugfs: restrictedLockdown integrity 모드 활성lockdown=none 커맨드라인 (디버깅 시)
DKMS 모듈 로드 실패자동 서명 미설정DKMS MOK 키 생성 + mokutil --import
kexec: Permission deniedCONFIG_KEXEC_SIG_FORCE + 미서명 커널서명된 커널 사용 또는 kexec -s 옵션
Setup Mode에서 PK 등록 불가일부 펌웨어에서 Setup Mode 진입 방식 상이BIOS 설정에서 "Clear Secure Boot keys" 후 재시도
SBAT 정책에 의한 GRUB 거부SbatLevel이 GRUB의 세대번호보다 높음최신 GRUB 패키지 업데이트
IMA appraise 실패로 파일 실행 불가security.ima xattr 누락/불일치evmctl ima_sign으로 재서명

디버깅 명령

# ============ Secure Boot 상태 확인 ============
# Secure Boot 활성 여부
$ mokutil --sb-state
SecureBoot enabled

# UEFI 변수 직접 확인
$ od -An -tx1 /sys/firmware/efi/efivars/SecureBoot-*
06 00 00 00 01
#              ^^ 01 = enabled, 00 = disabled

# Setup Mode 확인
$ od -An -tx1 /sys/firmware/efi/efivars/SetupMode-*
06 00 00 00 00
#              ^^ 00 = User Mode, 01 = Setup Mode

# ============ 키/인증서 확인 ============
# UEFI 보안 변수 목록
$ efi-readvar
Variable PK, length 862
PK: List 0, type X509
    Signature 0, size 834, owner ...
        Subject: CN=...
Variable KEK, length 1532
...

# 등록된 MOK 확인
$ mokutil --list-enrolled

# SBAT 폐기 목록
$ mokutil --list-sbat-revocations

# ============ 커널 키링 ============
$ keyctl show %:.builtin_trusted_keys
$ keyctl show %:.secondary_trusted_keys
$ keyctl show %:.platform_keyring
$ keyctl show %:.blacklist_keyring

# ============ 부팅 로그 ============
$ dmesg | grep -iE "secure.boot|lockdown|integrity|efi.*cert|ima|evm"
secureboot: Secure boot enabled
Lockdown: Kernel is locked down from EFI Secure Boot mode
integrity: Platform Keyring initialized
integrity: Loading X.509 certificate: UEFI:db
ima: policy update completed

# ============ 모듈 서명 ============
# 특정 모듈의 서명 정보
$ modinfo -F signer 
$ modinfo -F sig_hashalgo 

# 서명 없는 모듈 찾기
$ for mod in $(find /lib/modules/$(uname -r) -name "*.ko"); do
    if ! modinfo -F signer $mod &>/dev/null; then
        echo "Unsigned: $mod"
    fi
done

14. 커널 설정 종합

# ===== Secure Boot 관련 커널 설정 종합 =====

# -- 기본 EFI 지원 --
CONFIG_EFI=y
CONFIG_EFI_STUB=y
CONFIG_EFI_SECURE_BOOT_SIG_ENFORCE=y

# -- Lockdown LSM --
CONFIG_SECURITY_LOCKDOWN_LSM=y
CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y
CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT=y

# -- 모듈 서명 --
CONFIG_MODULE_SIG=y
CONFIG_MODULE_SIG_FORCE=y
CONFIG_MODULE_SIG_ALL=y
CONFIG_MODULE_SIG_SHA256=y
CONFIG_MODULE_SIG_KEY="certs/signing_key.pem"

# -- 키링/인증서 --
CONFIG_SYSTEM_TRUSTED_KEYRING=y
CONFIG_SYSTEM_TRUSTED_KEYS="certs/signing_key.pem"
CONFIG_SECONDARY_TRUSTED_KEYRING=y
CONFIG_INTEGRITY_PLATFORM_KEYRING=y

# -- 비대칭키/서명 검증 --
CONFIG_ASYMMETRIC_KEY_TYPE=y
CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
CONFIG_X509_CERTIFICATE_PARSER=y
CONFIG_PKCS7_MESSAGE_PARSER=y
CONFIG_PKCS7_TEST_KEY=y
CONFIG_SIGNED_PE_FILE_VERIFICATION=y

# -- kexec 서명 --
CONFIG_KEXEC_FILE=y
CONFIG_KEXEC_SIG=y
CONFIG_KEXEC_SIG_FORCE=y
CONFIG_KEXEC_BZIMAGE_VERIFY_SIG=y

# -- IMA/EVM --
CONFIG_INTEGRITY=y
CONFIG_INTEGRITY_SIGNATURE=y
CONFIG_IMA=y
CONFIG_IMA_MEASURE_PCR_IDX=10
CONFIG_IMA_APPRAISE=y
CONFIG_IMA_APPRAISE_MODSIG=y
CONFIG_EVM=y

# -- dm-verity --
CONFIG_DM_VERITY=y
CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y
CONFIG_DM_VERITY_FEC=y

# -- TPM --
CONFIG_TCG_TPM=y
CONFIG_TCG_TIS=y
CONFIG_TCG_CRB=y