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 * Common functions between firmware and kernel verified boot. 6 * (Firmware portion) 7 */ 8 9 #include "2sysincludes.h" 10 #include "2rsa.h" 11 #include "2sha.h" 12 #include "vb2_common.h" 13 14 uint8_t *vb2_signature_data(struct vb2_signature *sig) 15 { 16 return (uint8_t *)sig + sig->sig_offset; 17 } 18 19 int vb2_verify_member_inside(const void *parent, size_t parent_size, 20 const void *member, size_t member_size, 21 ptrdiff_t member_data_offset, 22 size_t member_data_size) 23 { 24 const uintptr_t parent_end = (uintptr_t)parent + parent_size; 25 const ptrdiff_t member_offs = vb2_offset_of(parent, member); 26 const ptrdiff_t member_end_offs = member_offs + member_size; 27 const ptrdiff_t data_offs = member_offs + member_data_offset; 28 const ptrdiff_t data_end_offs = data_offs + member_data_size; 29 30 /* Make sure parent doesn't wrap */ 31 if (parent_size < 0 || parent_end < (uintptr_t)parent) 32 return VB2_ERROR_INSIDE_PARENT_WRAPS; 33 34 /* 35 * Make sure the member is fully contained in the parent and doesn't 36 * wrap. Use >, not >=, since member_size = 0 is possible. 37 */ 38 if (member_size < 0 || member_end_offs < member_offs) 39 return VB2_ERROR_INSIDE_MEMBER_WRAPS; 40 if (member_offs < 0 || member_offs > parent_size || 41 member_end_offs > parent_size) 42 return VB2_ERROR_INSIDE_MEMBER_OUTSIDE; 43 44 /* Make sure the member data is after the member */ 45 if (member_data_size > 0 && data_offs < member_end_offs) 46 return VB2_ERROR_INSIDE_DATA_OVERLAP; 47 48 /* Make sure parent fully contains member data, if any */ 49 if (member_data_size < 0 || data_end_offs < data_offs) 50 return VB2_ERROR_INSIDE_DATA_WRAPS; 51 if (data_offs < 0 || data_offs > parent_size || 52 data_end_offs > parent_size) 53 return VB2_ERROR_INSIDE_DATA_OUTSIDE; 54 55 return VB2_SUCCESS; 56 } 57 58 int vb2_verify_signature_inside(const void *parent, 59 uint32_t parent_size, 60 const struct vb2_signature *sig) 61 { 62 return vb2_verify_member_inside(parent, parent_size, 63 sig, sizeof(*sig), 64 sig->sig_offset, sig->sig_size); 65 } 66 67 int vb2_verify_digest(const struct vb2_public_key *key, 68 struct vb2_signature *sig, 69 const uint8_t *digest, 70 const struct vb2_workbuf *wb) 71 { 72 uint8_t *sig_data = vb2_signature_data(sig); 73 74 if (sig->sig_size != vb2_rsa_sig_size(key->sig_alg)) { 75 VB2_DEBUG("Wrong data signature size for algorithm, " 76 "sig_size=%d, expected %d for algorithm %d.\n", 77 sig->sig_size, vb2_rsa_sig_size(key->sig_alg), 78 key->sig_alg); 79 return VB2_ERROR_VDATA_SIG_SIZE; 80 } 81 82 return vb2_rsa_verify_digest(key, sig_data, digest, wb); 83 } 84 85 int vb2_verify_data(const uint8_t *data, 86 uint32_t size, 87 struct vb2_signature *sig, 88 const struct vb2_public_key *key, 89 const struct vb2_workbuf *wb) 90 { 91 struct vb2_workbuf wblocal = *wb; 92 struct vb2_digest_context *dc; 93 uint8_t *digest; 94 uint32_t digest_size; 95 int rv; 96 97 if (sig->data_size > size) { 98 VB2_DEBUG("Data buffer smaller than length of signed data.\n"); 99 return VB2_ERROR_VDATA_NOT_ENOUGH_DATA; 100 } 101 102 /* Digest goes at start of work buffer */ 103 digest_size = vb2_digest_size(key->hash_alg); 104 if (!digest_size) 105 return VB2_ERROR_VDATA_DIGEST_SIZE; 106 107 digest = vb2_workbuf_alloc(&wblocal, digest_size); 108 if (!digest) 109 return VB2_ERROR_VDATA_WORKBUF_DIGEST; 110 111 /* Hashing requires temp space for the context */ 112 dc = vb2_workbuf_alloc(&wblocal, sizeof(*dc)); 113 if (!dc) 114 return VB2_ERROR_VDATA_WORKBUF_HASHING; 115 116 rv = vb2_digest_init(dc, key->hash_alg); 117 if (rv) 118 return rv; 119 120 rv = vb2_digest_extend(dc, data, sig->data_size); 121 if (rv) 122 return rv; 123 124 rv = vb2_digest_finalize(dc, digest, digest_size); 125 if (rv) 126 return rv; 127 128 vb2_workbuf_free(&wblocal, sizeof(*dc)); 129 130 return vb2_verify_digest(key, sig, digest, &wblocal); 131 } 132 133 int vb2_verify_keyblock(struct vb2_keyblock *block, 134 uint32_t size, 135 const struct vb2_public_key *key, 136 const struct vb2_workbuf *wb) 137 { 138 struct vb2_signature *sig; 139 int rv; 140 141 /* Sanity checks before attempting signature of data */ 142 if(size < sizeof(*block)) { 143 VB2_DEBUG("Not enough space for key block header.\n"); 144 return VB2_ERROR_KEYBLOCK_TOO_SMALL_FOR_HEADER; 145 } 146 if (memcmp(block->magic, KEY_BLOCK_MAGIC, KEY_BLOCK_MAGIC_SIZE)) { 147 VB2_DEBUG("Not a valid verified boot key block.\n"); 148 return VB2_ERROR_KEYBLOCK_MAGIC; 149 } 150 if (block->header_version_major != KEY_BLOCK_HEADER_VERSION_MAJOR) { 151 VB2_DEBUG("Incompatible key block header version.\n"); 152 return VB2_ERROR_KEYBLOCK_HEADER_VERSION; 153 } 154 if (size < block->keyblock_size) { 155 VB2_DEBUG("Not enough data for key block.\n"); 156 return VB2_ERROR_KEYBLOCK_SIZE; 157 } 158 159 /* Check signature */ 160 sig = &block->keyblock_signature; 161 162 if (vb2_verify_signature_inside(block, block->keyblock_size, sig)) { 163 VB2_DEBUG("Key block signature off end of block\n"); 164 return VB2_ERROR_KEYBLOCK_SIG_OUTSIDE; 165 } 166 167 /* Make sure advertised signature data sizes are sane. */ 168 if (block->keyblock_size < sig->data_size) { 169 VB2_DEBUG("Signature calculated past end of block\n"); 170 return VB2_ERROR_KEYBLOCK_SIGNED_TOO_MUCH; 171 } 172 173 VB2_DEBUG("Checking key block signature...\n"); 174 rv = vb2_verify_data((const uint8_t *)block, size, sig, key, wb); 175 if (rv) { 176 VB2_DEBUG("Invalid key block signature.\n"); 177 return VB2_ERROR_KEYBLOCK_SIG_INVALID; 178 } 179 180 /* Verify we signed enough data */ 181 if (sig->data_size < sizeof(struct vb2_keyblock)) { 182 VB2_DEBUG("Didn't sign enough data\n"); 183 return VB2_ERROR_KEYBLOCK_SIGNED_TOO_LITTLE; 184 } 185 186 /* Verify data key is inside the block and inside signed data */ 187 if (vb2_verify_packed_key_inside(block, block->keyblock_size, 188 &block->data_key)) { 189 VB2_DEBUG("Data key off end of key block\n"); 190 return VB2_ERROR_KEYBLOCK_DATA_KEY_OUTSIDE; 191 } 192 if (vb2_verify_packed_key_inside(block, sig->data_size, 193 &block->data_key)) { 194 VB2_DEBUG("Data key off end of signed data\n"); 195 return VB2_ERROR_KEYBLOCK_DATA_KEY_UNSIGNED; 196 } 197 198 /* Success */ 199 return VB2_SUCCESS; 200 } 201 202 int vb2_verify_fw_preamble(struct vb2_fw_preamble *preamble, 203 uint32_t size, 204 const struct vb2_public_key *key, 205 const struct vb2_workbuf *wb) 206 { 207 struct vb2_signature *sig = &preamble->preamble_signature; 208 209 VB2_DEBUG("Verifying preamble.\n"); 210 211 /* Sanity checks before attempting signature of data */ 212 if(size < sizeof(*preamble)) { 213 VB2_DEBUG("Not enough data for preamble header\n"); 214 return VB2_ERROR_PREAMBLE_TOO_SMALL_FOR_HEADER; 215 } 216 if (preamble->header_version_major != 217 FIRMWARE_PREAMBLE_HEADER_VERSION_MAJOR) { 218 VB2_DEBUG("Incompatible firmware preamble header version.\n"); 219 return VB2_ERROR_PREAMBLE_HEADER_VERSION; 220 } 221 222 if (preamble->header_version_minor < 1) { 223 VB2_DEBUG("Only preamble header 2.1+ supported\n"); 224 return VB2_ERROR_PREAMBLE_HEADER_OLD; 225 } 226 227 if (size < preamble->preamble_size) { 228 VB2_DEBUG("Not enough data for preamble.\n"); 229 return VB2_ERROR_PREAMBLE_SIZE; 230 } 231 232 /* Check signature */ 233 if (vb2_verify_signature_inside(preamble, preamble->preamble_size, 234 sig)) { 235 VB2_DEBUG("Preamble signature off end of preamble\n"); 236 return VB2_ERROR_PREAMBLE_SIG_OUTSIDE; 237 } 238 239 /* Make sure advertised signature data sizes are sane. */ 240 if (preamble->preamble_size < sig->data_size) { 241 VB2_DEBUG("Signature calculated past end of the block\n"); 242 return VB2_ERROR_PREAMBLE_SIGNED_TOO_MUCH; 243 } 244 245 if (vb2_verify_data((const uint8_t *)preamble, size, sig, key, wb)) { 246 VB2_DEBUG("Preamble signature validation failed\n"); 247 return VB2_ERROR_PREAMBLE_SIG_INVALID; 248 } 249 250 /* Verify we signed enough data */ 251 if (sig->data_size < sizeof(struct vb2_fw_preamble)) { 252 VB2_DEBUG("Didn't sign enough data\n"); 253 return VB2_ERROR_PREAMBLE_SIGNED_TOO_LITTLE; 254 } 255 256 /* Verify body signature is inside the signed data */ 257 if (vb2_verify_signature_inside(preamble, sig->data_size, 258 &preamble->body_signature)) { 259 VB2_DEBUG("Firmware body signature off end of preamble\n"); 260 return VB2_ERROR_PREAMBLE_BODY_SIG_OUTSIDE; 261 } 262 263 /* Verify kernel subkey is inside the signed data */ 264 if (vb2_verify_packed_key_inside(preamble, sig->data_size, 265 &preamble->kernel_subkey)) { 266 VB2_DEBUG("Kernel subkey off end of preamble\n"); 267 return VB2_ERROR_PREAMBLE_KERNEL_SUBKEY_OUTSIDE; 268 } 269 270 /* Success */ 271 return VB2_SUCCESS; 272 } 273