Plugin for RainbowCrack - PoC

This commit is contained in:
Vesselin Bontchev 2015-07-23 10:29:15 +00:00
commit e30f81194b
28 changed files with 702 additions and 0 deletions

11
Makefile Normal file
View file

@ -0,0 +1,11 @@
alglib1.so:
g++ -Wall -O3 -shared -fPIC alglib1.cpp sha1.c -o alglib1.so
windows:
# yum install mingw32-openssl mingw32-openssl-static mingw32-gcc mingw32-gcc-c++ mingw32-winpthreads-static -y
i686-w64-mingw32-g++ -c alglib1.cpp
i686-w64-mingw32-g++ -static -shared -o alglib1.dll alglib1.o -lcrypto -lpthread
# yum install mingw64-openssl mingw64-openssl-static mingw64-gcc mingw64-gcc-c++ mingw64-winpthreads-static mingw64-zlib-static mingw64-libgomp -y
x86_64-w64-mingw32-g++ -c alglib1.cpp -lcrypto
x86_64-w64-mingw32-g++ -static -shared -o alglib1.dll alglib1.o -lcrypto -lpthread

84
README.md Normal file
View file

@ -0,0 +1,84 @@
## NOTE (Licensing)
Commercial usage of this project requires a license from the author(s) of
this project. Contact us for details.
Note: The licensing terms of this project were changed due to commercial abuse
from OpenAudible (http://openaudible.org/) and other projects.
## About
Plugin for [RainbowCrack](http://project-rainbowcrack.com/) to recover your own
Audible activation data (activation_bytes) in an offline manner.
You need to recover or retrieve your "activation_bytes" only once. This single
"activation_bytes" value will work for all your .aax files.
## Donations
Donations are gladly accepted. Please send BTC to `1FDFp8kWjnUCGTLw1SVkim6kRnYDge2vYh`
to support the development, and maintenance of this project. Thank you!
## Note
Git clone this repository on your machine. This repository has the required
rainbow tables `(*.rtc files)` and RainbowCrack binaries.
```
git clone https://github.com/inAudible-NG/tables.git
```
## Usage on Linux
FFmpeg 2.8.1+ is required. Use Wine with the included (in `run` folder) Windows
binaries in case these Linux executables do not run on your distribution.
##### Extract SHA1 checksum from the .aax file
```
$ ffprobe test.aax # extract SHA1 checksum
...
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x1dde580] [aax] file checksum == 999a6ab8...
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x1dde580] [aax] activation_bytes option is missing!
```
##### Recover "activation_bytes"
```
$ ./rcrack . -h 999a6ab8...
```
## Usage on Windows
Download FFmpeg from https://ffmpeg.zeranoe.com/builds/.
##### Extract SHA1 checksum from .aax file
```
C:\>ffprobe.exe sample.aax
ffprobe version N-79460-g21acc4d Copyright (c) 2007-2016 the FFmpeg developers
built with gcc 5.3.0 (GCC)
...
[mov,mp4,m4a,3gp,3g2,mj2 @ 039aae60] [aax] file checksum == 999a6ab8...
[mov,mp4,m4a,3gp,3g2,mj2 @ 039aae60] [aax] activation_bytes option is missing!
```
##### Recover "activation_bytes"
```
C:\tables>run\rcrack.exe . -h 999a6ab8...
statistics
-------------------------------------------------------
plaintext found: 1 of 1
total time: 13.98 s
...
result
-------------------------------------------------------
999a6ab8... xyz hex:CAFED00D
```
"activation_bytes" is CAFED00D here.
## References
See http://project-rainbowcrack.com/alglib.htm for details.

BIN
alglib0.so Normal file

Binary file not shown.

80
alglib1.cpp Normal file
View file

@ -0,0 +1,80 @@
/*
* http://www.tobtu.com/rtcalc.php#params
*
* keyspace is 256^4 (length is always 4)
* 99.999999% (Total success rate)
*
* ./rtgen audible byte 4 4 0 10000 10008356 0
* ./rtgen audible byte 4 4 1 10000 10008356 0
* ./rtgen audible byte 4 4 2 10000 10008356 0
* ./rtgen audible byte 4 4 3 10000 10008356 0
* ./rtgen audible byte 4 4 4 10000 10008356 0
* ./rtgen audible byte 4 4 5 10000 10008356 0
* ./rtgen audible byte 4 4 6 10000 10008356 0
* ./rtgen audible byte 4 4 7 10000 10008356 0
* ./rtgen audible byte 4 4 8 10000 10008356 0
* ./rtgen audible byte 4 4 9 10000 10008356 0
*
* ./rtsort *.rt
* ./rt2rtc *.rt 21 24 -m 18 -p
* ./rt2rtc *.rt 25 25 -m 512 -p
*/
// #include <openssl/sha.h>
#include <stdio.h>
#include "sha1.h"
#ifdef _WIN32
#pragma comment(lib, "libeay32.lib")
#endif
#define MIN_HASH_LEN 8
#define MAX_HASH_LEN 32
void
#ifdef _WIN32
__stdcall
#endif
Audible(
unsigned char *pData, // [in] plaintext to be hashed
unsigned int uLen, // [in] length of the plaintext
unsigned char Hash[MAX_HASH_LEN]) // [out] the result hash, size of the buffer is MAX_HASH_LEN bytes
{
unsigned char fixed_key[] = { 0x77, 0x21, 0x4d, 0x4b, 0x19, 0x6a, 0x87,
0xcd, 0x52, 0x00, 0x45, 0xfd, 0x20, 0xa5, 0x1d, 0x67 };
unsigned char intermediate_key[20] = {0};
unsigned char intermediate_iv[20] = {0};
SHA_CTX ctx;
SHA1_Init(&ctx);
SHA1_Update(&ctx, fixed_key, 16);
SHA1_Update(&ctx, pData, uLen);
SHA1_Final(intermediate_key, &ctx);
SHA1_Init(&ctx);
SHA1_Update(&ctx, fixed_key, 16);
SHA1_Update(&ctx, intermediate_key, 20);
SHA1_Update(&ctx, pData, uLen);
SHA1_Final(intermediate_iv, &ctx);
SHA1_Init(&ctx);
SHA1_Update(&ctx, intermediate_key, 16);
SHA1_Update(&ctx, intermediate_iv, 16);
SHA1_Final(Hash, &ctx);
}
struct HashAlgorithmEntry
{
const char *szName; // name of the hash algorithm
void *pHashAlgorithm; // function pointer to the hash algorithm's implementation
unsigned int uHashLen; // output length of the hash algorithm, MIN_HASH_LEN <= uHashLen <= MAX_HASH_LEN
// input plaintext length range supported by the hash algorithm's implementation
unsigned int uPlaintextLenMin;
unsigned int uPlaintextLenMax;
};
struct HashAlgorithmEntry HashAlgorithms[] = { // this symbol will be exported
{"audible", (void *)Audible, 20, 4, 4}, // always 4 bytes
{0, 0, 0, 0, 0}, // terminated by an entry of all zeroes
};

BIN
alglib1.so Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

180
bswap.h Normal file
View file

@ -0,0 +1,180 @@
/*
* Let's make sure we always have a sane definition for ntohl()/htonl().
* Some libraries define those as a function call, just to perform byte
* shifting, bringing significant overhead to what should be a simple
* operation.
*/
/*
* Default version that the compiler ought to optimize properly with
* constant values.
*/
static inline uint32_t default_swab32(uint32_t val)
{
return (((val & 0xff000000) >> 24) |
((val & 0x00ff0000) >> 8) |
((val & 0x0000ff00) << 8) |
((val & 0x000000ff) << 24));
}
static inline uint64_t default_bswap64(uint64_t val)
{
return (((val & (uint64_t)0x00000000000000ffULL) << 56) |
((val & (uint64_t)0x000000000000ff00ULL) << 40) |
((val & (uint64_t)0x0000000000ff0000ULL) << 24) |
((val & (uint64_t)0x00000000ff000000ULL) << 8) |
((val & (uint64_t)0x000000ff00000000ULL) >> 8) |
((val & (uint64_t)0x0000ff0000000000ULL) >> 24) |
((val & (uint64_t)0x00ff000000000000ULL) >> 40) |
((val & (uint64_t)0xff00000000000000ULL) >> 56));
}
#undef bswap32
#undef bswap64
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
#define bswap32 git_bswap32
static inline uint32_t git_bswap32(uint32_t x)
{
uint32_t result;
if (__builtin_constant_p(x))
result = default_swab32(x);
else
__asm__("bswap %0" : "=r" (result) : "0" (x));
return result;
}
#define bswap64 git_bswap64
#if defined(__x86_64__)
static inline uint64_t git_bswap64(uint64_t x)
{
uint64_t result;
if (__builtin_constant_p(x))
result = default_bswap64(x);
else
__asm__("bswap %q0" : "=r" (result) : "0" (x));
return result;
}
#else
static inline uint64_t git_bswap64(uint64_t x)
{
union { uint64_t i64; uint32_t i32[2]; } tmp, result;
if (__builtin_constant_p(x))
result.i64 = default_bswap64(x);
else {
tmp.i64 = x;
result.i32[0] = git_bswap32(tmp.i32[1]);
result.i32[1] = git_bswap32(tmp.i32[0]);
}
return result.i64;
}
#endif
#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
#include <stdlib.h>
#define bswap32(x) _byteswap_ulong(x)
#define bswap64(x) _byteswap_uint64(x)
#endif
#if defined(bswap32)
#undef ntohl
#undef htonl
#define ntohl(x) bswap32(x)
#define htonl(x) bswap32(x)
#endif
#if defined(bswap64)
#undef ntohll
#undef htonll
#define ntohll(x) bswap64(x)
#define htonll(x) bswap64(x)
#else
#undef ntohll
#undef htonll
#if defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && defined(__BIG_ENDIAN)
# define GIT_BYTE_ORDER __BYTE_ORDER
# define GIT_LITTLE_ENDIAN __LITTLE_ENDIAN
# define GIT_BIG_ENDIAN __BIG_ENDIAN
#elif defined(BYTE_ORDER) && defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
# define GIT_BYTE_ORDER BYTE_ORDER
# define GIT_LITTLE_ENDIAN LITTLE_ENDIAN
# define GIT_BIG_ENDIAN BIG_ENDIAN
#else
# define GIT_BIG_ENDIAN 4321
# define GIT_LITTLE_ENDIAN 1234
# if defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)
# define GIT_BYTE_ORDER GIT_BIG_ENDIAN
# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
# define GIT_BYTE_ORDER GIT_LITTLE_ENDIAN
# elif defined(__THW_BIG_ENDIAN__) && !defined(__THW_LITTLE_ENDIAN__)
# define GIT_BYTE_ORDER GIT_BIG_ENDIAN
# elif defined(__THW_LITTLE_ENDIAN__) && !defined(__THW_BIG_ENDIAN__)
# define GIT_BYTE_ORDER GIT_LITTLE_ENDIAN
# else
# error "Cannot determine endianness"
# endif
#endif
#if GIT_BYTE_ORDER == GIT_BIG_ENDIAN
# define ntohll(n) (n)
# define htonll(n) (n)
#else
# define ntohll(n) default_bswap64(n)
# define htonll(n) default_bswap64(n)
#endif
#endif
/*
* Performance might be improved if the CPU architecture is OK with
* unaligned 32-bit loads and a fast ntohl() is available.
* Otherwise fall back to byte loads and shifts which is portable,
* and is faster on architectures with memory alignment issues.
*/
#if !defined(NO_UNALIGNED_LOADS) && ( \
defined(__i386__) || defined(__x86_64__) || \
defined(_M_IX86) || defined(_M_X64) || \
defined(__ppc__) || defined(__ppc64__) || \
defined(__powerpc__) || defined(__powerpc64__) || \
defined(__s390__) || defined(__s390x__))
#define get_be16(p) ntohs(*(unsigned short *)(p))
#define get_be32(p) ntohl(*(unsigned int *)(p))
#define put_be32(p, v) do { *(unsigned int *)(p) = htonl(v); } while (0)
#else
#define get_be16(p) ( \
(*((unsigned char *)(p) + 0) << 8) | \
(*((unsigned char *)(p) + 1) << 0) )
#define get_be32(p) ( \
(*((unsigned char *)(p) + 0) << 24) | \
(*((unsigned char *)(p) + 1) << 16) | \
(*((unsigned char *)(p) + 2) << 8) | \
(*((unsigned char *)(p) + 3) << 0) )
#define put_be32(p, v) do { \
unsigned int __v = (v); \
*((unsigned char *)(p) + 0) = __v >> 24; \
*((unsigned char *)(p) + 1) = __v >> 16; \
*((unsigned char *)(p) + 2) = __v >> 8; \
*((unsigned char *)(p) + 3) = __v >> 0; } while (0)
#endif

15
charset.txt Normal file
View file

@ -0,0 +1,15 @@
numeric = [0123456789]
alpha = [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
alpha-numeric = [ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]
loweralpha = [abcdefghijklmnopqrstuvwxyz]
loweralpha-numeric = [abcdefghijklmnopqrstuvwxyz0123456789]
mixalpha = [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]
mixalpha-numeric = [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]
ascii-32-95 = [ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~]
ascii-32-65-123-4 = [ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`{|}~]
alpha-numeric-symbol32-space = [ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_+=~`[]{}|\:;"'<>,.?/ ]

10
demo.sh Executable file
View file

@ -0,0 +1,10 @@
#!/bin/bash
# ./demo.sh <sha1 checksum>
# 00112233
pattern='hex:'
cd `dirname $0`
./rcrack . -h $1 | grep $pattern | awk -F $pattern '{print $2}'

20
generate-tables.sh Executable file
View file

@ -0,0 +1,20 @@
#!/bin/bash
# http://www.tobtu.com/rtcalc.php#params
# keyspace is 256^4 (length is always 4)
# 99.999999% (Total success rate)
./rtgen audible byte 4 4 0 10000 10008356 0
./rtgen audible byte 4 4 1 10000 10008356 0
./rtgen audible byte 4 4 2 10000 10008356 0
./rtgen audible byte 4 4 3 10000 10008356 0
./rtgen audible byte 4 4 4 10000 10008356 0
./rtgen audible byte 4 4 5 10000 10008356 0
./rtgen audible byte 4 4 6 10000 10008356 0
./rtgen audible byte 4 4 7 10000 10008356 0
./rtgen audible byte 4 4 8 10000 10008356 0
./rtgen audible byte 4 4 9 10000 10008356 0
# ./rtsort *.rt
# ./rt2rtc *.rt 21 24 -m 18 -p
# ./rt2rtc *.rt 25 25 -m 512 -p

BIN
rcrack Executable file

Binary file not shown.

BIN
run/alglib1.dll Normal file

Binary file not shown.

1
run/alglib1.dll.md5 Normal file
View file

@ -0,0 +1 @@
f0bb92cc20224fa806cd68d1bbd4fca4 alglib1.dll

15
run/charset.txt Normal file
View file

@ -0,0 +1,15 @@
numeric = [0123456789]
alpha = [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
alpha-numeric = [ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]
loweralpha = [abcdefghijklmnopqrstuvwxyz]
loweralpha-numeric = [abcdefghijklmnopqrstuvwxyz0123456789]
mixalpha = [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]
mixalpha-numeric = [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]
ascii-32-95 = [ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~]
ascii-32-65-123-4 = [ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`{|}~]
alpha-numeric-symbol32-space = [ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_+=~`[]{}|\:;"'<>,.?/ ]

BIN
run/rcrack.exe Normal file

Binary file not shown.

1
run/rcrack.exe.md5 Normal file
View file

@ -0,0 +1 @@
7a58ea0c818653a323345800d394dfc9 rcrack.exe

4
run/readme.txt Normal file
View file

@ -0,0 +1,4 @@
This folder contains a stripped down version of rainbowcrack-1.7-win64.zip
file.
Tested on CentOS 7 (with Wine from EPEL).

249
sha1.c Normal file
View file

@ -0,0 +1,249 @@
/*
* SHA1 routine optimized to do word accesses rather than byte accesses,
* and to avoid unnecessary copies into the context array.
*
* This was initially based on the Mozilla SHA1 implementation, although
* none of the original Mozilla code remains.
*/
/* this is only to get definitions for memcpy(), ntohl() and htonl() */
#include "sha1.h"
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
/*
* Force usage of rol or ror by selecting the one with the smaller constant.
* It _can_ generate slightly smaller code (a constant of 1 is special), but
* perhaps more importantly it's possibly faster on any uarch that does a
* rotate with a loop.
*/
#define SHA_ASM(op, x, n) ({ unsigned int __res; __asm__(op " %1,%0":"=r" (__res):"i" (n), "0" (x)); __res; })
#define SHA_ROL(x,n) SHA_ASM("rol", x, n)
#define SHA_ROR(x,n) SHA_ASM("ror", x, n)
#else
#define SHA_ROT(X,l,r) (((X) << (l)) | ((X) >> (r)))
#define SHA_ROL(X,n) SHA_ROT(X,n,32-(n))
#define SHA_ROR(X,n) SHA_ROT(X,32-(n),n)
#endif
/*
* If you have 32 registers or more, the compiler can (and should)
* try to change the array[] accesses into registers. However, on
* machines with less than ~25 registers, that won't really work,
* and at least gcc will make an unholy mess of it.
*
* So to avoid that mess which just slows things down, we force
* the stores to memory to actually happen (we might be better off
* with a 'W(t)=(val);asm("":"+m" (W(t))' there instead, as
* suggested by Artur Skawina - that will also make gcc unable to
* try to do the silly "optimize away loads" part because it won't
* see what the value will be).
*
* Ben Herrenschmidt reports that on PPC, the C version comes close
* to the optimized asm with this (ie on PPC you don't want that
* 'volatile', since there are lots of registers).
*
* On ARM we get the best code generation by forcing a full memory barrier
* between each SHA_ROUND, otherwise gcc happily get wild with spilling and
* the stack frame size simply explode and performance goes down the drain.
*/
#if defined(__i386__) || defined(__x86_64__)
#define setW(x, val) (*(volatile unsigned int *)&W(x) = (val))
#elif defined(__GNUC__) && defined(__arm__)
#define setW(x, val) do { W(x) = (val); __asm__("":::"memory"); } while (0)
#else
#define setW(x, val) (W(x) = (val))
#endif
/* This "rolls" over the 512-bit array */
#define W(x) (array[(x)&15])
/*
* Where do we get the source from? The first 16 iterations get it from
* the input data, the next mix it from the 512-bit array.
*/
#define SHA_SRC(t) get_be32((unsigned char *) block + (t)*4)
#define SHA_MIX(t) SHA_ROL(W((t)+13) ^ W((t)+8) ^ W((t)+2) ^ W(t), 1);
#define SHA_ROUND(t, input, fn, constant, A, B, C, D, E) do { \
unsigned int TEMP = input(t); setW(t, TEMP); \
E += TEMP + SHA_ROL(A,5) + (fn) + (constant); \
B = SHA_ROR(B, 2); } while (0)
#define T_0_15(t, A, B, C, D, E) SHA_ROUND(t, SHA_SRC, (((C^D)&B)^D) , 0x5a827999, A, B, C, D, E )
#define T_16_19(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (((C^D)&B)^D) , 0x5a827999, A, B, C, D, E )
#define T_20_39(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B^C^D) , 0x6ed9eba1, A, B, C, D, E )
#define T_40_59(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, ((B&C)+(D&(B^C))) , 0x8f1bbcdc, A, B, C, D, E )
#define T_60_79(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B^C^D) , 0xca62c1d6, A, B, C, D, E )
static void blk_SHA1_Block(blk_SHA_CTX *ctx, const void *block)
{
unsigned int A,B,C,D,E;
unsigned int array[16];
A = ctx->H[0];
B = ctx->H[1];
C = ctx->H[2];
D = ctx->H[3];
E = ctx->H[4];
/* Round 1 - iterations 0-16 take their input from 'block' */
T_0_15( 0, A, B, C, D, E);
T_0_15( 1, E, A, B, C, D);
T_0_15( 2, D, E, A, B, C);
T_0_15( 3, C, D, E, A, B);
T_0_15( 4, B, C, D, E, A);
T_0_15( 5, A, B, C, D, E);
T_0_15( 6, E, A, B, C, D);
T_0_15( 7, D, E, A, B, C);
T_0_15( 8, C, D, E, A, B);
T_0_15( 9, B, C, D, E, A);
T_0_15(10, A, B, C, D, E);
T_0_15(11, E, A, B, C, D);
T_0_15(12, D, E, A, B, C);
T_0_15(13, C, D, E, A, B);
T_0_15(14, B, C, D, E, A);
T_0_15(15, A, B, C, D, E);
/* Round 1 - tail. Input from 512-bit mixing array */
T_16_19(16, E, A, B, C, D);
T_16_19(17, D, E, A, B, C);
T_16_19(18, C, D, E, A, B);
T_16_19(19, B, C, D, E, A);
/* Round 2 */
T_20_39(20, A, B, C, D, E);
T_20_39(21, E, A, B, C, D);
T_20_39(22, D, E, A, B, C);
T_20_39(23, C, D, E, A, B);
T_20_39(24, B, C, D, E, A);
T_20_39(25, A, B, C, D, E);
T_20_39(26, E, A, B, C, D);
T_20_39(27, D, E, A, B, C);
T_20_39(28, C, D, E, A, B);
T_20_39(29, B, C, D, E, A);
T_20_39(30, A, B, C, D, E);
T_20_39(31, E, A, B, C, D);
T_20_39(32, D, E, A, B, C);
T_20_39(33, C, D, E, A, B);
T_20_39(34, B, C, D, E, A);
T_20_39(35, A, B, C, D, E);
T_20_39(36, E, A, B, C, D);
T_20_39(37, D, E, A, B, C);
T_20_39(38, C, D, E, A, B);
T_20_39(39, B, C, D, E, A);
/* Round 3 */
T_40_59(40, A, B, C, D, E);
T_40_59(41, E, A, B, C, D);
T_40_59(42, D, E, A, B, C);
T_40_59(43, C, D, E, A, B);
T_40_59(44, B, C, D, E, A);
T_40_59(45, A, B, C, D, E);
T_40_59(46, E, A, B, C, D);
T_40_59(47, D, E, A, B, C);
T_40_59(48, C, D, E, A, B);
T_40_59(49, B, C, D, E, A);
T_40_59(50, A, B, C, D, E);
T_40_59(51, E, A, B, C, D);
T_40_59(52, D, E, A, B, C);
T_40_59(53, C, D, E, A, B);
T_40_59(54, B, C, D, E, A);
T_40_59(55, A, B, C, D, E);
T_40_59(56, E, A, B, C, D);
T_40_59(57, D, E, A, B, C);
T_40_59(58, C, D, E, A, B);
T_40_59(59, B, C, D, E, A);
/* Round 4 */
T_60_79(60, A, B, C, D, E);
T_60_79(61, E, A, B, C, D);
T_60_79(62, D, E, A, B, C);
T_60_79(63, C, D, E, A, B);
T_60_79(64, B, C, D, E, A);
T_60_79(65, A, B, C, D, E);
T_60_79(66, E, A, B, C, D);
T_60_79(67, D, E, A, B, C);
T_60_79(68, C, D, E, A, B);
T_60_79(69, B, C, D, E, A);
T_60_79(70, A, B, C, D, E);
T_60_79(71, E, A, B, C, D);
T_60_79(72, D, E, A, B, C);
T_60_79(73, C, D, E, A, B);
T_60_79(74, B, C, D, E, A);
T_60_79(75, A, B, C, D, E);
T_60_79(76, E, A, B, C, D);
T_60_79(77, D, E, A, B, C);
T_60_79(78, C, D, E, A, B);
T_60_79(79, B, C, D, E, A);
ctx->H[0] += A;
ctx->H[1] += B;
ctx->H[2] += C;
ctx->H[3] += D;
ctx->H[4] += E;
}
void blk_SHA1_Init(blk_SHA_CTX *ctx)
{
ctx->size = 0;
/* Initialize H with the magic constants (see FIPS180 for constants) */
ctx->H[0] = 0x67452301;
ctx->H[1] = 0xefcdab89;
ctx->H[2] = 0x98badcfe;
ctx->H[3] = 0x10325476;
ctx->H[4] = 0xc3d2e1f0;
}
void blk_SHA1_Update(blk_SHA_CTX *ctx, const void *data, unsigned long len)
{
unsigned int lenW = ctx->size & 63;
ctx->size += len;
/* Read the data into W and process blocks as they get full */
if (lenW) {
unsigned int left = 64 - lenW;
if (len < left)
left = len;
memcpy(lenW + (char *)ctx->W, data, left);
lenW = (lenW + left) & 63;
len -= left;
data = ((const char *)data + left);
if (lenW)
return;
blk_SHA1_Block(ctx, ctx->W);
}
while (len >= 64) {
blk_SHA1_Block(ctx, data);
data = ((const char *)data + 64);
len -= 64;
}
if (len)
memcpy(ctx->W, data, len);
}
void blk_SHA1_Final(unsigned char hashout[20], blk_SHA_CTX *ctx)
{
static const unsigned char pad[64] = { 0x80 };
unsigned int padlen[2];
int i;
/* Pad with a binary 1 (ie 0x80), then zeroes, then length */
padlen[0] = htonl((uint32_t)(ctx->size >> 29));
padlen[1] = htonl((uint32_t)(ctx->size << 3));
i = ctx->size & 63;
blk_SHA1_Update(ctx, pad, 1 + (63 & (55 - i)));
blk_SHA1_Update(ctx, padlen, 8);
/* Output hash */
for (i = 0; i < 5; i++)
put_be32(hashout + i * 4, ctx->H[i]);
}

32
sha1.h Normal file
View file

@ -0,0 +1,32 @@
/*
* SHA1 routine optimized to do word accesses rather than byte accesses,
* and to avoid unnecessary copies into the context array.
*
* This was initially based on the Mozilla SHA1 implementation, although
* none of the original Mozilla code remains.
*/
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include "bswap.h"
typedef struct {
unsigned long long size;
unsigned int H[5];
unsigned int W[16];
} blk_SHA_CTX;
void blk_SHA1_Init(blk_SHA_CTX *ctx);
void blk_SHA1_Update(blk_SHA_CTX *ctx, const void *dataIn, unsigned long len);
void blk_SHA1_Final(unsigned char hashout[20], blk_SHA_CTX *ctx);
#define platform_SHA_CTX blk_SHA_CTX
#define platform_SHA1_Init blk_SHA1_Init
#define platform_SHA1_Update blk_SHA1_Update
#define platform_SHA1_Final blk_SHA1_Final
#define SHA_CTX blk_SHA_CTX
#define SHA1_Init blk_SHA1_Init
#define SHA1_Update blk_SHA1_Update
#define SHA1_Final blk_SHA1_Final