Print this page
4185 New hash algorithm support

@@ -1,9 +1,12 @@
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
+/*
+ * Copyright 2013 Saso Kiselkov.  All rights reserved.
+ */
 
 /*
  * The basic framework for this code came from the reference
  * implementation for MD5.  That implementation is Copyright (C)
  * 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved.

@@ -713,10 +716,30 @@
                 ctx->state.s64[4] = 0x510e527fade682d1ULL;
                 ctx->state.s64[5] = 0x9b05688c2b3e6c1fULL;
                 ctx->state.s64[6] = 0x1f83d9abfb41bd6bULL;
                 ctx->state.s64[7] = 0x5be0cd19137e2179ULL;
                 break;
+        case SHA512_224_MECH_INFO_TYPE:
+                ctx->state.s64[0] = 0x8C3D37C819544DA2ULL;
+                ctx->state.s64[1] = 0x73E1996689DCD4D6ULL;
+                ctx->state.s64[2] = 0x1DFAB7AE32FF9C82ULL;
+                ctx->state.s64[3] = 0x679DD514582F9FCFULL;
+                ctx->state.s64[4] = 0x0F6D2B697BD44DA8ULL;
+                ctx->state.s64[5] = 0x77E36F7304C48942ULL;
+                ctx->state.s64[6] = 0x3F9D85A86A1D36C8ULL;
+                ctx->state.s64[7] = 0x1112E6AD91D692A1ULL;
+                break;
+        case SHA512_256_MECH_INFO_TYPE:
+                ctx->state.s64[0] = 0x22312194FC2BF72CULL;
+                ctx->state.s64[1] = 0x9F555FA3C84C64C2ULL;
+                ctx->state.s64[2] = 0x2393B86B6F53B151ULL;
+                ctx->state.s64[3] = 0x963877195940EABDULL;
+                ctx->state.s64[4] = 0x96283EE2A88EFFE3ULL;
+                ctx->state.s64[5] = 0xBE5E1E2553863992ULL;
+                ctx->state.s64[6] = 0x2B0199FC2C85B8AAULL;
+                ctx->state.s64[7] = 0x0EB72DDC81C52CA2ULL;
+                break;
 #ifdef _KERNEL
         default:
                 cmn_err(CE_PANIC,
                     "sha2_init: failed to find a supported algorithm: 0x%x",
                     (uint32_t)mech);

@@ -899,11 +922,10 @@
                 index  = (ctx->count.c32[1] >> 3) & 0x3f;
                 Encode(bitcount_be, ctx->count.c32, sizeof (bitcount_be));
                 SHA2Update(ctx, PADDING, ((index < 56) ? 56 : 120) - index);
                 SHA2Update(ctx, bitcount_be, sizeof (bitcount_be));
                 Encode(digest, ctx->state.s32, sizeof (ctx->state.s32));
-
         } else {
                 index  = (ctx->count.c64[1] >> 3) & 0x7f;
                 Encode64(bitcount_be64, ctx->count.c64,
                     sizeof (bitcount_be64));
                 SHA2Update(ctx, PADDING, ((index < 112) ? 112 : 240) - index);

@@ -910,13 +932,29 @@
                 SHA2Update(ctx, bitcount_be64, sizeof (bitcount_be64));
                 if (algotype <= SHA384_HMAC_GEN_MECH_INFO_TYPE) {
                         ctx->state.s64[6] = ctx->state.s64[7] = 0;
                         Encode64(digest, ctx->state.s64,
                             sizeof (uint64_t) * 6);
-                } else
+                } else if (algotype == SHA512_224_MECH_INFO_TYPE) {
+                        uint8_t last[sizeof (uint64_t)];
+                        /*
+                         * Since SHA-512/224 doesn't align well to 64-bit
+                         * boundaries, we must do the encode in three steps:
+                         * 1) encode the three 64-bit words that fit neatly
+                         * 2) encode the last 64-bit word to a temp buffer
+                         * 3) chop out the lower 32-bits from the temp buffer
+                         *    and append them to the digest
+                         */
+                        Encode64(digest, ctx->state.s64, sizeof (uint64_t) * 3);
+                        Encode64(last, &ctx->state.s64[3], sizeof (uint64_t));
+                        bcopy(last, (uint8_t *)digest + 24, 4);
+                } else if (algotype == SHA512_256_MECH_INFO_TYPE) {
+                        Encode64(digest, ctx->state.s64, sizeof (uint64_t) * 4);
+                } else {
                         Encode64(digest, ctx->state.s64,
                             sizeof (ctx->state.s64));
         }
+        }
 
         /* zeroize sensitive information */
         bzero(ctx, sizeof (*ctx));
 }