blob: 233237b8dd2a712f050984c280021686fa39a956 [file] [log] [blame]
Alex Deymoaea4c1c2015-08-19 20:24:43 -07001//
2// Copyright (C) 2009 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//
rspangler@google.com49fdf182009-10-10 00:57:34 +000016
Alex Deymo39910dc2015-11-09 17:04:30 -080017#include "update_engine/common/hash_calculator.h"
Alex Deymoaab50e32014-11-10 19:55:35 -080018
rspangler@google.com49fdf182009-10-10 00:57:34 +000019#include <math.h>
20#include <unistd.h>
Darin Petkovd7061ab2010-10-06 14:37:09 -070021
Darin Petkov36a58222010-10-07 22:00:09 -070022#include <string>
Darin Petkovd7061ab2010-10-06 14:37:09 -070023#include <vector>
24
Sen Jiang2703ef42017-03-16 13:36:21 -070025#include <brillo/data_encoding.h>
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070026#include <brillo/secure_blob.h>
rspangler@google.com49fdf182009-10-10 00:57:34 +000027#include <gtest/gtest.h>
Darin Petkovd7061ab2010-10-06 14:37:09 -070028
Alex Deymo39910dc2015-11-09 17:04:30 -080029#include "update_engine/common/utils.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000030
Darin Petkov36a58222010-10-07 22:00:09 -070031using std::string;
Darin Petkovd7061ab2010-10-06 14:37:09 -070032using std::vector;
33
rspangler@google.com49fdf182009-10-10 00:57:34 +000034namespace chromeos_update_engine {
35
Darin Petkovd7061ab2010-10-06 14:37:09 -070036// Generated by running this on a linux shell:
Sen Jiang2703ef42017-03-16 13:36:21 -070037// $ echo -n hi | openssl dgst -sha256 -binary |
38// hexdump -v -e '" " 12/1 "0x%02x, " "\n"'
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080039static const uint8_t kExpectedRawHash[] = {
Darin Petkovd7061ab2010-10-06 14:37:09 -070040 0x8f, 0x43, 0x43, 0x46, 0x64, 0x8f, 0x6b, 0x96,
41 0xdf, 0x89, 0xdd, 0xa9, 0x01, 0xc5, 0x17, 0x6b,
42 0x10, 0xa6, 0xd8, 0x39, 0x61, 0xdd, 0x3c, 0x1a,
43 0xc8, 0x8b, 0x59, 0xb2, 0xdc, 0x32, 0x7a, 0xa4
44};
45
Alex Deymo39910dc2015-11-09 17:04:30 -080046class HashCalculatorTest : public ::testing::Test {
Alex Vakulenkod2779df2014-06-16 13:19:00 -070047 public:
Alex Deymo39910dc2015-11-09 17:04:30 -080048 HashCalculatorTest() {}
Han Shen2643cb72012-06-26 14:45:33 -070049};
50
Alex Deymo39910dc2015-11-09 17:04:30 -080051TEST_F(HashCalculatorTest, SimpleTest) {
52 HashCalculator calc;
rspangler@google.com49fdf182009-10-10 00:57:34 +000053 calc.Update("hi", 2);
54 calc.Finalize();
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070055 brillo::Blob raw_hash(std::begin(kExpectedRawHash),
56 std::end(kExpectedRawHash));
Darin Petkovd7061ab2010-10-06 14:37:09 -070057 EXPECT_TRUE(raw_hash == calc.raw_hash());
rspangler@google.com49fdf182009-10-10 00:57:34 +000058}
59
Alex Deymo39910dc2015-11-09 17:04:30 -080060TEST_F(HashCalculatorTest, MultiUpdateTest) {
61 HashCalculator calc;
rspangler@google.com49fdf182009-10-10 00:57:34 +000062 calc.Update("h", 1);
63 calc.Update("i", 1);
64 calc.Finalize();
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070065 brillo::Blob raw_hash(std::begin(kExpectedRawHash),
66 std::end(kExpectedRawHash));
Darin Petkovd7061ab2010-10-06 14:37:09 -070067 EXPECT_TRUE(raw_hash == calc.raw_hash());
rspangler@google.com49fdf182009-10-10 00:57:34 +000068}
69
Alex Deymo39910dc2015-11-09 17:04:30 -080070TEST_F(HashCalculatorTest, ContextTest) {
71 HashCalculator calc;
Darin Petkov73058b42010-10-06 16:32:19 -070072 calc.Update("h", 1);
Darin Petkov36a58222010-10-07 22:00:09 -070073 string calc_context = calc.GetContext();
74 calc.Finalize();
Alex Deymo39910dc2015-11-09 17:04:30 -080075 HashCalculator calc_next;
Darin Petkov36a58222010-10-07 22:00:09 -070076 calc_next.SetContext(calc_context);
Darin Petkov73058b42010-10-06 16:32:19 -070077 calc_next.Update("i", 1);
78 calc_next.Finalize();
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070079 brillo::Blob raw_hash(std::begin(kExpectedRawHash),
80 std::end(kExpectedRawHash));
Darin Petkov36a58222010-10-07 22:00:09 -070081 EXPECT_TRUE(raw_hash == calc_next.raw_hash());
Darin Petkov73058b42010-10-06 16:32:19 -070082}
83
Alex Deymo39910dc2015-11-09 17:04:30 -080084TEST_F(HashCalculatorTest, BigTest) {
85 HashCalculator calc;
rspangler@google.com49fdf182009-10-10 00:57:34 +000086
Andrew de los Reyes21067cc2011-06-28 15:27:03 -070087 int digit_count = 1;
88 int next_overflow = 10;
rspangler@google.com49fdf182009-10-10 00:57:34 +000089 for (int i = 0; i < 1000000; i++) {
90 char buf[8];
Andrew de los Reyes21067cc2011-06-28 15:27:03 -070091 if (i == next_overflow) {
92 next_overflow *= 10;
93 digit_count++;
94 }
95 ASSERT_EQ(digit_count, snprintf(buf, sizeof(buf), "%d", i)) << " i = " << i;
rspangler@google.com49fdf182009-10-10 00:57:34 +000096 calc.Update(buf, strlen(buf));
97 }
98 calc.Finalize();
99
100 // Hash constant generated by running this on a linux shell:
101 // $ C=0
102 // $ while [ $C -lt 1000000 ]; do
103 // echo -n $C
104 // let C=C+1
Darin Petkovd22cb292010-09-29 10:02:29 -0700105 // done | openssl dgst -sha256 -binary | openssl base64
Sen Jiang2703ef42017-03-16 13:36:21 -0700106 EXPECT_EQ("NZf8k6SPBkYMvhaX8YgzuMgbkLP1XZ+neM8K5wcSsf8=",
107 brillo::data_encoding::Base64Encode(calc.raw_hash()));
rspangler@google.com49fdf182009-10-10 00:57:34 +0000108}
109
Alex Deymo39910dc2015-11-09 17:04:30 -0800110TEST_F(HashCalculatorTest, UpdateFileSimpleTest) {
Darin Petkov36a58222010-10-07 22:00:09 -0700111 string data_path;
112 ASSERT_TRUE(
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700113 utils::MakeTempFile("data.XXXXXX", &data_path, nullptr));
Darin Petkov36a58222010-10-07 22:00:09 -0700114 ScopedPathUnlinker data_path_unlinker(data_path);
115 ASSERT_TRUE(utils::WriteFile(data_path.c_str(), "hi", 2));
116
117 static const int kLengths[] = { -1, 2, 10 };
118 for (size_t i = 0; i < arraysize(kLengths); i++) {
Alex Deymo39910dc2015-11-09 17:04:30 -0800119 HashCalculator calc;
Darin Petkov36a58222010-10-07 22:00:09 -0700120 EXPECT_EQ(2, calc.UpdateFile(data_path, kLengths[i]));
121 EXPECT_TRUE(calc.Finalize());
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700122 brillo::Blob raw_hash(std::begin(kExpectedRawHash),
123 std::end(kExpectedRawHash));
Darin Petkov36a58222010-10-07 22:00:09 -0700124 EXPECT_TRUE(raw_hash == calc.raw_hash());
125 }
126
Alex Deymo39910dc2015-11-09 17:04:30 -0800127 HashCalculator calc;
Darin Petkov36a58222010-10-07 22:00:09 -0700128 EXPECT_EQ(0, calc.UpdateFile(data_path, 0));
129 EXPECT_EQ(1, calc.UpdateFile(data_path, 1));
130 EXPECT_TRUE(calc.Finalize());
131 // echo -n h | openssl dgst -sha256 -binary | openssl base64
Sen Jiang2703ef42017-03-16 13:36:21 -0700132 EXPECT_EQ("qqlAJmTxpB9A67xSyZk+tmrrNmYClY/fqig7ceZNsSM=",
133 brillo::data_encoding::Base64Encode(calc.raw_hash()));
Darin Petkov36a58222010-10-07 22:00:09 -0700134}
135
Alex Deymo39910dc2015-11-09 17:04:30 -0800136TEST_F(HashCalculatorTest, RawHashOfFileSimpleTest) {
Darin Petkov698d0412010-10-13 10:59:44 -0700137 string data_path;
138 ASSERT_TRUE(
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700139 utils::MakeTempFile("data.XXXXXX", &data_path, nullptr));
Darin Petkov698d0412010-10-13 10:59:44 -0700140 ScopedPathUnlinker data_path_unlinker(data_path);
141 ASSERT_TRUE(utils::WriteFile(data_path.c_str(), "hi", 2));
142
143 static const int kLengths[] = { -1, 2, 10 };
144 for (size_t i = 0; i < arraysize(kLengths); i++) {
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700145 brillo::Blob exp_raw_hash(std::begin(kExpectedRawHash),
146 std::end(kExpectedRawHash));
147 brillo::Blob raw_hash;
Alex Deymo39910dc2015-11-09 17:04:30 -0800148 EXPECT_EQ(2, HashCalculator::RawHashOfFile(data_path,
149 kLengths[i],
150 &raw_hash));
Darin Petkov698d0412010-10-13 10:59:44 -0700151 EXPECT_TRUE(exp_raw_hash == raw_hash);
152 }
153}
154
Alex Deymo39910dc2015-11-09 17:04:30 -0800155TEST_F(HashCalculatorTest, UpdateFileNonexistentTest) {
156 HashCalculator calc;
Darin Petkov36a58222010-10-07 22:00:09 -0700157 EXPECT_EQ(-1, calc.UpdateFile("/some/non-existent/file", -1));
158}
159
Alex Deymo39910dc2015-11-09 17:04:30 -0800160TEST_F(HashCalculatorTest, AbortTest) {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000161 // Just make sure we don't crash and valgrind doesn't detect memory leaks
162 {
Alex Deymo39910dc2015-11-09 17:04:30 -0800163 HashCalculator calc;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000164 }
165 {
Alex Deymo39910dc2015-11-09 17:04:30 -0800166 HashCalculator calc;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000167 calc.Update("h", 1);
168 }
169}
170
171} // namespace chromeos_update_engine