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 * Signature validation functions 6 */ 7 8 #include "2sysincludes.h" 9 #include "2common.h" 10 #include "2rsa.h" 11 #include "2sha.h" 12 #include "vb2_common.h" 13 14 const char *vb2_common_desc(const void *buf) 15 { 16 const struct vb2_struct_common *c = buf; 17 18 return c->desc_size ? (const char *)c + c->fixed_size : ""; 19 } 20 21 int vb2_verify_common_header(const void *parent, uint32_t parent_size) 22 { 23 const struct vb2_struct_common *c = parent; 24 25 /* Parent buffer size must be at least the claimed total size */ 26 if (parent_size < c->total_size) 27 return VB2_ERROR_COMMON_TOTAL_SIZE; 28 29 /* 30 * And big enough for the fixed size, which itself must be at least as 31 * big as the common struct header. 32 */ 33 if (c->total_size < c->fixed_size || c->fixed_size < sizeof(*c)) 34 return VB2_ERROR_COMMON_FIXED_SIZE; 35 36 /* Make sure sizes are all multiples of 32 bits */ 37 if (!vb2_aligned(c->total_size, sizeof(uint32_t))) 38 return VB2_ERROR_COMMON_TOTAL_UNALIGNED; 39 if (!vb2_aligned(c->fixed_size, sizeof(uint32_t))) 40 return VB2_ERROR_COMMON_FIXED_UNALIGNED; 41 if (!vb2_aligned(c->desc_size, sizeof(uint32_t))) 42 return VB2_ERROR_COMMON_DESC_UNALIGNED; 43 44 /* Check description */ 45 if (c->desc_size > 0) { 46 /* Make sure description fits and doesn't wrap */ 47 if (c->fixed_size + c->desc_size < c->fixed_size) 48 return VB2_ERROR_COMMON_DESC_WRAPS; 49 if (c->fixed_size + c->desc_size > c->total_size) 50 return VB2_ERROR_COMMON_DESC_SIZE; 51 52 /* Description must be null-terminated */ 53 if (vb2_common_desc(c)[c->desc_size - 1] != 0) 54 return VB2_ERROR_COMMON_DESC_TERMINATOR; 55 } 56 57 return VB2_SUCCESS; 58 } 59 60 int vb2_verify_common_member(const void *parent, 61 uint32_t *min_offset, 62 uint32_t member_offset, 63 uint32_t member_size) 64 { 65 const struct vb2_struct_common *c = parent; 66 uint32_t member_end = member_offset + member_size; 67 68 /* Make sure member doesn't wrap */ 69 if (member_end < member_offset) 70 return VB2_ERROR_COMMON_MEMBER_WRAPS; 71 72 /* Member offset and size must be 32-bit aligned */ 73 if (!vb2_aligned(member_offset, sizeof(uint32_t)) || 74 !vb2_aligned(member_size, sizeof(uint32_t))) 75 return VB2_ERROR_COMMON_MEMBER_UNALIGNED; 76 77 /* Initialize minimum offset if necessary */ 78 if (!*min_offset) 79 *min_offset = c->fixed_size + c->desc_size; 80 81 /* Member must be after minimum offset */ 82 if (member_offset < *min_offset) 83 return VB2_ERROR_COMMON_MEMBER_OVERLAP; 84 85 /* Member must end before total size */ 86 if (member_end > c->total_size) 87 return VB2_ERROR_COMMON_MEMBER_SIZE; 88 89 /* Update minimum offset for subsequent checks */ 90 *min_offset = member_end; 91 92 return VB2_SUCCESS; 93 } 94 95 int vb2_verify_common_subobject(const void *parent, 96 uint32_t *min_offset, 97 uint32_t member_offset) 98 { 99 const struct vb2_struct_common *p = parent; 100 const struct vb2_struct_common *m = 101 (const struct vb2_struct_common *) 102 ((const uint8_t *)parent + member_offset); 103 int rv; 104 105 /* 106 * Verify the parent has space at the member offset for the common 107 * header. 108 */ 109 rv = vb2_verify_common_member(parent, min_offset, member_offset, 110 sizeof(*m)); 111 if (rv) 112 return rv; 113 114 /* 115 * Now it's safe to look at the member's header, and verify any 116 * additional data for the object past its common header fits in the 117 * parent. 118 */ 119 rv = vb2_verify_common_header(m, p->total_size - member_offset); 120 if (rv) 121 return rv; 122 123 /* Advance the min offset to the end of the subobject */ 124 *min_offset = member_offset + m->total_size; 125 126 return VB2_SUCCESS; 127 } 128 129 uint32_t vb2_sig_size(enum vb2_signature_algorithm sig_alg, 130 enum vb2_hash_algorithm hash_alg) 131 { 132 uint32_t digest_size = vb2_digest_size(hash_alg); 133 134 /* Fail if we don't support the hash algorithm */ 135 if (!digest_size) 136 return 0; 137 138 /* Handle unsigned hashes */ 139 if (sig_alg == VB2_SIG_NONE) 140 return digest_size; 141 142 return vb2_rsa_sig_size(sig_alg); 143 } 144 145 const struct vb2_guid *vb2_hash_guid(enum vb2_hash_algorithm hash_alg) 146 { 147 switch(hash_alg) { 148 #ifdef VB2_SUPPORT_SHA1 149 case VB2_HASH_SHA1: 150 { 151 static const struct vb2_guid guid = VB2_GUID_NONE_SHA1; 152 return &guid; 153 } 154 #endif 155 #ifdef VB2_SUPPORT_SHA256 156 case VB2_HASH_SHA256: 157 { 158 static const struct vb2_guid guid = 159 VB2_GUID_NONE_SHA256; 160 return &guid; 161 } 162 #endif 163 #ifdef VB2_SUPPORT_SHA512 164 case VB2_HASH_SHA512: 165 { 166 static const struct vb2_guid guid = 167 VB2_GUID_NONE_SHA512; 168 return &guid; 169 } 170 #endif 171 default: 172 return NULL; 173 } 174 } 175 176 int vb2_verify_signature(const struct vb2_signature *sig, uint32_t size) 177 { 178 uint32_t min_offset = 0; 179 uint32_t expect_sig_size; 180 int rv; 181 182 /* Check magic number */ 183 if (sig->c.magic != VB2_MAGIC_SIGNATURE) 184 return VB2_ERROR_SIG_MAGIC; 185 186 /* Make sure common header is good */ 187 rv = vb2_verify_common_header(sig, size); 188 if (rv) 189 return rv; 190 191 /* 192 * Check for compatible version. No need to check minor version, since 193 * that's compatible across readers matching the major version, and we 194 * haven't added any new fields. 195 */ 196 if (sig->c.struct_version_major != VB2_SIGNATURE_VERSION_MAJOR) 197 return VB2_ERROR_SIG_VERSION; 198 199 /* Make sure header is big enough for signature */ 200 if (sig->c.fixed_size < sizeof(*sig)) 201 return VB2_ERROR_SIG_HEADER_SIZE; 202 203 /* Make sure signature data is inside */ 204 rv = vb2_verify_common_member(sig, &min_offset, 205 sig->sig_offset, sig->sig_size); 206 if (rv) 207 return rv; 208 209 /* Make sure signature size is correct for the algorithm */ 210 expect_sig_size = vb2_sig_size(sig->sig_alg, sig->hash_alg); 211 if (!expect_sig_size) 212 return VB2_ERROR_SIG_ALGORITHM; 213 if (sig->sig_size != expect_sig_size) 214 return VB2_ERROR_SIG_SIZE; 215 216 return VB2_SUCCESS; 217 } 218 219 /** 220 * Return the signature data for a signature 221 */ 222 static uint8_t *vb2_signature_data(struct vb2_signature *sig) 223 { 224 return (uint8_t *)sig + sig->sig_offset; 225 } 226 227 int vb2_verify_digest(const struct vb2_public_key *key, 228 struct vb2_signature *sig, 229 const uint8_t *digest, 230 const struct vb2_workbuf *wb) 231 { 232 uint32_t key_sig_size = vb2_sig_size(key->sig_alg, key->hash_alg); 233 234 /* If we can't figure out the signature size, key algorithm was bad */ 235 if (!key_sig_size) 236 return VB2_ERROR_VDATA_ALGORITHM; 237 238 /* Make sure the signature and key algorithms match */ 239 if (key->sig_alg != sig->sig_alg || key->hash_alg != sig->hash_alg) 240 return VB2_ERROR_VDATA_ALGORITHM_MISMATCH; 241 242 if (sig->sig_size != key_sig_size) 243 return VB2_ERROR_VDATA_SIG_SIZE; 244 245 if (key->sig_alg == VB2_SIG_NONE) { 246 /* Bare hash */ 247 if (vb2_safe_memcmp(vb2_signature_data(sig), 248 digest, key_sig_size)) 249 return VB2_ERROR_VDATA_VERIFY_DIGEST; 250 251 return VB2_SUCCESS; 252 } else { 253 /* RSA-signed digest */ 254 return vb2_rsa_verify_digest(key, 255 vb2_signature_data(sig), 256 digest, wb); 257 } 258 } 259 260 int vb2_verify_data(const void *data, 261 uint32_t size, 262 struct vb2_signature *sig, 263 const struct vb2_public_key *key, 264 const struct vb2_workbuf *wb) 265 { 266 struct vb2_workbuf wblocal = *wb; 267 struct vb2_digest_context *dc; 268 uint8_t *digest; 269 uint32_t digest_size; 270 int rv; 271 272 if (sig->data_size != size) { 273 VB2_DEBUG("Wrong amount of data signed.\n"); 274 return VB2_ERROR_VDATA_SIZE; 275 } 276 277 /* Digest goes at start of work buffer */ 278 digest_size = vb2_digest_size(key->hash_alg); 279 if (!digest_size) 280 return VB2_ERROR_VDATA_DIGEST_SIZE; 281 282 digest = vb2_workbuf_alloc(&wblocal, digest_size); 283 if (!digest) 284 return VB2_ERROR_VDATA_WORKBUF_DIGEST; 285 286 /* Hashing requires temp space for the context */ 287 dc = vb2_workbuf_alloc(&wblocal, sizeof(*dc)); 288 if (!dc) 289 return VB2_ERROR_VDATA_WORKBUF_HASHING; 290 291 rv = vb2_digest_init(dc, key->hash_alg); 292 if (rv) 293 return rv; 294 295 rv = vb2_digest_extend(dc, data, size); 296 if (rv) 297 return rv; 298 299 rv = vb2_digest_finalize(dc, digest, digest_size); 300 if (rv) 301 return rv; 302 303 vb2_workbuf_free(&wblocal, sizeof(*dc)); 304 305 return vb2_verify_digest(key, sig, digest, &wblocal); 306 } 307 308 int vb2_verify_keyblock(struct vb2_keyblock *block, 309 uint32_t size, 310 const struct vb2_public_key *key, 311 const struct vb2_workbuf *wb) 312 { 313 uint32_t min_offset = 0, sig_offset; 314 int rv, i; 315 316 /* Check magic number */ 317 if (block->c.magic != VB2_MAGIC_KEYBLOCK) 318 return VB2_ERROR_KEYBLOCK_MAGIC; 319 320 /* Make sure common header is good */ 321 rv = vb2_verify_common_header(block, size); 322 if (rv) 323 return rv; 324 325 /* 326 * Check for compatible version. No need to check minor version, since 327 * that's compatible across readers matching the major version, and we 328 * haven't added any new fields. 329 */ 330 if (block->c.struct_version_major != VB2_KEYBLOCK_VERSION_MAJOR) 331 return VB2_ERROR_KEYBLOCK_HEADER_VERSION; 332 333 /* Make sure header is big enough */ 334 if (block->c.fixed_size < sizeof(*block)) 335 return VB2_ERROR_KEYBLOCK_SIZE; 336 337 /* Make sure data key is inside */ 338 rv = vb2_verify_common_subobject(block, &min_offset, block->key_offset); 339 if (rv) 340 return rv; 341 342 /* Loop over signatures */ 343 sig_offset = block->sig_offset; 344 for (i = 0; i < block->sig_count; i++, sig_offset = min_offset) { 345 struct vb2_signature *sig; 346 347 /* Make sure signature is inside keyblock */ 348 rv = vb2_verify_common_subobject(block, &min_offset, 349 sig_offset); 350 if (rv) 351 return rv; 352 353 sig = (struct vb2_signature *)((uint8_t *)block + sig_offset); 354 355 /* Verify the signature integrity */ 356 rv = vb2_verify_signature(sig, 357 block->c.total_size - sig_offset); 358 if (rv) 359 return rv; 360 361 /* Skip signature if it doesn't match the key GUID */ 362 if (memcmp(&sig->guid, key->guid, GUID_SIZE)) 363 continue; 364 365 /* Make sure we signed the right amount of data */ 366 if (sig->data_size != block->sig_offset) 367 return VB2_ERROR_KEYBLOCK_SIGNED_SIZE; 368 369 return vb2_verify_data(block, block->sig_offset, sig, key, wb); 370 } 371 372 /* If we're still here, no signature matched the key GUID */ 373 return VB2_ERROR_KEYBLOCK_SIG_GUID; 374 } 375 376 int vb2_verify_fw_preamble(struct vb2_fw_preamble *preamble, 377 uint32_t size, 378 const struct vb2_public_key *key, 379 const struct vb2_workbuf *wb) 380 { 381 struct vb2_signature *sig; 382 uint32_t min_offset = 0, hash_offset; 383 int rv, i; 384 385 /* Check magic number */ 386 if (preamble->c.magic != VB2_MAGIC_FW_PREAMBLE) 387 return VB2_ERROR_PREAMBLE_MAGIC; 388 389 /* Make sure common header is good */ 390 rv = vb2_verify_common_header(preamble, size); 391 if (rv) 392 return rv; 393 394 /* 395 * Check for compatible version. No need to check minor version, since 396 * that's compatible across readers matching the major version, and we 397 * haven't added any new fields. 398 */ 399 if (preamble->c.struct_version_major != VB2_FW_PREAMBLE_VERSION_MAJOR) 400 return VB2_ERROR_PREAMBLE_HEADER_VERSION; 401 402 /* Make sure header is big enough */ 403 if (preamble->c.fixed_size < sizeof(*preamble)) 404 return VB2_ERROR_PREAMBLE_SIZE; 405 406 /* Make sure all hash signatures are inside */ 407 hash_offset = preamble->hash_offset; 408 for (i = 0; i < preamble->hash_count; i++, hash_offset = min_offset) { 409 /* Make sure signature is inside preamble */ 410 rv = vb2_verify_common_subobject(preamble, &min_offset, 411 hash_offset); 412 if (rv) 413 return rv; 414 415 sig = (struct vb2_signature *) 416 ((uint8_t *)preamble + hash_offset); 417 418 /* Verify the signature integrity */ 419 rv = vb2_verify_signature( 420 sig, preamble->c.total_size - hash_offset); 421 if (rv) 422 return rv; 423 424 /* Hashes must all be unsigned */ 425 if (sig->sig_alg != VB2_SIG_NONE) 426 return VB2_ERROR_PREAMBLE_HASH_SIGNED; 427 } 428 429 /* Make sure signature is inside preamble */ 430 rv = vb2_verify_common_subobject(preamble, &min_offset, 431 preamble->sig_offset); 432 if (rv) 433 return rv; 434 435 /* Verify preamble signature */ 436 sig = (struct vb2_signature *)((uint8_t *)preamble + 437 preamble->sig_offset); 438 439 rv = vb2_verify_data(preamble, preamble->sig_offset, sig, key, wb); 440 if (rv) 441 return rv; 442 443 return VB2_SUCCESS; 444 } 445