1efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved. 2efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler * Use of this source code is governed by a BSD-style license that can be 3efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler * found in the LICENSE file. 4efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler * 5efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler * Externally-callable APIs 6efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler * (Firmware portion) 7efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler */ 8efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 9efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler#include "2sysincludes.h" 10efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler#include "2api.h" 11efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler#include "2common.h" 12efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler#include "2misc.h" 13efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler#include "2nvstorage.h" 14efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler#include "2secdata.h" 15efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler#include "2sha.h" 16efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler#include "2rsa.h" 17108d991c678f80c99967bd07035de7418c81a072Randall Spangler#include "vb2_common.h" 18efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 19308d2540929cd95e2a565be95ce0b1d45d2fbed2Randall Spanglerint vb2api_fw_phase3(struct vb2_context *ctx) 20efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler{ 21efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler int rv; 22efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 23efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler /* Verify firmware keyblock */ 24308d2540929cd95e2a565be95ce0b1d45d2fbed2Randall Spangler rv = vb2_load_fw_keyblock(ctx); 25efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler if (rv) { 26efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler vb2_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv); 27efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler return rv; 28efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler } 29efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 30efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler /* Verify firmware preamble */ 31308d2540929cd95e2a565be95ce0b1d45d2fbed2Randall Spangler rv = vb2_load_fw_preamble(ctx); 32efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler if (rv) { 33efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler vb2_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv); 34efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler return rv; 35efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler } 36efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 37efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler return VB2_SUCCESS; 38efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler} 39efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 40efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spanglerint vb2api_init_hash2(struct vb2_context *ctx, 41efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler const struct vb2_guid *guid, 42efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler uint32_t *size) 43efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler{ 44efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler struct vb2_shared_data *sd = vb2_get_sd(ctx); 45308d2540929cd95e2a565be95ce0b1d45d2fbed2Randall Spangler const struct vb2_fw_preamble *pre; 46308d2540929cd95e2a565be95ce0b1d45d2fbed2Randall Spangler const struct vb2_signature *sig = NULL; 47efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler struct vb2_digest_context *dc; 48efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler struct vb2_workbuf wb; 49efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler uint32_t hash_offset; 50f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner int i, rv; 51efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 52efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler vb2_workbuf_from_ctx(ctx, &wb); 53efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 54efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler /* Get preamble pointer */ 55efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler if (!sd->workbuf_preamble_size) 56efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler return VB2_ERROR_API_INIT_HASH_PREAMBLE; 57308d2540929cd95e2a565be95ce0b1d45d2fbed2Randall Spangler pre = (const struct vb2_fw_preamble *) 58efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler (ctx->workbuf + sd->workbuf_preamble_offset); 59efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 60efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler /* Find the matching signature */ 61efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler hash_offset = pre->hash_offset; 62efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler for (i = 0; i < pre->hash_count; i++) { 63308d2540929cd95e2a565be95ce0b1d45d2fbed2Randall Spangler sig = (const struct vb2_signature *) 64efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler ((uint8_t *)pre + hash_offset); 65efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 66efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler if (!memcmp(guid, &sig->guid, sizeof(*guid))) 67efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler break; 68efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 69efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler hash_offset += sig->c.total_size; 70efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler } 71efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler if (i >= pre->hash_count) 72efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler return VB2_ERROR_API_INIT_HASH_GUID; /* No match */ 73efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 74efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler /* Allocate workbuf space for the hash */ 75efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler if (sd->workbuf_hash_size) { 76efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler dc = (struct vb2_digest_context *) 77efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler (ctx->workbuf + sd->workbuf_hash_offset); 78efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler } else { 79efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler uint32_t dig_size = sizeof(*dc); 80efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 81efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler dc = vb2_workbuf_alloc(&wb, dig_size); 82efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler if (!dc) 83efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler return VB2_ERROR_API_INIT_HASH_WORKBUF; 84efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 85efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler sd->workbuf_hash_offset = vb2_offset_of(ctx->workbuf, dc); 86efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler sd->workbuf_hash_size = dig_size; 87efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler ctx->workbuf_used = sd->workbuf_hash_offset + dig_size; 88efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler } 89efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 90efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler sd->hash_tag = vb2_offset_of(ctx->workbuf, sig); 91efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler sd->hash_remaining_size = sig->data_size; 92efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 93efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler if (size) 94efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler *size = sig->data_size; 95efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 96f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner if (!(pre->flags & VB2_FIRMWARE_PREAMBLE_DISALLOW_HWCRYPTO)) { 97f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner rv = vb2ex_hwcrypto_digest_init(sig->hash_alg, sig->data_size); 98f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner if (!rv) { 99f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner VB2_DEBUG("Using HW crypto engine for hash_alg %d\n", 100f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner sig->hash_alg); 101f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner dc->hash_alg = sig->hash_alg; 102f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner dc->using_hwcrypto = 1; 103f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner return VB2_SUCCESS; 104f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner } 105f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner if (rv != VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED) 106f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner return rv; 107f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner VB2_DEBUG("HW crypto for hash_alg %d not supported, using SW\n", 108f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner sig->hash_alg); 109f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner } else { 110f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner VB2_DEBUG("HW crypto forbidden by preamble, using SW\n"); 111f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner } 112f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner 113efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler return vb2_digest_init(dc, sig->hash_alg); 114efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler} 115efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 116308d2540929cd95e2a565be95ce0b1d45d2fbed2Randall Spanglerint vb2api_check_hash(struct vb2_context *ctx) 117efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler{ 118efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler struct vb2_shared_data *sd = vb2_get_sd(ctx); 119efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler struct vb2_digest_context *dc = (struct vb2_digest_context *) 120efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler (ctx->workbuf + sd->workbuf_hash_offset); 121efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler struct vb2_workbuf wb; 122efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 123efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler uint8_t *digest; 124efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler uint32_t digest_size = vb2_digest_size(dc->hash_alg); 125efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 126308d2540929cd95e2a565be95ce0b1d45d2fbed2Randall Spangler const struct vb2_signature *sig; 127efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 128efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler int rv; 129efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 130efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler vb2_workbuf_from_ctx(ctx, &wb); 131efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 132efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler /* Get signature pointer */ 133efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler if (!sd->hash_tag) 134efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler return VB2_ERROR_API_CHECK_HASH_TAG; 135308d2540929cd95e2a565be95ce0b1d45d2fbed2Randall Spangler sig = (const struct vb2_signature *)(ctx->workbuf + sd->hash_tag); 136efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 137efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler /* Must have initialized hash digest work area */ 138efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler if (!sd->workbuf_hash_size) 139efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler return VB2_ERROR_API_CHECK_HASH_WORKBUF; 140efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 141efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler /* Should have hashed the right amount of data */ 142efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler if (sd->hash_remaining_size) 143efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler return VB2_ERROR_API_CHECK_HASH_SIZE; 144efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 145efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler /* Allocate the digest */ 146efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler digest = vb2_workbuf_alloc(&wb, digest_size); 147efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler if (!digest) 148efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler return VB2_ERROR_API_CHECK_HASH_WORKBUF_DIGEST; 149efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 150efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler /* Finalize the digest */ 151f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner if (dc->using_hwcrypto) 152f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner rv = vb2ex_hwcrypto_digest_finalize(digest, digest_size); 153f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner else 154f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner rv = vb2_digest_finalize(dc, digest, digest_size); 155efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler if (rv) 156efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler return rv; 157efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 158efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler /* Compare with the signature */ 159efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler if (vb2_safe_memcmp(digest, (const uint8_t *)sig + sig->sig_offset, 160efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler digest_size)) 161efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler return VB2_ERROR_API_CHECK_HASH_SIG; 162efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 163efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler // TODO: the old check-hash function called vb2_fail() on any mismatch. 164efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler // I don't think it should do that; the caller should. 165efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 166efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler return VB2_SUCCESS; 167efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler} 168