static int check_tpm(void) { unsigned char keybuf[TPM_MAX_KEY_SIZE]; unsigned char pcrvalue[TPM_AUTH_SIZE]; unsigned char srkauth[TPM_AUTH_SIZE]; uint32_t ret, srk_handle; unsigned int keylen; keydata k, key; int tpmfp; /* check /dev/tpm0 */ if ((tpmfp = open("/dev/tpm0", O_RDWR)) < 0) { printf("Unable to open /dev/tpm0\n"); exit(-1); } close(tpmfp); /* try a TPM_Reset (should work even if TPM disabled) */ if((ret=TPM_Reset())){ printf("TPM_Reset failed, error %s\n", TPM_GetErrMsg(ret)); exit(-2); } /* check if TPM enabled with TPM_PcrRead */ if((ret=TPM_PcrRead(0L,pcrvalue))){ printf("TPM_PcrRead failed, error %s\n", TPM_GetErrMsg(ret)); exit(-3); } /* check if TPM already has default IBM CSS owner */ srk_handle=TPM_SRK_HANDLE; TSS_sha1((unsigned char *)SRKPASS,8,srkauth); k.keyflags = 0; k.authdatausage = 0; /* key requires no password */ k.privkeylen = 0; /* no private key specified here */ k.pub.algorithm = 0x00000099; /* BOGUS ALG */ k.keyusage = 0x0014; /* key Usage - 0x0014 = bind */ k.pub.encscheme = 0x0003; /* encryption scheme 3 RSA */ k.pub.sigscheme = 0x0001; /* signature scheme none */ k.pub.keybitlen = 2048; /* RSA modulus size 2048 bits */ k.pub.numprimes = 2; /* required */ k.pub.expsize = 0; /* RSA exponent - default 0x010001 */ k.pub.keylength = 0; /* key not specified here */ k.pub.pcrinfolen = 0; /* no PCR's used at this time */ ret=TPM_CreateWrapKey(srk_handle,srkauth, NULL,NULL, &k,&key,keybuf,&keylen); if(ret==TPM_AUTHFAIL){ printf("TPM already has unknown owner\n"), exit(-4); } if(ret==TPM_BAD_KEY_PROPS){ printf("TPM is already IBM CSS managed\n"); return(0); } if(ret==TPM_NOSRK){ printf("TPM is already owned\n"); return(1); } printf("Unexpected return code %d\n",ret); exit(-5); }
uint32_t TSS_GenPCRInfo(uint32_t pcrmap, unsigned char *pcrinfo, uint32_t *len) { struct pcrinfo { uint16_t selsize; unsigned char select[TPM_PCR_MASK_SIZE]; unsigned char relhash[TPM_HASH_SIZE]; unsigned char crthash[TPM_HASH_SIZE]; } myinfo; uint32_t i; int j; uint32_t work; unsigned char *valarray; uint32_t numregs; uint32_t ret; uint32_t valsize; SHA_CTX sha; /* check arguments */ if (pcrinfo == NULL || len == NULL) return ERR_NULL_ARG; /* build pcr selection array */ work = pcrmap; memset(myinfo.select,0,TPM_PCR_MASK_SIZE); for (i = 0; i < TPM_PCR_MASK_SIZE; ++i) { myinfo.select[i] = work & 0x000000FF; work = work >> 8; } /* calculate number of PCR registers requested */ numregs = 0; work = pcrmap; for (i = 0; i < (TPM_PCR_MASK_SIZE * 8); ++i) { if (work & 1) ++numregs; work = work >> 1; } if (numregs == 0) { *len = 0; return 0; } /* create the array of PCR values */ valarray = (unsigned char *)malloc(TPM_HASH_SIZE * numregs); /* read the PCR values into the value array */ work = pcrmap; j = 0; for (i = 0; i < (TPM_PCR_MASK_SIZE * 8); ++i, work = work >> 1) { if ((work & 1) == 0) continue; ret = TPM_PcrRead(i,&(valarray[(j*TPM_HASH_SIZE)])); if (ret) return ret; ++j; } myinfo.selsize = ntohs(TPM_PCR_MASK_SIZE); valsize = ntohl(numregs * TPM_HASH_SIZE); /* calculate composite hash */ SHA1_Init(&sha); SHA1_Update(&sha,&myinfo.selsize,TPM_U16_SIZE); SHA1_Update(&sha,&myinfo.select,TPM_PCR_MASK_SIZE); SHA1_Update(&sha,&valsize,TPM_U32_SIZE); for (i = 0;i < numregs;++i) { SHA1_Update(&sha,&(valarray[(i*TPM_HASH_SIZE)]),TPM_HASH_SIZE); } SHA1_Final(myinfo.relhash,&sha); memcpy(myinfo.crthash,myinfo.relhash,TPM_HASH_SIZE); memcpy(pcrinfo,&myinfo,sizeof (struct pcrinfo)); *len = sizeof (struct pcrinfo); return 0; }