DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (c68fe15a81fc)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
/* 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)
typedef PRUint64 SHA_HW_t;
#define SHA1_USING_64_BIT 1
#else
typedef PRUint32 SHA_HW_t;
#endif

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 */
};

#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_ */