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