Philipp Deppenwiese has uploaded this change for review. ( https://review.coreboot.org/22872
Change subject: security/crypto: Add crypto primitives for hashing data ......................................................................
security/crypto: Add crypto primitives for hashing data
* Add crypto section to security directory. * Add SHA1 and SHA256 hashing functionality.
Change-Id: I807084ebfffdc159fe95c45b4e5f0820bbfee5e1 Signed-off-by: Philipp Deppenwiese zaolin@das-labor.org --- M src/security/Kconfig M src/security/Makefile.inc A src/security/crypto/Kconfig A src/security/crypto/Makefile.inc A src/security/crypto/hash.h A src/security/crypto/hash/hash.c A src/security/crypto/hash/sha1.c A src/security/crypto/hash/sha256.c 8 files changed, 515 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/72/22872/1
diff --git a/src/security/Kconfig b/src/security/Kconfig index 6a334ac..9a07b5f 100644 --- a/src/security/Kconfig +++ b/src/security/Kconfig @@ -14,3 +14,4 @@
source "src/security/vboot/Kconfig" source "src/security/tpm/Kconfig" +source "src/security/crypto/Kconfig" diff --git a/src/security/Makefile.inc b/src/security/Makefile.inc index a940b82..a941247 100644 --- a/src/security/Makefile.inc +++ b/src/security/Makefile.inc @@ -1,2 +1,3 @@ subdirs-y += vboot subdirs-y += tpm +subdirs-y += crypto diff --git a/src/security/crypto/Kconfig b/src/security/crypto/Kconfig new file mode 100644 index 0000000..5fbccd1 --- /dev/null +++ b/src/security/crypto/Kconfig @@ -0,0 +1,26 @@ +## This file is part of the coreboot project. +## +## Copyright (C) 2017 Philipp Deppenwiese, Facebook, Inc. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + +menu "Cryptographic Primitives" + +config CRYPTO_HASH + bool "Enable hashing primitives" + default n + help + Enable this option to enable hashing support in coreboot. + SHA1 and SHA256 are currently supported. + + If unsure, say N. + +endmenu # Cryptographic Primitives diff --git a/src/security/crypto/Makefile.inc b/src/security/crypto/Makefile.inc new file mode 100644 index 0000000..082f7b7 --- /dev/null +++ b/src/security/crypto/Makefile.inc @@ -0,0 +1,6 @@ +## crypto + +verstage-$(CONFIG_CRYPTO_HASH) += hash/hash.c hash/sha1.c hash/sha256.c +romstage-$(CONFIG_CRYPTO_HASH) += hash/hash.c hash/sha1.c hash/sha256.c +ramstage-$(CONFIG_CRYPTO_HASH) += hash/hash.c hash/sha1.c hash/sha256.c +smm-$(CONFIG_CRYPTO_HASH) += hash/hash.c hash/sha1.c hash/sha256.c diff --git a/src/security/crypto/hash.h b/src/security/crypto/hash.h new file mode 100644 index 0000000..9a684e8 --- /dev/null +++ b/src/security/crypto/hash.h @@ -0,0 +1,36 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2017 Facebook Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#define SHA1_BLOCK_LEN 64 // In bytes +#define SHA1_STATE_LEN 5 // In words + +#define SHA256_BLOCK_LEN 64 // In bytes +#define SHA256_STATE_LEN 8 // In words + +#define UINT32_C(value) (value##UL) + +void sha1_hash(const uint8_t message[], size_t len, + uint32_t hash[static SHA1_STATE_LEN]); +void sha1_compress(uint32_t state[static SHA1_STATE_LEN], + const uint8_t block[static SHA1_BLOCK_LEN]); + +void sha256_hash(const uint8_t message[], size_t len, + uint32_t hash[static SHA256_STATE_LEN]); +void sha256_compress(uint32_t state[static SHA256_STATE_LEN], + const uint8_t block[static SHA256_BLOCK_LEN]); diff --git a/src/security/crypto/hash/hash.c b/src/security/crypto/hash/hash.c new file mode 100644 index 0000000..32c4e27 --- /dev/null +++ b/src/security/crypto/hash/hash.c @@ -0,0 +1,93 @@ +/* + * SHA-1 hash in C and x86 assembly + * SHA-256 hash in C and x86 assembly + * + * Copyright (c) 2017 Project Nayuki. (MIT License) + * https://www.nayuki.io/page/fast-sha1-hash-implementation-in-x86-assembly + * https://www.nayuki.io/page/fast-sha2-hashes-in-x86-assembly + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * - The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * - The Software is provided "as is", without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall the + * authors or copyright holders be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the Software or the use or other dealings + * in the Software. + */ + +#include <security/crypto/hash.h> + +#define LENGTH_SIZE 8 // In bytes + +void sha1_hash(const uint8_t message[], size_t len, + uint32_t hash[static SHA1_STATE_LEN]) +{ + hash[0] = UINT32_C(0x67452301); + hash[1] = UINT32_C(0xEFCDAB89); + hash[2] = UINT32_C(0x98BADCFE); + hash[3] = UINT32_C(0x10325476); + hash[4] = UINT32_C(0xC3D2E1F0); + + size_t off; + for (off = 0; len - off >= SHA1_BLOCK_LEN; off += SHA1_BLOCK_LEN) + sha1_compress(hash, &message[off]); + + uint8_t block[SHA1_BLOCK_LEN] = {0}; + size_t rem = len - off; + memcpy(block, &message[off], rem); + + block[rem] = 0x80; + rem++; + if (SHA1_BLOCK_LEN - rem < LENGTH_SIZE) { + sha1_compress(hash, block); + memset(block, 0, sizeof(block)); + } + + block[SHA1_BLOCK_LEN - 1] = (uint8_t)((len & 0x1FU) << 3); + len >>= 5; + for (int i = 1; i < LENGTH_SIZE; i++, len >>= 8) + block[SHA1_BLOCK_LEN - 1 - i] = (uint8_t)(len & 0xFFU); + sha1_compress(hash, block); +} + +void sha256_hash(const uint8_t message[], size_t len, + uint32_t hash[static SHA256_STATE_LEN]) +{ + hash[0] = UINT32_C(0x6A09E667); + hash[1] = UINT32_C(0xBB67AE85); + hash[2] = UINT32_C(0x3C6EF372); + hash[3] = UINT32_C(0xA54FF53A); + hash[4] = UINT32_C(0x510E527F); + hash[5] = UINT32_C(0x9B05688C); + hash[6] = UINT32_C(0x1F83D9AB); + hash[7] = UINT32_C(0x5BE0CD19); + + size_t off; + for (off = 0; len - off >= SHA256_BLOCK_LEN; off += SHA256_BLOCK_LEN) + sha256_compress(hash, &message[off]); + + uint8_t block[SHA256_BLOCK_LEN] = {0}; + size_t rem = len - off; + memcpy(block, &message[off], rem); + + block[rem] = 0x80; + rem++; + if (SHA256_BLOCK_LEN - rem < LENGTH_SIZE) { + sha256_compress(hash, block); + memset(block, 0, sizeof(block)); + } + + block[SHA256_BLOCK_LEN - 1] = (uint8_t)((len & 0x1FU) << 3); + len >>= 5; + for (int i = 1; i < LENGTH_SIZE; i++, len >>= 8) + block[SHA256_BLOCK_LEN - 1 - i] = (uint8_t)(len & 0xFFU); + sha256_compress(hash, block); +} diff --git a/src/security/crypto/hash/sha1.c b/src/security/crypto/hash/sha1.c new file mode 100644 index 0000000..3c35394 --- /dev/null +++ b/src/security/crypto/hash/sha1.c @@ -0,0 +1,153 @@ +/* + * SHA-1 hash in C + * + * Copyright (c) 2017 Project Nayuki. (MIT License) + * https://www.nayuki.io/page/fast-sha1-hash-implementation-in-x86-assembly + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * - The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * - The Software is provided "as is", without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall the + * authors or copyright holders be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the Software or the use or other dealings + * in the Software. + */ + +#include <security/crypto/hash.h> + +#define ROTL32(x, n) \ + (((0U + (x)) << (n)) | \ + ((x) >> (32 - (n)))) // Assumes that x is uint32_t and 0 < n < 32 + +#define LOADSCHEDULE(i) \ + schedule[i] = (uint32_t)block[i * 4 + 0] << 24 | \ + (uint32_t)block[i * 4 + 1] << 16 | \ + (uint32_t)block[i * 4 + 2] << 8 | \ + (uint32_t)block[i * 4 + 3] << 0; + +#define SCHEDULE(i) \ + temp = schedule[(i - 3) & 0xF] ^ schedule[(i - 8) & 0xF] ^ \ + schedule[(i - 14) & 0xF] ^ schedule[(i - 16) & 0xF]; \ + schedule[i & 0xF] = ROTL32(temp, 1); + +#define ROUND0a(a, b, c, d, e, i) \ + LOADSCHEDULE(i) ROUNDTAIL(a, b, e, ((b & c) | (~b & d)), i, 0x5A827999) +#define ROUND0b(a, b, c, d, e, i) \ + SCHEDULE(i) ROUNDTAIL(a, b, e, ((b & c) | (~b & d)), i, 0x5A827999) +#define ROUND1(a, b, c, d, e, i) \ + SCHEDULE(i) ROUNDTAIL(a, b, e, (b ^ c ^ d), i, 0x6ED9EBA1) +#define ROUND2(a, b, c, d, e, i) \ + SCHEDULE(i) \ + ROUNDTAIL(a, b, e, ((b & c) ^ (b & d) ^ (c & d)), i, 0x8F1BBCDC) +#define ROUND3(a, b, c, d, e, i) \ + SCHEDULE(i) ROUNDTAIL(a, b, e, (b ^ c ^ d), i, 0xCA62C1D6) + +#define ROUNDTAIL(a, b, e, f, i, k) \ + e = 0U + e + ROTL32(a, 5) + f + UINT32_C(k) + schedule[i & 0xF]; \ + b = ROTL32(b, 30); + +void sha1_compress(uint32_t state[static 5], const uint8_t block[static 64]) +{ + uint32_t a = state[0]; + uint32_t b = state[1]; + uint32_t c = state[2]; + uint32_t d = state[3]; + uint32_t e = state[4]; + + uint32_t schedule[16]; + uint32_t temp; + ROUND0a(a, b, c, d, e, 0) + ROUND0a(e, a, b, c, d, 1) + ROUND0a(d, e, a, b, c, 2) + ROUND0a(c, d, e, a, b, 3) + ROUND0a(b, c, d, e, a, 4) + ROUND0a(a, b, c, d, e, 5) + ROUND0a(e, a, b, c, d, 6) + ROUND0a(d, e, a, b, c, 7) + ROUND0a(c, d, e, a, b, 8) + ROUND0a(b, c, d, e, a, 9) + ROUND0a(a, b, c, d, e, 10) + ROUND0a(e, a, b, c, d, 11) + ROUND0a(d, e, a, b, c, 12) + ROUND0a(c, d, e, a, b, 13) + ROUND0a(b, c, d, e, a, 14) + ROUND0a(a, b, c, d, e, 15) + ROUND0b(e, a, b, c, d, 16) + ROUND0b(d, e, a, b, c, 17) + ROUND0b(c, d, e, a, b, 18) + ROUND0b(b, c, d, e, a, 19) + ROUND1(a, b, c, d, e, 20) + ROUND1(e, a, b, c, d, 21) + ROUND1(d, e, a, b, c, 22) + ROUND1(c, d, e, a, b, 23) + ROUND1(b, c, d, e, a, 24) + ROUND1(a, b, c, d, e, 25) + ROUND1(e, a, b, c, d, 26) + ROUND1(d, e, a, b, c, 27) + ROUND1(c, d, e, a, b, 28) + ROUND1(b, c, d, e, a, 29) + ROUND1(a, b, c, d, e, 30) + ROUND1(e, a, b, c, d, 31) + ROUND1(d, e, a, b, c, 32) + ROUND1(c, d, e, a, b, 33) + ROUND1(b, c, d, e, a, 34) + ROUND1(a, b, c, d, e, 35) + ROUND1(e, a, b, c, d, 36) + ROUND1(d, e, a, b, c, 37) + ROUND1(c, d, e, a, b, 38) + ROUND1(b, c, d, e, a, 39) + ROUND2(a, b, c, d, e, 40) + ROUND2(e, a, b, c, d, 41) + ROUND2(d, e, a, b, c, 42) + ROUND2(c, d, e, a, b, 43) + ROUND2(b, c, d, e, a, 44) + ROUND2(a, b, c, d, e, 45) + ROUND2(e, a, b, c, d, 46) + ROUND2(d, e, a, b, c, 47) + ROUND2(c, d, e, a, b, 48) + ROUND2(b, c, d, e, a, 49) + ROUND2(a, b, c, d, e, 50) + ROUND2(e, a, b, c, d, 51) + ROUND2(d, e, a, b, c, 52) + ROUND2(c, d, e, a, b, 53) + ROUND2(b, c, d, e, a, 54) + ROUND2(a, b, c, d, e, 55) + ROUND2(e, a, b, c, d, 56) + ROUND2(d, e, a, b, c, 57) + ROUND2(c, d, e, a, b, 58) + ROUND2(b, c, d, e, a, 59) + ROUND3(a, b, c, d, e, 60) + ROUND3(e, a, b, c, d, 61) + ROUND3(d, e, a, b, c, 62) + ROUND3(c, d, e, a, b, 63) + ROUND3(b, c, d, e, a, 64) + ROUND3(a, b, c, d, e, 65) + ROUND3(e, a, b, c, d, 66) + ROUND3(d, e, a, b, c, 67) + ROUND3(c, d, e, a, b, 68) + ROUND3(b, c, d, e, a, 69) + ROUND3(a, b, c, d, e, 70) + ROUND3(e, a, b, c, d, 71) + ROUND3(d, e, a, b, c, 72) + ROUND3(c, d, e, a, b, 73) + ROUND3(b, c, d, e, a, 74) + ROUND3(a, b, c, d, e, 75) + ROUND3(e, a, b, c, d, 76) + ROUND3(d, e, a, b, c, 77) + ROUND3(c, d, e, a, b, 78) + ROUND3(b, c, d, e, a, 79) + + state[0] = 0U + state[0] + a; + state[1] = 0U + state[1] + b; + state[2] = 0U + state[2] + c; + state[3] = 0U + state[3] + d; + state[4] = 0U + state[4] + e; +} diff --git a/src/security/crypto/hash/sha256.c b/src/security/crypto/hash/sha256.c new file mode 100644 index 0000000..b0a6bc8 --- /dev/null +++ b/src/security/crypto/hash/sha256.c @@ -0,0 +1,199 @@ +/* + * SHA-256 hash in C + * + * Copyright (c) 2017 Project Nayuki. (MIT License) + * https://www.nayuki.io/page/fast-sha2-hashes-in-x86-assembly + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * - The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * - The Software is provided "as is", without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall the + * authors or copyright holders be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the Software or the use or other dealings + * in the Software. + */ + +#include <security/crypto/hash.h> + +#define ROTR32(x, n) \ + (((0U + (x)) << (32 - (n))) | \ + ((x) >> (n))) // Assumes that x is uint32_t and 0 < n < 32 + +#define LOADSCHEDULE(i) \ + schedule[i] = (uint32_t)block[i * 4 + 0] << 24 | \ + (uint32_t)block[i * 4 + 1] << 16 | \ + (uint32_t)block[i * 4 + 2] << 8 | \ + (uint32_t)block[i * 4 + 3] << 0; + +#define SCHEDULE(i) \ + schedule[i] = \ + 0U + schedule[i - 16] + schedule[i - 7] + \ + (ROTR32(schedule[i - 15], 7) ^ ROTR32(schedule[i - 15], 18) ^ \ + (schedule[i - 15] >> 3)) + \ + (ROTR32(schedule[i - 2], 17) ^ ROTR32(schedule[i - 2], 19) ^ \ + (schedule[i - 2] >> 10)); + +#define ROUND(a, b, c, d, e, f, g, h, i, k) \ + h = 0U + h + (ROTR32(e, 6) ^ ROTR32(e, 11) ^ ROTR32(e, 25)) + \ + (g ^ (e & (f ^ g))) + UINT32_C(k) + schedule[i]; \ + d = 0U + d + h; \ + h = 0U + h + (ROTR32(a, 2) ^ ROTR32(a, 13) ^ ROTR32(a, 22)) + \ + ((a & (b | c)) | (b & c)); + +void sha256_compress(uint32_t state[static 8], const uint8_t block[static 64]) +{ + uint32_t schedule[64]; + LOADSCHEDULE(0) + LOADSCHEDULE(1) + LOADSCHEDULE(2) + LOADSCHEDULE(3) + LOADSCHEDULE(4) + LOADSCHEDULE(5) + LOADSCHEDULE(6) + LOADSCHEDULE(7) + LOADSCHEDULE(8) + LOADSCHEDULE(9) + LOADSCHEDULE(10) + LOADSCHEDULE(11) + LOADSCHEDULE(12) + LOADSCHEDULE(13) + LOADSCHEDULE(14) + LOADSCHEDULE(15) + SCHEDULE(16) + SCHEDULE(17) + SCHEDULE(18) + SCHEDULE(19) + SCHEDULE(20) + SCHEDULE(21) + SCHEDULE(22) + SCHEDULE(23) + SCHEDULE(24) + SCHEDULE(25) + SCHEDULE(26) + SCHEDULE(27) + SCHEDULE(28) + SCHEDULE(29) + SCHEDULE(30) + SCHEDULE(31) + SCHEDULE(32) + SCHEDULE(33) + SCHEDULE(34) + SCHEDULE(35) + SCHEDULE(36) + SCHEDULE(37) + SCHEDULE(38) + SCHEDULE(39) + SCHEDULE(40) + SCHEDULE(41) + SCHEDULE(42) + SCHEDULE(43) + SCHEDULE(44) + SCHEDULE(45) + SCHEDULE(46) + SCHEDULE(47) + SCHEDULE(48) + SCHEDULE(49) + SCHEDULE(50) + SCHEDULE(51) + SCHEDULE(52) + SCHEDULE(53) + SCHEDULE(54) + SCHEDULE(55) + SCHEDULE(56) + SCHEDULE(57) + SCHEDULE(58) + SCHEDULE(59) + SCHEDULE(60) + SCHEDULE(61) + SCHEDULE(62) + SCHEDULE(63) + + uint32_t a = state[0]; + uint32_t b = state[1]; + uint32_t c = state[2]; + uint32_t d = state[3]; + uint32_t e = state[4]; + uint32_t f = state[5]; + uint32_t g = state[6]; + uint32_t h = state[7]; + ROUND(a, b, c, d, e, f, g, h, 0, 0x428A2F98) + ROUND(h, a, b, c, d, e, f, g, 1, 0x71374491) + ROUND(g, h, a, b, c, d, e, f, 2, 0xB5C0FBCF) + ROUND(f, g, h, a, b, c, d, e, 3, 0xE9B5DBA5) + ROUND(e, f, g, h, a, b, c, d, 4, 0x3956C25B) + ROUND(d, e, f, g, h, a, b, c, 5, 0x59F111F1) + ROUND(c, d, e, f, g, h, a, b, 6, 0x923F82A4) + ROUND(b, c, d, e, f, g, h, a, 7, 0xAB1C5ED5) + ROUND(a, b, c, d, e, f, g, h, 8, 0xD807AA98) + ROUND(h, a, b, c, d, e, f, g, 9, 0x12835B01) + ROUND(g, h, a, b, c, d, e, f, 10, 0x243185BE) + ROUND(f, g, h, a, b, c, d, e, 11, 0x550C7DC3) + ROUND(e, f, g, h, a, b, c, d, 12, 0x72BE5D74) + ROUND(d, e, f, g, h, a, b, c, 13, 0x80DEB1FE) + ROUND(c, d, e, f, g, h, a, b, 14, 0x9BDC06A7) + ROUND(b, c, d, e, f, g, h, a, 15, 0xC19BF174) + ROUND(a, b, c, d, e, f, g, h, 16, 0xE49B69C1) + ROUND(h, a, b, c, d, e, f, g, 17, 0xEFBE4786) + ROUND(g, h, a, b, c, d, e, f, 18, 0x0FC19DC6) + ROUND(f, g, h, a, b, c, d, e, 19, 0x240CA1CC) + ROUND(e, f, g, h, a, b, c, d, 20, 0x2DE92C6F) + ROUND(d, e, f, g, h, a, b, c, 21, 0x4A7484AA) + ROUND(c, d, e, f, g, h, a, b, 22, 0x5CB0A9DC) + ROUND(b, c, d, e, f, g, h, a, 23, 0x76F988DA) + ROUND(a, b, c, d, e, f, g, h, 24, 0x983E5152) + ROUND(h, a, b, c, d, e, f, g, 25, 0xA831C66D) + ROUND(g, h, a, b, c, d, e, f, 26, 0xB00327C8) + ROUND(f, g, h, a, b, c, d, e, 27, 0xBF597FC7) + ROUND(e, f, g, h, a, b, c, d, 28, 0xC6E00BF3) + ROUND(d, e, f, g, h, a, b, c, 29, 0xD5A79147) + ROUND(c, d, e, f, g, h, a, b, 30, 0x06CA6351) + ROUND(b, c, d, e, f, g, h, a, 31, 0x14292967) + ROUND(a, b, c, d, e, f, g, h, 32, 0x27B70A85) + ROUND(h, a, b, c, d, e, f, g, 33, 0x2E1B2138) + ROUND(g, h, a, b, c, d, e, f, 34, 0x4D2C6DFC) + ROUND(f, g, h, a, b, c, d, e, 35, 0x53380D13) + ROUND(e, f, g, h, a, b, c, d, 36, 0x650A7354) + ROUND(d, e, f, g, h, a, b, c, 37, 0x766A0ABB) + ROUND(c, d, e, f, g, h, a, b, 38, 0x81C2C92E) + ROUND(b, c, d, e, f, g, h, a, 39, 0x92722C85) + ROUND(a, b, c, d, e, f, g, h, 40, 0xA2BFE8A1) + ROUND(h, a, b, c, d, e, f, g, 41, 0xA81A664B) + ROUND(g, h, a, b, c, d, e, f, 42, 0xC24B8B70) + ROUND(f, g, h, a, b, c, d, e, 43, 0xC76C51A3) + ROUND(e, f, g, h, a, b, c, d, 44, 0xD192E819) + ROUND(d, e, f, g, h, a, b, c, 45, 0xD6990624) + ROUND(c, d, e, f, g, h, a, b, 46, 0xF40E3585) + ROUND(b, c, d, e, f, g, h, a, 47, 0x106AA070) + ROUND(a, b, c, d, e, f, g, h, 48, 0x19A4C116) + ROUND(h, a, b, c, d, e, f, g, 49, 0x1E376C08) + ROUND(g, h, a, b, c, d, e, f, 50, 0x2748774C) + ROUND(f, g, h, a, b, c, d, e, 51, 0x34B0BCB5) + ROUND(e, f, g, h, a, b, c, d, 52, 0x391C0CB3) + ROUND(d, e, f, g, h, a, b, c, 53, 0x4ED8AA4A) + ROUND(c, d, e, f, g, h, a, b, 54, 0x5B9CCA4F) + ROUND(b, c, d, e, f, g, h, a, 55, 0x682E6FF3) + ROUND(a, b, c, d, e, f, g, h, 56, 0x748F82EE) + ROUND(h, a, b, c, d, e, f, g, 57, 0x78A5636F) + ROUND(g, h, a, b, c, d, e, f, 58, 0x84C87814) + ROUND(f, g, h, a, b, c, d, e, 59, 0x8CC70208) + ROUND(e, f, g, h, a, b, c, d, 60, 0x90BEFFFA) + ROUND(d, e, f, g, h, a, b, c, 61, 0xA4506CEB) + ROUND(c, d, e, f, g, h, a, b, 62, 0xBEF9A3F7) + ROUND(b, c, d, e, f, g, h, a, 63, 0xC67178F2) + state[0] = 0U + state[0] + a; + state[1] = 0U + state[1] + b; + state[2] = 0U + state[2] + c; + state[3] = 0U + state[3] + d; + state[4] = 0U + state[4] + e; + state[5] = 0U + state[5] + f; + state[6] = 0U + state[6] + g; + state[7] = 0U + state[7] + h; +}