Skip to content
This repository has been archived by the owner on Sep 20, 2023. It is now read-only.

Commit

Permalink
add support for FIPS 180-4 truncated SHA512 value.
Browse files Browse the repository at this point in the history
  • Loading branch information
vincenthz committed Feb 19, 2011
1 parent 6524c8c commit 15cac90
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 0 deletions.
9 changes: 9 additions & 0 deletions Crypto/Hash/SHA512.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ module Crypto.Hash.SHA512

-- * Incremental hashing Functions
, init -- :: Ctx
, init_t -- :: Int -> Ctx
, update -- :: Ctx -> ByteString -> Ctx
, finalize -- :: Ctx -> ByteString

Expand Down Expand Up @@ -72,6 +73,9 @@ instance Storable Ctx where
foreign import ccall unsafe "sha512.h sha512_init"
c_sha512_init :: Ptr Ctx -> IO ()

foreign import ccall unsafe "sha512.h sha512_init_t"
c_sha512_init_t :: Ptr Ctx -> Int -> IO ()

foreign import ccall "sha512.h sha512_update"
c_sha512_update :: Ptr Ctx -> CString -> Word32 -> IO ()

Expand All @@ -97,6 +101,11 @@ finalizeInternalIO ptr =
init :: Ctx
init = unsafePerformIO $ allocInternal $ \ptr -> do (c_sha512_init ptr >> peek ptr)

{-# NOINLINE init_t #-}
-- | init a context using FIPS 180-4 for truncated SHA512
init_t :: Int -> Ctx
init_t t = unsafePerformIO $ allocInternal $ \ptr -> do (c_sha512_init_t ptr t >> peek ptr)

{-# NOINLINE update #-}
-- | update a context with a bytestring
update :: Ctx -> ByteString -> Ctx
Expand Down
50 changes: 50 additions & 0 deletions cbits/sha512.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,3 +193,53 @@ void sha512_finalize(struct sha512_ctx *ctx, uint8_t *out)
for (i = 0; i < 8; i++)
p[i] = cpu_to_be64(ctx->h[i]);
}

#include <stdio.h>

void sha512_init_t(struct sha512_ctx *ctx, int t)
{
memset(ctx, 0, sizeof(*ctx));
if (t >= 512)
return;

switch (t) {
case 224:
ctx->h[0] = 0x8c3d37c819544da2ULL;
ctx->h[1] = 0x73e1996689dcd4d6ULL;
ctx->h[2] = 0x1dfab7ae32ff9c82ULL;
ctx->h[3] = 0x679dd514582f9fcfULL;
ctx->h[4] = 0x0f6d2b697bd44da8ULL;
ctx->h[5] = 0x77e36f7304c48942ULL;
ctx->h[6] = 0x3f9d85a86a1d36c8ULL;
ctx->h[7] = 0x1112e6ad91d692a1ULL;
break;
case 256:
ctx->h[0] = 0x22312194fc2bf72cULL;
ctx->h[1] = 0x9f555fa3c84c64c2ULL;
ctx->h[2] = 0x2393b86b6f53b151ULL;
ctx->h[3] = 0x963877195940eabdULL;
ctx->h[4] = 0x96283ee2a88effe3ULL;
ctx->h[5] = 0xbe5e1e2553863992ULL;
ctx->h[6] = 0x2b0199fc2c85b8aaULL;
ctx->h[7] = 0x0eb72ddc81c52ca2ULL;
break;
default: {
char buf[8+4];
uint8_t out[64];
int i;

sha512_init(ctx);
for (i = 0; i < 8; i++)
ctx->h[i] ^= 0xa5a5a5a5a5a5a5a5ULL;

i = sprintf(buf, "SHA-512/%d", t);
sha512_update(ctx, buf, i);
sha512_finalize(ctx, out);

/* re-init the context, otherwise len is changed */
memset(ctx, 0, sizeof(*ctx));
for (i = 0; i < 8; i++)
ctx->h[i] = cpu_to_be64(((uint64_t *) out)[i]);
}
}
}
2 changes: 2 additions & 0 deletions cbits/sha512.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,6 @@ void sha512_init(struct sha512_ctx *ctx);
void sha512_update(struct sha512_ctx *ctx, uint8_t *data, uint32_t len);
void sha512_finalize(struct sha512_ctx *ctx, uint8_t *out);

void sha512_init_t(struct sha512_ctx *ctx, int t);

#endif

0 comments on commit 15cac90

Please sign in to comment.