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 <[email protected]>
+ * 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;
}