1 /** 2 * SHA-{224,256} 3 * 4 * Copyright: 5 * (C) 1999-2011 Jack Lloyd 6 * (C) 2014-2015 Etienne Cimon 7 * 2007 FlexSecure GmbH 8 * 9 * License: 10 * Botan is released under the Simplified BSD License (see LICENSE.md) 11 */ 12 module botan.hash.sha2_32; 13 14 import botan.constants; 15 static if (BOTAN_HAS_SHA2_32): 16 17 import botan.hash.mdx_hash; 18 import botan.hash.sha2_32; 19 import botan.utils.loadstor; 20 import botan.utils.rotate; 21 import botan.hash.hash; 22 import botan.utils.types; 23 import std.format : format; 24 25 /** 26 * SHA-224 27 */ 28 final class SHA224 : MDxHashFunction, HashFunction 29 { 30 public: 31 32 override @property size_t hashBlockSize() const { return super.hashBlockSize(); } 33 override @property string name() const { return "SHA-224"; } 34 override @property size_t outputLength() const { return 28; } 35 override HashFunction clone() const { return new SHA224; } 36 37 /* 38 * Clear memory of sensitive data 39 */ 40 override void clear() 41 { 42 super.clear(); 43 m_digest[0] = 0xC1059ED8; 44 m_digest[1] = 0x367CD507; 45 m_digest[2] = 0x3070DD17; 46 m_digest[3] = 0xF70E5939; 47 m_digest[4] = 0xFFC00B31; 48 m_digest[5] = 0x68581511; 49 m_digest[6] = 0x64F98FA7; 50 m_digest[7] = 0xBEFA4FA4; 51 } 52 53 54 this() 55 { 56 super(64, true, true); 57 m_digest.length = 8; 58 clear(); 59 } 60 61 protected: 62 /* 63 * SHA-224 compression function 64 */ 65 override void compressN(const(ubyte)* input, size_t blocks) 66 { 67 assert(m_digest.length == 8); 68 uint[8] digest = m_digest.ptr[0 .. 8]; 69 compress(digest, input, blocks); 70 m_digest[] = digest.ptr[0 .. 8]; 71 } 72 73 /* 74 * Copy out the digest 75 */ 76 override void copyOut(ubyte* output) 77 { 78 for (size_t i = 0; i != outputLength(); i += 4) 79 storeBigEndian(m_digest[i/4], output + i); 80 } 81 82 SecureVector!uint m_digest; 83 } 84 85 86 /** 87 * SHA-256 88 */ 89 class SHA256 : MDxHashFunction, HashFunction 90 { 91 public: 92 93 override @property size_t hashBlockSize() const { return super.hashBlockSize(); } 94 override @property string name() const { return "SHA-256"; } 95 override @property size_t outputLength() const { return 32; } 96 override HashFunction clone() const { return new SHA256; } 97 98 /* 99 * Clear memory of sensitive data 100 */ 101 override void clear() 102 { 103 super.clear(); 104 m_digest[0] = 0x6A09E667; 105 m_digest[1] = 0xBB67AE85; 106 m_digest[2] = 0x3C6EF372; 107 m_digest[3] = 0xA54FF53A; 108 m_digest[4] = 0x510E527F; 109 m_digest[5] = 0x9B05688C; 110 m_digest[6] = 0x1F83D9AB; 111 m_digest[7] = 0x5BE0CD19; 112 } 113 114 this() 115 { 116 super(64, true, true); 117 m_digest.length = 8; 118 clear(); 119 } 120 protected: 121 /* 122 * SHA-256 compression function 123 */ 124 override void compressN(const(ubyte)* input, size_t blocks) 125 { 126 assert(m_digest.length == 8); 127 uint[8] digest = m_digest.ptr[0 .. 8]; 128 compress(digest, input, blocks); 129 m_digest[] = digest.ptr[0 .. 8]; 130 } 131 132 /* 133 * Copy out the digest 134 */ 135 override void copyOut(ubyte* output) 136 { 137 for (size_t i = 0; i != outputLength(); i += 4) 138 storeBigEndian(m_digest[i/4], output + i); 139 } 140 141 142 SecureVector!uint m_digest; 143 } 144 145 private: 146 pure: 147 148 /* 149 * SHA-256 Rho Function 150 */ 151 uint rho(uint X, uint rot1, uint rot2, uint rot3) 152 { 153 return (rotateRight(X, rot1) ^ rotateRight(X, rot2) ^ rotateRight(X, rot3)); 154 } 155 156 /* 157 * SHA-256 Sigma Function 158 */ 159 uint sigma(uint X, uint rot1, uint rot2, uint shift) 160 { 161 return (rotateRight(X, rot1) ^ rotateRight(X, rot2) ^ (X >> shift)); 162 } 163 164 /* 165 * SHA-256 F1 Function 166 * 167 * Use a macro as many compilers won't a function this big, 168 * even though it is much faster if d. 169 */ 170 enum string SHA2_32_F(alias _A, alias _B, alias _C, alias _D, alias _E, alias _F, alias _G, alias _H, alias _M1, alias _M2, alias _M3, alias _M4, uint magic) = q{ 171 %9$s += %1$s + rho(%6$s, 6, 11, 25) + ((%6$s & %7$s) ^ (~%6$s & %8$s)) + %10$s; 172 %5$s += %9$s; 173 %9$s += rho(%2$s, 2, 13, 22) + ((%2$s & %3$s) | ((%2$s | %3$s) & %4$s)); 174 %10$s += sigma(%11$s, 17, 19, 10) + %12$s + sigma(%13$s, 7, 18, 3); 175 }.format(magic, 176 __traits(identifier, _A), __traits(identifier, _B), __traits(identifier, _C), __traits(identifier, _D), 177 __traits(identifier, _E), __traits(identifier, _F), __traits(identifier, _G), __traits(identifier, _H), 178 __traits(identifier, _M1), __traits(identifier, _M2), __traits(identifier, _M3), __traits(identifier, _M4)); 179 180 /* 181 * SHA-224 / SHA-256 compression function 182 */ 183 void compress(ref uint[8] digest, 184 const(ubyte)* input, size_t blocks) pure 185 { 186 uint A = digest[0], B = digest[1], C = digest[2], 187 D = digest[3], E = digest[4], F = digest[5], 188 G = digest[6], H = digest[7]; 189 190 foreach (size_t i; 0 .. blocks) 191 { 192 uint W00 = loadBigEndian!uint(input, 0); 193 uint W01 = loadBigEndian!uint(input, 1); 194 uint W02 = loadBigEndian!uint(input, 2); 195 uint W03 = loadBigEndian!uint(input, 3); 196 uint W04 = loadBigEndian!uint(input, 4); 197 uint W05 = loadBigEndian!uint(input, 5); 198 uint W06 = loadBigEndian!uint(input, 6); 199 uint W07 = loadBigEndian!uint(input, 7); 200 uint W08 = loadBigEndian!uint(input, 8); 201 uint W09 = loadBigEndian!uint(input, 9); 202 uint W10 = loadBigEndian!uint(input, 10); 203 uint W11 = loadBigEndian!uint(input, 11); 204 uint W12 = loadBigEndian!uint(input, 12); 205 uint W13 = loadBigEndian!uint(input, 13); 206 uint W14 = loadBigEndian!uint(input, 14); 207 uint W15 = loadBigEndian!uint(input, 15); 208 209 mixin( 210 SHA2_32_F!(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x428A2F98) ~ 211 SHA2_32_F!(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x71374491) ~ 212 SHA2_32_F!(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0xB5C0FBCF) ~ 213 SHA2_32_F!(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0xE9B5DBA5) ~ 214 SHA2_32_F!(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x3956C25B) ~ 215 SHA2_32_F!(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x59F111F1) ~ 216 SHA2_32_F!(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x923F82A4) ~ 217 SHA2_32_F!(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0xAB1C5ED5) ~ 218 SHA2_32_F!(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xD807AA98) ~ 219 SHA2_32_F!(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x12835B01) ~ 220 SHA2_32_F!(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x243185BE) ~ 221 SHA2_32_F!(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x550C7DC3) ~ 222 SHA2_32_F!(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x72BE5D74) ~ 223 SHA2_32_F!(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0x80DEB1FE) ~ 224 SHA2_32_F!(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x9BDC06A7) ~ 225 SHA2_32_F!(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC19BF174) ~ 226 SHA2_32_F!(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0xE49B69C1) ~ 227 SHA2_32_F!(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0xEFBE4786) ~ 228 SHA2_32_F!(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x0FC19DC6) ~ 229 SHA2_32_F!(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x240CA1CC) ~ 230 SHA2_32_F!(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x2DE92C6F) ~ 231 SHA2_32_F!(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4A7484AA) ~ 232 SHA2_32_F!(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5CB0A9DC) ~ 233 SHA2_32_F!(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x76F988DA) ~ 234 SHA2_32_F!(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x983E5152) ~ 235 SHA2_32_F!(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA831C66D) ~ 236 SHA2_32_F!(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xB00327C8) ~ 237 SHA2_32_F!(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xBF597FC7) ~ 238 SHA2_32_F!(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xC6E00BF3) ~ 239 SHA2_32_F!(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD5A79147) ~ 240 SHA2_32_F!(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x06CA6351) ~ 241 SHA2_32_F!(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x14292967) ~ 242 SHA2_32_F!(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x27B70A85) ~ 243 SHA2_32_F!(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x2E1B2138) ~ 244 SHA2_32_F!(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x4D2C6DFC) ~ 245 SHA2_32_F!(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x53380D13) ~ 246 SHA2_32_F!(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x650A7354) ~ 247 SHA2_32_F!(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x766A0ABB) ~ 248 SHA2_32_F!(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x81C2C92E) ~ 249 SHA2_32_F!(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x92722C85) ~ 250 SHA2_32_F!(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xA2BFE8A1) ~ 251 SHA2_32_F!(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA81A664B) ~ 252 SHA2_32_F!(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xC24B8B70) ~ 253 SHA2_32_F!(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xC76C51A3) ~ 254 SHA2_32_F!(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xD192E819) ~ 255 SHA2_32_F!(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD6990624) ~ 256 SHA2_32_F!(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xF40E3585) ~ 257 SHA2_32_F!(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x106AA070) ~ 258 SHA2_32_F!(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x19A4C116) ~ 259 SHA2_32_F!(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x1E376C08) ~ 260 SHA2_32_F!(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x2748774C) ~ 261 SHA2_32_F!(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x34B0BCB5) ~ 262 SHA2_32_F!(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x391C0CB3) ~ 263 SHA2_32_F!(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4ED8AA4A) ~ 264 SHA2_32_F!(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5B9CCA4F) ~ 265 SHA2_32_F!(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x682E6FF3) ~ 266 SHA2_32_F!(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x748F82EE) ~ 267 SHA2_32_F!(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x78A5636F) ~ 268 SHA2_32_F!(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x84C87814) ~ 269 SHA2_32_F!(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x8CC70208) ~ 270 SHA2_32_F!(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x90BEFFFA) ~ 271 SHA2_32_F!(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xA4506CEB) ~ 272 SHA2_32_F!(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xBEF9A3F7) ~ 273 SHA2_32_F!(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC67178F2) 274 ); 275 276 A = (digest[0] += A); 277 B = (digest[1] += B); 278 C = (digest[2] += C); 279 D = (digest[3] += D); 280 E = (digest[4] += E); 281 F = (digest[5] += F); 282 G = (digest[6] += G); 283 H = (digest[7] += H); 284 285 input += 64; 286 } 287 }