]> git.codecow.com Git - Monocypher.git/commitdiff
Renamed crypto_hmac_sha512*() to crypto_sha512*_hmac()
authorLoup Vaillant <loup@loup-vaillant.fr>
Mon, 30 Jan 2023 22:48:16 +0000 (23:48 +0100)
committerLoup Vaillant <loup@loup-vaillant.fr>
Mon, 30 Jan 2023 22:48:16 +0000 (23:48 +0100)
The main goal here is to have one man page per hash, and steer users who
are reaching for hashes when trying to compute MACs or derive keys to
the right functions.

Fusing the man pages for SHA-512 and HMAC also helped reduce the total
size of the documentation.

Related to #255

doc/crypto_hmac_sha512.3monocypher [deleted file]
doc/crypto_sha512.3monocypher
src/monocypher.c
src/optional/monocypher-ed25519.c
src/optional/monocypher-ed25519.h
tests/gen/makefile
tests/gen/sha512_hmac.c [moved from tests/gen/hmac_sha512.c with 100% similarity]
tests/gen/vectors/sha512_hmac [moved from tests/gen/vectors/hmac_sha512 with 100% similarity]
tests/test.c
tests/tis-ci-vectors.h
tests/tis-ci.c

diff --git a/doc/crypto_hmac_sha512.3monocypher b/doc/crypto_hmac_sha512.3monocypher
deleted file mode 100644 (file)
index 715b4a6..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-.\" This file is dual-licensed.  Choose whichever you want.
-.\"
-.\" 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) 2019-2020 Fabio Scotoni
-.\" 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 2019-2020 by Fabio Scotoni
-.\"
-.\" 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/>
-.\"
-.Dd March 2, 2020
-.Dt CRYPTO_HMAC_SHA512 3MONOCYPHER
-.Os
-.Sh NAME
-.Nm crypto_hmac_sha512 ,
-.Nm crypto_hmac_sha512_init ,
-.Nm crypto_hmac_sha512_update ,
-.Nm crypto_hmac_sha512_final
-.Nd cryptographic hash-based message authentication code with SHA-512
-.Sh SYNOPSIS
-.In monocypher-ed25519.h
-.Ft void
-.Fo crypto_hmac_sha512
-.Fa "uint8_t hmac[64]"
-.Fa "const uint8_t *key"
-.Fa "size_t key_size"
-.Fa "const uint8_t *message"
-.Fa "size_t message_size"
-.Fc
-.Ft void
-.Fo crypto_hmac_sha512_init
-.Fa "crypto_hmac_sha512_ctx *ctx"
-.Fa "const uint8_t *key"
-.Fa "size_t key_size"
-.Fc
-.Ft void
-.Fo crypto_hmac_sha512_update
-.Fa "crypto_hmac_sha512_ctx *ctx"
-.Fa "const uint8_t *message"
-.Fa "size_t message_size"
-.Fc
-.Ft void
-.Fo crypto_hmac_sha512_final
-.Fa "crypto_hmac_sha512_ctx *ctx"
-.Fa "uint8_t hmac[64]"
-.Fc
-.Sh DESCRIPTION
-HMAC with SHA-512 is a cryptographically secure message authentication
-code (MAC),
-provided to enable compatibility with other cryptographic systems.
-It is generally recommended to use
-.Xr crypto_blake2b_general 3monocypher
-instead,
-as it performs faster on x86_64 CPUs.
-.Pp
-The arguments are:
-.Bl -tag -width Ds
-.It Fa hmac
-The output MAC,
-which is always 64-bytes long.
-.It Fa key
-Some secret key.
-One cannot predict the final hash without it.
-Users may want to wipe the key with
-.Xr crypto_wipe 3monocypher
-once they are done with it.
-.It Fa key_size
-Length of
-.Fa key ,
-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 overlap with
-.Fa hmac .
-May be
-.Dv NULL
-if
-.Fa message_size
-is 0.
-.It Fa message_size
-Length of
-.Fa message ,
-in bytes.
-.El
-.Pp
-An incremental interface is provided.
-It is useful for handling streams of data or
-large files without using too much memory.
-This interface uses three steps:
-.Bl -bullet
-.It
-initialisation with
-.Fn crypto_hmac_sha512_init ,
-which sets up a context with the hashing parameters;
-.It
-update with
-.Fn crypto_hmac_sha512_update ,
-which hashes the message chunk by chunk and keeps the intermediary
-result in the context;
-.It
-and finalisation with
-.Fn crypto_hmac_sha512_final ,
-which produces the final hash.
-The
-.Ft crypto_hmac_sha512_ctx
-is automatically wiped upon finalisation.
-.El
-.Pp
-.Fn crypto_hmac_sha512
-is a convenience function that
-performs
-.Fn crypto_hmac_sha512_init ,
-.Fn crypto_hmac_sha512_update ,
-and
-.Fn crypto_hmac_sha512_final .
-.Pp
-MACs may be truncated safely down to at most 16 bytes;
-the
-.Xr crypto_verify64 3monocypher ,
-.Xr crypto_verify32 3monocypher ,
-and
-.Xr crypto_verify16 3monocypher
-functions can be used to compare (possibly truncated) MACs.
-.Sh RETURN VALUES
-These functions return nothing.
-.Sh EXAMPLES
-The following examples assume the existence of
-.Fn arc4random_buf ,
-which fills the given buffer with cryptographically secure random bytes.
-If
-.Fn arc4random_buf
-does not exist on your system, see
-.Xr intro 3monocypher
-for advice about how to generate cryptographically secure random bytes.
-.Pp
-Computing a message authentication code all at once:
-.Bd -literal -offset indent
-uint8_t hash   [64];                /* Output hash             */
-uint8_t key    [32];                /* Key                     */
-uint8_t message[10] = "Lorem ipsu"; /* Message to authenticate */
-arc4random_buf(key, 32);
-crypto_hmac_sha512(hash, key, 32, message, 10);
-/* Wipe secrets if they are no longer needed */
-crypto_wipe(message, 10);
-crypto_wipe(key, 32);
-.Ed
-.Pp
-Computing a message authentication code incrementally:
-.Bd -literal -offset indent
-uint8_t hash   [64];        /* Output hash             */
-uint8_t key    [32];        /* Key                     */
-uint8_t message[500] = {1}; /* Message to authenticate */
-crypto_hmac_sha512_ctx ctx;
-arc4random_buf(key, 32);
-crypto_hmac_sha512_init(&ctx, key, 32);
-/* Wipe the key */
-crypto_wipe(key, 32);
-for (size_t i = 0; i < 500; i += 100) {
-    crypto_hmac_sha512_update(&ctx, message + i, 100);
-    /* Wipe secrets if they are no longer needed */
-    crypto_wipe(message + i, 100);
-}
-crypto_hmac_sha512_final(&ctx, hash);
-.Ed
-.Sh SEE ALSO
-.Xr crypto_blake2b 3monocypher ,
-.Xr crypto_lock 3monocypher ,
-.Xr crypto_poly1305 3monocypher ,
-.Xr crypto_sha512 3monocypher ,
-.Xr intro 3monocypher
-.Sh STANDARDS
-These functions implement HMAC with SHA-512.
-HMAC and SHA-512 itself 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.
-.Sh HISTORY
-The
-.Fn crypto_hmac_sha512 ,
-.Fn crypto_hmac_sha512_init ,
-.Fn crypto_hmac_sha512_update ,
-and
-.Fn crypto_hmac_sha512_final
-functions first appeared in Monocypher 3.0.0.
index 61f4c70f08c28c369255ae83205d4f29b246255f..66c0e8fa7860d08f8bf4b522c7450cada4fc30ca 100644 (file)
@@ -9,6 +9,7 @@
 .\" ----------------------------------------------------------------------------
 .\"
 .\" Copyright (c) 2019-2020 Fabio Scotoni
+.\" Copyright (c) 2023      Loup Vaillant
 .\" All rights reserved.
 .\"
 .\"
@@ -38,7 +39,7 @@
 .\"
 .\" ----------------------------------------------------------------------------
 .\"
-.\" Written in 2019-2020 by Fabio Scotoni
+.\" Written in 2019-2020, 2023 by Fabio Scotoni and 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
 .Nm crypto_sha512_init ,
 .Nm crypto_sha512_update ,
 .Nm crypto_sha512_final
-.Nd cryptographic hashing with the SHA-512 algorithm
+.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
 .Sh SYNOPSIS
 .In monocypher-ed25519.h
 .Ft void
 .Fa "crypto_sha512_ctx *ctx"
 .Fa "uint8_t hash[64]"
 .Fc
+.Ft void
+.Fo crypto_sha512_hmac
+.Fa "uint8_t hmac[64]"
+.Fa "const uint8_t *key"
+.Fa "size_t key_size"
+.Fa "const uint8_t *message"
+.Fa "size_t message_size"
+.Fc
+.Ft void
+.Fo crypto_sha512_hmac_init
+.Fa "crypto_sha512_hmac_ctx *ctx"
+.Fa "const uint8_t *key"
+.Fa "size_t key_size"
+.Fc
+.Ft void
+.Fo crypto_sha512_hmac_update
+.Fa "crypto_sha512_hmac_ctx *ctx"
+.Fa "const uint8_t *message"
+.Fa "size_t message_size"
+.Fc
+.Ft void
+.Fo crypto_sha512_hmac_final
+.Fa "crypto_sha512_hmac_ctx *ctx"
+.Fa "uint8_t hmac[64]"
+.Fc
 .Sh DESCRIPTION
-SHA-512 is a cryptographically secure hash,
-provided to enable compatibility with other cryptographic systems.
+.Fn crypto_sha512 ,
+.Fn crypto_sha512_init ,
+.Fn crypto_sha512_update ,
+and
+.Fn crypto_sha512_final
+implement SHA-512,
+a cryptographically secure hash.
+They are provided to enable compatibility with other cryptographic
+systems.
 It is generally recommended to use
 .Xr crypto_blake2b 3monocypher
 instead,
@@ -96,25 +133,47 @@ use the
 family of functions for that purpose instead.
 .Pp
 SHA-512 is
-.Em vulnerable to length extension attacks ;
-using it as a message authentication code (MAC) algorithm or keyed hash
-requires precautions.
-The
-.Xr crypto_hmac_sha512 3monocypher
-family of functions provides HMAC with SHA-512.
-Use
-.Xr crypto_verify64 3monocypher
-to compare MACs created this way.
+.Em vulnerable to length extension attacks ,
+and thus cannot directly be used for message authentication codes (MAC),
+nor as a random oracle.
+For those, use the
+.Fn crypto_sha512_hmac
+family of functions instead.
+.Pp
+.Fn crypto_sha512_hmac ,
+.Fn crypto_sha512_hmac_init ,
+.Fn crypto_sha512_hmac_update ,
+and
+.Fn crypto_sha512_hmac_final
+implement HMAC with SHA-512,
+and can be used as for message authentication codes
+or as a random oracle.
+They are provided to enable compatibility with other cryptographic
+systems.
+It is generally recommended to use keyed
+.Xr crypto_blake2b 3monocypher
+instead,
+as it performs faster on x86_64 CPUs.
 .Pp
 The arguments are:
 .Bl -tag -width Ds
 .It Fa hash
-The output hash,
+The output SHA-512 hash,
 which is always 64-bytes long.
+.It Fa hmac
+The output MAC,
+which is always 64-bytes long.
+When used as a message authentication code,
+it can safely be truncated down to 16 bytes.
+To avoid timing attacks,
+use
+.Xr crypto_verify16 3monocypher ,
+.Xr crypto_verify32 3monocypher ,
+or
+.Xr crypto_verify64 3monocypher
+to compare (possibly truncated) MACs.
 .It Fa message
-The message to hash.
-May overlap with
-.Fa hash .
+The message to hash, or compute the HMAC for.
 May be
 .Dv NULL
 if
@@ -124,6 +183,19 @@ is 0.
 Length of
 .Fa message ,
 in bytes.
+.It Fa key
+Some secret key.
+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.
+.It Fa key_size
+Length of
+.Fa key ,
+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.
 .El
 .Pp
 An incremental interface is provided.
@@ -133,19 +205,27 @@ This interface uses three steps:
 .Bl -bullet
 .It
 initialisation with
-.Fn crypto_sha512_init ,
+.Fn crypto_sha512_init
+or
+.Fn crypto_sha512_hmac_init ,
 which sets up a context with the hashing parameters;
 .It
 update with
-.Fn crypto_sha512_update ,
+.Fn crypto_sha512_update
+or
+.Fn crypto_sha512_hmac_update ,
 which hashes the message chunk by chunk and keeps the intermediary
 result in the context;
 .It
 and finalisation with
-.Fn crypto_sha512_final ,
+.Fn crypto_sha512_final
+or
+.Fn crypto_sha512_hmac_final ,
 which produces the final hash.
 The
 .Ft crypto_sha512_ctx
+or
+.Ft crypto_sha512_hmac_ctx
 is automatically wiped upon finalisation.
 .El
 .Pp
@@ -156,6 +236,14 @@ performs
 .Fn crypto_sha512_update ,
 and
 .Fn crypto_sha512_final .
+.Pp
+.Fn crypto_sha512_hmac
+is a convenience function that
+performs
+.Fn crypto_sha512_hmac_init ,
+.Fn crypto_sha512_hmac_update ,
+and
+.Fn crypto_sha512_hmac_final .
 .Sh RETURN VALUES
 These functions return nothing.
 .Sh EXAMPLES
@@ -177,14 +265,47 @@ for (size_t i = 0; i < 500; i += 100) {
 }
 crypto_sha512_final(&ctx, hash);
 .Ed
+.Pp
+Computing a message authentication code all at once:
+.Bd -literal -offset indent
+uint8_t hash   [64];                /* Output hash             */
+uint8_t key    [32];                /* Key                     */
+uint8_t message[10] = "Lorem ipsu"; /* Message to authenticate */
+arc4random_buf(key, 32);
+crypto_sha512_hmac(hash, key, 32, message, 10);
+/* Wipe secrets if they are no longer needed */
+crypto_wipe(message, 10);
+crypto_wipe(key, 32);
+.Ed
+.Pp
+Computing a message authentication code incrementally:
+.Bd -literal -offset indent
+uint8_t hash   [64];        /* Output hash             */
+uint8_t key    [32];        /* Key                     */
+uint8_t message[500] = {1}; /* Message to authenticate */
+crypto_sha512_hmac_ctx ctx;
+arc4random_buf(key, 32);
+crypto_sha512_hmac_init(&ctx, key, 32);
+/* Wipe the key */
+crypto_wipe(key, 32);
+for (size_t i = 0; i < 500; i += 100) {
+    crypto_sha512_hmac_update(&ctx, message + i, 100);
+    /* Wipe secrets if they are no longer needed */
+    crypto_wipe(message + i, 100);
+}
+crypto_sha512_hmac_final(&ctx, hash);
+.Ed
 .Sh SEE ALSO
 .Xr crypto_blake2b 3monocypher ,
-.Xr crypto_hmac_sha512 3monocypher ,
 .Xr crypto_lock 3monocypher ,
+.Xr crypto_poly1305 3monocypher ,
 .Xr intro 3monocypher
 .Sh STANDARDS
-These functions implement SHA-512, described in RFC 6234 and
-the Federal Information Processing Standard (FIPS) 180-4.
+These functions implement SHA-512 and HMAC 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.
 .Sh HISTORY
 The
 .Fn crypto_sha512 ,
@@ -196,6 +317,21 @@ functions first appeared in Monocypher 0.3,
 but were not intended for use outside Monocypher itself and thus
 undocumented.
 They became part of the official API in Monocypher 3.0.0.
+.Pp
+The
+.Fn crypto_hmac_sha512 ,
+.Fn crypto_hmac_sha512_init ,
+.Fn crypto_hmac_sha512_update ,
+and
+.Fn crypto_hmac_sha512_final
+functions first appeared in Monocypher 3.0.0,
+then renamed
+.Fn crypto_sha512_hmac ,
+.Fn crypto_sha512_hmac_init ,
+.Fn crypto_sha512_hmac_update ,
+and
+.Fn crypto_sha512_hmac_final
+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
index f6af5ded703df0c875dd4cbeff7e4ef3fa9d986b..99306f51b55fcb353ae7537283467aaf74a4447c 100644 (file)
@@ -617,11 +617,28 @@ void crypto_blake2b_final(crypto_blake2b_ctx *ctx, u8 *hash)
                blake2b_set_input(ctx, 0, i);
        }
        blake2b_compress(ctx, 1); // compress the last block
-       size_t nb_words = ctx->hash_size >> 3;
+       size_t hash_size = MIN(ctx->hash_size, 64);
+       size_t nb_words  = hash_size >> 3;
        store64_le_buf(hash, ctx->hash, nb_words);
-       FOR (i, nb_words << 3, ctx->hash_size) {
+       FOR (i, nb_words << 3, hash_size) {
                hash[i] = (ctx->hash[i >> 3] >> (8 * (i & 7))) & 0xff;
        }
+
+       // Expand the hash if it exceeds 64 bytes
+       if (ctx->hash_size > 64) {
+               u8 block[128] = {0};
+               COPY(block + 16, hash, 64);
+               store64_le(block + 8, (u64)(ctx->hash_size));
+               u64 ctr = 0;
+               while (ctx->hash_size > 0) {
+                       crypto_blake2b_config config = { 0, 0, MIN(ctx->hash_size, 64) };
+                       store64_le(block, ctr);
+                       crypto_blake2b(hash, config, block, 128);
+                       hash           += config.hash_size;
+                       ctx->hash_size -= config.hash_size;
+                       ctr++;
+               }
+       }
        WIPE_CTX(ctx);
 }
 
@@ -634,6 +651,107 @@ void crypto_blake2b(u8 *hash, crypto_blake2b_config config,
        crypto_blake2b_final (&ctx, hash);
 }
 
+void crypto_blake2_kdf(uint8_t       *okm, size_t okm_size,   // unlimited
+                       const uint8_t *ikm, size_t ikm_size,   // unlimited
+                       const uint8_t *salt, size_t salt_size, // <= 64 bytes
+                       const uint8_t *info, size_t info_size) // unlimited
+{
+       // Extract
+       uint8_t prk[64];
+       crypto_blake2b_config config = {
+               .key       = salt,
+               .key_size  = salt_size,
+               .hash_size = 64,
+       };
+       crypto_blake2b(prk, config, ikm, ikm_size);
+
+       // Expand
+       uint64_t ctr = 0;
+       while (okm_size > 0) {
+               size_t hash_size = MIN(okm_size, 64);
+               crypto_blake2b_config config = {
+                       .key       = salt,
+                       .key_size  = salt_size,
+                       .hash_size = hash_size,
+               };
+               uint8_t ctr_buf[8];
+               store64_le(ctr_buf, ctr);
+               crypto_blake2b_ctx ctx;
+               crypto_blake2b_init  (&ctx, config);
+               crypto_blake2b_update(&ctx, info, info_size);
+               crypto_blake2b_update(&ctx, ctr_buf, sizeof(ctr_buf));
+               crypto_blake2b_final (&ctx, okm);
+               okm      += hash_size;
+               okm_size -= hash_size;
+               ctr++;
+       }
+}
+
+void crypto_blake2_kdf_expand_step(
+       uint8_t       *okm,  size_t okm_size,  // <= 64 bytes
+       const uint8_t *prk,  size_t prk_size,  // <= 64 bytes
+       const uint8_t *info, size_t info_size, // unlimited
+       uint64_t ctr)
+{
+       crypto_blake2b_config config = {
+               .key       = prk,
+               .key_size  = prk_size,
+               .hash_size = okm_size,
+       };
+       uint8_t ctr_buf[8];
+       store64_le(ctr_buf, ctr);
+       crypto_blake2b_ctx ctx;
+       crypto_blake2b_init  (&ctx, config);
+       crypto_blake2b_update(&ctx, info, info_size);
+       crypto_blake2b_update(&ctx, ctr_buf, sizeof(ctr_buf));
+       crypto_blake2b_final (&ctx, okm);
+}
+
+void crypto_blake2_kdf_expand_step2(
+       uint8_t       *okm,  size_t okm_size,  // <=  64 bytes
+       const uint8_t *prk,  size_t prk_size,  // <=  64 bytes
+       const uint8_t *info, size_t info_size, // <= 120 bytes
+       uint64_t ctr)
+{
+       crypto_blake2b_config config = {
+               .key       = prk,
+               .key_size  = prk_size,
+               .hash_size = okm_size,
+       };
+       uint8_t block[128] = { 0 };
+       store64_le(block, ctr);
+       COPY(block + 8, info, info_size);
+       crypto_blake2b(okm, config, block, sizeof(block));
+}
+
+void crypto_blake2_kdf2(uint8_t       *okm, size_t okm_size,   // unlimited
+                        const uint8_t *ikm, size_t ikm_size,   // unlimited
+                        const uint8_t *salt, size_t salt_size, // <= 64 bytes
+                        const uint8_t *info, size_t info_size) // unlimited?
+{
+       // Extract
+       uint8_t prk[64];
+       crypto_blake2b_config config = {
+               .key       = salt,
+               .key_size  = salt_size,
+               .hash_size = 64,
+       };
+       crypto_blake2b(prk, config, ikm, ikm_size);
+
+       // Expand
+       uint64_t ctr = 0;
+       while (okm_size > 0) {
+               size_t hash_size = MIN(okm_size, 64);
+               crypto_blake2_kdf_expand_step( // or step2
+                       okm, hash_size, prk, sizeof(prk), info, info_size, ctr);
+               okm      += hash_size;
+               okm_size -= hash_size;
+               ctr++;
+       }
+}
+
+
+
 //////////////
 /// Argon2 ///
 //////////////
index d175fb6cd912dec46c955eedcdf9383aa48ee59c..2daae15b1d8cfdaec4e8846bb648f62e9ce9f4f8 100644 (file)
@@ -286,7 +286,7 @@ void crypto_sha512(u8 hash[64], const u8 *message, size_t message_size)
 ////////////////////
 /// HMAC SHA 512 ///
 ////////////////////
-void crypto_hmac_sha512_init(crypto_hmac_sha512_ctx *ctx,
+void crypto_sha512_hmac_init(crypto_sha512_hmac_ctx *ctx,
                              const u8 *key, size_t key_size)
 {
        // hash key if it is too long
@@ -303,13 +303,13 @@ void crypto_hmac_sha512_init(crypto_hmac_sha512_ctx *ctx,
        crypto_sha512_update(&ctx->ctx, ctx->key, 128);
 }
 
-void crypto_hmac_sha512_update(crypto_hmac_sha512_ctx *ctx,
+void crypto_sha512_hmac_update(crypto_sha512_hmac_ctx *ctx,
                                const u8 *message, size_t message_size)
 {
        crypto_sha512_update(&ctx->ctx, message, message_size);
 }
 
-void crypto_hmac_sha512_final(crypto_hmac_sha512_ctx *ctx, u8 hmac[64])
+void crypto_sha512_hmac_final(crypto_sha512_hmac_ctx *ctx, u8 hmac[64])
 {
        // Finish computing inner hash
        crypto_sha512_final(&ctx->ctx, hmac);
@@ -325,13 +325,13 @@ void crypto_hmac_sha512_final(crypto_hmac_sha512_ctx *ctx, u8 hmac[64])
        WIPE_CTX(ctx);
 }
 
-void crypto_hmac_sha512(u8 hmac[64], const u8 *key, size_t key_size,
+void crypto_sha512_hmac(u8 hmac[64], const u8 *key, size_t key_size,
                         const u8 *message, size_t message_size)
 {
-       crypto_hmac_sha512_ctx ctx;
-       crypto_hmac_sha512_init  (&ctx, key, key_size);
-       crypto_hmac_sha512_update(&ctx, message, message_size);
-       crypto_hmac_sha512_final (&ctx, hmac);
+       crypto_sha512_hmac_ctx ctx;
+       crypto_sha512_hmac_init  (&ctx, key, key_size);
+       crypto_sha512_hmac_update(&ctx, message, message_size);
+       crypto_sha512_hmac_final (&ctx, hmac);
 }
 
 
index 77bb6b9bfa1992e8f94a2f94a8f8246d1c1bd3bc..9402b933eaed140668ede4d2f2da3620423a6d49 100644 (file)
@@ -78,7 +78,7 @@ typedef struct {
 typedef struct {
        uint8_t key[128];
        crypto_sha512_ctx ctx;
-} crypto_hmac_sha512_ctx;
+} crypto_sha512_hmac_ctx;
 
 
 // SHA 512
@@ -91,14 +91,14 @@ void crypto_sha512(uint8_t hash[64],
                    const uint8_t *message, size_t message_size);
 
 
-// HMAC SHA 512
+// SHA 512 HMAC
 // ------------
-void crypto_hmac_sha512_init(crypto_hmac_sha512_ctx *ctx,
+void crypto_sha512_hmac_init(crypto_sha512_hmac_ctx *ctx,
                              const uint8_t *key, size_t key_size);
-void crypto_hmac_sha512_update(crypto_hmac_sha512_ctx *ctx,
+void crypto_sha512_hmac_update(crypto_sha512_hmac_ctx *ctx,
                                const uint8_t *message, size_t  message_size);
-void crypto_hmac_sha512_final(crypto_hmac_sha512_ctx *ctx, uint8_t hmac[64]);
-void crypto_hmac_sha512(uint8_t hmac[64],
+void crypto_sha512_hmac_final(crypto_sha512_hmac_ctx *ctx, uint8_t hmac[64]);
+void crypto_sha512_hmac(uint8_t hmac[64],
                         const uint8_t *key    , size_t key_size,
                         const uint8_t *message, size_t message_size);
 
index be92c3d80d732c495bde534199a9c25f8e85df2e..3eccc35e6d245d23e68360bb295e14b04f125508 100644 (file)
@@ -56,7 +56,7 @@ CFLAGS = -pedantic -Wall -Wextra
 
 VEC     = chacha20  hchacha20  xchacha20     ietf_chacha20                \
           aead_ietf aead_8439                                             \
-          poly1305  blake2b    sha512        hmac_sha512   argon2         \
+          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
@@ -118,7 +118,7 @@ aead_ietf.all.vec     : aead_ietf.vec
 aead_8439.all.vec     : aead_8439.vec
 blake2b.all.vec       : blake2b.vec       vectors/blake2b
 sha512.all.vec        : sha512.vec
-hmac_sha512.all.vec   : hmac_sha512.vec   vectors/hmac_sha512
+sha512_hmac.all.vec   : sha512_hmac.vec   vectors/sha512_hmac
 argon2.all.vec        : argon2.vec       vectors/argon2
 edDSA.all.vec         : edDSA.vec
 edDSA_pk.all.vec      : edDSA_pk.vec
index 8cf2b4dc75cbea991b4791bb43261cac62e96453..ca8f9b741d227718e534eeb26f5203dba24976ac 100644 (file)
@@ -460,9 +460,18 @@ static void sha512(vector_reader *reader)
        crypto_sha512(out.buf, in.buf, in.size);
 }
 
+static void sha512_hmac(vector_reader *reader)
+{
+       vector key = next_input(reader);
+       vector msg = next_input(reader);
+       vector out = next_output(reader);
+       crypto_sha512_hmac(out.buf, key.buf, key.size, msg.buf, msg.size);
+}
+
 static void test_sha512()
 {
        VECTORS(sha512);
+       VECTORS(sha512_hmac);
 
        printf("\tSHA-512 (incremental)\n");
 #undef INPUT_SIZE
@@ -498,23 +507,6 @@ static void test_sha512()
                crypto_sha512(input+i, input + 64, SHA_512_BLOCK_SIZE);
                ASSERT_EQUAL(hash, input + i, 64);
        }
-}
-
-////////////////////
-/// HMAC SHA 512 ///
-////////////////////
-static void hmac_sha512(vector_reader *reader)
-{
-       vector key = next_input(reader);
-       vector msg = next_input(reader);
-       vector out = next_output(reader);
-       crypto_hmac_sha512(out.buf, key.buf, key.size, msg.buf, msg.size);
-}
-
-static void test_hmac_sha512()
-{
-       VECTORS(hmac_sha512);
-
 
        printf("\tHMAC SHA-512 (incremental)\n");
 #undef INPUT_SIZE
@@ -528,14 +520,14 @@ static void test_hmac_sha512()
                RANDOM_INPUT(input, INPUT_SIZE);
 
                // Authenticate bit by bit
-               crypto_hmac_sha512_ctx ctx;
-               crypto_hmac_sha512_init(&ctx, key, 32);
-               crypto_hmac_sha512_update(&ctx, input    , i);
-               crypto_hmac_sha512_update(&ctx, input + i, INPUT_SIZE - i);
-               crypto_hmac_sha512_final(&ctx, hash_chunk);
+               crypto_sha512_hmac_ctx ctx;
+               crypto_sha512_hmac_init(&ctx, key, 32);
+               crypto_sha512_hmac_update(&ctx, input    , i);
+               crypto_sha512_hmac_update(&ctx, input + i, INPUT_SIZE - i);
+               crypto_sha512_hmac_final(&ctx, hash_chunk);
 
                // Authenticate all at once
-               crypto_hmac_sha512(hash_whole, key, 32, input, INPUT_SIZE);
+               crypto_sha512_hmac(hash_whole, key, 32, input, INPUT_SIZE);
 
                // Compare the results (must be the same)
                ASSERT_EQUAL(hash_chunk, hash_whole, 64);
@@ -548,12 +540,13 @@ static void test_hmac_sha512()
                u8 hash [64];
                RANDOM_INPUT(key  , 32);
                RANDOM_INPUT(input, INPUT_SIZE);
-               crypto_hmac_sha512(hash   , key, 32, input + 64, SHA_512_BLOCK_SIZE);
-               crypto_hmac_sha512(input+i, key, 32, input + 64, SHA_512_BLOCK_SIZE);
+               crypto_sha512_hmac(hash   , key, 32, input + 64, SHA_512_BLOCK_SIZE);
+               crypto_sha512_hmac(input+i, key, 32, input + 64, SHA_512_BLOCK_SIZE);
                ASSERT_EQUAL(hash, input + i, 64);
        }
 }
 
+
 //////////////
 /// Argon2 ///
 //////////////
@@ -1136,7 +1129,6 @@ int main(int argc, char *argv[])
        test_poly1305();
        test_blake2b();
        test_sha512();
-       test_hmac_sha512();
        test_argon2();
 
        printf("X25519:\n");
index 5ef6f0dedaed0e45353c22c93effd7a3f2a76e26..5b0c4be179136288a40c60b9be496db9c7eab3e6 100644 (file)
@@ -296,7 +296,7 @@ static const char *sha512_vectors[]={
   "4bf909661a603c30199c63eefe96ac7b5489b2790c47db8f97b99cbc0fb4701831f7682d34302415974ff3f8e43f2592c6ce2c6e8a5518c3468a4cad6699ec35",
 };
 static size_t nb_sha512_vectors=14;
-static const char *hmac_sha512_vectors[]={
+static const char *sha512_hmac_vectors[]={
   "",
   "389e38a072cf1b413bb1517c3fe83abe",
   "9689b839211c1751e1faee45edd4662c6102049ba76c3eef46a28cc268818cc54b8955b68dfd17d6f0993844bf9952f6158aa2c3fe780e6a89d975597a504ada",
@@ -343,7 +343,7 @@ static const char *hmac_sha512_vectors[]={
   "6ab33d45513b7013624e01e15f616a3436caa8813c863a13eb85e06a973f95204b265c9f76496407bdd1bd16b7f6ea3e97f3346e63d5e05f9896b1821e3dbe382a8849e3e27e05c8572140297d86473e720d62e6c7ef1766e4aff8313c688b6b91667b20ccfc055f0d7917eff1c713f3712d948055a3139e6d758a308322503f4f28977329a2153bd6a8c1d47e8877a4abfcef83cdff4daa74845384d8bdcac050bddc4bfa7cdc185d3b2528559936510bfe814ae162eaddf609992f6796654a59a66323292142ca499c44cb95bc308c10d44aa534066efb413fbd7e622fb2a2366b20439156728d7753c598106508878bbf4467d9c7812ea686683580365a50",
   "ffb3011fcde35b8ff8c09a62fe02e7f17aefd1f458f3c01caa2d57b77699dd335f9670d359fc99c72b30ad3e92c9d39000b127967284cca14b759275531eaba2",
 };
-static size_t nb_hmac_sha512_vectors=45;
+static size_t nb_sha512_hmac_vectors=45;
 static const char *argon2_vectors[]={
   "0100000000000000",
   "0800000000000000",
index 64266c40bf04b9e4171ef37c763d575c658cb3cc..a624bba294a6f451f730a560a10b0bec065d376f 100644 (file)
@@ -149,12 +149,12 @@ static void sha512(vector_reader *reader)
        crypto_sha512(out.buf, in.buf, in.size);
 }
 
-static void hmac_sha512(vector_reader *reader)
+static void sha512_hmac(vector_reader *reader)
 {
        vector key = next_input(reader);
        vector msg = next_input(reader);
        vector out = next_output(reader);
-       crypto_hmac_sha512(out.buf, key.buf, key.size, msg.buf, msg.size);
+       crypto_sha512_hmac(out.buf, key.buf, key.size, msg.buf, msg.size);
 }
 
 static void argon2(vector_reader *reader)
@@ -384,7 +384,7 @@ TEST(blake2b)
 //@ ensures \result == 0;
 TEST(sha512)
 //@ ensures \result == 0;
-TEST(hmac_sha512)
+TEST(sha512_hmac)
 //@ ensures \result == 0;
 TEST(argon2)
 //@ ensures \result == 0;
@@ -410,7 +410,7 @@ int main(void) {
        ASSERT(v_aead_ietf     () == 0);
        ASSERT(v_blake2b       () == 0);
        ASSERT(v_sha512        () == 0);
-       ASSERT(v_hmac_sha512   () == 0);
+       ASSERT(v_sha512_hmac   () == 0);
        ASSERT(v_argon2        () == 0);
        ASSERT(v_x25519        () == 0);
        ASSERT(v_edDSA         () == 0);