예제 #1
0
파일: rng.c 프로젝트: 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;
}
예제 #2
0
static uint32_t TPM_TransmitCharDev(int sock_fd, struct tpm_buffer *tb,
                                    const char *msg)
{
    uint32_t nbytes = 0;
    ssize_t nwritten = 0;
    size_t nleft = 0;
    unsigned int offset = 0;
    uint32_t ret;
    char mymsg[1024];
    
    snprintf(mymsg, sizeof(mymsg), "TPM_TransmitCharDev: To TPM [%s]",
             msg);

    ret = tpm_buffer_load32(tb, TPM_PARAMSIZE_OFFSET, &nbytes);
    if ((ret & ERR_MASK)) {
        return ret;
    }
    showBuff(tb->buffer, mymsg);

    nleft = nbytes;
    while (nleft > 0) {
	nwritten = write(sock_fd, &tb->buffer[offset], nleft);
	if (nwritten < 0) {        /* error */
	    printf("TPM_TransmitCharDev: write error %d\n", (int)nwritten);
	    return nwritten;
	}
	nleft -= nwritten;
	offset += nwritten;
    }
    return 0;
}
예제 #3
0
파일: keyswap.c 프로젝트: P1119r1m/opentpm
/*
 * Check whether a key is in the TPM. Returns the index (>=0) at which
 * slot the key is, -1 otherwise.
 */
static int IsKeyInTPM(struct tpm_buffer *capabilities, uint32_t shandle)
{
	uint32_t ctr;
	int rc = 0;
	uint32_t handle;

	if (shandle == 0x00000000 ||
	    shandle == 0x40000000 ||
	    shandle == 0x40000006 ||
	    shandle == 0xffffffff) {
		return 1;
	}

	for (ctr = 2; ctr < capabilities->used; ctr += sizeof(handle)) {
		tpm_buffer_load32(capabilities,
		                  ctr,
		                  &handle);

		if (handle == shandle) {
			rc = 1;
			break;
		}
	}
	
#if 0
	if (rc == 1) {
		printf("key %08x is in TPM\n",shandle);
	} else {
		printf("key %08x is NOT in TPM\n", shandle);
	}
#endif
	return rc;
}
예제 #4
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;
}
예제 #5
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;
}
예제 #6
0
static uint32_t
TPM_ReceiveCharDev(int sock_fd, struct tpm_buffer *tb)
{
    uint32_t rc = 0;
    uint32_t paramSize = 0;
    unsigned char *buffer = tb->buffer;

#ifndef USE_PARTIAL_READ
    /* read the whole packet */
    if (rc == 0) {
        int nread;
        nread = read(sock_fd, tb->buffer, tb->size);
        if (nread < 0) {
            rc = ERR_IO;
        } else {
            tb->used = nread;
        }
    }
#endif

#ifdef USE_PARTIAL_READ
    /* read the tag and paramSize */
    if (rc == 0) {
	rc = TPM_ReceiveBytes(sock_fd, buffer, TPM_U16_SIZE + TPM_U32_SIZE);
    }
#endif
    /* extract the paramSize */
    if (rc == 0) {
	paramSize = LOAD32(buffer, TPM_PARAMSIZE_OFFSET);
	if (paramSize > TPM_MAX_BUFF_SIZE) {
	    printf("TPM_ReceiveCharDev: paramSize %u greater than %u\n",
		   paramSize, TPM_MAX_BUFF_SIZE);
	    rc = ERR_BAD_RESP;
	}
    }
#ifdef USE_PARTIAL_READ
    /* read the rest of the packet */
    if (rc == 0) {
	rc = TPM_ReceiveBytes(sock_fd,
			      buffer + TPM_U16_SIZE + TPM_U32_SIZE,
			      paramSize - (TPM_U16_SIZE + TPM_U32_SIZE));
    }
#endif
    /* read the TPM return code from the packet */
    if (rc == 0) {
	showBuff(buffer, "TPM_ReceiveCharDev: From TPM");
	tb->used = paramSize;
	tpm_buffer_load32(tb, TPM_RETURN_OFFSET, &rc);
    }
    return rc;
}
예제 #7
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;
}
예제 #8
0
파일: sha.c 프로젝트: 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;
}
예제 #9
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;
}
예제 #10
0
파일: keyswap.c 프로젝트: P1119r1m/opentpm
static uint32_t swapOutKeys(uint32_t neededslots,
                            uint32_t key1, uint32_t key2, uint32_t key3,
                            struct tpm_buffer *capabilities)
{
	uint32_t ret = 0;
	uint32_t ctr;
	uint32_t handle;
	
#if 0
	printf("must keep keys %08x %08x %08x   room=%d\n",
	        key1,key2,key3,neededslots);
#endif
	ctr = 2;
	while (ctr < capabilities->used) {
		tpm_buffer_load32(capabilities,
		                  ctr,
		                  &handle);

		if (handle != key1 &&
		    handle != key2 &&
		    handle != key3) {
		    	ret = swapOutKey(handle);
		}


		if (ret != 0 && ret != TPM_OWNER_CONTROL) {
			break;
		}

		if (ret == 0) {
			neededslots--;
			if (0 == neededslots) {
				break;
			}
		}
		ctr += sizeof(handle);
	}

	return ret;
}
예제 #11
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;
}
예제 #12
0
파일: keyswap.c 프로젝트: P1119r1m/opentpm
/* 
 * make sure the given keys are in the TPM and there is
 * enough room for 'room' keys in the TPM
 */
static uint32_t
needKeysRoom_General(uint32_t key1, uint32_t key2, uint32_t key3,
                     uint32_t room)
{
	uint32_t ret = 0;
	uint32_t scap_no;
	STACK_TPM_BUFFER(context);
	STACK_TPM_BUFFER(scap);
	STACK_TPM_BUFFER(capabilities);
	uint32_t tpmkeyroom;
	uint32_t keysintpm;
	int intpm1, intpm2, intpm3;
	uint32_t neededslots;
	static int in_swapping = 0;
	char *tmp1;
	char *tmp2;
	char *tmp3;
	
	/* do NOT allow recursion */
	if (in_swapping) {
		return 0;
	}
	
	tmp1 = getenv("TPM_AUDITING");
	tmp2 = getenv("TPM_TRANSPORT");
	tmp3 = getenv("TPM_NO_KEY_SWAP");

	if ((tmp1 && !strcmp(tmp1,"1") && 
	     tmp2 && !strcmp(tmp2,"1")) ||
	    (tmp3 && !strcmp(tmp3,"1")) ) {
		return 0;
	}
	
	in_swapping = 1;
#if 0
	printf("level: %d\n",g_num_transports);
#endif
	/*
	 * Support for 1.1 TPMs is not possible since the key handle
	 * must be maintained and the old SaveKeyContext functions don't
	 * do that.
	 *
	 * Strategy for 1.2 TPMs:
         *  Check the number of keys the TPM can handle.
         *  Check which keys are in the TPM and how many.
         *  If there's enough room for all keys that need to be loaded in,
         *   just load them in, otherwise swap an unneeded key out first.
         *  If necessary, swap as many keys out such that there's enough
         *  room for 'room' keys.
	 */
	
	scap_no = htonl(TPM_CAP_PROP_MAX_KEYS);   // 0x110
	SET_TPM_BUFFER(&scap, &scap_no, sizeof(scap_no));
	ret = TPM_GetCapability(TPM_CAP_PROPERTY, // 0x5
	                        &scap,
	                        &capabilities);
	if (ret != 0) {
		/* call may fail at very beginning */
		in_swapping = 0;
		return 0;
	} else {
		ret = tpm_buffer_load32(&capabilities, 0, &tpmkeyroom);
		if (ret != 0) {
			in_swapping = 0;
			return ret;
		}
//tpmkeyroom = 10;
	}


	scap_no = ntohl(TPM_RT_KEY);
	SET_TPM_BUFFER(&scap, &scap_no, sizeof(scap_no));
	ret = TPM_GetCapability(TPM_CAP_KEY_HANDLE,
	                        &scap,
	                        &capabilities);
	if (ret != 0) {
		in_swapping = 0;
		printf("Error %s from TPM_GetCapability.\n",
		       TPM_GetErrMsg(ret));
		return ret;
	}

	neededslots = room;
	intpm1 = IsKeyInTPM(&capabilities, key1);
	if (!intpm1)
		neededslots++;
	intpm2 = IsKeyInTPM(&capabilities, key2);
	if (!intpm2)
		neededslots++;
	intpm3 = IsKeyInTPM(&capabilities, key3);
	if (!intpm2)
		neededslots++;

#if 0
	uint32_t ctr, handle;
	for (ctr = 2; ctr < capabilities.used; ctr += sizeof(handle)) {
		ret = tpm_buffer_load32(&capabilities,
		                        ctr,
		                        &handle);
		if (ret != 0) {
			break;
		}
		printf("available key: %08x\n",handle);
	}
#endif

	keysintpm = (capabilities.used - 2 ) / 4;

#if 0
	printf("TPM has room for %d keys, holds %d keys.\n",
	        tpmkeyroom,keysintpm);
#endif

	if ((int)neededslots > ((int)tpmkeyroom - (int)keysintpm)) {
		ret = swapOutKeys((int)neededslots - ((int)tpmkeyroom-(int)keysintpm),
		                  key1,
		                  key2,
		                  key3,
		                  &capabilities);
#if 0
	} else {
		printf("No need to swap out keys.\n");
#endif
	}

	if (ret == 0 && !intpm1) {
		ret = swapInKey(key1);
	}
	if (ret == 0 && !intpm2) {
		ret = swapInKey(key2);
	}
	if (ret == 0 && !intpm3) {
		ret = swapInKey(key3);
	}

	in_swapping = 0;

	return ret;
}
예제 #13
0
파일: pcrs.c 프로젝트: osresearch/tpmtotp
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;
}
예제 #14
0
파일: pcrs.c 프로젝트: osresearch/tpmtotp
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;
}
예제 #15
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;
}
예제 #16
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;
}
예제 #17
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;
}