1 /* Copyright (c) 2014 The Chromium OS Authors. All rights reserved. 2 * Use of this source code is governed by a BSD-style license that can be 3 * found in the LICENSE file. 4 * 5 * Misc functions which need access to vb2_context but are not public APIs 6 */ 7 8 #include "2sysincludes.h" 9 #include "2api.h" 10 #include "2common.h" 11 #include "2misc.h" 12 #include "2nvstorage.h" 13 #include "2secdata.h" 14 #include "2sha.h" 15 #include "2rsa.h" 16 17 int vb2_validate_gbb_signature(uint8_t *sig) { 18 const static uint8_t sig_xor[VB2_GBB_SIGNATURE_SIZE] = 19 VB2_GBB_XOR_SIGNATURE; 20 int i; 21 for (i = 0; i < VB2_GBB_SIGNATURE_SIZE; i++) { 22 if (sig[i] != (sig_xor[i] ^ VB2_GBB_XOR_CHARS[i])) 23 return VB2_ERROR_GBB_MAGIC; 24 } 25 return VB2_SUCCESS; 26 } 27 28 void vb2_workbuf_from_ctx(struct vb2_context *ctx, struct vb2_workbuf *wb) 29 { 30 vb2_workbuf_init(wb, ctx->workbuf + ctx->workbuf_used, 31 ctx->workbuf_size - ctx->workbuf_used); 32 } 33 34 int vb2_read_gbb_header(struct vb2_context *ctx, struct vb2_gbb_header *gbb) 35 { 36 int rv; 37 38 /* Read the entire header */ 39 rv = vb2ex_read_resource(ctx, VB2_RES_GBB, 0, gbb, sizeof(*gbb)); 40 if (rv) 41 return rv; 42 43 /* Make sure it's really a GBB */ 44 rv = vb2_validate_gbb_signature(gbb->signature); 45 if (rv) 46 return rv; 47 48 /* Check for compatible version */ 49 if (gbb->major_version != VB2_GBB_MAJOR_VER) 50 return VB2_ERROR_GBB_VERSION; 51 52 /* Current code is not backwards-compatible to 1.0 headers */ 53 if (gbb->minor_version == 0) 54 return VB2_ERROR_GBB_TOO_OLD; 55 56 /* 57 * Header size should be at least as big as we expect. It could be 58 * bigger, if the header has grown. 59 */ 60 if (gbb->header_size < sizeof(*gbb)) 61 return VB2_ERROR_GBB_HEADER_SIZE; 62 63 return VB2_SUCCESS; 64 } 65 66 void vb2_fail(struct vb2_context *ctx, uint8_t reason, uint8_t subcode) 67 { 68 struct vb2_shared_data *sd = vb2_get_sd(ctx); 69 70 /* If NV data hasn't been initialized, initialize it now */ 71 if (!(sd->status & VB2_SD_STATUS_NV_INIT)) 72 vb2_nv_init(ctx); 73 74 /* See if we were far enough in the boot process to choose a slot */ 75 if (sd->status & VB2_SD_STATUS_CHOSE_SLOT) { 76 77 /* Boot failed */ 78 vb2_nv_set(ctx, VB2_NV_FW_RESULT, VB2_FW_RESULT_FAILURE); 79 80 /* Use up remaining tries */ 81 vb2_nv_set(ctx, VB2_NV_TRY_COUNT, 0); 82 83 /* 84 * Try the other slot next time. We'll alternate 85 * between slots, which may help if one or both slots is 86 * flaky. 87 */ 88 vb2_nv_set(ctx, VB2_NV_TRY_NEXT, 1 - sd->fw_slot); 89 90 /* 91 * If we didn't try the other slot last boot, or we tried it 92 * and it didn't fail, try it next boot. 93 */ 94 if (sd->last_fw_slot != 1 - sd->fw_slot || 95 sd->last_fw_result != VB2_FW_RESULT_FAILURE) 96 return; 97 } 98 99 /* 100 * If we're still here, we failed before choosing a slot, or both 101 * this slot and the other slot failed in successive boots. So we 102 * need to go to recovery. 103 * 104 * Set a recovery reason and subcode only if they're not already set. 105 * If recovery is already requested, it's a more specific error code 106 * than later code is providing and we shouldn't overwrite it. 107 */ 108 VB2_DEBUG("Need recovery, reason: %#x / %#x\n", reason, subcode); 109 if (!vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST)) { 110 vb2_nv_set(ctx, VB2_NV_RECOVERY_REQUEST, reason); 111 vb2_nv_set(ctx, VB2_NV_RECOVERY_SUBCODE, subcode); 112 } 113 } 114 115 int vb2_init_context(struct vb2_context *ctx) 116 { 117 struct vb2_shared_data *sd = vb2_get_sd(ctx); 118 119 /* Don't do anything if the context has already been initialized */ 120 if (ctx->workbuf_used) 121 return VB2_SUCCESS; 122 123 /* 124 * Workbuf had better be big enough for our shared data struct and 125 * aligned. Not much we can do if it isn't; we'll die before we can 126 * store a recovery reason. 127 */ 128 if (ctx->workbuf_size < sizeof(*sd)) 129 return VB2_ERROR_INITCTX_WORKBUF_SMALL; 130 if (!vb2_aligned(ctx->workbuf, VB2_WORKBUF_ALIGN)) 131 return VB2_ERROR_INITCTX_WORKBUF_ALIGN; 132 133 /* Initialize the shared data at the start of the work buffer */ 134 memset(sd, 0, sizeof(*sd)); 135 ctx->workbuf_used = sizeof(*sd); 136 return VB2_SUCCESS; 137 } 138 139 void vb2_check_recovery(struct vb2_context *ctx) 140 { 141 struct vb2_shared_data *sd = vb2_get_sd(ctx); 142 143 /* 144 * Read the current recovery request, unless there's already been a 145 * failure earlier in the boot process. 146 */ 147 if (!sd->recovery_reason) 148 sd->recovery_reason = vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST); 149 150 /* Clear the recovery request so we don't get stuck in recovery mode */ 151 if (sd->recovery_reason) { 152 vb2_nv_set(ctx, VB2_NV_RECOVERY_REQUEST, 153 VB2_RECOVERY_NOT_REQUESTED); 154 /* 155 * Note that we ignore failures clearing the request. We only 156 * hit this code path if recovery mode has already been 157 * requested, so what more can we do? Don't want to obscure 158 * the original reason for going into recovery mode. 159 */ 160 } 161 162 /* If forcing recovery, override recovery reason */ 163 if (ctx->flags & VB2_CONTEXT_FORCE_RECOVERY_MODE) { 164 sd->recovery_reason = VB2_RECOVERY_RO_MANUAL; 165 sd->flags |= VB2_SD_FLAG_MANUAL_RECOVERY; 166 } 167 168 /* If recovery reason is non-zero, tell caller we need recovery mode */ 169 if (sd->recovery_reason) { 170 ctx->flags |= VB2_CONTEXT_RECOVERY_MODE; 171 VB2_DEBUG("We have a recovery request: %#x / %#x\n", 172 sd->recovery_reason, 173 vb2_nv_get(ctx, VB2_NV_RECOVERY_SUBCODE)); 174 } 175 } 176 177 int vb2_fw_parse_gbb(struct vb2_context *ctx) 178 { 179 struct vb2_shared_data *sd = vb2_get_sd(ctx); 180 struct vb2_gbb_header *gbb; 181 struct vb2_workbuf wb; 182 int rv; 183 184 vb2_workbuf_from_ctx(ctx, &wb); 185 186 /* Read GBB into next chunk of work buffer */ 187 gbb = vb2_workbuf_alloc(&wb, sizeof(*gbb)); 188 if (!gbb) 189 return VB2_ERROR_GBB_WORKBUF; 190 191 rv = vb2_read_gbb_header(ctx, gbb); 192 if (rv) 193 return rv; 194 195 /* Extract the only things we care about at firmware time */ 196 sd->gbb_flags = gbb->flags; 197 sd->gbb_rootkey_offset = gbb->rootkey_offset; 198 sd->gbb_rootkey_size = gbb->rootkey_size; 199 memcpy(sd->gbb_hwid_digest, gbb->hwid_digest, VB2_GBB_HWID_DIGEST_SIZE); 200 201 return VB2_SUCCESS; 202 } 203 204 int vb2_check_dev_switch(struct vb2_context *ctx) 205 { 206 struct vb2_shared_data *sd = vb2_get_sd(ctx); 207 uint32_t flags; 208 uint32_t old_flags; 209 int is_dev = 0; 210 int rv; 211 212 /* Read secure flags */ 213 rv = vb2_secdata_get(ctx, VB2_SECDATA_FLAGS, &flags); 214 if (rv) 215 return rv; 216 217 old_flags = flags; 218 219 /* Handle dev disable request */ 220 if (vb2_nv_get(ctx, VB2_NV_DISABLE_DEV_REQUEST)) { 221 flags &= ~VB2_SECDATA_FLAG_DEV_MODE; 222 223 /* Clear the request */ 224 vb2_nv_set(ctx, VB2_NV_DISABLE_DEV_REQUEST, 0); 225 } 226 227 /* Check virtual dev switch */ 228 if (flags & VB2_SECDATA_FLAG_DEV_MODE) 229 is_dev = 1; 230 231 /* Handle forcing dev mode via physical switch */ 232 if (ctx->flags & VB2_CONTEXT_FORCE_DEVELOPER_MODE) 233 is_dev = 1; 234 235 /* Check if GBB is forcing dev mode */ 236 if (sd->gbb_flags & VB2_GBB_FLAG_FORCE_DEV_SWITCH_ON) 237 is_dev = 1; 238 239 /* Handle whichever mode we end up in */ 240 if (is_dev) { 241 /* Developer mode */ 242 sd->flags |= VB2_SD_DEV_MODE_ENABLED; 243 ctx->flags |= VB2_CONTEXT_DEVELOPER_MODE; 244 245 flags |= VB2_SECDATA_FLAG_LAST_BOOT_DEVELOPER; 246 } else { 247 /* Normal mode */ 248 flags &= ~VB2_SECDATA_FLAG_LAST_BOOT_DEVELOPER; 249 250 /* 251 * Disable dev_boot_* flags. This ensures they will be 252 * initially disabled if the user later transitions back into 253 * developer mode. 254 */ 255 vb2_nv_set(ctx, VB2_NV_DEV_BOOT_USB, 0); 256 vb2_nv_set(ctx, VB2_NV_DEV_BOOT_LEGACY, 0); 257 vb2_nv_set(ctx, VB2_NV_DEV_BOOT_SIGNED_ONLY, 0); 258 } 259 260 if (flags != old_flags) { 261 /* 262 * Just changed dev mode state. Clear TPM owner. This must be 263 * done here instead of simply passing a flag to 264 * vb2_check_tpm_clear(), because we don't want to update 265 * last_boot_developer and then fail to clear the TPM owner. 266 */ 267 rv = vb2ex_tpm_clear_owner(ctx); 268 if (rv) { 269 /* 270 * Note that this truncates rv to 8 bit. Which is not 271 * as useful as the full error code, but we don't have 272 * NVRAM space to store the full 32-bit code. 273 */ 274 vb2_fail(ctx, VB2_RECOVERY_TPM_CLEAR_OWNER, rv); 275 return rv; 276 } 277 278 /* Save new flags */ 279 rv = vb2_secdata_set(ctx, VB2_SECDATA_FLAGS, flags); 280 if (rv) 281 return rv; 282 } 283 284 return VB2_SUCCESS; 285 } 286 287 int vb2_check_tpm_clear(struct vb2_context *ctx) 288 { 289 int rv; 290 291 /* Check if we've been asked to clear the owner */ 292 if (!vb2_nv_get(ctx, VB2_NV_CLEAR_TPM_OWNER_REQUEST)) 293 return VB2_SUCCESS; /* No need to clear */ 294 295 /* Request applies one time only */ 296 vb2_nv_set(ctx, VB2_NV_CLEAR_TPM_OWNER_REQUEST, 0); 297 298 /* Try clearing */ 299 rv = vb2ex_tpm_clear_owner(ctx); 300 if (rv) { 301 /* 302 * Note that this truncates rv to 8 bit. Which is not as 303 * useful as the full error code, but we don't have NVRAM space 304 * to store the full 32-bit code. 305 */ 306 vb2_fail(ctx, VB2_RECOVERY_TPM_CLEAR_OWNER, rv); 307 return rv; 308 } 309 310 /* Clear successful */ 311 vb2_nv_set(ctx, VB2_NV_CLEAR_TPM_OWNER_DONE, 1); 312 return VB2_SUCCESS; 313 } 314 315 int vb2_select_fw_slot(struct vb2_context *ctx) 316 { 317 struct vb2_shared_data *sd = vb2_get_sd(ctx); 318 uint32_t tries; 319 320 /* Get result of last boot */ 321 sd->last_fw_slot = vb2_nv_get(ctx, VB2_NV_FW_TRIED); 322 sd->last_fw_result = vb2_nv_get(ctx, VB2_NV_FW_RESULT); 323 324 /* Save to the previous result fields in NV storage */ 325 vb2_nv_set(ctx, VB2_NV_FW_PREV_TRIED, sd->last_fw_slot); 326 vb2_nv_set(ctx, VB2_NV_FW_PREV_RESULT, sd->last_fw_result); 327 328 /* Clear result, since we don't know what will happen this boot */ 329 vb2_nv_set(ctx, VB2_NV_FW_RESULT, VB2_FW_RESULT_UNKNOWN); 330 331 /* Get slot to try */ 332 sd->fw_slot = vb2_nv_get(ctx, VB2_NV_TRY_NEXT); 333 334 /* Check try count */ 335 tries = vb2_nv_get(ctx, VB2_NV_TRY_COUNT); 336 337 if (sd->last_fw_result == VB2_FW_RESULT_TRYING && 338 sd->last_fw_slot == sd->fw_slot && 339 tries == 0) { 340 /* 341 * We used up our last try on the previous boot, so fall back 342 * to the other slot this boot. 343 */ 344 sd->fw_slot = 1 - sd->fw_slot; 345 vb2_nv_set(ctx, VB2_NV_TRY_NEXT, sd->fw_slot); 346 } 347 348 if (tries > 0) { 349 /* Still trying this firmware */ 350 vb2_nv_set(ctx, VB2_NV_FW_RESULT, VB2_FW_RESULT_TRYING); 351 352 /* Decrement non-zero try count */ 353 vb2_nv_set(ctx, VB2_NV_TRY_COUNT, tries - 1); 354 } 355 356 /* Store the slot we're trying */ 357 vb2_nv_set(ctx, VB2_NV_FW_TRIED, sd->fw_slot); 358 359 /* Set context flag if we're using slot B */ 360 if (sd->fw_slot) 361 ctx->flags |= VB2_CONTEXT_FW_SLOT_B; 362 363 /* Set status flag */ 364 sd->status |= VB2_SD_STATUS_CHOSE_SLOT; 365 366 return VB2_SUCCESS; 367 } 368