diff --git a/src/Mayaqua/Encrypt.c b/src/Mayaqua/Encrypt.c index b59ff886..4a640d87 100644 --- a/src/Mayaqua/Encrypt.c +++ b/src/Mayaqua/Encrypt.c @@ -4516,308 +4516,144 @@ final: ///////////////////////// // SHA0 implementation // ///////////////////////// -// -// From: https://bitbucket.org/Polarina/ampheck/src/097585ce2a74/src/ + +// Source codes from: +// https://android.googlesource.com/platform/system/core/+/81df1cc77722000f8d0025c1ab00ced123aa573c/libmincrypt/sha.c +// https://android.googlesource.com/platform/system/core/+/81df1cc77722000f8d0025c1ab00ced123aa573c/include/mincrypt/hash-internal.h +// https://android.googlesource.com/platform/system/core/+/81df1cc77722000f8d0025c1ab00ced123aa573c/include/mincrypt/sha.h + /* - Copyright (C) 2009 Gabriel A. Petursson - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ + * Copyright 2013 The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Google Inc. nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ -struct ampheck_sha0 -{ - UINT h[5]; - UCHAR buffer[64]; - UINT64 length; -}; -#define ROR(x, y) (((x) >> (y)) ^ ((x) << ((sizeof(x) * 8) - (y)))) -#define ROL(x, y) (((x) << (y)) ^ ((x) >> ((sizeof(x) * 8) - (y)))) -#define UNPACK_32_BE(x, str) { \ - *((str)) = (UCHAR) ((x) >> 24); \ - *((str) + 1) = (UCHAR) ((x) >> 16); \ - *((str) + 2) = (UCHAR) ((x) >> 8); \ - *((str) + 3) = (UCHAR) (x); \ -} -#define UNPACK_64_BE(x, str) { \ - *((str)) = (UCHAR) ((x) >> 56); \ - *((str) + 1) = (UCHAR) ((x) >> 48); \ - *((str) + 2) = (UCHAR) ((x) >> 40); \ - *((str) + 3) = (UCHAR) ((x) >> 32); \ - *((str) + 4) = (UCHAR) ((x) >> 24); \ - *((str) + 5) = (UCHAR) ((x) >> 16); \ - *((str) + 6) = (UCHAR) ((x) >> 8); \ - *((str) + 7) = (UCHAR) (x); \ -} -#define PACK_32_BE(str, x) { \ - *(x) = ((UINT) *((str) ) << 24) \ - ^ ((UINT) *((str) + 1) << 16) \ - ^ ((UINT) *((str) + 2) << 8) \ - ^ ((UINT) *((str) + 3)); \ -} -#define PACK_64_BE(str, x) { \ - *(x) = ((UINT64) *((str) ) << 56) \ - ^ ((UINT64) *((str) + 1) << 48) \ - ^ ((UINT64) *((str) + 2) << 40) \ - ^ ((UINT64) *((str) + 3) << 32) \ - ^ ((UINT64) *((str) + 4) << 24) \ - ^ ((UINT64) *((str) + 5) << 16) \ - ^ ((UINT64) *((str) + 6) << 8) \ - ^ ((UINT64) *((str) + 7)); \ -} -#define UNPACK_32_LE(x, str) { \ - *((str)) = (UCHAR) (x); \ - *((str) + 1) = (UCHAR) ((x) >> 8); \ - *((str) + 2) = (UCHAR) ((x) >> 16); \ - *((str) + 3) = (UCHAR) ((x) >> 24); \ -} -#define UNPACK_64_LE(x, str) { \ - *((str)) = (UCHAR) (x); \ - *((str) + 1) = (UCHAR) ((x) >> 8); \ - *((str) + 2) = (UCHAR) ((x) >> 16); \ - *((str) + 3) = (UCHAR) ((x) >> 24); \ - *((str) + 4) = (UCHAR) ((x) >> 32); \ - *((str) + 5) = (UCHAR) ((x) >> 40); \ - *((str) + 6) = (UCHAR) ((x) >> 48); \ - *((str) + 7) = (UCHAR) ((x) >> 56); \ -} -#define PACK_32_LE(str, x) { \ - *(x) = ((UINT) *((str) )) \ - ^ ((UINT) *((str) + 1) << 8) \ - ^ ((UINT) *((str) + 2) << 16) \ - ^ ((UINT) *((str) + 3) << 24); \ -} -#define PACK_64_LE(str, x) { \ - *(x) = ((UINT64) *((str) )) \ - ^ ((UINT64) *((str) + 1) << 8) \ - ^ ((UINT64) *((str) + 2) << 16) \ - ^ ((UINT64) *((str) + 3) << 24) \ - ^ ((UINT64) *((str) + 4) << 32) \ - ^ ((UINT64) *((str) + 5) << 40) \ - ^ ((UINT64) *((str) + 6) << 48) \ - ^ ((UINT64) *((str) + 7) << 56); \ -} -#define SHA0_R1(x, y, z) ((z ^ (x & (y ^ z))) + 0x5a827999) -#define SHA0_R2(x, y, z) ((x ^ y ^ z) + 0x6ed9eba1) -#define SHA0_R3(x, y, z) (((x & y) | (z & (x | y))) + 0x8f1bbcdc) -#define SHA0_R4(x, y, z) ((x ^ y ^ z) + 0xca62c1d6) -#define SHA0_PRC(a, b, c, d, e, idx, rnd) { \ - wv[e] += ROR(wv[a], 27) + SHA0_R##rnd(wv[b], wv[c], wv[d]) + idx; \ - wv[b] = ROR(wv[b], 2); \ -} -#define SHA0_EXT(i) ( \ - w[i] ^= w[(i - 3) & 0x0F] ^ w[(i - 8) & 0x0F] ^ w[(i - 14) & 0x0F] \ - ) -static void ampheck_sha0_init(struct ampheck_sha0 *ctx); -static void ampheck_sha0_update(struct ampheck_sha0 *ctx, const UCHAR *data, UINT length); -static void ampheck_sha0_finish(const struct ampheck_sha0 *ctx, UCHAR *digest); -static void ampheck_sha0_init(struct ampheck_sha0 *ctx) -{ - ctx->h[0] = 0x67452301; - ctx->h[1] = 0xefcdab89; - ctx->h[2] = 0x98badcfe; - ctx->h[3] = 0x10325476; - ctx->h[4] = 0xc3d2e1f0; - ctx->length = 0; +#define rol(bits, value) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +typedef struct MY_SHA0_CTX { +// const HASH_VTAB * f; + UINT64 count; + UCHAR buf[64]; + UINT state[8]; // upto SHA2 +} MY_SHA0_CTX; + +#define MY_SHA0_DIGEST_SIZE 20 + +static void MY_SHA0_Transform(MY_SHA0_CTX* ctx) { + UINT W[80]; + UINT A, B, C, D, E; + UCHAR* p = ctx->buf; + int t; + for(t = 0; t < 16; ++t) { + UINT tmp = *p++ << 24; + tmp |= *p++ << 16; + tmp |= *p++ << 8; + tmp |= *p++; + W[t] = tmp; + } + for(; t < 80; t++) { + //W[t] = rol(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); + W[t] = (1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); + } + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + E = ctx->state[4]; + for(t = 0; t < 80; t++) { + UINT tmp = rol(5,A) + E + W[t]; + if (t < 20) + tmp += (D^(B&(C^D))) + 0x5A827999; + else if ( t < 40) + tmp += (B^C^D) + 0x6ED9EBA1; + else if ( t < 60) + tmp += ((B&C)|(D&(B|C))) + 0x8F1BBCDC; + else + tmp += (B^C^D) + 0xCA62C1D6; + E = D; + D = C; + C = rol(30,B); + B = A; + A = tmp; + } + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; + ctx->state[4] += E; } - -static void ampheck_sha0_transform(struct ampheck_sha0 *ctx, const UCHAR *data, UINT blocks) -{ - UINT i; - for (i = 0; i < blocks; ++i) - { - UINT wv[5]; - UINT w[16]; - - PACK_32_BE(&data[(i << 6) ], &w[ 0]); - PACK_32_BE(&data[(i << 6) + 4], &w[ 1]); - PACK_32_BE(&data[(i << 6) + 8], &w[ 2]); - PACK_32_BE(&data[(i << 6) + 12], &w[ 3]); - PACK_32_BE(&data[(i << 6) + 16], &w[ 4]); - PACK_32_BE(&data[(i << 6) + 20], &w[ 5]); - PACK_32_BE(&data[(i << 6) + 24], &w[ 6]); - PACK_32_BE(&data[(i << 6) + 28], &w[ 7]); - PACK_32_BE(&data[(i << 6) + 32], &w[ 8]); - PACK_32_BE(&data[(i << 6) + 36], &w[ 9]); - PACK_32_BE(&data[(i << 6) + 40], &w[10]); - PACK_32_BE(&data[(i << 6) + 44], &w[11]); - PACK_32_BE(&data[(i << 6) + 48], &w[12]); - PACK_32_BE(&data[(i << 6) + 52], &w[13]); - PACK_32_BE(&data[(i << 6) + 56], &w[14]); - PACK_32_BE(&data[(i << 6) + 60], &w[15]); - - wv[0] = ctx->h[0]; - wv[1] = ctx->h[1]; - wv[2] = ctx->h[2]; - wv[3] = ctx->h[3]; - wv[4] = ctx->h[4]; - - SHA0_PRC(0, 1, 2, 3, 4, w[ 0], 1); - SHA0_PRC(4, 0, 1, 2, 3, w[ 1], 1); - SHA0_PRC(3, 4, 0, 1, 2, w[ 2], 1); - SHA0_PRC(2, 3, 4, 0, 1, w[ 3], 1); - SHA0_PRC(1, 2, 3, 4, 0, w[ 4], 1); - SHA0_PRC(0, 1, 2, 3, 4, w[ 5], 1); - SHA0_PRC(4, 0, 1, 2, 3, w[ 6], 1); - SHA0_PRC(3, 4, 0, 1, 2, w[ 7], 1); - SHA0_PRC(2, 3, 4, 0, 1, w[ 8], 1); - SHA0_PRC(1, 2, 3, 4, 0, w[ 9], 1); - SHA0_PRC(0, 1, 2, 3, 4, w[10], 1); - SHA0_PRC(4, 0, 1, 2, 3, w[11], 1); - SHA0_PRC(3, 4, 0, 1, 2, w[12], 1); - SHA0_PRC(2, 3, 4, 0, 1, w[13], 1); - SHA0_PRC(1, 2, 3, 4, 0, w[14], 1); - SHA0_PRC(0, 1, 2, 3, 4, w[15], 1); - SHA0_PRC(4, 0, 1, 2, 3, SHA0_EXT( 0), 1); - SHA0_PRC(3, 4, 0, 1, 2, SHA0_EXT( 1), 1); - SHA0_PRC(2, 3, 4, 0, 1, SHA0_EXT( 2), 1); - SHA0_PRC(1, 2, 3, 4, 0, SHA0_EXT( 3), 1); - - SHA0_PRC(0, 1, 2, 3, 4, SHA0_EXT( 4), 2); - SHA0_PRC(4, 0, 1, 2, 3, SHA0_EXT( 5), 2); - SHA0_PRC(3, 4, 0, 1, 2, SHA0_EXT( 6), 2); - SHA0_PRC(2, 3, 4, 0, 1, SHA0_EXT( 7), 2); - SHA0_PRC(1, 2, 3, 4, 0, SHA0_EXT( 8), 2); - SHA0_PRC(0, 1, 2, 3, 4, SHA0_EXT( 9), 2); - SHA0_PRC(4, 0, 1, 2, 3, SHA0_EXT(10), 2); - SHA0_PRC(3, 4, 0, 1, 2, SHA0_EXT(11), 2); - SHA0_PRC(2, 3, 4, 0, 1, SHA0_EXT(12), 2); - SHA0_PRC(1, 2, 3, 4, 0, SHA0_EXT(13), 2); - SHA0_PRC(0, 1, 2, 3, 4, SHA0_EXT(14), 2); - SHA0_PRC(4, 0, 1, 2, 3, SHA0_EXT(15), 2); - SHA0_PRC(3, 4, 0, 1, 2, SHA0_EXT( 0), 2); - SHA0_PRC(2, 3, 4, 0, 1, SHA0_EXT( 1), 2); - SHA0_PRC(1, 2, 3, 4, 0, SHA0_EXT( 2), 2); - SHA0_PRC(0, 1, 2, 3, 4, SHA0_EXT( 3), 2); - SHA0_PRC(4, 0, 1, 2, 3, SHA0_EXT( 4), 2); - SHA0_PRC(3, 4, 0, 1, 2, SHA0_EXT( 5), 2); - SHA0_PRC(2, 3, 4, 0, 1, SHA0_EXT( 6), 2); - SHA0_PRC(1, 2, 3, 4, 0, SHA0_EXT( 7), 2); - - SHA0_PRC(0, 1, 2, 3, 4, SHA0_EXT( 8), 3); - SHA0_PRC(4, 0, 1, 2, 3, SHA0_EXT( 9), 3); - SHA0_PRC(3, 4, 0, 1, 2, SHA0_EXT(10), 3); - SHA0_PRC(2, 3, 4, 0, 1, SHA0_EXT(11), 3); - SHA0_PRC(1, 2, 3, 4, 0, SHA0_EXT(12), 3); - SHA0_PRC(0, 1, 2, 3, 4, SHA0_EXT(13), 3); - SHA0_PRC(4, 0, 1, 2, 3, SHA0_EXT(14), 3); - SHA0_PRC(3, 4, 0, 1, 2, SHA0_EXT(15), 3); - SHA0_PRC(2, 3, 4, 0, 1, SHA0_EXT( 0), 3); - SHA0_PRC(1, 2, 3, 4, 0, SHA0_EXT( 1), 3); - SHA0_PRC(0, 1, 2, 3, 4, SHA0_EXT( 2), 3); - SHA0_PRC(4, 0, 1, 2, 3, SHA0_EXT( 3), 3); - SHA0_PRC(3, 4, 0, 1, 2, SHA0_EXT( 4), 3); - SHA0_PRC(2, 3, 4, 0, 1, SHA0_EXT( 5), 3); - SHA0_PRC(1, 2, 3, 4, 0, SHA0_EXT( 6), 3); - SHA0_PRC(0, 1, 2, 3, 4, SHA0_EXT( 7), 3); - SHA0_PRC(4, 0, 1, 2, 3, SHA0_EXT( 8), 3); - SHA0_PRC(3, 4, 0, 1, 2, SHA0_EXT( 9), 3); - SHA0_PRC(2, 3, 4, 0, 1, SHA0_EXT(10), 3); - SHA0_PRC(1, 2, 3, 4, 0, SHA0_EXT(11), 3); - - SHA0_PRC(0, 1, 2, 3, 4, SHA0_EXT(12), 4); - SHA0_PRC(4, 0, 1, 2, 3, SHA0_EXT(13), 4); - SHA0_PRC(3, 4, 0, 1, 2, SHA0_EXT(14), 4); - SHA0_PRC(2, 3, 4, 0, 1, SHA0_EXT(15), 4); - SHA0_PRC(1, 2, 3, 4, 0, SHA0_EXT( 0), 4); - SHA0_PRC(0, 1, 2, 3, 4, SHA0_EXT( 1), 4); - SHA0_PRC(4, 0, 1, 2, 3, SHA0_EXT( 2), 4); - SHA0_PRC(3, 4, 0, 1, 2, SHA0_EXT( 3), 4); - SHA0_PRC(2, 3, 4, 0, 1, SHA0_EXT( 4), 4); - SHA0_PRC(1, 2, 3, 4, 0, SHA0_EXT( 5), 4); - SHA0_PRC(0, 1, 2, 3, 4, SHA0_EXT( 6), 4); - SHA0_PRC(4, 0, 1, 2, 3, SHA0_EXT( 7), 4); - SHA0_PRC(3, 4, 0, 1, 2, SHA0_EXT( 8), 4); - SHA0_PRC(2, 3, 4, 0, 1, SHA0_EXT( 9), 4); - SHA0_PRC(1, 2, 3, 4, 0, SHA0_EXT(10), 4); - SHA0_PRC(0, 1, 2, 3, 4, SHA0_EXT(11), 4); - SHA0_PRC(4, 0, 1, 2, 3, SHA0_EXT(12), 4); - SHA0_PRC(3, 4, 0, 1, 2, SHA0_EXT(13), 4); - SHA0_PRC(2, 3, 4, 0, 1, SHA0_EXT(14), 4); - SHA0_PRC(1, 2, 3, 4, 0, SHA0_EXT(15), 4); - - ctx->h[0] += wv[0]; - ctx->h[1] += wv[1]; - ctx->h[2] += wv[2]; - ctx->h[3] += wv[3]; - ctx->h[4] += wv[4]; +void MY_SHA0_init(MY_SHA0_CTX* ctx) { + //ctx->f = &SHA_VTAB; + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0xC3D2E1F0; + ctx->count = 0; +} +void MY_SHA0_update(MY_SHA0_CTX* ctx, const void* data, int len) { + int i = (int) (ctx->count & 63); + const UCHAR* p = (const UCHAR*)data; + ctx->count += len; + while (len--) { + ctx->buf[i++] = *p++; + if (i == 64) { + MY_SHA0_Transform(ctx); + i = 0; + } } } - -static void ampheck_sha0_update(struct ampheck_sha0 *ctx, const UCHAR *data, UINT size) -{ - UINT tmp = size; - - if (size >= 64 - ctx->length % 64) - { - memcpy(&ctx->buffer[ctx->length % 64], data, 64 - ctx->length % 64); - - data += 64 - ctx->length % 64; - size -= 64 - ctx->length % 64; - - ampheck_sha0_transform(ctx, ctx->buffer, 1); - ampheck_sha0_transform(ctx, data, size / 64); - - data += size & ~63; - size %= 64; - - memcpy(ctx->buffer, data, size); +const UCHAR* MY_SHA0_final(MY_SHA0_CTX* ctx) { + UCHAR *p = ctx->buf; + UINT64 cnt = ctx->count * 8; + int i; + MY_SHA0_update(ctx, (UCHAR*)"\x80", 1); + while ((ctx->count & 63) != 56) { + MY_SHA0_update(ctx, (UCHAR*)"\0", 1); } - else - { - memcpy(&ctx->buffer[ctx->length % 64], data, size); + for (i = 0; i < 8; ++i) { + UCHAR tmp = (UCHAR) (cnt >> ((7 - i) * 8)); + MY_SHA0_update(ctx, &tmp, 1); } - - ctx->length += tmp; + for (i = 0; i < 5; i++) { + UINT tmp = ctx->state[i]; + *p++ = tmp >> 24; + *p++ = tmp >> 16; + *p++ = tmp >> 8; + *p++ = tmp >> 0; + } + return ctx->buf; } - -static void ampheck_sha0_finish(const struct ampheck_sha0 *ctx, UCHAR *digest) -{ - struct ampheck_sha0 tmp; - - memcpy(tmp.h, ctx->h, 5 * sizeof(UINT)); - memcpy(tmp.buffer, ctx->buffer, ctx->length % 64); - - tmp.buffer[ctx->length % 64] = 0x80; - - if (ctx->length % 64 < 56) - { - memset(&tmp.buffer[ctx->length % 64 + 1], 0x00, 55 - ctx->length % 64); - } - else - { - memset(&tmp.buffer[ctx->length % 64 + 1], 0x00, 63 - ctx->length % 64); - ampheck_sha0_transform(&tmp, tmp.buffer, 1); - - memset(tmp.buffer, 0x00, 56); - } - - UNPACK_64_BE(ctx->length * 8, &tmp.buffer[56]); - ampheck_sha0_transform(&tmp, tmp.buffer, 1); - - UNPACK_32_BE(tmp.h[0], &digest[ 0]); - UNPACK_32_BE(tmp.h[1], &digest[ 4]); - UNPACK_32_BE(tmp.h[2], &digest[ 8]); - UNPACK_32_BE(tmp.h[3], &digest[12]); - UNPACK_32_BE(tmp.h[4], &digest[16]); +/* Convenience function */ +const UCHAR* MY_SHA0_hash(const void* data, int len, UCHAR* digest) { + MY_SHA0_CTX ctx; + MY_SHA0_init(&ctx); + MY_SHA0_update(&ctx, data, len); + memcpy(digest, MY_SHA0_final(&ctx), MY_SHA0_DIGEST_SIZE); + return digest; } - static void Internal_Sha0(unsigned char *dest, const unsigned char *src, const UINT size) { - struct ampheck_sha0 c; - - ampheck_sha0_init(&c); - ampheck_sha0_update(&c, src, size); - ampheck_sha0_finish(&c, dest); + MY_SHA0_hash(src, (int)size, dest); }