OLD | NEW |
1 /* Software-Based Trusted Platform Module (TPM) Emulator for Linux | 1 /* Software-based Trusted Platform Module (TPM) Emulator |
2 * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, | 2 * Copyright (C) 2004-2010 Mario Strasser <mast@gmx.net> |
3 * Swiss Federal Institute of Technology (ETH) Zurich | |
4 * | 3 * |
5 * This module is free software; you can redistribute it and/or modify | 4 * This module is free software; you can redistribute it and/or modify |
6 * it under the terms of the GNU General Public License as published | 5 * it under the terms of the GNU General Public License as published |
7 * by the Free Software Foundation; either version 2 of the License, | 6 * by the Free Software Foundation; either version 2 of the License, |
8 * or (at your option) any later version. | 7 * or (at your option) any later version. |
9 * | 8 * |
10 * This module is distributed in the hope that it will be useful, | 9 * This module is distributed in the hope that it will be useful, |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 * GNU General Public License for more details. | 12 * GNU General Public License for more details. |
14 * | 13 * |
15 * $Id$ | 14 * $Id: tpm_cmd_handler.c 377 2010-02-16 14:52:57Z mast $ |
16 */ | 15 */ |
17 | 16 |
18 #include "tpm_marshalling.h" | 17 #include "tpm_marshalling.h" |
19 #include "tpm_commands.h" | 18 #include "tpm_commands.h" |
20 #include "crypto/sha1.h" | 19 #include "crypto/sha1.h" |
21 #include "crypto/hmac.h" | 20 #include "crypto/hmac.h" |
22 #include "tpm_data.h" | 21 #include "tpm_data.h" |
23 #include "tpm_handles.h" | 22 #include "tpm_handles.h" |
24 | 23 |
| 24 #ifdef MTM_EMULATOR |
| 25 #include "mtm/mtm_commands.h" |
| 26 #endif |
| 27 |
25 UINT32 tpm_get_in_param_offset(TPM_COMMAND_CODE ordinal) | 28 UINT32 tpm_get_in_param_offset(TPM_COMMAND_CODE ordinal) |
26 { | 29 { |
27 switch (ordinal) { | 30 switch (ordinal) { |
28 case TPM_ORD_ActivateIdentity: | 31 case TPM_ORD_ActivateIdentity: |
29 case TPM_ORD_ChangeAuth: | 32 case TPM_ORD_ChangeAuth: |
30 case TPM_ORD_ChangeAuthAsymStart: | 33 case TPM_ORD_ChangeAuthAsymStart: |
31 case TPM_ORD_CMK_ConvertMigration: | 34 case TPM_ORD_CMK_ConvertMigration: |
32 case TPM_ORD_CMK_CreateBlob: | 35 case TPM_ORD_CMK_CreateBlob: |
33 case TPM_ORD_CMK_CreateKey: | 36 case TPM_ORD_CMK_CreateKey: |
34 case TPM_ORD_ConvertMigrationBlob: | 37 case TPM_ORD_ConvertMigrationBlob: |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 BYTE *resp = NULL; | 357 BYTE *resp = NULL; |
355 TPM_RESULT res; | 358 TPM_RESULT res; |
356 /* unmarshal input */ | 359 /* unmarshal input */ |
357 ptr = req->param; | 360 ptr = req->param; |
358 len = req->paramSize; | 361 len = req->paramSize; |
359 if (tpm_unmarshal_TPM_CAPABILITY_AREA(&ptr, &len, &capArea) | 362 if (tpm_unmarshal_TPM_CAPABILITY_AREA(&ptr, &len, &capArea) |
360 || tpm_unmarshal_UINT32(&ptr, &len, &subCapSize) | 363 || tpm_unmarshal_UINT32(&ptr, &len, &subCapSize) |
361 || tpm_unmarshal_BLOB(&ptr, &len, &subCap, subCapSize) | 364 || tpm_unmarshal_BLOB(&ptr, &len, &subCap, subCapSize) |
362 || len != 0) return TPM_BAD_PARAMETER; | 365 || len != 0) return TPM_BAD_PARAMETER; |
363 /* execute command */ | 366 /* execute command */ |
| 367 #ifdef MTM_EMULATOR |
| 368 res = MTM_GetCapability(capArea, subCapSize, subCap, &respSize, &resp); |
| 369 #else |
364 res = TPM_GetCapability(capArea, subCapSize, subCap, &respSize, &resp); | 370 res = TPM_GetCapability(capArea, subCapSize, subCap, &respSize, &resp); |
| 371 #endif |
365 if (res != TPM_SUCCESS) return res; | 372 if (res != TPM_SUCCESS) return res; |
366 /* marshal output */ | 373 /* marshal output */ |
367 rsp->paramSize = len = 4 + respSize; | 374 rsp->paramSize = len = 4 + respSize; |
368 rsp->param = ptr = tpm_malloc(len); | 375 rsp->param = ptr = tpm_malloc(len); |
369 if (ptr == NULL | 376 if (ptr == NULL |
370 || tpm_marshal_UINT32(&ptr, &len, respSize) | 377 || tpm_marshal_UINT32(&ptr, &len, respSize) |
371 || tpm_marshal_BLOB(&ptr, &len, resp, respSize)) { | 378 || tpm_marshal_BLOB(&ptr, &len, resp, respSize)) { |
372 tpm_free(rsp->param); | 379 tpm_free(rsp->param); |
373 res = TPM_FAIL; | 380 res = TPM_FAIL; |
374 } | 381 } |
(...skipping 1457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1832 TPM_DIGEST inDigest; | 1839 TPM_DIGEST inDigest; |
1833 TPM_PCRVALUE outDigest; | 1840 TPM_PCRVALUE outDigest; |
1834 TPM_RESULT res; | 1841 TPM_RESULT res; |
1835 /* unmarshal input */ | 1842 /* unmarshal input */ |
1836 ptr = req->param; | 1843 ptr = req->param; |
1837 len = req->paramSize; | 1844 len = req->paramSize; |
1838 if (tpm_unmarshal_TPM_PCRINDEX(&ptr, &len, &pcrNum) | 1845 if (tpm_unmarshal_TPM_PCRINDEX(&ptr, &len, &pcrNum) |
1839 || tpm_unmarshal_TPM_DIGEST(&ptr, &len, &inDigest) | 1846 || tpm_unmarshal_TPM_DIGEST(&ptr, &len, &inDigest) |
1840 || len != 0) return TPM_BAD_PARAMETER; | 1847 || len != 0) return TPM_BAD_PARAMETER; |
1841 /* execute command */ | 1848 /* execute command */ |
| 1849 #ifdef MTM_EMULATOR |
| 1850 res = MTM_Extend(pcrNum, &inDigest, &outDigest); |
| 1851 #else |
1842 res = TPM_Extend(pcrNum, &inDigest, &outDigest); | 1852 res = TPM_Extend(pcrNum, &inDigest, &outDigest); |
| 1853 #endif |
1843 if (res != TPM_SUCCESS) return res; | 1854 if (res != TPM_SUCCESS) return res; |
1844 /* marshal output */ | 1855 /* marshal output */ |
1845 rsp->paramSize = len = 20; | 1856 rsp->paramSize = len = 20; |
1846 rsp->param = ptr = tpm_malloc(len); | 1857 rsp->param = ptr = tpm_malloc(len); |
1847 if (ptr == NULL | 1858 if (ptr == NULL |
1848 || tpm_marshal_TPM_PCRVALUE(&ptr, &len, &outDigest)) { | 1859 || tpm_marshal_TPM_PCRVALUE(&ptr, &len, &outDigest)) { |
1849 tpm_free(rsp->param); | 1860 tpm_free(rsp->param); |
1850 res = TPM_FAIL; | 1861 res = TPM_FAIL; |
1851 } | 1862 } |
1852 return res; | 1863 return res; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1919 { | 1930 { |
1920 BYTE *ptr; | 1931 BYTE *ptr; |
1921 UINT32 len; | 1932 UINT32 len; |
1922 TPM_PCR_SELECTION pcrSelection; | 1933 TPM_PCR_SELECTION pcrSelection; |
1923 /* unmarshal input */ | 1934 /* unmarshal input */ |
1924 ptr = req->param; | 1935 ptr = req->param; |
1925 len = req->paramSize; | 1936 len = req->paramSize; |
1926 if (tpm_unmarshal_TPM_PCR_SELECTION(&ptr, &len, &pcrSelection) | 1937 if (tpm_unmarshal_TPM_PCR_SELECTION(&ptr, &len, &pcrSelection) |
1927 || len != 0) return TPM_BAD_PARAMETER; | 1938 || len != 0) return TPM_BAD_PARAMETER; |
1928 /* execute command */ | 1939 /* execute command */ |
| 1940 #ifdef MTM_EMULATOR |
| 1941 return MTM_PCR_Reset(&pcrSelection); |
| 1942 #else |
1929 return TPM_PCR_Reset(&pcrSelection); | 1943 return TPM_PCR_Reset(&pcrSelection); |
| 1944 #endif |
1930 } | 1945 } |
1931 | 1946 |
1932 static TPM_RESULT execute_TPM_Quote2(TPM_REQUEST *req, TPM_RESPONSE *rsp) | 1947 static TPM_RESULT execute_TPM_Quote2(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
1933 { | 1948 { |
1934 BYTE *ptr; | 1949 BYTE *ptr; |
1935 UINT32 len; | 1950 UINT32 len; |
1936 TPM_KEY_HANDLE keyHandle; | 1951 TPM_KEY_HANDLE keyHandle; |
1937 TPM_NONCE externalData; | 1952 TPM_NONCE externalData; |
1938 TPM_PCR_SELECTION targetPCR; | 1953 TPM_PCR_SELECTION targetPCR; |
1939 BOOL addVersion; | 1954 BOOL addVersion; |
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2584 UINT32 len; | 2599 UINT32 len; |
2585 TPM_HANDLE handle; | 2600 TPM_HANDLE handle; |
2586 TPM_RESOURCE_TYPE resourceType; | 2601 TPM_RESOURCE_TYPE resourceType; |
2587 /* unmarshal input */ | 2602 /* unmarshal input */ |
2588 ptr = req->param; | 2603 ptr = req->param; |
2589 len = req->paramSize; | 2604 len = req->paramSize; |
2590 if (tpm_unmarshal_TPM_HANDLE(&ptr, &len, &handle) | 2605 if (tpm_unmarshal_TPM_HANDLE(&ptr, &len, &handle) |
2591 || tpm_unmarshal_TPM_RESOURCE_TYPE(&ptr, &len, &resourceType) | 2606 || tpm_unmarshal_TPM_RESOURCE_TYPE(&ptr, &len, &resourceType) |
2592 || len != 0) return TPM_BAD_PARAMETER; | 2607 || len != 0) return TPM_BAD_PARAMETER; |
2593 /* execute command */ | 2608 /* execute command */ |
| 2609 #ifdef MTM_EMULATOR |
| 2610 return MTM_FlushSpecific(handle, resourceType); |
| 2611 #else |
2594 return TPM_FlushSpecific(handle, resourceType); | 2612 return TPM_FlushSpecific(handle, resourceType); |
| 2613 #endif |
2595 } | 2614 } |
2596 | 2615 |
2597 static TPM_RESULT execute_TPM_GetTicks(TPM_REQUEST *req, TPM_RESPONSE *rsp) | 2616 static TPM_RESULT execute_TPM_GetTicks(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
2598 { | 2617 { |
2599 BYTE *ptr; | 2618 BYTE *ptr; |
2600 UINT32 len; | 2619 UINT32 len; |
2601 TPM_CURRENT_TICKS currentTime; | 2620 TPM_CURRENT_TICKS currentTime; |
2602 TPM_RESULT res; | 2621 TPM_RESULT res; |
2603 /* execute command */ | 2622 /* execute command */ |
2604 res = TPM_GetTicks(¤tTime); | 2623 res = TPM_GetTicks(¤tTime); |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2861 UINT32 len; | 2880 UINT32 len; |
2862 TPM_COUNT_ID countID; | 2881 TPM_COUNT_ID countID; |
2863 /* compute parameter digest */ | 2882 /* compute parameter digest */ |
2864 tpm_compute_in_param_digest(req); | 2883 tpm_compute_in_param_digest(req); |
2865 /* unmarshal input */ | 2884 /* unmarshal input */ |
2866 ptr = req->param; | 2885 ptr = req->param; |
2867 len = req->paramSize; | 2886 len = req->paramSize; |
2868 if (tpm_unmarshal_TPM_COUNT_ID(&ptr, &len, &countID) | 2887 if (tpm_unmarshal_TPM_COUNT_ID(&ptr, &len, &countID) |
2869 || len != 0) return TPM_BAD_PARAMETER; | 2888 || len != 0) return TPM_BAD_PARAMETER; |
2870 /* execute command */ | 2889 /* execute command */ |
| 2890 #ifdef MTM_EMULATOR |
| 2891 return MTM_ReleaseCounter(countID, &req->auth1); |
| 2892 #else |
2871 return TPM_ReleaseCounter(countID, &req->auth1); | 2893 return TPM_ReleaseCounter(countID, &req->auth1); |
| 2894 #endif |
2872 } | 2895 } |
2873 | 2896 |
2874 static TPM_RESULT execute_TPM_ReleaseCounterOwner(TPM_REQUEST *req, TPM_RESPONSE
*rsp) | 2897 static TPM_RESULT execute_TPM_ReleaseCounterOwner(TPM_REQUEST *req, TPM_RESPONSE
*rsp) |
2875 { | 2898 { |
2876 BYTE *ptr; | 2899 BYTE *ptr; |
2877 UINT32 len; | 2900 UINT32 len; |
2878 TPM_COUNT_ID countID; | 2901 TPM_COUNT_ID countID; |
2879 /* compute parameter digest */ | 2902 /* compute parameter digest */ |
2880 tpm_compute_in_param_digest(req); | 2903 tpm_compute_in_param_digest(req); |
2881 /* unmarshal input */ | 2904 /* unmarshal input */ |
2882 ptr = req->param; | 2905 ptr = req->param; |
2883 len = req->paramSize; | 2906 len = req->paramSize; |
2884 if (tpm_unmarshal_TPM_COUNT_ID(&ptr, &len, &countID) | 2907 if (tpm_unmarshal_TPM_COUNT_ID(&ptr, &len, &countID) |
2885 || len != 0) return TPM_BAD_PARAMETER; | 2908 || len != 0) return TPM_BAD_PARAMETER; |
2886 /* execute command */ | 2909 /* execute command */ |
| 2910 #ifdef MTM_EMULATOR |
| 2911 return MTM_ReleaseCounterOwner(countID, &req->auth1); |
| 2912 #else |
2887 return TPM_ReleaseCounterOwner(countID, &req->auth1); | 2913 return TPM_ReleaseCounterOwner(countID, &req->auth1); |
| 2914 #endif |
2888 } | 2915 } |
2889 | 2916 |
2890 static TPM_RESULT execute_TPM_DAA_Join(TPM_REQUEST *req, TPM_RESPONSE *rsp) | 2917 static TPM_RESULT execute_TPM_DAA_Join(TPM_REQUEST *req, TPM_RESPONSE *rsp) |
2891 { | 2918 { |
2892 BYTE *ptr; | 2919 BYTE *ptr; |
2893 UINT32 len; | 2920 UINT32 len; |
2894 TPM_HANDLE handle; | 2921 TPM_HANDLE handle; |
2895 BYTE stage; | 2922 BYTE stage; |
2896 UINT32 inputSize0; | 2923 UINT32 inputSize0; |
2897 BYTE *inputData0; | 2924 BYTE *inputData0; |
(...skipping 1128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4026 debug("[TPM_ORD_Reset]"); | 4053 debug("[TPM_ORD_Reset]"); |
4027 res = execute_TPM_Reset(req, rsp); | 4054 res = execute_TPM_Reset(req, rsp); |
4028 break; | 4055 break; |
4029 | 4056 |
4030 case TPM_ORD_OwnerReadPubek: | 4057 case TPM_ORD_OwnerReadPubek: |
4031 debug("[TPM_ORD_OwnerReadPubek]"); | 4058 debug("[TPM_ORD_OwnerReadPubek]"); |
4032 res = execute_TPM_OwnerReadPubek(req, rsp); | 4059 res = execute_TPM_OwnerReadPubek(req, rsp); |
4033 break; | 4060 break; |
4034 | 4061 |
4035 default: | 4062 default: |
| 4063 #ifdef MTM_EMULATOR |
| 4064 res = mtm_execute_command(req, rsp); |
| 4065 if (res != TPM_BAD_ORDINAL) break; |
| 4066 #endif |
4036 info("The ordinal (0x%02x) was unknown or inconsistent", req->ordinal); | 4067 info("The ordinal (0x%02x) was unknown or inconsistent", req->ordinal); |
4037 tpm_setup_error_response(TPM_BAD_ORDINAL, rsp); | 4068 tpm_setup_error_response(TPM_BAD_ORDINAL, rsp); |
4038 return; | 4069 return; |
4039 } | 4070 } |
4040 | 4071 |
4041 /* setup response */ | 4072 /* setup response */ |
4042 if (res != TPM_SUCCESS) { | 4073 if (res != TPM_SUCCESS) { |
4043 info("TPM command failed: (0x%02x) %s", res, tpm_error_to_string(res)); | 4074 info("TPM command failed: (0x%02x) %s", res, tpm_error_to_string(res)); |
4044 tpm_setup_error_response(res, rsp); | 4075 tpm_setup_error_response(res, rsp); |
4045 if (!(res & TPM_NON_FATAL)) { | 4076 if (!(res & TPM_NON_FATAL)) { |
4046 if (rsp->auth1 != NULL) rsp->auth1->continueAuthSession = FALSE; | 4077 if (rsp->auth1 != NULL) rsp->auth1->continueAuthSession = FALSE; |
4047 if (rsp->auth2 != NULL) rsp->auth2->continueAuthSession = FALSE; | 4078 if (rsp->auth2 != NULL) rsp->auth2->continueAuthSession = FALSE; |
4048 } | 4079 } |
4049 } else { | 4080 } else { |
4050 info("TPM command succeeded"); | 4081 info("TPM command succeeded"); |
4051 rsp->size += rsp->paramSize; | 4082 rsp->size += rsp->paramSize; |
4052 if (rsp->tag != TPM_TAG_RSP_COMMAND) tpm_setup_rsp_auth(req->ordinal, rsp); | 4083 if (rsp->tag != TPM_TAG_RSP_COMMAND) tpm_setup_rsp_auth(req->ordinal, rsp); |
4053 #ifdef TPM_STRONG_PERSISTENCE | 4084 if (tpmConf & TPM_CONF_STRONG_PERSISTENCE) { |
4054 if (tpm_store_permanent_data() != 0) { | 4085 if (tpm_store_permanent_data() != 0) { |
4055 error("tpm_store_permanent_data() failed"); | 4086 error("tpm_store_permanent_data() failed"); |
4056 } | 4087 } |
4057 #endif | 4088 } |
4058 } | 4089 } |
4059 /* terminate authorization sessions if necessary */ | 4090 /* terminate authorization sessions if necessary */ |
4060 if (rsp->auth1 != NULL && !rsp->auth1->continueAuthSession) | 4091 if (rsp->auth1 != NULL && !rsp->auth1->continueAuthSession) |
4061 TPM_FlushSpecific(rsp->auth1->authHandle, HANDLE_TO_RT(rsp->auth1->authHandl
e)); | 4092 TPM_FlushSpecific(rsp->auth1->authHandle, HANDLE_TO_RT(rsp->auth1->authHandl
e)); |
4062 if (rsp->auth2 != NULL && !rsp->auth2->continueAuthSession) | 4093 if (rsp->auth2 != NULL && !rsp->auth2->continueAuthSession) |
4063 TPM_FlushSpecific(rsp->auth2->authHandle, TPM_RT_AUTH); | 4094 TPM_FlushSpecific(rsp->auth2->authHandle, TPM_RT_AUTH); |
4064 /* if transportExclusive is set, only the execution of TPM_ExecuteTransport | 4095 /* if transportExclusive is set, only the execution of TPM_ExecuteTransport |
4065 and TPM_ReleaseTransportSigned is allowed */ | 4096 and TPM_ReleaseTransportSigned is allowed */ |
4066 if (tpmData.stany.flags.transportExclusive | 4097 if (tpmData.stany.flags.transportExclusive |
4067 && req->ordinal != TPM_ORD_ExecuteTransport | 4098 && req->ordinal != TPM_ORD_ExecuteTransport |
4068 && req->ordinal != TPM_ORD_ReleaseTransportSigned) { | 4099 && req->ordinal != TPM_ORD_ReleaseTransportSigned) { |
4069 TPM_FlushSpecific(tpmData.stany.data.transExclusive, TPM_RT_TRANS); | 4100 TPM_FlushSpecific(tpmData.stany.data.transExclusive, TPM_RT_TRANS); |
4070 tpmData.stany.flags.transportExclusive = FALSE; | 4101 tpmData.stany.flags.transportExclusive = FALSE; |
4071 } | 4102 } |
4072 } | 4103 } |
4073 | 4104 |
4074 void tpm_emulator_init(uint32_t startup) | 4105 void tpm_emulator_init(uint32_t startup, uint32_t conf) |
4075 { | 4106 { |
4076 debug("tpm_emulator_init()"); | 4107 debug("tpm_emulator_init(%d, 0x%08x)", startup, conf); |
| 4108 tpmConf = conf; |
| 4109 #ifdef MTM_EMULATOR |
| 4110 info("MTM support enabled"); |
| 4111 #endif |
4077 /* try to restore data, if it fails use default values */ | 4112 /* try to restore data, if it fails use default values */ |
4078 if (tpm_restore_permanent_data() != 0) tpm_init_data(); | 4113 if (tpm_restore_permanent_data() != 0) tpm_init_data(); |
4079 TPM_Init(startup); | 4114 TPM_Init(startup); |
4080 } | 4115 } |
4081 | 4116 |
4082 void tpm_emulator_shutdown() | 4117 void tpm_emulator_shutdown() |
4083 { | 4118 { |
4084 debug("tpm_emulator_shutdown()"); | 4119 debug("tpm_emulator_shutdown()"); |
4085 if (TPM_SaveState() != TPM_SUCCESS) { | 4120 if (TPM_SaveState() != TPM_SUCCESS) { |
4086 error("TPM_SaveState() failed"); | 4121 error("TPM_SaveState() failed"); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4139 if (tpm_marshal_TPM_RESPONSE(&ptr, &len, &rsp) != 0) { | 4174 if (tpm_marshal_TPM_RESPONSE(&ptr, &len, &rsp) != 0) { |
4140 error("tpm_marshal_TPM_RESPONSE() failed"); | 4175 error("tpm_marshal_TPM_RESPONSE() failed"); |
4141 if (free_out) tpm_free(*out); | 4176 if (free_out) tpm_free(*out); |
4142 tpm_free(rsp.param); | 4177 tpm_free(rsp.param); |
4143 return -1; | 4178 return -1; |
4144 } | 4179 } |
4145 tpm_free(rsp.param); | 4180 tpm_free(rsp.param); |
4146 return 0; | 4181 return 0; |
4147 } | 4182 } |
4148 | 4183 |
OLD | NEW |