Example #1
0
static TPM_RESULT execute_TPM_Quote(TPM_REQUEST *req, TPM_RESPONSE *rsp)
{
  BYTE *ptr;
  UINT32 len;
  TPM_KEY_HANDLE keyHandle;
  TPM_NONCE extrnalData;
  TPM_PCR_SELECTION targetPCR;
  TPM_PCR_COMPOSITE *pcrData;
  UINT32 sigSize;
  BYTE *sig = NULL;
  TPM_RESULT res;
  pcrData = (TPM_PCR_COMPOSITE *)InOutBuf;
  /* compute parameter digest */
  tpm_compute_in_param_digest(req);
  /* unmarshal input */
  ptr = req->param;
  len = req->paramSize;
  if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle)
      || tpm_unmarshal_TPM_NONCE(&ptr, &len, &extrnalData)
      || tpm_unmarshal_TPM_PCR_SELECTION(&ptr, &len, &targetPCR)
      || len != 0) return TPM_BAD_PARAMETER;
  /* execute command */
  res = TPM_Quote(keyHandle, &extrnalData, &targetPCR, &req->auth1, pcrData, &sigSize, &sig);
  if (res != TPM_SUCCESS) return res;
  /* marshal output */
  rsp->paramSize = len = sizeof_TPM_PCR_COMPOSITE((*pcrData)) + 4 + sigSize;
  rsp->param = ptr = ExtendBuf;
  if (ptr == NULL
      || tpm_marshal_TPM_PCR_COMPOSITE(&ptr, &len, pcrData)
      || tpm_marshal_UINT32(&ptr, &len, sigSize)
      || tpm_marshal_BLOB(&ptr, &len, sig, sigSize)) {
    free(rsp->param);
    res = TPM_FAIL;
  }
  free(sig);
  return res;
}
Example #2
0
int main(int argc, char **argv)
{
	int fd, size, i, ret;
	uint32_t kh, pcrs;

	unsigned char buf[1024], hash[20], pass[20];
	char *srkpass, *keyfile, ch;

	/* SHA1 hash of TPM's SRK password */
	char *tpmhash = "\x71\x10\xed\xa4\xd0\x9e\x06\x2a\xa5\xe4\xa3"
			"\x90\xb0\xa5\x72\xac\x0d\x2c\x02\x20";
	char *nonce =	"\x80\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0"
			"\x0\x0\x0\x0\x1";
	keydata k;
	RSA *rpub;

	srkpass = keyfile = NULL;
	while ((ch = getopt(argc, argv, "hs:f:")) != -1) {
		switch (ch) {
			case 's':
				srkpass = optarg;
				break;
			case 'f':
				keyfile = optarg;
				break;
			case 'h':
			default:
				usage(argv[0]);
				break;
		}
	}

	if (!srkpass)
		usage(argv[0]);
	if (!keyfile)
		keyfile = "key.blob";

	SHA1(srkpass, strlen(srkpass), pass);

	fd = open(keyfile, O_RDONLY);
	if (fd == -1)
		errx(1, "couldn't open %s\n", keyfile);

	size = read(fd, buf, 1024);
	if (size == -1)
		errx(1, "couldn't read\n");

	size = TSS_KeyExtract(buf, &k);
	printf("keybuf size: %d\n", size);

	close(fd);

	printf("loading . . .\n");
	/* 0x40000000 is the UID for the SRK */
	if (ret = TPM_LoadKey(0x40000000, pass, &k, &kh)) {
		printf("%s\n", TPM_GetErrMsg(ret));
		errx(1, "TPM_LoadKey\n");
	}

	/* Quote PCR 0 */
	printf("quoting . . .\n");
	if (ret = TPM_Quote(kh, (0x00000001 << 0), pass, nonce, &pcomp, buf,
	    &size)) {
		printf("%s\n", TPM_GetErrMsg(ret));
		errx(1, "TPM_Quote\n");
	}

	/* TPM will run out of memory if you forget to evict keys.  This can be
	 * fixed with a good ol' reboot.*/
	printf("evicting. . .\n");
	if (ret = TPM_EvictKey(kh)) {
		printf("%s\n", TPM_GetErrMsg(ret));
		errx(1, "TPM_EvictKey\n");
	}

	/* Compute composite hash */
	SHA1((char*)&pcomp, sizeof(pcomp), hash);

	printf("slen: %d\n", ntohs(pcomp.slen));
	printf("select: 0x%x\n", pcomp.s);
	printf("plen %d\n", ntohl(pcomp.plen));
	printf("pcr hash: ");
	for (i = 0; i < 20; i++)
		printf("%02x ", pcomp.p[i]);
	printf("\n");
	printf("composite hash: ");
	for (i = 0; i < 20; i++)
		printf("%02x ", hash[i]);
	printf("\n");
	printf("signed blob len: %d\n", size);
	printf("signed blob: ");
	for (i = 0; i < size; i++)
		printf("%02x ", buf[i]);
	printf("\n");

	/* See if the signed object matches the composite hash concatenated
	 * with the nonce */
	signedhash.fixed[0] = 1; signedhash.fixed[1] = 1;
	signedhash.fixed[2] = 0; signedhash.fixed[3] = 0;
	signedhash.fixed[4] = 'Q'; signedhash.fixed[5] = 'U';
	signedhash.fixed[6] = 'O'; signedhash.fixed[7] = 'T';
	memcpy(&signedhash.comphash, hash, 20);
	memcpy(&signedhash.nonce, nonce, 20);

	SHA1((char*)&signedhash, sizeof(signedhash), hash);
	/* Gives us an RSA public key from the TPM key */
	rpub = TSS_convpubkey(&k.pub);
	if (!rpub)
		errx(1, "TSS_convpubkey\n");

	if (!RSA_verify(NID_sha1, hash, 20, buf, size, rpub))
		printf("SIGNATURE FAILED\n");
	else
		printf("Signature is correct\n");

	return 0;
}
Example #3
0
int main(int argc, char *argv[])
{
    int ret;			/* general return value */
    uint32_t keyhandle = 0;	/* handle of quote key */
    unsigned int pcrmask = 0;	/* pcr register mask */
    unsigned char passhash1[TPM_HASH_SIZE];	/* hash of key password */
    unsigned char nonce[TPM_NONCE_SIZE];	/* nonce data */

    STACK_TPM_BUFFER(signature);
    pubkeydata pubkey;	/* public key structure */
    unsigned char *passptr;
    TPM_PCR_COMPOSITE tpc;
    STACK_TPM_BUFFER (ser_tpc);
    STACK_TPM_BUFFER (ser_tqi);
    STACK_TPM_BUFFER (response);
    uint32_t pcrs;
    int i;
    uint16_t sigscheme = TPM_SS_RSASSAPKCS1v15_SHA1;
    TPM_PCR_SELECTION tps;
    static char *keypass = NULL;
    const char *certFilename = NULL;
    int verbose = FALSE;
    
    TPM_setlog(0);		/* turn off verbose output from TPM driver */
    for (i=1 ; i<argc ; i++) {
	if (strcmp(argv[i],"-hk") == 0) {
	    i++;
	    if (i < argc) {
		/* convert key handle from hex */
		if (1 != sscanf(argv[i], "%x", &keyhandle)) {
		    printf("Invalid -hk argument '%s'\n",argv[i]);
		    exit(2);
		}
		if (keyhandle == 0) {
		    printf("Invalid -hk argument '%s'\n",argv[i]);
		    exit(2);
		}		 
	    }
	    else {
		printf("-hk option needs a value\n");
		printUsage();
	    }
	}
	else if (!strcmp(argv[i], "-pwdk")) {
	    i++;
	    if (i < argc) {
		keypass = argv[i];
	    }
	    else {
		printf("Missing parameter to -pwdk\n");
		printUsage();
	    }
	}
	else if (strcmp(argv[i],"-bm") == 0) {
	    i++;
	    if (i < argc) {
		/* convert key handle from hex */
		if (1 != sscanf(argv[i], "%x", &pcrmask)) {
		    printf("Invalid -bm argument '%s'\n",argv[i]);
		    exit(2);
		}
	    }
	    else {
		printf("-bm option needs a value\n");
		printUsage();
	    }
	}
	else if (!strcmp(argv[i], "-cert")) {
	    i++;
	    if (i < argc) {
		certFilename = argv[i];
	    }
	    else {
		printf("Missing parameter to -cert\n");
		printUsage();
	    }
	}
	else if (!strcmp(argv[i], "-h")) {
	    printUsage();
	}
	else if (!strcmp(argv[i], "-v")) {
	    verbose = TRUE;
	    TPM_setlog(1);
	}
	else {
	    printf("\n%s is not a valid option\n", argv[i]);
	    printUsage();
	}
    }
    if ((keyhandle == 0) ||
	(pcrmask == 0)) {
	printf("Missing argument\n");
	printUsage();
    }
    /* get the SHA1 hash of the password string for use as the Key Authorization Data */
    if (keypass != NULL) {
	TSS_sha1((unsigned char *)keypass, strlen(keypass), passhash1);
	passptr = passhash1;
    }
    else {
	passptr = NULL;
    }
    /* for testing, use the password hash as the test nonce */
    memcpy(nonce, passhash1, TPM_HASH_SIZE);
	
    ret = TPM_GetNumPCRRegisters(&pcrs);
    if (ret != 0) {
	printf("Error reading number of PCR registers.\n");
	exit(-1);
    }
    if (pcrs > TPM_NUM_PCR) {
	printf("Library does not support that many PCRs.\n");
	exit(-1);
    }
	
    tps.sizeOfSelect = pcrs / 8;
    for (i = 0; i < tps.sizeOfSelect; i++) {
	tps.pcrSelect[i] = (pcrmask & 0xff);
	pcrmask >>= 8;
    }
    /*
    ** perform the TPM Quote function
    */
    ret = TPM_Quote(keyhandle,	/* KEY handle */
		    passptr,	/* Key Password (hashed), or null */
		    nonce,	        /* nonce data */
		    &tps,	        /* specify PCR registers */
		    &tpc,		/* pointer to pcr composite */
		    &signature);/* buffer to receive result, int to receive result length */
    if (ret != 0) {
	printf("Error '%s' from TPM_Quote\n", TPM_GetErrMsg(ret));
	exit(ret);
    }
    /*
    ** Get the public key and convert to an OpenSSL RSA public key
    */
    ret = TPM_GetPubKey(keyhandle, passptr, &pubkey);
    if (ret != 0) {
	printf("quote: Error '%s' from TPM_GetPubKey\n", TPM_GetErrMsg(ret));
	exit(-6);
    }
	
    ret = TPM_ValidatePCRCompositeSignature(&tpc,
					    nonce,
					    &pubkey,
					    &signature,
					    sigscheme);
    if (ret) {
	printf("Error %s from validating the signature over the PCR composite.\n",
	       TPM_GetErrMsg(ret));
	exit(ret);
    }
    printf("Verification against AIK succeeded\n");

    /* optionally verify the quote signature against the key certificate */
    if (certFilename != NULL) {
	unsigned char *certStream = NULL;	/* freed @1 */
	uint32_t certStreamLength;
	X509 *x509Certificate = NULL;		/* freed @2 */
	unsigned char 	*tmpPtr;		/* because d2i_X509 moves the ptr */
	
	/* AIK public key parts */
	RSA *rsaKey = NULL; 			/* freed @3 */

	if (verbose) printf("quote: verifying the signature against the certificate\n");
	/* load the key certificate */
	if (ret == 0) {
	    ret = TPM_ReadFile(certFilename,
			       &certStream,	/* freed @1 */
			       &certStreamLength);
	}
	/* convert to openssl X509 */
	if (ret == 0) {
	    if (verbose) printf("quote: parsing the certificate stream\n");
	    tmpPtr = certStream;
	    x509Certificate = d2i_X509(NULL,
				       (const unsigned char **)&tmpPtr, certStreamLength);
	    if (x509Certificate == NULL) {
		printf("Error in certificate deserialization d2i_X509()\n");
		ret = -1;
	    }
	}
	if (ret == 0) {
	    if (verbose) printf("quote: get the certificate public key\n");
	    ret = GetRSAKey(&rsaKey,	/* freed @3 */
			    x509Certificate);
	}
	if (ret == 0) {
	    if (verbose) printf("quote: quote validate signature\n");
	    ret = TPM_ValidatePCRCompositeSignatureRSA(&tpc,
						       nonce,
						       rsaKey,
						       &signature,
						       sigscheme);
	    if (ret != 0) {
		printf("Verification against certificate failed\n");
	    }
	}
	if (ret == 0) {
	    printf("Verification against certificate succeeded\n");
	}
	free(certStream);		/* @1 */
	X509_free(x509Certificate); 	/* @2 */
	RSA_free(rsaKey);		/* @3 */
    }
    exit(ret);
}