5 #include "sw/device/lib/crypto/impl/sha2/sha256.h"
11 #include "sw/device/lib/crypto/drivers/otbn.h"
12 #include "sw/device/lib/crypto/impl/status.h"
15 #define MODULE_ID MAKE_MODULE_ID('s', '2', '2')
24 kSha256MaxMessageChunksPerOtbnRun = 41,
31 uint32_t data[kSha256MessageBlockWords];
47 static const uint32_t kSha256InitialState[kSha256StateWords] = {
48 0x5be0cd19, 0x1f83d9ab, 0x9b05688c, 0x510e527f,
49 0xa54ff53a, 0x3c6ef372, 0xbb67ae85, 0x6a09e667,
51 static_assert(
sizeof(kSha256InitialState) == kSha256StateBytes,
52 "Initial state for SHA-256 has an unexpected size.");
61 static const otbn_addr_t kOtbnVarSha256State =
63 static const otbn_addr_t kOtbnVarSha256Msg =
OTBN_ADDR_T_INIT(run_sha256, msg);
64 static const otbn_addr_t kOtbnVarSha256NumMsgChunks =
85 otbn_dmem_write(1, &ctx->
num_blocks, kOtbnVarSha256NumMsgChunks));
88 HARDENED_TRY(otbn_execute());
89 HARDENED_TRY(otbn_busy_wait_for_done());
108 size_t offset = ctx->
num_blocks * kSha256MessageBlockBytes;
109 otbn_addr_t dst = kOtbnVarSha256Msg + offset;
112 otbn_dmem_write(kSha256MessageBlockWords, block->data, dst);
119 if (ctx->
num_blocks == kSha256MaxMessageChunksPerOtbnRun) {
120 HARDENED_TRY(process_message_buffer(ctx));
140 const uint64_t total_len,
142 size_t partial_block_len = (total_len >> 3) % kSha256MessageBlockBytes;
145 unsigned char *data_end = (
unsigned char *)block->data + partial_block_len;
148 size_t padding_len = kSha256MessageBlockBytes - partial_block_len;
149 memset(data_end, 0, padding_len);
154 memset(data_end, 0x80, 1);
156 if (partial_block_len + 1 +
sizeof(total_len) > kSha256MessageBlockBytes) {
160 HARDENED_TRY(process_block(ctx, block));
161 memset(block, 0, kSha256MessageBlockBytes);
166 block->data[kSha256MessageBlockWords - 1] =
167 __builtin_bswap32(total_len & UINT32_MAX);
168 block->data[kSha256MessageBlockWords - 2] =
169 __builtin_bswap32(total_len >> 32);
172 return process_block(ctx, block);
188 HARDENED_TRY(otbn_load_app(kOtbnAppSha256));
192 uint64_t msg_bits = ((uint64_t)msg_len) << 3;
193 uint64_t max_msg_bits = UINT64_MAX - state->
total_len;
194 if (msg_bits > max_msg_bits) {
195 return OTCRYPTO_BAD_ARGS;
204 if (state->
total_len >= kSha256MessageBlockBytes) {
206 otbn_dmem_write(kSha256StateWords, state->
H, kOtbnVarSha256State));
213 size_t partial_block_len = (state->
total_len >> 3) % kSha256MessageBlockBytes;
221 while (msg_len >= kSha256MessageBlockBytes - partial_block_len) {
222 size_t available_len = kSha256MessageBlockBytes - partial_block_len;
223 memcpy((
unsigned char *)block.data + partial_block_len, msg, available_len);
224 msg += available_len;
225 msg_len -= available_len;
226 HARDENED_TRY(process_block(&ctx, &block));
227 partial_block_len = 0;
233 memcpy((
unsigned char *)block.data + partial_block_len, msg, msg_len);
237 HARDENED_TRY(process_padding(&ctx, new_state.
total_len, &block));
243 HARDENED_TRY(process_message_buffer(&ctx));
248 otbn_dmem_read(kSha256StateWords, kOtbnVarSha256State, new_state.
H));
251 HARDENED_TRY(otbn_dmem_sec_wipe());
262 const size_t msg_len) {
292 for (
size_t i = 0; i < kSha256StateWords / 2; i++) {
293 uint32_t tmp = __builtin_bswap32(state->
H[i]);
294 state->
H[i] = __builtin_bswap32(state->
H[kSha256StateWords - 1 - i]);
295 state->
H[kSha256StateWords - 1 - i] = tmp;
305 digest_get(state, digest);
310 status_t sha256(
const uint8_t *msg,
const size_t msg_len, uint32_t *digest) {
318 digest_get(&state, digest);