Note: DOS/TPM Testing program!

The source code need OpenWatcom v1.8 compiler with a 32bits DOS Extender(DOS/4GW and CauseWay).

Just test Int1A, AX=BB00 function now!

 

#define DEBUG 1

#include <i86.h>
#include <dos.h>
#include <stdio.h>
#include <string.h>

static struct rminfo {
  long EDI;
  long ESI;
  long EBP;
  long reserved_by_system;
  long EBX;
  long EDX;
  long ECX;
  long EAX;
  short flags;
  short ES,DS,FS,GS,IP,CS,SP,SS;
} RMI;

static unsigned initFlag = 0;
static union REGS regs;
static struct SREGS sregs;
static short selector;
static short segment;

static short selector_IPB;      //  for protect mode
static short segment_IPB;    // for Real mode
static short selector_OPB;
static short segment_OPB;

void InitInt1A(void)
{
    int interrupt_no=0x31;

    /* DPMI call 100h allocates DOS memory */
    memset(&sregs,0,sizeof(sregs));
    regs.w.ax=0x0100;
    regs.w.bx=0x0001; // request a block
    int386x( interrupt_no, &regs, &regs, &sregs);
    segment=regs.w.ax;
    selector=regs.w.dx;
    memset(&sregs,0,sizeof(sregs));
    regs.w.ax=0x0100;
    regs.w.bx=0x0001; // request a block
    int386x( interrupt_no, &regs, &regs, &sregs);
    segment_IPB = regs.w.ax;
    selector_IPB = regs.w.dx;
    memset(&sregs,0,sizeof(sregs));
    regs.w.ax=0x0100;
    regs.w.bx=0x0001; // request a block
    int386x( interrupt_no, &regs, &regs, &sregs);
    segment_OPB = regs.w.ax;
    selector_OPB = regs.w.dx;
    initFlag = 1;
}

unsigned chkCommReturn(void)
{
    if (0x86 == ((RMI.EAX >> 8) & 0xFF)) {
        printf("Not support TCG interfacen");
        return (unsigned)-1;
    } else if (0x41504354 == RMI.EBX) {
        if (0 == RMI.EAX) { // TCG_PC_OK
            return 0;
        } else if ( 1 == RMI.EAX) { // TCG_PC_TPMERROR
            #ifdef DEBUG
            printf("Status: TCG_PC_TPMERRORn");
            #endif
            return 1;
        } else if ( 2 == RMI.EAX) { // TCG_PC_LOGOVERFLOW
            #ifdef DEBUG
            printf("Status: TCG_PC_LOGOVERFLOWn");
            #endif
            return 2;
        } else if ( 3 == RMI.EAX) { // TCG_PC_UNSUPORTED
            #ifdef DEBUG
            printf("Status: TCG_PC_UNSUPORTEDn");
            #endif
            return 3;
        }
        #ifdef DEBUG
        printf("Status: Unknown");
        #endif
        return (unsigned) -1; // unknow the status
    }
    return -1; // pass to next task
}

#define CheckInitFlag()    if( 1 != initFlag) { printf("Need to call InitInt19 firstn"); return (unsigned) -1; }
void Int1Ah (unsigned char Func, unsigned short IPBSeg, unsigned int IPBOff,
                unsigned short OPBSeg, unsigned int OPBOff )
{
    int interrupt_no=0x31;
    memset(&RMI,0,sizeof(RMI));
    RMI.EAX = (0xBB) << 8 | (Func);
    RMI.ES = IPBSeg;    // set IPB
    RMI.EDI = IPBOff;
    RMI.DS = OPBSeg;    // set OPB
    RMI.ESI = OPBOff;
    #ifdef DEBUG
        printf("–> Int 1Ahn");
        printf("EAX:0x%08X, EBX:0x%08X, ECX:0x%08X, EDX:0x%08Xn", RMI.EAX, RMI.EBX, RMI.ECX, RMI.EDX);
        printf("ES:0x%04X, EDI:0x%08X, DS:0x%04X, ESI:0x%08Xn", RMI.ES, RMI.EDI, RMI.DS, RMI.ESI);
    #endif   
    /* Use DPMI call 300h to issue the TCG interrupt */
    interrupt_no = 0x31;
    regs.w.ax = 0x0300;
    regs.h.bl = 0x1a; // TCG Interrupt 1Ah
    regs.h.bh = 0;
    regs.w.cx = 0;
    sregs.es = FP_SEG(&RMI);
    regs.x.edi = FP_OFF(&RMI);
    int386x( interrupt_no, &regs, &regs, &sregs );
    #ifdef DEBUG
        printf("<– Int 1Ahn");
        printf("EAX:0x%08X, EBX:0x%08X, ECX:0x%08X, EDX:0x%08Xn", RMI.EAX, RMI.EBX, RMI.ECX, RMI.EDX);
        printf("ES:0x%04X, EDI:0x%08X, DS:0x%04X, ESI:0x%08Xn", RMI.ES, RMI.EDI, RMI.DS, RMI.ESI);
    #endif
}

unsigned TCG_StatusCheck(void)
{   
    #ifdef DEBUG
        printf("+++Entry TCG_StatusCheck()n");
    #endif
    CheckInitFlag();
    Int1Ah(0, 0, 0, 0, 0); // Func 0, IPB: 0:0, OPB: 0:0
    if (0x86 == ((RMI.EAX >> 8) & 0xFF)) {
        printf("Not support TCG interfacen");
    } else if ((0 == RMI.EAX) && (0x41504354 == RMI.EBX)) {
        return 0;
    }
    else {
        printf("Error! Can’t to get TCG Status!n");
    }
    return (unsigned)-1;
}

unsigned TCG_HashLogExtendEvent(void)
{
    unsigned ret;
    #ifdef DEBUG
        printf("+++Entry TCG_HashLogExtendEvent()n");
    #endif
    CheckInitFlag();
    Int1Ah( 1, segment_IPB, 0,segment_OPB, 0); // Func 1, IPB: 0:0, OPB: 0:0
    ret = chkCommReturn();
    if ((unsigned)-1 == ret) {
        printf("Error! Cannot to run HashLogExtendEvent()!n");
    }
    return ret;
}

unsigned TCG_PassThroughToTPM(void)
{
    unsigned ret;
    #ifdef DEBUG
        printf("+++Entry TCG_PassThroughToTPM()n");
    #endif
    CheckInitFlag();
    memset(&RMI,0,sizeof(RMI));

    Int1Ah( 2, segment_IPB, 0,segment_OPB, 0); // Func 2, IPB: xxxx:xxxx, OPB: xxxx:xxxx
    ret = chkCommReturn();
    if ((unsigned)-1 == ret) {
        printf("Error! Cannot to run TCG_PassThroughToTPM()!n");
    }
    return ret;
}

 

int main(int argc, char** argv)
{
  printf("TPM Test by KunYin");
  InitInt1A(); // need to prepare some variables
  if (0 == TCG_StatusCheck()) {
    printf("Support Int1Ah, Function BB interfacen");
  }

  printf("Exit n");

  return 0;
}

廣告

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s

%d 位部落客按了讚: