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