uint32_t TPM_ReadKeyfile(const char *filename, keydata * k) { unsigned char *buffer = NULL; uint32_t buffersize = 0; uint32_t ret = TPM_ReadFile(filename, &buffer, &buffersize); if ((ret & ERR_MASK) == 0) { STACK_TPM_BUFFER(buf); SET_TPM_BUFFER(&buf, buffer, buffersize); memset(k, 0x0, sizeof(*k)); if (buffersize != TSS_KeyExtract(&buf, 0, k)) ret = ERR_BAD_FILE; free(buffer); } return ret; }
static int loadKey(char * filename, keydata * key) { int ret = 0; FILE * kinfile; kinfile = fopen(filename,"rb"); if (kinfile == NULL) { printf("Could not open key file.\n"); ret = -1; } else { struct stat sbuf; if (0 ==stat(filename,&sbuf)) { unsigned int keyblen; unsigned char * keyblob = NULL; keyblen = (int)sbuf.st_size; keyblob = malloc(keyblen); if (NULL != keyblob) { ret = fread(keyblob,1,keyblen,kinfile); if (ret != (int)keyblen) { printf("Unable to read key file\n"); ret = -1; } else { STACK_TPM_BUFFER(tb) SET_TPM_BUFFER(&tb, keyblob, keyblen); TSS_KeyExtract(&tb,0,key); ret = 0; } fclose(kinfile); free(keyblob); } else { printf("Could not allocate memory.\n"); ret = -1; } } else { printf("Could not determine size of key file.\n"); ret = -1; } } return ret; }
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; }
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; struct stat sbuf; unsigned char keyblob[4096]; unsigned int keyblen; unsigned char outblob[4096]; unsigned int outblen; unsigned int handle; unsigned char filename[256]; unsigned char filename2[256]; unsigned char parphash[20]; unsigned char newphash[20]; unsigned char keyphash[20]; unsigned char *passptr1; FILE *outfile; FILE *ainfile; keydata key; unsigned char *keypass; unsigned char *newpass; unsigned char *keyname; unsigned char *parhndl; int nxtarg; nxtarg = ParseArgs(argc, argv); if (argc < (nxtarg + 4)) usage(); TPM_setlog(0); parhndl = argv[nxtarg + 0]; keyname = argv[nxtarg + 1]; keypass = argv[nxtarg + 2]; newpass = argv[nxtarg + 3]; /* ** convert parent key handle from hex */ ret = sscanf(parhndl, "%x", &handle); if (ret != 1) { fprintf(stderr, "Invalid argument '%s'\n", parhndl); exit(2); } /* * use SHA1 hash of password string as Parent Key Authorization */ if (parpass != NULL) { TSS_sha1(parpass, strlen(parpass), parphash); passptr1 = parphash; } else passptr1 = NULL; /* ** use SHA1 hash of password string as Key Authorization Data */ TSS_sha1(keypass, strlen(keypass), keyphash); /* ** use SHA1 hash of password string as New Authorization Data */ TSS_sha1(newpass, strlen(newpass), newphash); /* ** read the key blob */ ainfile = fopen(keyname, "r"); if (ainfile == NULL) { fprintf(stderr, "Unable to open key file\n"); exit(3); } stat(keyname, &sbuf); keyblen = (int) sbuf.st_size; ret = fread(keyblob, 1, keyblen, ainfile); if (ret != keyblen) { fprintf(stderr, "Unable to read key file\n"); exit(4); } fclose(ainfile); TSS_KeyExtract(keyblob, &key); ret = TPM_ChangeAuth(handle, passptr1, keyphash, newphash, &key); if (ret != 0) { fprintf(stderr, "Error %s from TPM_ChangeAuth\n", TPM_GetErrMsg(ret)); exit(5); } ret = TPM_BuildKey(outblob, &key); if ((ret & ERR_MASK) != 0) return ret; outblen = ret; sprintf(filename2, "%s.save", keyname); sprintf(filename, "%s", keyname); ret = rename(filename, filename2); if (ret != 0) { fprintf(stderr, "Unable to rename old key file\n"); exit(6); } outfile = fopen(filename, "w"); if (outfile == NULL) { fprintf(stderr, "Unable to create new key file\n"); exit(7); } ret = fwrite(outblob, 1, outblen, outfile); if (ret != outblen) { fprintf(stderr, "Unable to write new key file\n"); exit(8); } fclose(outfile); exit(0); }
uint32_t TPM_TakeOwnership(unsigned char *ownpass, unsigned char *srkpass, keydata * key) { unsigned char take_owner_fmt[] = "00 c2 T l s @ @ % l % 00 %"; /* required OAEP padding P parameter */ unsigned char tpm_oaep_pad_str[] = { 'T', 'C', 'P', 'A' }; uint32_t ret; int iret; unsigned char tpmdata[TPM_MAX_BUFF_SIZE]; pubkeydata tpmpubkey; /* public endorsement key data */ uint32_t srkparamsize; /* SRK parameter buffer size */ unsigned char nonceeven[TPM_HASH_SIZE]; /* even nonce (from OIAPopen) */ RSA *pubkey; /* PubEK converted to OpenSSL format */ unsigned char padded[RSA_MODULUS_BYTE_SIZE]; keydata srk; /* key info for SRK */ unsigned char dummypass[TPM_HASH_SIZE]; /* dummy srk password */ unsigned char *spass; /* pointer to srkpass or dummy */ unsigned int i; /* data to be inserted into Take Owner Request Buffer */ /* the uint32_t and uint16_t values are stored in network byte order */ uint32_t command; /* command ordinal */ uint16_t protocol; /* protocol ID */ uint32_t oencdatasize; /* owner auth data encrypted size */ unsigned char ownerencr[RSA_MODULUS_BYTE_SIZE]; uint32_t sencdatasize; /* srk auth data encrypted size */ unsigned char srkencr[RSA_MODULUS_BYTE_SIZE]; unsigned char srk_param_buff[TPM_SRK_PARAM_BUFF_SIZE]; uint32_t authhandle; /* auth handle (from OIAPopen) */ unsigned char nonceodd[TPM_HASH_SIZE]; /* odd nonce */ unsigned char authdata[TPM_HASH_SIZE]; /* auth data */ /* check that parameters are valid */ if (ownpass == NULL) return ERR_NULL_ARG; if (srkpass == NULL) { memset(dummypass, 0, sizeof dummypass); spass = dummypass; } else spass = srkpass; /* set up command and protocol values for TakeOwnership function */ command = htonl(0x0d); protocol = htons(0x05); /* get the TPM Endorsement Public Key */ ret = TPM_ReadPubek(&tpmpubkey); if (ret) return ret; /* convert the public key to OpenSSL format */ pubkey = TSS_convpubkey(&tpmpubkey); if (pubkey == NULL) return ERR_CRYPT_ERR; memset(ownerencr, 0, sizeof ownerencr); memset(srkencr, 0, sizeof srkencr); /* Pad and then encrypt the owner data using the RSA public key */ iret = RSA_padding_add_PKCS1_OAEP(padded, RSA_MODULUS_BYTE_SIZE, ownpass, TPM_HASH_SIZE, tpm_oaep_pad_str, sizeof tpm_oaep_pad_str); if (iret == 0) return ERR_CRYPT_ERR; iret = RSA_public_encrypt(RSA_MODULUS_BYTE_SIZE, padded, ownerencr, pubkey, RSA_NO_PADDING); if (iret < 0) return ERR_CRYPT_ERR; oencdatasize = htonl(iret); /* Pad and then encrypt the SRK data using the RSA public key */ iret = RSA_padding_add_PKCS1_OAEP(padded, RSA_MODULUS_BYTE_SIZE, spass, TPM_HASH_SIZE, tpm_oaep_pad_str, sizeof tpm_oaep_pad_str); if (iret == 0) return ERR_CRYPT_ERR; iret = RSA_public_encrypt(RSA_MODULUS_BYTE_SIZE, padded, srkencr, pubkey, RSA_NO_PADDING); if (iret < 0) return ERR_CRYPT_ERR; sencdatasize = htonl(iret); RSA_free(pubkey); if (ntohl(oencdatasize) < 0) return ERR_CRYPT_ERR; if (ntohl(sencdatasize) < 0) return ERR_CRYPT_ERR; /* fill the SRK-params key structure */ /* get tpm version */ ret = TPM_GetCapability(0x00000006, NULL, 0, &(srk.version[0]), &i); if (ret != 0) return ret; srk.keyusage = 0x0011; /* Storage Key */ srk.keyflags = 0; if (srkpass != NULL) srk.authdatausage = 0x01; else srk.authdatausage = 0x00; srk.privkeylen = 0; /* private key not specified here */ srk.pub.algorithm = 0x00000001; /* RSA */ srk.pub.encscheme = 0x0003; /* RSA OAEP SHA1 MGF1 */ srk.pub.sigscheme = 0x0001; /* NONE */ srk.pub.keybitlen = RSA_MODULUS_BIT_SIZE; srk.pub.numprimes = 2; srk.pub.expsize = 0; /* defaults to 0x010001 */ srk.pub.keylength = 0; /* not used here */ srk.pub.pcrinfolen = 0; /* not used here */ /* convert to a memory buffer */ srkparamsize = TPM_BuildKey(srk_param_buff, &srk); /* generate the odd nonce */ ret = TSS_gennonce(nonceodd); if (ret == 0) return ret; /* initiate the OIAP protocol */ ret = TSS_OIAPopen(&authhandle, nonceeven); if (ret != 0) return ret; /* calculate the Authorization Data */ ret = TSS_authhmac(authdata, ownpass, TPM_HASH_SIZE, nonceeven, nonceodd, 0, TPM_U32_SIZE, &command, TPM_U16_SIZE, &protocol, TPM_U32_SIZE, &oencdatasize, ntohl(oencdatasize), ownerencr, TPM_U32_SIZE, &sencdatasize, ntohl(sencdatasize), srkencr, srkparamsize, srk_param_buff, 0, 0); if (ret != 0) { TSS_OIAPclose(authhandle); return ret; } /* insert all the calculated fields into the request buffer */ ret = TSS_buildbuff(take_owner_fmt, tpmdata, command, protocol, ntohl(oencdatasize), ownerencr, ntohl(sencdatasize), srkencr, srkparamsize, srk_param_buff, authhandle, TPM_HASH_SIZE, nonceodd, TPM_HASH_SIZE, authdata); 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, "Take Ownership"); TSS_OIAPclose(authhandle); if (ret != 0) return ret; /* check the response HMAC */ srkparamsize = TSS_KeySize(tpmdata + TPM_DATA_OFFSET); ret = TSS_checkhmac1(tpmdata, command, nonceodd, ownpass, TPM_HASH_SIZE, srkparamsize, TPM_DATA_OFFSET, 0, 0); if (ret != 0) return ret; /* convert the returned key to a structure */ if (key == NULL) return 0; TSS_KeyExtract(tpmdata + TPM_DATA_OFFSET, key); return 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; }
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; }