PageRenderTime 25ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/src/tpm_mgmt/tpm_createek.c

https://github.com/srajiv/tpm-tools
C | 281 lines | 218 code | 35 blank | 28 comment | 44 complexity | 061b2e9fa3d691ff58f9fb5732496c02 MD5 | raw file
  1. /*
  2. * The Initial Developer of the Original Code is International
  3. * Business Machines Corporation. Portions created by IBM
  4. * Corporation are Copyright (C) 2005 International Business
  5. * Machines Corporation. All Rights Reserved.
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the Common Public License as published by
  9. * IBM Corporation; either version 1 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * Common Public License for more details.
  16. *
  17. * You should have received a copy of the Common Public License
  18. * along with this program; if not, a copy can be viewed at
  19. * http://www.opensource.org/licenses/cpl1.0.php.
  20. */
  21. #include "tpm_tspi.h"
  22. #include "tpm_utils.h"
  23. TSS_HCONTEXT hContext = 0;
  24. #ifdef TSS_LIB_IS_12
  25. #include <limits.h>
  26. //Controled by input options
  27. static char in_filename[PATH_MAX] = "", out_filename[PATH_MAX] = "";
  28. static BOOL isRevocable = FALSE;
  29. static BOOL needGenerateSecret = FALSE;
  30. static BOOL inFileSet = FALSE;
  31. static BOOL outFileSet = FALSE;
  32. static void help(const char *aCmd)
  33. {
  34. logCmdHelp(aCmd);
  35. logCmdOption("-r, --revocable",
  36. _("Creates a revocable EK instead of the default non-revocable one. Requires [-g -o] or [-i]"));
  37. logCmdOption("-i, --infile FILE",
  38. _("Filename containing the secret data used to revoke the EK."));
  39. logCmdOption("-g, --generate-secret",
  40. _("Generates a 20 Bytes secret that is used to revoke the EK. Requires [-o]"));
  41. logCmdOption("-o, --outfile FILE",
  42. _("Filename to write the secret data generated to revoke the EK."));
  43. }
  44. static int parse(const int aOpt, const char *aArg)
  45. {
  46. switch (aOpt){
  47. case 'r':
  48. isRevocable = TRUE;
  49. break;
  50. case 'g':
  51. needGenerateSecret = TRUE;
  52. break;
  53. case 'i':
  54. inFileSet = TRUE;
  55. if (aArg){
  56. strncpy(in_filename, aArg, PATH_MAX);
  57. }
  58. break;
  59. case 'o':
  60. outFileSet = TRUE;
  61. if (aArg){
  62. strncpy(out_filename, aArg, PATH_MAX);
  63. }
  64. break;
  65. default:
  66. return -1;
  67. }
  68. return 0;
  69. }
  70. static TSS_RESULT
  71. tpmCreateRevEk(TSS_HTPM a_hTpm, TSS_HKEY a_hKey,
  72. TSS_VALIDATION * a_pValData, UINT32 *revDataSz, BYTE **revData)
  73. {
  74. TSS_RESULT result = Tspi_TPM_CreateRevocableEndorsementKey(a_hTpm, a_hKey,
  75. a_pValData, revDataSz, revData);
  76. tspiResult("Tspi_TPM_CreateRevocableEndorsementKey", result);
  77. return result;
  78. }
  79. static int readData(UINT32 bytesToRead, BYTE **buffer)
  80. {
  81. FILE *infile = NULL;
  82. size_t iBytes;
  83. int rc = 0;
  84. BYTE eofile;
  85. memset(*buffer, 0x00, bytesToRead);
  86. infile = fopen(in_filename, "r");
  87. if ( !infile ){
  88. logError(_("Unable to open input file: %s\n"),
  89. in_filename);
  90. return -1;
  91. }
  92. //Read the data
  93. iBytes = fread( *buffer, 1, bytesToRead, infile );
  94. if ( iBytes < bytesToRead ) {
  95. logError(_("Error: the secret data file %s contains less than %d bytes. Aborting ...\n"),
  96. in_filename, bytesToRead);
  97. rc = -1;
  98. } else if ( (iBytes = fread( &eofile, 1, 1, infile )) ) {
  99. //Test if there's more than 20 bytes
  100. if ( !feof( infile))
  101. logMsg(_("WARNING: Using only the first %d bytes of file %s for secret data\n"),
  102. bytesToRead, in_filename);
  103. } else {
  104. logDebug(_("Read %d bytes of secret data from file %s.\n"),
  105. bytesToRead, in_filename);
  106. }
  107. fclose( infile);
  108. return rc;
  109. }
  110. static int writeData(UINT32 bytesToWrite, BYTE *buffer)
  111. {
  112. FILE *outfile = NULL;
  113. size_t iBytes;
  114. int rc = 0;
  115. logDebug(_("bytesToWrite: %d\n"), bytesToWrite);
  116. outfile = fopen(out_filename, "w");
  117. if ( !outfile ) {
  118. logError(_("Unable to open output file: %s\n"), out_filename);
  119. return -1;
  120. }
  121. //Write data in buffer
  122. iBytes = fwrite( buffer, 1, bytesToWrite, outfile);
  123. if ( iBytes != bytesToWrite ) {
  124. logError(_("Error: Unable to write %d bytes on the file %s.\n"),
  125. bytesToWrite, out_filename);
  126. rc = -1;
  127. }
  128. logDebug(_("%zd bytes written on file %s.\n"), iBytes, out_filename);
  129. fclose( outfile );
  130. return rc;
  131. }
  132. #endif
  133. static TSS_RESULT
  134. tpmCreateEk(TSS_HTPM a_hTpm, TSS_HKEY a_hKey,
  135. TSS_VALIDATION * a_pValData)
  136. {
  137. TSS_RESULT result = Tspi_TPM_CreateEndorsementKey(a_hTpm, a_hKey,
  138. a_pValData);
  139. tspiResult("Tspi_TPM_CreateEndorsementKey", result);
  140. return result;
  141. }
  142. int main(int argc, char **argv)
  143. {
  144. TSS_RESULT tResult;
  145. TSS_HTPM hTpm;
  146. TSS_HKEY hEk;
  147. TSS_FLAG fEkAttrs;
  148. int iRc = -1;
  149. #ifdef TSS_LIB_IS_12
  150. struct option opts[] = {{"revocable", no_argument, NULL, 'r'},
  151. {"generate-secret", no_argument, NULL, 'g'},
  152. {"infile", required_argument, NULL, 'i'},
  153. {"outfile", required_argument, NULL, 'o'},
  154. };
  155. UINT32 revDataSz;
  156. BYTE revokeData[TPM_SHA1BASED_NONCE_LEN];
  157. BYTE *pRevData;
  158. #endif
  159. initIntlSys();
  160. #ifdef TSS_LIB_IS_12
  161. if (genericOptHandler(argc, argv, "rgi:o:", opts, sizeof(opts) / sizeof(struct option),
  162. parse, help) != 0)
  163. goto out;
  164. //Check commands for command hierarchy
  165. if (isRevocable) {
  166. if (needGenerateSecret) {
  167. if (!outFileSet) {
  168. logError(_("Please specify an output file\n"));
  169. goto out;
  170. }
  171. if (inFileSet) {
  172. logError(_("The option -i, --infile is not valid with -g\n"));
  173. goto out;
  174. }
  175. } else if (!inFileSet) {
  176. logError(_("Please specify -i, --infile or -g, --generate-secret\n"));
  177. goto out;
  178. } else if (outFileSet) {
  179. logError(_("The option -o, --outfile is not valid with -i, --infile"));
  180. goto out;
  181. }
  182. }
  183. logDebug("Input file name: %s\n", in_filename);
  184. logDebug("Output file name: %s\n", out_filename);
  185. if (inFileSet) {
  186. pRevData = revokeData;
  187. revDataSz = sizeof(revokeData);
  188. if (readData(revDataSz, &pRevData))
  189. goto out;
  190. } else if (outFileSet) {
  191. FILE *outfile = fopen(out_filename, "w");
  192. if (!outfile) {
  193. iRc = -1;
  194. logError(_("Unable to open output file: %s\n"), out_filename);
  195. goto out;
  196. }
  197. fclose(outfile);
  198. //TPM should generate the revoke data
  199. revDataSz = 0;
  200. pRevData = NULL;
  201. }
  202. #else
  203. if (genericOptHandler(argc, argv, NULL, NULL, 0, NULL, NULL) != 0){
  204. logError(_("See man pages for details.\n"));
  205. goto out;
  206. }
  207. #endif
  208. if (contextCreate(&hContext) != TSS_SUCCESS)
  209. goto out;
  210. if (contextConnect(hContext) != TSS_SUCCESS)
  211. goto out_close;
  212. if (contextGetTpm(hContext, &hTpm) != TSS_SUCCESS)
  213. goto out_close;
  214. //Initialize EK attributes here
  215. fEkAttrs = TSS_KEY_SIZE_2048 | TSS_KEY_TYPE_LEGACY;
  216. if (contextCreateObject(hContext, TSS_OBJECT_TYPE_RSAKEY, fEkAttrs, &hEk) != TSS_SUCCESS)
  217. goto out_close;
  218. #ifdef TSS_LIB_IS_12
  219. if (isRevocable){
  220. tResult = tpmCreateRevEk(hTpm, hEk, NULL, &revDataSz, &pRevData);
  221. if (tResult != TSS_SUCCESS)
  222. goto out_close;
  223. //Writes the generated secret into the output file
  224. if (outFileSet) {
  225. if (writeData(revDataSz, pRevData)) {
  226. logError(_("Creating revocable EK succeeded, but writing the EK "
  227. "revoke authorization to disk failed.\nPrinting the "
  228. "revoke authorization instead:\n"));
  229. logHex(revDataSz, pRevData);
  230. logError(_("You should record this data, as its the authorization "
  231. "you'll need to revoke your EK!\n"));
  232. goto out_close;
  233. }
  234. }
  235. } else
  236. #endif
  237. tResult = tpmCreateEk(hTpm, hEk, NULL);
  238. if (tResult != TSS_SUCCESS)
  239. goto out_close;
  240. iRc = 0;
  241. logSuccess(argv[0]);
  242. out_close:
  243. contextClose(hContext);
  244. out:
  245. return iRc;
  246. }