| 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_data.c 372 2010-02-15 12:52:00Z mast $ |
| 16 */ | 15 */ |
| 17 | 16 |
| 18 #include "tpm_emulator.h" | 17 #include "tpm_emulator.h" |
| 19 #include "tpm_structures.h" | 18 #include "tpm_structures.h" |
| 20 #include "tpm_marshalling.h" | 19 #include "tpm_marshalling.h" |
| 20 #include "tpm_commands.h" |
| 21 #include "tpm_data.h" | 21 #include "tpm_data.h" |
| 22 | 22 |
| 23 TPM_DATA tpmData; | 23 TPM_DATA tpmData; |
| 24 UINT32 tpmConf; |
| 25 |
| 26 #ifdef MTM_EMULATOR |
| 27 #include "mtm/mtm_data.h" |
| 28 #include "mtm/mtm_marshalling.h" |
| 29 #endif |
| 24 | 30 |
| 25 static TPM_VERSION tpm_version = { 1, 2, VERSION_MAJOR, VERSION_MINOR }; | 31 static TPM_VERSION tpm_version = { 1, 2, VERSION_MAJOR, VERSION_MINOR }; |
| 26 | 32 |
| 27 BOOL tpm_get_physical_presence(void) | 33 BOOL tpm_get_physical_presence(void) |
| 28 { | 34 { |
| 29 return (tpmData.stclear.flags.physicalPresence || TRUE); | 35 return (tpmData.stclear.flags.physicalPresence || TRUE); |
| 30 } | 36 } |
| 31 | 37 |
| 32 static inline void init_pcr_attr(int pcr, BOOL reset, BYTE rl, BYTE el) | 38 static inline void init_pcr_attr(int pcr, BOOL reset, BYTE rl, BYTE el) |
| 33 { | 39 { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 tpmData.permanent.data.tis_timeouts[1] = 2000; | 71 tpmData.permanent.data.tis_timeouts[1] = 2000; |
| 66 tpmData.permanent.data.tis_timeouts[2] = 750; | 72 tpmData.permanent.data.tis_timeouts[2] = 750; |
| 67 tpmData.permanent.data.tis_timeouts[3] = 750; | 73 tpmData.permanent.data.tis_timeouts[3] = 750; |
| 68 tpmData.permanent.data.cmd_durations[0] = 1; | 74 tpmData.permanent.data.cmd_durations[0] = 1; |
| 69 tpmData.permanent.data.cmd_durations[1] = 10; | 75 tpmData.permanent.data.cmd_durations[1] = 10; |
| 70 tpmData.permanent.data.cmd_durations[2] = 1000; | 76 tpmData.permanent.data.cmd_durations[2] = 1000; |
| 71 } | 77 } |
| 72 | 78 |
| 73 void tpm_init_data(void) | 79 void tpm_init_data(void) |
| 74 { | 80 { |
| 75 #ifndef TPM_GENERATE_EK | |
| 76 /* endorsement key */ | 81 /* endorsement key */ |
| 77 uint8_t ek_n[] = "\xa8\xdb\xa9\x42\xa8\xf3\xb8\x06\x85\x90\x76\x93\xad\xf7" | 82 uint8_t ek_n[] = "\xa8\xdb\xa9\x42\xa8\xf3\xb8\x06\x85\x90\x76\x93\xad\xf7" |
| 78 "\x74\xec\x3f\xd3\x3d\x9d\xe8\x2e\xff\x15\xed\x0e\xce\x5f\x93" | 83 "\x74\xec\x3f\xd3\x3d\x9d\xe8\x2e\xff\x15\xed\x0e\xce\x5f\x93" |
| 79 "\x92\xeb\xd1\x96\x2b\x72\x18\x81\x79\x12\x9d\x9c\x40\xd7\x1a" | 84 "\x92\xeb\xd1\x96\x2b\x72\x18\x81\x79\x12\x9d\x9c\x40\xd7\x1a" |
| 80 "\x21\xda\x5f\x56\xe0\xc9\x48\x31\xdd\x96\xdc\xbb\x45\xc6\x8e" | 85 "\x21\xda\x5f\x56\xe0\xc9\x48\x31\xdd\x96\xdc\xbb\x45\xc6\x8e" |
| 81 "\xad\x58\x23\xcb\xbe\xbb\x13\x2d\x6b\x86\xc5\x57\xf5\xdd\x48" | 86 "\xad\x58\x23\xcb\xbe\xbb\x13\x2d\x6b\x86\xc5\x57\xf5\xdd\x48" |
| 82 "\xc1\x3d\xcd\x4d\xda\x81\xc4\x43\x17\xaa\x05\x40\x33\x62\x0a" | 87 "\xc1\x3d\xcd\x4d\xda\x81\xc4\x43\x17\xaa\x05\x40\x33\x62\x0a" |
| 83 "\x59\xdb\x28\xcd\xb5\x08\x31\xbb\x06\xf5\xf7\x71\xae\x21\xa8" | 88 "\x59\xdb\x28\xcd\xb5\x08\x31\xbb\x06\xf5\xf7\x71\xae\x21\xa8" |
| 84 "\xf2\x2f\x0e\x17\x80\x5d\x9c\xdf\xaa\xe9\x89\x09\x54\x65\x2b" | 89 "\xf2\x2f\x0e\x17\x80\x5d\x9c\xdf\xaa\xe9\x89\x09\x54\x65\x2b" |
| 85 "\x46\xfb\x9d\xb2\x00\x70\x63\x0d\x9a\x6d\x3d\x5e\x11\x78\x65" | 90 "\x46\xfb\x9d\xb2\x00\x70\x63\x0d\x9a\x6d\x3d\x5e\x11\x78\x65" |
| (...skipping 18 matching lines...) Expand all Loading... |
| 104 "\x40\x37\x70\x17\x4c\xe3\x69\xd4\x59"; | 109 "\x40\x37\x70\x17\x4c\xe3\x69\xd4\x59"; |
| 105 uint8_t ek_q[] = "\xc8\x34\xd2\xd0\x7c\xfa\xdc\x68\xe2\x72\xd7\x92\xe2\x50" | 110 uint8_t ek_q[] = "\xc8\x34\xd2\xd0\x7c\xfa\xdc\x68\xe2\x72\xd7\x92\xe2\x50" |
| 106 "\x93\xfc\xbb\x72\x55\x4d\x6b\x7a\x0c\x0b\xcf\x87\x66\x1f\x81" | 111 "\x93\xfc\xbb\x72\x55\x4d\x6b\x7a\x0c\x0b\xcf\x87\x66\x1f\x81" |
| 107 "\x71\xf3\x50\xcb\xaa\xe6\x43\x7e\xbe\x11\xc4\xec\x00\x53\xf4" | 112 "\x71\xf3\x50\xcb\xaa\xe6\x43\x7e\xbe\x11\xc4\xec\x00\x53\xf4" |
| 108 "\x78\x13\x2b\x59\x26\x4a\x9f\x91\x61\x8f\xa7\x07\x64\x11\x5a" | 113 "\x78\x13\x2b\x59\x26\x4a\x9f\x91\x61\x8f\xa7\x07\x64\x11\x5a" |
| 109 "\xf4\xaf\x9c\x9b\x5a\x5d\x69\x20\x17\x55\x74\xba\xd8\xe4\x59" | 114 "\xf4\xaf\x9c\x9b\x5a\x5d\x69\x20\x17\x55\x74\xba\xd8\xe4\x59" |
| 110 "\x39\x1a\x0a\x7b\x4a\x30\xf0\xc8\x7f\xd9\xaf\x72\xc5\xb6\x71" | 115 "\x39\x1a\x0a\x7b\x4a\x30\xf0\xc8\x7f\xd9\xaf\x72\xc5\xb6\x71" |
| 111 "\xd1\xc0\x8b\x5b\xa2\x2e\xa7\x15\xca\x50\x75\x10\x48\x9c\x2b" | 116 "\xd1\xc0\x8b\x5b\xa2\x2e\xa7\x15\xca\x50\x75\x10\x48\x9c\x2b" |
| 112 "\x18\xb9\x67\x8f\x5d\x64\xc3\x28\x9f\x2f\x16\x2f\x08\xda\x47" | 117 "\x18\xb9\x67\x8f\x5d\x64\xc3\x28\x9f\x2f\x16\x2f\x08\xda\x47" |
| 113 "\xec\x86\x43\x0c\x80\x99\x07\x34\x0f"; | 118 "\xec\x86\x43\x0c\x80\x99\x07\x34\x0f"; |
| 114 #endif | |
| 115 int i; | 119 int i; |
| 116 info("initializing TPM data to default values"); | 120 info("initializing TPM data to default values"); |
| 117 /* reset all data to NULL, FALSE or 0 */ | 121 /* reset all data to NULL, FALSE or 0 */ |
| 118 memset(&tpmData, 0, sizeof(tpmData)); | 122 memset(&tpmData, 0, sizeof(tpmData)); |
| 119 tpmData.permanent.data.tag = TPM_TAG_PERMANENT_DATA; | 123 tpmData.permanent.data.tag = TPM_TAG_PERMANENT_DATA; |
| 120 /* set permanent flags */ | 124 /* set permanent flags */ |
| 121 tpmData.permanent.flags.tag = TPM_TAG_PERMANENT_FLAGS; | 125 tpmData.permanent.flags.tag = TPM_TAG_PERMANENT_FLAGS; |
| 122 tpmData.permanent.flags.disable = FALSE; | 126 tpmData.permanent.flags.disable = FALSE; |
| 123 tpmData.permanent.flags.deactivated = FALSE; | 127 tpmData.permanent.flags.deactivated = FALSE; |
| 124 tpmData.permanent.flags.ownership = TRUE; | 128 tpmData.permanent.flags.ownership = TRUE; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 143 init_pcr_attr(18, TRUE, 0x10, 0x1c); | 147 init_pcr_attr(18, TRUE, 0x10, 0x1c); |
| 144 init_pcr_attr(19, TRUE, 0x10, 0x0c); | 148 init_pcr_attr(19, TRUE, 0x10, 0x0c); |
| 145 init_pcr_attr(20, TRUE, 0x14, 0x0e); | 149 init_pcr_attr(20, TRUE, 0x14, 0x0e); |
| 146 init_pcr_attr(21, TRUE, 0x04, 0x04); | 150 init_pcr_attr(21, TRUE, 0x04, 0x04); |
| 147 init_pcr_attr(22, TRUE, 0x04, 0x04); | 151 init_pcr_attr(22, TRUE, 0x04, 0x04); |
| 148 init_pcr_attr(23, TRUE, 0x1f, 0x1f); | 152 init_pcr_attr(23, TRUE, 0x1f, 0x1f); |
| 149 } | 153 } |
| 150 for (i = 24; i < TPM_NUM_PCR; i++) { | 154 for (i = 24; i < TPM_NUM_PCR; i++) { |
| 151 init_pcr_attr(i, TRUE, 0x00, 0x00); | 155 init_pcr_attr(i, TRUE, 0x00, 0x00); |
| 152 } | 156 } |
| 153 #ifdef TPM_GENERATE_EK | 157 if (tpmConf & TPM_CONF_GENERATE_EK) { |
| 154 /* generate a new endorsement key */ | 158 /* generate a new endorsement key */ |
| 155 tpm_rsa_generate_key(&tpmData.permanent.data.endorsementKey, 2048); | 159 tpm_rsa_generate_key(&tpmData.permanent.data.endorsementKey, 2048); |
| 156 #else | 160 } else { |
| 157 /* setup endorsement key */ | 161 /* setup endorsement key */ |
| 158 tpm_rsa_import_key(&tpmData.permanent.data.endorsementKey, | 162 tpm_rsa_import_key(&tpmData.permanent.data.endorsementKey, |
| 159 RSA_MSB_FIRST, ek_n, 256, ek_e, 3, ek_p, ek_q); | 163 RSA_MSB_FIRST, ek_n, 256, ek_e, 3, ek_p, ek_q); |
| 160 #endif | 164 } |
| 161 #ifdef TPM_GENERATE_SEED_DAA | 165 if (tpmConf & TPM_CONF_GENERATE_SEED_DAA) { |
| 162 /* generate the DAA seed */ | 166 /* generate the DAA seed */ |
| 163 tpm_get_random_bytes(tpmData.permanent.data.tpmDAASeed.nonce, | 167 tpm_get_random_bytes(tpmData.permanent.data.tpmDAASeed.nonce, |
| 164 sizeof(tpmData.permanent.data.tpmDAASeed.nonce)); | 168 sizeof(tpmData.permanent.data.tpmDAASeed.nonce)); |
| 165 #else | 169 } else { |
| 166 /* setup DAA seed */ | 170 /* setup DAA seed */ |
| 167 memcpy(tpmData.permanent.data.tpmDAASeed.nonce, | 171 memcpy(tpmData.permanent.data.tpmDAASeed.nonce, |
| 168 "\x77\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" | 172 "\x77\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
| 169 "\x00\x00\x00\x77", sizeof(TPM_NONCE)); | 173 "\x00\x00\x00\x77", sizeof(TPM_NONCE)); |
| 170 #endif | 174 } |
| 171 memcpy(tpmData.permanent.data.ekReset.nonce, "\xde\xad\xbe\xef", 4); | 175 memcpy(tpmData.permanent.data.ekReset.nonce, "\xde\xad\xbe\xef", 4); |
| 172 /* initialize predefined non-volatile storage */ | 176 /* initialize predefined non-volatile storage */ |
| 173 init_nv_storage(); | 177 init_nv_storage(); |
| 174 /* set the timeout and duration values */ | 178 /* set the timeout and duration values */ |
| 175 init_timeouts(); | 179 init_timeouts(); |
| 180 #ifdef MTM_EMULATOR |
| 181 mtm_init_data(); |
| 182 #endif |
| 176 } | 183 } |
| 177 | 184 |
| 178 void tpm_release_data(void) | 185 void tpm_release_data(void) |
| 179 { | 186 { |
| 180 unsigned int i; | 187 free_TPM_DATA(tpmData); |
| 181 /* release the EK, SRK as well as all other rsa keys */ | 188 #ifdef MTM_EMULATOR |
| 182 if (tpmData.permanent.data.endorsementKey.size > 0) | 189 free_MTM_DATA(mtmData); |
| 183 tpm_rsa_release_private_key(&tpmData.permanent.data.endorsementKey); | 190 #endif |
| 184 if (tpmData.permanent.data.srk.payload) | |
| 185 free_TPM_KEY_DATA(tpmData.permanent.data.srk); | |
| 186 if (tpmData.permanent.data.manuMaintPub.valid) | |
| 187 free_TPM_PUBKEY_DATA(tpmData.permanent.data.manuMaintPub); | |
| 188 for (i = 0; i < TPM_MAX_KEYS; i++) | |
| 189 if (tpmData.permanent.data.keys[i].payload) | |
| 190 free_TPM_KEY_DATA(tpmData.permanent.data.keys[i]); | |
| 191 } | 191 } |
| 192 | 192 |
| 193 int tpm_store_permanent_data(void) | 193 int tpm_store_permanent_data(void) |
| 194 { | 194 { |
| 195 uint8_t *buf, *ptr; | 195 uint8_t *buf, *ptr; |
| 196 size_t buf_length; | 196 size_t buf_length; |
| 197 uint32_t len; | 197 uint32_t len; |
| 198 | 198 |
| 199 /* marshal data */ | 199 /* marshal data */ |
| 200 buf_length = len = sizeof_TPM_VERSION(tpmData.permanent.data.version) | 200 buf_length = len = sizeof_TPM_VERSION(tpmData.permanent.data.version) |
| 201 + sizeof_TPM_PERMANENT_FLAGS(tpmData.permanent.flags) + 2 | 201 #ifdef MTM_EMULATOR |
| 202 + sizeof_TPM_PERMANENT_DATA(&tpmData.permanent.data) | 202 + sizeof_TPM_DATA(tpmData) + sizeof_MTM_DATA(mtmData); |
| 203 + sizeof_TPM_STCLEAR_FLAGS(tpmData.stclear.flags) | 203 #else |
| 204 + sizeof_TPM_STCLEAR_DATA(tpmData.stclear.data) | 204 + sizeof_TPM_DATA(tpmData); |
| 205 + sizeof_TPM_STANY_DATA(tpmData.stany.data); | 205 #endif |
| 206 debug("size of permanent data: %d", buf_length); | 206 debug("size of permanent data: %d", buf_length); |
| 207 buf = ptr = tpm_malloc(buf_length); | 207 buf = ptr = tpm_malloc(buf_length); |
| 208 if (buf == NULL | 208 if (buf == NULL |
| 209 || tpm_marshal_TPM_VERSION(&ptr, &len, &tpmData.permanent.data.version) | 209 || tpm_marshal_TPM_VERSION(&ptr, &len, &tpmData.permanent.data.version) |
| 210 || tpm_marshal_TPM_PERMANENT_FLAGS(&ptr, &len, &tpmData.permanent.flags) | 210 #ifdef MTM_EMULATOR |
| 211 || tpm_marshal_BOOL(&ptr, &len, tpmData.permanent.flags.selfTestSucceeded) | 211 || tpm_marshal_TPM_DATA(&ptr, &len, &tpmData) |
| 212 || tpm_marshal_BOOL(&ptr, &len, tpmData.permanent.flags.owned) | 212 || tpm_marshal_MTM_DATA(&ptr, &len, &mtmData)) { |
| 213 || tpm_marshal_TPM_PERMANENT_DATA(&ptr, &len, &tpmData.permanent.data) | 213 #else |
| 214 || tpm_marshal_TPM_STCLEAR_FLAGS(&ptr, &len, &tpmData.stclear.flags) | 214 || tpm_marshal_TPM_DATA(&ptr, &len, &tpmData)) { |
| 215 || tpm_marshal_TPM_STCLEAR_DATA(&ptr, &len, &tpmData.stclear.data) | 215 #endif |
| 216 || tpm_marshal_TPM_STANY_DATA(&ptr, &len, &tpmData.stany.data)) { | |
| 217 tpm_free(buf); | 216 tpm_free(buf); |
| 218 return -1; | 217 return -1; |
| 219 } | 218 } |
| 220 if (len != 0) debug("warning: buffer was too large, %d bytes left", len); | 219 if (len != 0) debug("warning: buffer was too large, %d bytes left", len); |
| 221 if (tpm_write_to_storage(buf, buf_length - len)) { | 220 if (tpm_write_to_storage(buf, buf_length - len)) { |
| 222 tpm_free(buf); | 221 tpm_free(buf); |
| 223 return -1; | 222 return -1; |
| 224 } | 223 } |
| 225 tpm_free(buf); | 224 tpm_free(buf); |
| 226 return 0; | 225 return 0; |
| 227 } | 226 } |
| 228 | 227 |
| 229 int tpm_restore_permanent_data(void) | 228 int tpm_restore_permanent_data(void) |
| 230 { | 229 { |
| 231 uint8_t *buf, *ptr; | 230 uint8_t *buf, *ptr; |
| 232 size_t buf_length; | 231 size_t buf_length; |
| 233 uint32_t len; | 232 uint32_t len; |
| 234 TPM_VERSION ver; | 233 TPM_VERSION ver; |
| 235 | 234 |
| 236 /* read data */ | 235 /* read data */ |
| 237 if (tpm_read_from_storage(&buf, &buf_length)) return -1; | 236 if (tpm_read_from_storage(&buf, &buf_length)) return -1; |
| 238 ptr = buf; | 237 ptr = buf; |
| 239 len = buf_length; | 238 len = buf_length; |
| 240 /* unmarshal data */ | 239 /* unmarshal data */ |
| 241 if (tpm_unmarshal_TPM_VERSION(&ptr, &len, &ver) | 240 if (tpm_unmarshal_TPM_VERSION(&ptr, &len, &ver) |
| 242 || memcmp(&ver, &tpm_version, sizeof(TPM_VERSION)) | 241 || memcmp(&ver, &tpm_version, sizeof(TPM_VERSION)) |
| 243 || tpm_unmarshal_TPM_PERMANENT_FLAGS(&ptr, &len, &tpmData.permanent.flags) | 242 || tpm_unmarshal_TPM_DATA(&ptr, &len, &tpmData) |
| 244 || tpm_unmarshal_BOOL(&ptr, &len, &tpmData.permanent.flags.selfTestSucceed
ed) | 243 #ifdef MTM_EMULATOR |
| 245 || tpm_unmarshal_BOOL(&ptr, &len, &tpmData.permanent.flags.owned) | 244 || tpm_unmarshal_MTM_DATA(&ptr, &len, &mtmData) |
| 246 || tpm_unmarshal_TPM_PERMANENT_DATA(&ptr, &len, &tpmData.permanent.data) | 245 #endif |
| 247 || tpm_unmarshal_TPM_STCLEAR_FLAGS(&ptr, &len, &tpmData.stclear.flags)
| |
| 248 || tpm_unmarshal_TPM_STCLEAR_DATA(&ptr, &len, &tpmData.stclear.data) | |
| 249 || tpm_unmarshal_TPM_STANY_DATA(&ptr, &len, &tpmData.stany.data) | |
| 250 || len > 0) { | 246 || len > 0) { |
| 251 tpm_free(buf); | 247 tpm_free(buf); |
| 252 return -1; | 248 return -1; |
| 253 } | 249 } |
| 254 tpm_free(buf); | 250 tpm_free(buf); |
| 255 tpmData.permanent.flags.dataRestored = TRUE; | 251 tpmData.permanent.flags.dataRestored = TRUE; |
| 256 return 0; | 252 return 0; |
| 257 } | 253 } |
| 258 | 254 |
| 259 int tpm_erase_permanent_data(void) | 255 int tpm_erase_permanent_data(void) |
| 260 { | 256 { |
| 261 uint8_t d[1]; | 257 uint8_t d[1]; |
| 262 int res = tpm_write_to_storage(d, 0); | 258 int res = tpm_write_to_storage(d, 0); |
| 263 return res; | 259 return res; |
| 264 } | 260 } |
| 265 | 261 |
| OLD | NEW |