1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <ctype.h> 18 #include <stdlib.h> 19 #include <android-base/strings.h> 20 #include "fec_private.h" 21 22 /* converts a hex nibble into an int */ 23 static inline int hextobin(char c) 24 { 25 if (c >= '0' && c <= '9') { 26 return c - '0'; 27 } else if (c >= 'a' && c <= 'f') { 28 return c - 'a' + 10; 29 } else { 30 errno = EINVAL; 31 return -1; 32 } 33 } 34 35 /* converts a hex string `src' of `size' characters to binary and copies the 36 the result into `dst' */ 37 static int parse_hex(uint8_t *dst, uint32_t size, const char *src) 38 { 39 int l, h; 40 41 check(dst); 42 check(src); 43 check(2 * size == strlen(src)); 44 45 while (size) { 46 h = hextobin(tolower(*src++)); 47 l = hextobin(tolower(*src++)); 48 49 check(l >= 0); 50 check(h >= 0); 51 52 *dst++ = (h << 4) | l; 53 --size; 54 } 55 56 return 0; 57 } 58 59 /* parses a 64-bit unsigned integer from string `src' into `dst' and if 60 `maxval' is >0, checks that `dst' <= `maxval' */ 61 static int parse_uint64(const char *src, uint64_t maxval, uint64_t *dst) 62 { 63 char *end; 64 unsigned long long int value; 65 66 check(src); 67 check(dst); 68 69 errno = 0; 70 value = strtoull(src, &end, 0); 71 72 if (*src == '\0' || *end != '\0' || 73 (errno == ERANGE && value == ULLONG_MAX)) { 74 errno = EINVAL; 75 return -1; 76 } 77 78 if (maxval && value > maxval) { 79 errno = EINVAL; 80 return -1; 81 } 82 83 *dst = (uint64_t)value; 84 return 0; 85 } 86 87 /* computes the size of verity hash tree for `file_size' bytes and returns the 88 number of hash tree levels in `verity_levels,' and the number of hashes per 89 level in `level_hashes', if the parameters are non-NULL */ 90 uint64_t verity_get_size(uint64_t file_size, uint32_t *verity_levels, 91 uint32_t *level_hashes) 92 { 93 /* we assume a known metadata size, 4 KiB block size, and SHA-256 to avoid 94 relying on disk content */ 95 96 uint32_t level = 0; 97 uint64_t total = 0; 98 uint64_t hashes = file_size / FEC_BLOCKSIZE; 99 100 do { 101 if (level_hashes) { 102 level_hashes[level] = hashes; 103 } 104 105 hashes = fec_div_round_up(hashes * SHA256_DIGEST_LENGTH, FEC_BLOCKSIZE); 106 total += hashes; 107 108 ++level; 109 } while (hashes > 1); 110 111 if (verity_levels) { 112 *verity_levels = level; 113 } 114 115 return total * FEC_BLOCKSIZE; 116 } 117 118 /* computes a SHA-256 salted with `f->verity.salt' from a FEC_BLOCKSIZE byte 119 buffer `block', and copies the hash to `hash' */ 120 static inline int verity_hash(fec_handle *f, const uint8_t *block, 121 uint8_t *hash) 122 { 123 SHA256_CTX ctx; 124 SHA256_Init(&ctx); 125 126 check(f); 127 check(f->verity.salt); 128 SHA256_Update(&ctx, f->verity.salt, f->verity.salt_size); 129 130 check(block); 131 SHA256_Update(&ctx, block, FEC_BLOCKSIZE); 132 133 check(hash); 134 SHA256_Final(hash, &ctx); 135 return 0; 136 } 137 138 /* computes a verity hash for FEC_BLOCKSIZE bytes from buffer `block' and 139 compares it to the expected value in `expected' */ 140 bool verity_check_block(fec_handle *f, const uint8_t *expected, 141 const uint8_t *block) 142 { 143 check(f); 144 check(block); 145 146 uint8_t hash[SHA256_DIGEST_LENGTH]; 147 148 if (unlikely(verity_hash(f, block, hash) == -1)) { 149 error("failed to hash"); 150 return false; 151 } 152 153 check(expected); 154 return !memcmp(expected, hash, SHA256_DIGEST_LENGTH); 155 } 156 157 /* reads a verity hash and the corresponding data block using error correction, 158 if available */ 159 static bool ecc_read_hashes(fec_handle *f, uint64_t hash_offset, 160 uint8_t *hash, uint64_t data_offset, uint8_t *data) 161 { 162 check(f); 163 164 if (hash && fec_pread(f, hash, SHA256_DIGEST_LENGTH, hash_offset) != 165 SHA256_DIGEST_LENGTH) { 166 error("failed to read hash tree: offset %" PRIu64 ": %s", hash_offset, 167 strerror(errno)); 168 return false; 169 } 170 171 check(data); 172 173 if (fec_pread(f, data, FEC_BLOCKSIZE, data_offset) != FEC_BLOCKSIZE) { 174 error("failed to read hash tree: data_offset %" PRIu64 ": %s", 175 data_offset, strerror(errno)); 176 return false; 177 } 178 179 return true; 180 } 181 182 /* reads the verity hash tree, validates it against the root hash in `root', 183 corrects errors if necessary, and copies valid data blocks for later use 184 to `f->verity.hash' */ 185 static int verify_tree(fec_handle *f, const uint8_t *root) 186 { 187 uint8_t data[FEC_BLOCKSIZE]; 188 uint8_t hash[SHA256_DIGEST_LENGTH]; 189 190 check(f); 191 check(root); 192 193 verity_info *v = &f->verity; 194 uint32_t levels = 0; 195 196 /* calculate the size and the number of levels in the hash tree */ 197 v->hash_size = 198 verity_get_size(v->data_blocks * FEC_BLOCKSIZE, &levels, NULL); 199 200 check(v->hash_start < UINT64_MAX - v->hash_size); 201 check(v->hash_start + v->hash_size <= f->data_size); 202 203 uint64_t hash_offset = v->hash_start; 204 uint64_t data_offset = hash_offset + FEC_BLOCKSIZE; 205 206 v->hash_data_offset = data_offset; 207 208 /* validate the root hash */ 209 if (!raw_pread(f, data, FEC_BLOCKSIZE, hash_offset) || 210 !verity_check_block(f, root, data)) { 211 /* try to correct */ 212 if (!ecc_read_hashes(f, 0, NULL, hash_offset, data) || 213 !verity_check_block(f, root, data)) { 214 error("root hash invalid"); 215 return -1; 216 } else if (f->mode & O_RDWR && 217 !raw_pwrite(f, data, FEC_BLOCKSIZE, hash_offset)) { 218 error("failed to rewrite the root block: %s", strerror(errno)); 219 return -1; 220 } 221 } 222 223 debug("root hash valid"); 224 225 /* calculate the number of hashes on each level */ 226 uint32_t hashes[levels]; 227 228 verity_get_size(v->data_blocks * FEC_BLOCKSIZE, NULL, hashes); 229 230 /* calculate the size and offset for the data hashes */ 231 for (uint32_t i = 1; i < levels; ++i) { 232 uint32_t blocks = hashes[levels - i]; 233 debug("%u hash blocks on level %u", blocks, levels - i); 234 235 v->hash_data_offset = data_offset; 236 v->hash_data_blocks = blocks; 237 238 data_offset += blocks * FEC_BLOCKSIZE; 239 } 240 241 check(v->hash_data_blocks); 242 check(v->hash_data_blocks <= v->hash_size / FEC_BLOCKSIZE); 243 244 check(v->hash_data_offset); 245 check(v->hash_data_offset <= 246 UINT64_MAX - (v->hash_data_blocks * FEC_BLOCKSIZE)); 247 check(v->hash_data_offset < f->data_size); 248 check(v->hash_data_offset + v->hash_data_blocks * FEC_BLOCKSIZE <= 249 f->data_size); 250 251 /* copy data hashes to memory in case they are corrupted, so we don't 252 have to correct them every time they are needed */ 253 std::unique_ptr<uint8_t[]> data_hashes( 254 new (std::nothrow) uint8_t[f->verity.hash_data_blocks * FEC_BLOCKSIZE]); 255 256 if (!data_hashes) { 257 errno = ENOMEM; 258 return -1; 259 } 260 261 /* validate the rest of the hash tree */ 262 data_offset = hash_offset + FEC_BLOCKSIZE; 263 264 for (uint32_t i = 1; i < levels; ++i) { 265 uint32_t blocks = hashes[levels - i]; 266 267 for (uint32_t j = 0; j < blocks; ++j) { 268 /* ecc reads are very I/O intensive, so read raw hash tree and do 269 error correcting only if it doesn't validate */ 270 if (!raw_pread(f, hash, SHA256_DIGEST_LENGTH, 271 hash_offset + j * SHA256_DIGEST_LENGTH) || 272 !raw_pread(f, data, FEC_BLOCKSIZE, 273 data_offset + j * FEC_BLOCKSIZE)) { 274 error("failed to read hashes: %s", strerror(errno)); 275 return -1; 276 } 277 278 if (!verity_check_block(f, hash, data)) { 279 /* try to correct */ 280 if (!ecc_read_hashes(f, 281 hash_offset + j * SHA256_DIGEST_LENGTH, hash, 282 data_offset + j * FEC_BLOCKSIZE, data) || 283 !verity_check_block(f, hash, data)) { 284 error("invalid hash tree: hash_offset %" PRIu64 ", " 285 "data_offset %" PRIu64 ", block %u", 286 hash_offset, data_offset, j); 287 return -1; 288 } 289 290 /* update the corrected blocks to the file if we are in r/w 291 mode */ 292 if (f->mode & O_RDWR) { 293 if (!raw_pwrite(f, hash, SHA256_DIGEST_LENGTH, 294 hash_offset + j * SHA256_DIGEST_LENGTH) || 295 !raw_pwrite(f, data, FEC_BLOCKSIZE, 296 data_offset + j * FEC_BLOCKSIZE)) { 297 error("failed to write hashes: %s", strerror(errno)); 298 return -1; 299 } 300 } 301 } 302 303 if (blocks == v->hash_data_blocks) { 304 memcpy(data_hashes.get() + j * FEC_BLOCKSIZE, data, 305 FEC_BLOCKSIZE); 306 } 307 } 308 309 hash_offset = data_offset; 310 data_offset += blocks * FEC_BLOCKSIZE; 311 } 312 313 debug("valid"); 314 315 if (v->hash) { 316 delete[] v->hash; 317 v->hash = NULL; 318 } 319 320 v->hash = data_hashes.release(); 321 return 0; 322 } 323 324 /* reads, corrects and parses the verity table, validates parameters, and if 325 `f->flags' does not have `FEC_VERITY_DISABLE' set, calls `verify_tree' to 326 load and validate the hash tree */ 327 static int parse_table(fec_handle *f, uint64_t offset, uint32_t size, bool useecc) 328 { 329 check(f); 330 check(size >= VERITY_MIN_TABLE_SIZE); 331 check(size <= VERITY_MAX_TABLE_SIZE); 332 333 debug("offset = %" PRIu64 ", size = %u", offset, size); 334 335 verity_info *v = &f->verity; 336 std::unique_ptr<char[]> table(new (std::nothrow) char[size + 1]); 337 338 if (!table) { 339 errno = ENOMEM; 340 return -1; 341 } 342 343 if (!useecc) { 344 if (!raw_pread(f, table.get(), size, offset)) { 345 error("failed to read verity table: %s", strerror(errno)); 346 return -1; 347 } 348 } else if (fec_pread(f, table.get(), size, offset) != (ssize_t)size) { 349 error("failed to ecc read verity table: %s", strerror(errno)); 350 return -1; 351 } 352 353 table[size] = '\0'; 354 debug("verity table: '%s'", table.get()); 355 356 int i = 0; 357 std::unique_ptr<uint8_t[]> salt; 358 uint8_t root[SHA256_DIGEST_LENGTH]; 359 360 auto tokens = android::base::Split(table.get(), " "); 361 362 for (const auto& token : tokens) { 363 switch (i++) { 364 case 0: /* version */ 365 if (token != stringify(VERITY_TABLE_VERSION)) { 366 error("unsupported verity table version: %s", token.c_str()); 367 return -1; 368 } 369 break; 370 case 3: /* data_block_size */ 371 case 4: /* hash_block_size */ 372 /* assume 4 KiB block sizes for everything */ 373 if (token != stringify(FEC_BLOCKSIZE)) { 374 error("unsupported verity block size: %s", token.c_str()); 375 return -1; 376 } 377 break; 378 case 5: /* num_data_blocks */ 379 if (parse_uint64(token.c_str(), f->data_size / FEC_BLOCKSIZE, 380 &v->data_blocks) == -1) { 381 error("invalid number of verity data blocks: %s", 382 token.c_str()); 383 return -1; 384 } 385 break; 386 case 6: /* hash_start_block */ 387 if (parse_uint64(token.c_str(), f->data_size / FEC_BLOCKSIZE, 388 &v->hash_start) == -1) { 389 error("invalid verity hash start block: %s", token.c_str()); 390 return -1; 391 } 392 393 v->hash_start *= FEC_BLOCKSIZE; 394 break; 395 case 7: /* algorithm */ 396 if (token != "sha256") { 397 error("unsupported verity hash algorithm: %s", token.c_str()); 398 return -1; 399 } 400 break; 401 case 8: /* digest */ 402 if (parse_hex(root, sizeof(root), token.c_str()) == -1) { 403 error("invalid verity root hash: %s", token.c_str()); 404 return -1; 405 } 406 break; 407 case 9: /* salt */ 408 v->salt_size = token.size(); 409 check(v->salt_size % 2 == 0); 410 v->salt_size /= 2; 411 412 salt.reset(new (std::nothrow) uint8_t[v->salt_size]); 413 414 if (!salt) { 415 errno = ENOMEM; 416 return -1; 417 } 418 419 if (parse_hex(salt.get(), v->salt_size, token.c_str()) == -1) { 420 error("invalid verity salt: %s", token.c_str()); 421 return -1; 422 } 423 break; 424 default: 425 break; 426 } 427 } 428 429 if (i < VERITY_TABLE_ARGS) { 430 error("not enough arguments in verity table: %d; expected at least " 431 stringify(VERITY_TABLE_ARGS), i); 432 return -1; 433 } 434 435 check(v->hash_start < f->data_size); 436 437 if (v->metadata_start < v->hash_start) { 438 check(v->data_blocks == v->metadata_start / FEC_BLOCKSIZE); 439 } else { 440 check(v->data_blocks == v->hash_start / FEC_BLOCKSIZE); 441 } 442 443 if (v->salt) { 444 delete[] v->salt; 445 v->salt = NULL; 446 } 447 448 v->salt = salt.release(); 449 450 if (v->table) { 451 delete[] v->table; 452 v->table = NULL; 453 } 454 455 v->table = table.release(); 456 457 if (!(f->flags & FEC_VERITY_DISABLE)) { 458 if (verify_tree(f, root) == -1) { 459 return -1; 460 } 461 462 check(v->hash); 463 464 uint8_t zero_block[FEC_BLOCKSIZE]; 465 memset(zero_block, 0, FEC_BLOCKSIZE); 466 467 if (verity_hash(f, zero_block, v->zero_hash) == -1) { 468 error("failed to hash"); 469 return -1; 470 } 471 } 472 473 return 0; 474 } 475 476 /* rewrites verity metadata block using error corrected data in `f->verity' */ 477 static int rewrite_metadata(fec_handle *f, uint64_t offset) 478 { 479 check(f); 480 check(f->data_size > VERITY_METADATA_SIZE); 481 check(offset <= f->data_size - VERITY_METADATA_SIZE); 482 483 std::unique_ptr<uint8_t[]> metadata( 484 new (std::nothrow) uint8_t[VERITY_METADATA_SIZE]); 485 486 if (!metadata) { 487 errno = ENOMEM; 488 return -1; 489 } 490 491 memset(metadata.get(), 0, VERITY_METADATA_SIZE); 492 493 verity_info *v = &f->verity; 494 memcpy(metadata.get(), &v->header, sizeof(v->header)); 495 496 check(v->table); 497 size_t len = strlen(v->table); 498 499 check(sizeof(v->header) + len <= VERITY_METADATA_SIZE); 500 memcpy(metadata.get() + sizeof(v->header), v->table, len); 501 502 return raw_pwrite(f, metadata.get(), VERITY_METADATA_SIZE, offset); 503 } 504 505 static int validate_header(const fec_handle *f, const verity_header *header, 506 uint64_t offset) 507 { 508 check(f); 509 check(header); 510 511 if (header->magic != VERITY_MAGIC && 512 header->magic != VERITY_MAGIC_DISABLE) { 513 return -1; 514 } 515 516 if (header->version != VERITY_VERSION) { 517 error("unsupported verity version %u", header->version); 518 return -1; 519 } 520 521 if (header->length < VERITY_MIN_TABLE_SIZE || 522 header->length > VERITY_MAX_TABLE_SIZE) { 523 error("invalid verity table size: %u; expected [" 524 stringify(VERITY_MIN_TABLE_SIZE) ", " 525 stringify(VERITY_MAX_TABLE_SIZE) ")", header->length); 526 return -1; 527 } 528 529 /* signature is skipped, because for our purposes it won't matter from 530 where the data originates; the caller of the library is responsible 531 for signature verification */ 532 533 if (offset > UINT64_MAX - header->length) { 534 error("invalid verity table length: %u", header->length); 535 return -1; 536 } else if (offset + header->length >= f->data_size) { 537 error("invalid verity table length: %u", header->length); 538 return -1; 539 } 540 541 return 0; 542 } 543 544 /* attempts to read verity metadata from `f->fd' position `offset'; if in r/w 545 mode, rewrites the metadata if it had errors */ 546 int verity_parse_header(fec_handle *f, uint64_t offset) 547 { 548 check(f); 549 check(f->data_size > VERITY_METADATA_SIZE); 550 551 if (offset > f->data_size - VERITY_METADATA_SIZE) { 552 debug("failed to read verity header: offset %" PRIu64 " is too far", 553 offset); 554 return -1; 555 } 556 557 verity_info *v = &f->verity; 558 uint64_t errors = f->errors; 559 560 if (!raw_pread(f, &v->header, sizeof(v->header), offset)) { 561 error("failed to read verity header: %s", strerror(errno)); 562 return -1; 563 } 564 565 /* use raw data to check for the alternative magic, because it will 566 be error corrected to VERITY_MAGIC otherwise */ 567 if (v->header.magic == VERITY_MAGIC_DISABLE) { 568 /* this value is not used by us, but can be used by a caller to 569 decide whether dm-verity should be enabled */ 570 v->disabled = true; 571 } 572 573 if (fec_pread(f, &v->ecc_header, sizeof(v->ecc_header), offset) != 574 sizeof(v->ecc_header)) { 575 warn("failed to read verity header: %s", strerror(errno)); 576 return -1; 577 } 578 579 if (validate_header(f, &v->header, offset)) { 580 /* raw verity header is invalid; this could be due to corruption, or 581 due to missing verity metadata */ 582 583 if (validate_header(f, &v->ecc_header, offset)) { 584 return -1; /* either way, we cannot recover */ 585 } 586 587 /* report mismatching fields */ 588 if (!v->disabled && v->header.magic != v->ecc_header.magic) { 589 warn("corrected verity header magic"); 590 v->header.magic = v->ecc_header.magic; 591 } 592 593 if (v->header.version != v->ecc_header.version) { 594 warn("corrected verity header version"); 595 v->header.version = v->ecc_header.version; 596 } 597 598 if (v->header.length != v->ecc_header.length) { 599 warn("corrected verity header length"); 600 v->header.length = v->ecc_header.length; 601 } 602 603 if (memcmp(v->header.signature, v->ecc_header.signature, 604 sizeof(v->header.signature))) { 605 warn("corrected verity header signature"); 606 /* we have no way of knowing which signature is correct, if either 607 of them is */ 608 } 609 } 610 611 v->metadata_start = offset; 612 613 if (parse_table(f, offset + sizeof(v->header), v->header.length, 614 false) == -1 && 615 parse_table(f, offset + sizeof(v->header), v->header.length, 616 true) == -1) { 617 return -1; 618 } 619 620 /* if we corrected something while parsing metadata and we are in r/w 621 mode, rewrite the corrected metadata */ 622 if (f->mode & O_RDWR && f->errors > errors && 623 rewrite_metadata(f, offset) < 0) { 624 warn("failed to rewrite verity metadata: %s", strerror(errno)); 625 } 626 627 if (v->metadata_start < v->hash_start) { 628 f->data_size = v->metadata_start; 629 } else { 630 f->data_size = v->hash_start; 631 } 632 633 return 0; 634 } 635 636 int fec_verity_set_status(struct fec_handle *f, bool enabled) 637 { 638 check(f); 639 640 if (!(f->mode & O_RDWR)) { 641 error("cannot update verity magic: read-only handle"); 642 errno = EBADF; 643 return -1; 644 } 645 646 verity_info *v = &f->verity; 647 648 if (!v->metadata_start) { 649 error("cannot update verity magic: no metadata found"); 650 errno = EINVAL; 651 return -1; 652 } 653 654 if (v->disabled == !enabled) { 655 return 0; /* nothing to do */ 656 } 657 658 uint32_t magic = enabled ? VERITY_MAGIC : VERITY_MAGIC_DISABLE; 659 660 if (!raw_pwrite(f, &magic, sizeof(magic), v->metadata_start)) { 661 error("failed to update verity magic to %08x: %s", magic, 662 strerror(errno)); 663 return -1; 664 } 665 666 warn("updated verity magic to %08x (%s)", magic, 667 enabled ? "enabled" : "disabled"); 668 v->disabled = !enabled; 669 670 return 0; 671 } 672