Ejemplo n.º 1
0
Archivo: trusted.c Proyecto: 7799/linux
/*
 * Create an object specific authorisation protocol (OSAP) session
 */
static int osap(struct tpm_buf *tb, struct osapsess *s,
		const unsigned char *key, uint16_t type, uint32_t handle)
{
	unsigned char enonce[TPM_NONCE_SIZE];
	unsigned char ononce[TPM_NONCE_SIZE];
	int ret;

	ret = tpm_get_random(TPM_ANY_NUM, ononce, TPM_NONCE_SIZE);
	if (ret != TPM_NONCE_SIZE)
		return ret;

	INIT_BUF(tb);
	store16(tb, TPM_TAG_RQU_COMMAND);
	store32(tb, TPM_OSAP_SIZE);
	store32(tb, TPM_ORD_OSAP);
	store16(tb, type);
	store32(tb, handle);
	storebytes(tb, ononce, TPM_NONCE_SIZE);

	ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, MAX_BUF_SIZE);
	if (ret < 0)
		return ret;

	s->handle = LOAD32(tb->data, TPM_DATA_OFFSET);
	memcpy(s->enonce, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)]),
	       TPM_NONCE_SIZE);
	memcpy(enonce, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t) +
				  TPM_NONCE_SIZE]), TPM_NONCE_SIZE);
	return TSS_rawhmac(s->secret, key, SHA1_DIGEST_SIZE, TPM_NONCE_SIZE,
			   enonce, TPM_NONCE_SIZE, ononce, 0, 0);
}
Ejemplo n.º 2
0
uint32_t TPM_ReadStartupEffects(const unsigned char *buffer,
				TPM_STARTUP_EFFECTS * se)
{
    uint32_t offset = 0;
    *se = LOAD32(buffer, offset);
    offset += 4;
    return offset;
}
Ejemplo n.º 3
0
static uint32_t TPM_ReceiveSocket(int sock_fd, struct tpm_buffer *tb)
{
    uint32_t rc = 0;
    uint32_t paramSize = 0;
    uint32_t addsize = 0;
    unsigned char *buffer = tb->buffer;

    if (TPM_LowLevel_Use_VTPM())
	addsize = sizeof(uint32_t);

    /* read the tag and paramSize */
    if (rc == 0) {
	rc = TPM_ReceiveBytes(sock_fd, buffer,
			      addsize + TPM_U16_SIZE + TPM_U32_SIZE);
    }
    /* extract the paramSize */
    if (rc == 0) {
	paramSize = LOAD32(buffer, addsize + TPM_PARAMSIZE_OFFSET);
	if (paramSize > TPM_MAX_BUFF_SIZE) {
	    printf
		("TPM_ReceiveSocket: ERROR: paramSize %u greater than %u\n",
		 paramSize, TPM_MAX_BUFF_SIZE);
	    rc = ERR_BAD_RESP;
	}
    }
    /* read the rest of the packet */
    if (rc == 0) {
	rc = TPM_ReceiveBytes(sock_fd,
			      buffer + addsize + TPM_U16_SIZE +
			      TPM_U32_SIZE,
			      paramSize - (TPM_U16_SIZE + TPM_U32_SIZE));
    }
    /* read the TPM return code from the packet */
    if (rc == 0) {
	showBuff(buffer, "TPM_ReceiveSocket: From TPM");
	rc = LOAD32(buffer, addsize + TPM_RETURN_OFFSET);
	tb->used = addsize + paramSize;
    }
    return rc;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
uint32_t TPM_ReadCounterValue(const unsigned char *buffer,
			      TPM_COUNTER_VALUE * counter)
{
    uint32_t offset = 0;
    counter->tag = LOAD16(buffer, offset);
    offset += TPM_U16_SIZE;
    if (counter->tag != TPM_TAG_COUNTER_VALUE)
	return ERR_STRUCTURE;
    memcpy(&counter->label[0], &buffer[offset], sizeof(counter->label));
    offset += sizeof(counter->label);

    counter->counter = LOAD32(buffer, offset);
    return 0;
}
Ejemplo n.º 6
0
/*
 * Create an object independent authorisation protocol (oiap) session
 */
static int oiap(struct tpm_buf *tb, uint32_t *handle, unsigned char *nonce)
{
	int ret;

	INIT_BUF(tb);
	store16(tb, TPM_TAG_RQU_COMMAND);
	store32(tb, TPM_OIAP_SIZE);
	store32(tb, TPM_ORD_OIAP);
	ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, MAX_BUF_SIZE);
	if (ret < 0)
		return ret;

	*handle = LOAD32(tb->data, TPM_DATA_OFFSET);
	memcpy(nonce, &tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)],
	       TPM_NONCE_SIZE);
	return 0;
}
Ejemplo n.º 7
0
int main(int argc, char *argv[])
   {
   int ret = 0;
   uint32_t handle;
   int listsize;
   int offset;
   int	i;		/* argc iterator */
   TPM_setlog(0);      	/* turn off verbose output */
   
   for (i=1 ; i<argc ; i++) {
       if (!strcmp(argv[i], "-h")) {
	   printUsage();
       }
       else if (!strcmp(argv[i], "-v")) {
	   TPM_setlog(1);
       }
       else {
	   printf("\n%s is not a valid option\n", argv[i]);
	   printUsage();
       }
   }
   STACK_TPM_BUFFER(response);
   if (ret == 0) {
       ret = TPM_GetCapability(0x0000007,NULL,&response);
       if (ret != 0)
           {
               printf("Error %s from TPM_GetCapability\n",TPM_GetErrMsg(ret));
               exit(1);
           }
       listsize = LOAD16(response.buffer,0);
       offset = 2;
       for (i = 0; i < listsize; ++i)
           {
               handle = LOAD32(response.buffer,offset);
               printf("Key handle %02d %08x\n",i,handle);
               offset += 4;
           }
   }
   exit(0);
   }
Ejemplo n.º 8
0
uint32_t TPM_ReadMSAFile(const char * filename, TPM_MSA_COMPOSITE * msaList)
{
	uint32_t ret;
	unsigned char * buffer = NULL;
	uint32_t buffersize = 0;
	ret = TPM_ReadFile(filename, &buffer, &buffersize);
	if ( (ret & ERR_MASK) != 0 ) {
		return ret;
	}
	msaList->MSAlist = LOAD32(buffer, 0);
	if (msaList->MSAlist * TPM_HASH_SIZE + 4 == buffersize) {
		msaList->migAuthDigest = malloc( msaList->MSAlist * TPM_HASH_SIZE );
		if (NULL == msaList->migAuthDigest) {
			return ERR_MEM_ERR;
		}
		memcpy(msaList->migAuthDigest,
		       buffer+sizeof(uint32_t),
		       msaList->MSAlist * TPM_HASH_SIZE);
	} else {
		return ERR_BAD_FILE;
	}
	return 0;
}
Ejemplo n.º 9
0
_CODE_ACCESS off_t HOSTlseek(int dev_fd, off_t offset, int origin)
{
   off_t result;

   /*-----------------------------------------------------------------------*/
   /* CRITICAL REGION TO PROTECT ACCESSES TO parmbuf[] AND _CIOBUF_ (see    */
   /* file header comment above for more about mutexes and data coherency). */
   /*-----------------------------------------------------------------------*/
   __TI_resource_lock(__TI_LOCK_HOST_CIO);

   LOADSHORT(parmbuf,dev_fd,0);
   LOAD32(parmbuf,offset,2);
   LOADSHORT(parmbuf,origin,6);

   __TI_writemsg(_DTLSEEK,parmbuf,NULL,0);
   __TI_readmsg(parmbuf,NULL);

   result = UNLOAD32(parmbuf,0);

   __TI_data_synch_WBINV(&parmbuf, sizeof(parmbuf));
   __TI_resource_unlock(__TI_LOCK_HOST_CIO);

   return result;
}
Ejemplo n.º 10
0
/* Process 2OPI Integer instructions */
bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c)
{
	#ifdef DEBUG
	char Name[20] = "ILLEGAL_2OPI";
	#endif

	/* 0x0E ... 0x2B */
	/* 0xB0 ... 0xDF */
	switch(c->raw2)
	{
		case 0x0E: /* ADDI */
		{
			#ifdef DEBUG
			strncpy(Name, "ADDI", 19);
			#elif TRACE
			record_trace("ADDI");
			#endif

			ADDI(vm, c);
			break;
		}
		case 0x0F: /* ADDUI */
		{
			#ifdef DEBUG
			strncpy(Name, "ADDUI", 19);
			#elif TRACE
			record_trace("ADDUI");
			#endif

			ADDUI(vm, c);
			break;
		}
		case 0x10: /* SUBI */
		{
			#ifdef DEBUG
			strncpy(Name, "SUBI", 19);
			#elif TRACE
			record_trace("SUBI");
			#endif

			SUBI(vm, c);
			break;
		}
		case 0x11: /* SUBUI */
		{
			#ifdef DEBUG
			strncpy(Name, "SUBUI", 19);
			#elif TRACE
			record_trace("SUBUI");
			#endif

			SUBUI(vm, c);
			break;
		}
		case 0x12: /* CMPI */
		{
			#ifdef DEBUG
			strncpy(Name, "CMPI", 19);
			#elif TRACE
			record_trace("CMPI");
			#endif

			CMPI(vm, c);
			break;
		}
		case 0x13: /* LOAD */
		{
			#ifdef DEBUG
			strncpy(Name, "LOAD", 19);
			#elif TRACE
			record_trace("LOAD");
			#endif

			LOAD(vm, c);
			break;
		}
		case 0x14: /* LOAD8 */
		{
			#ifdef DEBUG
			strncpy(Name, "LOAD8", 19);
			#elif TRACE
			record_trace("LOAD8");
			#endif

			LOAD8(vm, c);
			break;
		}
		case 0x15: /* LOADU8 */
		{
			#ifdef DEBUG
			strncpy(Name, "LOADU8", 19);
			#elif TRACE
			record_trace("LOADU8");
			#endif

			LOADU8(vm, c);
			break;
		}
		case 0x16: /* LOAD16 */
		{
			#ifdef DEBUG
			strncpy(Name, "LOAD16", 19);
			#elif TRACE
			record_trace("LOAD16");
			#endif

			LOAD16(vm, c);
			break;
		}
		case 0x17: /* LOADU16 */
		{
			#ifdef DEBUG
			strncpy(Name, "LOADU16", 19);
			#elif TRACE
			record_trace("LOADU16");
			#endif

			LOADU16(vm, c);
			break;
		}
		case 0x18: /* LOAD32 */
		{
			#ifdef DEBUG
			strncpy(Name, "LOAD32", 19);
			#elif TRACE
			record_trace("LOAD32");
			#endif

			LOAD32(vm, c);
			break;
		}
		case 0x19: /* LOADU32 */
		{
			#ifdef DEBUG
			strncpy(Name, "LOADU32", 19);
			#elif TRACE
			record_trace("LOADU32");
			#endif

			LOADU32(vm, c);
			break;
		}
		case 0x1F: /* CMPUI */
		{
			#ifdef DEBUG
			strncpy(Name, "CMPUI", 19);
			#elif TRACE
			record_trace("CMPUI");
			#endif

			CMPUI(vm, c);
			break;
		}
		case 0x20: /* STORE */
		{
			#ifdef DEBUG
			strncpy(Name, "STORE", 19);
			#elif TRACE
			record_trace("STORE");
			#endif

			STORE(vm, c);
			break;
		}
		case 0x21: /* STORE8 */
		{
			#ifdef DEBUG
			strncpy(Name, "STORE8", 19);
			#elif TRACE
			record_trace("STORE8");
			#endif

			STORE8(vm, c);
			break;
		}
		case 0x22: /* STORE16 */
		{
			#ifdef DEBUG
			strncpy(Name, "STORE16", 19);
			#elif TRACE
			record_trace("STORE16");
			#endif

			STORE16(vm, c);
			break;
		}
		case 0x23: /* STORE32 */
		{
			#ifdef DEBUG
			strncpy(Name, "STORE32", 19);
			#elif TRACE
			record_trace("STORE32");
			#endif

			STORE32(vm, c);
			break;
		}
		case 0xB0: /* ANDI */
		{
			#ifdef DEBUG
			strncpy(Name, "ANDI", 19);
			#elif TRACE
			record_trace("ANDI");
			#endif

			ANDI(vm, c);
			break;
		}
		case 0xB1: /* ORI */
		{
			#ifdef DEBUG
			strncpy(Name, "ORI", 19);
			#elif TRACE
			record_trace("ORI");
			#endif

			ORI(vm, c);
			break;
		}
		case 0xB2: /* XORI */
		{
			#ifdef DEBUG
			strncpy(Name, "XORI", 19);
			#elif TRACE
			record_trace("XORI");
			#endif

			XORI(vm, c);
			break;
		}
		case 0xB3: /* NANDI */
		{
			#ifdef DEBUG
			strncpy(Name, "NANDI", 19);
			#elif TRACE
			record_trace("NANDI");
			#endif

			NANDI(vm, c);
			break;
		}
		case 0xB4: /* NORI */
		{
			#ifdef DEBUG
			strncpy(Name, "NORI", 19);
			#elif TRACE
			record_trace("NORI");
			#endif

			NORI(vm, c);
			break;
		}
		case 0xB5: /* XNORI */
		{
			#ifdef DEBUG
			strncpy(Name, "XNORI", 19);
			#elif TRACE
			record_trace("XNORI");
			#endif

			XNORI(vm, c);
			break;
		}
		case 0xC0: /* CMPJUMPI.G */
		{
			#ifdef DEBUG
			strncpy(Name, "CMPJUMPI.G", 19);
			#elif TRACE
			record_trace("CMPJUMPI.G");
			#endif

			CMPJUMPI_G(vm, c);
			break;
		}
		case 0xC1: /* CMPJUMPI.GE */
		{
			#ifdef DEBUG
			strncpy(Name, "CMPJUMPI.GE", 19);
			#elif TRACE
			record_trace("CMPJUMPI.GE");
			#endif

			CMPJUMPI_GE(vm, c);
			break;
		}
		case 0xC2: /* CMPJUMPI.E */
		{
			#ifdef DEBUG
			strncpy(Name, "CMPJUMPI.E", 19);
			#elif TRACE
			record_trace("CMPJUMPI.E");
			#endif

			CMPJUMPI_E(vm, c);
			break;
		}
		case 0xC3: /* CMPJUMPI.NE */
		{
			#ifdef DEBUG
			strncpy(Name, "CMPJUMPI.NE", 19);
			#elif TRACE
			record_trace("CMPJUMPI.NE");
			#endif

			CMPJUMPI_NE(vm, c);
			break;
		}
		case 0xC4: /* CMPJUMPI.LE */
		{
			#ifdef DEBUG
			strncpy(Name, "CMPJUMPI.LE", 19);
			#elif TRACE
			record_trace("CMPJUMPI.LE");
			#endif

			CMPJUMPI_LE(vm, c);
			break;
		}
		case 0xC5: /* CMPJUMPI.L */
		{
			#ifdef DEBUG
			strncpy(Name, "CMPJUMPI.L", 19);
			#elif TRACE
			record_trace("CMPJUMPI.L");
			#endif

			CMPJUMPI_L(vm, c);
			break;
		}
		case 0xD0: /* CMPJUMPUI.G */
		{
			#ifdef DEBUG
			strncpy(Name, "CMPJUMPUI.G", 19);
			#elif TRACE
			record_trace("CMPJUMPUI.G");
			#endif

			CMPJUMPUI_G(vm, c);
			break;
		}
		case 0xD1: /* CMPJUMPUI.GE */
		{
			#ifdef DEBUG
			strncpy(Name, "CMPJUMPUI.GE", 19);
			#elif TRACE
			record_trace("CMPJUMPUI.GE");
			#endif

			CMPJUMPUI_GE(vm, c);
			break;
		}
		case 0xD4: /* CMPJUMPUI.LE */
		{
			#ifdef DEBUG
			strncpy(Name, "CMPJUMPUI.LE", 19);
			#elif TRACE
			record_trace("CMPJUMPUI.LE");
			#endif

			CMPJUMPUI_LE(vm, c);
			break;
		}
		case 0xD5: /* CMPJUMPUI.L */
		{
			#ifdef DEBUG
			strncpy(Name, "CMPJUMPUI.L", 19);
			#elif TRACE
			record_trace("CMPJUMPUI.L");
			#endif

			CMPJUMPUI_L(vm, c);
			break;
		}
		default:
		{
			illegal_instruction(vm, c);
			break;
		}
	}
	#ifdef DEBUG
	fprintf(stdout, "# %s reg%u reg%u %i\n", Name, c->reg0, c->reg1, c->raw_Immediate);
	#endif
	return false;
}
Ejemplo n.º 11
0
/*
 * Sign a blob provided by userspace (that has had the hash function applied)
 * using a specific key handle.  The handle is assumed to have been previously
 * loaded by e.g. LoadKey2.
 *
 * Note that the key signature scheme of the used key should be set to
 * TPM_SS_RSASSAPKCS1v15_DER.  This allows the hashed input to be of any size
 * up to key_length_in_bytes - 11 and not be limited to size 20 like the
 * TPM_SS_RSASSAPKCS1v15_SHA1 signature scheme.
 */
static int tpm_sign(struct tpm_buf *tb,
		    uint32_t keyhandle, unsigned char *keyauth,
		    const unsigned char *blob, uint32_t bloblen,
		    void *out, uint32_t outlen)
{
	unsigned char nonceodd[TPM_NONCE_SIZE];
	unsigned char enonce[TPM_NONCE_SIZE];
	unsigned char authdata[SHA1_DIGEST_SIZE];
	uint32_t authhandle = 0;
	unsigned char cont = 0;
	uint32_t ordinal;
	uint32_t datalen;
	int ret;

	ordinal = htonl(TPM_ORD_SIGN);
	datalen = htonl(bloblen);

	/* session for loading the key */
	ret = oiap(tb, &authhandle, enonce);
	if (ret < 0) {
		pr_info("oiap failed (%d)\n", ret);
		return ret;
	}

	/* generate odd nonce */
	ret = tpm_get_random(NULL, nonceodd, TPM_NONCE_SIZE);
	if (ret < 0) {
		pr_info("tpm_get_random failed (%d)\n", ret);
		return ret;
	}

	/* calculate authorization HMAC value */
	ret = TSS_authhmac(authdata, keyauth, SHA1_DIGEST_SIZE, enonce,
			   nonceodd, cont, sizeof(uint32_t), &ordinal,
			   sizeof(uint32_t), &datalen,
			   bloblen, blob, 0, 0);
	if (ret < 0)
		return ret;

	/* build the request buffer */
	INIT_BUF(tb);
	store16(tb, TPM_TAG_RQU_AUTH1_COMMAND);
	store32(tb, TPM_SIGN_SIZE + bloblen);
	store32(tb, TPM_ORD_SIGN);
	store32(tb, keyhandle);
	store32(tb, bloblen);
	storebytes(tb, blob, bloblen);
	store32(tb, authhandle);
	storebytes(tb, nonceodd, TPM_NONCE_SIZE);
	store8(tb, cont);
	storebytes(tb, authdata, SHA1_DIGEST_SIZE);

	ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
	if (ret < 0) {
		pr_info("authhmac failed (%d)\n", ret);
		return ret;
	}

	datalen = LOAD32(tb->data, TPM_DATA_OFFSET);

	ret = TSS_checkhmac1(tb->data, ordinal, nonceodd,
			     keyauth, SHA1_DIGEST_SIZE,
			     sizeof(uint32_t), TPM_DATA_OFFSET,
			     datalen, TPM_DATA_OFFSET + sizeof(uint32_t),
			     0, 0);
	if (ret < 0) {
		pr_info("TSS_checkhmac1 failed (%d)\n", ret);
		return ret;
	}

	memcpy(out, tb->data + TPM_DATA_OFFSET + sizeof(uint32_t),
	       min(datalen, outlen));

	return datalen;
}
Ejemplo n.º 12
0
int main(int argc, char *argv[])
{
    uint32_t ret;
    STACK_TPM_BUFFER(resp);
    int index = 0;
    STACK_TPM_BUFFER( subcap );;
	
    TPM_setlog(0);		/* turn off verbose output */

    ParseArgs(argc, argv);

    while ((int)matrx[index].cap != -1) {
	if (cap == matrx[index].cap) {
	    break;
	}
	index++;
    }
    if (-1 == (int)matrx[index].cap) {
	printf("Unknown or unsupported capability!\n");
	exit(-1);
    }
	
    subcap.used = 0;
    if (matrx[index].subcap_size > 0) {
	if ((int)scap == -1) {
	    printf("Need subcap parameter for this capability!\n");
	    exit(-1);
	}
	if (0 == prepare_subcap(cap, &subcap, scap)) {
	    if (2 == matrx[index].subcap_size) {
		STORE16(subcap.buffer,0,scap);
		subcap.used = 2;
	    } else
		if (matrx[index].subcap_size >= 4) {
		    STORE32(subcap.buffer,0,scap);
		    subcap.used  = 4;
		}
	}
    }
	
#if 0
    /* This was for VTPM extensions and needs retest */
    if (cap == TPM_CAP_MFR) {
	int idx2 = 0;
	while ((int)mfr_matrix[idx2].cap != -1) {
	    if (mfr_matrix[idx2].cap == scap) {
		break;
	    }
	    idx2++;
	}
	if (mfr_matrix[idx2].subcap_size > 0) {
	    uint32_t used = subcap.used +
			    mfr_matrix[idx2].subcap_size;
	    while (subcap.used < used) {
		if (argc <= nxtarg) {
		    printf("Need one more parameter for this "
			   "capability!\n");
		    exit(-1);
		}
		if (!strncmp("0x",argv[nxtarg],2)) {
		    sscanf(argv[nxtarg],"%x",&sscap);
		} else {
		    sscanf(argv[nxtarg],"%d",&sscap);
		}
		nxtarg++;
		if (2 == matrx[index].subcap_size) {
		    STORE16(subcap.buffer,
			    subcap.used,sscap);
		    subcap.used += 2;
		} else
		    if (matrx[index].subcap_size >= 4) {
			STORE32(subcap.buffer,
				subcap.used,sscap);
			subcap.used += 4;
		    }
	    }
	}
    }


#endif
    if (0 == sikeyhandle) {
	ret = TPM_GetCapability(cap,
				&subcap,
				&resp);

	if (0 != ret) {
	    printf("TPM_GetCapability returned %s.\n",
		   TPM_GetErrMsg(ret));
	    exit(ret);
	}
    } else {
	unsigned char antiReplay[TPM_HASH_SIZE];
	unsigned char signature[2048];
	uint32_t signaturelen = sizeof(signature);
	pubkeydata pubkey;
	RSA * rsa;
	unsigned char sighash[TPM_HASH_SIZE];
	unsigned char * buffer = NULL;
	unsigned char * sigkeyhashptr = NULL;
	unsigned char sigkeypasshash[TPM_HASH_SIZE];

	if (NULL != sikeypass) {
	    TSS_sha1(sikeypass,strlen(sikeypass),sigkeypasshash);
	    sigkeyhashptr = sigkeypasshash;
	}

	TSS_gennonce(antiReplay);
		
	ret = TPM_GetPubKey(sikeyhandle,
			    sigkeyhashptr,
			    &pubkey);

	if (0 != ret) {
	    printf("Error while trying to access the signing key's public key.\n");
	    exit(-1);
	}
		
	rsa = TSS_convpubkey(&pubkey);
		
	ret = TPM_GetCapabilitySigned(sikeyhandle,
				      sigkeyhashptr,
				      antiReplay,
				      cap,
				      &subcap,
				      &resp,
				      signature, &signaturelen);

	if (0 != ret) {
	    printf("TPM_GetCapabilitySigned returned %s.\n",
		   TPM_GetErrMsg(ret));
	    exit(ret);
	}

	buffer = malloc(resp.used+TPM_NONCE_SIZE);
	if (NULL == buffer) {
	    printf("Could not allocate buffer.\n");
	    exit(-1);
	}
	memcpy(&buffer[0], resp.buffer, resp.used);
	memcpy(&buffer[resp.used], antiReplay, TPM_NONCE_SIZE);

	TSS_sha1(buffer,
		 resp.used+TPM_NONCE_SIZE,
		 sighash);
	free(buffer);

	ret = RSA_verify(NID_sha1,
			 sighash,TPM_HASH_SIZE,
			 signature,signaturelen,
			 rsa);
	if (1 != ret) {
	    printf("Error: Signature verification failed.\n");
	    exit(-1);
	}
    }

    if (0 == resp.used) {
	printf("Empty response.\n");
    } else {

	if (-1 == (int)scap) {
	    printf("Result for capability 0x%x is : ",cap);
	} else {
	    printf("Result for capability 0x%x, subcapability 0x%x is : ",cap,scap);
	}
	if (TYPE_BOOL == matrx[index].result_size) {
	    if (resp.buffer[0] == 0) {
		printf("FALSE\n");
	    } else {
		printf("TRUE\n");
	    }
	} else
	    if (TYPE_UINT32 == matrx[index].result_size) {
		uint32_t rsp;
		rsp = LOAD32(resp.buffer,0);
		printf("0x%08X  = %d\n",rsp,rsp);
	    } else
		if (TYPE_UINT32_ARRAY == matrx[index].result_size) {
		    int i = 0;
		    printf("\n");
		    while (i+3 < (int)resp.used) {
			uint32_t rsp = LOAD32(resp.buffer,i);
			i+=4;
			if (TPM_CAP_NV_LIST == cap) {
			    /* don't zero extend, grep needs the exact value for test suite */
			    printf("%d. Index : %d = 0x%x.\n",
				   i/4,
				   rsp,
				   rsp);
			} else
			    if (TPM_CAP_KEY_HANDLE == cap) {
				printf("%d. keyhandle : %d.\n",
				       i/4,
				       rsp);
				} else {
				    printf("%d. item : %d.\n",
					   i/4,
					   rsp);
				}
		    }
		} else
		    if (TYPE_STRUCTURE == matrx[index].result_size) {
			switch(cap) {
			  case TPM_CAP_FLAG:
			      {
				  if (scap == TPM_CAP_FLAG_PERMANENT) {
				      TPM_PERMANENT_FLAGS pf;
				      STACK_TPM_BUFFER(tb)
					  TSS_SetTPMBuffer(&tb, resp.buffer, resp.used);
				      ret = TPM_ReadPermanentFlags(&tb, 0, &pf, resp.used);
				      if ( ( ret & ERR_MASK ) != 0 || ret > resp.used) {
					  printf("ret=%x, responselen=%d\n",ret,resp.used);
					  printf("Error parsing response!\n");
					  exit(-1);
				      }
						
				      printf("\n");
				      showPermanentFlags(&pf, resp.used);
				  } else 
				      if (scap == TPM_CAP_FLAG_VOLATILE) {
					  TPM_STCLEAR_FLAGS sf;
					  STACK_TPM_BUFFER(tb);
					  TSS_SetTPMBuffer(&tb, resp.buffer, resp.used);
					  ret = TPM_ReadSTClearFlags(&tb, 0, &sf);
					  if ( ( ret & ERR_MASK ) != 0 || ret > resp.used) {
					      printf("ret=%x, responselen=%d\n",ret,resp.used);
					      printf("Error parsing response!\n");
					      exit(-1);
					  }
						
					  printf("\n");
					  showVolatileFlags(&sf);
						
				      }
			      }
			      break;
				
			  case TPM_CAP_KEY_HANDLE:
			      {
				  uint16_t num = LOAD16(resp.buffer, 0);
				  uint32_t i = 0;
				  uint32_t handle;
				  printf("\n");
				  while (i < num) {
				      handle = LOAD32(resp.buffer,2+i*4);
				      printf("%d. handle: 0x%08X\n",
					     i,
					     handle);
				      i++;
				  }
			      }
			      break;
			  case TPM_CAP_NV_INDEX:
			      {
				  //char scratch_info[256];
				  unsigned char scratch_info[256];
				  uint32_t scratch_info_len;
				  TPM_NV_DATA_PUBLIC ndp;
				  uint32_t i, c;
				  STACK_TPM_BUFFER(tb)
				      TSS_SetTPMBuffer(&tb, resp.buffer, resp.used);
				  ret = TPM_ReadNVDataPublic(&tb,
							     0,
							     &ndp);
				  if ( ( ret & ERR_MASK) != 0) {
				      printf("Could not deserialize the TPM_NV_DATA_PUBLIC structure.\n");
				      exit(-1);
				  }
				  printf("permission.attributes : %08X\n",(unsigned int)ndp.permission.attributes);
				  printf("ReadSTClear           : %02X\n",ndp.bReadSTClear);
				  printf("WriteSTClear          : %02X\n",ndp.bWriteSTClear);
				  printf("WriteDefine           : %02X\n",ndp.bWriteDefine);
				  printf("dataSize              : %08X = %d",(unsigned int)ndp.dataSize,
					 (unsigned int)ndp.dataSize);

				  c = 0;
				  for (i = 0; i < ndp.pcrInfoRead.pcrSelection.sizeOfSelect*8; i++) {
				      if (ndp.pcrInfoRead.pcrSelection.pcrSelect[(i / 8)] & (1 << (i & 0x7))) {
					      if (!c)
						  printf("\nRead PCRs selected: ");
					      else
						  printf(", ");
					      printf("%d", i);
					      c++;

				      }
				  }

				  if (c) {
				      char pcrmap[4], *pf;

				      memcpy(pcrmap, ndp.pcrInfoRead.pcrSelection.pcrSelect,
					     ndp.pcrInfoRead.pcrSelection.sizeOfSelect);

				 //     printf("\npcrmap: %02x%02x%02x%02x\n", pcrmap[0], pcrmap[1],
				//	     pcrmap[2], pcrmap[3]);

				      ret = TSS_GenPCRInfo(*(uint32_t *)pcrmap,
							   scratch_info,
							   &scratch_info_len);

				      printf("\nRead PCR Composite: ");
				      for (i = 0; i < 20; i++)
					  printf("%02x", ndp.pcrInfoRead.digestAtRelease[i] & 0xff);
				      printf("\n");
#if 1
				      pf = &scratch_info[5];
				      printf("\nCurrent PCR composite: ");
				      for (i = 0; i < 20; i++)
					  //printf("%02x", scratch_info.digestAtRelease[i] & 0xff);
					  printf("%02x", pf[i] & 0xff);
				      printf("\n");
#endif
				      if (!ret) {
					      printf("Matches current TPM state: ");

					      if (!memcmp(&scratch_info[5],
							  &ndp.pcrInfoRead.digestAtRelease,
							  20)) {
						      printf("Yes\n");
					      } else {
						      printf("No\n");
					      }
				      }
				  }


				  c = 0;
				  for (i = 0; i < ndp.pcrInfoWrite.pcrSelection.sizeOfSelect*8; i++) {
				      if (ndp.pcrInfoWrite.pcrSelection.pcrSelect[(i / 8)] & (1 << (i & 0x7))) {
					      if (!c)
						  printf("\nWrite PCRs selected: ");
					      else
						  printf(", ");
					      printf("%d", i);
					      c++;

				      }
				  }

				  if (c) {
				      printf("\nWrite PCR Composite: ");
				      for (i = 0; i < 20; i++)
					  printf("%02x", ndp.pcrInfoWrite.digestAtRelease[i] & 0xff);
				      printf("\n");
				  }
			      }
			      break;
			  case TPM_CAP_HANDLE:
			      {
				  uint16_t num = LOAD16(resp.buffer, 0);
				  uint16_t x = 0;
				  while (x < num) {
				      uint32_t handle = LOAD32(resp.buffer,
							       sizeof(num)+4*x);
				      printf("%02d. 0x%08X\n",x,handle);
				      x++;
				  }
			      }
			      break;
			  case TPM_CAP_VERSION_VAL:
			      {
				  int i = 0;
				  TPM_CAP_VERSION_INFO cvi;
				  STACK_TPM_BUFFER(tb)
				      TSS_SetTPMBuffer(&tb, resp.buffer, resp.used);
				  ret = TPM_ReadCapVersionInfo(&tb,
							       0,
							       &cvi);
				  if ( ( ret & ERR_MASK) != 0) {
				      printf("Could not read the version info structure.\n");
				      exit(-1);
				  }
					
				  printf("\n");
				  printf("major      : 0x%02X\n",cvi.version.major);
				  printf("minor      : 0x%02X\n",cvi.version.minor);
				  printf("revMajor   : 0x%02X\n",cvi.version.revMajor);
				  printf("revMinor   : 0x%02X\n",cvi.version.revMinor);
				  printf("specLevel  : 0x%04X\n",cvi.specLevel);
				  printf("errataRev  : 0x%02X\n",cvi.errataRev);
	
				  printf("VendorID   : ");
				  while (i < 4) {
				      printf("%02X ",cvi.tpmVendorID[i]);
				      i++;
				  }
				  printf("\n");
				  /* Print vendor ID in text if printable */
				  for (i=0 ; i<4 ; i++) {
				      if (isprint(cvi.tpmVendorID[i])) {
					  if (i == 0) {
					      printf("VendorID   : ");
					  }
					  printf("%c", cvi.tpmVendorID[i]);
				      }
				      else {
					  break;
				      }
				  }	    
				  printf("\n");

				  printf("[not displaying vendor specific information]\n");
			      }
			      break;
#if 0	/* kgold: I don't think these are valid cap values */
			  case TPM_CAP_FLAG_PERMANENT:
			      {
				  TPM_PERMANENT_FLAGS pf;
				  STACK_TPM_BUFFER(tb)
				      TSS_SetTPMBuffer(&tb, resp.buffer, resp.used);

				  if (resp.used == 21) {
				      ret = TPM_ReadPermanentFlagsPre103(&tb, 0, &pf);
				  } else {
				      ret = TPM_ReadPermanentFlags(&tb, 0, &pf);
				  }
				  if ( ( ret & ERR_MASK ) != 0 || ret > resp.used) {
				      printf("ret=%x, responselen=%d\n",ret,resp.used);
				      printf("Error parsing response!\n");
				      exit(-1);
				  }
						
				  printf("\n");
				  showPermanentFlags(&pf, resp.used);
			      }
			      break;
				
			  case TPM_CAP_FLAG_VOLATILE:
			      {
				  TPM_STCLEAR_FLAGS sf;
				  STACK_TPM_BUFFER(tb);
				  TSS_SetTPMBuffer(&tb, resp.buffer, resp.used);
				  ret = TPM_ReadSTClearFlags(&tb, 0, &sf);
				  if ( ( ret & ERR_MASK ) != 0 || ret > resp.used) {
				      printf("ret=%x, responselen=%d\n",ret,resp.used);
				      printf("Error parsing response!\n");
				      exit(-1);
				  }
						
				  printf("\n");
				  showVolatileFlags(&sf);
			      }
			      break;
#endif
			  case TPM_CAP_DA_LOGIC:
			      {
				  uint32_t ctr;
				  TPM_BOOL lim = FALSE;
				  TPM_DA_INFO dainfo;
				  TPM_DA_INFO_LIMITED dainfo_lim;
				  STACK_TPM_BUFFER(tb);
				  TSS_SetTPMBuffer(&tb, resp.buffer, resp.used);
				  ret = TPM_ReadDAInfo(&tb, 0, &dainfo);
				  if ( ( ret & ERR_MASK) != 0 || ret > resp.used) {
				      ret = TPM_ReadDAInfoLimited(&tb, 0, &dainfo_lim);
				      if ( (ret & ERR_MASK ) != 0 || ret > resp.used) {
					  printf("ret=%x, responselen=%d\n",ret,resp.used);
					  printf("Error parsing response!\n");
					  exit(-1);
				      } else {
					  lim = TRUE;
				      }
				  }
					
				  printf("\n");
				  if (lim) {
				      printf("State      : %d\n",dainfo_lim.state);
				      printf("Actions    : 0x%08x\n",dainfo_lim.actionAtThreshold.actions);
						
				      ctr = 0;
				      while (ctr < dainfo_lim.vendorData.size) {
					  printf("%02x ",(unsigned char)dainfo_lim.vendorData.buffer[ctr]);
					  ctr++;
				      }
				  } else {
				      printf("State              : %d\n",dainfo.state);
				      printf("currentCount       : %d\n",dainfo.currentCount);
				      printf("thresholdCount     : %d\n",dainfo.thresholdCount);
				      printf("Actions            : 0x%08x\n",dainfo.actionAtThreshold.actions);
				      printf("actionDependValue  : %d\n",dainfo.actionDependValue);
						
#if 0
				      ctr = 0;
				      while (ctr < dainfo_lim.vendorData.size) {
					  printf("%02x ",(unsigned char)dainfo_lim.vendorData.buffer[ctr]);
					  ctr++;
				      }
#endif
				  }
			      }
			      break;
			}
		    } else
			if (TYPE_VARIOUS == matrx[index].result_size) {
			    switch(cap) {
			
			      case TPM_CAP_MFR:
				switch (scap) {
				  case TPM_CAP_PROCESS_ID:
				      {
					  uint32_t rsp;
					  rsp = LOAD32(resp.buffer,0);
					  printf("%d\n",rsp);
				      }
				      break;
				}
				break; /* TPM_CAP_MFR */
			
			      default:
				/* Show booleans */
				if (scap == TPM_CAP_PROP_OWNER ||
				    scap == TPM_CAP_PROP_DAA_INTERRUPT
				    ) {
				    if (0 == resp.buffer[0]) {
					printf("FALSE\n");
				    } else {
					printf("TRUE\n");
				    }
				} else /* check for array of 4 UINTs */
				    if (scap == TPM_CAP_PROP_TIS_TIMEOUT /* ||
									    scap == TPM_CAP_PROP_TIMEOUTS      */) {
					int i = 0;
					while (i < 4) {
					    uint32_t val = LOAD32(resp.buffer,i * 4);
					    printf("%d ",
						   val);
					    i++;
					}
					printf("\n");
				    } else /* check for TPM_STARTUP_EFFECTS */
					if (scap == TPM_CAP_PROP_STARTUP_EFFECT) {
					    TPM_STARTUP_EFFECTS se = 0;
					    ret = TPM_ReadStartupEffects(resp.buffer, 
									 &se);
					    if ( ( ret & ERR_MASK ) != 0 ) {
						printf("Could not read startup effects structure.\n");
						exit(-1);
					    }
					    printf("0x%08X=%d\n",
						   (unsigned int)se,
						   (unsigned int)se);
					    printf("\n");
					    printf("Startup effects:\n");
					    printf("Effect on audit digest: %s\n", (se & (1 << 7)) 
						   ? "none"
						   : "active");
					    printf("Audit Digest on TPM_Startup(ST_CLEAR): %s\n", ( se & (1 << 6)) 
						   ? "set to NULL" 
						   : "not set to NULL" );
		
					    printf("Audit Digest on TPM_Startup(any)     : %s\n", ( se & (1 << 5))
						   ? "set to NULL"
						   : "not set to NULL" );
					    printf("TPM_RT_KEY resource initialized on TPM_Startup(ST_ANY)     : %s\n", (se & ( 1 << 4))
						   ? "yes"
						   : "no");
					    printf("TPM_RT_AUTH resource initialized on TPM_Startup(ST_STATE)  : %s\n", (se & ( 1 << 3))
						   ? "yes"
						   : "no");
					    printf("TPM_RT_HASH resource initialized on TPM_Startup(ST_STATE)  : %s\n", (se & ( 1 << 2))
						   ? "yes"
						   : "no");
					    printf("TPM_RT_TRANS resource initialized on TPM_Startup(ST_STATE) : %s\n", (se & ( 1 << 1))
						   ? "yes"
						   : "no");
					    printf("TPM_RT_CONTEXT session initialized on TPM_Startup(ST_STATE): %s\n", (se & ( 1 << 0))
						   ? "yes"
						   : "no");
					} else /* check for  array of 3 UINTs */
					    if (scap == TPM_CAP_PROP_DURATION) {
						int i = 0;
						while (i < 4*3) {
						    uint32_t val = LOAD32(resp.buffer,i);
						    printf("%d ",
							   val);
						    i+= 4;
						}
						printf("\n");
					    } else /* check for TPM_COUNT_ID */
						if (scap == TPM_CAP_PROP_ACTIVE_COUNTER) {
						    uint32_t val = LOAD32(resp.buffer,0);
						    printf("0x%08X=%d",val,val);
						    if (0xffffffff == val) {
							printf(" (no counter is active)");
						    }
						    printf("\n");
						} else { /* just a single UINT32 */
						    printf("%ld=0x%08lX.\n",
							   (long)LOAD32(resp.buffer, 0),
							   (long)LOAD32(resp.buffer, 0));
						}
			    }
			}
    }		
	
    printf("\n");
    exit(0);
}
Ejemplo n.º 13
0
/*
 * Have the TPM seal(encrypt) the trusted key, possibly based on
 * Platform Configuration Registers (PCRs). AUTH1 for sealing key.
 */
static int tpm_seal(struct tpm_buf *tb, uint16_t keytype,
		    uint32_t keyhandle, const unsigned char *keyauth,
		    const unsigned char *data, uint32_t datalen,
		    unsigned char *blob, uint32_t *bloblen,
		    const unsigned char *blobauth,
		    const unsigned char *pcrinfo, uint32_t pcrinfosize)
{
	struct osapsess sess;
	struct tpm_digests *td;
	unsigned char cont;
	uint32_t ordinal;
	uint32_t pcrsize;
	uint32_t datsize;
	int sealinfosize;
	int encdatasize;
	int storedsize;
	int ret;
	int i;

	/* alloc some work space for all the hashes */
	td = kmalloc(sizeof *td, GFP_KERNEL);
	if (!td)
		return -ENOMEM;

	/* get session for sealing key */
	ret = osap(tb, &sess, keyauth, keytype, keyhandle);
	if (ret < 0)
		goto out;
	dump_sess(&sess);

	/* calculate encrypted authorization value */
	memcpy(td->xorwork, sess.secret, SHA1_DIGEST_SIZE);
	memcpy(td->xorwork + SHA1_DIGEST_SIZE, sess.enonce, SHA1_DIGEST_SIZE);
	ret = TSS_sha1(td->xorwork, SHA1_DIGEST_SIZE * 2, td->xorhash);
	if (ret < 0)
		goto out;

	ret = tpm_get_random(TPM_ANY_NUM, td->nonceodd, TPM_NONCE_SIZE);
	if (ret != TPM_NONCE_SIZE)
		goto out;
	ordinal = htonl(TPM_ORD_SEAL);
	datsize = htonl(datalen);
	pcrsize = htonl(pcrinfosize);
	cont = 0;

	/* encrypt data authorization key */
	for (i = 0; i < SHA1_DIGEST_SIZE; ++i)
		td->encauth[i] = td->xorhash[i] ^ blobauth[i];

	/* calculate authorization HMAC value */
	if (pcrinfosize == 0) {
		/* no pcr info specified */
		ret = TSS_authhmac(td->pubauth, sess.secret, SHA1_DIGEST_SIZE,
				   sess.enonce, td->nonceodd, cont,
				   sizeof(uint32_t), &ordinal, SHA1_DIGEST_SIZE,
				   td->encauth, sizeof(uint32_t), &pcrsize,
				   sizeof(uint32_t), &datsize, datalen, data, 0,
				   0);
	} else {
		/* pcr info specified */
		ret = TSS_authhmac(td->pubauth, sess.secret, SHA1_DIGEST_SIZE,
				   sess.enonce, td->nonceodd, cont,
				   sizeof(uint32_t), &ordinal, SHA1_DIGEST_SIZE,
				   td->encauth, sizeof(uint32_t), &pcrsize,
				   pcrinfosize, pcrinfo, sizeof(uint32_t),
				   &datsize, datalen, data, 0, 0);
	}
	if (ret < 0)
		goto out;

	/* build and send the TPM request packet */
	INIT_BUF(tb);
	store16(tb, TPM_TAG_RQU_AUTH1_COMMAND);
	store32(tb, TPM_SEAL_SIZE + pcrinfosize + datalen);
	store32(tb, TPM_ORD_SEAL);
	store32(tb, keyhandle);
	storebytes(tb, td->encauth, SHA1_DIGEST_SIZE);
	store32(tb, pcrinfosize);
	storebytes(tb, pcrinfo, pcrinfosize);
	store32(tb, datalen);
	storebytes(tb, data, datalen);
	store32(tb, sess.handle);
	storebytes(tb, td->nonceodd, TPM_NONCE_SIZE);
	store8(tb, cont);
	storebytes(tb, td->pubauth, SHA1_DIGEST_SIZE);

	ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, MAX_BUF_SIZE);
	if (ret < 0)
		goto out;

	/* calculate the size of the returned Blob */
	sealinfosize = LOAD32(tb->data, TPM_DATA_OFFSET + sizeof(uint32_t));
	encdatasize = LOAD32(tb->data, TPM_DATA_OFFSET + sizeof(uint32_t) +
			     sizeof(uint32_t) + sealinfosize);
	storedsize = sizeof(uint32_t) + sizeof(uint32_t) + sealinfosize +
	    sizeof(uint32_t) + encdatasize;

	/* check the HMAC in the response */
	ret = TSS_checkhmac1(tb->data, ordinal, td->nonceodd, sess.secret,
			     SHA1_DIGEST_SIZE, storedsize, TPM_DATA_OFFSET, 0,
			     0);

	/* copy the returned blob to caller */
	if (!ret) {
		memcpy(blob, tb->data + TPM_DATA_OFFSET, storedsize);
		*bloblen = storedsize;
	}
out:
	kfree(td);
	return ret;
}
Ejemplo n.º 14
0
/*
 * use the AUTH2_COMMAND form of unseal, to authorize both key and blob
 */
static int tpm_unseal(struct tpm_buf *tb,
		      uint32_t keyhandle, const unsigned char *keyauth,
		      const unsigned char *blob, int bloblen,
		      const unsigned char *blobauth,
		      unsigned char *data, unsigned int *datalen)
{
	unsigned char nonceodd[TPM_NONCE_SIZE];
	unsigned char enonce1[TPM_NONCE_SIZE];
	unsigned char enonce2[TPM_NONCE_SIZE];
	unsigned char authdata1[SHA1_DIGEST_SIZE];
	unsigned char authdata2[SHA1_DIGEST_SIZE];
	uint32_t authhandle1 = 0;
	uint32_t authhandle2 = 0;
	unsigned char cont = 0;
	uint32_t ordinal;
	uint32_t keyhndl;
	int ret;

	/* sessions for unsealing key and data */
	ret = oiap(tb, &authhandle1, enonce1);
	if (ret < 0) {
		pr_info("trusted_key: oiap failed (%d)\n", ret);
		return ret;
	}
	ret = oiap(tb, &authhandle2, enonce2);
	if (ret < 0) {
		pr_info("trusted_key: oiap failed (%d)\n", ret);
		return ret;
	}

	ordinal = htonl(TPM_ORD_UNSEAL);
	keyhndl = htonl(SRKHANDLE);
	ret = tpm_get_random(TPM_ANY_NUM, nonceodd, TPM_NONCE_SIZE);
	if (ret != TPM_NONCE_SIZE) {
		pr_info("trusted_key: tpm_get_random failed (%d)\n", ret);
		return ret;
	}
	ret = TSS_authhmac(authdata1, keyauth, TPM_NONCE_SIZE,
			   enonce1, nonceodd, cont, sizeof(uint32_t),
			   &ordinal, bloblen, blob, 0, 0);
	if (ret < 0)
		return ret;
	ret = TSS_authhmac(authdata2, blobauth, TPM_NONCE_SIZE,
			   enonce2, nonceodd, cont, sizeof(uint32_t),
			   &ordinal, bloblen, blob, 0, 0);
	if (ret < 0)
		return ret;

	/* build and send TPM request packet */
	INIT_BUF(tb);
	store16(tb, TPM_TAG_RQU_AUTH2_COMMAND);
	store32(tb, TPM_UNSEAL_SIZE + bloblen);
	store32(tb, TPM_ORD_UNSEAL);
	store32(tb, keyhandle);
	storebytes(tb, blob, bloblen);
	store32(tb, authhandle1);
	storebytes(tb, nonceodd, TPM_NONCE_SIZE);
	store8(tb, cont);
	storebytes(tb, authdata1, SHA1_DIGEST_SIZE);
	store32(tb, authhandle2);
	storebytes(tb, nonceodd, TPM_NONCE_SIZE);
	store8(tb, cont);
	storebytes(tb, authdata2, SHA1_DIGEST_SIZE);

	ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, MAX_BUF_SIZE);
	if (ret < 0) {
		pr_info("trusted_key: authhmac failed (%d)\n", ret);
		return ret;
	}

	*datalen = LOAD32(tb->data, TPM_DATA_OFFSET);
	ret = TSS_checkhmac2(tb->data, ordinal, nonceodd,
			     keyauth, SHA1_DIGEST_SIZE,
			     blobauth, SHA1_DIGEST_SIZE,
			     sizeof(uint32_t), TPM_DATA_OFFSET,
			     *datalen, TPM_DATA_OFFSET + sizeof(uint32_t), 0,
			     0);
	if (ret < 0) {
		pr_info("trusted_key: TSS_checkhmac2 failed (%d)\n", ret);
		return ret;
	}
	memcpy(data, tb->data + TPM_DATA_OFFSET + sizeof(uint32_t), *datalen);
	return 0;
}
Ejemplo n.º 15
0
/*
 * verify the AUTH2_COMMAND (unseal) result from TPM
 */
static int TSS_checkhmac2(unsigned char *buffer,
			  const uint32_t command,
			  const unsigned char *ononce,
			  const unsigned char *key1,
			  unsigned int keylen1,
			  const unsigned char *key2,
			  unsigned int keylen2, ...)
{
	uint32_t bufsize;
	uint16_t tag;
	uint32_t ordinal;
	uint32_t result;
	unsigned char *enonce1;
	unsigned char *continueflag1;
	unsigned char *authdata1;
	unsigned char *enonce2;
	unsigned char *continueflag2;
	unsigned char *authdata2;
	unsigned char testhmac1[SHA1_DIGEST_SIZE];
	unsigned char testhmac2[SHA1_DIGEST_SIZE];
	unsigned char paramdigest[SHA1_DIGEST_SIZE];
	struct sdesc *sdesc;
	unsigned int dlen;
	unsigned int dpos;
	va_list argp;
	int ret;

	bufsize = LOAD32(buffer, TPM_SIZE_OFFSET);
	tag = LOAD16(buffer, 0);
	ordinal = command;
	result = LOAD32N(buffer, TPM_RETURN_OFFSET);

	if (tag == TPM_TAG_RSP_COMMAND)
		return 0;
	if (tag != TPM_TAG_RSP_AUTH2_COMMAND)
		return -EINVAL;
	authdata1 = buffer + bufsize - (SHA1_DIGEST_SIZE + 1
			+ SHA1_DIGEST_SIZE + SHA1_DIGEST_SIZE);
	authdata2 = buffer + bufsize - (SHA1_DIGEST_SIZE);
	continueflag1 = authdata1 - 1;
	continueflag2 = authdata2 - 1;
	enonce1 = continueflag1 - TPM_NONCE_SIZE;
	enonce2 = continueflag2 - TPM_NONCE_SIZE;

	sdesc = init_sdesc(hashalg);
	if (IS_ERR(sdesc)) {
		pr_info("trusted_key: can't alloc %s\n", hash_alg);
		return PTR_ERR(sdesc);
	}
	ret = crypto_shash_init(&sdesc->shash);
	if (ret < 0)
		goto out;
	ret = crypto_shash_update(&sdesc->shash, (const u8 *)&result,
				  sizeof result);
	if (ret < 0)
		goto out;
	ret = crypto_shash_update(&sdesc->shash, (const u8 *)&ordinal,
				  sizeof ordinal);
	if (ret < 0)
		goto out;

	va_start(argp, keylen2);
	for (;;) {
		dlen = va_arg(argp, unsigned int);
		if (dlen == 0)
			break;
		dpos = va_arg(argp, unsigned int);
		ret = crypto_shash_update(&sdesc->shash, buffer + dpos, dlen);
		if (ret < 0)
			break;
	}
	va_end(argp);
	if (!ret)
		ret = crypto_shash_final(&sdesc->shash, paramdigest);
	if (ret < 0)
		goto out;

	ret = TSS_rawhmac(testhmac1, key1, keylen1, SHA1_DIGEST_SIZE,
			  paramdigest, TPM_NONCE_SIZE, enonce1,
			  TPM_NONCE_SIZE, ononce, 1, continueflag1, 0, 0);
	if (ret < 0)
		goto out;
	if (memcmp(testhmac1, authdata1, SHA1_DIGEST_SIZE)) {
		ret = -EINVAL;
		goto out;
	}
	ret = TSS_rawhmac(testhmac2, key2, keylen2, SHA1_DIGEST_SIZE,
			  paramdigest, TPM_NONCE_SIZE, enonce2,
			  TPM_NONCE_SIZE, ononce, 1, continueflag2, 0, 0);
	if (ret < 0)
		goto out;
	if (memcmp(testhmac2, authdata2, SHA1_DIGEST_SIZE))
		ret = -EINVAL;
out:
	kfree(sdesc);
	return ret;
}
Ejemplo n.º 16
0
/*
 * Load a TPM key from the blob provided by userspace
 */
static int tpm_loadkey2(struct tpm_buf *tb,
			uint32_t keyhandle, unsigned char *keyauth,
			const unsigned char *keyblob, int keybloblen,
			uint32_t *newhandle)
{
	unsigned char nonceodd[TPM_NONCE_SIZE];
	unsigned char enonce[TPM_NONCE_SIZE];
	unsigned char authdata[SHA1_DIGEST_SIZE];
	uint32_t authhandle = 0;
	unsigned char cont = 0;
	uint32_t ordinal;
	int ret;

	ordinal = htonl(TPM_ORD_LOADKEY2);

	/* session for loading the key */
	ret = oiap(tb, &authhandle, enonce);
	if (ret < 0) {
		pr_info("oiap failed (%d)\n", ret);
		return ret;
	}

	/* generate odd nonce */
	ret = tpm_get_random(NULL, nonceodd, TPM_NONCE_SIZE);
	if (ret < 0) {
		pr_info("tpm_get_random failed (%d)\n", ret);
		return ret;
	}

	/* calculate authorization HMAC value */
	ret = TSS_authhmac(authdata, keyauth, SHA1_DIGEST_SIZE, enonce,
			   nonceodd, cont, sizeof(uint32_t), &ordinal,
			   keybloblen, keyblob, 0, 0);
	if (ret < 0)
		return ret;

	/* build the request buffer */
	INIT_BUF(tb);
	store16(tb, TPM_TAG_RQU_AUTH1_COMMAND);
	store32(tb, TPM_LOADKEY2_SIZE + keybloblen);
	store32(tb, TPM_ORD_LOADKEY2);
	store32(tb, keyhandle);
	storebytes(tb, keyblob, keybloblen);
	store32(tb, authhandle);
	storebytes(tb, nonceodd, TPM_NONCE_SIZE);
	store8(tb, cont);
	storebytes(tb, authdata, SHA1_DIGEST_SIZE);

	ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
	if (ret < 0) {
		pr_info("authhmac failed (%d)\n", ret);
		return ret;
	}

	ret = TSS_checkhmac1(tb->data, ordinal, nonceodd, keyauth,
			     SHA1_DIGEST_SIZE, 0, 0);
	if (ret < 0) {
		pr_info("TSS_checkhmac1 failed (%d)\n", ret);
		return ret;
	}

	*newhandle = LOAD32(tb->data, TPM_DATA_OFFSET);
	return 0;
}
Ejemplo n.º 17
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;
}
Ejemplo 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;
}
Ejemplo n.º 19
0
int main(int argc, char *argv[])
{
	int ret;
	unsigned char familyTable[256];
	uint32_t familyTableSize = sizeof(familyTable);
	unsigned char delegateTable[256];
	uint32_t delegateTableSize = sizeof(delegateTable);
	uint32_t i = 0;
	(void)argv;
	(void)argc;
	
	TPM_setlog(0);

	ret = TPM_Delegate_ReadTable(familyTable, &familyTableSize,
	                             delegateTable, &delegateTableSize);

	if (0 != ret) {
		printf("Delegate_ReadTable returned error '%s' (%d).\n",
		       TPM_GetErrMsg(ret),
		       ret);

	} else {
		STACK_TPM_BUFFER( buffer )
		i = 0;
		SET_TPM_BUFFER( &buffer, familyTable, familyTableSize)
		while (i < familyTableSize) {
			TPM_FAMILY_TABLE_ENTRY fte;
			ret = TPM_ReadFamilyTableEntry(&buffer, i, &fte);
			if (0 == (ret & ERR_MASK) && ret > 0) {
				printf("Family Table Entry:\n"
				       "familyLabel       : %d\n"
				       "familyID          : "OUT_FORMAT("%d","%d")"\n"
				       "verificationCount : "OUT_FORMAT("%d","%d")"\n"
				       "flags             : "OUT_FORMAT("0x%x","0x%x")"\n\n",
				       fte.familyLabel,
				       fte.familyID,
				       fte.verificationCount,
				       fte.flags);
			} else {
				printf("Error %s from TPM_ReadFamilyTableEntry.\n",
				       TPM_GetErrMsg(ret));
				return ret;
			}
			i += ret;
		}

		SET_TPM_BUFFER( &buffer, delegateTable, delegateTableSize);
		i = 0;
		while (i < delegateTableSize) {
			TPM_DELEGATE_PUBLIC dtp;
			TPM_DELEGATE_INDEX didx = LOAD32(buffer.buffer, i);
			i += 4;
			ret = TPM_ReadDelegatePublic(&buffer, i, &dtp);
			if (0 == (ret & ERR_MASK) && ret > 0) {
				printf("\n\nDelegate Table Entry:\n"
				       "index             : "OUT_FORMAT("%d","%d")"\n"
				       "rowLabel          : %d\n"
				       "permissions       : "OUT_FORMAT("0x%08x, 0x%08x","0x%08x, 0x%08x")"\n"
				       "familyID          : "OUT_FORMAT("%d","%d")"\n"
				       "verificationCount : "OUT_FORMAT("%d","%d")"\n",
				       didx,
				       dtp.rowLabel,
				       dtp.permissions.per1, dtp.permissions.per2,
				       dtp.familyID,
				       dtp.verificationCount);
			} else {
				printf("Error %s from TPM_ReadDelegatePublic.\n",
				       TPM_GetErrMsg(ret));
				exit(ret);
			}
			i += ret;
		}
		printf("\n");
		ret = 0;
	}

	exit(ret);
}
Ejemplo n.º 20
0
int main(int argc, char * argv[]) {
	uint32_t ret = 0;
	int i =	0;
	int verbose = FALSE;
	uint32_t migkeyhandle = 0;
	char * filename = NULL;
	unsigned char * buffer = NULL;
	unsigned char keypasshash[TPM_HASH_SIZE];
	char * keypass = NULL;
	uint16_t migscheme = TPM_MS_MIGRATE;
	unsigned char * keyhashptr = NULL;
	
	i = 1;
	
	TPM_setlog(0);
	
	while (i < argc) {
	    if (!strcmp("-if",argv[i])) {
		i++;
		if (i < argc) {
		    filename = argv[i];
		} else {
		    printf("Missing mandatory parameter for -if.\n");
		    usage();
		}
	    }
	    else if (!strcmp("-hp",argv[i])) {
		i++;
		if (i < argc) {
		    sscanf(argv[i],"%x",&migkeyhandle);
		} else {
		    printf("Missing mandatory parameter for -hp.\n");
		    usage();
		}
	    }
	    else if (!strcmp("-pwdp",argv[i])) {
		i++;
		if (i < argc) {
		    keypass = argv[i];
		} else {
		    printf("Missing mandatory parameter for -pwdp.\n");
		    usage();
		}
	    }
	    else if (!strcmp("-rewrap",argv[i])) {
		migscheme = TPM_MS_REWRAP;
	    }
	    else if (!strcmp("-v",argv[i])) {
		verbose = TRUE;
		TPM_setlog(1);
	    }
	    else if (!strcmp("-h",argv[i])) {
		usage();
	    }
	    else {
		printf("\n%s is not a valid option\n", argv[i]);
		usage();
	    }
	    i++;
	}
	
	if (0 == migkeyhandle ||
	    NULL == filename) {
		printf("Missing mandatory parameter.\n");
		usage();
	}

	if (NULL != keypass) {
		TSS_sha1(keypass,strlen(keypass),keypasshash);
		keyhashptr = keypasshash;
	} else {
		keyhashptr = NULL;
	}
	
	buffer = readFile(filename);
	if (NULL != buffer) {
		int offset = 0;
		unsigned char * encblob = NULL;
		uint32_t encsize = 0;
		unsigned char * rndblob = NULL;
		uint32_t rndsize = 0;
		uint32_t keysize = 0;
		unsigned char * keyblob = NULL;
		unsigned char * outblob = NULL;
		uint32_t outblen;
		keydata newkey;
		STACK_TPM_BUFFER( tb );
		
		rndsize = LOAD32(buffer,offset);  offset += 4;
		rndblob = &buffer[offset];        offset += rndsize;
		encsize = LOAD32(buffer,offset);  offset += 4;
		encblob = &buffer[offset];        offset += encsize;
		keysize = LOAD32(buffer,offset);  offset += 4;
		keyblob = &buffer[offset];        offset += keysize;
		
		SET_TPM_BUFFER(&tb, keyblob, keysize);
		TSS_KeyExtract(&tb, 0,&newkey);

		outblob = malloc(encsize);
		if (NULL == outblob) {
			printf("Error allocating memory for decrypted blob.\n");
			exit(-1);
		}
		outblen = encsize;

		if (TPM_MS_REWRAP == migscheme || 0 == rndsize) {
			memcpy(newkey.encData.buffer,
			       encblob,
			       encsize);
			newkey.encData.size = outblen;
			ret = 0;
		} else {
			ret = TPM_ConvertMigrationBlob(migkeyhandle,
			                               keyhashptr,
			                               rndblob, rndsize,
			                               encblob, encsize,
			                               outblob, &outblen);

			if (0 == ret) {
				memcpy(newkey.encData.buffer,
				       outblob,
				       outblen);
				newkey.encData.size = outblen;
			} else {
				printf("ConvertMigrationBlob returned '%s' (0x%x).\n",
				       	TPM_GetErrMsg(ret),
				       	ret);
			}
		}
		if (0 == ret) {
			uint32_t newhandle;
			ret = TPM_LoadKey(migkeyhandle,
			                  keyhashptr,
			                  &newkey,
			                  &newhandle);
			if (0 == ret) {
				printf("Successfully loaded key into TPM.\n"
				       "New Key Handle = %08X\n",
				       newhandle);
			} else {
				printf("LoadKey returned '%s' (0x%x).\n",
				       	TPM_GetErrMsg(ret),
				       	ret);
			}
		}
	}
	return ret;
}
Ejemplo n.º 21
0
int main(int argc, char * argv[]) {
    char * migrationkeyfile = NULL;
    char * filename = NULL;
    char * migrationKeyPassword = NULL;
    unsigned char migrationkeyUsageAuth[TPM_DIGEST_SIZE];
    unsigned char * passptr = NULL;
    uint32_t ret = 0;
    int i =	0;
    keydata migrationkey;
    int verbose = FALSE;
    uint32_t migrationkeyhandle = 0;
    unsigned char * buffer = NULL;
    uint32_t bufferSize = 0;

    i = 1;

    TPM_setlog(0);

    while (i < argc) {
        if (!strcmp("-if",argv[i])) {
            i++;
            if (i < argc) {
                filename = argv[i];
            } else {
                printf("Missing parameter for -if.\n");
                usage();
                exit(-1);
            }
        }
        else if (!strcmp("-pwdm",argv[i])) {
            i++;
            if (i < argc) {
                migrationKeyPassword = argv[i];
            } else {
                printf("Missing parameter for -pwdm.\n");
                usage();
                exit(-1);
            }
        }
        else if (!strcmp("-hm",argv[i])) {
            i++;
            if (i < argc) {
                sscanf(argv[i],"%x",&migrationkeyhandle);
            } else {
                printf("Missing parameter for -hm.\n");
                usage();
                exit(-1);
            }
        }
        else if (!strcmp("-ik",argv[i])) {
            i++;
            if (i < argc) {
                migrationkeyfile = argv[i];
            } else {
                printf("Missing parameter for -ik.\n");
                usage();
                exit(-1);
            }
        }
        else if (!strcmp("-v",argv[i])) {
            verbose = TRUE;
            TPM_setlog(1);
        }
        else if (!strcmp("-h",argv[i])) {
            usage();
            exit(-1);
        } else {
            printf("\n%s is not a valid option\n", argv[i]);
            usage();
            exit(-1);
        }
        i++;
    }


    if (NULL == migrationkeyfile ||
            NULL == filename   ||
            -1 == (int)migrationkeyhandle) {
        printf("Missing or wrong parameter.\n");
        usage();
        exit(-1);
    }


    if (NULL != migrationKeyPassword) {
        TSS_sha1(migrationKeyPassword,
                 strlen(migrationKeyPassword),
                 migrationkeyUsageAuth);
        passptr = migrationkeyUsageAuth;
    }


    /*
     * load the key to be migrated from a file.
     */
    ret = 0;

    buffer = readFile(filename, &bufferSize);
    if (NULL != buffer) {

        unsigned int offset = 0;
        unsigned char * encblob = NULL;
        uint32_t encsize = 0;
        unsigned char * rndblob = NULL;
        uint32_t rndsize = 0;
        uint32_t keysize = 0;
        unsigned char * keyblob = NULL;
        keydata tobemigkey;
        STACK_TPM_BUFFER(tb)

        rndsize = LOAD32(buffer,offset);
        offset += 4;
        if (offset > bufferSize) {
            printf("Bad input file. Exiting.\n");
            return -1;
        }
        rndblob = &buffer[offset];
        offset += rndsize;
        if (offset > bufferSize) {
            printf("Bad input file. Exiting.\n");
            return -1;
        }
        encsize = LOAD32(buffer,offset);
        offset += 4;
        if (offset > bufferSize) {
            printf("Bad input file. Exiting.\n");
            return -1;
        }
        encblob = &buffer[offset];
        offset += encsize;
        if (offset > bufferSize) {
            printf("Bad input file. Exiting.\n");
            return -1;
        }
        keysize = LOAD32(buffer,offset);
        offset += 4;
        if (offset > bufferSize) {
            printf("Bad input file. Exiting.\n");
            return -1;
        }
        keyblob = &buffer[offset];
        offset += keysize;

        if (offset != bufferSize) {
            printf("Bad input file. Exiting");
            return -1;
        }

        SET_TPM_BUFFER(&tb, keyblob, keysize);
        TSS_KeyExtract(&tb,0,&tobemigkey);

        /*
         * load the migration key from the destination
         * TPM from a file. Need the public key part of
         * that key.
         */
        ret = loadKey(migrationkeyfile, &migrationkey);
        if (0 == ret) {
            STACK_TPM_BUFFER(keyblob)
            uint32_t keyblen = 0;
            unsigned char * reencData = malloc(encsize);
            uint32_t reencDataSize = encsize;

            if (NULL == encblob || NULL == reencData) {
                printf("Could not get memory for encryted private key blob.\n");
                exit (-1);
            }

            ret = TPM_WriteKeyPub(&keyblob, &migrationkey);

            if (ret & ERR_MASK) {
                printf("Could not serialize the keydata!\n");
                free(reencData);
                exit(-1);
            }
            keyblen = ret;

            ret = TPM_MigrateKey(migrationkeyhandle,
                                 passptr,
                                 keyblob.buffer, keyblen,
                                 encblob, encsize,
                                 reencData, &reencDataSize);

            if (0 == ret) {
                STACK_TPM_BUFFER(keybuf)
                // serialize the key to be migrated
                ret = TPM_WriteKey(&keybuf,&tobemigkey);
                if (ret > 0) {
                    unsigned int keybuflen = ret;
                    FILE * f = fopen(filename,"wb");
                    if (NULL != f) {
                        struct tpm_buffer *filebuf = TSS_AllocTPMBuffer(10240);
                        if (NULL != filebuf) {
                            int l;
                            l = TSS_buildbuff("@ @ @",filebuf,
                                              rndsize, rndblob,
                                              reencDataSize, reencData,
                                              keybuflen, keybuf.buffer);
                            fwrite(filebuf->buffer,
                                   l,
                                   1,
                                   f);
                            fclose(f);
                            printf("Wrote migration blob and associated data to file.\n");
                            ret = 0;
                            TSS_FreeTPMBuffer(filebuf);
                        } else {
                            printf("Error. Could not allocate memory.\n");
                            ret = -1;
                        }
                    }
                }
            } else {
                printf("MigrateKey returned '%s' (0x%x).\n",
                       TPM_GetErrMsg(ret),
                       ret);
            }
            free(reencData);
        } else {
            printf("Error. Could not load the migration key.");
        }
    } else {
        printf("Error. Could not load the blob from file '%s'.\n",
               filename);
    }
    return ret;
}
Ejemplo n.º 22
0
Archivo: seal.c Proyecto: 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;
}
Ejemplo n.º 23
0
Archivo: seal.c Proyecto: 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;
}