1*61c4878aSAndroid Build Coastguard Worker // Copyright 2021 The Pigweed Authors
2*61c4878aSAndroid Build Coastguard Worker //
3*61c4878aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4*61c4878aSAndroid Build Coastguard Worker // use this file except in compliance with the License. You may obtain a copy of
5*61c4878aSAndroid Build Coastguard Worker // the License at
6*61c4878aSAndroid Build Coastguard Worker //
7*61c4878aSAndroid Build Coastguard Worker // https://www.apache.org/licenses/LICENSE-2.0
8*61c4878aSAndroid Build Coastguard Worker //
9*61c4878aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*61c4878aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11*61c4878aSAndroid Build Coastguard Worker // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12*61c4878aSAndroid Build Coastguard Worker // License for the specific language governing permissions and limitations under
13*61c4878aSAndroid Build Coastguard Worker // the License.
14*61c4878aSAndroid Build Coastguard Worker
15*61c4878aSAndroid Build Coastguard Worker #include "pw_crypto/sha256.h"
16*61c4878aSAndroid Build Coastguard Worker
17*61c4878aSAndroid Build Coastguard Worker #include <cstring>
18*61c4878aSAndroid Build Coastguard Worker
19*61c4878aSAndroid Build Coastguard Worker #include "pw_stream/memory_stream.h"
20*61c4878aSAndroid Build Coastguard Worker #include "pw_unit_test/framework.h"
21*61c4878aSAndroid Build Coastguard Worker
22*61c4878aSAndroid Build Coastguard Worker namespace pw::crypto::sha256 {
23*61c4878aSAndroid Build Coastguard Worker namespace {
24*61c4878aSAndroid Build Coastguard Worker
25*61c4878aSAndroid Build Coastguard Worker #define ASSERT_FAIL(expr) ASSERT_NE(OkStatus(), expr)
26*61c4878aSAndroid Build Coastguard Worker
27*61c4878aSAndroid Build Coastguard Worker #define AS_BYTES(s) as_bytes(span(s, sizeof(s) - 1))
28*61c4878aSAndroid Build Coastguard Worker
29*61c4878aSAndroid Build Coastguard Worker // Generated in Python 3 with:
30*61c4878aSAndroid Build Coastguard Worker // `hashlib.sha256('Hello, Pigweed!'.encode('ascii')).hexdigest()`.
31*61c4878aSAndroid Build Coastguard Worker #define SHA256_HASH_OF_HELLO_PIGWEED \
32*61c4878aSAndroid Build Coastguard Worker "\x8d\xce\x14\xee\x2c\xd9\xfd\x9b\xbd\x8c\x8d\x57\x68\x50\x2c\x2f" \
33*61c4878aSAndroid Build Coastguard Worker "\xfb\xb3\x52\x36\xce\x93\x47\x1b\x80\xfc\xa4\x7d\xb5\xf8\x41\x9d"
34*61c4878aSAndroid Build Coastguard Worker
35*61c4878aSAndroid Build Coastguard Worker // Generated in Python with `hashlib.sha256().hexdigest()`.
36*61c4878aSAndroid Build Coastguard Worker #define SHA256_HASH_OF_EMPTY_STRING \
37*61c4878aSAndroid Build Coastguard Worker "\xe3\xb0\xc4\x42\x98\xfc\x1c\x14\x9a\xfb\xf4\xc8\x99\x6f\xb9\x24" \
38*61c4878aSAndroid Build Coastguard Worker "\x27\xae\x41\xe4\x64\x9b\x93\x4c\xa4\x95\x99\x1b\x78\x52\xb8\x55"
39*61c4878aSAndroid Build Coastguard Worker
TEST(Hash,ComputesCorrectDigest)40*61c4878aSAndroid Build Coastguard Worker TEST(Hash, ComputesCorrectDigest) {
41*61c4878aSAndroid Build Coastguard Worker std::byte digest[kDigestSizeBytes];
42*61c4878aSAndroid Build Coastguard Worker
43*61c4878aSAndroid Build Coastguard Worker PW_TEST_ASSERT_OK(Hash(AS_BYTES("Hello, Pigweed!"), digest));
44*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(0,
45*61c4878aSAndroid Build Coastguard Worker std::memcmp(digest, SHA256_HASH_OF_HELLO_PIGWEED, sizeof(digest)));
46*61c4878aSAndroid Build Coastguard Worker }
47*61c4878aSAndroid Build Coastguard Worker
TEST(Hash,ComputesCorrectDigestFromReader)48*61c4878aSAndroid Build Coastguard Worker TEST(Hash, ComputesCorrectDigestFromReader) {
49*61c4878aSAndroid Build Coastguard Worker std::byte digest[kDigestSizeBytes];
50*61c4878aSAndroid Build Coastguard Worker ConstByteSpan message = AS_BYTES("Hello, Pigweed!");
51*61c4878aSAndroid Build Coastguard Worker
52*61c4878aSAndroid Build Coastguard Worker stream::MemoryReader reader(message);
53*61c4878aSAndroid Build Coastguard Worker PW_TEST_ASSERT_OK(Hash(reader, digest));
54*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(0,
55*61c4878aSAndroid Build Coastguard Worker std::memcmp(digest, SHA256_HASH_OF_HELLO_PIGWEED, sizeof(digest)));
56*61c4878aSAndroid Build Coastguard Worker }
57*61c4878aSAndroid Build Coastguard Worker
TEST(Hash,ComputesCorrectDigestOnEmptyMessage)58*61c4878aSAndroid Build Coastguard Worker TEST(Hash, ComputesCorrectDigestOnEmptyMessage) {
59*61c4878aSAndroid Build Coastguard Worker std::byte digest[kDigestSizeBytes];
60*61c4878aSAndroid Build Coastguard Worker
61*61c4878aSAndroid Build Coastguard Worker PW_TEST_ASSERT_OK(Hash({}, digest));
62*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(0,
63*61c4878aSAndroid Build Coastguard Worker std::memcmp(digest, SHA256_HASH_OF_EMPTY_STRING, sizeof(digest)));
64*61c4878aSAndroid Build Coastguard Worker }
65*61c4878aSAndroid Build Coastguard Worker
TEST(Hash,ComputesCorrectDigestOnEmptyMessageFromReader)66*61c4878aSAndroid Build Coastguard Worker TEST(Hash, ComputesCorrectDigestOnEmptyMessageFromReader) {
67*61c4878aSAndroid Build Coastguard Worker std::byte digest[kDigestSizeBytes];
68*61c4878aSAndroid Build Coastguard Worker
69*61c4878aSAndroid Build Coastguard Worker ConstByteSpan empty;
70*61c4878aSAndroid Build Coastguard Worker stream::MemoryReader reader(empty);
71*61c4878aSAndroid Build Coastguard Worker PW_TEST_ASSERT_OK(Hash(reader, digest));
72*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(0,
73*61c4878aSAndroid Build Coastguard Worker std::memcmp(digest, SHA256_HASH_OF_EMPTY_STRING, sizeof(digest)));
74*61c4878aSAndroid Build Coastguard Worker }
75*61c4878aSAndroid Build Coastguard Worker
TEST(Hash,DigestBufferTooSmall)76*61c4878aSAndroid Build Coastguard Worker TEST(Hash, DigestBufferTooSmall) {
77*61c4878aSAndroid Build Coastguard Worker std::array<std::byte, 31> digest = {};
78*61c4878aSAndroid Build Coastguard Worker ASSERT_FAIL(Hash({}, digest));
79*61c4878aSAndroid Build Coastguard Worker }
80*61c4878aSAndroid Build Coastguard Worker
TEST(Hash,DigestBufferTooSmallForReaderBasedAPI)81*61c4878aSAndroid Build Coastguard Worker TEST(Hash, DigestBufferTooSmallForReaderBasedAPI) {
82*61c4878aSAndroid Build Coastguard Worker std::array<std::byte, 31> digest = {};
83*61c4878aSAndroid Build Coastguard Worker ConstByteSpan empty;
84*61c4878aSAndroid Build Coastguard Worker stream::MemoryReader reader(empty);
85*61c4878aSAndroid Build Coastguard Worker ASSERT_FAIL(Hash(reader, digest));
86*61c4878aSAndroid Build Coastguard Worker }
87*61c4878aSAndroid Build Coastguard Worker
TEST(Hash,AcceptsLargerDigestBuffer)88*61c4878aSAndroid Build Coastguard Worker TEST(Hash, AcceptsLargerDigestBuffer) {
89*61c4878aSAndroid Build Coastguard Worker std::array<std::byte, 33> digest = {};
90*61c4878aSAndroid Build Coastguard Worker PW_TEST_ASSERT_OK(Hash({}, digest));
91*61c4878aSAndroid Build Coastguard Worker }
92*61c4878aSAndroid Build Coastguard Worker
TEST(Hash,AcceptsLargerDigestBufferForReaderBasedAPI)93*61c4878aSAndroid Build Coastguard Worker TEST(Hash, AcceptsLargerDigestBufferForReaderBasedAPI) {
94*61c4878aSAndroid Build Coastguard Worker std::array<std::byte, 33> digest = {};
95*61c4878aSAndroid Build Coastguard Worker
96*61c4878aSAndroid Build Coastguard Worker ConstByteSpan empty;
97*61c4878aSAndroid Build Coastguard Worker stream::MemoryReader reader(empty);
98*61c4878aSAndroid Build Coastguard Worker PW_TEST_ASSERT_OK(Hash(reader, digest));
99*61c4878aSAndroid Build Coastguard Worker }
100*61c4878aSAndroid Build Coastguard Worker
TEST(Sha256,AllowsSkippedUpdate)101*61c4878aSAndroid Build Coastguard Worker TEST(Sha256, AllowsSkippedUpdate) {
102*61c4878aSAndroid Build Coastguard Worker std::byte digest[kDigestSizeBytes];
103*61c4878aSAndroid Build Coastguard Worker
104*61c4878aSAndroid Build Coastguard Worker PW_TEST_ASSERT_OK(Sha256().Final(digest));
105*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(0,
106*61c4878aSAndroid Build Coastguard Worker std::memcmp(digest, SHA256_HASH_OF_EMPTY_STRING, sizeof(digest)));
107*61c4878aSAndroid Build Coastguard Worker }
108*61c4878aSAndroid Build Coastguard Worker
TEST(Sha256,AllowsEmptyUpdate)109*61c4878aSAndroid Build Coastguard Worker TEST(Sha256, AllowsEmptyUpdate) {
110*61c4878aSAndroid Build Coastguard Worker std::byte digest[kDigestSizeBytes];
111*61c4878aSAndroid Build Coastguard Worker PW_TEST_ASSERT_OK(Sha256().Update({}).Final(digest));
112*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(0,
113*61c4878aSAndroid Build Coastguard Worker std::memcmp(digest, SHA256_HASH_OF_EMPTY_STRING, sizeof(digest)));
114*61c4878aSAndroid Build Coastguard Worker }
115*61c4878aSAndroid Build Coastguard Worker
TEST(Sha256,AllowsMultipleUpdates)116*61c4878aSAndroid Build Coastguard Worker TEST(Sha256, AllowsMultipleUpdates) {
117*61c4878aSAndroid Build Coastguard Worker std::byte digest[kDigestSizeBytes];
118*61c4878aSAndroid Build Coastguard Worker PW_TEST_ASSERT_OK(Sha256()
119*61c4878aSAndroid Build Coastguard Worker .Update(AS_BYTES("Hello, "))
120*61c4878aSAndroid Build Coastguard Worker .Update(AS_BYTES("Pigweed!"))
121*61c4878aSAndroid Build Coastguard Worker .Final(digest));
122*61c4878aSAndroid Build Coastguard Worker ASSERT_EQ(0,
123*61c4878aSAndroid Build Coastguard Worker std::memcmp(digest, SHA256_HASH_OF_HELLO_PIGWEED, sizeof(digest)));
124*61c4878aSAndroid Build Coastguard Worker }
125*61c4878aSAndroid Build Coastguard Worker
TEST(Sha256,NoFinalAfterFinal)126*61c4878aSAndroid Build Coastguard Worker TEST(Sha256, NoFinalAfterFinal) {
127*61c4878aSAndroid Build Coastguard Worker std::byte digest[kDigestSizeBytes];
128*61c4878aSAndroid Build Coastguard Worker auto h = Sha256();
129*61c4878aSAndroid Build Coastguard Worker
130*61c4878aSAndroid Build Coastguard Worker PW_TEST_ASSERT_OK(h.Final(digest));
131*61c4878aSAndroid Build Coastguard Worker ASSERT_FAIL(h.Final(digest));
132*61c4878aSAndroid Build Coastguard Worker }
133*61c4878aSAndroid Build Coastguard Worker
TEST(Sha256,NoUpdateAfterFinal)134*61c4878aSAndroid Build Coastguard Worker TEST(Sha256, NoUpdateAfterFinal) {
135*61c4878aSAndroid Build Coastguard Worker std::byte digest[kDigestSizeBytes];
136*61c4878aSAndroid Build Coastguard Worker auto h = Sha256();
137*61c4878aSAndroid Build Coastguard Worker
138*61c4878aSAndroid Build Coastguard Worker PW_TEST_ASSERT_OK(h.Final(digest));
139*61c4878aSAndroid Build Coastguard Worker ASSERT_FAIL(h.Update(AS_BYTES("blah")).Final(digest));
140*61c4878aSAndroid Build Coastguard Worker }
141*61c4878aSAndroid Build Coastguard Worker
142*61c4878aSAndroid Build Coastguard Worker } // namespace
143*61c4878aSAndroid Build Coastguard Worker } // namespace pw::crypto::sha256
144