📄 tcgbios.c
字号:
cmd32 = &pttti->tpmoperandin[0]; resbuflen = pttti->opblength - 4; resbuf32 = &pttto->tpmoperandout[0]; rc = MA_Transmit(cmd32, resbuf32, resbuflen); } if (rc == 0) { pttto->opblength = resbuflen+4; pttto->reserved = 0; } if (rc != 0) { pttto->opblength = 0; pttto->reserved = 0; } return rc;}staticuint32_t TCG_ShutdownPreBootInterface(uint32_t ebx){ uint32_t rc = 0; if (TCG_IsShutdownPreBootInterface() == 0) { tcpa_acpi.flags |= STATUS_FLAG_SHUTDOWN; } else { rc = (TCG_PC_TPMERROR | ((uint32_t)TCG_INTERFACE_SHUTDOWN << 16)); } return rc;}staticuint32_t HashLogEvent32(struct hlei *hlei, struct hleo *hleo, uint32_t ebx, uint32_t ecx, uint32_t edx){ uint32_t rc = 0; uint16_t size; uint32_t logdataptr; uint32_t logdatalen; uint32_t hashdataptr; uint32_t hashdatalen; if (TCG_IsShutdownPreBootInterface() != 0) { rc = (TCG_PC_TPMERROR | ((uint32_t)TCG_INTERFACE_SHUTDOWN << 16)); } if (rc == 0) { size = hlei->ipblength; if (size != 0x1c) { rc = (TCG_PC_TPMERROR | ((uint32_t)TCG_INVALID_ACCESS_REQUEST << 16)); } } if (rc == 0) { struct pcpes *pcpes; logdataptr = hlei->logdataptr; logdatalen = hlei->logdatalen; pcpes = (struct pcpes *)logdataptr; if (pcpes->pcrindex != hlei->pcrindex) { rc = (TCG_PC_TPMERROR | ((uint32_t)TCG_INVALID_ACCESS_REQUEST << 16)); } } if (rc == 0) { struct pcpes *pcpes= (struct pcpes *)logdataptr; if (pcpes->eventtype != hlei->logeventtype) { rc = (TCG_PC_TPMERROR | ((uint32_t)TCG_INVALID_ACCESS_REQUEST << 16)); } } if (rc == 0) { uint32_t entry; hashdataptr = hlei->hashdataptr; hashdatalen = hlei->hashdatalen; if ((hashdataptr != 0) | (hashdatalen != 0)) { uint8_t hash[20]; struct hai hai; /* HashAll Input Block */ hai.ipblength = 0x10; hai.reserved = 0x0; hai.hashdataptr = hashdataptr; hai.hashdatalen = hashdatalen; hai.algorithmid = TPM_ALG_SHA; rc = HashAll32(&hai, hash, TCG_MAGIC, 0x0, 0x0); if (rc == 0) { /* hashing was done ok */ memcpy((unsigned char *)logdataptr + 8, hash, 20); } } if (rc == 0) { /* extend the log with this event */ entry = tcpa_extend_acpi_log(logdataptr); if ((uint16_t)entry == 0) { /* upper 16 bits hold error code */ rc = (entry >> 16); } } if (rc == 0) { /* updating the log was fine */ hleo->opblength = 8; hleo->reserved = 0; hleo->eventnumber = entry; } } if (rc != 0) { hleo->opblength = 2; hleo->reserved = 0; } return rc;}staticuint32_t HashAll32(struct hai *hai, unsigned char *hash, uint32_t magic, uint32_t ecx, uint32_t edx){ uint32_t rc = 0; if (TCG_IsShutdownPreBootInterface() != 0) { rc = (TCG_PC_TPMERROR | ((uint32_t)TCG_INTERFACE_SHUTDOWN << 16)); } if (rc == 0) { if (hai->ipblength != 0x10) { rc = (TCG_PC_TPMERROR | ((uint32_t)TCG_INVALID_ACCESS_REQUEST << 16)); } } if (rc == 0) { if (hai->algorithmid != TPM_ALG_SHA) { rc = (TCG_PC_TPMERROR | ((uint32_t)TCG_INVALID_ACCESS_REQUEST << 16)); } } if (rc == 0) { uint8_t *hashdataptr32; uint32_t hashdatalen32; hashdataptr32 = (uint8_t *)hai->hashdataptr; hashdatalen32 = hai->hashdatalen; sha1(hashdataptr32, hashdatalen32, hash); } return rc;}staticuint32_t TSS32(struct ti *ti, struct to *to, uint32_t ebx, uint32_t ecx, uint32_t edx){ uint32_t rc = 0; if (TCG_IsShutdownPreBootInterface() == 0) { rc = TCG_PC_UNSUPPORTED; } else { rc = (TCG_PC_TPMERROR | ((uint32_t)TCG_INTERFACE_SHUTDOWN << 16)); } if (rc != 0) { to->opblength = 4; to->reserved = 0; } return rc;}staticuint32_t CompactHashLogExtendEvent32(unsigned char *buffer, uint32_t info, uint32_t magic, uint32_t length, uint32_t pcrindex, uint32_t *edx_ptr){ uint32_t rc = 0; struct hleeo hleeo; if (TCG_IsShutdownPreBootInterface() != 0) { rc = (TCG_PC_TPMERROR | ((uint32_t)TCG_INTERFACE_SHUTDOWN << 16)); } if (buffer == 0) { rc = (TCG_PC_TPMERROR | ((uint32_t)TCG_INVALID_INPUT_PARA << 16)); } if (rc == 0) { struct hleei_short hleei; struct pcpes pcpes; uint8_t *logdataptr; uint8_t *hashdataptr; logdataptr = (uint8_t*)&pcpes; hashdataptr = buffer; hleei.ipblength = 0x18; hleei.reserved = 0x0; hleei.hashdataptr = (uint32_t)hashdataptr; hleei.hashdatalen = length; hleei.pcrindex = pcrindex; hleei.logdataptr = (uint32_t)logdataptr; hleei.logdatalen = 32; memset(&pcpes, 0x0, 32); pcpes.pcrindex = pcrindex; pcpes.eventtype = 12; /* EV_COMPACT_HASH */ pcpes.eventdatasize = 4; pcpes.event = info; rc = HashLogExtendEvent32(&hleei, &hleeo, TCG_MAGIC, 0x0, 0x0); } if (rc == 0) { *edx_ptr = hleeo.eventnumber; } return rc;}/******************************************************************* Calculation of SHA1 in SW See: RFC3174, Wikipedia's SHA1 alogrithm description ******************************************************************/typedef struct _sha1_ctx { uint32_t h[5];} sha1_ctx;static inline uint32_t rol(uint32_t val, uint16_t rol){ return (val << rol) | (val >> (32 - rol));}static const uint32_t sha_ko[4] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 };static void sha1_block(uint32_t *w, sha1_ctx *ctx){ uint32_t i; uint32_t a,b,c,d,e,f; uint32_t tmp; uint32_t idx; /* change endianess of given data */ for (i = 0; i < 16; i++) { w[i] = bswap(w[i]); } for (i = 16; i <= 79; i++) { tmp = w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]; w[i] = rol(tmp,1); } a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3]; e = ctx->h[4]; for (i = 0; i <= 79; i++) { if (i <= 19) { f = (b & c) | ((b ^ 0xffffffff) & d); idx = 0; } else if (i <= 39) { f = b ^ c ^ d; idx = 1; } else if (i <= 59) { f = (b & c) | (b & d) | (c & d); idx = 2; } else { f = b ^ c ^ d; idx = 3; } tmp = rol(a, 5) + f + e + sha_ko[idx] + w[i]; e = d; d = c; c = rol(b, 30); b = a; a = tmp; } ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d; ctx->h[4] += e;}staticvoid sha1_do(sha1_ctx *ctx, const unsigned char *data32, uint32_t length){ uint32_t offset; uint16_t num; uint32_t bits = 0; uint32_t w[80]; uint32_t tmp; /* treat data in 64-byte chunks */ for (offset = 0; length - offset >= 64; offset += 64) { memcpy(w, data32 + offset, 64); sha1_block((uint32_t *)w, ctx); bits += (64 * 8); } /* last block with less than 64 bytes */ num = length - offset; bits += (num << 3); memset(w, 0x0, 64); memcpy(w, data32 + offset, num); ((uint8_t *)w)[num] = 0x80; if (num >= 56) { /* cannot append number of bits here */ sha1_block((uint32_t *)w, ctx); memset(w, 0x0, 60); } /* write number of bits to end of block */ tmp = bswap(bits); memcpy(&w[15], &tmp, 4); sha1_block(w, ctx); /* need to switch result's endianess */ for (num = 0; num < 5; num++) ctx->h[num] = bswap(ctx->h[num]);}/* sha1 initialization constants */static const uint32_t sha_const[5] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0};staticvoid sha1(const unsigned char *data, uint32_t length, unsigned char *hash){ sha1_ctx ctx; memcpy(&ctx.h[0], sha_const, 20); sha1_do(&ctx, data, length); memcpy(hash, &ctx.h[0], 20);}uint32_t TCGInterruptHandler(pushad_regs_t *regs, uint32_t esds, uint32_t flags_ptr){ uint16_t DS = esds >> 16; uint16_t ES = esds & 0xffff; uint16_t *FLAGS = (uint16_t *)flags_ptr; switch(regs->u.r8.al) { case 0x00: if (MA_IsTPMPresent() == 0) { /* no TPM available */ regs->u.r32.eax = TCG_PC_TPMERROR | ((uint32_t)(TCG_PC_TPM_NOT_PRESENT) << 16); } else { regs->u.r32.eax = MA_InitTPM(TPM_ST_CLEAR); if (regs->u.r32.eax == 0) { regs->u.r32.ebx = TCG_MAGIC; regs->u.r8.ch = TCG_VERSION_MAJOR; regs->u.r8.cl = TCG_VERSION_MINOR; regs->u.r32.edx = 0x0; regs->u.r32.esi = (Bit32u)tcpa_get_lasa_base_ptr(); regs->u.r32.edi = (Bit32u)tcpa_get_lasa_last_ptr(); CLEAR_CF(); } } break; case 0x01: regs->u.r32.eax = HashLogExtendEvent32((struct hleei_short*) ADDR_FROM_SEG_OFF(ES, regs->u.r16.di), (struct hleeo*) ADDR_FROM_SEG_OFF(DS, regs->u.r16.si), regs->u.r32.ebx, regs->u.r32.ecx, regs->u.r32.edx); CLEAR_CF(); break; case 0x02: regs->u.r32.eax = PassThroughToTPM32((struct pttti *) ADDR_FROM_SEG_OFF(ES, regs->u.r16.di), (struct pttto *) ADDR_FROM_SEG_OFF(DS, regs->u.r16.si), regs->u.r32.ebx, regs->u.r32.ecx, regs->u.r32.edx); CLEAR_CF(); break; case 0x03: regs->u.r32.eax = TCG_ShutdownPreBootInterface(regs->u.r32.ebx); CLEAR_CF(); break; case 0x04: regs->u.r32.eax = HashLogEvent32((struct hlei*) ADDR_FROM_SEG_OFF(ES, regs->u.r16.di), (struct hleo*) ADDR_FROM_SEG_OFF(DS, regs->u.r16.si), regs->u.r32.ebx, regs->u.r32.ecx, regs->u.r32.edx); CLEAR_CF(); break; case 0x05: regs->u.r32.eax = HashAll32((struct hai*) ADDR_FROM_SEG_OFF(ES, regs->u.r16.di), (unsigned char *) ADDR_FROM_SEG_OFF(DS, regs->u.r16.si), regs->u.r32.ebx, regs->u.r32.ecx, regs->u.r32.edx); CLEAR_CF(); break; case 0x06: regs->u.r32.eax = TSS32((struct ti*)ADDR_FROM_SEG_OFF(ES, regs->u.r16.di), (struct to*)ADDR_FROM_SEG_OFF(DS, regs->u.r16.si), regs->u.r32.ebx, regs->u.r32.ecx, regs->u.r32.edx); CLEAR_CF(); break; case 0x07: regs->u.r32.eax = CompactHashLogExtendEvent32((unsigned char *) ADDR_FROM_SEG_OFF(ES, regs->u.r16.di), regs->u.r32.esi, regs->u.r32.ebx, regs->u.r32.ecx, regs->u.r32.edx, ®s->u.r32.edx); CLEAR_CF(); break; default: SET_CF(); } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -