Print this page
5072961 Need an optimized MD5 implementation for amd64

@@ -1,17 +1,17 @@
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
 /*
  * Cleaned-up and optimized version of MD5, based on the reference
  * implementation provided in RFC 1321.  See RSA Copyright information
  * below.
  */
 
-#pragma ident   "@(#)md5.c      1.27    07/04/10 SMI"
+#pragma ident   "@(#)md5.c      1.28    08/01/02 SMI"
 
 /*
  * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
  */
 

@@ -49,12 +49,18 @@
 #ifdef _KERNEL
 #include <sys/systm.h>
 #endif /* _KERNEL */
 
 static void Encode(uint8_t *, const uint32_t *, size_t);
+
+#if !defined(__amd64)
 static void MD5Transform(uint32_t, uint32_t, uint32_t, uint32_t, MD5_CTX *,
     const uint8_t [64]);
+#else
+void md5_block_asm_host_order(MD5_CTX *ctx, const void *inpp,
+    unsigned int input_length_in_blocks);
+#endif /* !defined(__amd64) */
 
 static uint8_t PADDING[64] = { 0x80, /* all zeros */ };
 
 /*
  * F, G, H and I are the basic MD5 functions.

@@ -241,10 +247,13 @@
 {
         uint32_t                i, buf_index, buf_len;
 #ifdef  sun4v
         uint32_t                old_asi;
 #endif  /* sun4v */
+#if defined(__amd64)
+        uint32_t                block_count;
+#endif /* !defined(__amd64) */
         const unsigned char     *input = (const unsigned char *)inpp;
 
         /* compute (number of bytes computed so far) mod 64 */
         buf_index = (ctx->count[0] >> 3) & 0x3F;
 

@@ -280,22 +289,35 @@
 #endif /* sun4v */
 
                 if (buf_index) {
                         bcopy(input, &ctx->buf_un.buf8[buf_index], buf_len);
 
+#if !defined(__amd64)
                         MD5Transform(ctx->state[0], ctx->state[1],
                             ctx->state[2], ctx->state[3], ctx,
                             ctx->buf_un.buf8);
+#else
+                        md5_block_asm_host_order(ctx, ctx->buf_un.buf8, 1);
+#endif /* !defined(__amd64) */
 
                         i = buf_len;
                 }
 
+#if !defined(__amd64)
                 for (; i + 63 < input_len; i += 64)
                         MD5Transform(ctx->state[0], ctx->state[1],
                             ctx->state[2], ctx->state[3], ctx, &input[i]);
 
+#else
+                block_count = (input_len - i) >> 6;
+                if (block_count > 0) {
+                        md5_block_asm_host_order(ctx, &input[i], block_count);
+                        i += block_count << 6;
+                }
+#endif /* !defined(__amd64) */
 
+
 #ifdef sun4v
                 /*
                  * Restore old %ASI value
                  */
                 set_little(old_asi);

@@ -365,10 +387,11 @@
         MD5Final(output, &context);
 }
 
 #endif  /* !_KERNEL */
 
+#if !defined(__amd64)
 /*
  * sparc register window optimization:
  *
  * `a', `b', `c', and `d' are passed into MD5Transform explicitly
  * since it increases the number of registers available to the

@@ -633,10 +656,11 @@
          */
 
         x_0 = x_1  = x_2  = x_3  = x_4  = x_5  = x_6  = x_7 = x_8 = 0;
         x_9 = x_10 = x_11 = x_12 = x_13 = x_14 = x_15 = 0;
 }
+#endif /* !defined(__amd64) */
 
 /*
  * Encode()
  *
  * purpose: to convert a list of numbers from big endian to little endian