Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* |
michael@0 | 2 | * sha512.c - implementation of SHA224, SHA256, SHA384 and SHA512 |
michael@0 | 3 | * |
michael@0 | 4 | * This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 7 | |
michael@0 | 8 | #ifdef FREEBL_NO_DEPEND |
michael@0 | 9 | #include "stubs.h" |
michael@0 | 10 | #endif |
michael@0 | 11 | |
michael@0 | 12 | #include "prcpucfg.h" |
michael@0 | 13 | #if defined(NSS_X86) || defined(SHA_NO_LONG_LONG) |
michael@0 | 14 | #define NOUNROLL512 1 |
michael@0 | 15 | #undef HAVE_LONG_LONG |
michael@0 | 16 | #endif |
michael@0 | 17 | #include "prtypes.h" /* for PRUintXX */ |
michael@0 | 18 | #include "prlong.h" |
michael@0 | 19 | #include "secport.h" /* for PORT_XXX */ |
michael@0 | 20 | #include "blapi.h" |
michael@0 | 21 | #include "sha256.h" /* for struct SHA256ContextStr */ |
michael@0 | 22 | |
michael@0 | 23 | /* ============= Common constants and defines ======================= */ |
michael@0 | 24 | |
michael@0 | 25 | #define W ctx->u.w |
michael@0 | 26 | #define B ctx->u.b |
michael@0 | 27 | #define H ctx->h |
michael@0 | 28 | |
michael@0 | 29 | #define SHR(x,n) (x >> n) |
michael@0 | 30 | #define SHL(x,n) (x << n) |
michael@0 | 31 | #define Ch(x,y,z) ((x & y) ^ (~x & z)) |
michael@0 | 32 | #define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z)) |
michael@0 | 33 | #define SHA_MIN(a,b) (a < b ? a : b) |
michael@0 | 34 | |
michael@0 | 35 | /* Padding used with all flavors of SHA */ |
michael@0 | 36 | static const PRUint8 pad[240] = { |
michael@0 | 37 | 0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
michael@0 | 38 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
michael@0 | 39 | /* compiler will fill the rest in with zeros */ |
michael@0 | 40 | }; |
michael@0 | 41 | |
michael@0 | 42 | /* ============= SHA256 implementation ================================== */ |
michael@0 | 43 | |
michael@0 | 44 | /* SHA-256 constants, K256. */ |
michael@0 | 45 | static const PRUint32 K256[64] = { |
michael@0 | 46 | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, |
michael@0 | 47 | 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, |
michael@0 | 48 | 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, |
michael@0 | 49 | 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, |
michael@0 | 50 | 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, |
michael@0 | 51 | 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, |
michael@0 | 52 | 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, |
michael@0 | 53 | 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, |
michael@0 | 54 | 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, |
michael@0 | 55 | 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, |
michael@0 | 56 | 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, |
michael@0 | 57 | 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, |
michael@0 | 58 | 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, |
michael@0 | 59 | 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, |
michael@0 | 60 | 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, |
michael@0 | 61 | 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 |
michael@0 | 62 | }; |
michael@0 | 63 | |
michael@0 | 64 | /* SHA-256 initial hash values */ |
michael@0 | 65 | static const PRUint32 H256[8] = { |
michael@0 | 66 | 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, |
michael@0 | 67 | 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 |
michael@0 | 68 | }; |
michael@0 | 69 | |
michael@0 | 70 | #if (_MSC_VER >= 1300) |
michael@0 | 71 | #include <stdlib.h> |
michael@0 | 72 | #pragma intrinsic(_byteswap_ulong) |
michael@0 | 73 | #define SHA_HTONL(x) _byteswap_ulong(x) |
michael@0 | 74 | #define BYTESWAP4(x) x = SHA_HTONL(x) |
michael@0 | 75 | #elif defined(_MSC_VER) && defined(NSS_X86_OR_X64) |
michael@0 | 76 | #ifndef FORCEINLINE |
michael@0 | 77 | #if (_MSC_VER >= 1200) |
michael@0 | 78 | #define FORCEINLINE __forceinline |
michael@0 | 79 | #else |
michael@0 | 80 | #define FORCEINLINE __inline |
michael@0 | 81 | #endif |
michael@0 | 82 | #endif |
michael@0 | 83 | #define FASTCALL __fastcall |
michael@0 | 84 | |
michael@0 | 85 | static FORCEINLINE PRUint32 FASTCALL |
michael@0 | 86 | swap4b(PRUint32 dwd) |
michael@0 | 87 | { |
michael@0 | 88 | __asm { |
michael@0 | 89 | mov eax,dwd |
michael@0 | 90 | bswap eax |
michael@0 | 91 | } |
michael@0 | 92 | } |
michael@0 | 93 | |
michael@0 | 94 | #define SHA_HTONL(x) swap4b(x) |
michael@0 | 95 | #define BYTESWAP4(x) x = SHA_HTONL(x) |
michael@0 | 96 | |
michael@0 | 97 | #elif defined(__GNUC__) && defined(NSS_X86_OR_X64) |
michael@0 | 98 | static __inline__ PRUint32 swap4b(PRUint32 value) |
michael@0 | 99 | { |
michael@0 | 100 | __asm__("bswap %0" : "+r" (value)); |
michael@0 | 101 | return (value); |
michael@0 | 102 | } |
michael@0 | 103 | #define SHA_HTONL(x) swap4b(x) |
michael@0 | 104 | #define BYTESWAP4(x) x = SHA_HTONL(x) |
michael@0 | 105 | |
michael@0 | 106 | #elif defined(__GNUC__) && (defined(__thumb2__) || \ |
michael@0 | 107 | (!defined(__thumb__) && \ |
michael@0 | 108 | (defined(__ARM_ARCH_6__) || \ |
michael@0 | 109 | defined(__ARM_ARCH_6J__) || \ |
michael@0 | 110 | defined(__ARM_ARCH_6K__) || \ |
michael@0 | 111 | defined(__ARM_ARCH_6Z__) || \ |
michael@0 | 112 | defined(__ARM_ARCH_6ZK__) || \ |
michael@0 | 113 | defined(__ARM_ARCH_6T2__) || \ |
michael@0 | 114 | defined(__ARM_ARCH_7__) || \ |
michael@0 | 115 | defined(__ARM_ARCH_7A__) || \ |
michael@0 | 116 | defined(__ARM_ARCH_7R__)))) |
michael@0 | 117 | static __inline__ PRUint32 swap4b(PRUint32 value) |
michael@0 | 118 | { |
michael@0 | 119 | PRUint32 ret; |
michael@0 | 120 | __asm__("rev %0, %1" : "=r" (ret) : "r"(value)); |
michael@0 | 121 | return ret; |
michael@0 | 122 | } |
michael@0 | 123 | #define SHA_HTONL(x) swap4b(x) |
michael@0 | 124 | #define BYTESWAP4(x) x = SHA_HTONL(x) |
michael@0 | 125 | |
michael@0 | 126 | #else |
michael@0 | 127 | #define SWAP4MASK 0x00FF00FF |
michael@0 | 128 | #define SHA_HTONL(x) (t1 = (x), t1 = (t1 << 16) | (t1 >> 16), \ |
michael@0 | 129 | ((t1 & SWAP4MASK) << 8) | ((t1 >> 8) & SWAP4MASK)) |
michael@0 | 130 | #define BYTESWAP4(x) x = SHA_HTONL(x) |
michael@0 | 131 | #endif |
michael@0 | 132 | |
michael@0 | 133 | #if defined(_MSC_VER) |
michael@0 | 134 | #pragma intrinsic (_lrotr, _lrotl) |
michael@0 | 135 | #define ROTR32(x,n) _lrotr(x,n) |
michael@0 | 136 | #define ROTL32(x,n) _lrotl(x,n) |
michael@0 | 137 | #else |
michael@0 | 138 | #define ROTR32(x,n) ((x >> n) | (x << ((8 * sizeof x) - n))) |
michael@0 | 139 | #define ROTL32(x,n) ((x << n) | (x >> ((8 * sizeof x) - n))) |
michael@0 | 140 | #endif |
michael@0 | 141 | |
michael@0 | 142 | /* Capitol Sigma and lower case sigma functions */ |
michael@0 | 143 | #define S0(x) (ROTR32(x, 2) ^ ROTR32(x,13) ^ ROTR32(x,22)) |
michael@0 | 144 | #define S1(x) (ROTR32(x, 6) ^ ROTR32(x,11) ^ ROTR32(x,25)) |
michael@0 | 145 | #define s0(x) (t1 = x, ROTR32(t1, 7) ^ ROTR32(t1,18) ^ SHR(t1, 3)) |
michael@0 | 146 | #define s1(x) (t2 = x, ROTR32(t2,17) ^ ROTR32(t2,19) ^ SHR(t2,10)) |
michael@0 | 147 | |
michael@0 | 148 | SHA256Context * |
michael@0 | 149 | SHA256_NewContext(void) |
michael@0 | 150 | { |
michael@0 | 151 | SHA256Context *ctx = PORT_New(SHA256Context); |
michael@0 | 152 | return ctx; |
michael@0 | 153 | } |
michael@0 | 154 | |
michael@0 | 155 | void |
michael@0 | 156 | SHA256_DestroyContext(SHA256Context *ctx, PRBool freeit) |
michael@0 | 157 | { |
michael@0 | 158 | memset(ctx, 0, sizeof *ctx); |
michael@0 | 159 | if (freeit) { |
michael@0 | 160 | PORT_Free(ctx); |
michael@0 | 161 | } |
michael@0 | 162 | } |
michael@0 | 163 | |
michael@0 | 164 | void |
michael@0 | 165 | SHA256_Begin(SHA256Context *ctx) |
michael@0 | 166 | { |
michael@0 | 167 | memset(ctx, 0, sizeof *ctx); |
michael@0 | 168 | memcpy(H, H256, sizeof H256); |
michael@0 | 169 | } |
michael@0 | 170 | |
michael@0 | 171 | static void |
michael@0 | 172 | SHA256_Compress(SHA256Context *ctx) |
michael@0 | 173 | { |
michael@0 | 174 | { |
michael@0 | 175 | register PRUint32 t1, t2; |
michael@0 | 176 | |
michael@0 | 177 | #if defined(IS_LITTLE_ENDIAN) |
michael@0 | 178 | BYTESWAP4(W[0]); |
michael@0 | 179 | BYTESWAP4(W[1]); |
michael@0 | 180 | BYTESWAP4(W[2]); |
michael@0 | 181 | BYTESWAP4(W[3]); |
michael@0 | 182 | BYTESWAP4(W[4]); |
michael@0 | 183 | BYTESWAP4(W[5]); |
michael@0 | 184 | BYTESWAP4(W[6]); |
michael@0 | 185 | BYTESWAP4(W[7]); |
michael@0 | 186 | BYTESWAP4(W[8]); |
michael@0 | 187 | BYTESWAP4(W[9]); |
michael@0 | 188 | BYTESWAP4(W[10]); |
michael@0 | 189 | BYTESWAP4(W[11]); |
michael@0 | 190 | BYTESWAP4(W[12]); |
michael@0 | 191 | BYTESWAP4(W[13]); |
michael@0 | 192 | BYTESWAP4(W[14]); |
michael@0 | 193 | BYTESWAP4(W[15]); |
michael@0 | 194 | #endif |
michael@0 | 195 | |
michael@0 | 196 | #define INITW(t) W[t] = (s1(W[t-2]) + W[t-7] + s0(W[t-15]) + W[t-16]) |
michael@0 | 197 | |
michael@0 | 198 | /* prepare the "message schedule" */ |
michael@0 | 199 | #ifdef NOUNROLL256 |
michael@0 | 200 | { |
michael@0 | 201 | int t; |
michael@0 | 202 | for (t = 16; t < 64; ++t) { |
michael@0 | 203 | INITW(t); |
michael@0 | 204 | } |
michael@0 | 205 | } |
michael@0 | 206 | #else |
michael@0 | 207 | INITW(16); |
michael@0 | 208 | INITW(17); |
michael@0 | 209 | INITW(18); |
michael@0 | 210 | INITW(19); |
michael@0 | 211 | |
michael@0 | 212 | INITW(20); |
michael@0 | 213 | INITW(21); |
michael@0 | 214 | INITW(22); |
michael@0 | 215 | INITW(23); |
michael@0 | 216 | INITW(24); |
michael@0 | 217 | INITW(25); |
michael@0 | 218 | INITW(26); |
michael@0 | 219 | INITW(27); |
michael@0 | 220 | INITW(28); |
michael@0 | 221 | INITW(29); |
michael@0 | 222 | |
michael@0 | 223 | INITW(30); |
michael@0 | 224 | INITW(31); |
michael@0 | 225 | INITW(32); |
michael@0 | 226 | INITW(33); |
michael@0 | 227 | INITW(34); |
michael@0 | 228 | INITW(35); |
michael@0 | 229 | INITW(36); |
michael@0 | 230 | INITW(37); |
michael@0 | 231 | INITW(38); |
michael@0 | 232 | INITW(39); |
michael@0 | 233 | |
michael@0 | 234 | INITW(40); |
michael@0 | 235 | INITW(41); |
michael@0 | 236 | INITW(42); |
michael@0 | 237 | INITW(43); |
michael@0 | 238 | INITW(44); |
michael@0 | 239 | INITW(45); |
michael@0 | 240 | INITW(46); |
michael@0 | 241 | INITW(47); |
michael@0 | 242 | INITW(48); |
michael@0 | 243 | INITW(49); |
michael@0 | 244 | |
michael@0 | 245 | INITW(50); |
michael@0 | 246 | INITW(51); |
michael@0 | 247 | INITW(52); |
michael@0 | 248 | INITW(53); |
michael@0 | 249 | INITW(54); |
michael@0 | 250 | INITW(55); |
michael@0 | 251 | INITW(56); |
michael@0 | 252 | INITW(57); |
michael@0 | 253 | INITW(58); |
michael@0 | 254 | INITW(59); |
michael@0 | 255 | |
michael@0 | 256 | INITW(60); |
michael@0 | 257 | INITW(61); |
michael@0 | 258 | INITW(62); |
michael@0 | 259 | INITW(63); |
michael@0 | 260 | |
michael@0 | 261 | #endif |
michael@0 | 262 | #undef INITW |
michael@0 | 263 | } |
michael@0 | 264 | { |
michael@0 | 265 | PRUint32 a, b, c, d, e, f, g, h; |
michael@0 | 266 | |
michael@0 | 267 | a = H[0]; |
michael@0 | 268 | b = H[1]; |
michael@0 | 269 | c = H[2]; |
michael@0 | 270 | d = H[3]; |
michael@0 | 271 | e = H[4]; |
michael@0 | 272 | f = H[5]; |
michael@0 | 273 | g = H[6]; |
michael@0 | 274 | h = H[7]; |
michael@0 | 275 | |
michael@0 | 276 | #define ROUND(n,a,b,c,d,e,f,g,h) \ |
michael@0 | 277 | h += S1(e) + Ch(e,f,g) + K256[n] + W[n]; \ |
michael@0 | 278 | d += h; \ |
michael@0 | 279 | h += S0(a) + Maj(a,b,c); |
michael@0 | 280 | |
michael@0 | 281 | #ifdef NOUNROLL256 |
michael@0 | 282 | { |
michael@0 | 283 | int t; |
michael@0 | 284 | for (t = 0; t < 64; t+= 8) { |
michael@0 | 285 | ROUND(t+0,a,b,c,d,e,f,g,h) |
michael@0 | 286 | ROUND(t+1,h,a,b,c,d,e,f,g) |
michael@0 | 287 | ROUND(t+2,g,h,a,b,c,d,e,f) |
michael@0 | 288 | ROUND(t+3,f,g,h,a,b,c,d,e) |
michael@0 | 289 | ROUND(t+4,e,f,g,h,a,b,c,d) |
michael@0 | 290 | ROUND(t+5,d,e,f,g,h,a,b,c) |
michael@0 | 291 | ROUND(t+6,c,d,e,f,g,h,a,b) |
michael@0 | 292 | ROUND(t+7,b,c,d,e,f,g,h,a) |
michael@0 | 293 | } |
michael@0 | 294 | } |
michael@0 | 295 | #else |
michael@0 | 296 | ROUND( 0,a,b,c,d,e,f,g,h) |
michael@0 | 297 | ROUND( 1,h,a,b,c,d,e,f,g) |
michael@0 | 298 | ROUND( 2,g,h,a,b,c,d,e,f) |
michael@0 | 299 | ROUND( 3,f,g,h,a,b,c,d,e) |
michael@0 | 300 | ROUND( 4,e,f,g,h,a,b,c,d) |
michael@0 | 301 | ROUND( 5,d,e,f,g,h,a,b,c) |
michael@0 | 302 | ROUND( 6,c,d,e,f,g,h,a,b) |
michael@0 | 303 | ROUND( 7,b,c,d,e,f,g,h,a) |
michael@0 | 304 | |
michael@0 | 305 | ROUND( 8,a,b,c,d,e,f,g,h) |
michael@0 | 306 | ROUND( 9,h,a,b,c,d,e,f,g) |
michael@0 | 307 | ROUND(10,g,h,a,b,c,d,e,f) |
michael@0 | 308 | ROUND(11,f,g,h,a,b,c,d,e) |
michael@0 | 309 | ROUND(12,e,f,g,h,a,b,c,d) |
michael@0 | 310 | ROUND(13,d,e,f,g,h,a,b,c) |
michael@0 | 311 | ROUND(14,c,d,e,f,g,h,a,b) |
michael@0 | 312 | ROUND(15,b,c,d,e,f,g,h,a) |
michael@0 | 313 | |
michael@0 | 314 | ROUND(16,a,b,c,d,e,f,g,h) |
michael@0 | 315 | ROUND(17,h,a,b,c,d,e,f,g) |
michael@0 | 316 | ROUND(18,g,h,a,b,c,d,e,f) |
michael@0 | 317 | ROUND(19,f,g,h,a,b,c,d,e) |
michael@0 | 318 | ROUND(20,e,f,g,h,a,b,c,d) |
michael@0 | 319 | ROUND(21,d,e,f,g,h,a,b,c) |
michael@0 | 320 | ROUND(22,c,d,e,f,g,h,a,b) |
michael@0 | 321 | ROUND(23,b,c,d,e,f,g,h,a) |
michael@0 | 322 | |
michael@0 | 323 | ROUND(24,a,b,c,d,e,f,g,h) |
michael@0 | 324 | ROUND(25,h,a,b,c,d,e,f,g) |
michael@0 | 325 | ROUND(26,g,h,a,b,c,d,e,f) |
michael@0 | 326 | ROUND(27,f,g,h,a,b,c,d,e) |
michael@0 | 327 | ROUND(28,e,f,g,h,a,b,c,d) |
michael@0 | 328 | ROUND(29,d,e,f,g,h,a,b,c) |
michael@0 | 329 | ROUND(30,c,d,e,f,g,h,a,b) |
michael@0 | 330 | ROUND(31,b,c,d,e,f,g,h,a) |
michael@0 | 331 | |
michael@0 | 332 | ROUND(32,a,b,c,d,e,f,g,h) |
michael@0 | 333 | ROUND(33,h,a,b,c,d,e,f,g) |
michael@0 | 334 | ROUND(34,g,h,a,b,c,d,e,f) |
michael@0 | 335 | ROUND(35,f,g,h,a,b,c,d,e) |
michael@0 | 336 | ROUND(36,e,f,g,h,a,b,c,d) |
michael@0 | 337 | ROUND(37,d,e,f,g,h,a,b,c) |
michael@0 | 338 | ROUND(38,c,d,e,f,g,h,a,b) |
michael@0 | 339 | ROUND(39,b,c,d,e,f,g,h,a) |
michael@0 | 340 | |
michael@0 | 341 | ROUND(40,a,b,c,d,e,f,g,h) |
michael@0 | 342 | ROUND(41,h,a,b,c,d,e,f,g) |
michael@0 | 343 | ROUND(42,g,h,a,b,c,d,e,f) |
michael@0 | 344 | ROUND(43,f,g,h,a,b,c,d,e) |
michael@0 | 345 | ROUND(44,e,f,g,h,a,b,c,d) |
michael@0 | 346 | ROUND(45,d,e,f,g,h,a,b,c) |
michael@0 | 347 | ROUND(46,c,d,e,f,g,h,a,b) |
michael@0 | 348 | ROUND(47,b,c,d,e,f,g,h,a) |
michael@0 | 349 | |
michael@0 | 350 | ROUND(48,a,b,c,d,e,f,g,h) |
michael@0 | 351 | ROUND(49,h,a,b,c,d,e,f,g) |
michael@0 | 352 | ROUND(50,g,h,a,b,c,d,e,f) |
michael@0 | 353 | ROUND(51,f,g,h,a,b,c,d,e) |
michael@0 | 354 | ROUND(52,e,f,g,h,a,b,c,d) |
michael@0 | 355 | ROUND(53,d,e,f,g,h,a,b,c) |
michael@0 | 356 | ROUND(54,c,d,e,f,g,h,a,b) |
michael@0 | 357 | ROUND(55,b,c,d,e,f,g,h,a) |
michael@0 | 358 | |
michael@0 | 359 | ROUND(56,a,b,c,d,e,f,g,h) |
michael@0 | 360 | ROUND(57,h,a,b,c,d,e,f,g) |
michael@0 | 361 | ROUND(58,g,h,a,b,c,d,e,f) |
michael@0 | 362 | ROUND(59,f,g,h,a,b,c,d,e) |
michael@0 | 363 | ROUND(60,e,f,g,h,a,b,c,d) |
michael@0 | 364 | ROUND(61,d,e,f,g,h,a,b,c) |
michael@0 | 365 | ROUND(62,c,d,e,f,g,h,a,b) |
michael@0 | 366 | ROUND(63,b,c,d,e,f,g,h,a) |
michael@0 | 367 | #endif |
michael@0 | 368 | |
michael@0 | 369 | H[0] += a; |
michael@0 | 370 | H[1] += b; |
michael@0 | 371 | H[2] += c; |
michael@0 | 372 | H[3] += d; |
michael@0 | 373 | H[4] += e; |
michael@0 | 374 | H[5] += f; |
michael@0 | 375 | H[6] += g; |
michael@0 | 376 | H[7] += h; |
michael@0 | 377 | } |
michael@0 | 378 | #undef ROUND |
michael@0 | 379 | } |
michael@0 | 380 | |
michael@0 | 381 | #undef s0 |
michael@0 | 382 | #undef s1 |
michael@0 | 383 | #undef S0 |
michael@0 | 384 | #undef S1 |
michael@0 | 385 | |
michael@0 | 386 | void |
michael@0 | 387 | SHA256_Update(SHA256Context *ctx, const unsigned char *input, |
michael@0 | 388 | unsigned int inputLen) |
michael@0 | 389 | { |
michael@0 | 390 | unsigned int inBuf = ctx->sizeLo & 0x3f; |
michael@0 | 391 | if (!inputLen) |
michael@0 | 392 | return; |
michael@0 | 393 | |
michael@0 | 394 | /* Add inputLen into the count of bytes processed, before processing */ |
michael@0 | 395 | if ((ctx->sizeLo += inputLen) < inputLen) |
michael@0 | 396 | ctx->sizeHi++; |
michael@0 | 397 | |
michael@0 | 398 | /* if data already in buffer, attemp to fill rest of buffer */ |
michael@0 | 399 | if (inBuf) { |
michael@0 | 400 | unsigned int todo = SHA256_BLOCK_LENGTH - inBuf; |
michael@0 | 401 | if (inputLen < todo) |
michael@0 | 402 | todo = inputLen; |
michael@0 | 403 | memcpy(B + inBuf, input, todo); |
michael@0 | 404 | input += todo; |
michael@0 | 405 | inputLen -= todo; |
michael@0 | 406 | if (inBuf + todo == SHA256_BLOCK_LENGTH) |
michael@0 | 407 | SHA256_Compress(ctx); |
michael@0 | 408 | } |
michael@0 | 409 | |
michael@0 | 410 | /* if enough data to fill one or more whole buffers, process them. */ |
michael@0 | 411 | while (inputLen >= SHA256_BLOCK_LENGTH) { |
michael@0 | 412 | memcpy(B, input, SHA256_BLOCK_LENGTH); |
michael@0 | 413 | input += SHA256_BLOCK_LENGTH; |
michael@0 | 414 | inputLen -= SHA256_BLOCK_LENGTH; |
michael@0 | 415 | SHA256_Compress(ctx); |
michael@0 | 416 | } |
michael@0 | 417 | /* if data left over, fill it into buffer */ |
michael@0 | 418 | if (inputLen) |
michael@0 | 419 | memcpy(B, input, inputLen); |
michael@0 | 420 | } |
michael@0 | 421 | |
michael@0 | 422 | void |
michael@0 | 423 | SHA256_End(SHA256Context *ctx, unsigned char *digest, |
michael@0 | 424 | unsigned int *digestLen, unsigned int maxDigestLen) |
michael@0 | 425 | { |
michael@0 | 426 | unsigned int inBuf = ctx->sizeLo & 0x3f; |
michael@0 | 427 | unsigned int padLen = (inBuf < 56) ? (56 - inBuf) : (56 + 64 - inBuf); |
michael@0 | 428 | PRUint32 hi, lo; |
michael@0 | 429 | #ifdef SWAP4MASK |
michael@0 | 430 | PRUint32 t1; |
michael@0 | 431 | #endif |
michael@0 | 432 | |
michael@0 | 433 | hi = (ctx->sizeHi << 3) | (ctx->sizeLo >> 29); |
michael@0 | 434 | lo = (ctx->sizeLo << 3); |
michael@0 | 435 | |
michael@0 | 436 | SHA256_Update(ctx, pad, padLen); |
michael@0 | 437 | |
michael@0 | 438 | #if defined(IS_LITTLE_ENDIAN) |
michael@0 | 439 | W[14] = SHA_HTONL(hi); |
michael@0 | 440 | W[15] = SHA_HTONL(lo); |
michael@0 | 441 | #else |
michael@0 | 442 | W[14] = hi; |
michael@0 | 443 | W[15] = lo; |
michael@0 | 444 | #endif |
michael@0 | 445 | SHA256_Compress(ctx); |
michael@0 | 446 | |
michael@0 | 447 | /* now output the answer */ |
michael@0 | 448 | #if defined(IS_LITTLE_ENDIAN) |
michael@0 | 449 | BYTESWAP4(H[0]); |
michael@0 | 450 | BYTESWAP4(H[1]); |
michael@0 | 451 | BYTESWAP4(H[2]); |
michael@0 | 452 | BYTESWAP4(H[3]); |
michael@0 | 453 | BYTESWAP4(H[4]); |
michael@0 | 454 | BYTESWAP4(H[5]); |
michael@0 | 455 | BYTESWAP4(H[6]); |
michael@0 | 456 | BYTESWAP4(H[7]); |
michael@0 | 457 | #endif |
michael@0 | 458 | padLen = PR_MIN(SHA256_LENGTH, maxDigestLen); |
michael@0 | 459 | memcpy(digest, H, padLen); |
michael@0 | 460 | if (digestLen) |
michael@0 | 461 | *digestLen = padLen; |
michael@0 | 462 | } |
michael@0 | 463 | |
michael@0 | 464 | void |
michael@0 | 465 | SHA256_EndRaw(SHA256Context *ctx, unsigned char *digest, |
michael@0 | 466 | unsigned int *digestLen, unsigned int maxDigestLen) |
michael@0 | 467 | { |
michael@0 | 468 | PRUint32 h[8]; |
michael@0 | 469 | unsigned int len; |
michael@0 | 470 | #ifdef SWAP4MASK |
michael@0 | 471 | PRUint32 t1; |
michael@0 | 472 | #endif |
michael@0 | 473 | |
michael@0 | 474 | memcpy(h, ctx->h, sizeof(h)); |
michael@0 | 475 | |
michael@0 | 476 | #if defined(IS_LITTLE_ENDIAN) |
michael@0 | 477 | BYTESWAP4(h[0]); |
michael@0 | 478 | BYTESWAP4(h[1]); |
michael@0 | 479 | BYTESWAP4(h[2]); |
michael@0 | 480 | BYTESWAP4(h[3]); |
michael@0 | 481 | BYTESWAP4(h[4]); |
michael@0 | 482 | BYTESWAP4(h[5]); |
michael@0 | 483 | BYTESWAP4(h[6]); |
michael@0 | 484 | BYTESWAP4(h[7]); |
michael@0 | 485 | #endif |
michael@0 | 486 | |
michael@0 | 487 | len = PR_MIN(SHA256_LENGTH, maxDigestLen); |
michael@0 | 488 | memcpy(digest, h, len); |
michael@0 | 489 | if (digestLen) |
michael@0 | 490 | *digestLen = len; |
michael@0 | 491 | } |
michael@0 | 492 | |
michael@0 | 493 | SECStatus |
michael@0 | 494 | SHA256_HashBuf(unsigned char *dest, const unsigned char *src, |
michael@0 | 495 | PRUint32 src_length) |
michael@0 | 496 | { |
michael@0 | 497 | SHA256Context ctx; |
michael@0 | 498 | unsigned int outLen; |
michael@0 | 499 | |
michael@0 | 500 | SHA256_Begin(&ctx); |
michael@0 | 501 | SHA256_Update(&ctx, src, src_length); |
michael@0 | 502 | SHA256_End(&ctx, dest, &outLen, SHA256_LENGTH); |
michael@0 | 503 | memset(&ctx, 0, sizeof ctx); |
michael@0 | 504 | |
michael@0 | 505 | return SECSuccess; |
michael@0 | 506 | } |
michael@0 | 507 | |
michael@0 | 508 | |
michael@0 | 509 | SECStatus |
michael@0 | 510 | SHA256_Hash(unsigned char *dest, const char *src) |
michael@0 | 511 | { |
michael@0 | 512 | return SHA256_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src)); |
michael@0 | 513 | } |
michael@0 | 514 | |
michael@0 | 515 | |
michael@0 | 516 | void SHA256_TraceState(SHA256Context *ctx) { } |
michael@0 | 517 | |
michael@0 | 518 | unsigned int |
michael@0 | 519 | SHA256_FlattenSize(SHA256Context *ctx) |
michael@0 | 520 | { |
michael@0 | 521 | return sizeof *ctx; |
michael@0 | 522 | } |
michael@0 | 523 | |
michael@0 | 524 | SECStatus |
michael@0 | 525 | SHA256_Flatten(SHA256Context *ctx,unsigned char *space) |
michael@0 | 526 | { |
michael@0 | 527 | PORT_Memcpy(space, ctx, sizeof *ctx); |
michael@0 | 528 | return SECSuccess; |
michael@0 | 529 | } |
michael@0 | 530 | |
michael@0 | 531 | SHA256Context * |
michael@0 | 532 | SHA256_Resurrect(unsigned char *space, void *arg) |
michael@0 | 533 | { |
michael@0 | 534 | SHA256Context *ctx = SHA256_NewContext(); |
michael@0 | 535 | if (ctx) |
michael@0 | 536 | PORT_Memcpy(ctx, space, sizeof *ctx); |
michael@0 | 537 | return ctx; |
michael@0 | 538 | } |
michael@0 | 539 | |
michael@0 | 540 | void SHA256_Clone(SHA256Context *dest, SHA256Context *src) |
michael@0 | 541 | { |
michael@0 | 542 | memcpy(dest, src, sizeof *dest); |
michael@0 | 543 | } |
michael@0 | 544 | |
michael@0 | 545 | /* ============= SHA224 implementation ================================== */ |
michael@0 | 546 | |
michael@0 | 547 | /* SHA-224 initial hash values */ |
michael@0 | 548 | static const PRUint32 H224[8] = { |
michael@0 | 549 | 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, |
michael@0 | 550 | 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 |
michael@0 | 551 | }; |
michael@0 | 552 | |
michael@0 | 553 | SHA224Context * |
michael@0 | 554 | SHA224_NewContext(void) |
michael@0 | 555 | { |
michael@0 | 556 | return SHA256_NewContext(); |
michael@0 | 557 | } |
michael@0 | 558 | |
michael@0 | 559 | void |
michael@0 | 560 | SHA224_DestroyContext(SHA224Context *ctx, PRBool freeit) |
michael@0 | 561 | { |
michael@0 | 562 | SHA256_DestroyContext(ctx, freeit); |
michael@0 | 563 | } |
michael@0 | 564 | |
michael@0 | 565 | void |
michael@0 | 566 | SHA224_Begin(SHA224Context *ctx) |
michael@0 | 567 | { |
michael@0 | 568 | memset(ctx, 0, sizeof *ctx); |
michael@0 | 569 | memcpy(H, H224, sizeof H224); |
michael@0 | 570 | } |
michael@0 | 571 | |
michael@0 | 572 | void |
michael@0 | 573 | SHA224_Update(SHA224Context *ctx, const unsigned char *input, |
michael@0 | 574 | unsigned int inputLen) |
michael@0 | 575 | { |
michael@0 | 576 | SHA256_Update(ctx, input, inputLen); |
michael@0 | 577 | } |
michael@0 | 578 | |
michael@0 | 579 | void |
michael@0 | 580 | SHA224_End(SHA256Context *ctx, unsigned char *digest, |
michael@0 | 581 | unsigned int *digestLen, unsigned int maxDigestLen) |
michael@0 | 582 | { |
michael@0 | 583 | unsigned int maxLen = SHA_MIN(maxDigestLen, SHA224_LENGTH); |
michael@0 | 584 | SHA256_End(ctx, digest, digestLen, maxLen); |
michael@0 | 585 | } |
michael@0 | 586 | |
michael@0 | 587 | void |
michael@0 | 588 | SHA224_EndRaw(SHA256Context *ctx, unsigned char *digest, |
michael@0 | 589 | unsigned int *digestLen, unsigned int maxDigestLen) |
michael@0 | 590 | { |
michael@0 | 591 | unsigned int maxLen = SHA_MIN(maxDigestLen, SHA224_LENGTH); |
michael@0 | 592 | SHA256_EndRaw(ctx, digest, digestLen, maxLen); |
michael@0 | 593 | } |
michael@0 | 594 | |
michael@0 | 595 | SECStatus |
michael@0 | 596 | SHA224_HashBuf(unsigned char *dest, const unsigned char *src, |
michael@0 | 597 | PRUint32 src_length) |
michael@0 | 598 | { |
michael@0 | 599 | SHA256Context ctx; |
michael@0 | 600 | unsigned int outLen; |
michael@0 | 601 | |
michael@0 | 602 | SHA224_Begin(&ctx); |
michael@0 | 603 | SHA256_Update(&ctx, src, src_length); |
michael@0 | 604 | SHA256_End(&ctx, dest, &outLen, SHA224_LENGTH); |
michael@0 | 605 | memset(&ctx, 0, sizeof ctx); |
michael@0 | 606 | |
michael@0 | 607 | return SECSuccess; |
michael@0 | 608 | } |
michael@0 | 609 | |
michael@0 | 610 | SECStatus |
michael@0 | 611 | SHA224_Hash(unsigned char *dest, const char *src) |
michael@0 | 612 | { |
michael@0 | 613 | return SHA224_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src)); |
michael@0 | 614 | } |
michael@0 | 615 | |
michael@0 | 616 | void SHA224_TraceState(SHA224Context *ctx) { } |
michael@0 | 617 | |
michael@0 | 618 | unsigned int |
michael@0 | 619 | SHA224_FlattenSize(SHA224Context *ctx) |
michael@0 | 620 | { |
michael@0 | 621 | return SHA256_FlattenSize(ctx); |
michael@0 | 622 | } |
michael@0 | 623 | |
michael@0 | 624 | SECStatus |
michael@0 | 625 | SHA224_Flatten(SHA224Context *ctx, unsigned char *space) |
michael@0 | 626 | { |
michael@0 | 627 | return SHA256_Flatten(ctx, space); |
michael@0 | 628 | } |
michael@0 | 629 | |
michael@0 | 630 | SHA224Context * |
michael@0 | 631 | SHA224_Resurrect(unsigned char *space, void *arg) |
michael@0 | 632 | { |
michael@0 | 633 | return SHA256_Resurrect(space, arg); |
michael@0 | 634 | } |
michael@0 | 635 | |
michael@0 | 636 | void SHA224_Clone(SHA224Context *dest, SHA224Context *src) |
michael@0 | 637 | { |
michael@0 | 638 | SHA256_Clone(dest, src); |
michael@0 | 639 | } |
michael@0 | 640 | |
michael@0 | 641 | |
michael@0 | 642 | /* ======= SHA512 and SHA384 common constants and defines ================= */ |
michael@0 | 643 | |
michael@0 | 644 | /* common #defines for SHA512 and SHA384 */ |
michael@0 | 645 | #if defined(HAVE_LONG_LONG) |
michael@0 | 646 | #if defined(_MSC_VER) |
michael@0 | 647 | #pragma intrinsic(_rotr64,_rotl64) |
michael@0 | 648 | #define ROTR64(x,n) _rotr64(x,n) |
michael@0 | 649 | #define ROTL64(x,n) _rotl64(x,n) |
michael@0 | 650 | #else |
michael@0 | 651 | #define ROTR64(x,n) ((x >> n) | (x << (64 - n))) |
michael@0 | 652 | #define ROTL64(x,n) ((x << n) | (x >> (64 - n))) |
michael@0 | 653 | #endif |
michael@0 | 654 | |
michael@0 | 655 | #define S0(x) (ROTR64(x,28) ^ ROTR64(x,34) ^ ROTR64(x,39)) |
michael@0 | 656 | #define S1(x) (ROTR64(x,14) ^ ROTR64(x,18) ^ ROTR64(x,41)) |
michael@0 | 657 | #define s0(x) (t1 = x, ROTR64(t1, 1) ^ ROTR64(t1, 8) ^ SHR(t1,7)) |
michael@0 | 658 | #define s1(x) (t2 = x, ROTR64(t2,19) ^ ROTR64(t2,61) ^ SHR(t2,6)) |
michael@0 | 659 | |
michael@0 | 660 | #if PR_BYTES_PER_LONG == 8 |
michael@0 | 661 | #define ULLC(hi,lo) 0x ## hi ## lo ## UL |
michael@0 | 662 | #elif defined(_MSC_VER) |
michael@0 | 663 | #define ULLC(hi,lo) 0x ## hi ## lo ## ui64 |
michael@0 | 664 | #else |
michael@0 | 665 | #define ULLC(hi,lo) 0x ## hi ## lo ## ULL |
michael@0 | 666 | #endif |
michael@0 | 667 | |
michael@0 | 668 | #if defined(_MSC_VER) |
michael@0 | 669 | #pragma intrinsic(_byteswap_uint64) |
michael@0 | 670 | #define SHA_HTONLL(x) _byteswap_uint64(x) |
michael@0 | 671 | |
michael@0 | 672 | #elif defined(__GNUC__) && (defined(__x86_64__) || defined(__x86_64)) |
michael@0 | 673 | static __inline__ PRUint64 swap8b(PRUint64 value) |
michael@0 | 674 | { |
michael@0 | 675 | __asm__("bswapq %0" : "+r" (value)); |
michael@0 | 676 | return (value); |
michael@0 | 677 | } |
michael@0 | 678 | #define SHA_HTONLL(x) swap8b(x) |
michael@0 | 679 | |
michael@0 | 680 | #else |
michael@0 | 681 | #define SHA_MASK16 ULLC(0000FFFF,0000FFFF) |
michael@0 | 682 | #define SHA_MASK8 ULLC(00FF00FF,00FF00FF) |
michael@0 | 683 | #define SHA_HTONLL(x) (t1 = x, \ |
michael@0 | 684 | t1 = ((t1 & SHA_MASK8 ) << 8) | ((t1 >> 8) & SHA_MASK8 ), \ |
michael@0 | 685 | t1 = ((t1 & SHA_MASK16) << 16) | ((t1 >> 16) & SHA_MASK16), \ |
michael@0 | 686 | (t1 >> 32) | (t1 << 32)) |
michael@0 | 687 | #endif |
michael@0 | 688 | #define BYTESWAP8(x) x = SHA_HTONLL(x) |
michael@0 | 689 | |
michael@0 | 690 | #else /* no long long */ |
michael@0 | 691 | |
michael@0 | 692 | #if defined(IS_LITTLE_ENDIAN) |
michael@0 | 693 | #define ULLC(hi,lo) { 0x ## lo ## U, 0x ## hi ## U } |
michael@0 | 694 | #else |
michael@0 | 695 | #define ULLC(hi,lo) { 0x ## hi ## U, 0x ## lo ## U } |
michael@0 | 696 | #endif |
michael@0 | 697 | |
michael@0 | 698 | #define SHA_HTONLL(x) ( BYTESWAP4(x.lo), BYTESWAP4(x.hi), \ |
michael@0 | 699 | x.hi ^= x.lo ^= x.hi ^= x.lo, x) |
michael@0 | 700 | #define BYTESWAP8(x) do { PRUint32 tmp; BYTESWAP4(x.lo); BYTESWAP4(x.hi); \ |
michael@0 | 701 | tmp = x.lo; x.lo = x.hi; x.hi = tmp; } while (0) |
michael@0 | 702 | #endif |
michael@0 | 703 | |
michael@0 | 704 | /* SHA-384 and SHA-512 constants, K512. */ |
michael@0 | 705 | static const PRUint64 K512[80] = { |
michael@0 | 706 | #if PR_BYTES_PER_LONG == 8 |
michael@0 | 707 | 0x428a2f98d728ae22UL , 0x7137449123ef65cdUL , |
michael@0 | 708 | 0xb5c0fbcfec4d3b2fUL , 0xe9b5dba58189dbbcUL , |
michael@0 | 709 | 0x3956c25bf348b538UL , 0x59f111f1b605d019UL , |
michael@0 | 710 | 0x923f82a4af194f9bUL , 0xab1c5ed5da6d8118UL , |
michael@0 | 711 | 0xd807aa98a3030242UL , 0x12835b0145706fbeUL , |
michael@0 | 712 | 0x243185be4ee4b28cUL , 0x550c7dc3d5ffb4e2UL , |
michael@0 | 713 | 0x72be5d74f27b896fUL , 0x80deb1fe3b1696b1UL , |
michael@0 | 714 | 0x9bdc06a725c71235UL , 0xc19bf174cf692694UL , |
michael@0 | 715 | 0xe49b69c19ef14ad2UL , 0xefbe4786384f25e3UL , |
michael@0 | 716 | 0x0fc19dc68b8cd5b5UL , 0x240ca1cc77ac9c65UL , |
michael@0 | 717 | 0x2de92c6f592b0275UL , 0x4a7484aa6ea6e483UL , |
michael@0 | 718 | 0x5cb0a9dcbd41fbd4UL , 0x76f988da831153b5UL , |
michael@0 | 719 | 0x983e5152ee66dfabUL , 0xa831c66d2db43210UL , |
michael@0 | 720 | 0xb00327c898fb213fUL , 0xbf597fc7beef0ee4UL , |
michael@0 | 721 | 0xc6e00bf33da88fc2UL , 0xd5a79147930aa725UL , |
michael@0 | 722 | 0x06ca6351e003826fUL , 0x142929670a0e6e70UL , |
michael@0 | 723 | 0x27b70a8546d22ffcUL , 0x2e1b21385c26c926UL , |
michael@0 | 724 | 0x4d2c6dfc5ac42aedUL , 0x53380d139d95b3dfUL , |
michael@0 | 725 | 0x650a73548baf63deUL , 0x766a0abb3c77b2a8UL , |
michael@0 | 726 | 0x81c2c92e47edaee6UL , 0x92722c851482353bUL , |
michael@0 | 727 | 0xa2bfe8a14cf10364UL , 0xa81a664bbc423001UL , |
michael@0 | 728 | 0xc24b8b70d0f89791UL , 0xc76c51a30654be30UL , |
michael@0 | 729 | 0xd192e819d6ef5218UL , 0xd69906245565a910UL , |
michael@0 | 730 | 0xf40e35855771202aUL , 0x106aa07032bbd1b8UL , |
michael@0 | 731 | 0x19a4c116b8d2d0c8UL , 0x1e376c085141ab53UL , |
michael@0 | 732 | 0x2748774cdf8eeb99UL , 0x34b0bcb5e19b48a8UL , |
michael@0 | 733 | 0x391c0cb3c5c95a63UL , 0x4ed8aa4ae3418acbUL , |
michael@0 | 734 | 0x5b9cca4f7763e373UL , 0x682e6ff3d6b2b8a3UL , |
michael@0 | 735 | 0x748f82ee5defb2fcUL , 0x78a5636f43172f60UL , |
michael@0 | 736 | 0x84c87814a1f0ab72UL , 0x8cc702081a6439ecUL , |
michael@0 | 737 | 0x90befffa23631e28UL , 0xa4506cebde82bde9UL , |
michael@0 | 738 | 0xbef9a3f7b2c67915UL , 0xc67178f2e372532bUL , |
michael@0 | 739 | 0xca273eceea26619cUL , 0xd186b8c721c0c207UL , |
michael@0 | 740 | 0xeada7dd6cde0eb1eUL , 0xf57d4f7fee6ed178UL , |
michael@0 | 741 | 0x06f067aa72176fbaUL , 0x0a637dc5a2c898a6UL , |
michael@0 | 742 | 0x113f9804bef90daeUL , 0x1b710b35131c471bUL , |
michael@0 | 743 | 0x28db77f523047d84UL , 0x32caab7b40c72493UL , |
michael@0 | 744 | 0x3c9ebe0a15c9bebcUL , 0x431d67c49c100d4cUL , |
michael@0 | 745 | 0x4cc5d4becb3e42b6UL , 0x597f299cfc657e2aUL , |
michael@0 | 746 | 0x5fcb6fab3ad6faecUL , 0x6c44198c4a475817UL |
michael@0 | 747 | #else |
michael@0 | 748 | ULLC(428a2f98,d728ae22), ULLC(71374491,23ef65cd), |
michael@0 | 749 | ULLC(b5c0fbcf,ec4d3b2f), ULLC(e9b5dba5,8189dbbc), |
michael@0 | 750 | ULLC(3956c25b,f348b538), ULLC(59f111f1,b605d019), |
michael@0 | 751 | ULLC(923f82a4,af194f9b), ULLC(ab1c5ed5,da6d8118), |
michael@0 | 752 | ULLC(d807aa98,a3030242), ULLC(12835b01,45706fbe), |
michael@0 | 753 | ULLC(243185be,4ee4b28c), ULLC(550c7dc3,d5ffb4e2), |
michael@0 | 754 | ULLC(72be5d74,f27b896f), ULLC(80deb1fe,3b1696b1), |
michael@0 | 755 | ULLC(9bdc06a7,25c71235), ULLC(c19bf174,cf692694), |
michael@0 | 756 | ULLC(e49b69c1,9ef14ad2), ULLC(efbe4786,384f25e3), |
michael@0 | 757 | ULLC(0fc19dc6,8b8cd5b5), ULLC(240ca1cc,77ac9c65), |
michael@0 | 758 | ULLC(2de92c6f,592b0275), ULLC(4a7484aa,6ea6e483), |
michael@0 | 759 | ULLC(5cb0a9dc,bd41fbd4), ULLC(76f988da,831153b5), |
michael@0 | 760 | ULLC(983e5152,ee66dfab), ULLC(a831c66d,2db43210), |
michael@0 | 761 | ULLC(b00327c8,98fb213f), ULLC(bf597fc7,beef0ee4), |
michael@0 | 762 | ULLC(c6e00bf3,3da88fc2), ULLC(d5a79147,930aa725), |
michael@0 | 763 | ULLC(06ca6351,e003826f), ULLC(14292967,0a0e6e70), |
michael@0 | 764 | ULLC(27b70a85,46d22ffc), ULLC(2e1b2138,5c26c926), |
michael@0 | 765 | ULLC(4d2c6dfc,5ac42aed), ULLC(53380d13,9d95b3df), |
michael@0 | 766 | ULLC(650a7354,8baf63de), ULLC(766a0abb,3c77b2a8), |
michael@0 | 767 | ULLC(81c2c92e,47edaee6), ULLC(92722c85,1482353b), |
michael@0 | 768 | ULLC(a2bfe8a1,4cf10364), ULLC(a81a664b,bc423001), |
michael@0 | 769 | ULLC(c24b8b70,d0f89791), ULLC(c76c51a3,0654be30), |
michael@0 | 770 | ULLC(d192e819,d6ef5218), ULLC(d6990624,5565a910), |
michael@0 | 771 | ULLC(f40e3585,5771202a), ULLC(106aa070,32bbd1b8), |
michael@0 | 772 | ULLC(19a4c116,b8d2d0c8), ULLC(1e376c08,5141ab53), |
michael@0 | 773 | ULLC(2748774c,df8eeb99), ULLC(34b0bcb5,e19b48a8), |
michael@0 | 774 | ULLC(391c0cb3,c5c95a63), ULLC(4ed8aa4a,e3418acb), |
michael@0 | 775 | ULLC(5b9cca4f,7763e373), ULLC(682e6ff3,d6b2b8a3), |
michael@0 | 776 | ULLC(748f82ee,5defb2fc), ULLC(78a5636f,43172f60), |
michael@0 | 777 | ULLC(84c87814,a1f0ab72), ULLC(8cc70208,1a6439ec), |
michael@0 | 778 | ULLC(90befffa,23631e28), ULLC(a4506ceb,de82bde9), |
michael@0 | 779 | ULLC(bef9a3f7,b2c67915), ULLC(c67178f2,e372532b), |
michael@0 | 780 | ULLC(ca273ece,ea26619c), ULLC(d186b8c7,21c0c207), |
michael@0 | 781 | ULLC(eada7dd6,cde0eb1e), ULLC(f57d4f7f,ee6ed178), |
michael@0 | 782 | ULLC(06f067aa,72176fba), ULLC(0a637dc5,a2c898a6), |
michael@0 | 783 | ULLC(113f9804,bef90dae), ULLC(1b710b35,131c471b), |
michael@0 | 784 | ULLC(28db77f5,23047d84), ULLC(32caab7b,40c72493), |
michael@0 | 785 | ULLC(3c9ebe0a,15c9bebc), ULLC(431d67c4,9c100d4c), |
michael@0 | 786 | ULLC(4cc5d4be,cb3e42b6), ULLC(597f299c,fc657e2a), |
michael@0 | 787 | ULLC(5fcb6fab,3ad6faec), ULLC(6c44198c,4a475817) |
michael@0 | 788 | #endif |
michael@0 | 789 | }; |
michael@0 | 790 | |
michael@0 | 791 | struct SHA512ContextStr { |
michael@0 | 792 | union { |
michael@0 | 793 | PRUint64 w[80]; /* message schedule, input buffer, plus 64 words */ |
michael@0 | 794 | PRUint32 l[160]; |
michael@0 | 795 | PRUint8 b[640]; |
michael@0 | 796 | } u; |
michael@0 | 797 | PRUint64 h[8]; /* 8 state variables */ |
michael@0 | 798 | PRUint64 sizeLo; /* 64-bit count of hashed bytes. */ |
michael@0 | 799 | }; |
michael@0 | 800 | |
michael@0 | 801 | /* =========== SHA512 implementation ===================================== */ |
michael@0 | 802 | |
michael@0 | 803 | /* SHA-512 initial hash values */ |
michael@0 | 804 | static const PRUint64 H512[8] = { |
michael@0 | 805 | #if PR_BYTES_PER_LONG == 8 |
michael@0 | 806 | 0x6a09e667f3bcc908UL , 0xbb67ae8584caa73bUL , |
michael@0 | 807 | 0x3c6ef372fe94f82bUL , 0xa54ff53a5f1d36f1UL , |
michael@0 | 808 | 0x510e527fade682d1UL , 0x9b05688c2b3e6c1fUL , |
michael@0 | 809 | 0x1f83d9abfb41bd6bUL , 0x5be0cd19137e2179UL |
michael@0 | 810 | #else |
michael@0 | 811 | ULLC(6a09e667,f3bcc908), ULLC(bb67ae85,84caa73b), |
michael@0 | 812 | ULLC(3c6ef372,fe94f82b), ULLC(a54ff53a,5f1d36f1), |
michael@0 | 813 | ULLC(510e527f,ade682d1), ULLC(9b05688c,2b3e6c1f), |
michael@0 | 814 | ULLC(1f83d9ab,fb41bd6b), ULLC(5be0cd19,137e2179) |
michael@0 | 815 | #endif |
michael@0 | 816 | }; |
michael@0 | 817 | |
michael@0 | 818 | |
michael@0 | 819 | SHA512Context * |
michael@0 | 820 | SHA512_NewContext(void) |
michael@0 | 821 | { |
michael@0 | 822 | SHA512Context *ctx = PORT_New(SHA512Context); |
michael@0 | 823 | return ctx; |
michael@0 | 824 | } |
michael@0 | 825 | |
michael@0 | 826 | void |
michael@0 | 827 | SHA512_DestroyContext(SHA512Context *ctx, PRBool freeit) |
michael@0 | 828 | { |
michael@0 | 829 | memset(ctx, 0, sizeof *ctx); |
michael@0 | 830 | if (freeit) { |
michael@0 | 831 | PORT_Free(ctx); |
michael@0 | 832 | } |
michael@0 | 833 | } |
michael@0 | 834 | |
michael@0 | 835 | void |
michael@0 | 836 | SHA512_Begin(SHA512Context *ctx) |
michael@0 | 837 | { |
michael@0 | 838 | memset(ctx, 0, sizeof *ctx); |
michael@0 | 839 | memcpy(H, H512, sizeof H512); |
michael@0 | 840 | } |
michael@0 | 841 | |
michael@0 | 842 | #if defined(SHA512_TRACE) |
michael@0 | 843 | #if defined(HAVE_LONG_LONG) |
michael@0 | 844 | #define DUMP(n,a,d,e,h) printf(" t = %2d, %s = %016lx, %s = %016lx\n", \ |
michael@0 | 845 | n, #e, d, #a, h); |
michael@0 | 846 | #else |
michael@0 | 847 | #define DUMP(n,a,d,e,h) printf(" t = %2d, %s = %08x%08x, %s = %08x%08x\n", \ |
michael@0 | 848 | n, #e, d.hi, d.lo, #a, h.hi, h.lo); |
michael@0 | 849 | #endif |
michael@0 | 850 | #else |
michael@0 | 851 | #define DUMP(n,a,d,e,h) |
michael@0 | 852 | #endif |
michael@0 | 853 | |
michael@0 | 854 | #if defined(HAVE_LONG_LONG) |
michael@0 | 855 | |
michael@0 | 856 | #define ADDTO(x,y) y += x |
michael@0 | 857 | |
michael@0 | 858 | #define INITW(t) W[t] = (s1(W[t-2]) + W[t-7] + s0(W[t-15]) + W[t-16]) |
michael@0 | 859 | |
michael@0 | 860 | #define ROUND(n,a,b,c,d,e,f,g,h) \ |
michael@0 | 861 | h += S1(e) + Ch(e,f,g) + K512[n] + W[n]; \ |
michael@0 | 862 | d += h; \ |
michael@0 | 863 | h += S0(a) + Maj(a,b,c); \ |
michael@0 | 864 | DUMP(n,a,d,e,h) |
michael@0 | 865 | |
michael@0 | 866 | #else /* use only 32-bit variables, and don't unroll loops */ |
michael@0 | 867 | |
michael@0 | 868 | #undef NOUNROLL512 |
michael@0 | 869 | #define NOUNROLL512 1 |
michael@0 | 870 | |
michael@0 | 871 | #define ADDTO(x,y) y.lo += x.lo; y.hi += x.hi + (x.lo > y.lo) |
michael@0 | 872 | |
michael@0 | 873 | #define ROTR64a(x,n,lo,hi) (x.lo >> n | x.hi << (32-n)) |
michael@0 | 874 | #define ROTR64A(x,n,lo,hi) (x.lo << (64-n) | x.hi >> (n-32)) |
michael@0 | 875 | #define SHR64a(x,n,lo,hi) (x.lo >> n | x.hi << (32-n)) |
michael@0 | 876 | |
michael@0 | 877 | /* Capitol Sigma and lower case sigma functions */ |
michael@0 | 878 | #define s0lo(x) (ROTR64a(x,1,lo,hi) ^ ROTR64a(x,8,lo,hi) ^ SHR64a(x,7,lo,hi)) |
michael@0 | 879 | #define s0hi(x) (ROTR64a(x,1,hi,lo) ^ ROTR64a(x,8,hi,lo) ^ (x.hi >> 7)) |
michael@0 | 880 | |
michael@0 | 881 | #define s1lo(x) (ROTR64a(x,19,lo,hi) ^ ROTR64A(x,61,lo,hi) ^ SHR64a(x,6,lo,hi)) |
michael@0 | 882 | #define s1hi(x) (ROTR64a(x,19,hi,lo) ^ ROTR64A(x,61,hi,lo) ^ (x.hi >> 6)) |
michael@0 | 883 | |
michael@0 | 884 | #define S0lo(x)(ROTR64a(x,28,lo,hi) ^ ROTR64A(x,34,lo,hi) ^ ROTR64A(x,39,lo,hi)) |
michael@0 | 885 | #define S0hi(x)(ROTR64a(x,28,hi,lo) ^ ROTR64A(x,34,hi,lo) ^ ROTR64A(x,39,hi,lo)) |
michael@0 | 886 | |
michael@0 | 887 | #define S1lo(x)(ROTR64a(x,14,lo,hi) ^ ROTR64a(x,18,lo,hi) ^ ROTR64A(x,41,lo,hi)) |
michael@0 | 888 | #define S1hi(x)(ROTR64a(x,14,hi,lo) ^ ROTR64a(x,18,hi,lo) ^ ROTR64A(x,41,hi,lo)) |
michael@0 | 889 | |
michael@0 | 890 | /* 32-bit versions of Ch and Maj */ |
michael@0 | 891 | #define Chxx(x,y,z,lo) ((x.lo & y.lo) ^ (~x.lo & z.lo)) |
michael@0 | 892 | #define Majx(x,y,z,lo) ((x.lo & y.lo) ^ (x.lo & z.lo) ^ (y.lo & z.lo)) |
michael@0 | 893 | |
michael@0 | 894 | #define INITW(t) \ |
michael@0 | 895 | do { \ |
michael@0 | 896 | PRUint32 lo, tm; \ |
michael@0 | 897 | PRUint32 cy = 0; \ |
michael@0 | 898 | lo = s1lo(W[t-2]); \ |
michael@0 | 899 | lo += (tm = W[t-7].lo); if (lo < tm) cy++; \ |
michael@0 | 900 | lo += (tm = s0lo(W[t-15])); if (lo < tm) cy++; \ |
michael@0 | 901 | lo += (tm = W[t-16].lo); if (lo < tm) cy++; \ |
michael@0 | 902 | W[t].lo = lo; \ |
michael@0 | 903 | W[t].hi = cy + s1hi(W[t-2]) + W[t-7].hi + s0hi(W[t-15]) + W[t-16].hi; \ |
michael@0 | 904 | } while (0) |
michael@0 | 905 | |
michael@0 | 906 | #define ROUND(n,a,b,c,d,e,f,g,h) \ |
michael@0 | 907 | { \ |
michael@0 | 908 | PRUint32 lo, tm, cy; \ |
michael@0 | 909 | lo = S1lo(e); \ |
michael@0 | 910 | lo += (tm = Chxx(e,f,g,lo)); cy = (lo < tm); \ |
michael@0 | 911 | lo += (tm = K512[n].lo); if (lo < tm) cy++; \ |
michael@0 | 912 | lo += (tm = W[n].lo); if (lo < tm) cy++; \ |
michael@0 | 913 | h.lo += lo; if (h.lo < lo) cy++; \ |
michael@0 | 914 | h.hi += cy + S1hi(e) + Chxx(e,f,g,hi) + K512[n].hi + W[n].hi; \ |
michael@0 | 915 | d.lo += h.lo; \ |
michael@0 | 916 | d.hi += h.hi + (d.lo < h.lo); \ |
michael@0 | 917 | lo = S0lo(a); \ |
michael@0 | 918 | lo += (tm = Majx(a,b,c,lo)); cy = (lo < tm); \ |
michael@0 | 919 | h.lo += lo; if (h.lo < lo) cy++; \ |
michael@0 | 920 | h.hi += cy + S0hi(a) + Majx(a,b,c,hi); \ |
michael@0 | 921 | DUMP(n,a,d,e,h) \ |
michael@0 | 922 | } |
michael@0 | 923 | #endif |
michael@0 | 924 | |
michael@0 | 925 | static void |
michael@0 | 926 | SHA512_Compress(SHA512Context *ctx) |
michael@0 | 927 | { |
michael@0 | 928 | #if defined(IS_LITTLE_ENDIAN) |
michael@0 | 929 | { |
michael@0 | 930 | #if defined(HAVE_LONG_LONG) |
michael@0 | 931 | PRUint64 t1; |
michael@0 | 932 | #else |
michael@0 | 933 | PRUint32 t1; |
michael@0 | 934 | #endif |
michael@0 | 935 | BYTESWAP8(W[0]); |
michael@0 | 936 | BYTESWAP8(W[1]); |
michael@0 | 937 | BYTESWAP8(W[2]); |
michael@0 | 938 | BYTESWAP8(W[3]); |
michael@0 | 939 | BYTESWAP8(W[4]); |
michael@0 | 940 | BYTESWAP8(W[5]); |
michael@0 | 941 | BYTESWAP8(W[6]); |
michael@0 | 942 | BYTESWAP8(W[7]); |
michael@0 | 943 | BYTESWAP8(W[8]); |
michael@0 | 944 | BYTESWAP8(W[9]); |
michael@0 | 945 | BYTESWAP8(W[10]); |
michael@0 | 946 | BYTESWAP8(W[11]); |
michael@0 | 947 | BYTESWAP8(W[12]); |
michael@0 | 948 | BYTESWAP8(W[13]); |
michael@0 | 949 | BYTESWAP8(W[14]); |
michael@0 | 950 | BYTESWAP8(W[15]); |
michael@0 | 951 | } |
michael@0 | 952 | #endif |
michael@0 | 953 | |
michael@0 | 954 | { |
michael@0 | 955 | PRUint64 t1, t2; |
michael@0 | 956 | #ifdef NOUNROLL512 |
michael@0 | 957 | { |
michael@0 | 958 | /* prepare the "message schedule" */ |
michael@0 | 959 | int t; |
michael@0 | 960 | for (t = 16; t < 80; ++t) { |
michael@0 | 961 | INITW(t); |
michael@0 | 962 | } |
michael@0 | 963 | } |
michael@0 | 964 | #else |
michael@0 | 965 | INITW(16); |
michael@0 | 966 | INITW(17); |
michael@0 | 967 | INITW(18); |
michael@0 | 968 | INITW(19); |
michael@0 | 969 | |
michael@0 | 970 | INITW(20); |
michael@0 | 971 | INITW(21); |
michael@0 | 972 | INITW(22); |
michael@0 | 973 | INITW(23); |
michael@0 | 974 | INITW(24); |
michael@0 | 975 | INITW(25); |
michael@0 | 976 | INITW(26); |
michael@0 | 977 | INITW(27); |
michael@0 | 978 | INITW(28); |
michael@0 | 979 | INITW(29); |
michael@0 | 980 | |
michael@0 | 981 | INITW(30); |
michael@0 | 982 | INITW(31); |
michael@0 | 983 | INITW(32); |
michael@0 | 984 | INITW(33); |
michael@0 | 985 | INITW(34); |
michael@0 | 986 | INITW(35); |
michael@0 | 987 | INITW(36); |
michael@0 | 988 | INITW(37); |
michael@0 | 989 | INITW(38); |
michael@0 | 990 | INITW(39); |
michael@0 | 991 | |
michael@0 | 992 | INITW(40); |
michael@0 | 993 | INITW(41); |
michael@0 | 994 | INITW(42); |
michael@0 | 995 | INITW(43); |
michael@0 | 996 | INITW(44); |
michael@0 | 997 | INITW(45); |
michael@0 | 998 | INITW(46); |
michael@0 | 999 | INITW(47); |
michael@0 | 1000 | INITW(48); |
michael@0 | 1001 | INITW(49); |
michael@0 | 1002 | |
michael@0 | 1003 | INITW(50); |
michael@0 | 1004 | INITW(51); |
michael@0 | 1005 | INITW(52); |
michael@0 | 1006 | INITW(53); |
michael@0 | 1007 | INITW(54); |
michael@0 | 1008 | INITW(55); |
michael@0 | 1009 | INITW(56); |
michael@0 | 1010 | INITW(57); |
michael@0 | 1011 | INITW(58); |
michael@0 | 1012 | INITW(59); |
michael@0 | 1013 | |
michael@0 | 1014 | INITW(60); |
michael@0 | 1015 | INITW(61); |
michael@0 | 1016 | INITW(62); |
michael@0 | 1017 | INITW(63); |
michael@0 | 1018 | INITW(64); |
michael@0 | 1019 | INITW(65); |
michael@0 | 1020 | INITW(66); |
michael@0 | 1021 | INITW(67); |
michael@0 | 1022 | INITW(68); |
michael@0 | 1023 | INITW(69); |
michael@0 | 1024 | |
michael@0 | 1025 | INITW(70); |
michael@0 | 1026 | INITW(71); |
michael@0 | 1027 | INITW(72); |
michael@0 | 1028 | INITW(73); |
michael@0 | 1029 | INITW(74); |
michael@0 | 1030 | INITW(75); |
michael@0 | 1031 | INITW(76); |
michael@0 | 1032 | INITW(77); |
michael@0 | 1033 | INITW(78); |
michael@0 | 1034 | INITW(79); |
michael@0 | 1035 | #endif |
michael@0 | 1036 | } |
michael@0 | 1037 | #ifdef SHA512_TRACE |
michael@0 | 1038 | { |
michael@0 | 1039 | int i; |
michael@0 | 1040 | for (i = 0; i < 80; ++i) { |
michael@0 | 1041 | #ifdef HAVE_LONG_LONG |
michael@0 | 1042 | printf("W[%2d] = %016lx\n", i, W[i]); |
michael@0 | 1043 | #else |
michael@0 | 1044 | printf("W[%2d] = %08x%08x\n", i, W[i].hi, W[i].lo); |
michael@0 | 1045 | #endif |
michael@0 | 1046 | } |
michael@0 | 1047 | } |
michael@0 | 1048 | #endif |
michael@0 | 1049 | { |
michael@0 | 1050 | PRUint64 a, b, c, d, e, f, g, h; |
michael@0 | 1051 | |
michael@0 | 1052 | a = H[0]; |
michael@0 | 1053 | b = H[1]; |
michael@0 | 1054 | c = H[2]; |
michael@0 | 1055 | d = H[3]; |
michael@0 | 1056 | e = H[4]; |
michael@0 | 1057 | f = H[5]; |
michael@0 | 1058 | g = H[6]; |
michael@0 | 1059 | h = H[7]; |
michael@0 | 1060 | |
michael@0 | 1061 | #ifdef NOUNROLL512 |
michael@0 | 1062 | { |
michael@0 | 1063 | int t; |
michael@0 | 1064 | for (t = 0; t < 80; t+= 8) { |
michael@0 | 1065 | ROUND(t+0,a,b,c,d,e,f,g,h) |
michael@0 | 1066 | ROUND(t+1,h,a,b,c,d,e,f,g) |
michael@0 | 1067 | ROUND(t+2,g,h,a,b,c,d,e,f) |
michael@0 | 1068 | ROUND(t+3,f,g,h,a,b,c,d,e) |
michael@0 | 1069 | ROUND(t+4,e,f,g,h,a,b,c,d) |
michael@0 | 1070 | ROUND(t+5,d,e,f,g,h,a,b,c) |
michael@0 | 1071 | ROUND(t+6,c,d,e,f,g,h,a,b) |
michael@0 | 1072 | ROUND(t+7,b,c,d,e,f,g,h,a) |
michael@0 | 1073 | } |
michael@0 | 1074 | } |
michael@0 | 1075 | #else |
michael@0 | 1076 | ROUND( 0,a,b,c,d,e,f,g,h) |
michael@0 | 1077 | ROUND( 1,h,a,b,c,d,e,f,g) |
michael@0 | 1078 | ROUND( 2,g,h,a,b,c,d,e,f) |
michael@0 | 1079 | ROUND( 3,f,g,h,a,b,c,d,e) |
michael@0 | 1080 | ROUND( 4,e,f,g,h,a,b,c,d) |
michael@0 | 1081 | ROUND( 5,d,e,f,g,h,a,b,c) |
michael@0 | 1082 | ROUND( 6,c,d,e,f,g,h,a,b) |
michael@0 | 1083 | ROUND( 7,b,c,d,e,f,g,h,a) |
michael@0 | 1084 | |
michael@0 | 1085 | ROUND( 8,a,b,c,d,e,f,g,h) |
michael@0 | 1086 | ROUND( 9,h,a,b,c,d,e,f,g) |
michael@0 | 1087 | ROUND(10,g,h,a,b,c,d,e,f) |
michael@0 | 1088 | ROUND(11,f,g,h,a,b,c,d,e) |
michael@0 | 1089 | ROUND(12,e,f,g,h,a,b,c,d) |
michael@0 | 1090 | ROUND(13,d,e,f,g,h,a,b,c) |
michael@0 | 1091 | ROUND(14,c,d,e,f,g,h,a,b) |
michael@0 | 1092 | ROUND(15,b,c,d,e,f,g,h,a) |
michael@0 | 1093 | |
michael@0 | 1094 | ROUND(16,a,b,c,d,e,f,g,h) |
michael@0 | 1095 | ROUND(17,h,a,b,c,d,e,f,g) |
michael@0 | 1096 | ROUND(18,g,h,a,b,c,d,e,f) |
michael@0 | 1097 | ROUND(19,f,g,h,a,b,c,d,e) |
michael@0 | 1098 | ROUND(20,e,f,g,h,a,b,c,d) |
michael@0 | 1099 | ROUND(21,d,e,f,g,h,a,b,c) |
michael@0 | 1100 | ROUND(22,c,d,e,f,g,h,a,b) |
michael@0 | 1101 | ROUND(23,b,c,d,e,f,g,h,a) |
michael@0 | 1102 | |
michael@0 | 1103 | ROUND(24,a,b,c,d,e,f,g,h) |
michael@0 | 1104 | ROUND(25,h,a,b,c,d,e,f,g) |
michael@0 | 1105 | ROUND(26,g,h,a,b,c,d,e,f) |
michael@0 | 1106 | ROUND(27,f,g,h,a,b,c,d,e) |
michael@0 | 1107 | ROUND(28,e,f,g,h,a,b,c,d) |
michael@0 | 1108 | ROUND(29,d,e,f,g,h,a,b,c) |
michael@0 | 1109 | ROUND(30,c,d,e,f,g,h,a,b) |
michael@0 | 1110 | ROUND(31,b,c,d,e,f,g,h,a) |
michael@0 | 1111 | |
michael@0 | 1112 | ROUND(32,a,b,c,d,e,f,g,h) |
michael@0 | 1113 | ROUND(33,h,a,b,c,d,e,f,g) |
michael@0 | 1114 | ROUND(34,g,h,a,b,c,d,e,f) |
michael@0 | 1115 | ROUND(35,f,g,h,a,b,c,d,e) |
michael@0 | 1116 | ROUND(36,e,f,g,h,a,b,c,d) |
michael@0 | 1117 | ROUND(37,d,e,f,g,h,a,b,c) |
michael@0 | 1118 | ROUND(38,c,d,e,f,g,h,a,b) |
michael@0 | 1119 | ROUND(39,b,c,d,e,f,g,h,a) |
michael@0 | 1120 | |
michael@0 | 1121 | ROUND(40,a,b,c,d,e,f,g,h) |
michael@0 | 1122 | ROUND(41,h,a,b,c,d,e,f,g) |
michael@0 | 1123 | ROUND(42,g,h,a,b,c,d,e,f) |
michael@0 | 1124 | ROUND(43,f,g,h,a,b,c,d,e) |
michael@0 | 1125 | ROUND(44,e,f,g,h,a,b,c,d) |
michael@0 | 1126 | ROUND(45,d,e,f,g,h,a,b,c) |
michael@0 | 1127 | ROUND(46,c,d,e,f,g,h,a,b) |
michael@0 | 1128 | ROUND(47,b,c,d,e,f,g,h,a) |
michael@0 | 1129 | |
michael@0 | 1130 | ROUND(48,a,b,c,d,e,f,g,h) |
michael@0 | 1131 | ROUND(49,h,a,b,c,d,e,f,g) |
michael@0 | 1132 | ROUND(50,g,h,a,b,c,d,e,f) |
michael@0 | 1133 | ROUND(51,f,g,h,a,b,c,d,e) |
michael@0 | 1134 | ROUND(52,e,f,g,h,a,b,c,d) |
michael@0 | 1135 | ROUND(53,d,e,f,g,h,a,b,c) |
michael@0 | 1136 | ROUND(54,c,d,e,f,g,h,a,b) |
michael@0 | 1137 | ROUND(55,b,c,d,e,f,g,h,a) |
michael@0 | 1138 | |
michael@0 | 1139 | ROUND(56,a,b,c,d,e,f,g,h) |
michael@0 | 1140 | ROUND(57,h,a,b,c,d,e,f,g) |
michael@0 | 1141 | ROUND(58,g,h,a,b,c,d,e,f) |
michael@0 | 1142 | ROUND(59,f,g,h,a,b,c,d,e) |
michael@0 | 1143 | ROUND(60,e,f,g,h,a,b,c,d) |
michael@0 | 1144 | ROUND(61,d,e,f,g,h,a,b,c) |
michael@0 | 1145 | ROUND(62,c,d,e,f,g,h,a,b) |
michael@0 | 1146 | ROUND(63,b,c,d,e,f,g,h,a) |
michael@0 | 1147 | |
michael@0 | 1148 | ROUND(64,a,b,c,d,e,f,g,h) |
michael@0 | 1149 | ROUND(65,h,a,b,c,d,e,f,g) |
michael@0 | 1150 | ROUND(66,g,h,a,b,c,d,e,f) |
michael@0 | 1151 | ROUND(67,f,g,h,a,b,c,d,e) |
michael@0 | 1152 | ROUND(68,e,f,g,h,a,b,c,d) |
michael@0 | 1153 | ROUND(69,d,e,f,g,h,a,b,c) |
michael@0 | 1154 | ROUND(70,c,d,e,f,g,h,a,b) |
michael@0 | 1155 | ROUND(71,b,c,d,e,f,g,h,a) |
michael@0 | 1156 | |
michael@0 | 1157 | ROUND(72,a,b,c,d,e,f,g,h) |
michael@0 | 1158 | ROUND(73,h,a,b,c,d,e,f,g) |
michael@0 | 1159 | ROUND(74,g,h,a,b,c,d,e,f) |
michael@0 | 1160 | ROUND(75,f,g,h,a,b,c,d,e) |
michael@0 | 1161 | ROUND(76,e,f,g,h,a,b,c,d) |
michael@0 | 1162 | ROUND(77,d,e,f,g,h,a,b,c) |
michael@0 | 1163 | ROUND(78,c,d,e,f,g,h,a,b) |
michael@0 | 1164 | ROUND(79,b,c,d,e,f,g,h,a) |
michael@0 | 1165 | #endif |
michael@0 | 1166 | |
michael@0 | 1167 | ADDTO(a,H[0]); |
michael@0 | 1168 | ADDTO(b,H[1]); |
michael@0 | 1169 | ADDTO(c,H[2]); |
michael@0 | 1170 | ADDTO(d,H[3]); |
michael@0 | 1171 | ADDTO(e,H[4]); |
michael@0 | 1172 | ADDTO(f,H[5]); |
michael@0 | 1173 | ADDTO(g,H[6]); |
michael@0 | 1174 | ADDTO(h,H[7]); |
michael@0 | 1175 | } |
michael@0 | 1176 | } |
michael@0 | 1177 | |
michael@0 | 1178 | void |
michael@0 | 1179 | SHA512_Update(SHA512Context *ctx, const unsigned char *input, |
michael@0 | 1180 | unsigned int inputLen) |
michael@0 | 1181 | { |
michael@0 | 1182 | unsigned int inBuf; |
michael@0 | 1183 | if (!inputLen) |
michael@0 | 1184 | return; |
michael@0 | 1185 | |
michael@0 | 1186 | #if defined(HAVE_LONG_LONG) |
michael@0 | 1187 | inBuf = (unsigned int)ctx->sizeLo & 0x7f; |
michael@0 | 1188 | /* Add inputLen into the count of bytes processed, before processing */ |
michael@0 | 1189 | ctx->sizeLo += inputLen; |
michael@0 | 1190 | #else |
michael@0 | 1191 | inBuf = (unsigned int)ctx->sizeLo.lo & 0x7f; |
michael@0 | 1192 | ctx->sizeLo.lo += inputLen; |
michael@0 | 1193 | if (ctx->sizeLo.lo < inputLen) ctx->sizeLo.hi++; |
michael@0 | 1194 | #endif |
michael@0 | 1195 | |
michael@0 | 1196 | /* if data already in buffer, attemp to fill rest of buffer */ |
michael@0 | 1197 | if (inBuf) { |
michael@0 | 1198 | unsigned int todo = SHA512_BLOCK_LENGTH - inBuf; |
michael@0 | 1199 | if (inputLen < todo) |
michael@0 | 1200 | todo = inputLen; |
michael@0 | 1201 | memcpy(B + inBuf, input, todo); |
michael@0 | 1202 | input += todo; |
michael@0 | 1203 | inputLen -= todo; |
michael@0 | 1204 | if (inBuf + todo == SHA512_BLOCK_LENGTH) |
michael@0 | 1205 | SHA512_Compress(ctx); |
michael@0 | 1206 | } |
michael@0 | 1207 | |
michael@0 | 1208 | /* if enough data to fill one or more whole buffers, process them. */ |
michael@0 | 1209 | while (inputLen >= SHA512_BLOCK_LENGTH) { |
michael@0 | 1210 | memcpy(B, input, SHA512_BLOCK_LENGTH); |
michael@0 | 1211 | input += SHA512_BLOCK_LENGTH; |
michael@0 | 1212 | inputLen -= SHA512_BLOCK_LENGTH; |
michael@0 | 1213 | SHA512_Compress(ctx); |
michael@0 | 1214 | } |
michael@0 | 1215 | /* if data left over, fill it into buffer */ |
michael@0 | 1216 | if (inputLen) |
michael@0 | 1217 | memcpy(B, input, inputLen); |
michael@0 | 1218 | } |
michael@0 | 1219 | |
michael@0 | 1220 | void |
michael@0 | 1221 | SHA512_End(SHA512Context *ctx, unsigned char *digest, |
michael@0 | 1222 | unsigned int *digestLen, unsigned int maxDigestLen) |
michael@0 | 1223 | { |
michael@0 | 1224 | #if defined(HAVE_LONG_LONG) |
michael@0 | 1225 | unsigned int inBuf = (unsigned int)ctx->sizeLo & 0x7f; |
michael@0 | 1226 | PRUint64 t1; |
michael@0 | 1227 | #else |
michael@0 | 1228 | unsigned int inBuf = (unsigned int)ctx->sizeLo.lo & 0x7f; |
michael@0 | 1229 | PRUint32 t1; |
michael@0 | 1230 | #endif |
michael@0 | 1231 | unsigned int padLen = (inBuf < 112) ? (112 - inBuf) : (112 + 128 - inBuf); |
michael@0 | 1232 | PRUint64 lo; |
michael@0 | 1233 | LL_SHL(lo, ctx->sizeLo, 3); |
michael@0 | 1234 | |
michael@0 | 1235 | SHA512_Update(ctx, pad, padLen); |
michael@0 | 1236 | |
michael@0 | 1237 | #if defined(HAVE_LONG_LONG) |
michael@0 | 1238 | W[14] = 0; |
michael@0 | 1239 | #else |
michael@0 | 1240 | W[14].lo = 0; |
michael@0 | 1241 | W[14].hi = 0; |
michael@0 | 1242 | #endif |
michael@0 | 1243 | |
michael@0 | 1244 | W[15] = lo; |
michael@0 | 1245 | #if defined(IS_LITTLE_ENDIAN) |
michael@0 | 1246 | BYTESWAP8(W[15]); |
michael@0 | 1247 | #endif |
michael@0 | 1248 | SHA512_Compress(ctx); |
michael@0 | 1249 | |
michael@0 | 1250 | /* now output the answer */ |
michael@0 | 1251 | #if defined(IS_LITTLE_ENDIAN) |
michael@0 | 1252 | BYTESWAP8(H[0]); |
michael@0 | 1253 | BYTESWAP8(H[1]); |
michael@0 | 1254 | BYTESWAP8(H[2]); |
michael@0 | 1255 | BYTESWAP8(H[3]); |
michael@0 | 1256 | BYTESWAP8(H[4]); |
michael@0 | 1257 | BYTESWAP8(H[5]); |
michael@0 | 1258 | BYTESWAP8(H[6]); |
michael@0 | 1259 | BYTESWAP8(H[7]); |
michael@0 | 1260 | #endif |
michael@0 | 1261 | padLen = PR_MIN(SHA512_LENGTH, maxDigestLen); |
michael@0 | 1262 | memcpy(digest, H, padLen); |
michael@0 | 1263 | if (digestLen) |
michael@0 | 1264 | *digestLen = padLen; |
michael@0 | 1265 | } |
michael@0 | 1266 | |
michael@0 | 1267 | void |
michael@0 | 1268 | SHA512_EndRaw(SHA512Context *ctx, unsigned char *digest, |
michael@0 | 1269 | unsigned int *digestLen, unsigned int maxDigestLen) |
michael@0 | 1270 | { |
michael@0 | 1271 | #if defined(HAVE_LONG_LONG) |
michael@0 | 1272 | PRUint64 t1; |
michael@0 | 1273 | #else |
michael@0 | 1274 | PRUint32 t1; |
michael@0 | 1275 | #endif |
michael@0 | 1276 | PRUint64 h[8]; |
michael@0 | 1277 | unsigned int len; |
michael@0 | 1278 | |
michael@0 | 1279 | memcpy(h, ctx->h, sizeof(h)); |
michael@0 | 1280 | |
michael@0 | 1281 | #if defined(IS_LITTLE_ENDIAN) |
michael@0 | 1282 | BYTESWAP8(h[0]); |
michael@0 | 1283 | BYTESWAP8(h[1]); |
michael@0 | 1284 | BYTESWAP8(h[2]); |
michael@0 | 1285 | BYTESWAP8(h[3]); |
michael@0 | 1286 | BYTESWAP8(h[4]); |
michael@0 | 1287 | BYTESWAP8(h[5]); |
michael@0 | 1288 | BYTESWAP8(h[6]); |
michael@0 | 1289 | BYTESWAP8(h[7]); |
michael@0 | 1290 | #endif |
michael@0 | 1291 | len = PR_MIN(SHA512_LENGTH, maxDigestLen); |
michael@0 | 1292 | memcpy(digest, h, len); |
michael@0 | 1293 | if (digestLen) |
michael@0 | 1294 | *digestLen = len; |
michael@0 | 1295 | } |
michael@0 | 1296 | |
michael@0 | 1297 | SECStatus |
michael@0 | 1298 | SHA512_HashBuf(unsigned char *dest, const unsigned char *src, |
michael@0 | 1299 | PRUint32 src_length) |
michael@0 | 1300 | { |
michael@0 | 1301 | SHA512Context ctx; |
michael@0 | 1302 | unsigned int outLen; |
michael@0 | 1303 | |
michael@0 | 1304 | SHA512_Begin(&ctx); |
michael@0 | 1305 | SHA512_Update(&ctx, src, src_length); |
michael@0 | 1306 | SHA512_End(&ctx, dest, &outLen, SHA512_LENGTH); |
michael@0 | 1307 | memset(&ctx, 0, sizeof ctx); |
michael@0 | 1308 | |
michael@0 | 1309 | return SECSuccess; |
michael@0 | 1310 | } |
michael@0 | 1311 | |
michael@0 | 1312 | |
michael@0 | 1313 | SECStatus |
michael@0 | 1314 | SHA512_Hash(unsigned char *dest, const char *src) |
michael@0 | 1315 | { |
michael@0 | 1316 | return SHA512_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src)); |
michael@0 | 1317 | } |
michael@0 | 1318 | |
michael@0 | 1319 | |
michael@0 | 1320 | void SHA512_TraceState(SHA512Context *ctx) { } |
michael@0 | 1321 | |
michael@0 | 1322 | unsigned int |
michael@0 | 1323 | SHA512_FlattenSize(SHA512Context *ctx) |
michael@0 | 1324 | { |
michael@0 | 1325 | return sizeof *ctx; |
michael@0 | 1326 | } |
michael@0 | 1327 | |
michael@0 | 1328 | SECStatus |
michael@0 | 1329 | SHA512_Flatten(SHA512Context *ctx,unsigned char *space) |
michael@0 | 1330 | { |
michael@0 | 1331 | PORT_Memcpy(space, ctx, sizeof *ctx); |
michael@0 | 1332 | return SECSuccess; |
michael@0 | 1333 | } |
michael@0 | 1334 | |
michael@0 | 1335 | SHA512Context * |
michael@0 | 1336 | SHA512_Resurrect(unsigned char *space, void *arg) |
michael@0 | 1337 | { |
michael@0 | 1338 | SHA512Context *ctx = SHA512_NewContext(); |
michael@0 | 1339 | if (ctx) |
michael@0 | 1340 | PORT_Memcpy(ctx, space, sizeof *ctx); |
michael@0 | 1341 | return ctx; |
michael@0 | 1342 | } |
michael@0 | 1343 | |
michael@0 | 1344 | void SHA512_Clone(SHA512Context *dest, SHA512Context *src) |
michael@0 | 1345 | { |
michael@0 | 1346 | memcpy(dest, src, sizeof *dest); |
michael@0 | 1347 | } |
michael@0 | 1348 | |
michael@0 | 1349 | /* ======================================================================= */ |
michael@0 | 1350 | /* SHA384 uses a SHA512Context as the real context. |
michael@0 | 1351 | ** The only differences between SHA384 an SHA512 are: |
michael@0 | 1352 | ** a) the intialization values for the context, and |
michael@0 | 1353 | ** b) the number of bytes of data produced as output. |
michael@0 | 1354 | */ |
michael@0 | 1355 | |
michael@0 | 1356 | /* SHA-384 initial hash values */ |
michael@0 | 1357 | static const PRUint64 H384[8] = { |
michael@0 | 1358 | #if PR_BYTES_PER_LONG == 8 |
michael@0 | 1359 | 0xcbbb9d5dc1059ed8UL , 0x629a292a367cd507UL , |
michael@0 | 1360 | 0x9159015a3070dd17UL , 0x152fecd8f70e5939UL , |
michael@0 | 1361 | 0x67332667ffc00b31UL , 0x8eb44a8768581511UL , |
michael@0 | 1362 | 0xdb0c2e0d64f98fa7UL , 0x47b5481dbefa4fa4UL |
michael@0 | 1363 | #else |
michael@0 | 1364 | ULLC(cbbb9d5d,c1059ed8), ULLC(629a292a,367cd507), |
michael@0 | 1365 | ULLC(9159015a,3070dd17), ULLC(152fecd8,f70e5939), |
michael@0 | 1366 | ULLC(67332667,ffc00b31), ULLC(8eb44a87,68581511), |
michael@0 | 1367 | ULLC(db0c2e0d,64f98fa7), ULLC(47b5481d,befa4fa4) |
michael@0 | 1368 | #endif |
michael@0 | 1369 | }; |
michael@0 | 1370 | |
michael@0 | 1371 | SHA384Context * |
michael@0 | 1372 | SHA384_NewContext(void) |
michael@0 | 1373 | { |
michael@0 | 1374 | return SHA512_NewContext(); |
michael@0 | 1375 | } |
michael@0 | 1376 | |
michael@0 | 1377 | void |
michael@0 | 1378 | SHA384_DestroyContext(SHA384Context *ctx, PRBool freeit) |
michael@0 | 1379 | { |
michael@0 | 1380 | SHA512_DestroyContext(ctx, freeit); |
michael@0 | 1381 | } |
michael@0 | 1382 | |
michael@0 | 1383 | void |
michael@0 | 1384 | SHA384_Begin(SHA384Context *ctx) |
michael@0 | 1385 | { |
michael@0 | 1386 | memset(ctx, 0, sizeof *ctx); |
michael@0 | 1387 | memcpy(H, H384, sizeof H384); |
michael@0 | 1388 | } |
michael@0 | 1389 | |
michael@0 | 1390 | void |
michael@0 | 1391 | SHA384_Update(SHA384Context *ctx, const unsigned char *input, |
michael@0 | 1392 | unsigned int inputLen) |
michael@0 | 1393 | { |
michael@0 | 1394 | SHA512_Update(ctx, input, inputLen); |
michael@0 | 1395 | } |
michael@0 | 1396 | |
michael@0 | 1397 | void |
michael@0 | 1398 | SHA384_End(SHA384Context *ctx, unsigned char *digest, |
michael@0 | 1399 | unsigned int *digestLen, unsigned int maxDigestLen) |
michael@0 | 1400 | { |
michael@0 | 1401 | unsigned int maxLen = SHA_MIN(maxDigestLen, SHA384_LENGTH); |
michael@0 | 1402 | SHA512_End(ctx, digest, digestLen, maxLen); |
michael@0 | 1403 | } |
michael@0 | 1404 | |
michael@0 | 1405 | void |
michael@0 | 1406 | SHA384_EndRaw(SHA384Context *ctx, unsigned char *digest, |
michael@0 | 1407 | unsigned int *digestLen, unsigned int maxDigestLen) |
michael@0 | 1408 | { |
michael@0 | 1409 | unsigned int maxLen = SHA_MIN(maxDigestLen, SHA384_LENGTH); |
michael@0 | 1410 | SHA512_EndRaw(ctx, digest, digestLen, maxLen); |
michael@0 | 1411 | } |
michael@0 | 1412 | |
michael@0 | 1413 | SECStatus |
michael@0 | 1414 | SHA384_HashBuf(unsigned char *dest, const unsigned char *src, |
michael@0 | 1415 | PRUint32 src_length) |
michael@0 | 1416 | { |
michael@0 | 1417 | SHA512Context ctx; |
michael@0 | 1418 | unsigned int outLen; |
michael@0 | 1419 | |
michael@0 | 1420 | SHA384_Begin(&ctx); |
michael@0 | 1421 | SHA512_Update(&ctx, src, src_length); |
michael@0 | 1422 | SHA512_End(&ctx, dest, &outLen, SHA384_LENGTH); |
michael@0 | 1423 | memset(&ctx, 0, sizeof ctx); |
michael@0 | 1424 | |
michael@0 | 1425 | return SECSuccess; |
michael@0 | 1426 | } |
michael@0 | 1427 | |
michael@0 | 1428 | SECStatus |
michael@0 | 1429 | SHA384_Hash(unsigned char *dest, const char *src) |
michael@0 | 1430 | { |
michael@0 | 1431 | return SHA384_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src)); |
michael@0 | 1432 | } |
michael@0 | 1433 | |
michael@0 | 1434 | void SHA384_TraceState(SHA384Context *ctx) { } |
michael@0 | 1435 | |
michael@0 | 1436 | unsigned int |
michael@0 | 1437 | SHA384_FlattenSize(SHA384Context *ctx) |
michael@0 | 1438 | { |
michael@0 | 1439 | return sizeof(SHA384Context); |
michael@0 | 1440 | } |
michael@0 | 1441 | |
michael@0 | 1442 | SECStatus |
michael@0 | 1443 | SHA384_Flatten(SHA384Context *ctx,unsigned char *space) |
michael@0 | 1444 | { |
michael@0 | 1445 | return SHA512_Flatten(ctx, space); |
michael@0 | 1446 | } |
michael@0 | 1447 | |
michael@0 | 1448 | SHA384Context * |
michael@0 | 1449 | SHA384_Resurrect(unsigned char *space, void *arg) |
michael@0 | 1450 | { |
michael@0 | 1451 | return SHA512_Resurrect(space, arg); |
michael@0 | 1452 | } |
michael@0 | 1453 | |
michael@0 | 1454 | void SHA384_Clone(SHA384Context *dest, SHA384Context *src) |
michael@0 | 1455 | { |
michael@0 | 1456 | memcpy(dest, src, sizeof *dest); |
michael@0 | 1457 | } |
michael@0 | 1458 | |
michael@0 | 1459 | /* ======================================================================= */ |
michael@0 | 1460 | #ifdef SELFTEST |
michael@0 | 1461 | #include <stdio.h> |
michael@0 | 1462 | |
michael@0 | 1463 | static const char abc[] = { "abc" }; |
michael@0 | 1464 | static const char abcdbc[] = { |
michael@0 | 1465 | "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" |
michael@0 | 1466 | }; |
michael@0 | 1467 | static const char abcdef[] = { |
michael@0 | 1468 | "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" |
michael@0 | 1469 | "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" |
michael@0 | 1470 | }; |
michael@0 | 1471 | |
michael@0 | 1472 | void |
michael@0 | 1473 | dumpHash32(const unsigned char *buf, unsigned int bufLen) |
michael@0 | 1474 | { |
michael@0 | 1475 | unsigned int i; |
michael@0 | 1476 | for (i = 0; i < bufLen; i += 4) { |
michael@0 | 1477 | printf(" %02x%02x%02x%02x", buf[i], buf[i+1], buf[i+2], buf[i+3]); |
michael@0 | 1478 | } |
michael@0 | 1479 | printf("\n"); |
michael@0 | 1480 | } |
michael@0 | 1481 | |
michael@0 | 1482 | void test256(void) |
michael@0 | 1483 | { |
michael@0 | 1484 | unsigned char outBuf[SHA256_LENGTH]; |
michael@0 | 1485 | |
michael@0 | 1486 | printf("SHA256, input = %s\n", abc); |
michael@0 | 1487 | SHA256_Hash(outBuf, abc); |
michael@0 | 1488 | dumpHash32(outBuf, sizeof outBuf); |
michael@0 | 1489 | |
michael@0 | 1490 | printf("SHA256, input = %s\n", abcdbc); |
michael@0 | 1491 | SHA256_Hash(outBuf, abcdbc); |
michael@0 | 1492 | dumpHash32(outBuf, sizeof outBuf); |
michael@0 | 1493 | } |
michael@0 | 1494 | |
michael@0 | 1495 | void test224(void) |
michael@0 | 1496 | { |
michael@0 | 1497 | SHA224Context ctx; |
michael@0 | 1498 | unsigned char a1000times[1000]; |
michael@0 | 1499 | unsigned int outLen; |
michael@0 | 1500 | unsigned char outBuf[SHA224_LENGTH]; |
michael@0 | 1501 | int i; |
michael@0 | 1502 | |
michael@0 | 1503 | /* Test Vector 1 */ |
michael@0 | 1504 | printf("SHA224, input = %s\n", abc); |
michael@0 | 1505 | SHA224_Hash(outBuf, abc); |
michael@0 | 1506 | dumpHash32(outBuf, sizeof outBuf); |
michael@0 | 1507 | |
michael@0 | 1508 | /* Test Vector 2 */ |
michael@0 | 1509 | printf("SHA224, input = %s\n", abcdbc); |
michael@0 | 1510 | SHA224_Hash(outBuf, abcdbc); |
michael@0 | 1511 | dumpHash32(outBuf, sizeof outBuf); |
michael@0 | 1512 | |
michael@0 | 1513 | /* Test Vector 3 */ |
michael@0 | 1514 | |
michael@0 | 1515 | /* to hash one million 'a's perform 1000 |
michael@0 | 1516 | * sha224 updates on a buffer with 1000 'a's |
michael@0 | 1517 | */ |
michael@0 | 1518 | memset(a1000times, 'a', 1000); |
michael@0 | 1519 | printf("SHA224, input = %s\n", "a one million times"); |
michael@0 | 1520 | SHA224_Begin(&ctx); |
michael@0 | 1521 | for (i = 0; i < 1000; i++) |
michael@0 | 1522 | SHA224_Update(&ctx, a1000times, 1000); |
michael@0 | 1523 | SHA224_End(&ctx, outBuf, &outLen, SHA224_LENGTH); |
michael@0 | 1524 | dumpHash32(outBuf, sizeof outBuf); |
michael@0 | 1525 | } |
michael@0 | 1526 | |
michael@0 | 1527 | void |
michael@0 | 1528 | dumpHash64(const unsigned char *buf, unsigned int bufLen) |
michael@0 | 1529 | { |
michael@0 | 1530 | unsigned int i; |
michael@0 | 1531 | for (i = 0; i < bufLen; i += 8) { |
michael@0 | 1532 | if (i % 32 == 0) |
michael@0 | 1533 | printf("\n"); |
michael@0 | 1534 | printf(" %02x%02x%02x%02x%02x%02x%02x%02x", |
michael@0 | 1535 | buf[i ], buf[i+1], buf[i+2], buf[i+3], |
michael@0 | 1536 | buf[i+4], buf[i+5], buf[i+6], buf[i+7]); |
michael@0 | 1537 | } |
michael@0 | 1538 | printf("\n"); |
michael@0 | 1539 | } |
michael@0 | 1540 | |
michael@0 | 1541 | void test512(void) |
michael@0 | 1542 | { |
michael@0 | 1543 | unsigned char outBuf[SHA512_LENGTH]; |
michael@0 | 1544 | |
michael@0 | 1545 | printf("SHA512, input = %s\n", abc); |
michael@0 | 1546 | SHA512_Hash(outBuf, abc); |
michael@0 | 1547 | dumpHash64(outBuf, sizeof outBuf); |
michael@0 | 1548 | |
michael@0 | 1549 | printf("SHA512, input = %s\n", abcdef); |
michael@0 | 1550 | SHA512_Hash(outBuf, abcdef); |
michael@0 | 1551 | dumpHash64(outBuf, sizeof outBuf); |
michael@0 | 1552 | } |
michael@0 | 1553 | |
michael@0 | 1554 | void time512(void) |
michael@0 | 1555 | { |
michael@0 | 1556 | unsigned char outBuf[SHA512_LENGTH]; |
michael@0 | 1557 | |
michael@0 | 1558 | SHA512_Hash(outBuf, abc); |
michael@0 | 1559 | SHA512_Hash(outBuf, abcdef); |
michael@0 | 1560 | } |
michael@0 | 1561 | |
michael@0 | 1562 | void test384(void) |
michael@0 | 1563 | { |
michael@0 | 1564 | unsigned char outBuf[SHA384_LENGTH]; |
michael@0 | 1565 | |
michael@0 | 1566 | printf("SHA384, input = %s\n", abc); |
michael@0 | 1567 | SHA384_Hash(outBuf, abc); |
michael@0 | 1568 | dumpHash64(outBuf, sizeof outBuf); |
michael@0 | 1569 | |
michael@0 | 1570 | printf("SHA384, input = %s\n", abcdef); |
michael@0 | 1571 | SHA384_Hash(outBuf, abcdef); |
michael@0 | 1572 | dumpHash64(outBuf, sizeof outBuf); |
michael@0 | 1573 | } |
michael@0 | 1574 | |
michael@0 | 1575 | int main (int argc, char *argv[], char *envp[]) |
michael@0 | 1576 | { |
michael@0 | 1577 | int i = 1; |
michael@0 | 1578 | if (argc > 1) { |
michael@0 | 1579 | i = atoi(argv[1]); |
michael@0 | 1580 | } |
michael@0 | 1581 | if (i < 2) { |
michael@0 | 1582 | test224(); |
michael@0 | 1583 | test256(); |
michael@0 | 1584 | test384(); |
michael@0 | 1585 | test512(); |
michael@0 | 1586 | } else { |
michael@0 | 1587 | while (i-- > 0) { |
michael@0 | 1588 | time512(); |
michael@0 | 1589 | } |
michael@0 | 1590 | printf("done\n"); |
michael@0 | 1591 | } |
michael@0 | 1592 | return 0; |
michael@0 | 1593 | } |
michael@0 | 1594 | |
michael@0 | 1595 | void *PORT_Alloc(size_t len) { return malloc(len); } |
michael@0 | 1596 | void PORT_Free(void *ptr) { free(ptr); } |
michael@0 | 1597 | void PORT_ZFree(void *ptr, size_t len) { memset(ptr, 0, len); free(ptr); } |
michael@0 | 1598 | #endif |