Remove custom MD5 / SHA-1 implementations.

Use (optimized) versions from BoringSSL/OpenSSL instead.

Bug: webrtc:8677
Change-Id: I8610bb757c228ad99518ee583329eb7944c4bf08
Reviewed-on: https://webrtc-review.googlesource.com/35020
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Commit-Queue: Joachim Bauch <jbauch@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22084}
This commit is contained in:
Joachim Bauch 2017-12-21 22:34:37 +01:00 committed by Commit Bot
parent 0bc9c7d58a
commit 820941a1fd
10 changed files with 35 additions and 650 deletions

View File

@ -4,10 +4,6 @@ party licenses. Paths to the files and associated licenses are collected here.
Files governed by third party licenses:
base/base64.cc
base/base64.h
base/md5.cc
base/md5.h
base/sha1.cc
base/sha1.h
base/sigslot.cc
base/sigslot.h
common_audio/fft4g.c
@ -49,34 +45,6 @@ License:
//*********************************************************************
-------------------------------------------------------------------------------
Files:
base/md5.cc
base/md5.h
License:
/*
* This code implements the MD5 message-digest algorithm.
* The algorithm is due to Ron Rivest. This code was
* written by Colin Plumb in 1993, no copyright is claimed.
* This code is in the public domain; do with it what you wish.
*
-------------------------------------------------------------------------------
Files:
base/sha1.cc
base/sha1.h
License:
/*
* SHA-1 in C
* By Steve Reid <sreid@sea-to-sky.net>
* 100% Public Domain
*
* -----------------
* Modified 7/98
* By James H. Brown <jbrown@burgoyne.com>
* Still 100% Public Domain
*
-------------------------------------------------------------------------------
Files:
base/sigslot.cc
base/sigslot.h

View File

@ -841,8 +841,6 @@ rtc_source_set("rtc_base_tests_utils") {
"httpbase.h",
"httpserver.cc",
"httpserver.h",
"md5.cc",
"md5.h",
"md5digest.cc",
"md5digest.h",
"memory_usage.cc",
@ -856,8 +854,6 @@ rtc_source_set("rtc_base_tests_utils") {
"proxyserver.cc",
"proxyserver.h",
"refcount.h",
"sha1.cc",
"sha1.h",
"sha1digest.cc",
"sha1digest.h",
"sigslottester.h",
@ -886,6 +882,14 @@ rtc_source_set("rtc_base_tests_utils") {
public_deps = [
"//testing/gtest",
]
# TODO(jbauch): Remove once "md5digest" and "sha1digest" files have been
# removed.
if (rtc_build_ssl) {
deps += [ "//third_party/boringssl" ]
} else {
configs += [ ":external_ssl_library" ]
}
}
rtc_source_set("rtc_task_queue_for_test") {
@ -1010,6 +1014,14 @@ if (rtc_include_tests) {
"../system_wrappers:system_wrappers",
"../test:test_support",
]
# TODO(jbauch): Remove once "md5digest" and "sha1digest" files have been
# removed.
if (rtc_build_ssl) {
deps += [ "//third_party/boringssl" ]
} else {
configs += [ ":external_ssl_library" ]
}
}
rtc_source_set("rtc_task_queue_unittests") {

View File

@ -1,222 +0,0 @@
/*
* This code implements the MD5 message-digest algorithm.
* The algorithm is due to Ron Rivest. This code was
* written by Colin Plumb in 1993, no copyright is claimed.
* This code is in the public domain; do with it what you wish.
*
* Equivalent code is available from RSA Data Security, Inc.
* This code has been tested against that, and is equivalent,
* except that you don't need to include two pages of legalese
* with every copy.
*
* To compute the message digest of a chunk of bytes, declare an
* MD5Context structure, pass it to MD5Init, call MD5Update as
* needed on buffers full of bytes, and then call MD5Final, which
* will fill a supplied 16-byte array with the digest.
*/
// Changes from original C code:
// Ported to C++, type casting, Google code style.
#include "rtc_base/md5.h"
// TODO: Avoid memcmpy - hash directly from memory.
#include <string.h> // for memcpy().
#include "rtc_base/byteorder.h" // for RTC_ARCH_CPU_LITTLE_ENDIAN.
namespace rtc {
#ifdef RTC_ARCH_CPU_LITTLE_ENDIAN
#define ByteReverse(buf, len) // Nothing.
#else // RTC_ARCH_CPU_BIG_ENDIAN
static void ByteReverse(uint32_t* buf, int len) {
for (int i = 0; i < len; ++i) {
buf[i] = rtc::GetLE32(&buf[i]);
}
}
#endif
// Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
// initialization constants.
void MD5Init(MD5Context* ctx) {
ctx->buf[0] = 0x67452301;
ctx->buf[1] = 0xefcdab89;
ctx->buf[2] = 0x98badcfe;
ctx->buf[3] = 0x10325476;
ctx->bits[0] = 0;
ctx->bits[1] = 0;
}
// Update context to reflect the concatenation of another buffer full of bytes.
void MD5Update(MD5Context* ctx, const uint8_t* buf, size_t len) {
// Update bitcount.
uint32_t t = ctx->bits[0];
if ((ctx->bits[0] = t + (static_cast<uint32_t>(len) << 3)) < t) {
ctx->bits[1]++; // Carry from low to high.
}
ctx->bits[1] += static_cast<uint32_t>(len >> 29);
t = (t >> 3) & 0x3f; // Bytes already in shsInfo->data.
// Handle any leading odd-sized chunks.
if (t) {
uint8_t* p = reinterpret_cast<uint8_t*>(ctx->in) + t;
t = 64-t;
if (len < t) {
memcpy(p, buf, len);
return;
}
memcpy(p, buf, t);
ByteReverse(ctx->in, 16);
MD5Transform(ctx->buf, ctx->in);
buf += t;
len -= t;
}
// Process data in 64-byte chunks.
while (len >= 64) {
memcpy(ctx->in, buf, 64);
ByteReverse(ctx->in, 16);
MD5Transform(ctx->buf, ctx->in);
buf += 64;
len -= 64;
}
// Handle any remaining bytes of data.
memcpy(ctx->in, buf, len);
}
// Final wrapup - pad to 64-byte boundary with the bit pattern.
// 1 0* (64-bit count of bits processed, MSB-first)
void MD5Final(MD5Context* ctx, uint8_t digest[16]) {
// Compute number of bytes mod 64.
uint32_t count = (ctx->bits[0] >> 3) & 0x3F;
// Set the first char of padding to 0x80. This is safe since there is
// always at least one byte free.
uint8_t* p = reinterpret_cast<uint8_t*>(ctx->in) + count;
*p++ = 0x80;
// Bytes of padding needed to make 64 bytes.
count = 64 - 1 - count;
// Pad out to 56 mod 64.
if (count < 8) {
// Two lots of padding: Pad the first block to 64 bytes.
memset(p, 0, count);
ByteReverse(ctx->in, 16);
MD5Transform(ctx->buf, ctx->in);
// Now fill the next block with 56 bytes.
memset(ctx->in, 0, 56);
} else {
// Pad block to 56 bytes.
memset(p, 0, count - 8);
}
ByteReverse(ctx->in, 14);
// Append length in bits and transform.
ctx->in[14] = ctx->bits[0];
ctx->in[15] = ctx->bits[1];
MD5Transform(ctx->buf, ctx->in);
ByteReverse(ctx->buf, 4);
memcpy(digest, ctx->buf, 16);
memset(ctx, 0, sizeof(*ctx)); // In case it's sensitive.
}
// The four core functions - F1 is optimized somewhat.
// #define F1(x, y, z) (x & y | ~x & z)
#define F1(x, y, z) (z ^ (x & (y ^ z)))
#define F2(x, y, z) F1(z, x, y)
#define F3(x, y, z) (x ^ y ^ z)
#define F4(x, y, z) (y ^ (x | ~z))
// This is the central step in the MD5 algorithm.
#define MD5STEP(f, w, x, y, z, data, s) \
(w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x)
// The core of the MD5 algorithm, this alters an existing MD5 hash to
// reflect the addition of 16 longwords of new data. MD5Update blocks
// the data and converts bytes into longwords for this routine.
void MD5Transform(uint32_t buf[4], const uint32_t in[16]) {
uint32_t a = buf[0];
uint32_t b = buf[1];
uint32_t c = buf[2];
uint32_t d = buf[3];
MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478, 7);
MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12);
MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17);
MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22);
MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf, 7);
MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12);
MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17);
MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22);
MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8, 7);
MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12);
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562, 5);
MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340, 9);
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20);
MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d, 5);
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20);
MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6, 5);
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14);
MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20);
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8, 9);
MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14);
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942, 4);
MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11);
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44, 4);
MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11);
MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16);
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11);
MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16);
MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23);
MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039, 4);
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
MD5STEP(F3, b, c, d, a, in[ 2] + 0xc4ac5665, 23);
MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244, 6);
MD5STEP(F4, d, a, b, c, in[ 7] + 0x432aff97, 10);
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
MD5STEP(F4, b, c, d, a, in[ 5] + 0xfc93a039, 21);
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
MD5STEP(F4, d, a, b, c, in[ 3] + 0x8f0ccc92, 10);
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
MD5STEP(F4, b, c, d, a, in[ 1] + 0x85845dd1, 21);
MD5STEP(F4, a, b, c, d, in[ 8] + 0x6fa87e4f, 6);
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
MD5STEP(F4, c, d, a, b, in[ 6] + 0xa3014314, 15);
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
MD5STEP(F4, a, b, c, d, in[ 4] + 0xf7537e82, 6);
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
MD5STEP(F4, c, d, a, b, in[ 2] + 0x2ad7d2bb, 15);
MD5STEP(F4, b, c, d, a, in[ 9] + 0xeb86d391, 21);
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
}
} // namespace rtc

View File

@ -1,44 +0,0 @@
/*
* This is the header file for the MD5 message-digest algorithm.
* The algorithm is due to Ron Rivest. This code was
* written by Colin Plumb in 1993, no copyright is claimed.
* This code is in the public domain; do with it what you wish.
*
* Equivalent code is available from RSA Data Security, Inc.
* This code has been tested against that, and is equivalent,
* except that you don't need to include two pages of legalese
* with every copy.
* To compute the message digest of a chunk of bytes, declare an
* MD5Context structure, pass it to MD5Init, call MD5Update as
* needed on buffers full of bytes, and then call MD5Final, which
* will fill a supplied 16-byte array with the digest.
*
*/
// Changes(fbarchard): Ported to C++ and Google style guide.
// Made context first parameter in MD5Final for consistency with Sha1.
// Changes(hellner): added rtc namespace
// Changes(pbos): Reverted types back to uint32(8)_t with _t suffix.
#ifndef RTC_BASE_MD5_H_
#define RTC_BASE_MD5_H_
#include <stdint.h>
#include <stdlib.h>
namespace rtc {
struct MD5Context {
uint32_t buf[4];
uint32_t bits[2];
uint32_t in[16];
};
void MD5Init(MD5Context* context);
void MD5Update(MD5Context* context, const uint8_t* data, size_t len);
void MD5Final(MD5Context* context, uint8_t digest[16]);
void MD5Transform(uint32_t buf[4], const uint32_t in[16]);
} // namespace rtc
#endif // RTC_BASE_MD5_H_

View File

@ -17,16 +17,16 @@ size_t Md5Digest::Size() const {
}
void Md5Digest::Update(const void* buf, size_t len) {
MD5Update(&ctx_, static_cast<const uint8_t*>(buf), len);
MD5_Update(&ctx_, static_cast<const uint8_t*>(buf), len);
}
size_t Md5Digest::Finish(void* buf, size_t len) {
if (len < kSize) {
return 0;
}
MD5Final(&ctx_, static_cast<uint8_t*>(buf));
MD5Init(&ctx_); // Reset for next use.
MD5_Final(static_cast<uint8_t*>(buf), &ctx_);
MD5_Init(&ctx_); // Reset for next use.
return kSize;
}
}; // namespace rtc
} // namespace rtc

View File

@ -11,24 +11,25 @@
#ifndef RTC_BASE_MD5DIGEST_H_
#define RTC_BASE_MD5DIGEST_H_
#include "rtc_base/md5.h"
#include <openssl/md5.h>
#include "rtc_base/messagedigest.h"
namespace rtc {
// A simple wrapper for our MD5 implementation.
// A simple wrapper for the MD5 implementation.
class Md5Digest : public MessageDigest {
public:
enum { kSize = 16 };
enum { kSize = MD5_DIGEST_LENGTH };
Md5Digest() {
MD5Init(&ctx_);
MD5_Init(&ctx_);
}
size_t Size() const override;
void Update(const void* buf, size_t len) override;
size_t Finish(void* buf, size_t len) override;
private:
MD5Context ctx_;
MD5_CTX ctx_;
};
} // namespace rtc

View File

@ -1,298 +0,0 @@
/*
* SHA-1 in C
* By Steve Reid <sreid@sea-to-sky.net>
* 100% Public Domain
*
* -----------------
* Modified 7/98
* By James H. Brown <jbrown@burgoyne.com>
* Still 100% Public Domain
*
* Corrected a problem which generated improper hash values on 16 bit machines
* Routine SHA1Update changed from
* void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int
* len)
* to
* void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
* long len)
*
* The 'len' parameter was declared an int which works fine on 32 bit machines.
* However, on 16 bit machines an int is too small for the shifts being done
* against
* it. This caused the hash function to generate incorrect values if len was
* greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
*
* Since the file IO in main() reads 16K at a time, any file 8K or larger would
* be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million
* "a"s).
*
* I also changed the declaration of variables i & j in SHA1Update to
* unsigned long from unsigned int for the same reason.
*
* These changes should make no difference to any 32 bit implementations since
* an
* int and a long are the same size in those environments.
*
* --
* I also corrected a few compiler warnings generated by Borland C.
* 1. Added #include <process.h> for exit() prototype
* 2. Removed unused variable 'j' in SHA1Final
* 3. Changed exit(0) to return(0) at end of main.
*
* ALL changes I made can be located by searching for comments containing 'JHB'
* -----------------
* Modified 8/98
* By Steve Reid <sreid@sea-to-sky.net>
* Still 100% public domain
*
* 1- Removed #include <process.h> and used return() instead of exit()
* 2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
* 3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net
*
* -----------------
* Modified 4/01
* By Saul Kravitz <Saul.Kravitz@celera.com>
* Still 100% PD
* Modified to run on Compaq Alpha hardware.
*
* -----------------
* Modified 07/2002
* By Ralph Giles <giles@ghostscript.com>
* Still 100% public domain
* modified for use with stdint types, autoconf
* code cleanup, removed attribution comments
* switched SHA1Final() argument order for consistency
* use SHA1_ prefix for public api
* move public api to sha1.h
*
* -----------------
* Modified 02/2012
* By Justin Uberti <juberti@google.com>
* Remove underscore from SHA1 prefix to avoid conflict with OpenSSL
* Remove test code
* Untabify
*
* -----------------
* Modified 03/2012
* By Ronghua Wu <ronghuawu@google.com>
* Change the typedef of uint32(8)_t to uint32(8). We need this because in the
* chromium android build, the stdio.h will include stdint.h which already
* defined uint32(8)_t.
*
* -----------------
* Modified 04/2012
* By Frank Barchard <fbarchard@google.com>
* Ported to C++, Google style, change len to size_t, enable SHA1HANDSOFF
*
* Test Vectors (from FIPS PUB 180-1)
* "abc"
* A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
* "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
* 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
* A million repetitions of "a"
* 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
*
* -----------------
* Modified 05/2015
* By Sergey Ulanov <sergeyu@chromium.org>
* Removed static buffer to make computation thread-safe.
*
* -----------------
* Modified 10/2015
* By Peter Boström <pbos@webrtc.org>
* Change uint32(8) back to uint32(8)_t (undoes (03/2012) change).
*/
// Enabling SHA1HANDSOFF preserves the caller's data buffer.
// Disabling SHA1HANDSOFF the buffer will be modified (end swapped).
#define SHA1HANDSOFF
#include "rtc_base/sha1.h"
#include <stdio.h>
#include <string.h>
namespace rtc {
namespace {
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
// blk0() and blk() perform the initial expand.
// I got the idea of expanding during the round function from SSLeay
// FIXME: can we do this in an endian-proof way?
#ifdef RTC_ARCH_CPU_BIG_ENDIAN
#define blk0(i) block->l[i]
#else
#define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | \
(rol(block->l[i], 8) & 0x00FF00FF))
#endif
#define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ \
block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1))
// (R0+R1), R2, R3, R4 are the different operations used in SHA1.
#define R0(v, w, x, y, z, i) \
z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \
w = rol(w, 30);
#define R1(v, w, x, y, z, i) \
z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
w = rol(w, 30);
#define R2(v, w, x, y, z, i) \
z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5);\
w = rol(w, 30);
#define R3(v, w, x, y, z, i) \
z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
w = rol(w, 30);
#define R4(v, w, x, y, z, i) \
z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
w = rol(w, 30);
#ifdef VERBOSE // SAK
void SHAPrintContext(SHA1_CTX *context, char *msg) {
printf("%s (%d,%d) %x %x %x %x %x\n",
msg,
context->count[0], context->count[1],
context->state[0],
context->state[1],
context->state[2],
context->state[3],
context->state[4]);
}
#endif /* VERBOSE */
// Hash a single 512-bit block. This is the core of the algorithm.
void SHA1Transform(uint32_t state[5], const uint8_t buffer[64]) {
union CHAR64LONG16 {
uint8_t c[64];
uint32_t l[16];
};
#ifdef SHA1HANDSOFF
uint8_t workspace[64];
memcpy(workspace, buffer, 64);
CHAR64LONG16* block = reinterpret_cast<CHAR64LONG16*>(workspace);
#else
// Note(fbarchard): This option does modify the user's data buffer.
CHAR64LONG16* block = const_cast<CHAR64LONG16*>(
reinterpret_cast<const CHAR64LONG16*>(buffer));
#endif
// Copy context->state[] to working vars.
uint32_t a = state[0];
uint32_t b = state[1];
uint32_t c = state[2];
uint32_t d = state[3];
uint32_t e = state[4];
// 4 rounds of 20 operations each. Loop unrolled.
// Note(fbarchard): The following has lint warnings for multiple ; on
// a line and no space after , but is left as-is to be similar to the
// original code.
R0(a,b,c,d,e,0); R0(e,a,b,c,d,1); R0(d,e,a,b,c,2); R0(c,d,e,a,b,3);
R0(b,c,d,e,a,4); R0(a,b,c,d,e,5); R0(e,a,b,c,d,6); R0(d,e,a,b,c,7);
R0(c,d,e,a,b,8); R0(b,c,d,e,a,9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
// Add the working vars back into context.state[].
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
}
} // namespace
// SHA1Init - Initialize new context.
void SHA1Init(SHA1_CTX* context) {
// SHA1 initialization constants.
context->state[0] = 0x67452301;
context->state[1] = 0xEFCDAB89;
context->state[2] = 0x98BADCFE;
context->state[3] = 0x10325476;
context->state[4] = 0xC3D2E1F0;
context->count[0] = context->count[1] = 0;
}
// Run your data through this.
void SHA1Update(SHA1_CTX* context, const uint8_t* data, size_t input_len) {
size_t i = 0;
#ifdef VERBOSE
SHAPrintContext(context, "before");
#endif
// Compute number of bytes mod 64.
size_t index = (context->count[0] >> 3) & 63;
// Update number of bits.
// TODO: Use uint64_t instead of 2 uint32_t for count.
// count[0] has low 29 bits for byte count + 3 pad 0's making 32 bits for
// bit count.
// Add bit count to low uint32_t
context->count[0] += static_cast<uint32_t>(input_len << 3);
if (context->count[0] < static_cast<uint32_t>(input_len << 3)) {
++context->count[1]; // if overlow (carry), add one to high word
}
context->count[1] += static_cast<uint32_t>(input_len >> 29);
if ((index + input_len) > 63) {
i = 64 - index;
memcpy(&context->buffer[index], data, i);
SHA1Transform(context->state, context->buffer);
for (; i + 63 < input_len; i += 64) {
SHA1Transform(context->state, data + i);
}
index = 0;
}
memcpy(&context->buffer[index], &data[i], input_len - i);
#ifdef VERBOSE
SHAPrintContext(context, "after ");
#endif
}
// Add padding and return the message digest.
void SHA1Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE]) {
uint8_t finalcount[8];
for (int i = 0; i < 8; ++i) {
// Endian independent
finalcount[i] = static_cast<uint8_t>(
(context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 255);
}
SHA1Update(context, reinterpret_cast<const uint8_t*>("\200"), 1);
while ((context->count[0] & 504) != 448) {
SHA1Update(context, reinterpret_cast<const uint8_t*>("\0"), 1);
}
SHA1Update(context, finalcount, 8); // Should cause a SHA1Transform().
for (int i = 0; i < SHA1_DIGEST_SIZE; ++i) {
digest[i] = static_cast<uint8_t>(
(context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
}
// Wipe variables.
memset(context->buffer, 0, 64);
memset(context->state, 0, 20);
memset(context->count, 0, 8);
memset(finalcount, 0, 8); // SWR
#ifdef SHA1HANDSOFF // Make SHA1Transform overwrite its own static vars.
SHA1Transform(context->state, context->buffer);
#endif
}
} // namespace rtc

View File

@ -1,33 +0,0 @@
/*
* SHA-1 in C
* By Steve Reid <sreid@sea-to-sky.net>
* 100% Public Domain
*
*/
// Ported to C++, Google style, under namespace rtc.
#ifndef RTC_BASE_SHA1_H_
#define RTC_BASE_SHA1_H_
#include <stdint.h>
#include <stdlib.h>
namespace rtc {
struct SHA1_CTX {
uint32_t state[5];
// TODO: Change bit count to uint64_t.
uint32_t count[2]; // Bit count of input.
uint8_t buffer[64];
};
#define SHA1_DIGEST_SIZE 20
void SHA1Init(SHA1_CTX* context);
void SHA1Update(SHA1_CTX* context, const uint8_t* data, size_t len);
void SHA1Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE]);
} // namespace rtc
#endif // RTC_BASE_SHA1_H_

View File

@ -17,15 +17,15 @@ size_t Sha1Digest::Size() const {
}
void Sha1Digest::Update(const void* buf, size_t len) {
SHA1Update(&ctx_, static_cast<const uint8_t*>(buf), len);
SHA1_Update(&ctx_, static_cast<const uint8_t*>(buf), len);
}
size_t Sha1Digest::Finish(void* buf, size_t len) {
if (len < kSize) {
return 0;
}
SHA1Final(&ctx_, static_cast<uint8_t*>(buf));
SHA1Init(&ctx_); // Reset for next use.
SHA1_Final(static_cast<uint8_t*>(buf), &ctx_);
SHA1_Init(&ctx_); // Reset for next use.
return kSize;
}

View File

@ -11,24 +11,25 @@
#ifndef RTC_BASE_SHA1DIGEST_H_
#define RTC_BASE_SHA1DIGEST_H_
#include <openssl/sha.h>
#include "rtc_base/messagedigest.h"
#include "rtc_base/sha1.h"
namespace rtc {
// A simple wrapper for our SHA-1 implementation.
// A simple wrapper for the SHA-1 implementation.
class Sha1Digest : public MessageDigest {
public:
enum { kSize = SHA1_DIGEST_SIZE };
enum { kSize = SHA_DIGEST_LENGTH };
Sha1Digest() {
SHA1Init(&ctx_);
SHA1_Init(&ctx_);
}
size_t Size() const override;
void Update(const void* buf, size_t len) override;
size_t Finish(void* buf, size_t len) override;
private:
SHA1_CTX ctx_;
SHA_CTX ctx_;
};
} // namespace rtc