1 // SPDX-License-Identifier: GPL-2.0 OR MIT
3 * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
5 * This is an implementation of the BLAKE2s hash and PRF functions.
7 * Information: https://blake2.net/
11 #include <crypto/internal/blake2s.h>
12 #include <linux/types.h>
13 #include <linux/string.h>
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/init.h>
17 #include <linux/bug.h>
19 static inline void blake2s_set_lastblock(struct blake2s_state
*state
)
24 void blake2s_update(struct blake2s_state
*state
, const u8
*in
, size_t inlen
)
26 const size_t fill
= BLAKE2S_BLOCK_SIZE
- state
->buflen
;
31 memcpy(state
->buf
+ state
->buflen
, in
, fill
);
32 blake2s_compress(state
, state
->buf
, 1, BLAKE2S_BLOCK_SIZE
);
37 if (inlen
> BLAKE2S_BLOCK_SIZE
) {
38 const size_t nblocks
= DIV_ROUND_UP(inlen
, BLAKE2S_BLOCK_SIZE
);
39 blake2s_compress(state
, in
, nblocks
- 1, BLAKE2S_BLOCK_SIZE
);
40 in
+= BLAKE2S_BLOCK_SIZE
* (nblocks
- 1);
41 inlen
-= BLAKE2S_BLOCK_SIZE
* (nblocks
- 1);
43 memcpy(state
->buf
+ state
->buflen
, in
, inlen
);
44 state
->buflen
+= inlen
;
46 EXPORT_SYMBOL(blake2s_update
);
48 void blake2s_final(struct blake2s_state
*state
, u8
*out
)
50 WARN_ON(IS_ENABLED(DEBUG
) && !out
);
51 blake2s_set_lastblock(state
);
52 memset(state
->buf
+ state
->buflen
, 0,
53 BLAKE2S_BLOCK_SIZE
- state
->buflen
); /* Padding */
54 blake2s_compress(state
, state
->buf
, 1, state
->buflen
);
55 cpu_to_le32_array(state
->h
, ARRAY_SIZE(state
->h
));
56 memcpy(out
, state
->h
, state
->outlen
);
57 memzero_explicit(state
, sizeof(*state
));
59 EXPORT_SYMBOL(blake2s_final
);
61 static int __init
blake2s_mod_init(void)
63 if (!IS_ENABLED(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS
) &&
64 WARN_ON(!blake2s_selftest()))
69 module_init(blake2s_mod_init
);
70 MODULE_DESCRIPTION("BLAKE2s hash function");
71 MODULE_AUTHOR("Jason A. Donenfeld <Jason@zx2c4.com>");