/* * Validate the signature over a PCR composite structure. * Returns '0' on success, an error code otherwise. */ uint32_t TPM_ValidatePCRCompositeSignature(TPM_PCR_COMPOSITE *tpc, unsigned char *antiReplay, pubkeydata *pk, struct tpm_buffer *signature, uint16_t sigscheme) { uint32_t ret; RSA *rsa; /* openssl RSA public key */ TPM_QUOTE_INFO tqi; STACK_TPM_BUFFER (ser_tqi); STACK_TPM_BUFFER(response); STACK_TPM_BUFFER (ser_tpc); /* ** Convert to an OpenSSL RSA public key */ rsa = TSS_convpubkey(pk); ret = TPM_GetCapability(TPM_CAP_VERSION, NULL, &response); if (ret != 0) { RSA_free(rsa); return ret; } memcpy(&(tqi.version), response.buffer, response.used); memcpy(&(tqi.fixed), "QUOT", 4); memcpy(&(tqi.externalData), antiReplay, TPM_NONCE_SIZE); ret = TPM_WritePCRComposite(&ser_tpc, tpc); if ((ret & ERR_MASK)) { RSA_free(rsa); return ret; } /* create the hash of the PCR_composite data for the quoteinfo structure */ TSS_sha1(ser_tpc.buffer, ser_tpc.used, tqi.digestValue); ret = TPM_WriteQuoteInfo(&ser_tqi, &tqi); if ((ret & ERR_MASK)) { RSA_free(rsa); return ret; } ret = TPM_ValidateSignature(sigscheme, &ser_tqi, signature, rsa); RSA_free(rsa); return ret; }
int main(int argc, char *argv[]) { uint32_t startOrdinal = -1; int ret; int verbose = FALSE; TPM_COUNTER_VALUE counter; int i = 1; char * keypass = NULL; unsigned char keyAuth[TPM_HASH_SIZE]; unsigned char * keyAuthPtr = NULL; uint32_t keyhandle = -1; STACK_TPM_BUFFER(signature); unsigned char digest[TPM_DIGEST_SIZE]; unsigned char ordinalDigest[TPM_DIGEST_SIZE]; unsigned char antiReplay[TPM_NONCE_SIZE]; TPM_setlog(0); TSS_gennonce(antiReplay); while (i < argc) { if (!strcmp("-s",argv[i])) { i++; if (i < argc) { sscanf(argv[i],"%d",&startOrdinal); } else { printf("Missing parameter for -s.\n"); usage(); } } else if (!strcmp("-h",argv[i])) { i++; if (i < argc) { sscanf(argv[i],"%x",&keyhandle); } else { printf("Missing parameter for -h.\n"); usage(); } } else if (!strcmp("-p",argv[i])) { i++; if (i < argc) { keypass = argv[i]; } else { printf("Missing parameter for -p.\n"); usage(); } } else if (!strcmp("-v",argv[i])) { verbose = TRUE; TPM_setlog(1); } else { printf("\n%s is not a valid option\n", argv[i]); usage(); } i++; } (void)verbose; if (-1 == (int)startOrdinal || -1 == (int)keyhandle) { printf("Missing command line parameter.\n"); usage(); } if (NULL != keypass) { TSS_sha1(keypass,strlen(keypass),keyAuth); keyAuthPtr = keyAuth; } ret = TPM_GetAuditDigestSigned(keyhandle, FALSE, keyAuthPtr, antiReplay, &counter, digest, ordinalDigest, &signature); if (0 != ret) { printf("Error %s from GetAuditDigestSigned.\n", TPM_GetErrMsg(ret)); } else { TPM_SIGN_INFO tsi; STACK_TPM_BUFFER(tsi_ser); STACK_TPM_BUFFER(serial); STACK_TPM_BUFFER(ctr_ser); pubkeydata pubkey; RSA *rsa; i = 0; printf("AuditDigest : "); while (i < (int)sizeof(digest)) { printf("%02X",digest[i]); i++; } printf("\n"); i = 0; printf("OrdinalDigest : "); while (i < (int)sizeof(digest)) { printf("%02X",ordinalDigest[i]); i++; } printf("\n"); ret = TPM_GetPubKey(keyhandle, keyAuthPtr, &pubkey); if (ret != 0) { printf("Could not get public key of signing key.\n"); exit(-1); } rsa = TSS_convpubkey(&pubkey); if (!rsa) { printf("Could not convert public key.\n"); exit(-1); } tsi.tag = TPM_TAG_SIGNINFO; memcpy(tsi.fixed, "ADIG", 4); memcpy(tsi.replay, antiReplay, sizeof(antiReplay)); /* D4=ordinalDigest */ TPM_WriteCounterValue(&ctr_ser, &counter); memcpy(&serial.buffer[0], digest, sizeof(digest)); memcpy(&serial.buffer[sizeof(digest)], ctr_ser.buffer, ctr_ser.used); memcpy(&serial.buffer[sizeof(digest)+ctr_ser.used], ordinalDigest, sizeof(ordinalDigest)); serial.used = sizeof(digest) + ctr_ser.used + sizeof(ordinalDigest); tsi.data.size = serial.used; tsi.data.buffer = serial.buffer; ret = TPM_WriteSignInfo(&tsi_ser, &tsi); if ((ret & ERR_MASK)) { printf("Error serializing TPM_SIGN_INFO.\n"); exit(-1); } ret = TPM_ValidateSignature(TPM_SS_RSASSAPKCS1v15_SHA1, &tsi_ser, &signature, rsa); if (ret != 0) { printf("Error validating signature.\n"); exit(-1); } printf("Signature verification successful.\n"); } exit(ret); }
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 data[TPM_HASH_SIZE];/* nonce data */ STACK_TPM_BUFFER(signature); pubkeydata pubkey; /* public key structure */ RSA *rsa; /* openssl RSA public key */ unsigned char *passptr; TPM_PCR_SELECTION selection; TPM_PCR_INFO_SHORT s1; TPM_QUOTE_INFO2 quoteinfo; STACK_TPM_BUFFER( serQuoteInfo ) uint32_t pcrs; int i; uint16_t sigscheme = TPM_SS_RSASSAPKCS1v15_SHA1; TPM_BOOL addVersion = FALSE; STACK_TPM_BUFFER(versionblob); static char *keypass = NULL; 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); } } 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], "-vinfo")) { addVersion = TRUE; printf("Adding version info.\n"); } else 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(); } } if ((keyhandle == 0) || (pcrmask == 0)) { printf("Missing argument\n"); printUsage(); } memset(&s1, 0x0, sizeof(s1)); /* ** Parse and process the command line arguments */ /* 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(data,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); } memset(&selection, 0x0, sizeof(selection)); selection.sizeOfSelect = pcrs / 8; for (i = 0; i < selection.sizeOfSelect; i++) { selection.pcrSelect[i] = (pcrmask & 0xff); pcrmask >>= 8; } /* ** perform the TPM Quote function */ ret = TPM_Quote2(keyhandle, /* key handle */ &selection, /* specify PCR registers */ addVersion, /* add Version */ passptr, /* Key Password (hashed), or null */ data, /* nonce data */ &s1, /* pointer to pcr info */ &versionblob, /* pointer to TPM_CAP_VERSION_INFO */ &signature); /* buffer to receive result, int to receive result length */ if (ret != 0) { printf("Error '%s' from TPM_Quote2\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("Error '%s' from TPM_GetPubKey\n",TPM_GetErrMsg(ret)); exit(ret); } rsa = TSS_convpubkey(&pubkey); /* ** fill the quote info structure and calculate the hashes needed for verification */ quoteinfo.tag = TPM_TAG_QUOTE_INFO2; memcpy(&(quoteinfo.fixed),"QUT2",4); quoteinfo.infoShort = s1; memcpy(&(quoteinfo.externalData),data,TPM_NONCE_SIZE); unsigned char *corey_ptr = (unsigned char *)"einfo; unsigned int x; printf("quote info: \n"); for (x=0;x<128;x++) { if (x != 0 && x % 16 == 0) printf("\n"); printf("%02x ", corey_ptr[x]); } printf("\n"); /* create the hash of the quoteinfo structure for signature verification */ ret = TPM_WriteQuoteInfo2(&serQuoteInfo, "einfo); if ( ( ret & ERR_MASK ) != 0) { exit(-1); } printf("serquoteinfo: \n"); for (x=0;x<128;x++) { if (x != 0 && x % 16 == 0) printf("\n"); printf("%02x ", serQuoteInfo.buffer[x]); } printf("\n"); /* append version information if given in response */ if (addVersion) { printf("addversion is called\n"); memcpy(serQuoteInfo.buffer + serQuoteInfo.used, versionblob.buffer, versionblob.used); serQuoteInfo.used += versionblob.used; } ret = TPM_ValidateSignature(sigscheme, &serQuoteInfo, &signature, rsa); if (ret != 0) { printf("Verification failed\n"); } else { printf("Verification succeeded\n"); } RSA_free(rsa); exit(ret); }
int main(int argc, char *argv[]) { int ret; struct stat sbuf; unsigned char databuff[65535]; /* data read work buffer */ unsigned char datahash[20]; /* hash of data file */ unsigned char digest[20]; SHA_CTX sha; FILE *datafile; const char *datafilename = NULL; FILE *sigfile; const char *sigfilename = NULL; FILE *keyfile; const char *kfilename = NULL; EVP_PKEY *pkey; RSA *rsa; uint16_t sigscheme = TPM_SS_RSASSAPKCS1v15_SHA1; int plain; unsigned char padded[4096]; unsigned char plainarray[4096]; TPM_SIGN_INFO tsi; STACK_TPM_BUFFER(tsi_ser); STACK_TPM_BUFFER(signature); int i; for (i=1 ; i<argc ; i++) { if (!strcmp(argv[i], "-ss")) { i++; if (i < argc) { if (!strcmp(argv[i], "info")) { sigscheme = TPM_SS_RSASSAPKCS1v15_INFO; } else if (!strcmp(argv[i], "der")) { sigscheme = TPM_SS_RSASSAPKCS1v15_DER; } else { printf("Bad parameter for -ss\n"); printUsage(); } } else { printf("Missing parameter for -ss\n"); printUsage(); } } else if (strcmp(argv[i],"-if") == 0) { i++; if (i < argc) { datafilename = argv[i]; } else { printf("-if option needs a value\n"); printUsage(); exit(2); } } else if (strcmp(argv[i],"-is") == 0) { i++; if (i < argc) { sigfilename = argv[i]; } else { printf("-is option needs a value\n"); printUsage(); } } else if (strcmp(argv[i],"-ik") == 0) { i++; if (i < argc) { kfilename = argv[i]; } else { printf("-ik option needs a value\n"); printUsage(); exit(2); } } else 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(); } } if ((datafilename == NULL) || (sigfilename == NULL) || (kfilename == NULL)) { printf("Missing parameter\n"); printUsage(); } /* ** read and hash the data file */ datafile = fopen(datafilename,"rb"); if (datafile == NULL) { printf("Unable to open data file '%s'\n",datafilename); exit(2); } SHA1_Init(&sha); for (;;) { ret = fread(databuff,1,sizeof databuff,datafile); if (ret < 0) { printf("I/O Error while reading data file '%s'\n",datafilename); exit(3); } SHA1_Update(&sha,databuff,ret); if (ret < (int)sizeof(databuff)) break; } fclose(datafile); SHA1_Final(datahash,&sha); /* ** get size of signature file */ stat(sigfilename,&sbuf); signature.used = (int)sbuf.st_size; sigfile = fopen(sigfilename,"rb"); if (sigfile == NULL) { printf("Unable to open signature file '%s'\n",sigfilename); exit(4); } /* ** read the signature file */ ret = fread(signature.buffer,1,signature.used,sigfile); if (ret != (int)signature.used) { printf("I/O Error while reading signature file '%s'\n",sigfilename); exit(5); } fclose(sigfile); /* ** read the key file */ keyfile = fopen(kfilename,"rb"); if (keyfile == NULL) { printf("Unable to open public key file '%s'\n",kfilename); exit(6); } pkey = PEM_read_PUBKEY(keyfile,NULL,NULL,NULL); if (pkey == NULL) { printf("I/O Error while reading public key file '%s'\n",kfilename); exit(7); } rsa = EVP_PKEY_get1_RSA(pkey); if (rsa == NULL) { printf("Error while converting public key \n"); exit(8); } switch (sigscheme) { default: case TPM_SS_RSASSAPKCS1v15_SHA1: ret = RSA_verify(NID_sha1,datahash,20, signature.buffer,signature.used, rsa); if (ret != 1) { printf("Verification Failed\n"); exit(100); } break; case TPM_SS_RSASSAPKCS1v15_DER: plain = RSA_public_decrypt(signature.used, signature.buffer, plainarray, rsa, RSA_NO_PADDING); if (plain == -1) { printf("Verification (DER) had an error\n"); exit(100); } ret = RSA_padding_add_PKCS1_type_1(padded,plain,datahash,sizeof(datahash)); if (ret != 1) { printf("Could not add the padding.\n"); exit(100); } if (memcmp(padded, plainarray, plain) != 0) { printf("Verfication (DER) failed.\n"); exit(100); } break; case TPM_SS_RSASSAPKCS1v15_INFO: // the nonce is the digest of the hashed data!! TSS_sha1(datahash, 20, digest); tsi.tag = TPM_TAG_SIGNINFO; memcpy(tsi.fixed,"SIGN",4); tsi.data.size = TPM_HASH_SIZE; tsi.data.buffer = datahash; memcpy(tsi.replay, digest, TPM_HASH_SIZE); /* need to calcualte the digest of the TPM_SIGN_INFO structure */ ret = TPM_WriteSignInfo(&tsi_ser, &tsi); if ((ret & ERR_MASK)) { printf("Could not serialize TPM_SIGN_INFO structure.\n"); exit(100); } ret = TPM_ValidateSignature(sigscheme, &tsi_ser, &signature, rsa); if (ret != 0) { printf("Verification (INFO) failed.\n"); exit(-1); } break; } RSA_free(rsa); EVP_PKEY_free(pkey); exit(0); }