신뢰할 수 있는 실행 환경 EFI 프로토콜

라이선스: Microsoft는 이 사양의 구현을 생성, 사용, 판매, 영업 제안, 수입, 배포하기 위한 목적으로만 합리적이고 비차별적인 조건으로 필요한 클레임에 대한 무료의 로열티가 없는 라이선스를 사용자에게 부여하는 데 동의합니다. "필요한 클레임"은 이 사양의 필수 부분(선택적 부분의 필수 요소 포함)을 구현하는 데 기술적으로 필요한 Microsoft 소유 또는 Microsoft 관리 특허의 클레임입니다. 여기서, 침해의 원인이 되는 기능은 이 사양에서 단순히 참조되지 않고 자세히 설명됩니다.

1.0 소개

이 문서에서는 TrEE(신뢰할 수 있는 실행 환경)와 상호 작용하기 위한 EFI 프로토콜을 지정하고, TCG(신뢰할 수 있는 컴퓨팅 그룹) 신뢰할 수 있는 플랫폼 모듈 2.0 라이브러리 사양에 따라 TPM 2.0 기능을 구현합니다. 또한 이 문서에서는 플랫폼 펌웨어 측정 요구 사항도 지정합니다. 이 문서에 정의된 EFI 프로토콜은 대규모 [TCG06a] 및 [TCG06b]를 활용합니다.

2.0 데이터 구조 및 약어

2.1 데이터 구조

[TCG06a]처럼 모든 데이터 값은 Little-Endian 형식으로 표현되어야 합니다. 문자열은 맨 왼쪽에 있는 문자가 가장 낮은 메모리 위치에 배치되는 ASCII 바이트 배열로 표현되어야 합니다.

2.2 약어 및 규칙

(여기에 정의되지 않은 약어는 [TCG06a] 참조)

TrEETrusted 실행 환경

이 문서에서 "~야 합니다"라는 문구는 [RFC2119]에 따라 해석해야 합니다.

3.0 EFI TrEE 프로토콜

이 섹션에서는 EFI_TREE_PROTOCOL 및 EFI_TREE_SERVICE_BINDING_PROTOCOL에 대해 자세히 설명합니다. EFI TrEE 프로토콜은 TrEE와 통신하는 데 사용됩니다.

3.1 TrEE EFI 서비스 바인딩 프로토콜

이 섹션에서는 TrEE EFI 서비스 바인딩 프로토콜을 정의합니다.

요약 - EFI TrEE 서비스 바인딩 프로토콜은 EFI TrEE 프로토콜 드라이버에서 지원되는 TrEE 디바이스를 찾고, 기본 TrEE 디바이스를 사용할 수 있는 EFI TrEE 프로토콜 자식 드라이버 인스턴스를 만들고 삭제하는 데 사용됩니다.

GUID - #define EFI_TREE_SERVICE_BINDING_PROTOCOL_GUID \ {0x4cf01d0a, 0xc48c, 0x4271, 0xa2, 0x2a, 0xad, 0x8e, 0x55, 0x97,\ 0x81, 0x88}

설명 TrEE 서비스가 필요한 애플리케이션(또는 드라이버)은 BS->LocateHandleBuffer()와 같은 프로토콜 처리기 서비스 중 하나를 사용하여 EFI TrEE 서비스 바인딩 프로토콜을 게시하는 디바이스를 검색할 수 있습니다. 게시된 EFI TrEE 서비스 바인딩 프로토콜이 있는 각 디바이스는 EFI TrEE 프로토콜을 지원하며 사용할 수 있습니다.

EFI_TREE_SERVICE_BINDING_PROTOCOL.CreateChild() 함수가 성공적으로 호출되면 자식 EFI TrEE 프로토콜 드라이버 인스턴스를 사용할 준비가 된 것입니다.

EFI 애플리케이션 또는 드라이버가 실행을 종료하기 전에, 성공적인 모든 EFI_TREE_SERVICE_BINDING_PROTOCOL.CreateChild() 함수 호출이 EFI_TREE_SERVICE_BINDING_PROTOCOL.DestroyChild() 함수 호출과 일치해야 합니다.

3.2 TrEE EFI 프로토콜

요약 - EFI TrEE 프로토콜은 TrEE와 통신하는 데 사용됩니다. TrEE에 명령을 보내려면 이 프로토콜을 신뢰할 수 있는 실행 작업에 사용하고 TrEE에서 확장된 측정값의 펌웨어 로그에 대한 액세스를 제공합니다. 이 프로토콜은 이 사양에서는 TrEE 이벤트 로그 형식 TCG 1.2 이벤트 로그라고 부르는 TCG 1.2 TCG 이벤트 로그와 동일한 형식으로 TrEE에 기록된 측정값의 이벤트 로그를 유지합니다([TCG06b] 참조). 구현자는 다른 형식으로 추가 이벤트 로그를 만들 수 있지만, 이 버전의 프로토콜은 추가 이벤트를 검색하는 방법을 정의하지 않습니다.

GUID - #define EFI_TREE_PROTOCOL_GUID \ {0x607f766c, 0x7455, 0x42be, 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2,\ 0x72, 0x0f}

프로토콜 인터페이스 구조 -

typedef struct _EFI_TREE_PROTOCOL {
  EFI_TREE_GET_CAPABILITYGetCapability;
  EFI_TREE_GET_EVENT_LOGGetEventLog;
  EFI_TREE_HASH_LOG_EXTEND_EVENTHashLogExtendEvent;
  EFI_TREE_SUBMIT_COMMANDSubmitCommand;
} EFI_TREE_PROTOCOL;

매개 변수

GetCapability

이 서비스는 TrEE 및 펌웨어 기능에 대한 정보를 제공합니다.

GetEventLog

펌웨어 이벤트 로그에 대한 포인터를 가져옵니다.

HashLogExtendEvent

이 서비스를 사용하면 EFI TrEE 드라이버가 이벤트를 확장하고 (선택 사항으로) 이벤트를 TrEE 로그에 씁니다.

SubmitCommand

이 서비스는 TrEE에 직접 명령을 제출합니다.

설명 - EFI_TREE_PROTOCOL은 TrEE 활동을 추상화합니다. 이 프로토콜 인스턴스는 부팅 서비스를 제공하며 부팅 서비스 드라이버로 인스턴스화됩니다.

ExitBootServices ( )가 호출되고 부팅 서비스 드라이버에서 사용하는 모든 메모리 리소스가 운영 체제 환경에 사용하기 위해 해제되면 부팅 서비스 드라이버가 종료됩니다.

이 부팅 서비스는 EVT_SIGNAL_EXIT_BOOT_SERVICES 이벤트를 만들어야 합니다. ExitBootServices ( )가 호출될 때 시스템에서 이 이벤트에 대한 알림을 받습니다.

EVT_SIGNAL_EXIT_BOOT_SERVICES는 특정 인터페이스 함수를 호출한 후 특정 활동이 발생하도록 하는 데 사용되는 동기 이벤트입니다. 이 경우 ExitBootServices ( ) 함수에 대한 응답으로 수행해야 하는 정리입니다. ExitBootServices ( )는 시스템에 로드된 드라이버를 대신하여 정리할 수 없습니다. 드라이버는 형식이 EVT_SIGNAL_EXIT_BOOT_SERVICES이고 알림 함수가 드라이버 자체 내의 함수인 이벤트를 만들어서 직접 정리를 수행해야 합니다. 그런 다음, ExitBootServices ( )는 정리를 마치면 EVT_SIGNAL_EXIT_BOOT_SERVICES 이벤트 유형을 보냅니다.

EFI 드라이버로 인스턴스화된 부팅 서비스가 이 필수 EVT_SIGNAL_EXIT_BOOT_SERVICES 이벤트를 만드는 방법에 대한 구현 세부 정보는 [UEFI12]의 섹션 6.1을 참조하세요.

3.3 EFI_TREE_PROTOCOL.GetCapability

EFI_TREE_PROTOCOL GetCapability 함수를 호출하면 프로토콜 기능 정보 및 TrEE에 대한 상태 정보가 제공됩니다.

프로토타입

typedef
EFI_STATUS
(EFIAPI *EFI_TREE_GET_CAPABILITY) (
  IN EFI_TREE_PROTOCOL      *This,
  IN OUT TREE_BOOT_SERVICE_CAPABILITY*ProtocolCapability,
);

매개 변수

This

호출 컨텍스트를 나타냅니다.

ProtocolCapability

호출자는 TREE_BOOT_SERVICE_CAPABILITY 구조체에 대한 메모리를 할당하고 크기 필드를 할당된 구조체의 크기로 설정합니다. 호출 수신자는 전달된 구조체의 크기에 맞는 필드 개수까지 EFI 프로토콜 기능 정보 및 현재 TrEE 상태 정보로 필드를 채웁니다.

관련 정의

typedef struct _TREE_VERSION { 
  UINT8 Major; 
  UINT8 Minor; 
} TREE_VERSION;
typedef UINT64 EFI_PHYSICAL_ADDRESS;
typedef UINT32 TREE_EVENT_LOG_BITMAP;
typedef UINT32 TREE_EVENT_LOG_FORMAT;
#define TREE_EVENT_LOG_FORMAT_TCG_1_2 0x00000001
typedef struct _TREE_BOOT_SERVICE_CAPABILITY { 
  UINT8 Size;
  TREE_VERSION StructureVersion; 
  TREE_VERSION ProtocolVersion;
  UINT32 HashAlgorithmBitmap;
  TREE_EVENT_LOG_BITMAPSupportedEventLogs;
  BOOLEAN TrEEPresentFlag;
  UINT16MaxCommandSize;
  UINT16MaxResponseSize;
  UINT32ManufacturerID;  
} TREE_BOOT_SERVICE_CAPABILITY;

#define TREE_BOOT_HASH_ALG_SHA1       0x00000001
#define TREE_BOOT_HASH_ALG_SHA256     0x00000002
#define TREE_BOOT_HASH_ALG_SHA384     0x00000004
#define TREE_BOOT_HASH_ALG_SHA512     0x00000008

크기

전달된 구조체에 할당된 크기

StructureVersion

TREE_BOOT_SERVICE_CAPABILITY 구조체 자체의 버전입니다. 이 프로토콜 버전의 경우 버전은 1로 설정하고 버전은 0으로 설정해야 합니다.

ProtocolVersion

TrEE 프로토콜의 버전입니다. 이 프로토콜 버전의 경우 버전은 1로 설정하고 버전은 0으로 설정해야 합니다.

HashAlgorithmBitMap

지원되는 해시 알고리즘

SupportedEventLogs

지원되는 이벤트 로그 형식의 비트맵(위 참조)

TrEEPresentFlag

False = TrEE가 없음

MaxCommandSize

TrEE로 보낼 수 있는 명령의 최대 크기(바이트)

MaxResponseSize

TrEE에서 제공할 수 있는 응답의 최대 크기(바이트)

ManufacturerID

4바이트 공급업체 ID([TCG07]의 "TPM 기능 공급업체 ID" 섹션 참조)

설명

EFI_TREE_PROTOCOL Get Capability 함수를 호출하면 EFI 프로토콜 버전 및 기능 정보와 TrEE에 대한 상태 정보가 제공됩니다. 호출자는 할당된 TREE_BOOT_SERVICE_CAPABILITY 구조체의 크기 필드를 설정해야 합니다. 이 함수의 향후 버전에서는 호출 후 구조체에 필드를 더 추가할 수 있을 것으로 예상됩니다. 전달된 크기 값을 사용하면 이 함수는 호출자가 메모리를 할당한 필드만 채울 수 있습니다. 예:

ProtocolCapability.Size = sizeof(TREE_BOOT_SERVICE_CAPABILITY);

이 버전의 사양은 다음과 같습니다.

  1. This 또는 ProtocolCapability 매개 변수가 NULL이면 함수 호출 시 EFI_INVALID_PARAMETER가 반환됩니다.

  2. 입력 ProtocolCapability.Size < sizeof(TREE_BOOT_SERVICE_CAPABILITY)이면 이 함수는 이 사양에 정의된 대로 ProtocolCapability.Size를 sizeof(TREE_BOOT_SERVICE_CAPABILITY)와 동일하게 설정하고 EFI_BUFFER_TOO_SMALL 오류 코드를 반환합니다. 나머지 필드의 값은 정의되지 않습니다.

  3. 다음 반환 값을 설정해야 합니다.

    ProtocolCapability.StructureVersion.Major = 1

    ProtocolCapability.StructureVersion.Minor = 0

    ProtocolCapability.ProtocolVersion.Major = 1

    ProtocolCapability.ProtocolVersion.Minor = 0

  4. 플랫폼에 TrEE가 없는 경우 다음 값을 반환해야 합니다.

    ProtocolCapability.SupportedEventLogs = 0

    ProtocolCapability.HashAlgorithmBitmap = 0

    ProtocolCapability.TrEEPresentFlag = FALSE

    ProtocolCapability.MaxCommandSize = 0

    ProtocolCapability.MaxResponseSize = 0

    ProtocolCapability.ManufacturerID = 0

  5. Windows의 경우 최소 MaxCommandSize 및 MaxResponseSize가 0x500 이상이어야 합니다.

반환되는 상태 코드

EFI_SUCCESS

작업이 완료되었습니다.

EFI_DEVICE_ERROR

명령이 실패했습니다. ProtocolCapability 변수가 채워지지 않습니다.

EFI_INVALID_PARAMETER

하나 이상의 매개 변수가 잘못되었습니다. ProtocolCapability 변수가 채워지지 않습니다.

EFI_BUFFER_TOO_SMALL

ProtocolCapability 변수가 너무 작아서 전체 응답을 보유할 수 없습니다. 부분적으로 채워집니다(필요한 Size 필드가 설정됨).

3.4 EFI_TREE_PROTOCOL.GetEventLog

EFI_TREE_PROTOCOL Get Event Log 함수를 호출하면 호출자가 특정 이벤트 로그의 주소와 마지막 항목을 검색할 수 있습니다.

프로토타입

typedef
EFI_STATUS
(EFIAPI *EFI_TREE_GET_EVENT_LOG) (
  IN  EFI_TREE_PROTOCOL      *This,
  IN  TREE_EVENT_LOG_FORMATEventLogFormat,
  OUT EFI_PHYSICAL_ADDRESS*EventLogLocation,
  OUT EFI_PHYSICAL_ADDRESS*EventLogLastEntry,
  OUT BOOLEAN*EventLogTruncated
);

매개 변수

EventLogFormat

정보가 요청되는 이벤트 로그의 형식입니다.

EventLogLocation

이벤트 로그의 메모리 주소를 가리키는 포인터입니다.

EventLogLastEntry

이벤트 로그에 둘 이상의 항목이 포함된 경우 메모리에 있는 이벤트 로그의 마지막 항목 시작 주소를 가리키는 포인터입니다. 이벤트 로그가 비어 있거나 이벤트 로그의 항목이 하나뿐인 특수한 상황에서 이 매개 변수에 반환되는 값에 대한 자세한 내용은 아래 설명 섹션을 참조하세요.

EventLogTruncated

이벤트가 이벤트에 할당된 영역을 초과했기 때문에 이벤트 로그에 하나 이상의 항목이 누락된 경우 이 값은 TRUE로 설정됩니다. 그렇지 않으면 이 값이 FALSE이고 이벤트 로그가 완료됩니다.

설명

펌웨어는 부팅 프로세스 중에 TrEE에 기록된 측정값의 이벤트 로그를 관리합니다. 부팅 프로세스 동안 UEFI 플랫폼 초기화 전에 TrEE에서 확장된 각 측정값에 대한 이벤트 로그에 항목이 만들어집니다. UEFI 환경에서는 TrEE에서 측정값을 확장하기 위해 HashLogExtendEvent를 호출할 때마다 일반적으로 확장된 측정값이 포함된 이벤트 로그에 이벤트가 기록됩니다. 펌웨어가 이벤트 로그에 할당한 영역이 너무 작아서 추가된 모든 이벤트를 보유할 수 없는 경우 함수를 호출하면 이벤트 로그가 잘렸고 누락된 항목이 있다는 내용이 표시됩니다. 이 버전의 사양은 SHA1 측정의 이벤트 로그만 유지하면 됩니다. 이 사양의 향후 버전에서는 여러 해시 알고리즘을 지원하는 추가 이벤트 로그를 유지할 수 있게 될 수도 있습니다.

이 함수에서 반환된 이벤트 로그 영역은 ExitBootServices ( )가 호출될 때 해제됩니다. ExitBootServices ( )가 호출된 후에는 이 메서드의 호출자가 영역에 액세스하면 안 됩니다. 이 버전의 사양은 다음과 같습니다.

  1. EventLogFormat이 TREE_EVENT_LOG_FORMAT_TCG_1_2와 다른 경우 이 함수를 호출하면 EFI_INVALID_PARAMETER가 반환되어야 합니다.

  2. TrEE가 없는 경우 이 함수는 다음 값을 설정하고 EFI_SUCCESS를 반환해야 합니다.

    1. EventLogLocation = NULL

    2. EventLogLastEntry = NULL

    3. EventLogTruncated = FALSE

  3. EventLogLocation 값은 메모리에서 지정된 이벤트 로그 형식의 시작으로 설정해야 합니다.

  4. 지정된 이벤트 로그에

    1. 이벤트가 없는 경우 EventLogLastEntry를 0으로 설정해야 합니다.

    2. 정확히 1개 항목이 있는 경우 EventLogLastEntry를 EventLogLocation과 동일한 값으로 설정해야 합니다.

    3. 2개 이상의 이벤트가 있는 경우 EventLogLastEntry를 지정된 이벤트 로그의 마지막 이벤트 시작 주소로 설정해야 합니다.

  5. 이전에 EFI_TREE_PROTOCOL.HashLogExtendEvent를 호출했을 때 EFI_VOLUME_FULL이 반환된 경우 EventLogTruncated를 TRUE로 설정해야 하고, 그렇지 않은 경우 FALSE로 설정해야 합니다.

반환되는 상태 코드

EFI_SUCCESS

작업이 완료되었습니다.

EFI_INVALID_PARAMETER

하나 이상의 매개 변수가 잘못되었습니다(예: 지원되지 않는 형식의 이벤트 로그 요청).

3.5 EFI_TREE_PROTOCOL.HashLogExtendEvent

EFI_TREE_PROTOCOL HashLogExtendEvent 함수를 호출하면 실제 TPM 명령에 대한 지식이 없어도 이벤트를 확장하고 필요에 따라 이벤트를 로깅할 수 있는 기회가 호출자에게 제공됩니다. 확장 작업은 이 함수가 이벤트 로그 항목을 만들 수 없는 경우에도 발생합니다(예: 이벤트 로그가 가득 차서).

프로토타입

typedef
EFI_STATUS
(EFIAPI * EFI_TREE_HASH_LOG_EXTEND_EVENT) (
  IN EFI_TREE_PROTOCOL*This,
  IN UINT64Flags,
  IN EFI_PHYSICAL_ADDRESSDataToHash,
  IN UINT64DataToHashLen,
  IN TrEE_EVENT*Event,
);

매개 변수

This

호출 컨텍스트를 나타냅니다.

플래그

추가 정보를 제공하는 비트맵(아래 참조)입니다.

DataToHash

해시할 데이터 버퍼의 실제 시작

주소입니다.

DataToHashLen

DataToHash에서 참조하는 버퍼의 길이(바이트)입니다.

Event

이벤트에 대한 정보를 포함하고 있는 데이터 버퍼를 가리키는 포인터입니다.

관련 정의

#pragma pack(1)
typedef struct _TrEE_EVENT {
  UINT32Size;            
  TrEE_EVENT_HEADERHeader;
  UINT8Event[ANYSIZE_ARRAY];
} TrEE_EVENT;
typedef struct _TrEE_EVENT_HEADER {
  UINT32HeaderSize;
  UINT16HeaderVersion;
  TrEE_PCRINDEXPCRIndex;
  TrEE_EVENTTYPEEventType;
} TrEE_EVENT_HEADER;
#pragma pack()
typedef UINT32 TrEE_PCRINDEX;
typedef UINT32 TrEE_EVENTTYPE;

크기

크기 구성 요소, 헤더 및 이벤트 데이터를 포함한 이벤트의 총 크기입니다.

HeaderSize

이벤트 헤더 자체의 크기(sizeof(TrEE_EVENT_HEADER))입니다.

HeaderVersion

헤더 버전입니다. 이 사양 버전에서는 값이 1이어야 합니다.

PCRIndex

확장해야 PCR의 인덱스입니다(0~23).

EventType

확장(그리고 필요에 따라 로깅)해야 하는 이벤트 유형입니다.

플래그 값

Flags 변수는 다음과 같이 추가 데이터를 제공하는 비트맵입니다.

#define TREE_EXTEND_ONLY 0x0000000000000001

이벤트를 확장해야 하지만 기록하지 않을 때에는 이 비트를 설정해야 합니다.

#define PE_COFF_IMAGE 0x0000000000000010

PE/COFF 이미지를 측정하려는 경우 이 비트를 설정해야 합니다.

설명

EFI_TREE_PROTOCOL Hash Log Extend Event 함수를 호출하면 데이터 버퍼(PE/COFF 이진 이미지를 포함하고 있을 수 있음) 측정값이 계산되고 TrEE 드라이버가 측정을 확장합니다. 또한 이 서비스는 필요에 따라 이벤트 로그 항목을 만들고 서비스에서 지원하는 각 이벤트 로그 형식에 대한 이벤트 로그에 추가합니다. 이 서비스를 사용하면 호출자는 특정 TrEE 명령에 대해 몰라도 TrEE를 사용할 수 있습니다.

이미지를 다시 배치하려면 먼저 이 함수를 사용하여 PE/COFF 이미지를 측정해야 합니다. 참고: PE/COFF 이미지를 측정하려면 이 메서드를 신중하게 사용합니다. 일반적으로 PE/COFF 이미지를 로드하는 구현은 이미지에서 로드하는 프로세스 중에 중요한 데이터를 제거하고 메모리의 이미지 섹션 맞춤을 변경할 수 있습니다. 결과적으로 메모리 내 이미지의 해시 계산 값이 스토리지 미디어에서 로드될 때 올바르게 계산된 이미지의 실제 측정값과 일치하지 않습니다.

이 함수는 호출되면 다음 작업을 수행해야 합니다.

  1. This, DataToHash 또는 Event 매개 변수 중 하나라도 NULL이면 이 함수는 EFI_INVALID_PARAMETER를 반환해야 합니다.

  2. Event.Size가 Event.Header.HeaderSize + sizeof(UINT32)보다 작으면 이 함수는 EFI_INVALID_PARAMETER를 반환해야 합니다.

  3. Event.Header.PCRIndex가 0~23 사이의 값이 아니면 이 함수는 EFI_INVALID_PARAMETER를 반환해야 합니다.

  4. Flags 비트맵에서 PE_COFF_IMAGE 비트가 설정되었지만 PE/COFF 이미지가 손상되었거나 이해할 수 없는 경우 이 함수는 EFI_UNSUPPORTED를 반환해야 합니다.

  5. 이 함수는 Event.Header.EventType 매개 변수에 모든 값을 허용합니다.

  6. 이 함수는 DataToHash에서 시작하는 데이터의 다이제스트(측정값)를 DataToHashLen 길이로 계산해야 합니다. PE_COFF_IMAGE 비트가 설정되면 이 함수는 아래 부록 A의 "PE/COFF 이미지 측정"에 따라 PE/COFF 이미지의 측정값을 계산해야 합니다.

  7. 이 함수는 측정 다이제스트를 사용하여 Event.Header.PCRIndex로 표시된 PCR을 확장할 수 있도록 TPM2_PCR_Extend 명령을 TrEE에 성공적으로 보내야 합니다. 명령을 성공적으로 보낼 수 없는 경우 이 함수는 EFI_DEVICE_ERROR를 반환해야 합니다. 펌웨어가 SHA1보다 많은 알고리즘을 지원하는 경우 다른 알고리즘을 사용하여 다이제스트를 계산하고 확장할 수도 있습니다.

  8. 이전에 이 함수를 호출했을 때 EFI_VOLUME_FULL이 반환되고 TREE_EXTEND_ONLY 비트가 Flags 매개 변수에서 설정된 경우 이 함수는 EFI_VOLUME_FULL을 반환해야 합니다. (이벤트 로그에 이벤트 로그 항목을 추가하려는 시도가 수행되지 않습니다.)

  9. 이 함수는 다음과 같이 TCG 이벤트 로그 항목을 작성해야 합니다. (참고: TCG_PCR_EVENT 구조체는 [TCG06b]에 정의되며 바이트 정렬로 간주되어야 합니다.)

    1. TCG_PCR_EVENT.PCRIndex = Event.Header.PCRIndex

    2. TCG_PCR_EVENT.EventType = Event.Header.EventType

    3. TCG_PCR_EVENT.Digest = <위에서 계산한 SHA1 측정 다이제스트>

    4. TCG_PCR_EVENT.EventSize = Event.Size - sizeof(UINT32) - Event.Header.HeaderSize

    5. TCG_PCR_EVENT.Event = Event.Event(참고: 이것은 EventSize 바이트의 메모리 복사본임)

  10. 이 함수는 지원되는 다른 이벤트 로그 형식에 대해 유사한 이벤트 로그 항목을 작성할 수 있습니다.

  11. 위에서 만든 TCG_PCR_EVENT 이벤트 로그 항목이 TrEE 이벤트 로그 형식 TCG 1.2 이벤트 로그에 할당된 영역에 맞지 않는 경우 이 함수는 EFI_VOLUME_FULL을 반환해야 합니다.

  12. 펌웨어가 추가 이벤트 로그 형식을 지원하고 해당 이벤트 로그에 대해 생성된 이벤트가 이벤트 로그에 할당된 영역을 초과하는 경우 이 함수는 EFI_VOLUME_FULL을 반환해야 합니다.

  13. 이 함수는 해당 이벤트 로그에 생성된 이벤트를 추가해야 하고 이 서비스는 해당 내부 포인터를 각 이벤트 로그의 마지막 이벤트 시작으로 업데이트해야 합니다.

반환되는 상태 코드

EFI_SUCCESS

작업이 완료되었습니다.

EFI_DEVICE_ERROR

명령이 실패했습니다.

EFI_VOLUME_FULL

확장 작업이 발생했지만 하나 이상의 이벤트 로그에 이벤트를 쓸 수 없습니다.

EFI_INVALID_PARAMETER

하나 이상의 매개 변수가 잘못되었습니다.

EFI_UNSUPPORTED

PE/COFF 이미지 형식은 지원되지 않습니다.

3.6 EFI_TREE_PROTOCOL.SubmitCommand

이 서비스를 사용하면 TrEE에 명령을 보낼 수 있습니다.

프로토타입

typedef
EFI_STATUS
(EFIAPI *EFI_TREE_SUBMIT_COMMAND) (
  IN EFI_TREE_PROTOCOL*This,
  IN UINT32InputParameterBlockSize,
  IN UINT8*InputParameterBlock,
  IN UINT32OutputParameterBlockSize,
  IN UINT8*OutputParameterBlock 
);

매개 변수

This

호출 컨텍스트를 나타냅니다.

InputParameterBlockSize

TrEE 입력 매개 변수 블록의 크기입니다.

InputParameterBlock

TrEE 입력 매개 변수 블록의 포인터입니다.

OutputParameterBlockSize

TrEE 출력 매개 변수 블록의 크기입니다.

OutputParameterBlock

TrEE 출력 매개 변수 블록의 포인터입니다.

설명

EFI_TREE_PROTOCOL Submit Command 함수를 호출하면 호출자에서 시스템 TrEE로의 통과 기능이 제공됩니다.

TrEE로 보낼 명령 바이트스트림을 만들고 TrEE에서 반환된 결과 바이트스트림을 해석하는 것은 호출자의 몫입니다. 각 TrEE 명령의 TrEE 입력 및 출력 피연산자는 다른 곳에서 정의됩니다.

반환된 상태 코드는 기본 TrEE 명령의 성공(또는 실패) 여부가 아닌 함수 호출의 결과를 반영합니다.

TPM 2.0은 ExitBootServices() 호출이 완료되기 전에 TPM2_RC_RETRY를 반환하면 안 됩니다. (이렇게 요구하는 이유는 TPM 명령을 완료할 수 있을 때까지 반환 코드가 부팅 프로세스를 차단하기 때문입니다.)

TPM 2.0은 ExitBootServices 호출이 완료되기 전에 영구 스토리지에 액세스할 수 있어야 합니다. ExitBootServices를 호출한 후 TPM 2.0 구현에서 영구 스토리지에 액세스할 수 없는 경우 Microsoft에 추가 요구 사항을 문의하세요.

반환되는 상태 코드

EFI_SUCCESS

명령 바이트스트림이 디바이스에 성공적으로 전송되었고 응답이 성공적으로 수신되었습니다.

EFI_DEVICE_ERROR

명령이 디바이스에 전송되지 않았거나 디바이스에서 응답이 수신되지 않았습니다.

EFI_INVALID_PARAMETER

하나 이상의 매개 변수가 잘못되었습니다.

EFI_BUFFER_TOO_SMALL

출력 매개 변수 블록이 너무 작습니다.

참고 자료

[MSFT08]

Microsoft Corporation, "Windows Authenticode 이식 가능한 실행 파일 서명 형식", 버전 1.0, 2008년 3월 21일.

[RFC2119]

Bradner, S., "Keywords for Use in RFCs to Indicate Requirement Levels(요구 사항 수준을 나타내기 위해 RFC에 사용되는 키워드)," IETF RFC 2119, 1997년 3월.

[TCG06a]

신뢰할 수 있는 컴퓨팅 그룹, "TCG EFI 프로토콜", 버전 1.20 수중 버전 1.00, 2006년 6월 9일.

[TCG06b]

신뢰할 수 있는 컴퓨팅 그룹, "TCG EFI 플랫폼 사양", 버전 1.20 수정 버전 1.0, 2006년 6월 7일.

[TCG07]

신뢰할 수 있는 컴퓨팅 그룹, "TCG 공급업체 ID 레지스트리", 버전 1.0, 수정 버전 0.1, 2007년 8월 31일.

[UEFI12]

UEFI, "통합 확장 가능한 펌웨어 인터페이스 사양", 버전 2.3.1 오류 정정 C,

2012년 6월

부록 A: 정적 신뢰 측정 루트

중요

PCR[7] 측정값의 부록 A 구현은 InstantGo 시스템에 필수입니다.

간략하게 말해서, 펌웨어는 부팅 중에 다음과 같은 구성 요소를 측정해야 합니다.

  • UEFI 부팅 서비스 및 UEFI 런타임 서비스를 포함하거나 측정하는 플랫폼 펌웨어

  • 플랫폼 펌웨어와 관련된 보안 관련 변수

  • 별도로 로드된 UEFI 드라이버 또는 부팅 애플리케이션

  • 별도로 로드된 UEFI 드라이버 또는 UEFI 부팅 애플리케이션과 연결된 변수

위의 측정은 TCG EFI 플랫폼 사양 [TCG06b] 5.1~5.5 섹션에 정의되어 있으며 이 문서에서는 더 이상 언급하지 않습니다. PCR[1] 및 PCR[3] 측정은 플랫폼 구성에 따라 선택 사항입니다.

Windows 경우 PCR[7]은 UEFI 2.3.1 보안 부팅 정책을 반영하는 데 사용됩니다. 이 정책은 UEFI 환경 이전에 시작된 모든 부팅 구성 요소를 인증하는 펌웨어에 의존하며, UEFI 플랫폼 초기화 코드(또는 이전 펌웨어 코드)는 보안 부팅 정책 정보를 PCR[7]에 고정적으로 기록합니다.

따라서 정책을 준수하는 플랫폼 펌웨어는 PCR[7]에 다음 값을 측정해야 합니다.

  1. PK 변수의 내용

  2. KEK 변수의 내용

  3. EFI_IMAGE_SECURITY_DATABASE 변수의 내용

  4. EFI_IMAGE_SECURITY_DATABASE1 변수의 내용

  5. 부팅 경로에서 EFI 드라이버 또는 EFI 부팅 애플리케이션의 유효성을 검사하는 데 사용되는 EFI_IMAGE_SECURITY_DATABASE의 항목

  6. SecureBoot 변수의 내용

위의 이유로 UEFI 변수 PK, KEK, EFI_IMAGE_SECURITY_DATABASE, EFI_IMAGE_SECURITY_DATABASE1 및 SecureBoot는 PCR[3]로 측정하면 안 됩니다.

또한 플랫폼이 UEFI 환경 이전에 시작할 수 있는 펌웨어 디버거를 제공하는 경우 이 사실을 PCR[7]에 기록해야 합니다. 마찬가지로 플랫폼이 UEFI 환경에 대한 디버거를 제공하는 경우 디버거의 시작을 PCR[7]에 기록해야 합니다.

구현 참고 사항

UEFI LoadImage 함수는 [TCG06b]에 설명된 이벤트별 PCR[2] 또는 PCR[4]의 측정값을 기록해야 하며, 아래의 "PCR[7]로 UEFI 구성 측정" 섹션에 설명된 이벤트별 PCR[7]도 기록해야 합니다. 이미지 측정이 PCR[2] 또는 PCR[4]에 적용되는지 확인하려면 LoadImage 함수는 PE/COFF 이미지의 하위 시스템 필드를 검사해야 합니다. IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER, IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 및 IMAGE_SUBSYSTEM_EFI_ROM 값은 PCR[2]와 일치합니다. IMAGE_SUBSYSTEM_EFI_APPLICATION 값은 PCR[4]와 일치합니다. 로드된 이미지가 다른 형식인 경우 PCR[4]에 기록해야 합니다. (a) 서명 확인 실패로 인해 또는 (b) 이미지가 현재 적용된 UEFI 2.3.1 보안 부팅 정책을 준수하지 않아 LoadImage 함수가 로드할 수 없는 이미지는 PCR에서 측정할 필요가 없습니다.

****관련 정의

#define EV_EFI_VARIABLE_DRIVER_CONFIG \
                                  0x80000001 /* Defined in [TCG06b] */
#define EV_EFI_ACTION             0x80000007 /* Defined in [TCG06b] */
#define EV_EFI_VARIABLE_AUTHORITY 0x800000E0

This specification requires a modified TCG structure definition for EFI_VARIABLE_DATA.  The revised structure is:
typedef struct {
  EFI_GUIDVariableName;
  UINT64        UnicodeNameLength;    // The TCG Defintion used UINTN
  UINT64        VariableDataLength;   // The TCG Defintion used UINTN
  CHAR16       UnicodeName[1];
  INT8         VariableData[1];   
} EFI_VARIABLE_DATA;

PE/COFF 이미지 측정

PE/COFF 이미지를 측정할 때 EventType은 [TCG06b]에 정의되어야 하고(예: EFI 부팅 애플리케이션을 측정할 때 EventType은 EV_EFI_BOOT_SERVICES_APPLICATION이어야 함) 이벤트 값은 [TCG06b]에 정의된 EFI_IMAGE_LOAD_EVENT 구조체의 값이어야 합니다.

HashLogExtendEvent 서비스는 [MSFT08]의 "PE 이미지 해시 계산" 섹션에 지정된 절차에 따라 PE/COFF 이미지를 해시해야 합니다.

PCR[7]로 UEFI 구성 측정

모든 EFI 변수 값 이벤트의 경우 EventType은 위에서 정의한 EV_EFI_VARIABLE_DRIVER_CONFIG여야 하고, 이벤트 값은 이 사양의 위에서 정의한 EFI_VARIABLE_DATA 구조체의 값이어야 합니다(이 구조체는 바이트 정렬로 간주해야 함). 측정 다이제스트는 EFI_VARIABLE_DATA 구조체인 이벤트 데이터의 SHA-1 해시여야 합니다. (참고: 이 다이제스트는 [TCG06b]에서 지정한 다이제스트와 다릅니다.) EFI_VARIABLE_DATA.UnicodeNameLength 값은 CHAR16 문자 수입니다(바이트 수 아님). EFI_VARIABLE_DATA.UnicodeName 내용에 null 종결자가 있으면 안 됩니다. EFI 변수를 읽으면 EFI_NOT_FOUND가 반환되는 경우 EFI_VARIABLE_DATA.VariableDataLength 필드는 0으로 설정되어야 하고 EFI_VARIABLE_DATA.VariableData 필드의 크기는 0입니다.

  1. 플랫폼에서 UEFI 이전 환경에 사용할 수 있는 펌웨어 디버거 모드 또는 UEFI 환경용 디버거를 제공하는 경우 디버거 사용을 허용하기 전에 [TCG06b]에 지정된 대로 플랫폼에서 EV_EFI_ACTION 이벤트를 PCR[7]로 확장해야 합니다. 이벤트 문자열은 "UEFI Debug Mode"여야 합니다. 또한 플랫폼에서 다음과 같이 TCG 이벤트 로그 항목을 만들어야 합니다.

    1. TCG_PCR_EVENT.PCRIndex = 7

    2. TCG_PCR_EVENT.EventType = EV_EFI_ACTION

    3. TCG_PCR_EVENT.Digest = <종료 NULL 문자 없이 문자열 값 "UEFI Debug Mode"의 SHA-1 다이제스트>

    4. TCG_PCR_EVENT.EventSize = strlen("UEFI Debug Mode")

    5. TCG_PCR_EVENT.Event = "UEFI Debug Mode"

    이 플랫폼에서 지원되는 다른 이벤트 로그 형식에 대해 유사한 이벤트 로그 항목을 작성할 수 있습니다.

  2. 플랫폼 제조업체에서 제공하는 것으로 암호화 인증되지 않은 코드를 실행하기 전에, 플랫폼 제조업체 펌웨어는 EV_EFI_VARIABLE_DRIVER_CONFIG 이벤트 유형을 PCR[7]에 사용하여 다음 값을 나열된 순서대로 측정해야 합니다.

    1. SecureBoot 변수 값

    2. PK 변수 값

    3. KEK 변수 값

    4. EFI_IMAGE_SECURITY_DATABASE_GUID/EFI_IMAGE_SECURITY_DATABASE 변수 값

    5. EFI_IMAGE_SECURITY_DATABASE_GUID/EFI_IMAGE_SECURITY_DATABASE1 변수 값

  3. 다음 UEFI 정책 변수가 PCR[7]에서 처음으로 측정된 후 무조건 플랫폼을 다시 시작하지 않고 ExitBootServices ( )가 완료되기 전에 이러한 정책 변수를 변경할 수 있도록 플랫폼에서 지원하는 경우 변경 즉시 변수를 다시 측정해야 합니다. 또한 아래의 UEFI 변수를 설정하기 위한 일반적인 업데이트 프로세스는 PCR[7]에서 처음으로 측정하기 전에 또는 ExitBootServices() 호출이 완료된 후에 발생해야 합니다.

    1. SecureBoot 변수 값

    2. PK 변수 값

    3. KEK 변수 값

    4. EFI_IMAGE_SECURITY_DATABASE_GUID/EFI_IMAGE_SECURITY_DATABASE 변수 값

    5. EFI_IMAGE_SECURITY_DATABASE_GUID/EFI_IMAGE_SECURITY_DATABASE1 변수 값

  4. 시스템은 PCR[7]에서 EV_SEPARATOR 이벤트를 측정해야 합니다. (구분 기호가 PCR[7]에서 PCR[0]까지 측정되는 동시에 발생합니다.)

  5. EFI 드라이버 또는 EFI 부팅 애플리케이션을 시작하기 전에(그리고 EFI 부팅 관리자가 DriverOrder 또는 BootOrder UEFI 변수에서 이미지를 선택하여 시작되든 아니면 UEFI LoadImage() 함수를 호출하는 이미 시작된 이미지를 선택하여 시작되든 관계없이) UEFI 펌웨어는 PCR[7]에서 EFI 이미지의 유효성을 검사하는 데 사용된 EFI_IMAGE_SECURITY_DATABASE_GUID/EFI_IMAGE_SECURITY_DATABASE 변수의 항목을 측정해야 합니다. 측정은 이미지 로드와 함께 발생해야 합니다. 이 이벤트의 경우 EventType은 EV_EFI_VARIABLE_AUTHORITY이고 이벤트 값은 EFI_VARIABLE_DATA 구조체의 값이어야 합니다(구조체는 위에서 TCG 사양과 다른 정의를 사용하여 이 사양에서 정의됨). EFI_VARIABLE_DATA.VariableData 값은 이미지의 유효성을 검사하는 데 사용된 권한이 있는 EFI_SIGNATURE_LIST의 EFI_SIGNATURE_DATA 값이어야 하고 EFI_VARIABLE_DATA.VariableName은 EFI_IMAGE_SECURITY_DATABASE_GUID로 설정해야 합니다. EFI_VARIABLE_DATA.UnicodeName은 EFI_IMAGE_SECURITY_DATABASE 값으로 설정해야 합니다. 이 값에는 종결 NULL 문자가 있으면 안 됩니다.

  6. 추가 EFI 드라이버 또는 EFI 부팅 애플리케이션을 시작하기 전에, UEFI 펌웨어는 EFI 이미지의 유효성을 검사하는 EFI_IMAGE_SECURITY_DATABASE_GUID/EFI_IMAGE_SECURITY_DATABASE 변수의 항목이 이전에 PCR[7]에서 EV_EFI_VARIABLE_AUTHORITY 이벤트 유형으로 측정되었는지 확인해야 합니다. 측정되지 않은 경우 이전 단계에서 설명한 대로 측정해야 합니다. 이전에 측정된 경우 다시 측정해서는 안 됩니다.

참고

PCR[7] 측정에 대한 측정 예제는 Microsoft의 요청에 따라 사용할 수 있습니다.