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