5 #include "sw/device/lib/crypto/impl/sha2/sha512.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', '5')
24 kSha512MaxMessageChunksPerOtbnRun = 16,
31 uint32_t data[kSha512MessageBlockWords];
45 static const uint32_t kSha384InitialState[] = {
46 0xcbbb9d5d, 0xc1059ed8, 0x629a292a, 0x367cd507, 0x9159015a, 0x3070dd17,
47 0x152fecd8, 0xf70e5939, 0x67332667, 0xffc00b31, 0x8eb44a87, 0x68581511,
48 0xdb0c2e0d, 0x64f98fa7, 0x47b5481d, 0xbefa4fa4,
52 static const uint32_t kSha512InitialState[kSha512StateWords] = {
53 0x6a09e667, 0xf3bcc908, 0xbb67ae85, 0x84caa73b, 0x3c6ef372, 0xfe94f82b,
54 0xa54ff53a, 0x5f1d36f1, 0x510e527f, 0xade682d1, 0x9b05688c, 0x2b3e6c1f,
55 0x1f83d9ab, 0xfb41bd6b, 0x5be0cd19, 0x137e2179,
57 static_assert(
sizeof(kSha512InitialState) == kSha512StateBytes,
58 "Initial state for SHA-512 has an unexpected size.");
66 static const otbn_addr_t kOtbnVarSha512State =
68 static const otbn_addr_t kOtbnVarSha512Msg =
OTBN_ADDR_T_INIT(run_sha512, msg);
69 static const otbn_addr_t kOtbnVarSha512NChunks =
115 new_total_len->
upper += 1;
120 return OTCRYPTO_BAD_ARGS;
133 HARDENED_TRY(otbn_dmem_write(1, &ctx->
num_blocks, kOtbnVarSha512NChunks));
136 HARDENED_TRY(otbn_execute());
137 HARDENED_TRY(otbn_busy_wait_for_done());
156 size_t offset = ctx->
num_blocks * kSha512MessageBlockBytes;
157 otbn_addr_t dst = kOtbnVarSha512Msg + offset;
162 for (
size_t i = 0; i + 1 < kSha512MessageBlockWords; i += 2) {
163 uint32_t bytes_7to4 = __builtin_bswap32(block->data[i + 1]);
164 uint32_t bytes_3to0 = __builtin_bswap32(block->data[i]);
165 HARDENED_TRY(otbn_dmem_write(1, &bytes_7to4, dst));
166 dst +=
sizeof(uint32_t);
167 HARDENED_TRY(otbn_dmem_write(1, &bytes_3to0, dst));
168 dst +=
sizeof(uint32_t);
176 if (ctx->
num_blocks == kSha512MaxMessageChunksPerOtbnRun) {
177 HARDENED_TRY(process_message_buffer(ctx));
199 size_t partial_block_len = (total_len.
lower >> 3) % kSha512MessageBlockBytes;
202 unsigned char *data_end = (
unsigned char *)block->data + partial_block_len;
205 size_t padding_len = kSha512MessageBlockBytes - partial_block_len;
206 memset(data_end, 0, padding_len);
211 memset(data_end, 0x80, 1);
213 if (partial_block_len + 1 + 2 *
sizeof(uint64_t) > kSha512MessageBlockBytes) {
217 HARDENED_TRY(process_block(ctx, block));
218 memset(block, 0, kSha512MessageBlockBytes);
223 block->data[kSha512MessageBlockWords - 1] =
224 __builtin_bswap32(total_len.
lower & UINT32_MAX);
225 block->data[kSha512MessageBlockWords - 2] =
226 __builtin_bswap32(total_len.
lower >> 32);
227 block->data[kSha512MessageBlockWords - 3] =
228 __builtin_bswap32(total_len.
upper & UINT32_MAX);
229 block->data[kSha512MessageBlockWords - 4] =
230 __builtin_bswap32(total_len.
upper >> 32);
233 return process_block(ctx, block);
249 HARDENED_TRY(otbn_load_app(kOtbnAppSha512));
254 HARDENED_TRY(get_new_total_len(state, msg_len, &new_state.
total_len));
258 otbn_addr_t state_write_addr = kOtbnVarSha512State;
259 for (
size_t i = 0; i + 1 < kSha512StateWords; i += 2) {
260 HARDENED_TRY(otbn_dmem_write(1, &state->
H[i + 1], state_write_addr));
262 otbn_dmem_write(1, &state->
H[i], state_write_addr +
sizeof(uint32_t)));
263 state_write_addr += kOtbnWideWordNumBytes;
270 size_t partial_block_len =
279 while (msg_len >= kSha512MessageBlockBytes - partial_block_len) {
280 size_t available_len = kSha512MessageBlockBytes - partial_block_len;
281 memcpy((
unsigned char *)block.data + partial_block_len, msg, available_len);
282 msg += available_len;
283 msg_len -= available_len;
284 HARDENED_TRY(process_block(&ctx, &block));
285 partial_block_len = 0;
291 memcpy((
unsigned char *)block.data + partial_block_len, msg, msg_len);
295 HARDENED_TRY(process_padding(&ctx, new_state.
total_len, &block));
301 HARDENED_TRY(process_message_buffer(&ctx));
307 otbn_addr_t state_read_addr = kOtbnVarSha512State;
308 for (
size_t i = 0; i + 1 < kSha512StateWords; i += 2) {
309 HARDENED_TRY(otbn_dmem_read(1, state_read_addr, &new_state.
H[i + 1]));
311 otbn_dmem_read(1, state_read_addr +
sizeof(uint32_t), &new_state.
H[i]));
312 state_read_addr += kOtbnWideWordNumBytes;
316 HARDENED_TRY(otbn_dmem_sec_wipe());
328 const size_t msg_len) {
355 static void sha512_digest_get(
sha512_state_t *state, uint32_t *digest) {
357 for (
size_t i = 0; i < kSha512StateWords; i++) {
358 state->
H[i] = __builtin_bswap32(state->
H[i]);
372 static void sha384_digest_get(
sha512_state_t *state, uint32_t *digest) {
374 for (
size_t i = 0; i < kSha512StateWords; i++) {
375 state->
H[i] = __builtin_bswap32(state->
H[i]);
385 sha512_digest_get(state, digest);
390 status_t sha512(
const uint8_t *msg,
const size_t msg_len, uint32_t *digest) {
396 sha512_digest_get(&state, digest);
402 const size_t msg_len) {
404 return sha512_update(state, msg, msg_len);
412 sha384_digest_get(state, digest);
417 status_t sha384(
const uint8_t *msg,
const size_t msg_len, uint32_t *digest) {
423 sha384_digest_get(&state, digest);