mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 12:51:06 +00:00
Bug 798634 - Style patrol on mfbt/SHA1.*. r=espindola
--HG-- extra : rebase_source : 7282b80ebe5f23b669a5f3142f3a6e50b6776789
This commit is contained in:
parent
34be9490e9
commit
6c828f9bb0
141
mfbt/SHA1.cpp
141
mfbt/SHA1.cpp
@ -2,49 +2,54 @@
|
||||
* 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/. */
|
||||
|
||||
#include <string.h>
|
||||
#include "mozilla/SHA1.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/SHA1.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
// FIXME: We should probably create a more complete mfbt/Endian.h. This assumes
|
||||
// that any compiler that doesn't define these macros is little endian.
|
||||
#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__)
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
#define MOZ_IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
# define MOZ_IS_LITTLE_ENDIAN
|
||||
# endif
|
||||
#else
|
||||
#define MOZ_IS_LITTLE_ENDIAN
|
||||
# define MOZ_IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
using mozilla::SHA1Sum;
|
||||
|
||||
static inline uint32_t SHA_ROTL(uint32_t t, uint32_t n)
|
||||
static inline uint32_t
|
||||
SHA_ROTL(uint32_t t, uint32_t n)
|
||||
{
|
||||
return ((t << n) | (t >> (32 - n)));
|
||||
MOZ_ASSERT(n < 32);
|
||||
return (t << n) | (t >> (32 - n));
|
||||
}
|
||||
|
||||
static inline unsigned
|
||||
SHA_HTONL(unsigned x)
|
||||
{
|
||||
#ifdef MOZ_IS_LITTLE_ENDIAN
|
||||
static inline unsigned SHA_HTONL(unsigned x) {
|
||||
const unsigned int mask = 0x00FF00FF;
|
||||
x = (x << 16) | (x >> 16);
|
||||
return ((x & mask) << 8) | ((x >> 8) & mask);
|
||||
}
|
||||
#else
|
||||
static inline unsigned SHA_HTONL(unsigned x) {
|
||||
return x;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void shaCompress(volatile unsigned *X, const uint32_t * datain);
|
||||
static void
|
||||
shaCompress(volatile unsigned* X, const uint32_t* datain);
|
||||
|
||||
#define SHA_F1(X,Y,Z) ((((Y)^(Z))&(X))^(Z))
|
||||
#define SHA_F2(X,Y,Z) ((X)^(Y)^(Z))
|
||||
#define SHA_F3(X,Y,Z) (((X)&(Y))|((Z)&((X)|(Y))))
|
||||
#define SHA_F4(X,Y,Z) ((X)^(Y)^(Z))
|
||||
#define SHA_F1(X, Y, Z) ((((Y) ^ (Z)) & (X)) ^ (Z))
|
||||
#define SHA_F2(X, Y, Z) ((X) ^ (Y) ^ (Z))
|
||||
#define SHA_F3(X, Y, Z) (((X) & (Y)) | ((Z) & ((X) | (Y))))
|
||||
#define SHA_F4(X, Y, Z) ((X) ^ (Y) ^ (Z))
|
||||
|
||||
#define SHA_MIX(n,a,b,c) XW(n) = SHA_ROTL(XW(a)^XW(b)^XW(c)^XW(n), 1)
|
||||
#define SHA_MIX(n, a, b, c) XW(n) = SHA_ROTL(XW(a) ^ XW(b) ^ XW(c) ^XW(n), 1)
|
||||
|
||||
SHA1Sum::SHA1Sum() : size(0), mDone(false)
|
||||
SHA1Sum::SHA1Sum()
|
||||
: size(0), mDone(false)
|
||||
{
|
||||
// Initialize H with constants from FIPS180-1.
|
||||
H[0] = 0x67452301L;
|
||||
@ -54,7 +59,9 @@ SHA1Sum::SHA1Sum() : size(0), mDone(false)
|
||||
H[4] = 0xc3d2e1f0L;
|
||||
}
|
||||
|
||||
/* Explanation of H array and index values:
|
||||
/*
|
||||
* Explanation of H array and index values:
|
||||
*
|
||||
* The context's H array is actually the concatenation of two arrays
|
||||
* defined by SHA1, the H array of state variables (5 elements),
|
||||
* and the W array of intermediate values, of which there are 16 elements.
|
||||
@ -91,80 +98,77 @@ SHA1Sum::SHA1Sum() : size(0), mDone(false)
|
||||
/*
|
||||
* SHA: Add data to context.
|
||||
*/
|
||||
void SHA1Sum::update(const uint8_t *dataIn, uint32_t len)
|
||||
void
|
||||
SHA1Sum::update(const uint8_t* dataIn, uint32_t len)
|
||||
{
|
||||
MOZ_ASSERT(!mDone);
|
||||
register unsigned int lenB;
|
||||
register unsigned int togo;
|
||||
MOZ_ASSERT(!mDone, "SHA1Sum can only be used to compute a single hash.");
|
||||
|
||||
if (!len)
|
||||
if (len == 0)
|
||||
return;
|
||||
|
||||
/* accumulate the byte count. */
|
||||
lenB = (unsigned int)(size) & 63U;
|
||||
/* Accumulate the byte count. */
|
||||
unsigned int lenB = static_cast<unsigned int>(size) & 63U;
|
||||
|
||||
size += len;
|
||||
|
||||
/*
|
||||
* Read the data into W and process blocks as they get full
|
||||
*/
|
||||
/* Read the data into W and process blocks as they get full. */
|
||||
unsigned int togo;
|
||||
if (lenB > 0) {
|
||||
togo = 64U - lenB;
|
||||
if (len < togo)
|
||||
togo = len;
|
||||
memcpy(u.b + lenB, dataIn, togo);
|
||||
len -= togo;
|
||||
len -= togo;
|
||||
dataIn += togo;
|
||||
lenB = (lenB + togo) & 63U;
|
||||
if (!lenB) {
|
||||
lenB = (lenB + togo) & 63U;
|
||||
if (!lenB)
|
||||
shaCompress(&H[H2X], u.w);
|
||||
}
|
||||
}
|
||||
|
||||
while (len >= 64U) {
|
||||
len -= 64U;
|
||||
shaCompress(&H[H2X], (uint32_t *)dataIn);
|
||||
len -= 64U;
|
||||
shaCompress(&H[H2X], reinterpret_cast<const uint32_t*>(dataIn));
|
||||
dataIn += 64U;
|
||||
}
|
||||
if (len) {
|
||||
|
||||
if (len > 0)
|
||||
memcpy(u.b, dataIn, len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* SHA: Generate hash value
|
||||
*/
|
||||
void SHA1Sum::finish(uint8_t hashout[20])
|
||||
void
|
||||
SHA1Sum::finish(SHA1Sum::Hash& hashOut)
|
||||
{
|
||||
MOZ_ASSERT(!mDone);
|
||||
register uint64_t size2 = size;
|
||||
register uint32_t lenB = (uint32_t)size2 & 63;
|
||||
MOZ_ASSERT(!mDone, "SHA1Sum can only be used to compute a single hash.");
|
||||
|
||||
static const uint8_t bulk_pad[64] = { 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,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 };
|
||||
uint64_t size2 = size;
|
||||
uint32_t lenB = uint32_t(size2) & 63;
|
||||
|
||||
/*
|
||||
* Pad with a binary 1 (e.g. 0x80), then zeroes, then length in bits
|
||||
*/
|
||||
static const uint8_t bulk_pad[64] =
|
||||
{ 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,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 };
|
||||
|
||||
/* Pad with a binary 1 (e.g. 0x80), then zeroes, then length in bits. */
|
||||
update(bulk_pad, (((55 + 64) - lenB) & 63) + 1);
|
||||
MOZ_ASSERT((uint32_t(size) & 63) == 56);
|
||||
|
||||
update(bulk_pad, (((55+64) - lenB) & 63) + 1);
|
||||
MOZ_ASSERT(((uint32_t)size & 63) == 56);
|
||||
/* Convert size from bytes to bits. */
|
||||
size2 <<= 3;
|
||||
u.w[14] = SHA_HTONL((uint32_t)(size2 >> 32));
|
||||
u.w[15] = SHA_HTONL((uint32_t)size2);
|
||||
u.w[14] = SHA_HTONL(uint32_t(size2 >> 32));
|
||||
u.w[15] = SHA_HTONL(uint32_t(size2));
|
||||
shaCompress(&H[H2X], u.w);
|
||||
|
||||
/*
|
||||
* Output hash
|
||||
*/
|
||||
/* Output hash. */
|
||||
u.w[0] = SHA_HTONL(H[0]);
|
||||
u.w[1] = SHA_HTONL(H[1]);
|
||||
u.w[2] = SHA_HTONL(H[2]);
|
||||
u.w[3] = SHA_HTONL(H[3]);
|
||||
u.w[4] = SHA_HTONL(H[4]);
|
||||
memcpy(hashout, u.w, 20);
|
||||
memcpy(hashOut, u.w, 20);
|
||||
mDone = true;
|
||||
}
|
||||
|
||||
@ -218,25 +222,24 @@ void SHA1Sum::finish(uint8_t hashout[20])
|
||||
static void
|
||||
shaCompress(volatile unsigned *X, const uint32_t *inbuf)
|
||||
{
|
||||
register unsigned A, B, C, D, E;
|
||||
unsigned A, B, C, D, E;
|
||||
|
||||
|
||||
#define XH(n) X[n-H2X]
|
||||
#define XW(n) X[n-W2X]
|
||||
#define XH(n) X[n - H2X]
|
||||
#define XW(n) X[n - W2X]
|
||||
|
||||
#define K0 0x5a827999L
|
||||
#define K1 0x6ed9eba1L
|
||||
#define K2 0x8f1bbcdcL
|
||||
#define K3 0xca62c1d6L
|
||||
|
||||
#define SHA_RND1(a,b,c,d,e,n) \
|
||||
a = SHA_ROTL(b,5)+SHA_F1(c,d,e)+a+XW(n)+K0; c=SHA_ROTL(c,30)
|
||||
#define SHA_RND2(a,b,c,d,e,n) \
|
||||
a = SHA_ROTL(b,5)+SHA_F2(c,d,e)+a+XW(n)+K1; c=SHA_ROTL(c,30)
|
||||
#define SHA_RND3(a,b,c,d,e,n) \
|
||||
a = SHA_ROTL(b,5)+SHA_F3(c,d,e)+a+XW(n)+K2; c=SHA_ROTL(c,30)
|
||||
#define SHA_RND4(a,b,c,d,e,n) \
|
||||
a = SHA_ROTL(b,5)+SHA_F4(c,d,e)+a+XW(n)+K3; c=SHA_ROTL(c,30)
|
||||
#define SHA_RND1(a, b, c, d, e, n) \
|
||||
a = SHA_ROTL(b, 5) + SHA_F1(c, d, e) + a + XW(n) + K0; c = SHA_ROTL(c, 30)
|
||||
#define SHA_RND2(a, b, c, d, e, n) \
|
||||
a = SHA_ROTL(b, 5) + SHA_F2(c, d, e) + a + XW(n) + K1; c = SHA_ROTL(c, 30)
|
||||
#define SHA_RND3(a, b, c, d, e, n) \
|
||||
a = SHA_ROTL(b, 5) + SHA_F3(c, d, e) + a + XW(n) + K2; c = SHA_ROTL(c, 30)
|
||||
#define SHA_RND4(a, b, c, d, e, n) \
|
||||
a = SHA_ROTL(b ,5) + SHA_F4(c, d, e) + a + XW(n) + K3; c = SHA_ROTL(c, 30)
|
||||
|
||||
#define LOAD(n) XW(n) = SHA_HTONL(inbuf[n])
|
||||
|
||||
|
76
mfbt/SHA1.h
76
mfbt/SHA1.h
@ -5,42 +5,56 @@
|
||||
|
||||
/* Simple class for computing SHA1. */
|
||||
|
||||
/*
|
||||
* To compute the SHA1 of a buffer using this class you should write something
|
||||
* like:
|
||||
* void SHA1(const uint8_t* buf, unsigned size, uint8_t hash[20])
|
||||
* {
|
||||
* SHA1Sum S;
|
||||
* S.update(buf, size);
|
||||
* S.finish(hash);
|
||||
* }
|
||||
* If there are multiple buffers or chunks, the update method can be called
|
||||
* multiple times and the SHA1 is computed on the concatenation of all the
|
||||
* buffers passed to it.
|
||||
* The finish method may only be called once and cannot be followed by calls
|
||||
* to update.
|
||||
*/
|
||||
|
||||
#ifndef mozilla_SHA1_h_
|
||||
#define mozilla_SHA1_h_
|
||||
|
||||
#include "mozilla/StandardInteger.h"
|
||||
namespace mozilla {
|
||||
class SHA1Sum {
|
||||
union {
|
||||
uint32_t w[16]; /* input buffer */
|
||||
uint8_t b[64];
|
||||
} u;
|
||||
uint64_t size; /* count of hashed bytes. */
|
||||
unsigned H[22]; /* 5 state variables, 16 tmp values, 1 extra */
|
||||
bool mDone;
|
||||
|
||||
public:
|
||||
static const unsigned int HashSize = 20;
|
||||
SHA1Sum();
|
||||
void update(const uint8_t *dataIn, uint32_t len);
|
||||
void finish(uint8_t hashout[20]);
|
||||
#include <stddef.h>
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
/**
|
||||
* This class computes the SHA1 hash of a byte sequence, or of the concatenation
|
||||
* of multiple sequences. For example, computing the SHA1 of two sequences of
|
||||
* bytes could be done as follows:
|
||||
*
|
||||
* void SHA1(const uint8_t* buf1, uint32_t size1,
|
||||
* const uint8_t* buf2, uint32_t size2,
|
||||
* SHA1Sum::Hash& hash)
|
||||
* {
|
||||
* SHA1Sum s;
|
||||
* s.update(buf1, size1);
|
||||
* s.update(buf2, size2);
|
||||
* s.finish(hash);
|
||||
* }
|
||||
*
|
||||
* The finish method may only be called once and cannot be followed by calls
|
||||
* to update.
|
||||
*/
|
||||
class SHA1Sum
|
||||
{
|
||||
union {
|
||||
uint32_t w[16]; /* input buffer */
|
||||
uint8_t b[64];
|
||||
} u;
|
||||
uint64_t size; /* count of hashed bytes. */
|
||||
unsigned H[22]; /* 5 state variables, 16 tmp values, 1 extra */
|
||||
bool mDone;
|
||||
|
||||
public:
|
||||
SHA1Sum();
|
||||
|
||||
static const size_t HashSize = 20;
|
||||
typedef uint8_t Hash[HashSize];
|
||||
|
||||
/* Add len bytes of dataIn to the data sequence being hashed. */
|
||||
void update(const uint8_t* dataIn, uint32_t len);
|
||||
|
||||
/* Compute the final hash of all data into hashOut. */
|
||||
void finish(SHA1Sum::Hash& hashOut);
|
||||
};
|
||||
}
|
||||
|
||||
} /* namespace mozilla */
|
||||
|
||||
#endif /* mozilla_SHA1_h_ */
|
||||
|
@ -2,11 +2,12 @@
|
||||
* 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/. */
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/SHA1.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using mozilla::SHA1Sum;
|
||||
|
||||
static unsigned int TestV[1024] = {
|
||||
static unsigned int testV[1024] = {
|
||||
0x048edc1a, 0x4345588c, 0x0ef03cbf, 0x1d6438f5, 0x094e0a1e, 0x68535f60,
|
||||
0x14e8c927, 0x60190043, 0x5d640ab7, 0x73dc7c62, 0x364223f9, 0x47320292,
|
||||
0x3924cae0, 0x5f6b26d3, 0x5efa04ef, 0x7aab361e, 0x2773b1aa, 0x1631b07d,
|
||||
@ -180,20 +181,24 @@ static unsigned int TestV[1024] = {
|
||||
0x236f5e8d, 0x1a4b4495, 0x360bd008, 0x32227d40
|
||||
};
|
||||
|
||||
int main()
|
||||
int
|
||||
main()
|
||||
{
|
||||
SHA1Sum S;
|
||||
unsigned char hash[20];
|
||||
S.update((const unsigned char*) TestV, sizeof(TestV));
|
||||
S.finish(hash);
|
||||
const unsigned char expected[20] = {
|
||||
0xc8, 0xf2, 0x09, 0x59, 0x4e, 0x64, 0x40, 0xaa, 0x7b, 0xf7, 0xb8, 0xe0,
|
||||
0xfa, 0x44, 0xb2, 0x31, 0x95, 0xad, 0x94, 0x81};
|
||||
SHA1Sum sum;
|
||||
SHA1Sum::Hash hash;
|
||||
sum.update(reinterpret_cast<const uint8_t*>(testV), sizeof(testV));
|
||||
sum.finish(hash);
|
||||
|
||||
static const uint8_t expected[20] =
|
||||
{ 0xc8, 0xf2, 0x09, 0x59, 0x4e, 0x64, 0x40, 0xaa, 0x7b, 0xf7, 0xb8, 0xe0,
|
||||
0xfa, 0x44, 0xb2, 0x31, 0x95, 0xad, 0x94, 0x81 };
|
||||
|
||||
MOZ_STATIC_ASSERT(sizeof(expected) == sizeof(SHA1Sum::Hash),
|
||||
"expected-data size should be the same as the actual hash "
|
||||
"size");
|
||||
|
||||
for (size_t i = 0; i < SHA1Sum::HashSize; i++)
|
||||
MOZ_ASSERT(hash[i] == expected[i]);
|
||||
|
||||
for (unsigned int i = 0; i < 20; ++i) {
|
||||
if (hash[i] != expected[i]) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user