sha_fast.h (5154B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifndef _SHA_FAST_H_ 6 #define _SHA_FAST_H_ 7 8 #include "prlong.h" 9 #include "blapii.h" 10 11 #define SHA1_INPUT_LEN 64 12 13 #if defined(IS_64) && !defined(__sparc) && !defined(__aarch64__) 14 typedef PRUint64 SHA_HW_t; 15 #define SHA1_USING_64_BIT 1 16 #else 17 typedef PRUint32 SHA_HW_t; 18 #endif 19 20 struct SHA1ContextStr; 21 22 typedef void (*sha1_compress_t)(struct SHA1ContextStr *); 23 typedef void (*sha1_update_t)(struct SHA1ContextStr *, const unsigned char *, 24 unsigned int); 25 26 struct SHA1ContextStr { 27 union { 28 PRUint32 w[16]; /* input buffer */ 29 PRUint8 b[64]; 30 } u; 31 PRUint64 size; /* count of hashed bytes. */ 32 SHA_HW_t H[22]; /* 5 state variables, 16 tmp values, 1 extra */ 33 sha1_compress_t compress; 34 sha1_update_t update; 35 }; 36 37 #if defined(_MSC_VER) 38 #include <stdlib.h> 39 #if defined(IS_LITTLE_ENDIAN) 40 #if (_MSC_VER >= 1300) 41 #pragma intrinsic(_byteswap_ulong) 42 #define SHA_HTONL(x) _byteswap_ulong(x) 43 #elif defined(NSS_X86_OR_X64) 44 #ifndef FORCEINLINE 45 #if (_MSC_VER >= 1200) 46 #define FORCEINLINE __forceinline 47 #else 48 #define FORCEINLINE __inline 49 #endif /* _MSC_VER */ 50 #endif /* !defined FORCEINLINE */ 51 #define FASTCALL __fastcall 52 53 static FORCEINLINE PRUint32 FASTCALL 54 swap4b(PRUint32 dwd) 55 { 56 __asm { 57 mov eax,dwd 58 bswap eax 59 } 60 } 61 62 #define SHA_HTONL(x) swap4b(x) 63 #endif /* NSS_X86_OR_X64 */ 64 #endif /* IS_LITTLE_ENDIAN */ 65 66 #pragma intrinsic(_lrotr, _lrotl) 67 #define SHA_ROTL(x, n) _lrotl(x, n) 68 #define SHA_ROTL_IS_DEFINED 1 69 #endif /* _MSC_VER */ 70 71 #if defined(__GNUC__) 72 /* __x86_64__ and __x86_64 are defined by GCC on x86_64 CPUs */ 73 #if defined(SHA1_USING_64_BIT) 74 static __inline__ PRUint64 75 SHA_ROTL(PRUint64 x, PRUint32 n) 76 { 77 PRUint32 t = (PRUint32)x; 78 return ((t << n) | (t >> (32 - n))); 79 } 80 #else 81 static __inline__ PRUint32 82 SHA_ROTL(PRUint32 t, PRUint32 n) 83 { 84 return ((t << n) | (t >> (32 - n))); 85 } 86 #endif 87 #define SHA_ROTL_IS_DEFINED 1 88 89 #if defined(NSS_X86_OR_X64) 90 static __inline__ PRUint32 91 swap4b(PRUint32 value) 92 { 93 __asm__("bswap %0" 94 : "+r"(value)); 95 return (value); 96 } 97 #define SHA_HTONL(x) swap4b(x) 98 99 #elif defined(__thumb2__) || \ 100 (!defined(__thumb__) && \ 101 (defined(__ARM_ARCH_6__) || \ 102 defined(__ARM_ARCH_6J__) || \ 103 defined(__ARM_ARCH_6K__) || \ 104 defined(__ARM_ARCH_6Z__) || \ 105 defined(__ARM_ARCH_6ZK__) || \ 106 defined(__ARM_ARCH_6T2__) || \ 107 defined(__ARM_ARCH_7__) || \ 108 defined(__ARM_ARCH_7A__) || \ 109 defined(__ARM_ARCH_7R__))) 110 #if defined(IS_LITTLE_ENDIAN) 111 static __inline__ PRUint32 112 swap4b(PRUint32 value) 113 { 114 PRUint32 ret; 115 __asm__("rev %0, %1" 116 : "=r"(ret) 117 : "r"(value)); 118 return ret; 119 } 120 #define SHA_HTONL(x) swap4b(x) 121 #endif 122 123 #endif /* x86 family */ 124 125 #endif /* __GNUC__ */ 126 127 #if !defined(SHA_ROTL_IS_DEFINED) 128 #define SHA_NEED_TMP_VARIABLE 1 129 #define SHA_ROTL(X, n) (tmp = (X), ((tmp) << (n)) | ((tmp) >> (32 - (n)))) 130 #endif 131 132 #if !defined(SHA_HTONL) 133 #define SHA_MASK 0x00FF00FF 134 #if defined(IS_LITTLE_ENDIAN) 135 #undef SHA_NEED_TMP_VARIABLE 136 #define SHA_NEED_TMP_VARIABLE 1 137 #define SHA_HTONL(x) (tmp = (x), tmp = (tmp << 16) | (tmp >> 16), \ 138 ((tmp & SHA_MASK) << 8) | ((tmp >> 8) & SHA_MASK)) 139 #else 140 #define SHA_HTONL(x) (x) 141 #endif 142 #endif 143 144 #define SHA_BYTESWAP(x) x = SHA_HTONL(x) 145 146 #define SHA_STORE(n) ((PRUint32 *)hashout)[n] = SHA_HTONL(ctx->H[n]) 147 #if defined(HAVE_UNALIGNED_ACCESS) 148 #define SHA_STORE_RESULT \ 149 SHA_STORE(0); \ 150 SHA_STORE(1); \ 151 SHA_STORE(2); \ 152 SHA_STORE(3); \ 153 SHA_STORE(4); 154 155 #elif defined(IS_LITTLE_ENDIAN) || defined(SHA1_USING_64_BIT) 156 #define SHA_STORE_RESULT \ 157 if (!((ptrdiff_t)hashout % sizeof(PRUint32))) { \ 158 SHA_STORE(0); \ 159 SHA_STORE(1); \ 160 SHA_STORE(2); \ 161 SHA_STORE(3); \ 162 SHA_STORE(4); \ 163 } else { \ 164 PRUint32 tmpbuf[5]; \ 165 tmpbuf[0] = SHA_HTONL(ctx->H[0]); \ 166 tmpbuf[1] = SHA_HTONL(ctx->H[1]); \ 167 tmpbuf[2] = SHA_HTONL(ctx->H[2]); \ 168 tmpbuf[3] = SHA_HTONL(ctx->H[3]); \ 169 tmpbuf[4] = SHA_HTONL(ctx->H[4]); \ 170 memcpy(hashout, tmpbuf, SHA1_LENGTH); \ 171 } 172 173 #else 174 #define SHA_STORE_RESULT \ 175 if (!((ptrdiff_t)hashout % sizeof(PRUint32))) { \ 176 SHA_STORE(0); \ 177 SHA_STORE(1); \ 178 SHA_STORE(2); \ 179 SHA_STORE(3); \ 180 SHA_STORE(4); \ 181 } else { \ 182 memcpy(hashout, ctx->H, SHA1_LENGTH); \ 183 } 184 #endif 185 186 #endif /* _SHA_FAST_H_ */