sha256.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2021 Regents of the University of California.
4  *
5  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6  *
7  * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8  * terms of the GNU Lesser General Public License as published by the Free Software
9  * Foundation, either version 3 of the License, or (at your option) any later version.
10  *
11  * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13  * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14  *
15  * You should have received copies of the GNU General Public License and GNU Lesser
16  * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17  * <http://www.gnu.org/licenses/>.
18  *
19  * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20  */
21 
22 #include "ndn-cxx/util/sha256.hpp"
24 #include "ndn-cxx/security/impl/openssl.hpp"
28 
29 namespace ndn {
30 namespace util {
31 
32 const size_t Sha256::DIGEST_SIZE;
33 
35 {
36  reset();
37 }
38 
39 Sha256::Sha256(std::istream& is)
40  : m_output(make_unique<OBufferStream>())
41  , m_isEmpty(false)
42  , m_isFinalized(true)
43 {
44  namespace tr = security::transform;
45 
47 }
48 
49 void
51 {
52  namespace tr = security::transform;
53 
54  m_input = make_unique<tr::StepSource>();
55  m_output = make_unique<OBufferStream>();
56  m_isEmpty = true;
57  m_isFinalized = false;
58 
59  *m_input >> tr::digestFilter(DigestAlgorithm::SHA256) >> tr::streamSink(*m_output);
60 }
61 
64 {
65  if (!m_isFinalized) {
66  BOOST_ASSERT(m_input != nullptr);
67  m_input->end();
68  m_isFinalized = true;
69  }
70 
71  return m_output->buf();
72 }
73 
74 bool
76 {
77  const Buffer& lhs = *computeDigest();
78  const Buffer& rhs = *digest.computeDigest();
79 
80  if (lhs.size() != rhs.size()) {
81  return false;
82  }
83 
84  // constant-time buffer comparison to mitigate timing attacks
85  return CRYPTO_memcmp(lhs.data(), rhs.data(), lhs.size()) == 0;
86 }
87 
90 {
91  auto buf = src.computeDigest();
92  update(buf->data(), buf->size());
93  return *this;
94 }
95 
97 Sha256::operator<<(const std::string& str)
98 {
99  update(reinterpret_cast<const uint8_t*>(str.data()), str.size());
100  return *this;
101 }
102 
104 Sha256::operator<<(const Block& block)
105 {
106  update(block.wire(), block.size());
107  return *this;
108 }
109 
111 Sha256::operator<<(uint64_t value)
112 {
113  update(reinterpret_cast<const uint8_t*>(&value), sizeof(uint64_t));
114  return *this;
115 }
116 
117 void
118 Sha256::update(const uint8_t* buffer, size_t size)
119 {
120  if (m_isFinalized)
121  NDN_THROW(Error("Digest has been already finalized"));
122 
123  BOOST_ASSERT(m_input != nullptr);
124  m_input->write({buffer, size});
125  m_isEmpty = false;
126 }
127 
128 std::string
130 {
131  auto buf = computeDigest();
132  return toHex(*buf);
133 }
134 
136 Sha256::computeDigest(const uint8_t* buffer, size_t size)
137 {
138  Sha256 sha256;
139  sha256.update(buffer, size);
140  return sha256.computeDigest();
141 }
142 
143 std::ostream&
144 operator<<(std::ostream& os, Sha256& digest)
145 {
146  auto buf = digest.computeDigest();
147  printHex(os, *buf);
148  return os;
149 }
150 
151 } // namespace util
152 } // namespace ndn
Represents a TLV element of the NDN packet format.
Definition: block.hpp:45
const uint8_t * wire() const
Return a raw pointer to the beginning of the encoded wire.
Definition: block.cpp:296
size_t size() const
Return the size of the encoded wire, i.e.
Definition: block.cpp:305
General-purpose automatically managed/resized buffer.
Definition: buffer.hpp:42
implements an output stream that constructs ndn::Buffer
Provides stateful SHA-256 digest calculation.
Definition: sha256.hpp:45
ConstBufferPtr computeDigest()
Finalize and return the digest based on all previously supplied inputs.
Definition: sha256.cpp:63
Sha256()
Create an empty SHA-256 digest.
Definition: sha256.cpp:34
static const size_t DIGEST_SIZE
Length in bytes of a SHA-256 digest.
Definition: sha256.hpp:56
void update(const uint8_t *buffer, size_t size)
Add a raw buffer to the digest calculation.
Definition: sha256.cpp:118
bool operator==(Sha256 &digest)
Check if the supplied digest is equal to this digest.
Definition: sha256.cpp:75
Sha256 & operator<<(Sha256 &src)
Add existing digest to the digest calculation.
Definition: sha256.cpp:89
std::string toString()
Convert digest to std::string.
Definition: sha256.cpp:129
void reset()
Discard the current state and start a new digest calculation.
Definition: sha256.cpp:50
#define NDN_THROW(e)
Definition: exception.hpp:61
unique_ptr< Transform > digestFilter(DigestAlgorithm algo)
unique_ptr< Sink > streamSink(std::ostream &os)
Definition: stream-sink.cpp:53
std::ostream & operator<<(std::ostream &os, LogLevel level)
Output LogLevel as a string.
Definition: logger.cpp:31
Definition: data.cpp:25
void printHex(std::ostream &os, uint64_t num, bool wantUpperCase)
Output the hex representation of num to the output stream os.
std::string toHex(span< const uint8_t > buffer, bool wantUpperCase)
Return a string containing the hex representation of the bytes in buffer.
shared_ptr< const Buffer > ConstBufferPtr
Definition: buffer.hpp:139