blake2b: add support for parameter setting and keyed hash
[oweals/openssl.git] / crypto / blake2 / blake2b.c
index fb128e4bb4fd028ecdfd7f2c39036377a07a71dd..b5eb928708cde0da09a76c0036ebe02854e862c8 100644 (file)
@@ -80,10 +80,9 @@ static void blake2b_init_param(BLAKE2B_CTX *S, const BLAKE2B_PARAM *P)
     }
 }
 
-/* Initialize the hashing context.  Always returns 1. */
-int BLAKE2b_Init(BLAKE2B_CTX *c)
+/* Initialize the parameter block with default values */
+void blake2b_param_init(BLAKE2B_PARAM *P)
 {
-    BLAKE2B_PARAM P[1];
     P->digest_length = BLAKE2B_DIGEST_LENGTH;
     P->key_length    = 0;
     P->fanout        = 1;
@@ -95,10 +94,60 @@ int BLAKE2b_Init(BLAKE2B_CTX *c)
     memset(P->reserved, 0, sizeof(P->reserved));
     memset(P->salt,     0, sizeof(P->salt));
     memset(P->personal, 0, sizeof(P->personal));
+}
+
+void blake2b_param_set_digest_length(BLAKE2B_PARAM *P, uint8_t outlen)
+{
+    P->digest_length = outlen;
+}
+
+void blake2b_param_set_key_length(BLAKE2B_PARAM *P, uint8_t keylen)
+{
+    P->key_length = keylen;
+}
+
+void blake2b_param_set_personal(BLAKE2B_PARAM *P, const uint8_t *personal, size_t len)
+{
+    memcpy(P->personal, personal, len);
+    memset(P->personal + len, 0, BLAKE2B_PERSONALBYTES - len);
+}
+
+void blake2b_param_set_salt(BLAKE2B_PARAM *P, const uint8_t *salt, size_t len)
+{
+    memcpy(P->salt, salt, len);
+    memset(P->salt + len, 0, BLAKE2B_SALTBYTES - len);
+}
+
+/*
+ * Initialize the hashing context with the given parameter block.
+ * Always returns 1.
+ */
+int BLAKE2b_Init(BLAKE2B_CTX *c, const BLAKE2B_PARAM *P)
+{
     blake2b_init_param(c, P);
     return 1;
 }
 
+/*
+ * Initialize the hashing context with the given parameter block and key.
+ * Always returns 1.
+ */
+int BLAKE2b_Init_key(BLAKE2B_CTX *c, const BLAKE2B_PARAM *P, const void *key)
+{
+    blake2b_init_param(c, P);
+
+    /* Pad the key to form first data block */
+    {
+        uint8_t block[BLAKE2B_BLOCKBYTES] = {0};
+
+        memcpy(block, key, P->key_length);
+        BLAKE2b_Update(c, block, BLAKE2B_BLOCKBYTES);
+        OPENSSL_cleanse(block, BLAKE2B_BLOCKBYTES);
+    }
+
+    return 1;
+}
+
 /* Permute the state while xoring in the block of data. */
 static void blake2b_compress(BLAKE2B_CTX *S,
                             const uint8_t *blocks,