diff options
Diffstat (limited to 'security/nss/lib/freebl/sha_fast.h')
-rw-r--r-- | security/nss/lib/freebl/sha_fast.h | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/security/nss/lib/freebl/sha_fast.h b/security/nss/lib/freebl/sha_fast.h new file mode 100644 index 0000000000..c03c0637a3 --- /dev/null +++ b/security/nss/lib/freebl/sha_fast.h @@ -0,0 +1,186 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _SHA_FAST_H_ +#define _SHA_FAST_H_ + +#include "prlong.h" +#include "blapii.h" + +#define SHA1_INPUT_LEN 64 + +#if defined(IS_64) && !defined(__sparc) && !defined(__aarch64__) +typedef PRUint64 SHA_HW_t; +#define SHA1_USING_64_BIT 1 +#else +typedef PRUint32 SHA_HW_t; +#endif + +struct SHA1ContextStr; + +typedef void (*sha1_compress_t)(struct SHA1ContextStr *); +typedef void (*sha1_update_t)(struct SHA1ContextStr *, const unsigned char *, + unsigned int); + +struct SHA1ContextStr { + union { + PRUint32 w[16]; /* input buffer */ + PRUint8 b[64]; + } u; + PRUint64 size; /* count of hashed bytes. */ + SHA_HW_t H[22]; /* 5 state variables, 16 tmp values, 1 extra */ + sha1_compress_t compress; + sha1_update_t update; +}; + +#if defined(_MSC_VER) +#include <stdlib.h> +#if defined(IS_LITTLE_ENDIAN) +#if (_MSC_VER >= 1300) +#pragma intrinsic(_byteswap_ulong) +#define SHA_HTONL(x) _byteswap_ulong(x) +#elif defined(NSS_X86_OR_X64) +#ifndef FORCEINLINE +#if (_MSC_VER >= 1200) +#define FORCEINLINE __forceinline +#else +#define FORCEINLINE __inline +#endif /* _MSC_VER */ +#endif /* !defined FORCEINLINE */ +#define FASTCALL __fastcall + +static FORCEINLINE PRUint32 FASTCALL +swap4b(PRUint32 dwd) +{ + __asm { + mov eax,dwd + bswap eax + } +} + +#define SHA_HTONL(x) swap4b(x) +#endif /* NSS_X86_OR_X64 */ +#endif /* IS_LITTLE_ENDIAN */ + +#pragma intrinsic(_lrotr, _lrotl) +#define SHA_ROTL(x, n) _lrotl(x, n) +#define SHA_ROTL_IS_DEFINED 1 +#endif /* _MSC_VER */ + +#if defined(__GNUC__) +/* __x86_64__ and __x86_64 are defined by GCC on x86_64 CPUs */ +#if defined(SHA1_USING_64_BIT) +static __inline__ PRUint64 +SHA_ROTL(PRUint64 x, PRUint32 n) +{ + PRUint32 t = (PRUint32)x; + return ((t << n) | (t >> (32 - n))); +} +#else +static __inline__ PRUint32 +SHA_ROTL(PRUint32 t, PRUint32 n) +{ + return ((t << n) | (t >> (32 - n))); +} +#endif +#define SHA_ROTL_IS_DEFINED 1 + +#if defined(NSS_X86_OR_X64) +static __inline__ PRUint32 +swap4b(PRUint32 value) +{ + __asm__("bswap %0" + : "+r"(value)); + return (value); +} +#define SHA_HTONL(x) swap4b(x) + +#elif defined(__thumb2__) || \ + (!defined(__thumb__) && \ + (defined(__ARM_ARCH_6__) || \ + defined(__ARM_ARCH_6J__) || \ + defined(__ARM_ARCH_6K__) || \ + defined(__ARM_ARCH_6Z__) || \ + defined(__ARM_ARCH_6ZK__) || \ + defined(__ARM_ARCH_6T2__) || \ + defined(__ARM_ARCH_7__) || \ + defined(__ARM_ARCH_7A__) || \ + defined(__ARM_ARCH_7R__))) +#if defined(IS_LITTLE_ENDIAN) +static __inline__ PRUint32 +swap4b(PRUint32 value) +{ + PRUint32 ret; + __asm__("rev %0, %1" + : "=r"(ret) + : "r"(value)); + return ret; +} +#define SHA_HTONL(x) swap4b(x) +#endif + +#endif /* x86 family */ + +#endif /* __GNUC__ */ + +#if !defined(SHA_ROTL_IS_DEFINED) +#define SHA_NEED_TMP_VARIABLE 1 +#define SHA_ROTL(X, n) (tmp = (X), ((tmp) << (n)) | ((tmp) >> (32 - (n)))) +#endif + +#if !defined(SHA_HTONL) +#define SHA_MASK 0x00FF00FF +#if defined(IS_LITTLE_ENDIAN) +#undef SHA_NEED_TMP_VARIABLE +#define SHA_NEED_TMP_VARIABLE 1 +#define SHA_HTONL(x) (tmp = (x), tmp = (tmp << 16) | (tmp >> 16), \ + ((tmp & SHA_MASK) << 8) | ((tmp >> 8) & SHA_MASK)) +#else +#define SHA_HTONL(x) (x) +#endif +#endif + +#define SHA_BYTESWAP(x) x = SHA_HTONL(x) + +#define SHA_STORE(n) ((PRUint32 *)hashout)[n] = SHA_HTONL(ctx->H[n]) +#if defined(HAVE_UNALIGNED_ACCESS) +#define SHA_STORE_RESULT \ + SHA_STORE(0); \ + SHA_STORE(1); \ + SHA_STORE(2); \ + SHA_STORE(3); \ + SHA_STORE(4); + +#elif defined(IS_LITTLE_ENDIAN) || defined(SHA1_USING_64_BIT) +#define SHA_STORE_RESULT \ + if (!((ptrdiff_t)hashout % sizeof(PRUint32))) { \ + SHA_STORE(0); \ + SHA_STORE(1); \ + SHA_STORE(2); \ + SHA_STORE(3); \ + SHA_STORE(4); \ + } else { \ + PRUint32 tmpbuf[5]; \ + tmpbuf[0] = SHA_HTONL(ctx->H[0]); \ + tmpbuf[1] = SHA_HTONL(ctx->H[1]); \ + tmpbuf[2] = SHA_HTONL(ctx->H[2]); \ + tmpbuf[3] = SHA_HTONL(ctx->H[3]); \ + tmpbuf[4] = SHA_HTONL(ctx->H[4]); \ + memcpy(hashout, tmpbuf, SHA1_LENGTH); \ + } + +#else +#define SHA_STORE_RESULT \ + if (!((ptrdiff_t)hashout % sizeof(PRUint32))) { \ + SHA_STORE(0); \ + SHA_STORE(1); \ + SHA_STORE(2); \ + SHA_STORE(3); \ + SHA_STORE(4); \ + } else { \ + memcpy(hashout, ctx->H, SHA1_LENGTH); \ + } +#endif + +#endif /* _SHA_FAST_H_ */ |