1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Permission is hereby granted, free of charge, to any person 5 * obtaining a copy of this software and associated documentation 6 * files (the "Software"), to deal in the Software without 7 * restriction, including without limitation the rights to use, copy, 8 * modify, merge, publish, distribute, sublicense, and/or sell copies 9 * of the Software, and to permit persons to whom the Software is 10 * furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 */ 24 25 #include "avb_unittest_util.h" 26 27 #include <android-base/file.h> 28 29 std::string mem_to_hexstring(const uint8_t* data, size_t len) { 30 std::string ret; 31 char digits[17] = "0123456789abcdef"; 32 for (size_t n = 0; n < len; n++) { 33 ret.push_back(digits[data[n] >> 4]); 34 ret.push_back(digits[data[n] & 0x0f]); 35 } 36 return ret; 37 } 38 39 std::string string_trim(const std::string& str) { 40 size_t first = str.find_first_not_of(" \t\n"); 41 if (first == std::string::npos) { 42 return str; 43 } 44 size_t last = str.find_last_not_of(" \t\n"); 45 return str.substr(first, (last - first + 1)); 46 } 47 48 namespace avb { 49 50 void BaseAvbToolTest::SetUp() { 51 /* Change current directory to test executable directory so that relative path 52 * references to test dependencies don't rely on being manually run from 53 * correct directory */ 54 base::SetCurrentDirectory( 55 base::FilePath(android::base::GetExecutableDirectory())); 56 57 /* Create temporary directory to stash images in. */ 58 base::FilePath ret; 59 char* buf = strdup("/tmp/libavb-tests.XXXXXX"); 60 ASSERT_TRUE(mkdtemp(buf) != nullptr); 61 testdir_ = base::FilePath(buf); 62 free(buf); 63 64 /* Reset memory leak tracing */ 65 avb::testing_memory_reset(); 66 } 67 68 void BaseAvbToolTest::TearDown() { 69 /* Nuke temporary directory. */ 70 ASSERT_EQ(0U, testdir_.value().find("/tmp/libavb-tests")); 71 ASSERT_TRUE(base::DeleteFile(testdir_, true /* recursive */)); 72 /* Ensure all memory has been freed. */ 73 EXPECT_TRUE(avb::testing_memory_all_freed()); 74 } 75 76 std::string BaseAvbToolTest::CalcVBMetaDigest(const std::string& vbmeta_image, 77 const std::string& digest_alg) { 78 base::FilePath vbmeta_path = testdir_.Append(vbmeta_image); 79 base::FilePath vbmeta_digest_path = testdir_.Append("vbmeta_digest"); 80 EXPECT_COMMAND( 81 0, 82 "./avbtool calculate_vbmeta_digest --image %s --hash_algorithm %s" 83 " --output %s", 84 vbmeta_path.value().c_str(), 85 digest_alg.c_str(), 86 vbmeta_digest_path.value().c_str()); 87 std::string vbmeta_digest_data; 88 EXPECT_TRUE(base::ReadFileToString(vbmeta_digest_path, &vbmeta_digest_data)); 89 return string_trim(vbmeta_digest_data); 90 } 91 92 void BaseAvbToolTest::GenerateVBMetaImage( 93 const std::string& image_name, 94 const std::string& algorithm, 95 uint64_t rollback_index, 96 const base::FilePath& key_path, 97 const std::string& additional_options) { 98 std::string signing_options; 99 if (algorithm == "") { 100 signing_options = " --algorithm NONE "; 101 } else { 102 signing_options = std::string(" --algorithm ") + algorithm + " --key " + 103 key_path.value() + " "; 104 } 105 vbmeta_image_path_ = testdir_.Append(image_name); 106 EXPECT_COMMAND(0, 107 "./avbtool make_vbmeta_image" 108 " --rollback_index %" PRIu64 109 " %s %s " 110 " --output %s", 111 rollback_index, 112 additional_options.c_str(), 113 signing_options.c_str(), 114 vbmeta_image_path_.value().c_str()); 115 int64_t file_size; 116 ASSERT_TRUE(base::GetFileSize(vbmeta_image_path_, &file_size)); 117 vbmeta_image_.resize(file_size); 118 ASSERT_TRUE(base::ReadFile(vbmeta_image_path_, 119 reinterpret_cast<char*>(vbmeta_image_.data()), 120 vbmeta_image_.size())); 121 } 122 123 /* Generate a file with name |file_name| of size |image_size| with 124 * known content (0x00 0x01 0x02 .. 0xff 0x00 0x01 ..). 125 */ 126 base::FilePath BaseAvbToolTest::GenerateImage(const std::string file_name, 127 size_t image_size, 128 uint8_t start_byte) { 129 std::vector<uint8_t> image; 130 image.resize(image_size); 131 for (size_t n = 0; n < image_size; n++) { 132 image[n] = uint8_t(n + start_byte); 133 } 134 base::FilePath image_path = testdir_.Append(file_name); 135 EXPECT_EQ(image_size, 136 static_cast<const size_t>( 137 base::WriteFile(image_path, 138 reinterpret_cast<const char*>(image.data()), 139 image.size()))); 140 return image_path; 141 } 142 143 std::string BaseAvbToolTest::InfoImage(const base::FilePath& image_path) { 144 base::FilePath tmp_path = testdir_.Append("info_output.txt"); 145 EXPECT_COMMAND(0, 146 "./avbtool info_image --image %s --output %s", 147 image_path.value().c_str(), 148 tmp_path.value().c_str()); 149 std::string info_data; 150 EXPECT_TRUE(base::ReadFileToString(tmp_path, &info_data)); 151 return info_data; 152 } 153 154 std::string BaseAvbToolTest::PublicKeyAVB(const base::FilePath& key_path) { 155 base::FilePath tmp_path = testdir_.Append("public_key.bin"); 156 EXPECT_COMMAND(0, 157 "./avbtool extract_public_key --key %s" 158 " --output %s", 159 key_path.value().c_str(), 160 tmp_path.value().c_str()); 161 std::string key_data; 162 EXPECT_TRUE(base::ReadFileToString(tmp_path, &key_data)); 163 return key_data; 164 } 165 166 } // namespace avb 167