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; }
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; }
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); }