mincrypt: support SHA-256 hash algorithm

- adds a library to compute the SHA-256 hash

- updates the RSA verifier to take an argument specifying either SHA-1
  or SHA-256

- updates DumpPublicKey to with new "key" version numbers for
  specifying SHA-256

- adds new argument to adb auth code to maintain existing behavior

Change-Id: I5b1406cf57c2b8993f6032eda3e29139f7740839
diff --git a/libmincrypt/sha.c b/libmincrypt/sha.c
index e089d79..5bef32e 100644
--- a/libmincrypt/sha.c
+++ b/libmincrypt/sha.c
@@ -1,6 +1,6 @@
 /* sha.c
 **
-** Copyright 2008, The Android Open Source Project
+** 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:
@@ -25,177 +25,20 @@
 ** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
+// Optimized for minimal code size.
+
 #include "mincrypt/sha.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 <byteswap.h>
-#include <memory.h>
-
-// 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)
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
 
 #define rol(bits, value) (((value) << (bits)) | ((value) >> (32 - (bits))))
 
-static void SHA1_transform(SHA_CTX *ctx) {
+static void SHA1_Transform(SHA_CTX* ctx) {
     uint32_t W[80];
     uint32_t A, B, C, D, E;
-    uint8_t *p = ctx->buf;
+    uint8_t* p = ctx->buf;
     int t;
 
     for(t = 0; t < 16; ++t) {
@@ -242,31 +85,52 @@
     ctx->state[4] += E;
 }
 
-void SHA_update(SHA_CTX *ctx, const void *data, int len) {
-    int i = ctx->count % sizeof(ctx->buf);
+static const HASH_VTAB SHA_VTAB = {
+    SHA_init,
+    SHA_update,
+    SHA_final,
+    SHA_hash,
+    SHA_DIGEST_SIZE
+};
+
+void SHA_init(SHA_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 SHA_update(SHA_CTX* ctx, const void* data, int len) {
+    int i = (int) (ctx->count & 63);
     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);
+        if (i == 64) {
+            SHA1_Transform(ctx);
             i = 0;
         }
     }
 }
-const uint8_t *SHA_final(SHA_CTX *ctx) {
+
+
+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)) {
+    while ((ctx->count & 63) != 56) {
         SHA_update(ctx, (uint8_t*)"\0", 1);
     }
     for (i = 0; i < 8; ++i) {
-        uint8_t tmp = cnt >> ((7 - i) * 8);
+        uint8_t tmp = (uint8_t) (cnt >> ((7 - i) * 8));
         SHA_update(ctx, &tmp, 1);
     }
 
@@ -281,27 +145,11 @@
     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;
+const uint8_t* SHA_hash(const void* data, int len, uint8_t* digest) {
     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++;
-    }
+    memcpy(digest, SHA_final(&ctx), SHA_DIGEST_SIZE);
     return digest;
 }