SipHash: add separate setter for the hash size
[openssl.git] / crypto / siphash / siphash.c
index 4bf2382972064ecad92da6a4e3bf052b19188d58..e2352fc73043ec34ae51e0c49d577b73a2635a36 100644 (file)
    SipHash reference C implementation
 
    Copyright (c) 2012-2016 Jean-Philippe Aumasson
-   <jeanphilippe.aumasson@gmail.com>
-   Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>
+   Copyright (c) 2012-2014 Daniel J. Bernstein
 
    To the extent possible under law, the author(s) have dedicated all copyright
    and related and neighboring rights to this software to the public domain
    worldwide. This software is distributed without any warranty.
 
    You should have received a copy of the CC0 Public Domain Dedication along
-   with
-   this software. If not, see
+   with this software. If not, see
    <http://creativecommons.org/publicdomain/zero/1.0/>.
  */
 
@@ -82,17 +80,32 @@ size_t SipHash_hash_size(SIPHASH *ctx)
     return ctx->hash_size;
 }
 
+static size_t siphash_adjust_hash_size(size_t hash_size)
+{
+    if (hash_size == 0)
+        hash_size = SIPHASH_MAX_DIGEST_SIZE;
+    return hash_size;
+}
+
+int SipHash_set_hash_size(SIPHASH *ctx, size_t hash_size)
+{
+    hash_size = siphash_adjust_hash_size(hash_size);
+    if (hash_size != SIPHASH_MIN_DIGEST_SIZE
+        && hash_size != SIPHASH_MAX_DIGEST_SIZE)
+        return 0;
+
+    ctx->hash_size = hash_size;
+    return 1;
+}
+
 /* hash_size = crounds = drounds = 0 means SipHash24 with 16-byte output */
-int SipHash_Init(SIPHASH *ctx, const unsigned char *k, int hash_size, int crounds, int drounds)
+int SipHash_Init(SIPHASH *ctx, const unsigned char *k, int crounds, int drounds)
 {
     uint64_t k0 = U8TO64_LE(k);
     uint64_t k1 = U8TO64_LE(k + 8);
 
-    if (hash_size == 0)
-        hash_size = SIPHASH_MAX_DIGEST_SIZE;
-    else if (hash_size != SIPHASH_MIN_DIGEST_SIZE &&
-             hash_size != SIPHASH_MAX_DIGEST_SIZE)
-        return 0;
+    /* If the hash size wasn't set, i.e. is zero */
+    ctx->hash_size = siphash_adjust_hash_size(ctx->hash_size);
 
     if (drounds == 0)
         drounds = SIPHASH_D_ROUNDS;
@@ -101,7 +114,6 @@ int SipHash_Init(SIPHASH *ctx, const unsigned char *k, int hash_size, int cround
 
     ctx->crounds = crounds;
     ctx->drounds = drounds;
-    ctx->hash_size = hash_size;
 
     ctx->len = 0;
     ctx->total_inlen = 0;
@@ -191,16 +203,22 @@ int SipHash_Final(SIPHASH *ctx, unsigned char *out, size_t outlen)
     switch (ctx->len) {
     case 7:
         b |= ((uint64_t)ctx->leavings[6]) << 48;
+        /* fall thru */
     case 6:
         b |= ((uint64_t)ctx->leavings[5]) << 40;
+        /* fall thru */
     case 5:
         b |= ((uint64_t)ctx->leavings[4]) << 32;
+        /* fall thru */
     case 4:
         b |= ((uint64_t)ctx->leavings[3]) << 24;
+        /* fall thru */
     case 3:
         b |= ((uint64_t)ctx->leavings[2]) << 16;
+        /* fall thru */
     case 2:
         b |= ((uint64_t)ctx->leavings[1]) <<  8;
+        /* fall thru */
     case 1:
         b |= ((uint64_t)ctx->leavings[0]);
     case 0: