Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
Arquivo: dir.c Projeto: Jnig/tpm-luks
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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
Arquivo: rng.c Projeto: Jnig/tpm-luks
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;
}
Exemplo n.º 7
0
Arquivo: sha.c Projeto: Jnig/tpm-luks
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;
}
Exemplo n.º 8
0
Arquivo: sha.c Projeto: Jnig/tpm-luks
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;
}
Exemplo n.º 9
0
Arquivo: rng.c Projeto: Jnig/tpm-luks
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;
}
Exemplo n.º 10
0
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;
   }
Exemplo n.º 11
0
Arquivo: owner.c Projeto: 3van/tpmtotp
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;
}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
0
Arquivo: sha.c Projeto: Jnig/tpm-luks
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;
}
Exemplo n.º 14
0
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;
}
Exemplo n.º 15
0
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;
}
Exemplo n.º 16
0
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;
}
Exemplo n.º 17
0
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;
}
Exemplo n.º 18
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;
}
Exemplo n.º 19
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;
}
Exemplo n.º 20
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;
}
Exemplo n.º 21
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;
}
Exemplo n.º 22
0
Arquivo: seal.c Projeto: 3van/tpmtotp
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;
}
Exemplo n.º 23
0
Arquivo: seal.c Projeto: 3van/tpmtotp
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;
}
Exemplo n.º 24
0
Arquivo: owner.c Projeto: 3van/tpmtotp
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;
}
Exemplo n.º 25
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;
}
Exemplo n.º 26
0
Arquivo: dir.c Projeto: Jnig/tpm-luks
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;
}
Exemplo n.º 27
0
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;
}
Exemplo n.º 28
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;
}