From b9d88acdc02a191efafbf74ab201f0de84fe1c67 Mon Sep 17 00:00:00 2001 From: Dees_Troy Date: Fri, 14 Sep 2012 14:34:19 -0400 Subject: Move to shared libmincrypt Remove mincrypt source from TWRP and add rule to make libmincrypt as a shared library. No more crashes during zip signature verification and less code to maintain in TWRP. --- Android.mk | 8 +- prebuilt/Android.mk | 1 + twinstall.cpp | 165 +-------------------------- twmincrypt/Android.mk | 11 ++ twmincrypt/twrsa.c | 199 -------------------------------- twmincrypt/twrsa.h | 56 --------- twmincrypt/twsha.c | 307 -------------------------------------------------- twmincrypt/twsha.h | 63 ----------- 8 files changed, 19 insertions(+), 791 deletions(-) create mode 100644 twmincrypt/Android.mk delete mode 100644 twmincrypt/twrsa.c delete mode 100644 twmincrypt/twrsa.h delete mode 100644 twmincrypt/twsha.c delete mode 100644 twmincrypt/twsha.h diff --git a/Android.mk b/Android.mk index 6c6ee9b28..304e60727 100644 --- a/Android.mk +++ b/Android.mk @@ -37,8 +37,6 @@ LOCAL_SRC_FILES += \ partitionmanager.cpp \ mtdutils/mtdutils.c \ twinstall.cpp \ - twmincrypt/twrsa.c \ - twmincrypt/twsha.c \ twrp-functions.cpp ifeq ($(TARGET_RECOVERY_REBOOT_SRC),) @@ -70,7 +68,7 @@ LOCAL_SHARED_LIBRARIES := LOCAL_STATIC_LIBRARIES += libmtdutils LOCAL_STATIC_LIBRARIES += libext4_utils libminadbd libminzip libunz LOCAL_STATIC_LIBRARIES += libminuitwrp libpixelflinger_static libpng libjpegtwrp libgui -LOCAL_SHARED_LIBRARIES += libz libc libstlport libcutils libstdc++ +LOCAL_SHARED_LIBRARIES += libz libc libstlport libcutils libstdc++ libmincrypt ifeq ($(TARGET_USERIMAGES_USE_EXT4), true) LOCAL_CFLAGS += -DUSE_EXT4 @@ -254,7 +252,9 @@ include $(commands_recovery_local_path)/libjpegtwrp/Android.mk \ $(commands_recovery_local_path)/mtdutils/Android.mk \ $(commands_recovery_local_path)/pigz/Android.mk \ $(commands_recovery_local_path)/crypto/cryptsettings/Android.mk \ - $(commands_recovery_local_path)/libcrecovery/Android.mk + $(commands_recovery_local_path)/libcrecovery/Android.mk \ + $(commands_recovery_local_path)/twmincrypt/Android.mk + ifeq ($(TW_INCLUDE_JB_CRYPTO), true) include $(commands_recovery_local_path)/crypto/fs_mgr/Android.mk diff --git a/prebuilt/Android.mk b/prebuilt/Android.mk index 58268f992..17e2d4aca 100644 --- a/prebuilt/Android.mk +++ b/prebuilt/Android.mk @@ -38,6 +38,7 @@ RELINK_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libmmcutils.so RELINK_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libbmlutils.so RELINK_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libflashutils.so RELINK_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libstlport.so +RELINK_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libmincrypt.so ifeq ($(TW_INCLUDE_BLOBPACK), true) RELINK_SOURCE_FILES += $(TARGET_RECOVERY_ROOT_OUT)/sbin/blobpack endif diff --git a/twinstall.cpp b/twinstall.cpp index 967528e27..af5325698 100644 --- a/twinstall.cpp +++ b/twinstall.cpp @@ -26,8 +26,8 @@ #include #include "common.h" -#include "twmincrypt/twrsa.h" -#include "twmincrypt/twsha.h" +#include "mincrypt/rsa.h" +#include "mincrypt/sha.h" #include "minui/minui.h" #include "minzip/SysUtil.h" #include "minzip/Zip.h" @@ -59,165 +59,6 @@ static const float DEFAULT_IMAGE_PROGRESS_FRACTION = 0.1; enum { INSTALL_SUCCESS, INSTALL_ERROR, INSTALL_CORRUPT }; -// Look for an RSA signature embedded in the .ZIP file comment given -// the path to the zip. Verify it matches one of the given public -// keys. -// -// Return VERIFY_SUCCESS, VERIFY_FAILURE (if any error is encountered -// or no key matches the signature). - -int TWverify_file(const char* path, const RSAPublicKey *pKeys, unsigned int numKeys) { - ui->SetProgress(0.0); - - FILE* f = fopen(path, "rb"); - if (f == NULL) { - LOGE("failed to open %s (%s)\n", path, strerror(errno)); - return VERIFY_FAILURE; - } - - // An archive with a whole-file signature will end in six bytes: - // - // (2-byte signature start) $ff $ff (2-byte comment size) - // - // (As far as the ZIP format is concerned, these are part of the - // archive comment.) We start by reading this footer, this tells - // us how far back from the end we have to start reading to find - // the whole comment. - -#define FOOTER_SIZE 6 - - if (fseek(f, -FOOTER_SIZE, SEEK_END) != 0) { - LOGE("failed to seek in %s (%s)\n", path, strerror(errno)); - fclose(f); - return VERIFY_FAILURE; - } - - unsigned char footer[FOOTER_SIZE]; - if (fread(footer, 1, FOOTER_SIZE, f) != FOOTER_SIZE) { - LOGE("failed to read footer from %s (%s)\n", path, strerror(errno)); - fclose(f); - return VERIFY_FAILURE; - } - - if (footer[2] != 0xff || footer[3] != 0xff) { - fclose(f); - return VERIFY_FAILURE; - } - - size_t comment_size = footer[4] + (footer[5] << 8); - size_t signature_start = footer[0] + (footer[1] << 8); - LOGI("comment is %d bytes; signature %d bytes from end\n", - comment_size, signature_start); - - if (signature_start - FOOTER_SIZE < RSANUMBYTES) { - // "signature" block isn't big enough to contain an RSA block. - LOGE("signature is too short\n"); - fclose(f); - return VERIFY_FAILURE; - } - -#define EOCD_HEADER_SIZE 22 - - // The end-of-central-directory record is 22 bytes plus any - // comment length. - size_t eocd_size = comment_size + EOCD_HEADER_SIZE; - - if (fseek(f, -eocd_size, SEEK_END) != 0) { - LOGE("failed to seek in %s (%s)\n", path, strerror(errno)); - fclose(f); - return VERIFY_FAILURE; - } - - // Determine how much of the file is covered by the signature. - // This is everything except the signature data and length, which - // includes all of the EOCD except for the comment length field (2 - // bytes) and the comment data. - size_t signed_len = ftell(f) + EOCD_HEADER_SIZE - 2; - - unsigned char* eocd = (unsigned char*)malloc(eocd_size); - if (eocd == NULL) { - LOGE("malloc for EOCD record failed\n"); - fclose(f); - return VERIFY_FAILURE; - } - if (fread(eocd, 1, eocd_size, f) != eocd_size) { - LOGE("failed to read eocd from %s (%s)\n", path, strerror(errno)); - fclose(f); - return VERIFY_FAILURE; - } - - // If this is really is the EOCD record, it will begin with the - // magic number $50 $4b $05 $06. - if (eocd[0] != 0x50 || eocd[1] != 0x4b || - eocd[2] != 0x05 || eocd[3] != 0x06) { - LOGE("signature length doesn't match EOCD marker\n"); - fclose(f); - return VERIFY_FAILURE; - } - - size_t i; - for (i = 4; i < eocd_size-3; ++i) { - if (eocd[i ] == 0x50 && eocd[i+1] == 0x4b && - eocd[i+2] == 0x05 && eocd[i+3] == 0x06) { - // if the sequence $50 $4b $05 $06 appears anywhere after - // the real one, minzip will find the later (wrong) one, - // which could be exploitable. Fail verification if - // this sequence occurs anywhere after the real one. - LOGE("EOCD marker occurs after start of EOCD\n"); - fclose(f); - return VERIFY_FAILURE; - } - } - -#define BUFFER_SIZE 4096 - - SHA_CTX ctx; - SHA_init(&ctx); - unsigned char* buffer = (unsigned char*)malloc(BUFFER_SIZE); - if (buffer == NULL) { - LOGE("failed to alloc memory for sha1 buffer\n"); - fclose(f); - return VERIFY_FAILURE; - } - - double frac = -1.0; - size_t so_far = 0; - fseek(f, 0, SEEK_SET); - while (so_far < signed_len) { - size_t size = BUFFER_SIZE; - if (signed_len - so_far < size) size = signed_len - so_far; - if (fread(buffer, 1, size, f) != size) { - LOGE("failed to read data from %s (%s)\n", path, strerror(errno)); - fclose(f); - return VERIFY_FAILURE; - } - SHA_update(&ctx, buffer, size); - so_far += size; - double f = so_far / (double)signed_len; - if (f > frac + 0.02 || size == so_far) { - ui->SetProgress(f); - frac = f; - } - } - fclose(f); - free(buffer); - - const uint8_t* sha1 = SHA_final(&ctx); - for (i = 0; i < numKeys; ++i) { - // The 6 bytes is the "(signature_start) $ff $ff (comment_size)" that - // the signing tool appends after the signature itself. - if (RSA_verify(pKeys+i, eocd + eocd_size - 6 - RSANUMBYTES, - RSANUMBYTES, sha1)) { - LOGI("whole-file signature verified against key %d\n", i); - free(eocd); - return VERIFY_SUCCESS; - } - } - free(eocd); - LOGE("failed to verify whole-file signature\n"); - return VERIFY_FAILURE; -} - // If the package contains an update binary, extract it and run it. static int try_update_binary(const char *path, ZipArchive *zip, int* wipe_cache) { @@ -466,7 +307,7 @@ extern "C" int TWinstall_zip(const char* path, int* wipe_cache) { ui->SetProgressType(RecoveryUI::DETERMINATE); ui->ShowProgress(VERIFICATION_PROGRESS_FRACTION, VERIFICATION_PROGRESS_TIME); - err = TWverify_file(path, loadedKeys, numKeys); + err = verify_file(path, loadedKeys, numKeys); free(loadedKeys); LOGI("verify_file returned %d\n", err); if (err != VERIFY_SUCCESS) { diff --git a/twmincrypt/Android.mk b/twmincrypt/Android.mk new file mode 100644 index 000000000..0e1fbfd9a --- /dev/null +++ b/twmincrypt/Android.mk @@ -0,0 +1,11 @@ +# This provides a rule to make libmincrypt as a shared library. +# As a static library, zip signature verification was crashing. +# Making it as a shared library seems to fix that issue. + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS:= eng +LOCAL_MODULE := libmincrypt +LOCAL_SRC_FILES := ../../../system/core/libmincrypt/rsa.c ../../../system/core/libmincrypt/sha.c +include $(BUILD_SHARED_LIBRARY) diff --git a/twmincrypt/twrsa.c b/twmincrypt/twrsa.c deleted file mode 100644 index 52d6bfbc2..000000000 --- a/twmincrypt/twrsa.c +++ /dev/null @@ -1,199 +0,0 @@ -/* rsa.c -** -** Copyright 2008, 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. -*/ - -#include "twrsa.h" -#include "twsha.h" -#include "common.h" - -/* a[] -= mod */ -static void subM(const RSAPublicKey *key, uint32_t *a) { - int64_t A = 0; - int i; - for (i = 0; i < key->len; ++i) { - A += (uint64_t)a[i] - key->n[i]; - a[i] = (uint32_t)A; - A >>= 32; - } -} - -/* return a[] >= mod */ -static int geM(const RSAPublicKey *key, const uint32_t *a) { - int i; - for (i = key->len; i;) { - --i; - if (a[i] < key->n[i]) return 0; - if (a[i] > key->n[i]) return 1; - } - return 1; /* equal */ -} - -/* montgomery c[] += a * b[] / R % mod */ -static void montMulAdd(const RSAPublicKey *key, - uint32_t* c, - const uint32_t a, - const uint32_t* b) { - uint64_t A = (uint64_t)a * b[0] + c[0]; - uint32_t d0 = (uint32_t)A * key->n0inv; - uint64_t B = (uint64_t)d0 * key->n[0] + (uint32_t)A; - int i; - - for (i = 1; i < key->len; ++i) { - A = (A >> 32) + (uint64_t)a * b[i] + c[i]; - B = (B >> 32) + (uint64_t)d0 * key->n[i] + (uint32_t)A; - c[i - 1] = (uint32_t)B; - } - - A = (A >> 32) + (B >> 32); - - c[i - 1] = (uint32_t)A; - - if (A >> 32) { - subM(key, c); - } -} - -/* montgomery c[] = a[] * b[] / R % mod */ -static void montMul(const RSAPublicKey *key, - uint32_t* c, - const uint32_t* a, - const uint32_t* b) { - int i; - for (i = 0; i < key->len; ++i) { - c[i] = 0; - } - for (i = 0; i < key->len; ++i) { - montMulAdd(key, c, a[i], b); - } -} - -/* In-place public exponentiation. -** Input and output big-endian byte array in inout. -*/ -static void modpow3(const RSAPublicKey *key, - uint8_t* inout) { - uint32_t a[RSANUMWORDS]; - uint32_t aR[RSANUMWORDS]; - uint32_t aaR[RSANUMWORDS]; - uint32_t *aaa = aR; /* Re-use location. */ - int i; - - /* Convert from big endian byte array to little endian word array. */ - for (i = 0; i < key->len; ++i) { - uint32_t tmp = - (inout[((key->len - 1 - i) * 4) + 0] << 24) | - (inout[((key->len - 1 - i) * 4) + 1] << 16) | - (inout[((key->len - 1 - i) * 4) + 2] << 8) | - (inout[((key->len - 1 - i) * 4) + 3] << 0); - a[i] = tmp; - } - - montMul(key, aR, a, key->rr); /* aR = a * RR / R mod M */ - montMul(key, aaR, aR, aR); /* aaR = aR * aR / R mod M */ - montMul(key, aaa, aaR, a); /* aaa = aaR * a / R mod M */ - - /* Make sure aaa < mod; aaa is at most 1x mod too large. */ - if (geM(key, aaa)) { - subM(key, aaa); - } - - /* Convert to bigendian byte array */ - for (i = key->len - 1; i >= 0; --i) { - uint32_t tmp = aaa[i]; - *inout++ = tmp >> 24; - *inout++ = tmp >> 16; - *inout++ = tmp >> 8; - *inout++ = tmp >> 0; - } -} - -/* Expected PKCS1.5 signature padding bytes, for a keytool RSA signature. -** Has the 0-length optional parameter encoded in the ASN1 (as opposed to the -** other flavor which omits the optional parameter entirely). This code does not -** accept signatures without the optional parameter. -*/ -static const uint8_t padding[RSANUMBYTES - SHA_DIGEST_SIZE] = { - 0x00,0x01,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, - 0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x05,0x00, - 0x04,0x14 -}; - -/* Verify a 2048 bit RSA PKCS1.5 signature against an expected SHA-1 hash. -** Returns 0 on failure, 1 on success. -*/ -int RSA_verify(const RSAPublicKey *key, - const uint8_t *signature, - const int len, - const uint8_t *sha) { - uint8_t buf[RSANUMBYTES]; - int i; - - if (key->len != RSANUMWORDS) { - return 0; /* Wrong key passed in. */ - } - - if (len != sizeof(buf)) { - return 0; /* Wrong input length. */ - } - - for (i = 0; i < len; ++i) { - buf[i] = signature[i]; - } - - modpow3(key, buf); - - /* Check pkcs1.5 padding bytes. */ - for (i = 0; i < (int) sizeof(padding); ++i) { - if (buf[i] != padding[i]) { - return 0; - } - } - - /* Check sha digest matches. */ - for (; i < len; ++i) { - if (buf[i] != *sha++) { - return 0; - } - } - - return 1; -} diff --git a/twmincrypt/twrsa.h b/twmincrypt/twrsa.h deleted file mode 100644 index 7d7d57158..000000000 --- a/twmincrypt/twrsa.h +++ /dev/null @@ -1,56 +0,0 @@ -/* rsa.h -** -** Copyright 2008, 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. -*/ - -#ifndef _EMBEDDED_RSA_H_ -#define _EMBEDDED_RSA_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define RSANUMBYTES 256 /* 2048 bit key length */ -#define RSANUMWORDS (RSANUMBYTES / sizeof(uint32_t)) - -typedef struct RSAPublicKey { - int len; /* Length of n[] in number of uint32_t */ - uint32_t n0inv; /* -1 / n[0] mod 2^32 */ - uint32_t n[RSANUMWORDS]; /* modulus as little endian array */ - uint32_t rr[RSANUMWORDS]; /* R^2 as little endian array */ -} RSAPublicKey; - -int RSA_verify(const RSAPublicKey *key, - const uint8_t* signature, - const int len, - const uint8_t* sha); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/twmincrypt/twsha.c b/twmincrypt/twsha.c deleted file mode 100644 index ac712c245..000000000 --- a/twmincrypt/twsha.c +++ /dev/null @@ -1,307 +0,0 @@ -/* sha.c -** -** Copyright 2008, 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. -*/ - -#include "twsha.h" - -// Some machines lack byteswap.h and endian.h. These have to use the -// slower code, even if they're little-endian. - -#if defined(HAVE_ENDIAN_H) && defined(HAVE_LITTLE_ENDIAN) - -#include -#include - -// This version is about 28% faster than the generic version below, -// but assumes little-endianness. - -static inline uint32_t ror27(uint32_t val) { - return (val >> 27) | (val << 5); -} -static inline uint32_t ror2(uint32_t val) { - return (val >> 2) | (val << 30); -} -static inline uint32_t ror31(uint32_t val) { - return (val >> 31) | (val << 1); -} - -static void SHA1_Transform(SHA_CTX* ctx) { - uint32_t W[80]; - register uint32_t A, B, C, D, E; - int t; - - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - E = ctx->state[4]; - -#define SHA_F1(A,B,C,D,E,t) \ - E += ror27(A) + \ - (W[t] = bswap_32(ctx->buf.w[t])) + \ - (D^(B&(C^D))) + 0x5A827999; \ - B = ror2(B); - - for (t = 0; t < 15; t += 5) { - SHA_F1(A,B,C,D,E,t + 0); - SHA_F1(E,A,B,C,D,t + 1); - SHA_F1(D,E,A,B,C,t + 2); - SHA_F1(C,D,E,A,B,t + 3); - SHA_F1(B,C,D,E,A,t + 4); - } - SHA_F1(A,B,C,D,E,t + 0); // 16th one, t == 15 - -#undef SHA_F1 - -#define SHA_F1(A,B,C,D,E,t) \ - E += ror27(A) + \ - (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \ - (D^(B&(C^D))) + 0x5A827999; \ - B = ror2(B); - - SHA_F1(E,A,B,C,D,t + 1); - SHA_F1(D,E,A,B,C,t + 2); - SHA_F1(C,D,E,A,B,t + 3); - SHA_F1(B,C,D,E,A,t + 4); - -#undef SHA_F1 - -#define SHA_F2(A,B,C,D,E,t) \ - E += ror27(A) + \ - (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \ - (B^C^D) + 0x6ED9EBA1; \ - B = ror2(B); - - for (t = 20; t < 40; t += 5) { - SHA_F2(A,B,C,D,E,t + 0); - SHA_F2(E,A,B,C,D,t + 1); - SHA_F2(D,E,A,B,C,t + 2); - SHA_F2(C,D,E,A,B,t + 3); - SHA_F2(B,C,D,E,A,t + 4); - } - -#undef SHA_F2 - -#define SHA_F3(A,B,C,D,E,t) \ - E += ror27(A) + \ - (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \ - ((B&C)|(D&(B|C))) + 0x8F1BBCDC; \ - B = ror2(B); - - for (; t < 60; t += 5) { - SHA_F3(A,B,C,D,E,t + 0); - SHA_F3(E,A,B,C,D,t + 1); - SHA_F3(D,E,A,B,C,t + 2); - SHA_F3(C,D,E,A,B,t + 3); - SHA_F3(B,C,D,E,A,t + 4); - } - -#undef SHA_F3 - -#define SHA_F4(A,B,C,D,E,t) \ - E += ror27(A) + \ - (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \ - (B^C^D) + 0xCA62C1D6; \ - B = ror2(B); - - for (; t < 80; t += 5) { - SHA_F4(A,B,C,D,E,t + 0); - SHA_F4(E,A,B,C,D,t + 1); - SHA_F4(D,E,A,B,C,t + 2); - SHA_F4(C,D,E,A,B,t + 3); - SHA_F4(B,C,D,E,A,t + 4); - } - -#undef SHA_F4 - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; - ctx->state[4] += E; -} - -void SHA_update(SHA_CTX* ctx, const void* data, int len) { - int i = ctx->count % sizeof(ctx->buf); - const uint8_t* p = (const uint8_t*)data; - - ctx->count += len; - - while (len > sizeof(ctx->buf) - i) { - memcpy(&ctx->buf.b[i], p, sizeof(ctx->buf) - i); - len -= sizeof(ctx->buf) - i; - p += sizeof(ctx->buf) - i; - SHA1_Transform(ctx); - i = 0; - } - - while (len--) { - ctx->buf.b[i++] = *p++; - if (i == sizeof(ctx->buf)) { - SHA1_Transform(ctx); - i = 0; - } - } -} - - -const uint8_t* SHA_final(SHA_CTX* ctx) { - uint64_t cnt = ctx->count * 8; - int i; - - SHA_update(ctx, (uint8_t*)"\x80", 1); - while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) { - SHA_update(ctx, (uint8_t*)"\0", 1); - } - for (i = 0; i < 8; ++i) { - uint8_t tmp = cnt >> ((7 - i) * 8); - SHA_update(ctx, &tmp, 1); - } - - for (i = 0; i < 5; i++) { - ctx->buf.w[i] = bswap_32(ctx->state[i]); - } - - return ctx->buf.b; -} - -#else // #if defined(HAVE_ENDIAN_H) && defined(HAVE_LITTLE_ENDIAN) - -#define rol(bits, value) (((value) << (bits)) | ((value) >> (32 - (bits)))) - -static void SHA1_transform(SHA_CTX *ctx) { - uint32_t W[80]; - uint32_t A, B, C, D, E; - uint8_t *p = ctx->buf; - int t; - - for(t = 0; t < 16; ++t) { - uint32_t 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]); - } - - 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++) { - uint32_t 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; -} - -void SHA_update(SHA_CTX *ctx, const void *data, int len) { - int i = ctx->count % sizeof(ctx->buf); - const uint8_t* p = (const uint8_t*)data; - - ctx->count += len; - - while (len--) { - ctx->buf[i++] = *p++; - if (i == sizeof(ctx->buf)) { - SHA1_transform(ctx); - i = 0; - } - } -} -const uint8_t *SHA_final(SHA_CTX *ctx) { - uint8_t *p = ctx->buf; - uint64_t cnt = ctx->count * 8; - int i; - - SHA_update(ctx, (uint8_t*)"\x80", 1); - while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) { - SHA_update(ctx, (uint8_t*)"\0", 1); - } - for (i = 0; i < 8; ++i) { - uint8_t tmp = cnt >> ((7 - i) * 8); - SHA_update(ctx, &tmp, 1); - } - - for (i = 0; i < 5; i++) { - uint32_t tmp = ctx->state[i]; - *p++ = tmp >> 24; - *p++ = tmp >> 16; - *p++ = tmp >> 8; - *p++ = tmp >> 0; - } - - return ctx->buf; -} - -#endif // endianness - -void SHA_init(SHA_CTX* ctx) { - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; - ctx->state[4] = 0xC3D2E1F0; - ctx->count = 0; -} - -/* Convenience function */ -const uint8_t* SHA(const void *data, int len, uint8_t *digest) { - const uint8_t *p; - int i; - SHA_CTX ctx; - SHA_init(&ctx); - SHA_update(&ctx, data, len); - p = SHA_final(&ctx); - for (i = 0; i < SHA_DIGEST_SIZE; ++i) { - digest[i] = *p++; - } - return digest; -} diff --git a/twmincrypt/twsha.h b/twmincrypt/twsha.h deleted file mode 100644 index af63e8775..000000000 --- a/twmincrypt/twsha.h +++ /dev/null @@ -1,63 +0,0 @@ -/* sha.h -** -** Copyright 2008, 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. -*/ - -#ifndef _EMBEDDED_SHA_H_ -#define _EMBEDDED_SHA_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct SHA_CTX { - uint64_t count; - uint32_t state[5]; -#if defined(HAVE_ENDIAN_H) && defined(HAVE_LITTLE_ENDIAN) - union { - uint8_t b[64]; - uint32_t w[16]; - } buf; -#else - uint8_t buf[64]; -#endif -} SHA_CTX; - -void SHA_init(SHA_CTX* ctx); -void SHA_update(SHA_CTX* ctx, const void* data, int len); -const uint8_t* SHA_final(SHA_CTX* ctx); - -/* Convenience method. Returns digest parameter value. */ -const uint8_t* SHA(const void* data, int len, uint8_t* digest); - -#define SHA_DIGEST_SIZE 20 - -#ifdef __cplusplus -} -#endif - -#endif -- cgit v1.2.3