uint32_t TPM_LoadKeyContext(struct tpm_buffer *context, uint32_t *keyhandle) { uint32_t ret; uint32_t ordinal_no = htonl(TPM_ORD_LoadKeyContext); STACK_TPM_BUFFER(tpmdata); ret = TSS_buildbuff("00 c1 T l @",&tpmdata, ordinal_no, context->used, context->buffer); if ((ret & ERR_MASK) != 0) { return ret; } ret = TPM_Transmit(&tpmdata,"LoadKeyContext"); if (ret != 0) { return ret; } ret = tpm_buffer_load32(&tpmdata, TPM_DATA_OFFSET, keyhandle); if ((ret & ERR_MASK)) { return ret; } return ret; }
uint32_t TPM_DirRead(uint32_t dirIndex, unsigned char * dirValueBuffer) { uint32_t ret; uint32_t ordinal_no = htonl(TPM_ORD_DirRead); STACK_TPM_BUFFER(tpmdata) uint32_t dirIndex_no = htonl(dirIndex); ret = TSS_buildbuff("00 c1 T l l",&tpmdata, ordinal_no, dirIndex_no); if ((ret & ERR_MASK)) { return ret; } ret = TPM_Transmit(&tpmdata,"DirRead"); if (ret != 0) { return ret; } if (tpmdata.used != 30) { ret = ERR_BAD_RESP; } if (NULL != dirValueBuffer) { memcpy(dirValueBuffer, &tpmdata.buffer[TPM_DATA_OFFSET], 20); } return ret; }
uint32_t TPM_LoadAuthContext(unsigned char *authContextBlob, uint32_t authContextSize, uint32_t *authhandle) { uint32_t ret; uint32_t ordinal_no = htonl(TPM_ORD_LoadAuthContext); STACK_TPM_BUFFER(tpmdata); ret = TSS_buildbuff("00 c1 T l @",&tpmdata, ordinal_no, authContextSize, authContextBlob); if ( ( ret & ERR_MASK ) != 0) { return ret; } ret = TPM_Transmit(&tpmdata,"LoadAuthContext"); if (ret != 0) { return ret; } ret = tpm_buffer_load32(&tpmdata, TPM_DATA_OFFSET, authhandle); if ((ret & ERR_MASK)) { return ret; } return ret; }
uint32_t TPM_Extend(uint32_t pcrIndex, unsigned char * event, unsigned char * outDigest) { uint32_t ret; uint32_t ordinal_no = htonl(TPM_ORD_Extend); uint32_t pcrIndex_no = htonl(pcrIndex); STACK_TPM_BUFFER(tpmdata) ret = TSS_buildbuff("00 c1 T l l %",&tpmdata, ordinal_no, pcrIndex_no, TPM_HASH_SIZE, event); if ((ret & ERR_MASK)) { return ret; } ret = TPM_Transmit(&tpmdata,"Extend"); if (0 != ret) { return ret; } if (NULL != outDigest) { memcpy(outDigest, &tpmdata.buffer[TPM_DATA_OFFSET], TPM_HASH_SIZE); } return ret; }
uint32_t TPM_PCRReset(TPM_PCR_SELECTION * selection) { uint32_t ret; uint32_t ordinal_no = htonl(TPM_ORD_PCR_Reset); STACK_TPM_BUFFER(tpmdata) struct tpm_buffer *serPCRMap = TSS_AllocTPMBuffer(TPM_U16_SIZE + selection->sizeOfSelect + 10); uint32_t serPCRMapSize; if (NULL == serPCRMap) { return ERR_MEM_ERR; } ret = TPM_WritePCRSelection(serPCRMap, selection); if ((ret & ERR_MASK) != 0) { TSS_FreeTPMBuffer(serPCRMap); return ret; } serPCRMapSize = ret; ret = TSS_buildbuff("00 c1 T l %",&tpmdata, ordinal_no, serPCRMapSize, serPCRMap->buffer); TSS_FreeTPMBuffer(serPCRMap); if ((ret & ERR_MASK)) { return ret; } ret = TPM_Transmit(&tpmdata,"PCR Reset"); return ret; }
uint32_t TPM_GetRandom(uint32_t bytesreq, unsigned char * buffer, uint32_t * bytesret) { uint32_t ret; STACK_TPM_BUFFER( tpmdata ) uint32_t ordinal_no = htonl(TPM_ORD_GetRandom); uint32_t numbytes_no = htonl(bytesreq); TSS_buildbuff("00 c1 T l l",&tpmdata, ordinal_no, numbytes_no); ret = TPM_Transmit(&tpmdata,"GetRandom"); if (0 != ret) { return ret; } ret = tpm_buffer_load32(&tpmdata, TPM_DATA_OFFSET, bytesret); if ((ret & ERR_MASK)) { return ret; } memcpy(buffer, &tpmdata.buffer[TPM_DATA_OFFSET + TPM_U32_SIZE], *bytesret); return ret; }
uint32_t TPM_SHA1CompleteExtend(void *data, uint32_t datalen, uint32_t pcrNum, unsigned char * hash, unsigned char * pcrValue) { uint32_t ordinal_no; uint32_t pcrNum_no = htonl(pcrNum); uint32_t ret; STACK_TPM_BUFFER(tpmdata) /* move Network byte order data to varaible for hmac calcualtion */ ordinal_no = htonl(TPM_ORD_SHA1CompleteExtend); TSS_buildbuff("00 c1 T l l @", &tpmdata, ordinal_no, pcrNum_no, datalen, data); /* transmit the request buffer to the TPM device and read the reply */ ret = TPM_Transmit(&tpmdata,"SHA1CompleteExtend"); if (0 != ret) { return ret; } memcpy(hash, &tpmdata.buffer[TPM_DATA_OFFSET], TPM_HASH_SIZE); memcpy(pcrValue, &tpmdata.buffer[TPM_DATA_OFFSET + TPM_HASH_SIZE], TPM_HASH_SIZE); return ret; }
uint32_t TPM_SHA1Update(void * data, uint32_t datalen) { uint32_t ordinal_no; uint32_t ret; struct tpm_buffer *tpmdata = TSS_AllocTPMBuffer(datalen+20); /* move Network byte order data to variable for hmac calcualtion */ ordinal_no = htonl(TPM_ORD_SHA1Update); if (NULL == tpmdata) { return ERR_BAD_SIZE; } ret = TSS_buildbuff("00 c1 T l @", tpmdata, ordinal_no, datalen, data); if (ret & ERR_MASK) { goto err_exit; } /* transmit the request buffer to the TPM device and read the reply */ ret = TPM_Transmit(tpmdata,"SHA1Update"); err_exit: TSS_FreeTPMBuffer(tpmdata); return ret; }
uint32_t TPM_StirRandom(unsigned char * data, uint32_t datalen) { uint32_t ret; STACK_TPM_BUFFER(tpmdata) uint32_t ordinal_no = htonl(TPM_ORD_StirRandom); TSS_buildbuff("00 c1 T l @",&tpmdata, ordinal_no, (datalen & 0xff), data); ret = TPM_Transmit(&tpmdata,"StirRandom"); return ret; }
uint32_t TPM_PcrRead(uint32_t pcrindex, unsigned char *pcrvalue) { uint32_t ret; STACK_TPM_BUFFER(tpmdata) if (pcrvalue == NULL) return ERR_NULL_ARG; ret = TSS_buildbuff("00 c1 T 00 00 00 15 L",&tpmdata,pcrindex); if ((ret & ERR_MASK) != 0 ) return ret; ret = TPM_Transmit(&tpmdata,"PCRRead"); if (ret != 0) return ret; memcpy(pcrvalue, &tpmdata.buffer[TPM_DATA_OFFSET], TPM_HASH_SIZE); return 0; }
uint32_t TPM_OwnerClear(unsigned char *ownpass) { unsigned char clear_owner_fmt[] = "00 c2 T l l % 00 %"; uint32_t ret; unsigned char tpmdata[TPM_MAX_BUFF_SIZE]; unsigned char nonceeven[TPM_HASH_SIZE]; /* fields to be inserted into Owner Clear Request Buffer */ uint32_t command; uint32_t authhandle; unsigned char nonceodd[TPM_HASH_SIZE]; unsigned char authdata[TPM_HASH_SIZE]; /* check that parameters are valid */ if (ownpass == NULL) return ERR_NULL_ARG; command = htonl(91); /* generate odd nonce */ ret = TSS_gennonce(nonceodd); if (ret == 0) return ret; /* start OIAP Protocol */ ret = TSS_OIAPopen(&authhandle, nonceeven); if (ret != 0) return ret; ret = TSS_authhmac(authdata, ownpass, TPM_HASH_SIZE, nonceeven, nonceodd, 0, TPM_U32_SIZE, &command, 0, 0); if (ret != 0) { TSS_OIAPclose(authhandle); return ret; } ret = TSS_buildbuff(clear_owner_fmt, tpmdata, command, authhandle, TPM_HASH_SIZE, nonceodd, TPM_HASH_SIZE, authdata); if ((ret & ERR_MASK) != 0) { TSS_OIAPclose(authhandle); return ret; } ret = TPM_Transmit(tpmdata, "Owner Clear"); TSS_OIAPclose(authhandle); return ret; }
static uint32_t TPM_GetCapability_Internal(uint32_t caparea, struct tpm_buffer *scap, struct tpm_buffer *response, int allowTransport) { uint32_t ret; uint32_t rlen; uint32_t ordinal_no = htonl(TPM_ORD_GetCapability); STACK_TPM_BUFFER(tpmdata) /* request/response buffer */ uint32_t scaplen = 0; unsigned char *buffer = NULL; /* check arguments */ if (scap) { scaplen = scap->used; buffer = scap->buffer; } if (response == NULL) return ERR_NULL_ARG; ret = TSS_buildbuff("00 c1 T l L @", &tpmdata, ordinal_no, caparea, scaplen, buffer); if (ret & ERR_MASK) return ret; /* transmit the request buffer to the TPM device and read the reply */ if (allowTransport) ret = TPM_Transmit(&tpmdata, "GetCapability"); else ret = TPM_Transmit_NoTransport(&tpmdata, "GetCapability"); if (ret) return ret; ret = tpm_buffer_load32(&tpmdata, TPM_DATA_OFFSET, &rlen); if (ret & ERR_MASK) return ret; if (response) SET_TPM_BUFFER(response, &tpmdata.buffer[TPM_DATA_OFFSET + TPM_U32_SIZE], rlen); return 0; }
uint32_t TPM_SHA1Start(uint32_t *maxNumBytes) { uint32_t ordinal_no; uint32_t ret; STACK_TPM_BUFFER(tpmdata) /* move Network byte order data to varaible for hmac calcualtion */ ordinal_no = htonl(TPM_ORD_SHA1Start); TSS_buildbuff("00 c1 T l", &tpmdata, ordinal_no); /* transmit the request buffer to the TPM device and read the reply */ ret = TPM_Transmit(&tpmdata,"SHA1Start"); if (ret != 0) { return ret; } ret = tpm_buffer_load32(&tpmdata, TPM_DATA_OFFSET, maxNumBytes); return ret; }
uint32_t TPM_SetOwnerInstall(TPM_BOOL state) { uint32_t ret; uint32_t ordinal_no = htonl(TPM_ORD_SetOwnerInstall); STACK_TPM_BUFFER(tpmdata) ret = TSS_buildbuff("00 c1 T l o",&tpmdata, ordinal_no, state); if ((ret & ERR_MASK)) { return ret; } ret = TPM_Transmit(&tpmdata,"SetOwnerInstall"); if (ret == 0 && tpmdata.used != 10) { ret = ERR_BAD_RESP; } return ret; }
uint32_t TPM_SaveKeyContext(uint32_t keyhandle, struct tpm_buffer *context) { uint32_t ret; uint32_t ordinal_no = htonl(TPM_ORD_SaveKeyContext); STACK_TPM_BUFFER(tpmdata) uint32_t keyhandle_no = htonl(keyhandle); uint32_t len; ret = needKeysRoom(keyhandle, 0, 0, 0); if (ret != 0) { return ret; } ret = TSS_buildbuff("00 c1 T l l",&tpmdata, ordinal_no, keyhandle_no); if (( ret & ERR_MASK )!= 0) { return ret; } ret = TPM_Transmit(&tpmdata,"SaveKeyContext"); if (ret != 0) { return ret; } ret = tpm_buffer_load32(&tpmdata, TPM_DATA_OFFSET, &len); if ((ret & ERR_MASK)) { return ret; } if (NULL != context) { SET_TPM_BUFFER(context, &tpmdata.buffer[TPM_DATA_OFFSET+TPM_U32_SIZE], len); } return ret; }
uint32_t TPM_SaveAuthContext(uint32_t authhandle, unsigned char * authContextBlob, uint32_t * authContextSize) { uint32_t ret; uint32_t ordinal_no = htonl(TPM_ORD_SaveAuthContext); STACK_TPM_BUFFER(tpmdata) uint32_t authhandle_no = htonl(authhandle); uint32_t len; ret = TSS_buildbuff("00 c1 T l l",&tpmdata, ordinal_no, authhandle_no); if (( ret & ERR_MASK )!= 0) { return ret; } ret = TPM_Transmit(&tpmdata,"SaveAuthContext"); if (ret != 0) { return ret; } ret = tpm_buffer_load32(&tpmdata, TPM_DATA_OFFSET, &len); if ((ret & ERR_MASK)) { return ret; } if (NULL != authContextBlob) { *authContextSize = MIN(*authContextSize, len); memcpy(authContextBlob, &tpmdata.buffer[TPM_DATA_OFFSET+TPM_U32_SIZE], *authContextSize); } return ret; }
uint32_t TPM_AuthorizeMigrationKey(unsigned char *ownpass, int migtype, unsigned char *keyblob, unsigned int keyblen, unsigned char *migblob, unsigned int *migblen) { unsigned char auth_mig_fmt[] = "00 c2 T l s % l % o %"; uint32_t ret; unsigned char tpmdata[TPM_MAX_BUFF_SIZE]; unsigned char nonceodd[TPM_NONCE_SIZE]; unsigned char evennonce[TPM_NONCE_SIZE]; unsigned char pubauth[TPM_HASH_SIZE]; unsigned char c; uint32_t ordinal; uint16_t migscheme; uint32_t authhandle; int size; /* check input arguments */ if (keyblob == NULL || migblob == NULL || migblen == NULL) return ERR_NULL_ARG; if (migtype != 1 && migtype != 2) return ERR_BAD_ARG; /* generate odd nonce */ TSS_gennonce(nonceodd); /* Open OIAP Session */ ret = TSS_OIAPopen(&authhandle, evennonce); if (ret != 0) return ret; /* move Network byte order data to variables for hmac calculation */ ordinal = htonl(0x2B); migscheme = htons(migtype); c = 0; /* calculate authorization HMAC value */ ret = TSS_authhmac(pubauth, ownpass, TPM_HASH_SIZE, evennonce, nonceodd, c, TPM_U32_SIZE, &ordinal, TPM_U16_SIZE, &migscheme, keyblen, keyblob, 0, 0); if (ret != 0) { TSS_OIAPclose(authhandle); return ret; } /* build the request buffer */ ret = TSS_buildbuff(auth_mig_fmt, tpmdata, ordinal, migscheme, keyblen, keyblob, authhandle, TPM_NONCE_SIZE, nonceodd, c, TPM_HASH_SIZE, pubauth); if ((ret & ERR_MASK) != 0) { TSS_OIAPclose(authhandle); return ret; } /* transmit the request buffer to the TPM device and read the reply */ ret = TPM_Transmit(tpmdata, "AuthMigrationKey"); if (ret != 0) { TSS_OIAPclose(authhandle); return ret; } TSS_OIAPclose(authhandle); size = TSS_PubKeySize(tpmdata + TPM_DATA_OFFSET, 0); size += TPM_U16_SIZE + TPM_HASH_SIZE; ret = TSS_checkhmac1(tpmdata, ordinal, nonceodd, ownpass, TPM_HASH_SIZE, size, TPM_DATA_OFFSET, 0, 0); if (ret != 0) return ret; memcpy(migblob, tpmdata + TPM_DATA_OFFSET, size); *migblen = size; return 0; }
uint32_t TPM_ConvertMigrationBlob(unsigned int keyhandle, unsigned char *keyauth, unsigned char *rndblob, unsigned int rndblen, unsigned char *keyblob, unsigned int keyblen, unsigned char *encblob, unsigned int *encblen) { unsigned char convert_mig_fmt[] = "00 c2 T l l @ @ l % o %"; uint32_t ret; unsigned char tpmdata[TPM_MAX_BUFF_SIZE]; unsigned char nonceodd[TPM_NONCE_SIZE]; unsigned char evennonce[TPM_NONCE_SIZE]; unsigned char pubauth[TPM_HASH_SIZE]; unsigned char c; uint32_t ordinal; uint32_t authhandle; uint32_t keyhndl; uint32_t rndsize; uint32_t datsize; int size; /* check input arguments */ if (keyauth == NULL || rndblob == NULL || keyblob == NULL || encblob == NULL || encblen == NULL) return ERR_NULL_ARG; /* generate odd nonce */ TSS_gennonce(nonceodd); /* Open OIAP Session */ ret = TSS_OIAPopen(&authhandle, evennonce); if (ret != 0) return ret; /* move Network byte order data to variables for hmac calculation */ ordinal = htonl(0x2A); keyhndl = htonl(keyhandle); rndsize = htonl(rndblen); datsize = htonl(keyblen); c = 0; /* calculate authorization HMAC value */ ret = TSS_authhmac(pubauth, keyauth, TPM_HASH_SIZE, evennonce, nonceodd, c, TPM_U32_SIZE, &ordinal, TPM_U32_SIZE, &datsize, keyblen, keyblob, TPM_U32_SIZE, &rndsize, rndblen, rndblob, 0, 0); if (ret != 0) { TSS_OIAPclose(authhandle); return ret; } /* build the request buffer */ ret = TSS_buildbuff(convert_mig_fmt, tpmdata, ordinal, keyhndl, keyblen, keyblob, rndblen, rndblob, authhandle, TPM_NONCE_SIZE, nonceodd, c, TPM_HASH_SIZE, pubauth); if ((ret & ERR_MASK) != 0) { TSS_OIAPclose(authhandle); return ret; } /* transmit the request buffer to the TPM device and read the reply */ ret = TPM_Transmit(tpmdata, "ConvertMigrationBlob"); if (ret != 0) { TSS_OIAPclose(authhandle); return ret; } TSS_OIAPclose(authhandle); size = LOAD32(tpmdata, TPM_DATA_OFFSET); ret = TSS_checkhmac1(tpmdata, ordinal, nonceodd, keyauth, TPM_HASH_SIZE, TPM_U32_SIZE, TPM_DATA_OFFSET, size, TPM_DATA_OFFSET + TPM_U32_SIZE, 0, 0); if (ret != 0) return ret; memcpy(encblob, tpmdata + TPM_DATA_OFFSET + TPM_U32_SIZE, size); *encblen = size; return 0; }
uint32_t TPM_CreateMigrationBlob(unsigned int keyhandle, unsigned char *keyauth, unsigned char *migauth, int migtype, unsigned char *migblob, unsigned int migblen, unsigned char *keyblob, unsigned int keyblen, unsigned char *rndblob, unsigned int *rndblen, unsigned char *outblob, unsigned int *outblen) { unsigned char create_mig_fmt[] = "00 c3 T l l s % @ l % o % l % o %"; unsigned char create_mig_fmt_noauth[] = "00 c2 T l l s % @ l % o %"; uint32_t ret; unsigned char tpmdata[TPM_MAX_BUFF_SIZE]; unsigned char nonceodd[TPM_NONCE_SIZE]; unsigned char enonce1[TPM_NONCE_SIZE]; unsigned char enonce2[TPM_NONCE_SIZE]; unsigned char c; uint32_t ordinal; uint32_t keyhndl; uint32_t datsize; uint16_t migscheme; uint32_t authhandle1; uint32_t authhandle2; unsigned char authdata1[TPM_HASH_SIZE]; unsigned char authdata2[TPM_HASH_SIZE]; uint32_t size1; uint32_t size2; keydata k; /* check input arguments */ if (migauth == NULL || migblob == NULL || keyblob == NULL) return ERR_NULL_ARG; if (rndblob == NULL || rndblen == NULL || outblob == NULL || outblen == NULL) return ERR_NULL_ARG; if (migtype != 1 && migtype != 2) return ERR_BAD_ARG; TSS_KeyExtract(keyblob, &k); /* move data to Network byte order variables for HMAC calculation */ ordinal = htonl(0x28); keyhndl = htonl(keyhandle); migscheme = htons(migtype); datsize = htonl(k.privkeylen); /* generate odd nonce */ TSS_gennonce(nonceodd); c = 0; if (keyauth != NULL) { /* parent key password is required */ /* open TWO OIAP sessions: Parent and Migrating Key */ ret = TSS_OIAPopen(&authhandle1, enonce1); if (ret != 0) return ret; ret = TSS_OIAPopen(&authhandle2, enonce2); if (ret != 0) return ret; /* calculate Parent KEY authorization HMAC value */ ret = TSS_authhmac(authdata1, keyauth, TPM_HASH_SIZE, enonce1, nonceodd, c, TPM_U32_SIZE, &ordinal, TPM_U16_SIZE, &migscheme, migblen, migblob, TPM_U32_SIZE, &datsize, k.privkeylen, k.encprivkey, 0, 0); if (ret != 0) { TSS_OIAPclose(authhandle1); TSS_OIAPclose(authhandle2); return ret; } /* calculate Migration authorization HMAC value */ ret = TSS_authhmac(authdata2, migauth, TPM_HASH_SIZE, enonce2, nonceodd, c, TPM_U32_SIZE, &ordinal, TPM_U16_SIZE, &migscheme, migblen, migblob, TPM_U32_SIZE, &datsize, k.privkeylen, k.encprivkey, 0, 0); if (ret != 0) { TSS_OIAPclose(authhandle1); TSS_OIAPclose(authhandle2); return ret; } /* build the request buffer */ ret = TSS_buildbuff(create_mig_fmt, tpmdata, ordinal, keyhndl, migscheme, migblen, migblob, k.privkeylen, k.encprivkey, authhandle1, TPM_NONCE_SIZE, nonceodd, c, TPM_HASH_SIZE, authdata1, authhandle2, TPM_NONCE_SIZE, nonceodd, c, TPM_HASH_SIZE, authdata2); if ((ret & ERR_MASK) != 0) { TSS_OIAPclose(authhandle1); TSS_OIAPclose(authhandle2); return ret; } /* transmit buffer to the TPM device and read the reply */ ret = TPM_Transmit(tpmdata, "CreateMigrationBlob"); if (ret != 0) { TSS_OIAPclose(authhandle1); TSS_OIAPclose(authhandle2); return ret; } /* validate HMAC in response */ size1 = LOAD32(tpmdata, TPM_DATA_OFFSET); size2 = LOAD32(tpmdata, TPM_DATA_OFFSET + TPM_U32_SIZE + size1); if (size1 != 0) { ret = TSS_checkhmac2(tpmdata, ordinal, nonceodd, keyauth, TPM_HASH_SIZE, migauth, TPM_HASH_SIZE, TPM_U32_SIZE, TPM_DATA_OFFSET, size1, TPM_DATA_OFFSET + TPM_U32_SIZE, TPM_U32_SIZE, TPM_DATA_OFFSET + TPM_U32_SIZE + size1, size2, TPM_DATA_OFFSET + TPM_U32_SIZE + size1 + TPM_U32_SIZE, 0, 0); } else { ret = TSS_checkhmac2(tpmdata, ordinal, nonceodd, keyauth, TPM_HASH_SIZE, migauth, TPM_HASH_SIZE, TPM_U32_SIZE, TPM_DATA_OFFSET, TPM_U32_SIZE, TPM_DATA_OFFSET + TPM_U32_SIZE, size2, TPM_DATA_OFFSET + TPM_U32_SIZE + TPM_U32_SIZE, 0, 0); } TSS_OIAPclose(authhandle1); TSS_OIAPclose(authhandle2); if (ret != 0) return ret; } else { /* no parent key password required */ /* open OIAP session for the Migrating Key */ ret = TSS_OIAPopen(&authhandle1, enonce1); if (ret != 0) return ret; /* calculate Migration authorization HMAC value */ ret = TSS_authhmac(authdata1, migauth, TPM_HASH_SIZE, enonce1, nonceodd, c, TPM_U32_SIZE, &ordinal, TPM_U16_SIZE, &migscheme, migblen, migblob, TPM_U32_SIZE, &datsize, k.privkeylen, k.encprivkey, 0, 0); if (ret != 0) { TSS_OIAPclose(authhandle1); return ret; } /* build the request buffer */ ret = TSS_buildbuff(create_mig_fmt_noauth, tpmdata, ordinal, keyhndl, migscheme, migblen, migblob, k.privkeylen, k.encprivkey, authhandle1, TPM_NONCE_SIZE, nonceodd, c, TPM_HASH_SIZE, authdata1); if ((ret & ERR_MASK) != 0) { TSS_OIAPclose(authhandle1); return ret; } /* transmit buffer to the TPM device and read the reply */ ret = TPM_Transmit(tpmdata, "CreateMigrationBlob"); if (ret != 0) { TSS_OIAPclose(authhandle1); return ret; } /* check HMAC in response */ size1 = LOAD32(tpmdata, TPM_DATA_OFFSET); size2 = LOAD32(tpmdata, TPM_DATA_OFFSET + TPM_U32_SIZE + size1); if (size1 != 0) { ret = TSS_checkhmac1(tpmdata, ordinal, nonceodd, migauth, TPM_HASH_SIZE, TPM_U32_SIZE, TPM_DATA_OFFSET, size1, TPM_DATA_OFFSET + TPM_U32_SIZE, TPM_U32_SIZE, TPM_DATA_OFFSET + TPM_U32_SIZE + size1, size2, TPM_DATA_OFFSET + TPM_U32_SIZE + size1 + TPM_U32_SIZE, 0, 0); } else { ret = TSS_checkhmac1(tpmdata, ordinal, nonceodd, migauth, TPM_HASH_SIZE, TPM_U32_SIZE, TPM_DATA_OFFSET, TPM_U32_SIZE, TPM_DATA_OFFSET + TPM_U32_SIZE, size2, TPM_DATA_OFFSET + TPM_U32_SIZE + TPM_U32_SIZE, 0, 0); } TSS_OIAPclose(authhandle1); if (ret != 0) return ret; } memcpy(rndblob, tpmdata + TPM_DATA_OFFSET + TPM_U32_SIZE, size1); memcpy(outblob, tpmdata + TPM_DATA_OFFSET + TPM_U32_SIZE + size1 + TPM_U32_SIZE, size2); *rndblen = size1; *outblen = size2; return 0; }
uint32_t TPM_Quote(uint32_t keyhandle, unsigned char *keyauth, unsigned char *externalData, TPM_PCR_SELECTION *tps, TPM_PCR_COMPOSITE *tpc, struct tpm_buffer *signature) { uint32_t ret; STACK_TPM_BUFFER( tpmdata ) session sess; unsigned char pubauth[TPM_HASH_SIZE]; unsigned char nonceodd[TPM_NONCE_SIZE]; unsigned char c; uint32_t ordinal = htonl(TPM_ORD_Quote); uint32_t keyhndl = htonl(keyhandle); uint16_t pcrselsize; uint32_t valuesize; uint32_t sigsize; uint32_t offset; STACK_TPM_BUFFER( serPcrSel ); /* check input arguments */ if (tpc == NULL || externalData == NULL || signature == NULL) return ERR_NULL_ARG; ret = needKeysRoom(keyhandle, 0, 0, 0); if (ret != 0) { return ret; } ret = TPM_WritePCRSelection(&serPcrSel, tps); if ((ret & ERR_MASK)) return ret; if (keyauth != NULL) /* authdata required */ { /* Open OSAP Session */ ret = TSS_SessionOpen(SESSION_OSAP|SESSION_DSAP,&sess, keyauth,TPM_ET_KEYHANDLE,keyhandle); if (ret != 0) return ret; /* generate odd nonce */ TSS_gennonce(nonceodd); /* move Network byte order data to variables for hmac calculation */ c = 0; /* calculate authorization HMAC value */ ret = TSS_authhmac(pubauth,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE,TSS_Session_GetENonce(&sess),nonceodd,c, TPM_U32_SIZE,&ordinal, TPM_HASH_SIZE,externalData, serPcrSel.used,serPcrSel.buffer, 0,0); if (ret != 0) { TSS_SessionClose(&sess); return ret; } /* build the request buffer */ ret = TSS_buildbuff("00 C2 T l l % % L % o %",&tpmdata, ordinal, keyhndl, TPM_HASH_SIZE,externalData, serPcrSel.used, serPcrSel.buffer, TSS_Session_GetHandle(&sess), TPM_NONCE_SIZE,nonceodd, c, TPM_HASH_SIZE,pubauth); if ((ret & ERR_MASK) != 0) { TSS_SessionClose(&sess); return ret; } /* transmit the request buffer to the TPM device and read the reply */ ret = TPM_Transmit(&tpmdata,"Quote"); TSS_SessionClose(&sess); if (ret != 0) { return ret; } offset = TPM_DATA_OFFSET; /* calculate the size of the returned Blob */ ret = tpm_buffer_load16(&tpmdata,offset,&pcrselsize); if ((ret & ERR_MASK)) { return ret; } offset += TPM_U16_SIZE + pcrselsize; ret = tpm_buffer_load32(&tpmdata,offset,&valuesize); if ((ret & ERR_MASK)) { return ret; } offset += TPM_U32_SIZE + valuesize; ret = tpm_buffer_load32(&tpmdata,offset, &sigsize); if ((ret & ERR_MASK)) { return ret; } offset += TPM_U32_SIZE; /* check the HMAC in the response */ ret = TSS_checkhmac1(&tpmdata,ordinal,nonceodd,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE, offset-TPM_DATA_OFFSET+sigsize,TPM_DATA_OFFSET, 0,0); if (ret != 0) { return ret; } ret = TPM_ReadPCRComposite(&tpmdata, TPM_DATA_OFFSET, tpc); if ((ret & ERR_MASK)) { return ret; } /* copy the returned blob to caller */ SET_TPM_BUFFER(signature, &tpmdata.buffer[offset], sigsize); } else /* no authdata required */ { /* build the request buffer */ ret = TSS_buildbuff("00 C1 T l l % %",&tpmdata, ordinal, keyhndl, TPM_HASH_SIZE,externalData, serPcrSel.used,serPcrSel.buffer); if ((ret & ERR_MASK) != 0) return ret; /* transmit the request buffer to the TPM device and read the reply */ ret = TPM_Transmit(&tpmdata,"Quote"); if (ret != 0) return ret; /* calculate the size of the returned Blob */ offset = TPM_DATA_OFFSET; ret = tpm_buffer_load16(&tpmdata,offset, &pcrselsize); if ((ret & ERR_MASK)) { return ret; } offset += TPM_U16_SIZE + pcrselsize; ret = tpm_buffer_load32(&tpmdata,offset, &valuesize); if ((ret & ERR_MASK)) { return ret; } offset += TPM_U32_SIZE + valuesize; ret = tpm_buffer_load32(&tpmdata,offset, &sigsize); if ((ret & ERR_MASK)) { return ret; } offset += TPM_U32_SIZE; /* copy the returned PCR composite to caller */ ret = TPM_ReadPCRComposite(&tpmdata, TPM_DATA_OFFSET, tpc); if ((ret & ERR_MASK)) { return ret; } /* copy the returned blob to caller */ SET_TPM_BUFFER(signature, &tpmdata.buffer[offset], sigsize); } return 0; }
uint32_t TPM_Quote2(uint32_t keyhandle, TPM_PCR_SELECTION * selection, TPM_BOOL addVersion, unsigned char *keyauth, unsigned char *antiReplay, TPM_PCR_INFO_SHORT * pcrinfo, struct tpm_buffer *versionblob, struct tpm_buffer *signature) { uint32_t ret; uint32_t rc; STACK_TPM_BUFFER( tpmdata ) session sess; unsigned char pubauth[TPM_HASH_SIZE]; unsigned char nonceodd[TPM_NONCE_SIZE]; unsigned char c = 0; uint32_t ordinal_no = htonl(TPM_ORD_Quote2); uint16_t pcrselsize; uint32_t verinfosize; uint32_t sigsize; uint32_t storedsize; uint32_t keyhndl = htonl(keyhandle); uint16_t keytype; struct tpm_buffer * serPCRSelection; uint32_t serPCRSelectionSize; /* check input arguments */ if (pcrinfo == NULL || selection == NULL || antiReplay == NULL) return ERR_NULL_ARG; keytype = 0x0001; ret = needKeysRoom(keyhandle, 0, 0, 0); if (ret != 0) { return ret; } TSS_gennonce(antiReplay); serPCRSelection = TSS_AllocTPMBuffer(TPM_U16_SIZE + selection->sizeOfSelect); if (NULL == serPCRSelection) { return ERR_MEM_ERR; } ret = TPM_WritePCRSelection(serPCRSelection, selection); if (( ret & ERR_MASK) != 0) { TSS_FreeTPMBuffer(serPCRSelection); return ret; } serPCRSelectionSize = ret; if (keyauth != NULL) { /* Open OSAP Session */ ret = TSS_SessionOpen(SESSION_OSAP|SESSION_DSAP,&sess,keyauth,keytype,keyhandle); if (ret != 0) { TSS_FreeTPMBuffer(serPCRSelection); return ret; } /* generate odd nonce */ TSS_gennonce(nonceodd); /* move Network byte order data to variables for hmac calculation */ /* calculate authorization HMAC value */ ret = TSS_authhmac(pubauth,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE,TSS_Session_GetENonce(&sess),nonceodd,c, TPM_U32_SIZE,&ordinal_no, TPM_HASH_SIZE,antiReplay, serPCRSelectionSize, serPCRSelection->buffer, sizeof(TPM_BOOL), &addVersion, 0,0); if (ret != 0) { TSS_FreeTPMBuffer(serPCRSelection); TSS_SessionClose(&sess); return ret; } /* build the request buffer */ ret = TSS_buildbuff("00 C2 T l l % % o L % o %",&tpmdata, ordinal_no, keyhndl, TPM_HASH_SIZE,antiReplay, serPCRSelectionSize,serPCRSelection->buffer, addVersion, TSS_Session_GetHandle(&sess), TPM_NONCE_SIZE,nonceodd, c, TPM_HASH_SIZE,pubauth); TSS_FreeTPMBuffer(serPCRSelection); if ((ret & ERR_MASK) != 0) { TSS_SessionClose(&sess); return ret; } /* transmit the request buffer to the TPM device and read the reply */ ret = TPM_Transmit(&tpmdata,"Quote2 - AUTH1"); TSS_SessionClose(&sess); if (ret != 0) { return ret; } } else { /* build the request buffer */ ret = TSS_buildbuff("00 C1 T l l % % o",&tpmdata, ordinal_no, keyhndl, TPM_HASH_SIZE,antiReplay, serPCRSelectionSize,serPCRSelection->buffer, addVersion); TSS_FreeTPMBuffer(serPCRSelection); if ((ret & ERR_MASK) != 0) { TSS_SessionClose(&sess); return ret; } /* transmit the request buffer to the TPM device and read the reply */ ret = TPM_Transmit(&tpmdata,"Quote2"); TSS_SessionClose(&sess); if (ret != 0) { return ret; } } /* calculate the size of the returned Blob */ ret = tpm_buffer_load16(&tpmdata,TPM_DATA_OFFSET, &pcrselsize); if ((ret & ERR_MASK)) { return ret; } pcrselsize += TPM_U16_SIZE + 1 + TPM_HASH_SIZE; ret = tpm_buffer_load32(&tpmdata, TPM_DATA_OFFSET + pcrselsize, &verinfosize); if ((ret & ERR_MASK)) { return ret; } ret = tpm_buffer_load32(&tpmdata, TPM_DATA_OFFSET + pcrselsize + TPM_U32_SIZE + verinfosize, &sigsize); if ((ret & ERR_MASK)) { return ret; } storedsize = pcrselsize + TPM_U32_SIZE + verinfosize + TPM_U32_SIZE + sigsize; if (keyauth != NULL) { /* check the HMAC in the response */ ret = TSS_checkhmac1(&tpmdata,ordinal_no,nonceodd,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE, storedsize,TPM_DATA_OFFSET, 0,0); if (ret != 0) { return ret; } } /* copy the returned PCR composite to caller */ if (pcrselsize != (rc = TPM_ReadPCRInfoShort(&tpmdata, TPM_DATA_OFFSET, pcrinfo))) { if ((rc & ERR_MASK)) return rc; return ERR_BUFFER; } if (NULL != versionblob) { SET_TPM_BUFFER( versionblob, &tpmdata.buffer[TPM_DATA_OFFSET+pcrselsize+TPM_U32_SIZE], verinfosize); } if (NULL != signature) { SET_TPM_BUFFER(signature, &tpmdata.buffer[TPM_DATA_OFFSET+pcrselsize+TPM_U32_SIZE+verinfosize+TPM_U32_SIZE], sigsize); } return ret; }
uint32_t TPM_Seal(uint32_t keyhandle, unsigned char *pcrinfo, uint32_t pcrinfosize, unsigned char *keyauth, unsigned char *dataauth, unsigned char *data, unsigned int datalen, unsigned char *blob, unsigned int *bloblen) { unsigned char seal_fmt[] = "00 C2 T l l % @ @ l % o %"; uint32_t ret; int i; unsigned char tpmdata[TPM_MAX_BUFF_SIZE]; osapsess sess; unsigned char encauth[TPM_HASH_SIZE]; unsigned char pubauth[TPM_HASH_SIZE]; unsigned char xorwork[TPM_HASH_SIZE * 2]; unsigned char xorhash[TPM_HASH_SIZE]; unsigned char dummyauth[TPM_HASH_SIZE]; unsigned char nonceodd[TPM_NONCE_SIZE]; unsigned char c; uint32_t ordinal; uint32_t pcrsize; uint32_t datsize; uint32_t keyhndl; uint16_t keytype; unsigned char *passptr1; unsigned char *passptr2; int sealinfosize; int encdatasize; int storedsize; memset(dummyauth, 0, sizeof dummyauth); /* check input arguments */ if (data == NULL || blob == NULL) return ERR_NULL_ARG; if (pcrinfosize != 0 && pcrinfo == NULL) return ERR_NULL_ARG; if (keyhandle == 0x40000000) keytype = 0x0004; else keytype = 0x0001; if (keyauth == NULL) passptr1 = dummyauth; else passptr1 = keyauth; if (dataauth == NULL) passptr2 = dummyauth; else passptr2 = dataauth; /* Open OSAP Session */ ret = TSS_OSAPopen(&sess, passptr1, keytype, keyhandle); if (ret != 0) return ret; /* calculate encrypted authorization value */ memcpy(xorwork, sess.ssecret, TPM_HASH_SIZE); memcpy(xorwork + TPM_HASH_SIZE, sess.enonce, TPM_HASH_SIZE); TSS_sha1(xorwork, TPM_HASH_SIZE * 2, xorhash); /* generate odd nonce */ TSS_gennonce(nonceodd); /* move Network byte order data to variables for hmac calculation */ ordinal = htonl(0x17); datsize = htonl(datalen); keyhndl = htonl(keyhandle); pcrsize = htonl(pcrinfosize); c = 0; /* encrypt data authorization key */ for (i = 0; i < TPM_HASH_SIZE; ++i) encauth[i] = xorhash[i] ^ passptr2[i]; /* calculate authorization HMAC value */ if (pcrinfosize == 0) { /* no pcr info specified */ ret = TSS_authhmac(pubauth, sess.ssecret, TPM_HASH_SIZE, sess.enonce, nonceodd, c, TPM_U32_SIZE, &ordinal, TPM_HASH_SIZE, encauth, TPM_U32_SIZE, &pcrsize, TPM_U32_SIZE, &datsize, datalen, data, 0, 0); } else { /* pcr info specified */ ret = TSS_authhmac(pubauth, sess.ssecret, TPM_HASH_SIZE, sess.enonce, nonceodd, c, TPM_U32_SIZE, &ordinal, TPM_HASH_SIZE, encauth, TPM_U32_SIZE, &pcrsize, pcrinfosize, pcrinfo, TPM_U32_SIZE, &datsize, datalen, data, 0, 0); } if (ret != 0) { TSS_OSAPclose(&sess); return ret; } /* build the request buffer */ ret = TSS_buildbuff(seal_fmt, tpmdata, ordinal, keyhndl, TPM_HASH_SIZE, encauth, pcrinfosize, pcrinfo, datalen, data, sess.handle, TPM_NONCE_SIZE, nonceodd, c, TPM_HASH_SIZE, pubauth); if ((ret & ERR_MASK) != 0) { TSS_OSAPclose(&sess); return ret; } /* transmit the request buffer to the TPM device and read the reply */ ret = TPM_Transmit(tpmdata, "Seal"); if (ret != 0) { TSS_OSAPclose(&sess); return ret; } /* calculate the size of the returned Blob */ sealinfosize = LOAD32(tpmdata, TPM_DATA_OFFSET + TPM_U32_SIZE); encdatasize = LOAD32(tpmdata, TPM_DATA_OFFSET + TPM_U32_SIZE + TPM_U32_SIZE + sealinfosize); storedsize = TPM_U32_SIZE + TPM_U32_SIZE + sealinfosize + TPM_U32_SIZE + encdatasize; /* check the HMAC in the response */ ret = TSS_checkhmac1(tpmdata, ordinal, nonceodd, sess.ssecret, TPM_HASH_SIZE, storedsize, TPM_DATA_OFFSET, 0, 0); if (ret != 0) { TSS_OSAPclose(&sess); return ret; } /* copy the returned blob to caller */ memcpy(blob, tpmdata + TPM_DATA_OFFSET, storedsize); *bloblen = storedsize; TSS_OSAPclose(&sess); return 0; }
uint32_t TPM_Unseal(uint32_t keyhandle, unsigned char *keyauth, unsigned char *dataauth, unsigned char *blob, unsigned int bloblen, unsigned char *rawdata, unsigned int *datalen) { unsigned char unseal_fmt[] = "00 C3 T l l % l % o % l % o %"; unsigned char unseal_fmt_noauth[] = "00 C2 T l l % l % o %"; uint32_t ret; unsigned char tpmdata[TPM_MAX_BUFF_SIZE]; unsigned char nonceodd[TPM_NONCE_SIZE]; unsigned char enonce1[TPM_NONCE_SIZE]; unsigned char enonce2[TPM_NONCE_SIZE]; unsigned char dummyauth[TPM_NONCE_SIZE]; unsigned char *passptr2; unsigned char c; uint32_t ordinal; uint32_t keyhndl; uint32_t authhandle1; uint32_t authhandle2; unsigned char authdata1[TPM_HASH_SIZE]; unsigned char authdata2[TPM_HASH_SIZE]; memset(dummyauth, 0, sizeof dummyauth); /* check input arguments */ if (rawdata == NULL || blob == NULL) return ERR_NULL_ARG; if (dataauth == NULL) passptr2 = dummyauth; else passptr2 = dataauth; if (keyauth != NULL) { /* key password specified */ /* open TWO OIAP sessions, Key and Data */ ret = TSS_OIAPopen(&authhandle1, enonce1); if (ret != 0) return ret; ret = TSS_OIAPopen(&authhandle2, enonce2); if (ret != 0) return ret; /* data to Network byte order variables for HMAC calculation */ ordinal = htonl(0x18); keyhndl = htonl(keyhandle); /* generate odd nonce */ TSS_gennonce(nonceodd); c = 0; /* calculate KEY authorization HMAC value */ ret = TSS_authhmac(authdata1, keyauth, TPM_HASH_SIZE, enonce1, nonceodd, c, TPM_U32_SIZE, &ordinal, bloblen, blob, 0, 0); if (ret != 0) { TSS_OIAPclose(authhandle1); TSS_OIAPclose(authhandle2); return ret; } /* calculate DATA authorization HMAC value */ ret = TSS_authhmac(authdata2, passptr2, TPM_NONCE_SIZE, enonce2, nonceodd, c, TPM_U32_SIZE, &ordinal, bloblen, blob, 0, 0); if (ret != 0) { TSS_OIAPclose(authhandle1); TSS_OIAPclose(authhandle2); return ret; } /* build the request buffer */ ret = TSS_buildbuff(unseal_fmt, tpmdata, ordinal, keyhndl, bloblen, blob, authhandle1, TPM_NONCE_SIZE, nonceodd, c, TPM_HASH_SIZE, authdata1, authhandle2, TPM_NONCE_SIZE, nonceodd, c, TPM_HASH_SIZE, authdata2); if ((ret & ERR_MASK) != 0) { TSS_OIAPclose(authhandle1); TSS_OIAPclose(authhandle2); return ret; } /* transmit buffer to the TPM device and read the reply */ ret = TPM_Transmit(tpmdata, "Unseal"); if (ret != 0) { TSS_OIAPclose(authhandle1); TSS_OIAPclose(authhandle2); return ret; } *datalen = LOAD32(tpmdata, TPM_DATA_OFFSET); /* check HMAC in response */ ret = TSS_checkhmac2(tpmdata, ordinal, nonceodd, keyauth, TPM_HASH_SIZE, passptr2, TPM_HASH_SIZE, TPM_U32_SIZE, TPM_DATA_OFFSET, *datalen, TPM_DATA_OFFSET + TPM_U32_SIZE, 0, 0); TSS_OIAPclose(authhandle1); TSS_OIAPclose(authhandle2); if (ret != 0) return ret; } else { /* no key password */ /* open ONE OIAP session, for the Data */ ret = TSS_OIAPopen(&authhandle2, enonce2); if (ret != 0) return ret; /* data to Network byte order variables for HMAC calculation */ ordinal = htonl(0x18); keyhndl = htonl(keyhandle); /* generate odd nonce */ TSS_gennonce(nonceodd); c = 0; /* calculate DATA authorization HMAC value */ ret = TSS_authhmac(authdata2, passptr2, TPM_NONCE_SIZE, enonce2, nonceodd, c, TPM_U32_SIZE, &ordinal, bloblen, blob, 0, 0); if (ret != 0) { TSS_OIAPclose(authhandle2); return ret; } /* build the request buffer */ ret = TSS_buildbuff(unseal_fmt_noauth, tpmdata, ordinal, keyhndl, bloblen, blob, authhandle2, TPM_NONCE_SIZE, nonceodd, c, TPM_HASH_SIZE, authdata2); if ((ret & ERR_MASK) != 0) { TSS_OIAPclose(authhandle2); return ret; } /* transmit buffer to the TPM device and read the reply */ ret = TPM_Transmit(tpmdata, "Unseal"); if (ret != 0) { TSS_OIAPclose(authhandle2); return ret; } *datalen = LOAD32(tpmdata, TPM_DATA_OFFSET); /* check HMAC in response */ ret = TSS_checkhmac1(tpmdata, ordinal, nonceodd, passptr2, TPM_HASH_SIZE, TPM_U32_SIZE, TPM_DATA_OFFSET, *datalen, TPM_DATA_OFFSET + TPM_U32_SIZE, 0, 0); TSS_OIAPclose(authhandle2); if (ret != 0) return ret; } /* copy decrypted data back to caller */ memcpy(rawdata, tpmdata + TPM_DATA_OFFSET + TPM_U32_SIZE, *datalen); return 0; }
uint32_t TPM_TakeOwnership(unsigned char *ownpass, unsigned char *srkpass, keydata * key) { unsigned char take_owner_fmt[] = "00 c2 T l s @ @ % l % 00 %"; /* required OAEP padding P parameter */ unsigned char tpm_oaep_pad_str[] = { 'T', 'C', 'P', 'A' }; uint32_t ret; int iret; unsigned char tpmdata[TPM_MAX_BUFF_SIZE]; pubkeydata tpmpubkey; /* public endorsement key data */ uint32_t srkparamsize; /* SRK parameter buffer size */ unsigned char nonceeven[TPM_HASH_SIZE]; /* even nonce (from OIAPopen) */ RSA *pubkey; /* PubEK converted to OpenSSL format */ unsigned char padded[RSA_MODULUS_BYTE_SIZE]; keydata srk; /* key info for SRK */ unsigned char dummypass[TPM_HASH_SIZE]; /* dummy srk password */ unsigned char *spass; /* pointer to srkpass or dummy */ unsigned int i; /* data to be inserted into Take Owner Request Buffer */ /* the uint32_t and uint16_t values are stored in network byte order */ uint32_t command; /* command ordinal */ uint16_t protocol; /* protocol ID */ uint32_t oencdatasize; /* owner auth data encrypted size */ unsigned char ownerencr[RSA_MODULUS_BYTE_SIZE]; uint32_t sencdatasize; /* srk auth data encrypted size */ unsigned char srkencr[RSA_MODULUS_BYTE_SIZE]; unsigned char srk_param_buff[TPM_SRK_PARAM_BUFF_SIZE]; uint32_t authhandle; /* auth handle (from OIAPopen) */ unsigned char nonceodd[TPM_HASH_SIZE]; /* odd nonce */ unsigned char authdata[TPM_HASH_SIZE]; /* auth data */ /* check that parameters are valid */ if (ownpass == NULL) return ERR_NULL_ARG; if (srkpass == NULL) { memset(dummypass, 0, sizeof dummypass); spass = dummypass; } else spass = srkpass; /* set up command and protocol values for TakeOwnership function */ command = htonl(0x0d); protocol = htons(0x05); /* get the TPM Endorsement Public Key */ ret = TPM_ReadPubek(&tpmpubkey); if (ret) return ret; /* convert the public key to OpenSSL format */ pubkey = TSS_convpubkey(&tpmpubkey); if (pubkey == NULL) return ERR_CRYPT_ERR; memset(ownerencr, 0, sizeof ownerencr); memset(srkencr, 0, sizeof srkencr); /* Pad and then encrypt the owner data using the RSA public key */ iret = RSA_padding_add_PKCS1_OAEP(padded, RSA_MODULUS_BYTE_SIZE, ownpass, TPM_HASH_SIZE, tpm_oaep_pad_str, sizeof tpm_oaep_pad_str); if (iret == 0) return ERR_CRYPT_ERR; iret = RSA_public_encrypt(RSA_MODULUS_BYTE_SIZE, padded, ownerencr, pubkey, RSA_NO_PADDING); if (iret < 0) return ERR_CRYPT_ERR; oencdatasize = htonl(iret); /* Pad and then encrypt the SRK data using the RSA public key */ iret = RSA_padding_add_PKCS1_OAEP(padded, RSA_MODULUS_BYTE_SIZE, spass, TPM_HASH_SIZE, tpm_oaep_pad_str, sizeof tpm_oaep_pad_str); if (iret == 0) return ERR_CRYPT_ERR; iret = RSA_public_encrypt(RSA_MODULUS_BYTE_SIZE, padded, srkencr, pubkey, RSA_NO_PADDING); if (iret < 0) return ERR_CRYPT_ERR; sencdatasize = htonl(iret); RSA_free(pubkey); if (ntohl(oencdatasize) < 0) return ERR_CRYPT_ERR; if (ntohl(sencdatasize) < 0) return ERR_CRYPT_ERR; /* fill the SRK-params key structure */ /* get tpm version */ ret = TPM_GetCapability(0x00000006, NULL, 0, &(srk.version[0]), &i); if (ret != 0) return ret; srk.keyusage = 0x0011; /* Storage Key */ srk.keyflags = 0; if (srkpass != NULL) srk.authdatausage = 0x01; else srk.authdatausage = 0x00; srk.privkeylen = 0; /* private key not specified here */ srk.pub.algorithm = 0x00000001; /* RSA */ srk.pub.encscheme = 0x0003; /* RSA OAEP SHA1 MGF1 */ srk.pub.sigscheme = 0x0001; /* NONE */ srk.pub.keybitlen = RSA_MODULUS_BIT_SIZE; srk.pub.numprimes = 2; srk.pub.expsize = 0; /* defaults to 0x010001 */ srk.pub.keylength = 0; /* not used here */ srk.pub.pcrinfolen = 0; /* not used here */ /* convert to a memory buffer */ srkparamsize = TPM_BuildKey(srk_param_buff, &srk); /* generate the odd nonce */ ret = TSS_gennonce(nonceodd); if (ret == 0) return ret; /* initiate the OIAP protocol */ ret = TSS_OIAPopen(&authhandle, nonceeven); if (ret != 0) return ret; /* calculate the Authorization Data */ ret = TSS_authhmac(authdata, ownpass, TPM_HASH_SIZE, nonceeven, nonceodd, 0, TPM_U32_SIZE, &command, TPM_U16_SIZE, &protocol, TPM_U32_SIZE, &oencdatasize, ntohl(oencdatasize), ownerencr, TPM_U32_SIZE, &sencdatasize, ntohl(sencdatasize), srkencr, srkparamsize, srk_param_buff, 0, 0); if (ret != 0) { TSS_OIAPclose(authhandle); return ret; } /* insert all the calculated fields into the request buffer */ ret = TSS_buildbuff(take_owner_fmt, tpmdata, command, protocol, ntohl(oencdatasize), ownerencr, ntohl(sencdatasize), srkencr, srkparamsize, srk_param_buff, authhandle, TPM_HASH_SIZE, nonceodd, TPM_HASH_SIZE, authdata); if ((ret & ERR_MASK) != 0) { TSS_OIAPclose(authhandle); return ret; } /* transmit the request buffer to the TPM device and read the reply */ ret = TPM_Transmit(tpmdata, "Take Ownership"); TSS_OIAPclose(authhandle); if (ret != 0) return ret; /* check the response HMAC */ srkparamsize = TSS_KeySize(tpmdata + TPM_DATA_OFFSET); ret = TSS_checkhmac1(tpmdata, command, nonceodd, ownpass, TPM_HASH_SIZE, srkparamsize, TPM_DATA_OFFSET, 0, 0); if (ret != 0) return ret; /* convert the returned key to a structure */ if (key == NULL) return 0; TSS_KeyExtract(tpmdata + TPM_DATA_OFFSET, key); return 0; }
uint32_t TPM_GetCapabilitySigned(uint32_t keyhandle, unsigned char *keypass, unsigned char *antiReplay, uint32_t caparea, struct tpm_buffer * scap, struct tpm_buffer * resp, unsigned char *sig, uint32_t * siglen) { uint32_t ret; uint32_t rlen; STACK_TPM_BUFFER(tpmdata) /* request/response buffer */ uint32_t ordinal_no = htonl(TPM_ORD_GetCapabilitySigned); uint32_t keyhandle_no = htonl(keyhandle); uint32_t caparea_no = htonl(caparea); unsigned char c = 0; unsigned char authdata[TPM_HASH_SIZE]; uint32_t ssize; unsigned char *buffer = NULL; uint32_t subcaplen = 0; uint32_t subcaplen_no; /* check arguments */ if (scap) { subcaplen = scap->used; buffer = scap->buffer; } subcaplen_no = htonl(subcaplen); ret = needKeysRoom(keyhandle, 0, 0, 0); if (ret) return ret; if (resp == NULL) return ERR_NULL_ARG; if (keypass) { unsigned char nonceodd[TPM_HASH_SIZE]; session sess; ret = TSS_gennonce(nonceodd); if (ret == 0) return ERR_CRYPT_ERR; ret = TSS_SessionOpen(SESSION_OSAP | SESSION_OIAP, &sess, keypass, TPM_ET_KEYHANDLE, keyhandle); if (ret) return ret; /* move Network byte order data to variable for hmac calculation */ ret = TSS_authhmac(authdata, TSS_Session_GetAuth(&sess), TPM_HASH_SIZE, TSS_Session_GetENonce(&sess), nonceodd, c, TPM_U32_SIZE, &ordinal_no, TPM_NONCE_SIZE, antiReplay, TPM_U32_SIZE, &caparea_no, TPM_U32_SIZE, &subcaplen_no, subcaplen, buffer, 0, 0); if (ret) { TSS_SessionClose(&sess); return ret; } ret = TSS_buildbuff("00 c2 T l l % l @ L % o %", &tpmdata, ordinal_no, keyhandle_no, TPM_NONCE_SIZE, antiReplay, caparea_no, subcaplen, buffer, TSS_Session_GetHandle(&sess), TPM_NONCE_SIZE, nonceodd, c, TPM_HASH_SIZE, authdata); if (ret & ERR_MASK) { TSS_SessionClose(&sess); return ret; } /* transmit the request buffer to the TPM device and read the reply */ ret = TPM_Transmit(&tpmdata, "GetCapability - AUTH1"); TSS_SessionClose(&sess); if (ret) return ret; ret = tpm_buffer_load32(&tpmdata, TPM_DATA_OFFSET+TPM_U32_SIZE, &rlen); if (ret & ERR_MASK) return ret; ret = tpm_buffer_load32(&tpmdata, TPM_DATA_OFFSET + TPM_U32_SIZE + TPM_U32_SIZE + rlen, &ssize); if (ret & ERR_MASK) return ret; ret = TSS_checkhmac1(&tpmdata, ordinal_no, nonceodd, TSS_Session_GetAuth(&sess), TPM_HASH_SIZE, TPM_U32_SIZE + TPM_U32_SIZE + rlen + TPM_U32_SIZE + ssize, TPM_DATA_OFFSET, 0, 0); if (ret) return ret; } else { ret = TSS_buildbuff("00 c1 T l l % l @", &tpmdata, ordinal_no, keyhandle_no, TPM_NONCE_SIZE, antiReplay, caparea_no, subcaplen, buffer); if (ret & ERR_MASK) return ret; /* transmit the request buffer to the TPM device and read the reply */ ret = TPM_Transmit(&tpmdata, "GetCapability - NO AUTH"); if (ret) return ret; ret = tpm_buffer_load32(&tpmdata, TPM_DATA_OFFSET+TPM_U32_SIZE, &rlen); if (ret & ERR_MASK) return ret; ret = tpm_buffer_load32(&tpmdata, TPM_DATA_OFFSET + TPM_U32_SIZE + TPM_U32_SIZE + rlen, &ssize); if (ret & ERR_MASK) return ret; } if (resp) SET_TPM_BUFFER(resp, &tpmdata.buffer[TPM_DATA_OFFSET + TPM_U32_SIZE + TPM_U32_SIZE], rlen); if (sig) { *siglen = MIN(*siglen, ssize); memcpy(sig, &tpmdata.buffer[TPM_DATA_OFFSET + TPM_U32_SIZE + TPM_U32_SIZE + rlen + TPM_U32_SIZE], *siglen); } return ret; }
uint32_t TPM_DirWriteAuth(uint32_t dirIndex, unsigned char * newValue, unsigned char * ownerAuth) { STACK_TPM_BUFFER(tpmdata) uint32_t ordinal_no = htonl(TPM_ORD_DirWriteAuth); uint32_t ret; uint32_t dirIndex_no = htonl(dirIndex); unsigned char nonceodd[TPM_NONCE_SIZE]; unsigned char authdata[TPM_NONCE_SIZE]; session sess; int c = 0; /* check input arguments */ if (NULL == ownerAuth || NULL == newValue) { return ERR_NULL_ARG; } /* Open OSAP Session */ ret = TSS_SessionOpen(SESSION_DSAP | SESSION_OSAP | SESSION_OIAP, &sess, ownerAuth, TPM_ET_OWNER, 0); if (ret != 0) return ret; /* generate odd nonce */ ret = TSS_gennonce(nonceodd); if (0 == ret) return ERR_CRYPT_ERR; /* move Network byte order data to varaible for hmac calcualtion */ ret = TSS_authhmac(authdata,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE,TSS_Session_GetENonce(&sess),nonceodd,c, TPM_U32_SIZE,&ordinal_no, TPM_U32_SIZE,&dirIndex_no, TPM_HASH_SIZE, newValue, 0,0); if (0 != ret) { TSS_SessionClose(&sess); return ret; } /* build the request buffer */ ret = TSS_buildbuff("00 c2 T l l % L % o %", &tpmdata, ordinal_no, dirIndex_no, TPM_HASH_SIZE, newValue, TSS_Session_GetHandle(&sess), TPM_HASH_SIZE, nonceodd, c, TPM_HASH_SIZE, authdata); if ((ret & ERR_MASK)) { TSS_SessionClose(&sess); return ret; } /* transmit the request buffer to the TPM device and read the reply */ ret = TPM_Transmit(&tpmdata,"DirWriteAuth"); TSS_SessionClose(&sess); if (ret != 0) { return ret; } /* check the HMAC in the response */ ret = TSS_checkhmac1(&tpmdata,ordinal_no,nonceodd,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE, 0,0); return ret; }
uint32_t TPM_GetCapabilityOwner(unsigned char *ownpass, uint32_t * volflags, uint32_t * nvolflags) { uint32_t ret; STACK_TPM_BUFFER(tpmdata) /* data to be inserted into Request Buffer (in Network Byte Order) */ /* the uint32_t and uint16_t values are stored in network byte order so they ** are in the correct format when being hashed by the HMAC calculation */ uint32_t command; /* command ordinal */ unsigned char nonceodd[TPM_HASH_SIZE]; /* odd nonce */ unsigned char authdata[TPM_HASH_SIZE]; /* auth data */ session sess; /* check that parameters are valid */ if (ownpass == NULL || volflags == NULL || nvolflags == NULL) return ERR_NULL_ARG; /* set up command and protocol values for TakeOwnership function */ command = htonl(TPM_ORD_GetCapabilityOwner); /* generate the odd nonce */ ret = TSS_gennonce(nonceodd); if (ret == 0) return ret; /* initiate the OSAP protocol */ ret = TSS_SessionOpen(SESSION_OSAP, &sess, ownpass, TPM_OWNER_ETYPE, TPM_OWNER_EVALUE); if (ret) return ret; /* calculate the Authorization Data */ ret = TSS_authhmac(authdata, TSS_Session_GetAuth(&sess), TPM_HASH_SIZE, TSS_Session_GetENonce(&sess), nonceodd, 0, TPM_U32_SIZE, &command, 0, 0); if (ret) { TSS_SessionClose(&sess); return ret; } /* insert all the calculated fields into the request buffer */ ret = TSS_buildbuff("00 c2 T l L % 00 %", &tpmdata, command, TSS_Session_GetHandle(&sess), TPM_HASH_SIZE, nonceodd, TPM_HASH_SIZE, authdata); if (ret & ERR_MASK) { TSS_SessionClose(&sess); return ret; } /* transmit the request buffer to the TPM device and read the reply */ ret = TPM_Transmit(&tpmdata, "GetCapabilityOwner"); TSS_SessionClose(&sess); if (ret) return ret; ret = TSS_checkhmac1(&tpmdata, command, nonceodd, TSS_Session_GetAuth(&sess), TPM_HASH_SIZE, TPM_U32_SIZE, TPM_DATA_OFFSET, TPM_U32_SIZE, TPM_DATA_OFFSET + TPM_U32_SIZE, TPM_U32_SIZE, TPM_DATA_OFFSET + TPM_U32_SIZE + TPM_U32_SIZE, 0, 0); if (ret) return ret; ret = tpm_buffer_load32(&tpmdata, TPM_DATA_OFFSET + 4, nvolflags); if (ret & ERR_MASK) return ret; ret = tpm_buffer_load32(&tpmdata, TPM_DATA_OFFSET + 4 + TPM_U32_SIZE, volflags); if (ret & ERR_MASK) return ret; return 0; }
uint32_t TPM_UnBind(uint32_t keyhandle, unsigned char *keyauth, unsigned char *data, uint32_t datalen, unsigned char *blob, uint32_t * bloblen) { uint32_t ret = 0; STACK_TPM_BUFFER(tpmdata) session sess; unsigned char pubauth[TPM_HASH_SIZE]; unsigned char nonceodd[TPM_NONCE_SIZE]; unsigned char c = 0; uint32_t ordinal = htonl(TPM_ORD_UnBind); uint32_t datsize = htonl(datalen); uint32_t keyhndl = htonl(keyhandle); uint16_t keytype; uint32_t infosize; /* check input arguments */ if (data == NULL || blob == NULL) return ERR_NULL_ARG; if (keyhandle == 0x40000000) keytype = TPM_ET_SRK; else keytype = TPM_ET_KEYHANDLE; ret = needKeysRoom(keyhandle, 0, 0, 0); if (ret) return ret; if (keyauth != NULL) { /* key needs authorization */ /* Open OSAP Session */ ret = TSS_SessionOpen(SESSION_OSAP | SESSION_DSAP, &sess, keyauth, keytype, keyhandle); if (ret) return ret; /* generate odd nonce */ TSS_gennonce(nonceodd); /* move Network byte order data to variables for HMAC calculation */ /* calculate authorization HMAC value */ ret = TSS_authhmac(pubauth, TSS_Session_GetAuth(&sess), TPM_HASH_SIZE, TSS_Session_GetENonce(&sess), nonceodd, c, TPM_U32_SIZE, &ordinal, TPM_U32_SIZE, &datsize, datalen, data, 0, 0); if (ret) { TSS_SessionClose(&sess); return ret; } /* build the request buffer */ ret = TSS_buildbuff("00 C2 T l l @ L % o %", &tpmdata, ordinal, keyhndl, datalen, data, TSS_Session_GetHandle(&sess), TPM_NONCE_SIZE, nonceodd, c, TPM_HASH_SIZE, pubauth); if (ret & ERR_MASK) { TSS_SessionClose(&sess); return ret; } /* transmit the request buffer to the TPM device and read the reply */ ret = TPM_Transmit(&tpmdata, "UnBind"); TSS_SessionClose(&sess); if (ret) return ret; /* calculate the size of the returned Blob */ ret = tpm_buffer_load32(&tpmdata, TPM_DATA_OFFSET, &infosize); if (ret & ERR_MASK) return ret; /* check the HMAC in the response */ ret = TSS_checkhmac1(&tpmdata, ordinal, nonceodd, TSS_Session_GetAuth(&sess), TPM_HASH_SIZE, TPM_U32_SIZE, TPM_DATA_OFFSET, infosize, TPM_DATA_OFFSET + TPM_U32_SIZE, 0, 0); if (ret) return ret; /* copy the returned blob to caller */ memcpy(blob, &tpmdata.buffer[TPM_DATA_OFFSET + TPM_U32_SIZE], infosize); *bloblen = infosize; } else { /* key needs NO authorization */ /* move Network byte order data to variables for HMAC calculation */ /* build the request buffer */ ret = TSS_buildbuff("00 C1 T l l @", &tpmdata, ordinal, keyhndl, datalen, data); if (ret & ERR_MASK) return ret; /* transmit the request buffer to the TPM device and read the reply */ ret = TPM_Transmit(&tpmdata, "UnBind"); if (ret) return ret; /* calculate the size of the returned Blob */ ret = tpm_buffer_load32(&tpmdata, TPM_DATA_OFFSET, &infosize); if (ret & ERR_MASK) return ret; /* copy the returned blob to caller */ memcpy(blob, &tpmdata.buffer[TPM_DATA_OFFSET + TPM_U32_SIZE], infosize); *bloblen = infosize; } return ret; }