1//
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//
16
17#ifndef UPDATE_ENGINE_COMMON_HASH_CALCULATOR_H_
18#define UPDATE_ENGINE_COMMON_HASH_CALCULATOR_H_
19
20#include <openssl/sha.h>
21#include <unistd.h>
22
23#include <string>
24#include <vector>
25
26#include <base/logging.h>
27#include <base/macros.h>
28#include <brillo/secure_blob.h>
29
30// This class provides a simple wrapper around OpenSSL providing a hash of data
31// passed in.
32// The methods of this class must be called in a very specific order: First the
33// ctor (of course), then 0 or more calls to Update(), then Finalize(), then 0
34// or more calls to raw_hash().
35
36namespace chromeos_update_engine {
37
38class HashCalculator {
39 public:
40  HashCalculator();
41
42  // Update is called with all of the data that should be hashed in order.
43  // Update will read |length| bytes of |data|.
44  // Returns true on success.
45  bool Update(const void* data, size_t length);
46
47  // Updates the hash with up to |length| bytes of data from |file|. If |length|
48  // is negative, reads in and updates with the whole file. Returns the number
49  // of bytes that the hash was updated with, or -1 on error.
50  off_t UpdateFile(const std::string& name, off_t length);
51
52  // Call Finalize() when all data has been passed in. This method tells
53  // OpenSSL that no more data will come in.
54  // Returns true on success.
55  bool Finalize();
56
57  const brillo::Blob& raw_hash() const {
58    DCHECK(!raw_hash_.empty()) << "Call Finalize() first";
59    return raw_hash_;
60  }
61
62  // Gets the current hash context. Note that the string will contain binary
63  // data (including \0 characters).
64  std::string GetContext() const;
65
66  // Sets the current hash context. |context| must the string returned by a
67  // previous HashCalculator::GetContext method call. Returns true on success,
68  // and false otherwise.
69  bool SetContext(const std::string& context);
70
71  static bool RawHashOfBytes(const void* data,
72                             size_t length,
73                             brillo::Blob* out_hash);
74  static bool RawHashOfData(const brillo::Blob& data,
75                            brillo::Blob* out_hash);
76  static off_t RawHashOfFile(const std::string& name, off_t length,
77                             brillo::Blob* out_hash);
78
79 private:
80  // If non-empty, the final raw hash. Will only be set to non-empty when
81  // Finalize is called.
82  brillo::Blob raw_hash_;
83
84  // Init success
85  bool valid_;
86
87  // The hash state used by OpenSSL
88  SHA256_CTX ctx_;
89  DISALLOW_COPY_AND_ASSIGN(HashCalculator);
90};
91
92}  // namespace chromeos_update_engine
93
94#endif  // UPDATE_ENGINE_COMMON_HASH_CALCULATOR_H_
95