| OLD | NEW | 
|---|
| 1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 
| 2  * Use of this source code is governed by a BSD-style license that can be | 2  * Use of this source code is governed by a BSD-style license that can be | 
| 3  * found in the LICENSE file. | 3  * found in the LICENSE file. | 
| 4  * | 4  * | 
| 5  * High-level firmware API for loading and verifying rewritable firmware. | 5  * High-level firmware API for loading and verifying rewritable firmware. | 
| 6  * (Firmware portion) | 6  * (Firmware portion) | 
| 7  */ | 7  */ | 
| 8 | 8 | 
| 9 #include "load_firmware_fw.h" | 9 #include "load_firmware_fw.h" | 
| 10 #include "rollback_index.h" | 10 #include "rollback_index.h" | 
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 44   int index; | 44   int index; | 
| 45 | 45 | 
| 46   /* Clear output params in case we fail */ | 46   /* Clear output params in case we fail */ | 
| 47   params->firmware_index = 0; | 47   params->firmware_index = 0; | 
| 48   params->kernel_sign_key_blob = NULL; | 48   params->kernel_sign_key_blob = NULL; | 
| 49   params->kernel_sign_key_size = 0; | 49   params->kernel_sign_key_size = 0; | 
| 50 | 50 | 
| 51   debug("LoadFirmware started...\n"); | 51   debug("LoadFirmware started...\n"); | 
| 52 | 52 | 
| 53   /* Must have a root key */ | 53   /* Must have a root key */ | 
| 54   if (!root_key) | 54   if (!root_key) { | 
|  | 55     debug("No root key\n"); | 
| 55     return LOAD_FIRMWARE_RECOVERY; | 56     return LOAD_FIRMWARE_RECOVERY; | 
|  | 57   } | 
| 56 | 58 | 
| 57   /* Initialize the TPM and read rollback indices. */ | 59   /* Initialize the TPM and read rollback indices. */ | 
| 58   /* TODO: fix SetupTPM parameter for developer mode */ | 60   /* TODO: fix SetupTPM parameter for developer mode */ | 
| 59   if (0 != SetupTPM(RO_NORMAL_MODE, 0) ) | 61   if (0 != SetupTPM(RO_NORMAL_MODE, 0)) { | 
|  | 62     debug("SetupTPM failed\n"); | 
| 60     return LOAD_FIRMWARE_RECOVERY; | 63     return LOAD_FIRMWARE_RECOVERY; | 
|  | 64   } | 
| 61   if (0 != GetStoredVersions(FIRMWARE_VERSIONS, | 65   if (0 != GetStoredVersions(FIRMWARE_VERSIONS, | 
| 62                              &tpm_key_version, &tpm_fw_version)) | 66                              &tpm_key_version, &tpm_fw_version)) { | 
|  | 67     debug("Unable to get stored versions.\n"); | 
| 63     return LOAD_FIRMWARE_RECOVERY; | 68     return LOAD_FIRMWARE_RECOVERY; | 
|  | 69   } | 
| 64 | 70 | 
| 65   /* Allocate our internal data */ | 71   /* Allocate our internal data */ | 
| 66   lfi = (VbLoadFirmwareInternal*)Malloc(sizeof(VbLoadFirmwareInternal)); | 72   lfi = (VbLoadFirmwareInternal*)Malloc(sizeof(VbLoadFirmwareInternal)); | 
| 67   if (!lfi) | 73   if (!lfi) | 
| 68     return LOAD_FIRMWARE_RECOVERY; | 74     return LOAD_FIRMWARE_RECOVERY; | 
| 69   params->load_firmware_internal = (uint8_t*)lfi; | 75   params->load_firmware_internal = (uint8_t*)lfi; | 
| 70 | 76 | 
| 71   /* Loop over indices */ | 77   /* Loop over indices */ | 
| 72   for (index = 0; index < 2; index++) { | 78   for (index = 0; index < 2; index++) { | 
| 73     VbKeyBlockHeader* key_block; | 79     VbKeyBlockHeader* key_block; | 
| 74     uint64_t vblock_size; | 80     uint64_t vblock_size; | 
| 75     VbFirmwarePreambleHeader* preamble; | 81     VbFirmwarePreambleHeader* preamble; | 
| 76     RSAPublicKey* data_key; | 82     RSAPublicKey* data_key; | 
| 77     uint64_t key_version; | 83     uint64_t key_version; | 
| 78     uint8_t* body_digest; | 84     uint8_t* body_digest; | 
| 79 | 85 | 
| 80     /* Verify the key block */ | 86     /* Verify the key block */ | 
| 81     if (0 == index) { | 87     if (0 == index) { | 
| 82       key_block = (VbKeyBlockHeader*)params->verification_block_0; | 88       key_block = (VbKeyBlockHeader*)params->verification_block_0; | 
| 83       vblock_size = params->verification_size_0; | 89       vblock_size = params->verification_size_0; | 
| 84     } else { | 90     } else { | 
| 85       key_block = (VbKeyBlockHeader*)params->verification_block_1; | 91       key_block = (VbKeyBlockHeader*)params->verification_block_1; | 
| 86       vblock_size = params->verification_size_1; | 92       vblock_size = params->verification_size_1; | 
| 87     } | 93     } | 
| 88     if ((0 != KeyBlockVerify(key_block, vblock_size, root_key))) | 94     if ((0 != KeyBlockVerify(key_block, vblock_size, root_key))) { | 
|  | 95       debug("Key block verification failed.\n"); | 
| 89       continue; | 96       continue; | 
|  | 97     } | 
| 90 | 98 | 
| 91     /* Check for rollback of key version. */ | 99     /* Check for rollback of key version. */ | 
| 92     key_version = key_block->data_key.key_version; | 100     key_version = key_block->data_key.key_version; | 
| 93     if (key_version < tpm_key_version) | 101     if (key_version < tpm_key_version) { | 
|  | 102       debug("Key rollback detected.\n"); | 
| 94       continue; | 103       continue; | 
|  | 104     } | 
| 95 | 105 | 
| 96     /* Get the key for preamble/data verification from the key block. */ | 106     /* Get the key for preamble/data verification from the key block. */ | 
| 97     data_key = PublicKeyToRSA(&key_block->data_key); | 107     data_key = PublicKeyToRSA(&key_block->data_key); | 
| 98     if (!data_key) | 108     if (!data_key) { | 
|  | 109       debug("Unable to parse data key.\n"); | 
| 99       continue; | 110       continue; | 
|  | 111     } | 
| 100 | 112 | 
| 101     /* Verify the preamble, which follows the key block. */ | 113     /* Verify the preamble, which follows the key block. */ | 
| 102     preamble = (VbFirmwarePreambleHeader*)((uint8_t*)key_block + | 114     preamble = (VbFirmwarePreambleHeader*)((uint8_t*)key_block + | 
| 103                                            key_block->key_block_size); | 115                                            key_block->key_block_size); | 
| 104     if ((0 != VerifyFirmwarePreamble2(preamble, | 116     if ((0 != VerifyFirmwarePreamble2(preamble, | 
| 105                                       vblock_size - key_block->key_block_size, | 117                                       vblock_size - key_block->key_block_size, | 
| 106                                       data_key))) { | 118                                       data_key))) { | 
|  | 119       debug("Preamble verfication failed.\n"); | 
| 107       RSAPublicKeyFree(data_key); | 120       RSAPublicKeyFree(data_key); | 
| 108       continue; | 121       continue; | 
| 109     } | 122     } | 
| 110 | 123 | 
| 111     /* Check for rollback of firmware version. */ | 124     /* Check for rollback of firmware version. */ | 
| 112     if (key_version == tpm_key_version && | 125     if (key_version == tpm_key_version && | 
| 113         preamble->firmware_version < tpm_fw_version) { | 126         preamble->firmware_version < tpm_fw_version) { | 
|  | 127       debug("Firmware version rollback detected.\n"); | 
| 114       RSAPublicKeyFree(data_key); | 128       RSAPublicKeyFree(data_key); | 
| 115       continue; | 129       continue; | 
| 116     } | 130     } | 
| 117 | 131 | 
| 118     /* Check for lowest key version from a valid header. */ | 132     /* Check for lowest key version from a valid header. */ | 
| 119     if (lowest_key_version > key_version) { | 133     if (lowest_key_version > key_version) { | 
| 120       lowest_key_version = key_version; | 134       lowest_key_version = key_version; | 
| 121       lowest_fw_version = preamble->firmware_version; | 135       lowest_fw_version = preamble->firmware_version; | 
| 122     } | 136     } | 
| 123     else if (lowest_key_version == key_version && | 137     else if (lowest_key_version == key_version && | 
| 124              lowest_fw_version > preamble->firmware_version) { | 138              lowest_fw_version > preamble->firmware_version) { | 
| 125       lowest_fw_version = preamble->firmware_version; | 139       lowest_fw_version = preamble->firmware_version; | 
| 126     } | 140     } | 
| 127 | 141 | 
| 128     /* If we already have good firmware, no need to read another one; | 142     /* If we already have good firmware, no need to read another one; | 
| 129      * we only needed to look at the versions to check for | 143      * we only needed to look at the versions to check for | 
| 130      * rollback. */ | 144      * rollback. */ | 
| 131     if (-1 != good_index) | 145     if (-1 != good_index) | 
| 132       continue; | 146       continue; | 
| 133 | 147 | 
| 134     /* Read the firmware data */ | 148     /* Read the firmware data */ | 
| 135     DigestInit(&lfi->body_digest_context, data_key->algorithm); | 149     DigestInit(&lfi->body_digest_context, data_key->algorithm); | 
| 136     lfi->body_size_accum = 0; | 150     lfi->body_size_accum = 0; | 
| 137     if ((0 != GetFirmwareBody(params, index)) || | 151     if (0 != GetFirmwareBody(params, index)) { | 
| 138         (lfi->body_size_accum != preamble->body_signature.data_size)) { | 152       debug("GetFirmwareBody() failed for index %d\n", index); | 
| 139       RSAPublicKeyFree(data_key); | 153       RSAPublicKeyFree(data_key); | 
| 140       continue; | 154       continue; | 
| 141     } | 155     } | 
|  | 156     if (lfi->body_size_accum != preamble->body_signature.data_size) { | 
|  | 157       debug("Hash updated %d bytes but expected %d\n", | 
|  | 158             (int)lfi->body_size_accum, (int)preamble->body_signature.data_size); | 
|  | 159       RSAPublicKeyFree(data_key); | 
|  | 160       continue; | 
|  | 161     } | 
| 142 | 162 | 
| 143     /* Verify firmware data */ | 163     /* Verify firmware data */ | 
| 144     body_digest = DigestFinal(&lfi->body_digest_context); | 164     body_digest = DigestFinal(&lfi->body_digest_context); | 
| 145     if (0 != VerifyDigest(body_digest, &preamble->body_signature, data_key)) { | 165     if (0 != VerifyDigest(body_digest, &preamble->body_signature, data_key)) { | 
|  | 166       debug("Firmware body verification failed.\n"); | 
| 146       RSAPublicKeyFree(data_key); | 167       RSAPublicKeyFree(data_key); | 
| 147       Free(body_digest); | 168       Free(body_digest); | 
| 148       continue; | 169       continue; | 
| 149     } | 170     } | 
| 150 | 171 | 
| 151     /* Done with the digest and data key, so can free them now */ | 172     /* Done with the digest and data key, so can free them now */ | 
| 152     RSAPublicKeyFree(data_key); | 173     RSAPublicKeyFree(data_key); | 
| 153     Free(body_digest); | 174     Free(body_digest); | 
| 154 | 175 | 
| 155     /* If we're still here, the firmware is valid. */ | 176     /* If we're still here, the firmware is valid. */ | 
|  | 177     debug("Firmware %d is valid.\n", index); | 
| 156     if (-1 == good_index) { | 178     if (-1 == good_index) { | 
| 157       VbPublicKey *kdest = (VbPublicKey*)params->kernel_sign_key_blob; | 179       VbPublicKey *kdest = (VbPublicKey*)params->kernel_sign_key_blob; | 
| 158 | 180 | 
| 159       /* Copy the kernel sign key blob into the destination buffer */ | 181       /* Copy the kernel sign key blob into the destination buffer */ | 
| 160       PublicKeyInit(kdest, (uint8_t*)(kdest + 1), | 182       PublicKeyInit(kdest, (uint8_t*)(kdest + 1), | 
| 161                     (params->kernel_sign_key_size - sizeof(VbPublicKey))); | 183                     (params->kernel_sign_key_size - sizeof(VbPublicKey))); | 
| 162 | 184 | 
| 163       if (0 != PublicKeyCopy(kdest, &preamble->kernel_subkey)) | 185       if (0 != PublicKeyCopy(kdest, &preamble->kernel_subkey)) { | 
|  | 186         debug("Kernel subkey too big for buffer.\n"); | 
| 164         continue;  /* The firmware signature was good, but the public | 187         continue;  /* The firmware signature was good, but the public | 
| 165                     * key was bigger that the caller can handle. */ | 188                     * key was bigger that the caller can handle. */ | 
|  | 189       } | 
| 166 | 190 | 
| 167       /* Save the key size we actually used */ | 191       /* Save the key size we actually used */ | 
| 168       params->kernel_sign_key_size = kdest->key_offset + kdest->key_size; | 192       params->kernel_sign_key_size = kdest->key_offset + kdest->key_size; | 
| 169 | 193 | 
| 170       /* Save the good index, now that we're sure we can actually use | 194       /* Save the good index, now that we're sure we can actually use | 
| 171        * this firmware.  That's the one we'll boot. */ | 195        * this firmware.  That's the one we'll boot. */ | 
| 172       good_index = index; | 196       good_index = index; | 
| 173       params->firmware_index = index; | 197       params->firmware_index = index; | 
| 174 | 198 | 
| 175       /* If the good firmware's key version is the same as the tpm, | 199       /* If the good firmware's key version is the same as the tpm, | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
| 188 | 212 | 
| 189   /* Handle finding good firmware */ | 213   /* Handle finding good firmware */ | 
| 190   if (good_index >= 0) { | 214   if (good_index >= 0) { | 
| 191 | 215 | 
| 192     /* Update TPM if necessary */ | 216     /* Update TPM if necessary */ | 
| 193     if ((lowest_key_version > tpm_key_version) || | 217     if ((lowest_key_version > tpm_key_version) || | 
| 194         (lowest_key_version == tpm_key_version && | 218         (lowest_key_version == tpm_key_version && | 
| 195          lowest_fw_version > tpm_fw_version)) { | 219          lowest_fw_version > tpm_fw_version)) { | 
| 196       if (0 != WriteStoredVersions(FIRMWARE_VERSIONS, | 220       if (0 != WriteStoredVersions(FIRMWARE_VERSIONS, | 
| 197                                    (uint16_t)lowest_key_version, | 221                                    (uint16_t)lowest_key_version, | 
| 198                                    (uint16_t)lowest_fw_version)) | 222                                    (uint16_t)lowest_fw_version)) { | 
|  | 223         debug("Unable to write stored versions.\n"); | 
| 199         return LOAD_FIRMWARE_RECOVERY; | 224         return LOAD_FIRMWARE_RECOVERY; | 
|  | 225       } | 
| 200     } | 226     } | 
| 201 | 227 | 
| 202     /* Lock Firmware TPM rollback indices from further writes.  In | 228     /* Lock Firmware TPM rollback indices from further writes.  In | 
| 203      * this design, this is done by setting the globalLock bit, which | 229      * this design, this is done by setting the globalLock bit, which | 
| 204      * is cleared only by TPM_Init at reboot.  */ | 230      * is cleared only by TPM_Init at reboot.  */ | 
| 205     if (0 != LockFirmwareVersions()) | 231     if (0 != LockFirmwareVersions()) { | 
|  | 232       debug("Unable to lock firmware versions.\n"); | 
| 206       return LOAD_FIRMWARE_RECOVERY; | 233       return LOAD_FIRMWARE_RECOVERY; | 
|  | 234     } | 
| 207 | 235 | 
| 208     /* Success */ | 236     /* Success */ | 
|  | 237     debug("Will boot firmware index %d\n", (int)params->firmware_index); | 
| 209     return LOAD_FIRMWARE_SUCCESS; | 238     return LOAD_FIRMWARE_SUCCESS; | 
| 210   } | 239   } | 
| 211 | 240 | 
| 212   /* If we're still here, no good firmware, so go to recovery mode. */ | 241   /* If we're still here, no good firmware, so go to recovery mode. */ | 
|  | 242   debug("Alas, no good firmware.\n"); | 
| 213   return LOAD_FIRMWARE_RECOVERY; | 243   return LOAD_FIRMWARE_RECOVERY; | 
| 214 } | 244 } | 
| OLD | NEW | 
|---|