1 /* Copyright 2015 The ChromiumOS Authors
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 * (Kernel portion)
7 */
8
9 #include "2api.h"
10 #include "2common.h"
11 #include "2misc.h"
12 #include "2nvstorage.h"
13 #include "2rsa.h"
14 #include "2secdata.h"
15 #include "2sha.h"
16 #include "2sysincludes.h"
17
vb2api_load_kernel_vblock(struct vb2_context * ctx)18 vb2_error_t vb2api_load_kernel_vblock(struct vb2_context *ctx)
19 {
20 /* Verify kernel keyblock */
21 VB2_TRY(vb2_load_kernel_keyblock(ctx));
22
23 /* Verify kernel preamble */
24 VB2_TRY(vb2_load_kernel_preamble(ctx));
25
26 return VB2_SUCCESS;
27 }
28
vb2api_get_kernel_size(struct vb2_context * ctx,uint32_t * offset_ptr,uint32_t * size_ptr)29 vb2_error_t vb2api_get_kernel_size(struct vb2_context *ctx,
30 uint32_t *offset_ptr, uint32_t *size_ptr)
31 {
32 struct vb2_shared_data *sd = vb2_get_sd(ctx);
33 const struct vb2_kernel_preamble *pre;
34
35 /* Get preamble pointer */
36 if (!sd->preamble_size)
37 return VB2_ERROR_API_GET_KERNEL_SIZE_PREAMBLE;
38
39 pre = (const struct vb2_kernel_preamble *)
40 vb2_member_of(sd, sd->preamble_offset);
41
42 if (offset_ptr) {
43 /* The kernel implicitly follows the preamble */
44 *offset_ptr = sd->vblock_preamble_offset +
45 sd->preamble_size;
46 }
47
48 if (size_ptr) {
49 /* Expect the kernel to be the size of data we signed */
50 *size_ptr = pre->body_signature.data_size;
51 }
52
53 return VB2_SUCCESS;
54 }
55
vb2api_verify_kernel_data(struct vb2_context * ctx,const void * buf,uint32_t size)56 vb2_error_t vb2api_verify_kernel_data(struct vb2_context *ctx, const void *buf,
57 uint32_t size)
58 {
59 struct vb2_shared_data *sd = vb2_get_sd(ctx);
60 struct vb2_kernel_preamble *pre;
61 struct vb2_digest_context *dc;
62 struct vb2_public_key key;
63 struct vb2_workbuf wb;
64
65 uint8_t *digest;
66 uint32_t digest_size;
67
68 vb2_workbuf_from_ctx(ctx, &wb);
69
70 /* Get preamble pointer */
71 if (!sd->preamble_size)
72 return VB2_ERROR_API_VERIFY_KDATA_PREAMBLE;
73
74 pre = (struct vb2_kernel_preamble *)
75 vb2_member_of(sd, sd->preamble_offset);
76
77 /* Make sure we were passed the right amount of data */
78 if (size != pre->body_signature.data_size)
79 return VB2_ERROR_API_VERIFY_KDATA_SIZE;
80
81 /* Allocate workbuf space for the hash */
82 dc = vb2_workbuf_alloc(&wb, sizeof(*dc));
83 if (!dc)
84 return VB2_ERROR_API_VERIFY_KDATA_WORKBUF;
85
86 /*
87 * Unpack the kernel data key to see which hashing algorithm we
88 * should use.
89 *
90 * TODO: really, the kernel body should be hashed, and not signed,
91 * because the signature we're checking is already signed as part of
92 * the kernel preamble. But until we can change the signing scripts,
93 * we're stuck with a signature here instead of a hash.
94 */
95 if (!sd->data_key_size)
96 return VB2_ERROR_API_VERIFY_KDATA_KEY;
97
98 VB2_TRY(vb2_unpack_key_buffer(&key,
99 vb2_member_of(sd, sd->data_key_offset),
100 sd->data_key_size));
101
102 VB2_TRY(vb2_digest_init(dc, vb2api_hwcrypto_allowed(ctx),
103 key.hash_alg, size));
104
105 VB2_TRY(vb2_digest_extend(dc, buf, size));
106
107 digest_size = vb2_digest_size(key.hash_alg);
108 digest = vb2_workbuf_alloc(&wb, digest_size);
109 if (!digest)
110 return VB2_ERROR_API_CHECK_HASH_WORKBUF_DIGEST;
111
112 VB2_TRY(vb2_digest_finalize(dc, digest, digest_size));
113
114 /*
115 * The body signature is currently a *signature* of the body data, not
116 * just its hash. So we need to verify the signature.
117 */
118
119 /*
120 * Check digest vs. signature. Note that this destroys the signature.
121 * That's ok, because we only check each signature once per boot.
122 */
123 return vb2_verify_digest(&key, &pre->body_signature, digest, &wb);
124 }
125
vb2api_kernel_phase3(struct vb2_context * ctx)126 vb2_error_t vb2api_kernel_phase3(struct vb2_context *ctx)
127 {
128 struct vb2_shared_data *sd = vb2_get_sd(ctx);
129
130 /*
131 * If the kernel is a newer version than in secure storage, and the
132 * kernel signature is valid, and we're not in recovery mode, and we're
133 * allowed to, roll forward the version in secure storage.
134 */
135 if (sd->kernel_version > sd->kernel_version_secdata &&
136 (sd->flags & VB2_SD_FLAG_KERNEL_SIGNED) &&
137 !(ctx->flags & VB2_CONTEXT_RECOVERY_MODE) &&
138 (ctx->flags & VB2_CONTEXT_ALLOW_KERNEL_ROLL_FORWARD)) {
139 vb2_secdata_kernel_set(ctx, VB2_SECDATA_KERNEL_VERSIONS,
140 sd->kernel_version);
141 sd->kernel_version_secdata = sd->kernel_version;
142 }
143
144 return VB2_SUCCESS;
145 }
146