symm/sha512.[ch], etc.: Support SHA512/224 and SHA512/256.
[catacomb] / symm / sha512.c
index 04b0a9d..ed022ca 100644 (file)
@@ -36,7 +36,7 @@
 
 /*----- Main code ---------------------------------------------------------*/
 
-/* --- @sha512_compress@, @sha384_compress@ --- *
+/* --- @sha512_compress@, etc. --- *
  *
  * Arguments:  @sha512_ctx *ctx@ = pointer to context block
  *             @const void *sbuf@ = pointer to buffer of appropriate size
@@ -176,7 +176,7 @@ void sha512_compress(sha512_ctx *ctx, const void *sbuf)
   ADD64(ctx->h, ctx->h, h);
 }
 
-/* --- @sha512_init@, @sha384_init@ --- *
+/* --- @sha512_init@, etc. --- *
  *
  * Arguments:  @sha512_ctx *ctx@ = pointer to context block to initialize
  *
@@ -213,7 +213,35 @@ void sha384_init(sha512_ctx *ctx)
   ctx->nh = ctx->nl = 0;
 }
 
-/* --- @sha512_set@, @sha384_set@ --- *
+void sha512_256_init(sha512_ctx *ctx)
+{
+  SET64(ctx->a,        0x22312194, 0xfc2bf72c);
+  SET64(ctx->b,        0x9f555fa3, 0xc84c64c2);
+  SET64(ctx->c,        0x2393b86b, 0x6f53b151);
+  SET64(ctx->d,        0x96387719, 0x5940eabd);
+  SET64(ctx->e,        0x96283ee2, 0xa88effe3);
+  SET64(ctx->f,        0xbe5e1e25, 0x53863992);
+  SET64(ctx->g,        0x2b0199fc, 0x2c85b8aa);
+  SET64(ctx->h,        0x0eb72ddc, 0x81c52ca2);
+  ctx->off = 0;
+  ctx->nh = ctx->nl = 0;
+}
+
+void sha512_224_init(sha512_ctx *ctx)
+{
+  SET64(ctx->a,        0x8c3d37c8, 0x19544da2);
+  SET64(ctx->b,        0x73e19966, 0x89dcd4d6);
+  SET64(ctx->c,        0x1dfab7ae, 0x32ff9c82);
+  SET64(ctx->d,        0x679dd514, 0x582f9fcf);
+  SET64(ctx->e,        0x0f6d2b69, 0x7bd44da8);
+  SET64(ctx->f,        0x77e36f73, 0x04c48942);
+  SET64(ctx->g,        0x3f9d85a8, 0x6a1d36c8);
+  SET64(ctx->h,        0x1112e6ad, 0x91d692a1);
+  ctx->off = 0;
+  ctx->nh = ctx->nl = 0;
+}
+
+/* --- @sha512_set@, etc. --- *
  *
  * Arguments:  @sha512_ctx *ctx@ = pointer to context block
  *             @const void *buf@ = pointer to state buffer
@@ -259,7 +287,7 @@ void sha512_hash(sha512_ctx *ctx, const void *buf, size_t sz)
   HASH_BUFFER(SHA512, sha512, ctx, buf, sz);
 }
 
-/* --- @sha512_done@, @sha384_done@ --- *
+/* --- @sha512_done@, etc. --- *
  *
  * Arguments:  @sha512_ctx *ctx@ = pointer to context block
  *             @void *hash@ = pointer to output buffer
@@ -292,7 +320,7 @@ void sha512_done(sha512_ctx *ctx, void *hash)
   STORE64_(p + 56, ctx->h);
 }
 
-void sha384_done(sha384_ctx *ctx, void *hash)
+void sha384_done(sha512_ctx *ctx, void *hash)
 {
   octet *p = hash;
   final(ctx);
@@ -304,7 +332,27 @@ void sha384_done(sha384_ctx *ctx, void *hash)
   STORE64_(p + 40, ctx->f);
 }
 
-/* --- @sha512_state@, @sha384_state@ --- *
+void sha512_256_done(sha384_ctx *ctx, void *hash)
+{
+  octet *p = hash;
+  final(ctx);
+  STORE64_(p + 0, ctx->a);
+  STORE64_(p + 8, ctx->b);
+  STORE64_(p + 16, ctx->c);
+  STORE64_(p + 24, ctx->d);
+}
+
+void sha512_224_done(sha384_ctx *ctx, void *hash)
+{
+  octet *p = hash;
+  final(ctx);
+  STORE64_(p + 0, ctx->a);
+  STORE64_(p + 8, ctx->b);
+  STORE64_(p + 16, ctx->c);
+  STORE32 (p + 24, HI64(ctx->d));
+}
+
+/* --- @sha512_state@, etc. --- *
  *
  * Arguments:  @sha512_ctx *ctx@ = pointer to context
  *             @void *state@ = pointer to buffer for current state
@@ -332,6 +380,8 @@ unsigned long sha512_state(sha512_ctx *ctx, void *state)
 /* --- Generic interface --- */
 
 #define HASHES(_)                                                      \
+  _(SHA512_224, sha512_224, "sha512/224")                              \
+  _(SHA512_256, sha512_256, "sha512/256")                              \
   _(SHA384, sha384, "sha384")                                          \
   _(SHA512, sha512, "sha512")