📄 tcgbios.c
字号:
memset(&pcpes, 0x0, sizeof(pcpes)); pcpes.pcrindex = pcrIndex; pcpes.eventtype = event_type; /* specs: 10.4.1, EV_IPL eventfield should not contain the code.*/ pcpes.eventdatasize = 0; hleei.ipblength = 0x18; hleei.reserved = 0x0; hleei.hashdataptr = (uint32_t)ptr; hleei.hashdatalen = length; hleei.pcrindex = pcrIndex; hleei.logdataptr = (uint32_t)&pcpes; hleei.logdatalen = 32; rc = HashLogExtendEvent32(&hleei, &hleeo, TCG_MAGIC, 0x0, 0x0); return rc;}/* table of event types according to 10.4.1 / table 11 */static const char ev_action[][23] = { /* 0 */ "Calling INT 19h", "Returned INT 19h", "Returned via INT 18h", "", "", /* 5 */ "", "", "", "", "", /* 10 */ "", "", "", "", "Start Option ROM Scan"};static char evt_separator[] = {0xff,0xff,0xff,0xff}; static char wake_event_1[] = "Wake Event 1";/* * Add a measurement to the list of measurements * pcrIndex : PCR to be extended * event_type : type of event; specs 10.4.1 * data : additional parameter; used as parameter for 10.4.3 * 'action index' */static void tcpa_add_measurement(uint32_t pcrIndex, uint16_t event_type, uint32_t data){ const char *string; switch (event_type) { case EV_SEPARATOR: tcpa_add_measurement_to_log_simple(pcrIndex, event_type, (uint8_t *)evt_separator, 4); break; case EV_ACTION: string = ev_action[data /* event_id */]; tcpa_add_measurement_to_log(pcrIndex, event_type, data, string, strlen(string)); break; }}/* * Add measurement to log about call of int 19h */void tcpa_calling_int19h(){ tcpa_add_measurement(4, EV_ACTION, 0);}/* * Add measurement to log about retuning from int 19h */void tcpa_returned_int19h(){ tcpa_add_measurement(4, EV_ACTION, 1);}/* * Add event separators for PCRs 0 to 7; specs 8.2.3 */void tcpa_add_event_separators(){ uint32_t pcrIndex = 0; while (pcrIndex <= 7) { tcpa_add_measurement(pcrIndex, EV_SEPARATOR, 0); pcrIndex ++; }}/* * Add a wake event to the log */void tcpa_wake_event(){ tcpa_add_measurement_to_log(6, EV_ACTION, 10, wake_event_1, strlen(wake_event_1));}/* * add the boot device to the measurement log */void tcpa_add_bootdevice(uint32_t bootcd, uint32_t bootdrv){ char *string; if (bootcd == 0) { if (bootdrv == 0) { string = "Booting BCV device 00h (Floppy)"; } else if (bootdrv == 0x80) { string = "Booting BCV device 80h (HDD)"; } else { string = "Booting unknown device"; } } else { string = "Booting from CD ROM device"; } tcpa_add_measurement_to_log(4, 5, 0, string, strlen(string));}/* * Add measurement to the log about option rom scan * 10.4.3 : action 14 */void tcpa_start_option_rom_scan(){ tcpa_add_measurement(2, EV_ACTION, 14);}/* * Add measurement to the log about an option rom */void tcpa_option_rom(uint32_t seg){ uint32_t len = read_byte(seg, 2) << 9; uint8_t *addr = (uint8_t *)ADDR_FROM_SEG_OFF(seg,0); char append[32]; /* TCG_PCClientTaggedEventStruct and OptionROMExecuteStructure; specs 10.4.2.1 */ struct hai hai; /* HashAll Input Block; specs 12.10 */ memset(append, 0x0, sizeof(append)); append[0] = 7; /* Option ROM Execute */ append[4] = 24;/* size of OptionROMExecute Structure */ /* leave the rest to '0' */ /* 12.10 table 21 */ hai.ipblength = 0x10; hai.reserved = 0; hai.hashdataptr = (uint32_t)addr; hai.hashdatalen = len; hai.algorithmid = TPM_ALG_SHA; HashAll32(&hai, (unsigned char *)append+12, TCG_MAGIC, 0, 0); tcpa_add_measurement_to_log(2, EV_EVENT_TAG, 0, append, 32);}/* * Add a measurement to the log in support of 8.2.5.3 * Creates two log entries * * Input parameter: * bootcd : 0: MBR of hdd, 1: boot image, 2: boot catalog of El Torito * seg : segment where the IPL data are located * off : offset where the IPL data are located * count : length in bytes */void tcpa_ipl(Bit32u bootcd,Bit32u seg,Bit32u off,Bit32u count){ uint8_t *addr = (uint8_t *)ADDR_FROM_SEG_OFF(seg,off); if (bootcd == 1) { /* specs: 8.2.5.6 El Torito */ tcpa_add_measurement_to_log_simple(4, EV_IPL, addr, count); } else if (bootcd == 2) { /* Boot Catalog */ /* specs: 8.2.5.6 El Torito */ tcpa_add_measurement_to_log_simple(5, EV_IPL_PARTITION_DATA, addr, count); } else { /* specs: 8.2.5.3 */ /* equivalent to: dd if=/dev/hda ibs=1 count=440 | sha1sum */ tcpa_add_measurement_to_log_simple(4, EV_IPL, addr, 0x1b8); /* equivalent to: dd if=/dev/hda ibs=1 count=72 skip=440 | sha1sum */ tcpa_add_measurement_to_log_simple(5, EV_IPL_PARTITION_DATA, addr + 0x1b8, 0x48); }}void tcpa_measure_post(Bit32u from, Bit32u to){ struct pcpes pcpes; /* PCClientPCREventStruc */ int len = to - from; memset(&pcpes, 0x0, sizeof(pcpes)); if (len > 0) { sha1((unsigned char *)from, to-from, (unsigned char *)&pcpes.digest); pcpes.eventtype = EV_POST_CODE; pcpes.eventdatasize = 0; pcpes.pcrindex = 0; tcpa_add_pcpes_to_log(&pcpes); }}staticuint32_t SendCommand32(uint32_t idx, struct pttto *pttto, uint32_t size_ptto){ uint32_t rc = 0; struct pttti *pttti = (struct pttti *)TCG_CommandList[idx]; uint8_t _pttto[30]; if (size_ptto > 0 && size_ptto < 14) { rc = (TCG_PC_TPMERROR | ((uint32_t)TCG_INVALID_INPUT_PARA << 16)); } if (rc == 0) { if (size_ptto == 0) { pttto = (struct pttto *)_pttto; size_ptto = sizeof(_pttto); } pttti->opblength = size_ptto; } if (rc == 0) { if (pttti->opblength > size_ptto) { rc = (TCG_PC_TPMERROR | ((uint32_t)TCG_OUTPUT_BUFFER_TOO_SHORT << 16)); } } if (rc == 0) { rc = PassThroughToTPM32(pttti, pttto, TCG_MAGIC, 0x0, 0x0); } return rc;}uint32_t tcpa_initialize_tpm(uint32_t physpres){ uint32_t rc = 0; uint8_t _pttto[40]; struct pttto *pttto = (struct pttto *)_pttto; uint32_t pttto_size = sizeof(_pttto); if (rc == 0) { rc = SendCommand32(IDX_CMD_TPM_Startup_0x01, pttto, pttto_size); } if (rc == 0 && physpres != 0) { rc = SendCommand32(IDX_CMD_TSC_PhysicalPresence_0x20, pttto, pttto_size); } if (rc == 0 && physpres != 0) { rc = SendCommand32(IDX_CMD_TSC_PhysicalPresence_0x08, pttto, pttto_size); } if (rc == 0 && physpres != 0) { rc = SendCommand32(IDX_CMD_TPM_PhysicalEnable, pttto, pttto_size); } if (rc == 0 && physpres != 0) { rc = SendCommand32(IDX_CMD_TPM_PhysicalSetDeactivated_0x00, pttto, pttto_size); } if (rc == 0) { rc = SendCommand32(IDX_CMD_TSC_PhysicalPresence_0x100, pttto, pttto_size); } if (rc == 0) { rc = SendCommand32(IDX_CMD_TSC_PhysicalPresence_0x10, pttto, pttto_size); } return rc;}static uint16_t TCG_IsShutdownPreBootInterface(void){ return tcpa_acpi.flags & STATUS_FLAG_SHUTDOWN;}staticuint32_t _TCG_TPM_Extend(unsigned char *hash, uint32_t pcrindex){ uint32_t rc; uint8_t _pttti[8+34]; uint8_t _pttto[4+30]; struct pttti *pttti = (struct pttti*)&_pttti; struct pttto *pttto = (struct pttto*)&_pttto; pttti->ipblength = 8 + 34; pttti->reserved = 0; pttti->opblength = 4 + 30; pttti->reserved2 = 0; _pttti[8 + 0] = 0x0; _pttti[8 + 1] = 0xc1; *(uint32_t *)&_pttti[8 + 2] = bswap(34); *(uint32_t *)&_pttti[8 + 6] = bswap(0x14); *(uint32_t *)&_pttti[8 + 10]= bswap(pcrindex); memcpy(&_pttti[8+14], hash, 20); rc = PassThroughToTPM32(pttti, pttto, TCG_MAGIC, 0x0, 0x0); /* sanity check of result */ if (_pttto[4] != 0x00 || _pttto[5] != 0xc4) { rc = (TCG_PC_TPMERROR | ((uint32_t)TCG_FATAL_COM_ERROR << 16)); } if (rc != 0) { /* Invalidate the log since system did not process this extend properly. */ tcpa_reset_acpi_log(); memset(&tcpa_acpi, 0x0, sizeof(tcpa_acpi)); TCG_ShutdownPreBootInterface(0); } return rc;}staticuint32_t HashLogExtendEvent32(struct hleei_short *hleei_s, struct hleeo *hleeo, uint32_t magic, uint32_t ecx, uint32_t edx){ uint32_t rc = 0; uint16_t size; struct hlei hlei ; /* HashLogEventInput block */ struct hleo hleo; /* HashLogEventOutput block */ struct hleei_long *hleei_l = (struct hleei_long *)hleei_s; int sh = 0; uint32_t logdataptr; if (TCG_IsShutdownPreBootInterface() != 0) { rc = (TCG_PC_TPMERROR | ((uint32_t)TCG_INTERFACE_SHUTDOWN << 16)); } if (rc == 0) { /* short or long version? */ size = hleei_s->ipblength; if (size == 0x18) { /* short */ sh = 1; } else if (size == 0x1c) { /* long */ sh = 0; } else { /* bad input block */ rc = TCG_PC_TPMERROR | ((uint32_t)(TCG_INVALID_ACCESS_REQUEST << 16)); } } if (rc == 0) { uint32_t hashdataptr; uint32_t hashdatalen; uint32_t pcrindex; uint32_t logeventtype; uint32_t logdatalen; uint32_t eventnumber; uint8_t hash[20]; struct pcpes *pcpes; hashdataptr = hleei_s->hashdataptr; hashdatalen = hleei_s->hashdatalen; pcrindex = hleei_s->pcrindex; if (sh) { logdataptr = hleei_s->logdataptr; logdatalen = hleei_s->logdatalen; } else { logdataptr = hleei_l->logdataptr; logdatalen = hleei_l->logdatalen; } pcpes = (struct pcpes *)logdataptr; logeventtype = pcpes->eventtype; /* fill out HashLogEventInput block 'hlie' */ hlei.ipblength = 0x1c; hlei.reserved = 0; hlei.hashdataptr = hashdataptr; hlei.hashdatalen = hashdatalen; hlei.pcrindex = pcrindex; hlei.logeventtype= logeventtype; hlei.logdataptr = logdataptr; hlei.logdatalen = logdatalen; rc = HashLogEvent32(&hlei, &hleo, TCG_MAGIC, 0x0, 0x0); eventnumber = hleo.eventnumber; hleeo->opblength = 8 + 20; hleeo->reserved = 0; hleeo->eventnumber = eventnumber; memcpy(hash, (unsigned char *)logdataptr + 0x8, 20); _TCG_TPM_Extend(hash, pcrindex); } if (rc != 0) { hleeo->opblength = 4; hleeo->reserved = 0; } return rc;}staticuint32_t PassThroughToTPM32(struct pttti *pttti, struct pttto *pttto, uint32_t magic, uint32_t ecx, uint32_t edx){ uint32_t rc = 0; uint8_t *cmd32; uint32_t resbuflen = 0; if (TCG_IsShutdownPreBootInterface() != 0) { rc = (TCG_PC_TPMERROR | ((uint32_t)TCG_INTERFACE_SHUTDOWN << 16)); } if (rc == 0) { if (pttti->ipblength < 0x8 + 10) { rc = TCG_PC_TPMERROR | ((uint32_t)(TCG_INVALID_ACCESS_REQUEST << 16)); } } if (rc == 0) { if (pttti->opblength < 0x4) { rc = TCG_PC_TPMERROR | ((uint32_t)(TCG_INVALID_ACCESS_REQUEST << 16)); } } if (rc == 0) { uint8_t *resbuf32;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -