Chinaunix首页 | 论坛 | 博客
  • 博客访问: 273905
  • 博文数量: 18
  • 博客积分: 787
  • 博客等级: 军士长
  • 技术积分: 235
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-27 21:20
文章分类

全部博文(18)

文章存档

2015年(2)

2013年(2)

2012年(7)

2011年(1)

2010年(6)

分类: LINUX

2012-02-16 14:39:52

最近更新时间:2012/6/14 10:24

参考书籍《可信计算》(A Practical Guide of Trusted Computing, 机械工业出版社)。
详细讲解书中 第八章--使用TPM密钥 的示例,因为openssl的开发库变动,所以使用不同的openssl API不保证成功,书中代码有一些不能直接调试通过,我对无法通过的部分做了改动,下面部分经测试无误,但仍然不完整,仅进行到创建AIK这一步,创建AIK的过程可能会另开一篇博文。
另需要注意的是,由于我的openssl-tpm-engine无法安装成功,所以关于openssl我使用了一些内嵌的函数实现,而非直接使用openssl-tpm-engine的API,下面是代码部分:

MyFunc_KeyHierarchy.c:

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <errno.h>
  4. #include <tss/platform.h>
  5. #include <tss/tss_typedef.h>
  6. #include <tss/tss_structs.h>
  7. #include <tss/tss_defines.h>
  8. #include <tss/tspi.h>
  9. #include <openssl/rsa.h>
  10. #include <openssl/err.h>
  11. #include <openssl/ssl.h>


  12. //下面三个参数在书中都没有定义,此处为我本人主动定义
  13. #define ENTROPY_SIZE 10
  14. #define MAX_PASS_LEN 4097
  15. #define RANDOM_DEVICE "/dev/random"
  16. #define SOFTWARE_KEY_FILE_PATH "/home/darcy/exercise/TPM/test.key"
  17. #define CA_KEY_FILE_PATH "/home/darcy/exercise/TPM/test1.key"

  18. TSS_HCONTEXT hContext;
  19. TSS_HKEY hSRK;
  20. TSS_HTPM hTPM;

  21. //获取错误信息,工具函数
  22. const char *get_error(TSS_RESULT res)
  23. {
  24.     switch(ERROR_CODE(res))
  25.     {
  26.         case 0x0001L:
  27.             return "Authentication failed";
  28.         case TSS_SUCCESS:
  29.             return "success";
  30.         case TSS_E_INVALID_HANDLE:
  31.             return "hContext or phObject is an invalid handle";
  32.         case TSS_E_BAD_PARAMETER:
  33.             return "persistent storage type is not valid/One or more parameters is incorrect";
  34.         case TSS_E_INTERNAL_ERROR:
  35.             return "an error occurred internal to the TSS";
  36.         case TSS_E_PS_KEY_NOTFOUND:
  37.             return "NOT FOUND SRK";
  38.         case TSS_E_INVALID_ATTRIB_FLAG:
  39.             return "attrib flag is incorrect";
  40.         case TSS_E_INVALID_ATTRIB_SUBFLAG:
  41.             return "subflag is incorrect";
  42.         case TSS_E_INVALID_ATTRIB_DATA:
  43.             return "ulAttrib is incorrect";
  44.         case TSS_E_KEY_ALREADY_REGISTERED:
  45.             return "UUID used";
  46.         case TSS_E_KEY_NOT_LOADED:
  47.             return "the addressed key is currently not loaded";
  48.         default:
  49.             return "unknown error";
  50.     }
  51. }

  52. //判断操作是否成功
  53. void
  54. Assert(TSS_RESULT result, char *functionName)
  55. {
  56.     if(result != TSS_SUCCESS)
  57.     {
  58.         printf("%s Error: %s\n", functionName, get_error(result));
  59.         exit(1);
  60.     }
  61. }

  62. //计算size,返回密钥大小
  63. TSS_FLAG
  64. get_tss_key_size(UINT32 size)
  65. {
  66.     if(size <= 512){
  67.         return TSS_KEY_SIZE_512;
  68.     }else if(size <= 1024){
  69.         return TSS_KEY_SIZE_1024;
  70.     }else if(size <= 2048){
  71.         return TSS_KEY_SIZE_2048;
  72.     }else if(size <= 4096){
  73.         return TSS_KEY_SIZE_4096;
  74.     }else if(size <= 8192){
  75.         return TSS_KEY_SIZE_8192;
  76.     }else if(size <= 16384){
  77.         return TSS_KEY_SIZE_16384;
  78.     }

  79.     return TSS_KEY_SIZE_2048;
  80. }

  81. void
  82. openssl_print_errors()
  83. {
  84.     ERR_load_ERR_strings();
  85.     ERR_load_crypto_strings();
  86.     ERR_print_errors_fp(stderr);
  87. }

  88. RSA *
  89. openssl_read_key(char *filename)
  90. {
  91.         BIO *b = NULL;
  92.         RSA *rsa = NULL;

  93.         b = BIO_new_file(filename, "r");
  94.         if (b == NULL) {
  95.                 fprintf(stderr, "Error opening file for read: %s\n", filename);
  96.                 return NULL;
  97.         }

  98.         if ((rsa = PEM_read_bio_RSAPrivateKey(b, NULL, 0, NULL)) == NULL) {
  99.                 fprintf(stderr, "Reading key %s from disk failed.\n", filename);
  100.                 openssl_print_errors();
  101.         }
  102.         BIO_free(b);

  103.         return rsa;
  104. }

  105. int
  106. openssl_get_modulus_and_prime(RSA *rsa, unsigned int *size_n, unsigned char *n,
  107.                   unsigned int *size_p, unsigned char *p)
  108. {
  109.     /* get the modulus from the RSA object */
  110.     if ((*size_n = BN_bn2bin(rsa->n, n)) <= 0) {
  111.         openssl_print_errors();
  112.         return -1;
  113.     }
  114.     /* get one of the primes from the RSA object */
  115.     if ((*size_p = BN_bn2bin(rsa->p, p)) <= 0) {
  116.         openssl_print_errors();
  117.         return -1;
  118.     }

  119.     return 0;
  120. }

  121. //获取系统随机数函数
  122. TSS_RESULT
  123. MyFunc_GetRandom(UINT32 size, BYTE *data)
  124. {
  125.     FILE *f = NULL;
  126.     f = fopen(RANDOM_DEVICE, "r");
  127.     if (f == NULL) {
  128.         //书中采用了LogError函数,此处我直接使用printf
  129.         printf("open of %s failed: %s", RANDOM_DEVICE,
  130.         strerror(errno));
  131.         return TSS_E_INTERNAL_ERROR;
  132.     }
  133.     if (fread(data, size, 1, f) == 0) {
  134.         printf("fread of %s failed: %s", RANDOM_DEVICE,
  135.         strerror(errno));
  136.         fclose(f);
  137.         return TSS_E_INTERNAL_ERROR;
  138.     }
  139.     fclose(f);
  140.     return TSS_SUCCESS;
  141. }

  142. TSS_RESULT
  143. MyFunc_CreateTPMKey(TSS_HKEY hParentKey,
  144.                     TSS_FLAG initFlags,
  145.                     TSS_HPCRS hPcrs,
  146.                     TSS_HKEY *hKey)
  147. {
  148.     TSS_RESULT result;
  149.     TSS_HPOLICY hPolicy;
  150.     char *secret = "test";
  151.     /* create the key object */
  152.     result = Tspi_Context_CreateObject(hContext,TSS_OBJECT_TYPE_RSAKEY,
  153.                                         initFlags, hKey);
  154.     if (result) {
  155.         printf("Tspi_Context_CreateObject failed: %s\n",
  156.                 get_error(result));
  157.         return result;
  158.     }
  159.     /* Get the policy object, implicitly created when we created the
  160.      * key object */
  161.     result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_POLICY,TSS_POLICY_USAGE, &hPolicy);
  162.     if (result) {
  163.         printf("Tspi_GetPolicyObject failed: %s\n", get_error(result));
  164.         Tspi_Context_CloseObject(hContext, *hKey);
  165.         return result;
  166.     }
  167.     /* If we’re creating this key with no password, set the secret
  168.     * mode so that the popup will be supressed */
  169.     if (!(initFlags & TSS_KEY_AUTHORIZATION)) {
  170.         result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_NONE,
  171.                                         0, NULL);
  172.         if(result)
  173.         {
  174.             printf("Tspi_Policy_SetSecret error: %s\n", get_error(result));
  175.         }
  176.     }
  177.     /* Make the call to the TPM to create the key */
  178.     result = Tspi_Key_CreateKey(*hKey, hParentKey, hPcrs);
  179.     if (result) {
  180.         printf("Tspi_Key_CreateKey failed: %s\n", get_error(result));
  181.         Tspi_Context_CloseObject(hContext, *hKey);
  182.         return result;
  183.     }
  184.     
  185.     if(result == TSS_SUCCESS)
  186.     {
  187.         printf("Create TPM key succeed!\n");
  188.     }

  189.     return TSS_SUCCESS;
  190. }


  191. TSS_RESULT
  192. MyFunc_WrapKey(char *path,
  193.                 TSS_HKEY hParentKey,
  194.                 TSS_FLAG initFlags,
  195.                 TSS_HPCRS hPcrs,
  196.                 TSS_HKEY *hKey)
  197. {

  198.     RSA *rsa;
  199.     UINT32 pubKeyLen;
  200.     BYTE *pubKey;
  201.     TSS_RESULT result;
  202.     unsigned char n[2048], p[2048];
  203.     int sizeN, sizeP;
  204.     UINT32 keySize;
  205.     TSS_HPOLICY keyMigPolicy;
  206.     /* Read in the plaintext key from disk. */
  207.     if ((rsa = openssl_read_key(path)) == NULL) {
  208.         printf("Failed opening OpenSSL key file!\n");
  209.         return TSS_E_FAIL;
  210.     }

  211.     /* Pull the SRK’s pub key into the hSRK object. Note that this is
  212.     * not necessary for any key but the SRK. The SRK’s pub key is not
  213.     * stored in system persistent storage as other keys are. This
  214.     * protects it from being loaded by unauthorized users who could
  215.     * then use it to identify the machine from across the Internet. */
  216.     //result = Tspi_Key_GetPubKey(hSRK, &pubKeyLen, &pubKey);
  217.     result = Tspi_TPM_OwnerGetSRKPubKey(hTPM, &pubKeyLen, &pubKey);
  218.     if (result != TSS_SUCCESS) {
  219.         printf("Tspi_Key_GetPubKey failed: %s\n", get_error(result));
  220.         RSA_free(rsa);
  221.         printf("Error code:%d!\n", result);
  222.         return result;
  223.     }
  224.     /* Free here since the pubKey data is stored internally to the
  225.     * hSRK object in addition to being returned above */
  226.     //Tspi_Context_FreeMemory(hContext, pubKey);
  227.     /* convert the OpenSSL key’s size in bits to a TSS key size flag
  228.     * suitable for including in initFlags. */
  229.     if ((keySize = get_tss_key_size(RSA_size(rsa) * 8)) == 0){
  230.         return TSS_E_BAD_PARAMETER;
  231.     }
  232.     /* create the TSS key object */
  233.     /*TSS_FLAG tempFlag = TSS_KEY_SIZE_2048|
  234.                               TSS_KEY_TYPE_STORAGE|
  235.                               TSS_KEY_AUTHORIZATION;*/
  236.     result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_RSAKEY,
  237.                                         keySize|initFlags, hKey);

  238.     if (result != TSS_SUCCESS) {
  239.         printf("Tspi_Context_CreateObject failed: %s\n",
  240.                 get_error(result));
  241.         return result;
  242.     }
  243.     /*if This function handles the OpenSSL calls to extract the public N
  244.     * and private P, parts of the software RSA key. Both of these
  245.     * components will be put into the wrapped TSS key object. */
  246.     if(openssl_get_modulus_and_prime(rsa, &sizeN, n, &sizeP, p) != 0) {
  247.         Tspi_Context_CloseObject(hContext, *hKey);
  248.         *hKey = 0;
  249.         return result;
  250.     }
  251.     /* set the public key data in the TSS object */
  252.     result = Tspi_SetAttribData(*hKey, TSS_TSPATTRIB_RSAKEY_INFO,
  253.                                 TSS_TSPATTRIB_KEYINFO_RSA_MODULUS,
  254.                                 sizeN, n);
  255.     if (result != TSS_SUCCESS) {
  256.         printf("Tspi_SetAttribData failed: %s; Error number:%.2x\n", get_error(result),result);
  257.         Tspi_Context_CloseObject(hContext, *hKey);
  258.         *hKey = 0;
  259.         return result;
  260.     }
  261.     /* set the private key data in the TSS object */
  262.     result = Tspi_SetAttribData(*hKey, TSS_TSPATTRIB_KEY_BLOB,
  263.                                 TSS_TSPATTRIB_KEYBLOB_PRIVATE_KEY,
  264.                                 sizeP, p);
  265.     if (result != TSS_SUCCESS) {
  266.         printf("Tspi_SetAttribData failed: %s\n", get_error(result));
  267.         Tspi_Context_CloseObject(hContext, *hKey);
  268.         *hKey = 0;
  269.         return result;
  270.     }
  271.     
  272.     result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_MIGRATION, &keyMigPolicy);
  273.     Assert(result, "Tspi_GetPolicyObject");
  274.     BYTE wellKnownSecret[] = TSS_WELL_KNOWN_SECRET;
  275.     result = Tspi_Policy_SetSecret(keyMigPolicy,TSS_SECRET_MODE_SHA1,
  276.                                     20, wellKnownSecret);
  277.     Assert(result, "Tspi_Policy_SetSecret");
  278.     result = Tspi_Policy_AssignToObject(keyMigPolicy, *hKey);
  279.     Assert(result, "Tspi_Policy_AssignToObject");

  280.     /* Call the TSS to do the key wrapping */
  281.     result = Tspi_Key_WrapKey(*hKey, hParentKey, hPcrs);
  282.     //result = Tspi_Key_CreateKey(*hKey, hParentKey, 0);
  283.     if (result != TSS_SUCCESS) {
  284.         printf("Tspi_Key_WrapKey failed: %s; Error number:%.2x\n", get_error(result), result);
  285.         Tspi_Context_CloseObject(hContext, *hKey);
  286.         *hKey = 0;
  287.     }
  288.     RSA_free(rsa);

  289.     if(result ==TSS_SUCCESS)
  290.     {
  291.         printf("Wrap key succeed!\n");
  292.     }

  293.     return result;
  294. }

  295. /*create the key hierarchy*/
  296. int MyFunc_CreateKeyHierarchy()
  297. {
  298.     //TSS_HCONTEXT hContext;
  299.     //TSS_HTPM hTPM;
  300.     TSS_HPOLICY hSRKPolicy, hTpmPolicy;
  301.     BYTE entropyData[ENTROPY_SIZE];
  302.     BYTE secretData[] = TSS_WELL_KNOWN_SECRET;
  303.     int secretDataLen = TCPA_SHA1_160_HASH_LEN;
  304.     BYTE tpmPasswd[] = "helloworld";
  305.     int tpmPasswdLen = strlen(tpmPasswd);
  306.     BYTE srkPasswd[] = "helloworld";
  307.     //char *secretData = "helloworld";
  308.     TSS_FLAG initFlags;
  309.     TSS_UUID swMigKeyUuid, systemMigKeyUuid;
  310.     TSS_HKEY hUserSWMigKey, hSystemMigKey, hKeyPcrs;
  311.     TSS_HKEY hMigKeyBind, hSealingKey, hMAKey;
  312.     TSS_HKEY hAIKey, hMtncKey;
  313.     TSS_HPOLICY hUserSWMigKeyPolicy;
  314.     TSS_HPCRS hPcrs;
  315.     UINT32 pcrLen;
  316.     BYTE *pcrValue;
  317.     TSS_RESULT result;
  318.     TSS_BOOL tpmState;
  319.     BYTE userPass[MAX_PASS_LEN];
  320.     BYTE *random;
  321.     UINT32 aik_label_len, credSize;
  322.     BYTE *aik_label, *cred;
  323.     TSS_UUID AIKUuid;
  324.     TSS_VALIDATION validationData;
  325.     BYTE *ticket;
  326.     UINT32 ticketLen;

  327.     BYTE *mtncBlob, *migBlob;
  328.     UINT32 mtncBlobLen, migBlobLen;
  329.     int i; //loop index
  330.     TSS_UUID SRK_UUID = TSS_UUID_SRK;

  331.     /* OpenSSL objects */
  332.     RSA *ca_rsa, *migration_pub_rsa, *maintenance_pub_rsa;

  333.     /* Make any necessary setup calls to OpenSSL */
  334.     //init_external_libraries();
  335.     /* SSL init*/

  336.     //书中使用的init_external_libraries找不到函数,用别的方式代替
  337.     SSL_library_init();
  338.     /* load all SSL */
  339.     OpenSSL_add_all_algorithms();
  340.     /* load all SSL error message */
  341.     SSL_load_error_strings();

  342.     Tspi_Context_Create(&hContext);
  343.     Tspi_Context_Connect(hContext, NULL);
  344.     result = Tspi_Context_GetTpmObject(hContext, &hTPM);
  345.     if(result != TSS_SUCCESS)
  346.     {
  347.         printf("Tspi_Context_GetTpmObject Error: %s\n", get_error(result));
  348.         exit(1);
  349.     }

  350.     /* Add entropy to the TPM’s random number generator from the
  351.     * system’s random device */
  352.     MyFunc_GetRandom(ENTROPY_SIZE, entropyData);
  353.     Tspi_TPM_StirRandom(hTPM, ENTROPY_SIZE, entropyData);
  354.     printf("Random number:");
  355.     for(i=0; i<ENTROPY_SIZE; i++)
  356.     {
  357.         printf("%.2x ", entropyData[i]);
  358.     }
  359.     printf("\n");

  360.     /* Load the SRK from storage in the System Persistent Store */
  361.     result = Tspi_Context_LoadKeyByUUID(hContext, TSS_PS_TYPE_SYSTEM, SRK_UUID,
  362.                                         &hSRK);
  363.     Assert(result, "Tspi_Context_LoadKeyByUUID");

  364.     /*get the tpm policy to take the tpm ownership*/
  365.     result = Tspi_GetPolicyObject(hTPM, TSS_POLICY_USAGE, &hTpmPolicy);
  366.     Assert(result, "Tspi_GetPolicyObject for TPM");
  367.     result = Tspi_Policy_SetSecret(hTpmPolicy, TSS_SECRET_MODE_PLAIN,
  368.                                     tpmPasswdLen, tpmPasswd);
  369.     Assert(result, "Tspi_Policy_SetSecret");
  370.     /* Set the SRK’s password since it will be referenced below */
  371.     //changed by zw
  372.     //hContext做第一个参数的时候,始终报错TSS_E_BAD_PARAMETER,所以替换成hSRK
  373.     result = Tspi_GetPolicyObject(hSRK, TSS_POLICY_USAGE, &hSRKPolicy);
  374.     Assert(result, "Tspi_GetPolicyObject");

  375.     result = Tspi_Policy_SetSecret(hSRKPolicy, TSS_SECRET_MODE_PLAIN,
  376.                                      strlen(srkPasswd), srkPasswd);
  377.     //同样,因为我的机器上SRK没有设置密码认证,所有密钥模式为TSS_SECRET_MODE_NONE
  378.     //result = Tspi_Policy_SetSecret(hSRKPolicy, TSS_SECRET_MODE_NONE,
  379.     //                                0, NULL);
  380.     Assert(result, "Tspi_Policy_SetSecret");

  381.     /*take ownership*/
  382.     //result = Tspi_TPM_TakeOwnership(hTPM, hSRK, 0);
  383.     //Assert(result, "Tspi_TPM_TakeOwnership");

  384.     /* Wrap the software generated key with the SRK’s public key.
  385.     * initFlags is set to make this key a migratable storage key
  386.     * that requires a password. */
  387.     initFlags = TSS_KEY_TYPE_STORAGE | TSS_KEY_MIGRATABLE |
  388.                     TSS_KEY_AUTHORIZATION;
  389.     
  390.     MyFunc_WrapKey(SOFTWARE_KEY_FILE_PATH, hSRK, initFlags, 0,
  391.                  &hUserSWMigKey);
  392.     
  393.     /* Register the wrapped key in user persistent storage */
  394.     result = Tspi_Context_RegisterKey(hContext, hUserSWMigKey,
  395.                                     TSS_PS_TYPE_USER, swMigKeyUuid,
  396.                                     TSS_PS_TYPE_SYSTEM, SRK_UUID);
  397.     Assert(result, "Tspi_Context_RegisterKey");
  398.     
  399.     result = Tspi_GetPolicyObject(hUserSWMigKey, TSS_POLICY_USAGE,
  400.                                     &hUserSWMigKeyPolicy);
  401.     Assert(result, "Tspi_GetPolicyObject");

  402.     sprintf(userPass, "helloworld");
  403.     Tspi_Policy_SetSecret(hUserSWMigKeyPolicy, TSS_SECRET_MODE_PLAIN,
  404.                             strlen(userPass), userPass);

  405.     /* Zero-out the password entered, keeping it in memory for the
  406.      * smallest amount of time possible */

  407.     memset(userPass, 0, MAX_PASS_LEN);
  408.     /* create a non-migratable signing key not bound to any PCRs */
  409.     initFlags = TSS_KEY_TYPE_SIGNING | TSS_KEY_SIZE_2048 |
  410.                 TSS_KEY_NOT_MIGRATABLE;
  411.     /* Pass ‘0’ as the handle to the PCRs object, to keep the TSS from
  412.     * binding this key to any PCRs */
  413.     MyFunc_CreateTPMKey(hSRK, initFlags, 0, &hSystemMigKey);
  414.     /* Register the key in system persistent storage */
  415.     Tspi_Context_RegisterKey(hContext, hSystemMigKey, TSS_PS_TYPE_SYSTEM,
  416.                             systemMigKeyUuid, TSS_PS_TYPE_SYSTEM,
  417.                             SRK_UUID);
  418.     /* Create a PCR composite object with the current values of PCRs
  419.     * 4 and 5 */
  420.     Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_PCRS, 0, &hPcrs);
  421.     Tspi_TPM_PcrRead(hTPM, 4, &pcrLen, &pcrValue);
  422.     Tspi_PcrComposite_SetPcrValue(hPcrs, 4, pcrLen, pcrValue);
  423.     /* Free the pcrValue data returned from the Tspi_TPM_PcrRead()
  424.     * function. At this point, the value of the PCR register has been
  425.     * copied into the PCR object hPcrs by the TSS. */
  426.     Tspi_Context_FreeMemory(hContext, pcrValue);
  427.     Tspi_TPM_PcrRead(hTPM, 5, &pcrLen, &pcrValue);
  428.     Tspi_PcrComposite_SetPcrValue(hPcrs, 5, pcrLen, pcrValue);
  429.     Tspi_Context_FreeMemory(hContext, pcrValue);

  430.     /* Create a non-migratable signing key bound to PCRs 4 and 5 */
  431.     initFlags = TSS_KEY_TYPE_SIGNING | TSS_KEY_SIZE_2048 |
  432.     TSS_KEY_NOT_MIGRATABLE;
  433.     /*
  434.     *Passing the hPcrs handle here ensures the new key is bound to
  435.     *PCRs 4 and 5. If the value of those PCRs changes, the key will
  436.     *become unusable until a platform reset can return them to their
  437.     *present state */
  438.     MyFunc_CreateTPMKey(hSRK, initFlags, hPcrs, &hKeyPcrs);

  439.     /* Read in the Privacy CA’s key from disk */
  440.     ca_rsa = openssl_read_key(CA_KEY_FILE_PATH);
  441.     aik_label = "My Identity Label";
  442.     aik_label_len = strlen(aik_label) + 1;

  443.     /*Create AIK*/
  444.     /*MyFunc_CreateAIK(ca_rsa, aik_label, aik_label_len, &hAIKey,
  445.                     &credSize, cred);
  446.     */
  447.     return 0;
  448. }

  449. int main(void)
  450. {
  451.     MyFunc_CreateKeyHierarchy();

  452.     return 0;
  453. }
编译方法:
gcc -g -o MyFunc_KeyHierarchy MyFunc_KeyHierarchy.c -ltspi -lcrypto -lssl

(未完待续...)



阅读(8261) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

xuxin2358916s2014-06-11 16:48:24

您好,最近在学习可信计算,我在linux下安装好了Trousers和tpm-tools,可是在执行tpm_version时出现Tspi_Context_Connect Failed : 0x00002004 lay=tcs code=00004 Internal software error的错误,请问该如何解决,谢谢。