]> git.codecow.com Git - Monocypher.git/commitdiff
Add HKDF SHA-512
authorLoup Vaillant <loup@loup-vaillant.fr>
Wed, 1 Feb 2023 22:03:06 +0000 (23:03 +0100)
committerLoup Vaillant <loup@loup-vaillant.fr>
Wed, 1 Feb 2023 22:16:39 +0000 (23:16 +0100)
In principle, we can imitate HKDF quite easily with SHA-512 alone.
Being fully RFC compliant however is fiddly and tedious, so for users
who want to do key derivation with SHA-512 in the most standard way
possible need dedicated functions.

Note the absence of a `crypto_sha512_hkdf_extract()` function, which
would be nothing more than an alias of `crypto_sha512_hmac()`.  Aliases
to the equivalent incremental interface are also absent.  There are pros
and cons to both the presence and absence of those aliases, I personally
prefer to leave them out.

See #255

doc/crypto_sha512.3monocypher
src/optional/monocypher-ed25519.c
src/optional/monocypher-ed25519.h
tests/gen/makefile
tests/gen/sha512_hkdf.py [new file with mode: 0755]
tests/test.c
tests/tis-ci-gen-config.sh
tests/tis-ci-vectors.h
tests/tis-ci.c
tis.config

index 66c0e8fa7860d08f8bf4b522c7450cada4fc30ca..62ba438a01d9531de031207d6a35e292d395801e 100644 (file)
 .Nm crypto_sha512_hmac ,
 .Nm crypto_sha512_hmac_init ,
 .Nm crypto_sha512_hmac_update ,
-.Nm crypto_sha512_hmac_final
-.Nd hashing and message authenticaton with SHA-512
+.Nm crypto_sha512_hmac_final ,
+.Nm crypto_sha512_hkdf ,
+.Nm crypto_sha512_hkdf_expand
+.Nd hashing, message authentication, and key derivation with SHA-512
 .Sh SYNOPSIS
 .In monocypher-ed25519.h
 .Ft void
 .Fa "crypto_sha512_hmac_ctx *ctx"
 .Fa "uint8_t hmac[64]"
 .Fc
+.Fo crypto_sha512_hkdf
+.Fa "uint8_t *okm"
+.Fa "size_t okm_size"
+.Fa "const uint8_t *ikm"
+.Fa "size_t ikm_size"
+.Fa "const uint8_t *salt"
+.Fa "size_t salt_size"
+.Fa "const uint8_t *info"
+.Fa "size_t info_size"
+.Fc
+.Ft void
+.Fo crypto_sha512_hkdf_expand
+.Fa "uint8_t *okm"
+.Fa "size_t okm_size"
+.Fa "const uint8_t *prk"
+.Fa "size_t prk_size"
+.Fa "const uint8_t *info"
+.Fa "size_t info_size"
+.Fc
+.Ft void
 .Sh DESCRIPTION
+.Ss Hashing
 .Fn crypto_sha512 ,
 .Fn crypto_sha512_init ,
 .Fn crypto_sha512_update ,
@@ -140,6 +163,24 @@ For those, use the
 .Fn crypto_sha512_hmac
 family of functions instead.
 .Pp
+The arguments are:
+.Bl -tag -width Ds
+.It Fa hash
+The output SHA-512 hash,
+which is always 64-bytes long.
+.It Fa message
+The message to hash.
+May be
+.Dv NULL
+if
+.Fa message_size
+is 0.
+.It Fa message_size
+Length of
+.Fa message ,
+in bytes.
+.El
+.Ss Message authentication codes
 .Fn crypto_sha512_hmac ,
 .Fn crypto_sha512_hmac_init ,
 .Fn crypto_sha512_hmac_update ,
@@ -157,9 +198,6 @@ as it performs faster on x86_64 CPUs.
 .Pp
 The arguments are:
 .Bl -tag -width Ds
-.It Fa hash
-The output SHA-512 hash,
-which is always 64-bytes long.
 .It Fa hmac
 The output MAC,
 which is always 64-bytes long.
@@ -172,23 +210,18 @@ use
 or
 .Xr crypto_verify64 3monocypher
 to compare (possibly truncated) MACs.
-.It Fa message
-The message to hash, or compute the HMAC for.
-May be
-.Dv NULL
-if
-.Fa message_size
-is 0.
-.It Fa message_size
-Length of
-.Fa message ,
-in bytes.
 .It Fa key
 Some secret key.
-One cannot predict the final HMAC without it.
+When uniformly random,
+one cannot predict the final HMAC without it.
 Users may want to wipe the key with
 .Xr crypto_wipe 3monocypher
 once they are done with it.
+Also stands for the
+.Fa salt
+argument when using
+.Fn crypto_sha512_hmac
+for HKDF extraction.
 .It Fa key_size
 Length of
 .Fa key ,
@@ -196,8 +229,131 @@ in bytes.
 32 is a good default.
 Keys longer than 128 bytes will be reduced to 64 bytes by hashing
 the key with SHA-512.
+.It Fa message
+The message to compute the HMAC for.
+May be
+.Dv NULL
+if
+.Fa message_size
+is 0.
+Also stands for the
+.Fa ikm
+argument when using
+.Fn crypto_sha512_hmac
+for HKDF extraction.
+.It Fa message_size
+Length of
+.Fa message ,
+in bytes.
 .El
+.Ss Key derivation
+.Fn crypto_sha512_hkdf
+and
+.Fn crypto_sha512_hkdf_expand
+implement HKDF key derivation on top of SHA-512.
+HKDF is divided in two phases:
+first we
+.Em extract
+entropy from some input key material to produce a
+.Em pseudo-random key
+(PRK) which is indistinguishable from uniform random bytes.
+Then we
+.Em expand
+that pseudo-random key into a longer stream of independent random bytes
+called
+.Em output key material
+(OKM).
+.Pp
+HKDF extraction is already implemented in
+.Fn crypto_sha512_hmac ,
+so there is no dedicated function.
+HKDF expansion is implemented by
+.Fn crypto_sha512_hkdf_expand .
+Note that expansion works with any uniformly random key,
+the PRK does not have to come from
+.Fn crypto_sha512_hmac
+specifically.
+Likewise,
+if compatibility or standard compliance is not an issue,
+expansion could in principle use any pseudo-random function,
+such as
+.Xr crypto_chacha20_djb 3monocypher .
 .Pp
+.Fn crypto_sha512_hkdf
+is a convenience function that performs
+.Fn crypto_sha512_hmac
+and
+.Fn crypto_sha512_hkdf_expand .
+.Pp
+Contrary to most functions in Monocypher,
+the inputs of
+.Fn crypto_sha512_hkdf
+and
+.Fn crypto_sha512_hkdf_expand
+.Em cannot overlap
+with their output.
+The unlimited size of both inputs and output prevents us from from
+caching one of them in a local variable.
+.Pp
+The arguments are:
+.Bl -tag -width Ds
+.It Fa okm
+The output key material of HKDF or HKDF expansion,
+usable as a symmetric encryption key,
+or set thereof.
+.It Fa okm_size
+Length of
+.Fa okm ,
+in bytes.
+.It Fa ikm
+Input key material containing enough secret entropy to derive uniformly
+random keys from,
+such as the shared secret of a key exchange performed with
+.Xr crypto_x25519 3monocypher .
+Passwords do
+.Sy not
+contain enough entropy to be used as input key material.
+Hash them with
+.Xr crypto_argon2 3monocypher
+instead.
+.It Fa ikm_size
+Length of
+.Fa ikm ,
+in bytes.
+.It Fa prk
+Pseudo-random key.
+Typically comes from an HKDF extraction with
+.Fn crypto_sha512_hmac ,
+but can come from any source as long as it is uniformly random.
+Should be at least 32 bytes long.
+.It Fa prk_size
+Length of
+.Fa prk ,
+in bytes.
+.It Fa salt
+An optional random salt,
+used to increase the security of the output key material
+.Fa okm
+in some settings.
+Can be NULL if
+.Fa salt_size
+is zero.
+Otherwise it should contain at least 16 bytes.
+.It Fa salt_size
+Length of
+.Fa salt,
+in bytes.
+.It Fa info
+Optional domain separation string for key derivation.
+Can be NULL if
+.Fa info_size
+is zero.
+.It Fa info_size
+Length of
+.Fa info ,
+in bytes.
+.El
+.Ss Incremental interface
 An incremental interface is provided.
 It is useful for handling streams of data or
 large files without using too much memory.
@@ -295,17 +451,68 @@ for (size_t i = 0; i < 500; i += 100) {
 }
 crypto_sha512_hmac_final(&ctx, hash);
 .Ed
+.Pp
+Deriving keys from input key material:
+.Bd -literal -offset indent
+uint8_t okm[128];                 /* Output random keys */
+uint8_t ikm [96];                 /* Input key material */
+uint8_t salt[16];                 /* Random salt        */
+uint8_t info[11] = "Lorem ipsum"; /* Domain separation  */
+arc4random_buf(salt, sizeof(salt));
+crypto_sha512_hkdf(okm, sizeof(okm),
+                   ikm, sizeof(ikm),
+                   salt, sizeof(salt),
+                   info, sizeof(info));
+uint8_t *key1 = okm +  0;
+uint8_t *key2 = okm + 32;
+uint8_t *key3 = okm + 64;
+uint8_t *key4 = okm + 96;
+/* Wipe okm when it is no longer needed */
+.Ed
+.Pp
+Deriving keys from several bits of input key material:
+.Bd -literal -offset indent
+uint8_t okm [96];            /* Output secret keys        */
+uint8_t pk_a[32];            /* Alice public X25519 key   */
+uint8_t pk_b[32];            /* Bob   public X25519 key   */
+uint8_t skab[32];            /* Alice & bob shared secret */
+uint8_t ikm [96];            /* Input key material        */
+uint8_t salt[16];            /* Random salt               */
+uint8_t info[ 6] = "X25519"; /* Domain separation         */
+arc4random_buf(salt, sizeof(salt));
+
+/* Extract */
+uint8_t prk[64];             /* pseudo-random key         */
+crypto_sha512_hmac_ctx ctx;
+crypto_sha512_hmac_init  (&ctx);
+crypto_sha512_hmac_update(&ctx, pk_a);
+crypto_sha512_hmac_update(&ctx, pk_b);
+crypto_sha512_hmac_update(&ctx, skab);
+crypto_sha512_hmac_final (&ctx, prk);
+
+/* Expand */
+crypto_sha512_hkdf_expand(okm, sizeof(okm),
+                          prk, sizeof(prk),
+                          info, sizeof(info));
+uint8_t *key1 = okm +  0;
+uint8_t *key2 = okm + 32;
+uint8_t *key3 = okm + 64;
+/* Wipe okm when it is no longer needed */
+.Ed
 .Sh SEE ALSO
 .Xr crypto_blake2b 3monocypher ,
 .Xr crypto_lock 3monocypher ,
 .Xr crypto_poly1305 3monocypher ,
 .Xr intro 3monocypher
 .Sh STANDARDS
-These functions implement SHA-512 and HMAC with SHA-512.
+These functions implement SHA-512,
+HMAC with SHA-512,
+and HKDF with SHA-512.
 HMAC and SHA-512 are described in RFC 6234;
 SHA-512 is also described in the Federal Information Processing Standard
 (FIPS) 180-4;
 HMAC is also described in FIPS 198-1.
+HKDF is described in RFC 5869.
 .Sh HISTORY
 The
 .Fn crypto_sha512 ,
@@ -332,6 +539,11 @@ then renamed
 and
 .Fn crypto_sha512_hmac_final
 in Monocypher 4.0.0.
+.Pp
+.Fn crypto_sha512_hkdf
+and
+.Fn crypto_sha512_hkdf_expand
+were added in Monocypher 4.0.0.
 .Sh SECURITY CONSIDERATIONS
 SHA-512 is a general-purpose cryptographic hash function;
 this means that it is not suited for hashing passwords and deriving
@@ -347,3 +559,15 @@ computationally difficult hashing algorithms.
 Monocypher therefore provides
 .Xr crypto_argon2i 3monocypher
 for password hashing and deriving keys from passwords.
+.Pp
+While HKDF and HMAC are proper key derivation functions (KDF),
+the HKDF expand step alone is
+.Em not .
+It is a
+.Em pseudo-random function
+(PRF),
+that only works with a
+.Em uniformly
+random key.
+We cannot simply input regular (non uniform) input key material
+without making unusually strong assumptions about the security of HMAC.
index 2daae15b1d8cfdaec4e8846bb648f62e9ce9f4f8..2dfa9ac8bff1b146382ca5caa26d55bf6a594439 100644 (file)
@@ -334,6 +334,53 @@ void crypto_sha512_hmac(u8 hmac[64], const u8 *key, size_t key_size,
        crypto_sha512_hmac_final (&ctx, hmac);
 }
 
+////////////////////
+/// HKDF SHA 512 ///
+////////////////////
+void crypto_sha512_hkdf_expand(u8       *okm,  size_t okm_size,
+                               const u8 *prk,  size_t prk_size,
+                               const u8 *info, size_t info_size)
+{
+       int not_first = 0;
+       u8 ctr = 1;
+       u8 blk[64];
+
+       while (okm_size > 0) {
+               size_t out_size = MIN(okm_size, sizeof(blk));
+
+               crypto_sha512_hmac_ctx ctx;
+               crypto_sha512_hmac_init(&ctx, prk , prk_size);
+               if (not_first) {
+                       // For some reason HKDF uses some kind of CBC mode.
+                       // For some reason CTR mode alone wasn't enough.
+                       // Like what, they didn't trust HMAC in 2010?  Really??
+                       crypto_sha512_hmac_update(&ctx, blk , sizeof(blk));
+               }
+               crypto_sha512_hmac_update(&ctx, info, info_size);
+               crypto_sha512_hmac_update(&ctx, &ctr, 1);
+               crypto_sha512_hmac_final(&ctx, blk);
+
+               COPY(okm, blk, out_size);
+
+               not_first = 1;
+               okm      += 64;
+               okm_size -= out_size;
+               ctr++;
+       }
+}
+
+void crypto_sha512_hkdf(u8       *okm , size_t okm_size,
+                        const u8 *ikm , size_t ikm_size,
+                        const u8 *salt, size_t salt_size,
+                        const u8 *info, size_t info_size)
+{
+       // Extract
+       u8 prk[64];
+       crypto_sha512_hmac(prk, salt, salt_size, ikm, ikm_size);
+
+       // Expand
+       crypto_sha512_hkdf_expand(okm, okm_size, prk, sizeof(prk), info, info_size);
+}
 
 ///////////////
 /// Ed25519 ///
index 9402b933eaed140668ede4d2f2da3620423a6d49..d207619bf73a2afc0715d6512661d3d66548c915 100644 (file)
@@ -102,6 +102,15 @@ void crypto_sha512_hmac(uint8_t hmac[64],
                         const uint8_t *key    , size_t key_size,
                         const uint8_t *message, size_t message_size);
 
+// SHA 512 HKDF
+// ------------
+void crypto_sha512_hkdf_expand(uint8_t       *okm,  size_t okm_size,
+                               const uint8_t *prk,  size_t prk_size,
+                               const uint8_t *info, size_t info_size);
+void crypto_sha512_hkdf(uint8_t       *okm , size_t okm_size,
+                        const uint8_t *ikm , size_t ikm_size,
+                        const uint8_t *salt, size_t salt_size,
+                        const uint8_t *info, size_t info_size);
 
 // Ed25519
 // -------
index 3eccc35e6d245d23e68360bb295e14b04f125508..486045a21d33bd18034c4e5fed711dede3bb49db 100644 (file)
@@ -54,12 +54,12 @@ CFLAGS = -pedantic -Wall -Wextra
 
 .PHONY: all clean
 
-VEC     = chacha20  hchacha20  xchacha20     ietf_chacha20                \
-          aead_ietf aead_8439                                             \
-          poly1305  blake2b    sha512        sha512_hmac   argon2         \
-          edDSA     edDSA_pk   ed_25519      ed_25519_pk   ed_25519_check \
-          ed_25519ph                                                      \
-          x25519    x25519_pk  elligator_inv elligator_dir
+VEC     = chacha20 hchacha20 xchacha20 ietf_chacha20             \
+          aead_ietf aead_8439                                    \
+          poly1305 blake2b sha512 sha512_hmac sha512_hkdf argon2 \
+          edDSA edDSA_pk ed_25519 ed_25519_pk ed_25519_check     \
+          ed_25519ph                                             \
+          x25519 x25519_pk elligator_inv elligator_dir
 VEC2    = $(patsubst %, %.all.vec, $(VEC))
 HEADERS = $(patsubst %, %.h.vec  , $(VEC))
 VECTORS = ../vectors.h
@@ -74,7 +74,8 @@ elligator_inv.vec: elligator-inverse.py elligator.py elligator_scalarmult.py
        ./$< >$@
 elligator_dir.vec: elligator-direct.py elligator.py
        ./$< >$@
-
+sha512_hkdf.vec: sha512_hkdf.py
+       ./$< >$@
 %.vec: %.out
        ./$< > $@
 
@@ -119,7 +120,8 @@ aead_8439.all.vec     : aead_8439.vec
 blake2b.all.vec       : blake2b.vec       vectors/blake2b
 sha512.all.vec        : sha512.vec
 sha512_hmac.all.vec   : sha512_hmac.vec   vectors/sha512_hmac
-argon2.all.vec        : argon2.vec       vectors/argon2
+sha512_hkdf.all.vec   : sha512_hkdf.vec
+argon2.all.vec        : argon2.vec        vectors/argon2
 edDSA.all.vec         : edDSA.vec
 edDSA_pk.all.vec      : edDSA_pk.vec
 ed_25519.all.vec      : ed_25519.vec
diff --git a/tests/gen/sha512_hkdf.py b/tests/gen/sha512_hkdf.py
new file mode 100755 (executable)
index 0000000..1d696c0
--- /dev/null
@@ -0,0 +1,109 @@
+#! /usr/bin/env python3
+
+# This file is dual-licensed.  Choose whichever licence you want from
+# the two licences listed below.
+#
+# The first licence is a regular 2-clause BSD licence.  The second licence
+# is the CC-0 from Creative Commons. It is intended to release Monocypher
+# to the public domain.  The BSD licence serves as a fallback option.
+#
+# SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+#
+# ------------------------------------------------------------------------
+#
+# Copyright (c) 2023, Loup Vaillant
+# All rights reserved.
+#
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the
+#    distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# ------------------------------------------------------------------------
+#
+# Written in 2023 by Loup Vaillant
+#
+# To the extent possible under law, the author(s) have dedicated all copyright
+# and related 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
+# <https://creativecommons.org/publicdomain/zero/1.0/>
+
+from binascii                                import hexlify
+from cryptography.hazmat.primitives.hashes   import SHA512
+from cryptography.hazmat.primitives.kdf.hkdf import HKDF
+from random                                  import randrange
+from random                                  import seed
+
+seed(12345) # deterministic test vectors
+
+def rand_buf(size):
+    buf = bytearray(size)
+    for i in range(size):
+        buf[i] = randrange(0, 256)
+    return bytes(buf)
+
+def vectors(ikm_size, salt_size, info_size, okm_size):
+    ikm  = rand_buf(ikm_size)
+    salt = rand_buf(salt_size)
+    info = rand_buf(info_size)
+    okm  = HKDF(
+        algorithm = SHA512(),
+        length    = okm_size,
+        salt      = salt,
+        info      = info,
+    ).derive(ikm)
+    print(hexlify(ikm ).decode() + ":")
+    print(hexlify(salt).decode() + ":")
+    print(hexlify(info).decode() + ":")
+    print(hexlify(okm ).decode() + ":")
+
+vectors(0, 0, 0, 0)
+vectors(0, 0, 0, 64)
+
+vectors(32, 16, 8, 63)
+vectors(32, 16, 8, 64)
+vectors(32, 16, 8, 65)
+vectors(32, 16, 8, 127)
+vectors(32, 16, 8, 128)
+vectors(32, 16, 8, 129)
+
+vectors(32, 16, 8, 128)
+
+vectors(127, 16, 8, 128)
+vectors(128, 16, 8, 128)
+vectors(129, 16, 8, 128)
+
+vectors(32, 127, 8, 128)
+vectors(32, 128, 8, 128)
+vectors(32, 129, 8, 128)
+
+vectors(32, 16, 127, 128)
+vectors(32, 16, 128, 128)
+vectors(32, 16, 129, 128)
+
+vectors(127, 127, 127, 127)
+vectors(128, 128, 128, 128)
+vectors(129, 129, 129, 129)
index ca8f9b741d227718e534eeb26f5203dba24976ac..492f9fa2fa02c9e8f1ffb37391f570e60efad31c 100644 (file)
@@ -468,10 +468,23 @@ static void sha512_hmac(vector_reader *reader)
        crypto_sha512_hmac(out.buf, key.buf, key.size, msg.buf, msg.size);
 }
 
+static void sha512_hkdf(vector_reader *reader)
+{
+       vector ikm  = next_input(reader);
+       vector salt = next_input(reader);
+       vector info = next_input(reader);
+       vector okm  = next_output(reader);
+       crypto_sha512_hkdf(okm .buf, okm .size,
+                          ikm .buf, ikm .size,
+                          salt.buf, salt.size,
+                          info.buf, info.size);
+}
+
 static void test_sha512()
 {
        VECTORS(sha512);
        VECTORS(sha512_hmac);
+       VECTORS(sha512_hkdf);
 
        printf("\tSHA-512 (incremental)\n");
 #undef INPUT_SIZE
index fa0e5200dc4016b42e863bef7605e8c805bde889..8ad1a59103d94950445f9dac81ac1bf2e8bdb894 100755 (executable)
@@ -66,7 +66,8 @@ for entry_point in      \
     "v_aead_ietf"       \
     "v_blake2b"         \
     "v_sha512"          \
-    "v_hmac_sha512"     \
+    "v_sha512_hmac"     \
+    "v_sha512_hkdf"     \
     "v_argon2"          \
     "v_edDSA"           \
     "v_ed_25519"        \
index 5b0c4be179136288a40c60b9be496db9c7eab3e6..5e310f5def07d8feaaf2ebd6032acfbaf4ad5e45 100644 (file)
@@ -344,6 +344,21 @@ static const char *sha512_hmac_vectors[]={
   "ffb3011fcde35b8ff8c09a62fe02e7f17aefd1f458f3c01caa2d57b77699dd335f9670d359fc99c72b30ad3e92c9d39000b127967284cca14b759275531eaba2",
 };
 static size_t nb_sha512_hmac_vectors=45;
+static const char *sha512_hkdf_vectors[]={
+  "15b607ad7a0be00fab2b557e9a55ba304fe6d04e0e828ca83dbc4373ca84e59b220bb1a2e47c9a74bddcaad2db6239b4f538e12459bd9440d09644148e90c6d53b0d8c02eb9eeec77d33995008208f96a923d2702f69255be6d55e92f1c73353816b30ba59723c9e39f0941ef19ad6023eecd70d3295c0d05331b315caad52",
+  "01b56e40efba58a21e398e351e0c2600ef4a57e144bab0cdeb02c131c89ac632c222aa93994ae8042a68237a82abd2337be60e5fd85532ff68fdbada5f7215d974591123c90abd908d901c969445883ba195678158cca17c2bff4a33526da645bf61352d0567c1e5cf641f036f2d5ce7df45c894a8eca8882ff7905480f6c8",
+  "16a2ca0477d8d5c7531469ada982369eb3b2e27e537050af1fa7b82a16064396bb8cd0589d1be5850f22a168ef3753a3c43908047f67baaa851d4de0ed5f58b3c596d01387b44cd553f4211f285fdc27ae33661b32b10b7a1c729b26b2c23b8cda89d7a07543b6ce8a8600ed78205769f31952c9404e43570f06f5b0f8a85d",
+  "c3adb005347e78273a62a79d1be677fd6fef9875e18556daabc8b84cffa0a481f28d0f2d06e86cf2d36b8b2be83e75ea04ae33b621155fdce91734cf6a1ebfafead9a9f3503f11586809670edf031005c7399b8443675df1502ee1fa7f6729569113f15aceccf8e4cc456dae78740589d90dc5d7b8d839fe191fd267729e44",
+  "76f2008619c417a3b43f8225774a2f736d01931e17a36f436cc47af3e95bd0f5af832d45694a8be6a01e87217b87a8bb24c45f37b4a06e0ceb1b0af6b4e09346939e244b61b2fe471297db7eb27adb8e63086b8fc391c4dfc97e94c1d153866b268e497bf752a3980e9376c68acb2a0b7a13dbd9ad4f3702055b915af095ab4a",
+  "baff250589242160421dc33cef55a11962a28287beafacfd7c5ee112117beec1d1f24dd0ec42a495034cec9f74ac62e2b3524b5a9953666196065b85353486f680cc449fee5872f2ddff16341eb3f2d4afe083db244589f8160a678627f8ae17c3622aa7d6ff6b330245f93b5c51cc0b4a25faefe4e5b93478ca14105ef6b470",
+  "a2564fb6ccdc4cac30bca1b44d7be37c6c8ef7aa2de91b327c253a0a2a6c9b692a163d1442de8ddaee8eacba3d437e77c30089c14173c68c5622ac06ac00566d2702f38d6d72a0296bd4899172ac01c4e2b95da3d7299d48b555af8ad6644d9ec6399b18b85d4c79983e3ad238e7c9cfd923d0f37e810446a271bfe45b0648e7",
+  "c57429d66d9c29f977bf3cef2ffb1b3dde08e2ed19ac22ecce9cca0c3e0391d956d41759dd421d7fb4db8fbc6b7d9099547d92b26d214b20aeed8ff8622d66fed4b13a76e50eb452b782894b568fa9b16fc7bf4c86187c214d258846fb5ff4fb39d088b9b662d05a8bb37640a89d4ffb95a613aaa4efe589e315dbd3a71b3a96",
+  "5eedb3f58206d94977f1d3bbc8ca33c75d3fb51a0852a54861278fa7dce088be88c2c6530c6e6b69f61d1d3d8f9656dfb1039bdf76f9e5c7004c204dc6edcb921233bc331aff02d0f76cf2b0e2d6c971d000526dba8d9edacdf67314e42b263582f5236b38652c9aa0fb37629f1391798581bfa4c608b61ad2dd1aa1bfe0c1e5cc",
+  "55879d5e0164b75fc4cf92a55dccb2c2a5ecf783b73f5262e60a46b38c8c5f1c7374258b1f9bfdd0d62b37c1b074c16d83ba66ab8e51c9baa95f5e632978e1d512bf4582d2daa48d95ef9fe1e3fd0e250ed375c111f4efbbc4f16acad358c29d30a694305719f4a59ca964fb379caa654d1eba55f7fc68f9bb38e8d12b3a0e8207",
+  "55dd06136ae6732c4600b9a04cdb9362de8a19d9bbe2bee477eeba530c2552e1582714a10c96dc25496325ce16f60a5291e098cdb89fc9af488f92610aca213bf4716014fac914fdb976b4e3fc8f54cbf889584917faf47880a853879fa49d4f0ade8c81a27c8f28158479851bc9d52ca0a9068f339275875b6cb053b0e314fd9d",
+  "be696a270482f9f8f6bc3b9bbe4f91b1b6a857efb5b926e7a07cdb2cd7af9a4a65085f21afd7f781320cb79c65766922ffa2e08a5f9238d186e932ad50cfec5aa826acb2595580fcdc1e43d59d2df3d1ee00c2cf0729dabe12a2f330989169a515d1b9e8fcfdb33299a9b46710234c46defcc29f1ad58c66c8cc44663fc63f3108",
+};
+static size_t nb_sha512_hkdf_vectors=12;
 static const char *argon2_vectors[]={
   "0100000000000000",
   "0800000000000000",
index a624bba294a6f451f730a560a10b0bec065d376f..5798f703980b54fb9858a5e052c26d3030fbb61d 100644 (file)
@@ -157,6 +157,18 @@ static void sha512_hmac(vector_reader *reader)
        crypto_sha512_hmac(out.buf, key.buf, key.size, msg.buf, msg.size);
 }
 
+static void sha512_hkdf(vector_reader *reader)
+{
+       vector ikm  = next_input(reader);
+       vector salt = next_input(reader);
+       vector info = next_input(reader);
+       vector okm  = next_output(reader);
+       crypto_sha512_hkdf(okm .buf, okm .size,
+                          ikm .buf, ikm .size,
+                          salt.buf, salt.size,
+                          info.buf, info.size);
+}
+
 static void argon2(vector_reader *reader)
 {
        crypto_argon2_config config;
@@ -386,6 +398,8 @@ TEST(sha512)
 //@ ensures \result == 0;
 TEST(sha512_hmac)
 //@ ensures \result == 0;
+TEST(sha512_hkdf)
+//@ ensures \result == 0;
 TEST(argon2)
 //@ ensures \result == 0;
 TEST(x25519)
@@ -411,6 +425,7 @@ int main(void) {
        ASSERT(v_blake2b       () == 0);
        ASSERT(v_sha512        () == 0);
        ASSERT(v_sha512_hmac   () == 0);
+       ASSERT(v_sha512_hkdf   () == 0);
        ASSERT(v_argon2        () == 0);
        ASSERT(v_x25519        () == 0);
        ASSERT(v_edDSA         () == 0);
index bff0a04e7478d8b47d9f102e28aae195c7649f0f..18c3b92c0132a554eb6b2131e0380bd8d57a1a7d 100644 (file)
 , "no-results"    : true
 , "main"          : "v_sha512"
 },
-{ "name"          : "v_hmac_sha512 - sparc_32"
+{ "name"          : "v_sha512_hmac - sparc_32"
 , "files"         :
   [ "src/monocypher.c"
   , "src/optional/monocypher-ed25519.c"
 , "cpp-extra-args": "-Isrc -Isrc/optional -Itests"
 , "machdep"       : "sparc_32"
 , "no-results"    : true
-, "main"          : "v_hmac_sha512"
+, "main"          : "v_sha512_hmac"
 },
-{ "name"          : "v_hmac_sha512 - x86_32"
+{ "name"          : "v_sha512_hmac - x86_32"
 , "files"         :
   [ "src/monocypher.c"
   , "src/optional/monocypher-ed25519.c"
 , "cpp-extra-args": "-Isrc -Isrc/optional -Itests"
 , "machdep"       : "x86_32"
 , "no-results"    : true
-, "main"          : "v_hmac_sha512"
+, "main"          : "v_sha512_hmac"
 },
-{ "name"          : "v_hmac_sha512 - x86_16"
+{ "name"          : "v_sha512_hmac - x86_16"
 , "files"         :
   [ "src/monocypher.c"
   , "src/optional/monocypher-ed25519.c"
 , "cpp-extra-args": "-Isrc -Isrc/optional -Itests"
 , "machdep"       : "x86_16"
 , "no-results"    : true
-, "main"          : "v_hmac_sha512"
+, "main"          : "v_sha512_hmac"
 },
-{ "name"          : "v_hmac_sha512 - x86_win64"
+{ "name"          : "v_sha512_hmac - x86_win64"
 , "files"         :
   [ "src/monocypher.c"
   , "src/optional/monocypher-ed25519.c"
 , "cpp-extra-args": "-Isrc -Isrc/optional -Itests"
 , "machdep"       : "x86_win64"
 , "no-results"    : true
-, "main"          : "v_hmac_sha512"
+, "main"          : "v_sha512_hmac"
 },
-{ "name"          : "v_hmac_sha512 - armeb_eabi"
+{ "name"          : "v_sha512_hmac - armeb_eabi"
 , "files"         :
   [ "src/monocypher.c"
   , "src/optional/monocypher-ed25519.c"
 , "cpp-extra-args": "-Isrc -Isrc/optional -Itests"
 , "machdep"       : "armeb_eabi"
 , "no-results"    : true
-, "main"          : "v_hmac_sha512"
+, "main"          : "v_sha512_hmac"
 },
-{ "name"          : "v_hmac_sha512 - arm_eabi"
+{ "name"          : "v_sha512_hmac - arm_eabi"
 , "files"         :
   [ "src/monocypher.c"
   , "src/optional/monocypher-ed25519.c"
 , "cpp-extra-args": "-Isrc -Isrc/optional -Itests"
 , "machdep"       : "arm_eabi"
 , "no-results"    : true
-, "main"          : "v_hmac_sha512"
+, "main"          : "v_sha512_hmac"
 },
-{ "name"          : "v_hmac_sha512 - aarch64"
+{ "name"          : "v_sha512_hmac - aarch64"
 , "files"         :
   [ "src/monocypher.c"
   , "src/optional/monocypher-ed25519.c"
 , "cpp-extra-args": "-Isrc -Isrc/optional -Itests"
 , "machdep"       : "aarch64"
 , "no-results"    : true
-, "main"          : "v_hmac_sha512"
+, "main"          : "v_sha512_hmac"
 },
-{ "name"          : "v_hmac_sha512 - rv64ifdq"
+{ "name"          : "v_sha512_hmac - rv64ifdq"
 , "files"         :
   [ "src/monocypher.c"
   , "src/optional/monocypher-ed25519.c"
 , "cpp-extra-args": "-Isrc -Isrc/optional -Itests"
 , "machdep"       : "rv64ifdq"
 , "no-results"    : true
-, "main"          : "v_hmac_sha512"
+, "main"          : "v_sha512_hmac"
 },
-{ "name"          : "v_hmac_sha512 - mips_64"
+{ "name"          : "v_sha512_hmac - mips_64"
 , "files"         :
   [ "src/monocypher.c"
   , "src/optional/monocypher-ed25519.c"
 , "cpp-extra-args": "-Isrc -Isrc/optional -Itests"
 , "machdep"       : "mips_64"
 , "no-results"    : true
-, "main"          : "v_hmac_sha512"
+, "main"          : "v_sha512_hmac"
 },
-{ "name"          : "v_hmac_sha512 - ppc_64"
+{ "name"          : "v_sha512_hmac - ppc_64"
 , "files"         :
   [ "src/monocypher.c"
   , "src/optional/monocypher-ed25519.c"
 , "cpp-extra-args": "-Isrc -Isrc/optional -Itests"
 , "machdep"       : "ppc_64"
 , "no-results"    : true
-, "main"          : "v_hmac_sha512"
+, "main"          : "v_sha512_hmac"
+},
+{ "name"          : "v_sha512_hkdf - sparc_32"
+, "files"         :
+  [ "src/monocypher.c"
+  , "src/optional/monocypher-ed25519.c"
+  , "tests/utils.c"
+  , "tests/tis-ci.c"
+  ]
+, "cpp-extra-args": "-Isrc -Isrc/optional -Itests"
+, "machdep"       : "sparc_32"
+, "no-results"    : true
+, "main"          : "v_sha512_hkdf"
+},
+{ "name"          : "v_sha512_hkdf - x86_32"
+, "files"         :
+  [ "src/monocypher.c"
+  , "src/optional/monocypher-ed25519.c"
+  , "tests/utils.c"
+  , "tests/tis-ci.c"
+  ]
+, "cpp-extra-args": "-Isrc -Isrc/optional -Itests"
+, "machdep"       : "x86_32"
+, "no-results"    : true
+, "main"          : "v_sha512_hkdf"
+},
+{ "name"          : "v_sha512_hkdf - x86_16"
+, "files"         :
+  [ "src/monocypher.c"
+  , "src/optional/monocypher-ed25519.c"
+  , "tests/utils.c"
+  , "tests/tis-ci.c"
+  ]
+, "cpp-extra-args": "-Isrc -Isrc/optional -Itests"
+, "machdep"       : "x86_16"
+, "no-results"    : true
+, "main"          : "v_sha512_hkdf"
+},
+{ "name"          : "v_sha512_hkdf - x86_win64"
+, "files"         :
+  [ "src/monocypher.c"
+  , "src/optional/monocypher-ed25519.c"
+  , "tests/utils.c"
+  , "tests/tis-ci.c"
+  ]
+, "cpp-extra-args": "-Isrc -Isrc/optional -Itests"
+, "machdep"       : "x86_win64"
+, "no-results"    : true
+, "main"          : "v_sha512_hkdf"
+},
+{ "name"          : "v_sha512_hkdf - armeb_eabi"
+, "files"         :
+  [ "src/monocypher.c"
+  , "src/optional/monocypher-ed25519.c"
+  , "tests/utils.c"
+  , "tests/tis-ci.c"
+  ]
+, "cpp-extra-args": "-Isrc -Isrc/optional -Itests"
+, "machdep"       : "armeb_eabi"
+, "no-results"    : true
+, "main"          : "v_sha512_hkdf"
+},
+{ "name"          : "v_sha512_hkdf - arm_eabi"
+, "files"         :
+  [ "src/monocypher.c"
+  , "src/optional/monocypher-ed25519.c"
+  , "tests/utils.c"
+  , "tests/tis-ci.c"
+  ]
+, "cpp-extra-args": "-Isrc -Isrc/optional -Itests"
+, "machdep"       : "arm_eabi"
+, "no-results"    : true
+, "main"          : "v_sha512_hkdf"
+},
+{ "name"          : "v_sha512_hkdf - aarch64"
+, "files"         :
+  [ "src/monocypher.c"
+  , "src/optional/monocypher-ed25519.c"
+  , "tests/utils.c"
+  , "tests/tis-ci.c"
+  ]
+, "cpp-extra-args": "-Isrc -Isrc/optional -Itests"
+, "machdep"       : "aarch64"
+, "no-results"    : true
+, "main"          : "v_sha512_hkdf"
+},
+{ "name"          : "v_sha512_hkdf - rv64ifdq"
+, "files"         :
+  [ "src/monocypher.c"
+  , "src/optional/monocypher-ed25519.c"
+  , "tests/utils.c"
+  , "tests/tis-ci.c"
+  ]
+, "cpp-extra-args": "-Isrc -Isrc/optional -Itests"
+, "machdep"       : "rv64ifdq"
+, "no-results"    : true
+, "main"          : "v_sha512_hkdf"
+},
+{ "name"          : "v_sha512_hkdf - mips_64"
+, "files"         :
+  [ "src/monocypher.c"
+  , "src/optional/monocypher-ed25519.c"
+  , "tests/utils.c"
+  , "tests/tis-ci.c"
+  ]
+, "cpp-extra-args": "-Isrc -Isrc/optional -Itests"
+, "machdep"       : "mips_64"
+, "no-results"    : true
+, "main"          : "v_sha512_hkdf"
+},
+{ "name"          : "v_sha512_hkdf - ppc_64"
+, "files"         :
+  [ "src/monocypher.c"
+  , "src/optional/monocypher-ed25519.c"
+  , "tests/utils.c"
+  , "tests/tis-ci.c"
+  ]
+, "cpp-extra-args": "-Isrc -Isrc/optional -Itests"
+, "machdep"       : "ppc_64"
+, "no-results"    : true
+, "main"          : "v_sha512_hkdf"
 },
 { "name"          : "v_argon2 - sparc_32"
 , "files"         :