C/C++ API Reference
Loading...
Searching...
No Matches
sha256.h
1// Copyright 2021 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14
15#pragma once
16
17#include <cstdint>
18
19#include "pw_bytes/span.h"
20#include "pw_crypto/sha256_backend.h"
21#include "pw_log/log.h"
22#include "pw_status/status.h"
23#include "pw_status/try.h"
24#include "pw_stream/stream.h"
25
27namespace pw::crypto {
28
30
31namespace sha256 {
32
34inline constexpr uint32_t kDigestSizeBytes = 32;
35
37enum class Sha256State {
39 kReady = 1,
40
43 kFinalized = 2,
44
46 kError = 3,
47};
48
49namespace backend {
50
51// Primitive operations to be implemented by backends.
52Status DoInit(NativeSha256Context& ctx);
53Status DoUpdate(NativeSha256Context& ctx, ConstByteSpan data);
54Status DoFinal(NativeSha256Context& ctx, ByteSpan out_digest);
55
56} // namespace backend
57
68class Sha256 {
69 public:
70 Sha256() {
71 if (!backend::DoInit(native_ctx_).ok()) {
72 PW_LOG_DEBUG("backend::DoInit() failed");
73 state_ = Sha256State::kError;
74 return;
75 }
76
77 state_ = Sha256State::kReady;
78 }
79
83 if (state_ != Sha256State::kReady) {
84 PW_LOG_DEBUG("The backend is not ready/initialized");
85 return *this;
86 }
87
88 if (!backend::DoUpdate(native_ctx_, data).ok()) {
89 PW_LOG_DEBUG("backend::DoUpdate() failed");
90 state_ = Sha256State::kError;
91 return *this;
92 }
93
94 return *this;
95 }
96
105 Status Final(ByteSpan out_digest) {
106 if (out_digest.size() < kDigestSizeBytes) {
107 PW_LOG_DEBUG("Digest output buffer is too small");
108 state_ = Sha256State::kError;
110 }
111
112 if (state_ != Sha256State::kReady) {
113 PW_LOG_DEBUG("The backend is not ready/initialized");
115 }
116
117 auto status = backend::DoFinal(native_ctx_, out_digest);
118 if (!status.ok()) {
119 PW_LOG_DEBUG("backend::DoFinal() failed");
120 state_ = Sha256State::kError;
121 return status;
122 }
123
125 return OkStatus();
126 }
127
128 private:
129 // Common hasher state. Tracked by the front-end.
130 Sha256State state_;
131 // Backend-specific context.
132 backend::NativeSha256Context native_ctx_;
133};
134
167inline Status Hash(ConstByteSpan message, ByteSpan out_digest) {
168 return Sha256().Update(message).Final(out_digest);
169}
170
171inline Status Hash(stream::Reader& reader, ByteSpan out_digest) {
172 if (out_digest.size() < kDigestSizeBytes) {
174 }
175
176 Sha256 sha256;
177 while (true) {
178 Result<ByteSpan> res = reader.Read(out_digest);
179 if (res.status().IsOutOfRange()) {
180 break;
181 }
182
183 PW_TRY(res.status());
184 sha256.Update(res.value());
185 }
186
187 return sha256.Final(out_digest);
188}
189
190} // namespace sha256
191
192} // namespace pw::crypto
Definition: poll.h:25
Definition: status.h:109
static constexpr Status InvalidArgument()
Argument was malformed; e.g. invalid characters when parsing integer.
Definition: status.h:131
static constexpr Status FailedPrecondition()
System isn’t in the required state; e.g. deleting a non-empty directory.
Definition: status.h:162
Definition: sha256.h:68
Definition: stream.h:351
Result< ByteSpan > Read(ByteSpan dest)
Definition: stream.h:122
Sha256State
A state machine of a hashing session.
Definition: sha256.h:37
Status Final(ByteSpan out_digest)
Definition: sha256.h:105
Sha256 & Update(ConstByteSpan data)
Definition: sha256.h:82
constexpr uint32_t kDigestSizeBytes
The size of a SHA256 digest in bytes.
Definition: sha256.h:34
Status Hash(ConstByteSpan message, ByteSpan out_digest)
Definition: sha256.h:167
@ kReady
Initialized and accepting input (via Update()).
@ kError
In an unrecoverable error state.
#define PW_TRY(expr)
Returns early if expr is a non-OK Status or Result.
Definition: try.h:27
constexpr Status OkStatus()
Definition: status.h:297
Cryptography library.
Definition: ecdsa.h:20