Author: mturk
Date: Fri Aug  7 20:45:48 2009
New Revision: 802177

URL: http://svn.apache.org/viewvc?rev=802177&view=rev
Log:
Port APR's md5 code

Added:
    commons/sandbox/runtime/trunk/src/main/native/shared/md5.c   (with props)
Modified:
    commons/sandbox/runtime/trunk/src/main/native/Makefile.in
    commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in
    commons/sandbox/runtime/trunk/src/main/native/include/acr_crypto.h
    commons/sandbox/runtime/trunk/src/main/native/shared/sha.c

Modified: commons/sandbox/runtime/trunk/src/main/native/Makefile.in
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/Makefile.in?rev=802177&r1=802176&r2=802177&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/Makefile.in (original)
+++ commons/sandbox/runtime/trunk/src/main/native/Makefile.in Fri Aug  7 
20:45:48 2009
@@ -87,6 +87,7 @@
        $(SRCDIR)/shared/nbb.$(OBJ) \
        $(SRCDIR)/shared/pointer.$(OBJ) \
        $(SRCDIR)/shared/object.$(OBJ) \
+       $(SRCDIR)/shared/md5.$(OBJ) \
        $(SRCDIR)/shared/sha.$(OBJ) \
        $(SRCDIR)/shared/string.$(OBJ) \
        $(SRCDIR)/shared/tables.$(OBJ) \

Modified: commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in?rev=802177&r1=802176&r2=802177&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in (original)
+++ commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in Fri Aug  7 
20:45:48 2009
@@ -80,6 +80,7 @@
        $(SRCDIR)/shared/nbb.$(OBJ) \
        $(SRCDIR)/shared/pointer.$(OBJ) \
        $(SRCDIR)/shared/object.$(OBJ) \
+       $(SRCDIR)/shared/md5.$(OBJ) \
        $(SRCDIR)/shared/sha.$(OBJ) \
        $(SRCDIR)/shared/string.$(OBJ) \
        $(SRCDIR)/shared/tables.$(OBJ) \

Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr_crypto.h
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr_crypto.h?rev=802177&r1=802176&r2=802177&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr_crypto.h 
(original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr_crypto.h Fri Aug  
7 20:45:48 2009
@@ -31,29 +31,33 @@
  *
  */
 
+#define ACR_SHA1_BLOCK_LENGTH           64
+#define ACR_SHA1_DIGEST_LENGTH          20
+#define ACR_SHA1_DIGEST_STRING_LENGTH   (ACR_SHA1_DIGEST_LENGTH * 2 + 1)
+
+#define ACR_MD5_BLOCK_LENGTH            64
+#define ACR_MD5_DIGEST_LENGTH           16
+#define ACR_MD5_DIGEST_STRING_LENGTH    (ACR_MD5_DIGEST_LENGTH * 2 + 1)
+
+typedef struct acr_sha1_ctx_t {
+    acr_uint32_t state[5];
+    acr_uint64_t count;
+    acr_byte_t   buffer[ACR_SHA1_BLOCK_LENGTH];
+} acr_sha1_ctx_t;
+
+typedef struct acr_md5_ctx_t {
+    acr_uint32_t state[4];                      /* state */
+    acr_uint64_t count;                         /* number of bits, mod 2^64 */
+    acr_byte_t buffer[ACR_MD5_BLOCK_LENGTH];    /* input buffer */
+} acr_md5_ctx_t;
+
+
 /** 
  * Size of the SHA1 DIGEST
  */
 #define ACR_SHA1_DIGESTSIZE 20
 #define ACR_SHA1_BASE16SIZE 41
 
-/** @see acr_sha1_ctx_t */
-typedef struct acr_sha1_ctx_t acr_sha1_ctx_t;
-
-/** 
- * SHA1 context structure
- */
-struct acr_sha1_ctx_t {
-    /** message digest */
-    acr_uint32_t digest[5];
-    /** 64-bit bit counts */
-    acr_uint32_t count_lo, count_hi;
-    /** SHA data buffer */
-    acr_uint32_t data[16];
-    /** unprocessed amount in data */
-    int local;
-};
-
 /**
  * Initialize the SHA digest
  * @param context The SHA context to initialize
@@ -68,7 +72,7 @@
  */
 ACR_DECLARE(void) ACR_Sha1Update(acr_sha1_ctx_t *context,
                                  const unsigned char *input,
-                                 unsigned int count);
+                                 size_t count);
 
 /**
  * Update the SHA digest
@@ -78,7 +82,7 @@
  */
 ACR_DECLARE(void) ACR_Sha1UpdateA(acr_sha1_ctx_t *context,
                                   const char *input,
-                                  unsigned int count);
+                                  size_t count);
 
 /**
  * Update the SHA digest
@@ -88,14 +92,14 @@
  */
 ACR_DECLARE(void) ACR_Sha1UpdateW(acr_sha1_ctx_t *context,
                                   const wchar_t *input,
-                                  unsigned int count);
+                                  size_t count);
 
 /**
  * Finish computing the SHA digest
  * @param digest the output buffer in which to store the digest
  * @param context The context to finalize
  */
-ACR_DECLARE(void) ACR_Sha1Final(unsigned char digest[ACR_SHA1_DIGESTSIZE],
+ACR_DECLARE(void) ACR_Sha1Final(unsigned char digest[ACR_SHA1_DIGEST_LENGTH],
                                 acr_sha1_ctx_t *context);
 
 /**
@@ -105,7 +109,7 @@
  * @param len The length of the plaintext data
  * @param out The encrypted/encoded password
  */
-ACR_DECLARE(void) ACR_Sha1Base16A(const char *clear, int len, char *out);
+ACR_DECLARE(char *) ACR_Sha1Base16A(const char *clear, size_t len, char *out);
 
 /**
  * Provide a means to SHA1 crypt/encode a plaintext data using
@@ -114,7 +118,71 @@
  * @param len The length of the plaintext data
  * @param out The encrypted/encoded password
  */
-ACR_DECLARE(void) ACR_Sha1Base16W(const wchar_t *clear, int len, wchar_t *out);
+ACR_DECLARE(wchar_t *) ACR_Sha1Base16W(const wchar_t *clear, size_t len,
+                                       wchar_t *out);
+
+/**
+ * Initialize the MD5 digest
+ * @param context The MD5 context to initialize
+ */
+ACR_DECLARE(void) ACR_Md5Init(acr_md5_ctx_t *ctx);
+
+/**
+ * Update the MD5 digest with binary data
+ * @param context The MD5 context to update
+ * @param input The buffer to add to the MD5 digest
+ * @param count The length of the input buffer
+ */
+ACR_DECLARE(void) ACR_Md5Update(acr_md5_ctx_t *ctx,
+                                const unsigned char *input,
+                                size_t count);
+
+/**
+ * Update the MD5 digest
+ * @param context The MD5 context to update
+ * @param input The buffer to add to the MD5 digest
+ * @param count The length of the input buffer
+ */
+ACR_DECLARE(void) ACR_Md5UpdateA(acr_md5_ctx_t *context,
+                                 const char *input,
+                                 size_t count);
+
+/**
+ * Update the MD5 digest
+ * @param context The MD5 context to update
+ * @param input The buffer to add to the MD5 digest
+ * @param count The length of the input buffer
+ */
+ACR_DECLARE(void) ACR_Md5UpdateW(acr_md5_ctx_t *context,
+                                 const wchar_t *input,
+                                 size_t count);
+
+/**
+ * Finish computing the MD5 digest
+ * @param digest the output buffer in which to store the digest
+ * @param context The context to finalize
+ */
+ACR_DECLARE(void) ACR_Md5Final(unsigned char digest[ACR_MD5_DIGEST_LENGTH],
+                               acr_md5_ctx_t *context);
+
+/**
+ * Provide a means to MD5 crypt/encode a plaintext data using
+ * base 16 encoding.
+ * @param clear The plaintext data.
+ * @param len The length of the plaintext data
+ * @param out The encrypted/encoded password
+ */
+ACR_DECLARE(char *) ACR_Md5Base16A(const char *clear, size_t len, char *out);
+
+/**
+ * Provide a means to MD5 crypt/encode a plaintext data using
+ * base 16 encoding.
+ * @param clear The plaintext data.
+ * @param len The length of the plaintext data
+ * @param out The encrypted/encoded password
+ */
+ACR_DECLARE(wchar_t *) ACR_Md5Base16W(const wchar_t *clear, size_t len,
+                                      wchar_t *out);
 
 #ifdef __cplusplus
 }

Added: commons/sandbox/runtime/trunk/src/main/native/shared/md5.c
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/md5.c?rev=802177&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/shared/md5.c (added)
+++ commons/sandbox/runtime/trunk/src/main/native/shared/md5.c Fri Aug  7 
20:45:48 2009
@@ -0,0 +1,330 @@
+/*
+ * 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.
+ */
+
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "acr.h"
+#include "acr_private.h"
+#include "acr_error.h"
+#include "acr_string.h"
+#include "acr_clazz.h"
+#include "acr_crypto.h"
+
+static const char basis16[] =
+    "0123456789abcdef";
+
+#define HI_NIBBLE_HEX(a) (basis16[((unsigned char)(a) >> 4)])
+#define LO_NIBBLE_HEX(a) (basis16[((unsigned char)(a) & 0x0F)])
+
+#define PUT_64BIT_LE(cp, value) do {            \
+    (cp)[7] = (value) >> 56;                    \
+    (cp)[6] = (value) >> 48;                    \
+    (cp)[5] = (value) >> 40;                    \
+    (cp)[4] = (value) >> 32;                    \
+    (cp)[3] = (value) >> 24;                    \
+    (cp)[2] = (value) >> 16;                    \
+    (cp)[1] = (value) >> 8;                     \
+    (cp)[0] = (value); } while (0)
+
+#define PUT_32BIT_LE(cp, value) do {            \
+    (cp)[3] = (value) >> 24;                    \
+    (cp)[2] = (value) >> 16;                    \
+    (cp)[1] = (value) >> 8;                     \
+    (cp)[0] = (value); } while (0)
+
+static acr_byte_t PADDING[ACR_MD5_BLOCK_LENGTH] = {
+    0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*
+ * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+ACR_DECLARE(void) ACR_Md5Init(acr_md5_ctx_t *ctx)
+{
+    ctx->count = 0;
+    ctx->state[0] = 0x67452301;
+    ctx->state[1] = 0xefcdab89;
+    ctx->state[2] = 0x98badcfe;
+    ctx->state[3] = 0x10325476;
+}
+
+/* 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.
+ */
+static void
+md5transform(acr_uint32_t state[4],
+             const acr_byte_t block[ACR_MD5_BLOCK_LENGTH])
+{
+    acr_uint32_t a, b, c, d, in[ACR_MD5_BLOCK_LENGTH / 4];
+
+#if !CC_IS_BIG_ENDIAN
+    memcpy(in, block, sizeof(in));
+#else
+    for (a = 0; a < ACR_MD5_BLOCK_LENGTH / 4; a++) {
+        in[a] = (acr_uint32_t)(
+            (acr_uint32_t)(block[a * 4 + 0]) |
+            (acr_uint32_t)(block[a * 4 + 1]) <<  8 |
+            (acr_uint32_t)(block[a * 4 + 2]) << 16 |
+            (acr_uint32_t)(block[a * 4 + 3]) << 24);
+    }
+#endif
+
+    a = state[0];
+    b = state[1];
+    c = state[2];
+    d = state[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);
+
+    state[0] += a;
+    state[1] += b;
+    state[2] += c;
+    state[3] += d;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+ACR_DECLARE(void)
+ACR_Md5Update(acr_md5_ctx_t *ctx, const unsigned char *input, size_t len)
+{
+    size_t have, need;
+
+    /* Check how many bytes we already have and how many more we need. */
+    have = (size_t)((ctx->count >> 3) & (ACR_MD5_BLOCK_LENGTH - 1));
+    need = ACR_MD5_BLOCK_LENGTH - have;
+
+    /* Update bitcount */
+    ctx->count += (acr_uint64_t)len << 3;
+
+    if (len >= need) {
+        if (have != 0) {
+            memcpy(ctx->buffer + have, input, need);
+            md5transform(ctx->state, ctx->buffer);
+            input += need;
+            len -= need;
+            have = 0;
+        }
+
+        /* Process data in ACR_MD5_BLOCK_LENGTH-byte chunks. */
+        while (len >= ACR_MD5_BLOCK_LENGTH) {
+            md5transform(ctx->state, input);
+            input += ACR_MD5_BLOCK_LENGTH;
+            len -= ACR_MD5_BLOCK_LENGTH;
+        }
+    }
+
+    /* Handle any remaining bytes of data. */
+    if (len != 0)
+        memcpy(ctx->buffer + have, input, len);
+}
+
+ACR_DECLARE(void) ACR_Md5UpdateA(acr_md5_ctx_t *context,
+                                 const char *data,
+                                 size_t count)
+{
+    ACR_Md5Update(context, (const unsigned char *)data, count);
+}
+
+ACR_DECLARE(void) ACR_Md5UpdateW(acr_md5_ctx_t *context,
+                                 const wchar_t *data,
+                                 size_t count)
+{
+    ACR_Md5Update(context, (const unsigned char *)data,
+                  count * sizeof(wchar_t));
+}
+
+/*
+ * Pad pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+static void
+md5pad(acr_md5_ctx_t *ctx)
+{
+    acr_byte_t count[8];
+    size_t padlen;
+
+    /* Convert count to 8 bytes in little endian order. */
+    PUT_64BIT_LE(count, ctx->count);
+
+    /* Pad out to 56 mod 64. */
+    padlen = ACR_MD5_BLOCK_LENGTH -
+             ((ctx->count >> 3) & (ACR_MD5_BLOCK_LENGTH - 1));
+    if (padlen < 1 + 8)
+        padlen += ACR_MD5_BLOCK_LENGTH;
+    ACR_Md5Update(ctx, PADDING, padlen - 8);        /* padlen - 8 <= 64 */
+    ACR_Md5Update(ctx, count, 8);
+}
+
+/*
+ * Final wrapup--call MD5Pad, fill in digest and zero out ctx.
+ */
+ACR_DECLARE(void)
+ACR_Md5Final(unsigned char digest[ACR_MD5_DIGEST_LENGTH], acr_md5_ctx_t *ctx)
+{
+    int i;
+
+    md5pad(ctx);
+    if (digest != NULL) {
+        for (i = 0; i < 4; i++)
+            PUT_32BIT_LE(digest + i * 4, ctx->state[i]);
+        memset(ctx, 0, sizeof(*ctx));
+    }
+}
+
+ACR_DECLARE(char *) ACR_Md5Base16A(const char *clear, size_t len, char *out)
+{
+    int i, x = 0;
+    acr_md5_ctx_t context;
+    acr_byte_t digest[ACR_MD5_DIGEST_LENGTH];
+
+    if (out == NULL && (out = malloc(ACR_MD5_DIGEST_STRING_LENGTH)) == NULL)
+        return NULL;
+
+    ACR_Md5Init(&context);
+    ACR_Md5UpdateA(&context, clear, len);
+    ACR_Md5Final(digest, &context);
+    for (i = 0; i < ACR_MD5_DIGEST_LENGTH; i++) {
+        out[x++] = HI_NIBBLE_HEX(digest[i]);
+        out[x++] = LO_NIBBLE_HEX(digest[i]);
+    }
+    out[x] = '\0';
+
+    memset(digest, 0, sizeof(digest));
+    return out;
+}
+
+ACR_DECLARE(wchar_t *) ACR_Md5Base16W(const wchar_t *clear, size_t len, 
wchar_t *out)
+{
+    int i, x = 0;
+    acr_md5_ctx_t context;
+    acr_byte_t digest[ACR_MD5_DIGEST_LENGTH];
+
+    if (out == NULL &&
+       (out = malloc(ACR_MD5_DIGEST_STRING_LENGTH * sizeof(wchar_t))) == NULL)
+        return NULL;
+    ACR_Md5Init(&context);
+    ACR_Md5UpdateW(&context, clear, len);
+    ACR_Md5Final(digest, &context);
+    for (i = 0; i < ACR_MD5_DIGEST_LENGTH; i++) {
+        out[x++] = HI_NIBBLE_HEX(digest[i]);
+        out[x++] = LO_NIBBLE_HEX(digest[i]);
+    }
+    out[x] = L'\0';
+
+    memset(digest, 0, sizeof(digest));
+    return out;
+}
+

Propchange: commons/sandbox/runtime/trunk/src/main/native/shared/md5.c
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: commons/sandbox/runtime/trunk/src/main/native/shared/sha.c
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/sha.c?rev=802177&r1=802176&r2=802177&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/shared/sha.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/shared/sha.c Fri Aug  7 
20:45:48 2009
@@ -15,6 +15,20 @@
  */
 
 /*
+ * SHA-1 in C
+ * By Steve Reid <st...@edmweb.com>
+ * 100% Public Domain
+ *
+ * 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
+ */
+
+/*
  *
  * @author Mladen Turk
  */
@@ -32,254 +46,219 @@
 #define HI_NIBBLE_HEX(a) (basis16[((unsigned char)(a) >> 4)])
 #define LO_NIBBLE_HEX(a) (basis16[((unsigned char)(a) & 0x0F)])
 
-/* a bit faster & bigger, if defined */
-#define UNROLL_LOOPS
-
-/* NIST's proposed modification to SHA, 7/11/94 */
-#define USE_MODIFIED_SHA
-
-/* SHA f()-functions */
-#define f1(x,y,z)   ((x & y) | (~x & z))
-#define f2(x,y,z)   (x ^ y ^ z)
-#define f3(x,y,z)   ((x & y) | (x & z) | (y & z))
-#define f4(x,y,z)   (x ^ y ^ z)
-
-/* SHA constants */
-#define CONST1      0x5a827999L
-#define CONST2      0x6ed9eba1L
-#define CONST3      0x8f1bbcdcL
-#define CONST4      0xca62c1d6L
 
-/* 32-bit rotate */
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
 
-#define ROT32(x,n)  ((x << n) | (x >> (32 - n)))
-
-#define FUNC(n,i)                       \
-    temp = ROT32(A,5) + f##n(B,C,D) + E + W[i] + CONST##n;  \
-    E = D; D = C; C = ROT32(B,30); B = A; A = temp
-
-#define SHA_BLOCKSIZE           64
-
-/* do SHA transformation */
-static void sha_transform(acr_sha1_ctx_t *context)
-{
-    int i;
-    acr_uint32_t temp, A, B, C, D, E, W[80];
+/*
+ * blk0() and blk() perform the initial expand.
+ * I got the idea of expanding during the round function from SSLeay
+ */
+#if !CC_IS_BIG_ENDIAN
+# define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
+    |(rol(block->l[i],8)&0x00FF00FF))
+#else
+# define blk0(i) block->l[i]
+#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))
 
-    for (i = 0; i < 16; ++i) {
-        W[i] = context->data[i];
-    }
-    for (i = 16; i < 80; ++i) {
-        W[i] = W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16];
-#ifdef USE_MODIFIED_SHA
-        W[i] = ROT32(W[i], 1);
-#endif /* USE_MODIFIED_SHA */
-    }
-    A = context->digest[0];
-    B = context->digest[1];
-    C = context->digest[2];
-    D = context->digest[3];
-    E = context->digest[4];
-
-    FUNC(1, 0);  FUNC(1, 1);  FUNC(1, 2);  FUNC(1, 3);  FUNC(1, 4);
-    FUNC(1, 5);  FUNC(1, 6);  FUNC(1, 7);  FUNC(1, 8);  FUNC(1, 9);
-    FUNC(1,10);  FUNC(1,11);  FUNC(1,12);  FUNC(1,13);  FUNC(1,14);
-    FUNC(1,15);  FUNC(1,16);  FUNC(1,17);  FUNC(1,18);  FUNC(1,19);
-
-    FUNC(2,20);  FUNC(2,21);  FUNC(2,22);  FUNC(2,23);  FUNC(2,24);
-    FUNC(2,25);  FUNC(2,26);  FUNC(2,27);  FUNC(2,28);  FUNC(2,29);
-    FUNC(2,30);  FUNC(2,31);  FUNC(2,32);  FUNC(2,33);  FUNC(2,34);
-    FUNC(2,35);  FUNC(2,36);  FUNC(2,37);  FUNC(2,38);  FUNC(2,39);
-
-    FUNC(3,40);  FUNC(3,41);  FUNC(3,42);  FUNC(3,43);  FUNC(3,44);
-    FUNC(3,45);  FUNC(3,46);  FUNC(3,47);  FUNC(3,48);  FUNC(3,49);
-    FUNC(3,50);  FUNC(3,51);  FUNC(3,52);  FUNC(3,53);  FUNC(3,54);
-    FUNC(3,55);  FUNC(3,56);  FUNC(3,57);  FUNC(3,58);  FUNC(3,59);
-
-    FUNC(4,60);  FUNC(4,61);  FUNC(4,62);  FUNC(4,63);  FUNC(4,64);
-    FUNC(4,65);  FUNC(4,66);  FUNC(4,67);  FUNC(4,68);  FUNC(4,69);
-    FUNC(4,70);  FUNC(4,71);  FUNC(4,72);  FUNC(4,73);  FUNC(4,74);
-    FUNC(4,75);  FUNC(4,76);  FUNC(4,77);  FUNC(4,78);  FUNC(4,79);
-
-    context->digest[0] += A;
-    context->digest[1] += B;
-    context->digest[2] += C;
-    context->digest[3] += D;
-    context->digest[4] += E;
-}
+/*
+ * (R0+R1), R2, R3, R4 are the different operations (rounds) 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);
+
+typedef union {
+    acr_byte_t   c[64];
+    acr_uint32_t l[16];
+} CHAR64LONG16;
 
-#if !CC_IS_BIG_ENDIAN
-/* Change endianness of data.
- * count is the number of bytes to do an endian flip
+/*
+ * Hash a single 512-bit block. This is the core of the algorithm.
  */
-static void byte_reverse(acr_uint32_t *buffer, int count)
-{
-    int i;
-    acr_byte_t ct[4], *cp;
+static void
+sha1transform(acr_uint32_t state[5],
+              const acr_byte_t buffer[ACR_SHA1_BLOCK_LENGTH])
+{
+    acr_uint32_t a, b, c, d, e;
+    acr_byte_t workspace[ACR_SHA1_BLOCK_LENGTH];
+    CHAR64LONG16 *block = (CHAR64LONG16 *)workspace;
+
+    (void)memcpy(block, buffer, ACR_SHA1_BLOCK_LENGTH);
+
+    /* Copy context->state[] to working vars */
+    a = state[0];
+    b = state[1];
+    c = state[2];
+    d = state[3];
+    e = state[4];
+
+    /* 4 rounds of 20 operations each. Loop unrolled. */
+    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;
 
-    count /= sizeof(acr_uint32_t);
-    cp = (acr_byte_t *) buffer;
-    for (i = 0; i < count; ++i) {
-        ct[0] = cp[0];
-        ct[1] = cp[1];
-        ct[2] = cp[2];
-        ct[3] = cp[3];
-        cp[0] = ct[3];
-        cp[1] = ct[2];
-        cp[2] = ct[1];
-        cp[3] = ct[0];
-        cp += sizeof(acr_uint32_t);
-    }
+    /* Wipe variables */
+    a = b = c = d = e = 0;
 }
-#endif
 
 /* initialize the SHA digest */
 
 ACR_DECLARE(void) ACR_Sha1Init(acr_sha1_ctx_t *context)
 {
-    context->digest[0] = 0x67452301L;
-    context->digest[1] = 0xefcdab89L;
-    context->digest[2] = 0x98badcfeL;
-    context->digest[3] = 0x10325476L;
-    context->digest[4] = 0xc3d2e1f0L;
-    context->count_lo  = 0L;
-    context->count_hi  = 0L;
-    context->local     = 0;
+    /* SHA1 initialization constants */
+    context->count = 0;
+    context->state[0] = 0x67452301;
+    context->state[1] = 0xEFCDAB89;
+    context->state[2] = 0x98BADCFE;
+    context->state[3] = 0x10325476;
+    context->state[4] = 0xC3D2E1F0;
 }
 
 /* 
  * Update the SHA digest
  */
 ACR_DECLARE(void) ACR_Sha1Update(acr_sha1_ctx_t *context,
-                                 const unsigned char *buffer,
-                                 unsigned int count)
+                                 const unsigned char *data,
+                                 size_t len)
 {
-    unsigned int i;
+    size_t i, j;
 
-    if ((context->count_lo + ((acr_uint32_t) count << 3)) < context->count_lo) 
{
-        ++context->count_hi;
+    j = (size_t)((context->count >> 3) & 63);
+    context->count += (len << 3);
+    if ((j + len) > 63) {
+        (void)memcpy(&context->buffer[j], data, (i = 64-j));
+        sha1transform(context->state, context->buffer);
+        for ( ; i + 63 < len; i += 64)
+            sha1transform(context->state, (acr_byte_t *)&data[i]);
+        j = 0;
+    } else {
+        i = 0;
     }
-    context->count_lo += (acr_uint32_t) count << 3;
-    context->count_hi += (acr_uint32_t) count >> 29;
-    if (context->local) {
-        i = SHA_BLOCKSIZE - context->local;
-        if (i > count) {
-            i = count;
-        }
-        memcpy(((acr_byte_t *) context->data) + context->local, buffer, i);
-        count -= i;
-        buffer += i;
-        context->local += i;
-        if (context->local == SHA_BLOCKSIZE) {
-#if !CC_IS_BIG_ENDIAN
-            byte_reverse(context->data, SHA_BLOCKSIZE);
-#endif
-            sha_transform(context);
-        }
-        else {
-            return;
-        }
-    }
-    while (count >= SHA_BLOCKSIZE) {
-        memcpy(context->data, buffer, SHA_BLOCKSIZE);
-        buffer += SHA_BLOCKSIZE;
-        count -= SHA_BLOCKSIZE;
-#if !CC_IS_BIG_ENDIAN
-        byte_reverse(context->data, SHA_BLOCKSIZE);
-#endif
-        sha_transform(context);
-    }
-    memcpy(context->data, buffer, count);
-    context->local = count;
+    memcpy(&context->buffer[j], &data[i], len - i);
 }
 
 ACR_DECLARE(void) ACR_Sha1UpdateA(acr_sha1_ctx_t *context,
-                                  const char *buf,
-                                  unsigned int count)
+                                  const char *data,
+                                  size_t count)
 {
-    ACR_Sha1Update(context, (const unsigned char *)buf, count);
+    ACR_Sha1Update(context, (const unsigned char *)data, count);
 }
 
 ACR_DECLARE(void) ACR_Sha1UpdateW(acr_sha1_ctx_t *context,
-                                  const wchar_t *buf,
-                                  unsigned int count)
+                                  const wchar_t *data,
+                                  size_t count)
 {
-    ACR_Sha1Update(context, (const unsigned char *)buf,
+    ACR_Sha1Update(context, (const unsigned char *)data,
                    count * sizeof(wchar_t));
 }
 
+/*
+ * Add padding and return the message digest.
+ */
+static void sha1pad(acr_sha1_ctx_t *context)
+{
+    acr_byte_t finalcount[8];
+    u_int i;
+
+    for (i = 0; i < 8; i++) {
+        finalcount[i] = (acr_byte_t)((context->count >>
+            ((7 - (i & 7)) * 8)) & 255);    /* Endian independent */
+    }
+    ACR_Sha1Update(context, (acr_byte_t *)"\200", 1);
+    while ((context->count & 504) != 448)
+        ACR_Sha1Update(context, (acr_byte_t *)"\0", 1);
+    ACR_Sha1Update(context, finalcount, 8); /* Should cause a SHA1Transform() 
*/
+}
+
 /* 
  * Finish computing the SHA digest
  */
-ACR_DECLARE(void) ACR_Sha1Final(unsigned char digest[ACR_SHA1_DIGESTSIZE],
+ACR_DECLARE(void) ACR_Sha1Final(unsigned char digest[ACR_SHA1_DIGEST_LENGTH],
                                 acr_sha1_ctx_t *context)
 {
-    int count, i, j;
-    acr_uint32_t lo_bit_count, hi_bit_count, k;
-
-    lo_bit_count = context->count_lo;
-    hi_bit_count = context->count_hi;
-    count = (int) ((lo_bit_count >> 3) & 0x3f);
-    ((acr_byte_t *) context->data)[count++] = 0x80;
+    unsigned int i;
 
-    if (count > SHA_BLOCKSIZE - 8) {
-        memset(((acr_byte_t *) context->data) + count, 0, SHA_BLOCKSIZE - 
count);
-#if !CC_IS_BIG_ENDIAN
-        byte_reverse(context->data, SHA_BLOCKSIZE);
-#endif
-        sha_transform(context);
-        memset((acr_byte_t *) context->data, 0, SHA_BLOCKSIZE - 8);
-    }
-    else {
-        memset(((acr_byte_t *) context->data) + count, 0,
-               SHA_BLOCKSIZE - 8 - count);
-    }
-#if !CC_IS_BIG_ENDIAN
-    byte_reverse(context->data, SHA_BLOCKSIZE);
-#endif
-    context->data[14] = hi_bit_count;
-    context->data[15] = lo_bit_count;
-    sha_transform(context);
-
-    for (i = 0, j = 0; j < ACR_SHA1_DIGESTSIZE; i++) {
-        k = context->digest[i];
-        digest[j++] = (unsigned char)((k >> 24) & 0xff);
-        digest[j++] = (unsigned char)((k >> 16) & 0xff);
-        digest[j++] = (unsigned char)((k >> 8 ) & 0xff);
-        digest[j++] = (unsigned char)( k        & 0xff);
+    sha1pad(context);
+    if (digest) {
+        for (i = 0; i < ACR_SHA1_DIGEST_LENGTH; i++) {
+            digest[i] = (acr_byte_t)
+               ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
+        }
+        memset(context, 0, sizeof(*context));
     }
 }
 
-ACR_DECLARE(void) ACR_Sha1Base16A(const char *clear, int len, char *out)
+ACR_DECLARE(char *) ACR_Sha1Base16A(const char *clear, size_t len, char *out)
 {
     int i, x = 0;
     acr_sha1_ctx_t context;
-    acr_byte_t digest[ACR_SHA1_DIGESTSIZE];
+    acr_byte_t digest[ACR_SHA1_DIGEST_LENGTH];
+
+    if (out == NULL && (out = malloc(ACR_SHA1_DIGEST_STRING_LENGTH)) == NULL)
+        return NULL;
 
     ACR_Sha1Init(&context);
     ACR_Sha1UpdateA(&context, clear, len);
     ACR_Sha1Final(digest, &context);
-    for (i = 0; i < ACR_SHA1_DIGESTSIZE; i++) {
+    for (i = 0; i < ACR_SHA1_DIGEST_LENGTH; i++) {
         out[x++] = HI_NIBBLE_HEX(digest[i]);
         out[x++] = LO_NIBBLE_HEX(digest[i]);
     }
     out[x] = '\0';
 
+    memset(digest, 0, sizeof(digest));
+    return out;
 }
 
-ACR_DECLARE(void) ACR_Sha1Base16W(const wchar_t *clear, int len, wchar_t *out)
+ACR_DECLARE(wchar_t *) ACR_Sha1Base16W(const wchar_t *clear, size_t len,
+                                       wchar_t *out)
 {
     int i, x = 0;
     acr_sha1_ctx_t context;
-    acr_byte_t digest[ACR_SHA1_DIGESTSIZE];
+    acr_byte_t digest[ACR_SHA1_DIGEST_LENGTH];
+
+    if (out == NULL &&
+       (out = malloc(ACR_SHA1_DIGEST_STRING_LENGTH * sizeof(wchar_t))) == NULL)
+        return NULL;
 
     ACR_Sha1Init(&context);
     ACR_Sha1UpdateW(&context, clear, len);
     ACR_Sha1Final(digest, &context);
-    for (i = 0; i < ACR_SHA1_DIGESTSIZE; i++) {
+    for (i = 0; i < ACR_SHA1_DIGEST_LENGTH; i++) {
         out[x++] = HI_NIBBLE_HEX(digest[i]);
         out[x++] = LO_NIBBLE_HEX(digest[i]);
     }
     out[x] = L'\0';
+
+    memset(digest, 0, sizeof(digest));
+    return out;
 }
 


Reply via email to