1 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2 From: Ard Biesheuvel <ardb@kernel.org>
3 Date: Fri, 8 Nov 2019 13:22:30 +0100
4 Subject: [PATCH] crypto: blake2s - implement generic shash driver
6 commit 7f9b0880925f1f9d7d59504ea0892d2ae9cfc233 upstream.
8 Wire up our newly added Blake2s implementation via the shash API.
10 Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
11 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
12 Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
14 crypto/Kconfig | 18 ++++
16 crypto/blake2s_generic.c | 171 ++++++++++++++++++++++++++++++
17 include/crypto/internal/blake2s.h | 5 +
18 4 files changed, 195 insertions(+)
19 create mode 100644 crypto/blake2s_generic.c
23 @@ -639,6 +639,24 @@ config CRYPTO_XXHASH
24 xxHash non-cryptographic hash algorithm. Extremely fast, working at
25 speeds close to RAM limits.
27 +config CRYPTO_BLAKE2S
28 + tristate "BLAKE2s digest algorithm"
29 + select CRYPTO_LIB_BLAKE2S_GENERIC
32 + Implementation of cryptographic hash function BLAKE2s
33 + optimized for 8-32bit platforms and can produce digests of any size
34 + between 1 to 32. The keyed hash is also implemented.
36 + This module provides the following algorithms:
43 + See https://blake2.net for further information.
45 config CRYPTO_CRCT10DIF
46 tristate "CRCT10DIF algorithm"
50 @@ -74,6 +74,7 @@ obj-$(CONFIG_CRYPTO_STREEBOG) += streebo
51 obj-$(CONFIG_CRYPTO_WP512) += wp512.o
52 CFLAGS_wp512.o := $(call cc-option,-fno-schedule-insns) # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79149
53 obj-$(CONFIG_CRYPTO_TGR192) += tgr192.o
54 +obj-$(CONFIG_CRYPTO_BLAKE2S) += blake2s_generic.o
55 obj-$(CONFIG_CRYPTO_GF128MUL) += gf128mul.o
56 obj-$(CONFIG_CRYPTO_ECB) += ecb.o
57 obj-$(CONFIG_CRYPTO_CBC) += cbc.o
59 +++ b/crypto/blake2s_generic.c
61 +// SPDX-License-Identifier: GPL-2.0 OR MIT
63 + * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
66 +#include <crypto/internal/blake2s.h>
67 +#include <crypto/internal/simd.h>
68 +#include <crypto/internal/hash.h>
70 +#include <linux/types.h>
71 +#include <linux/jump_label.h>
72 +#include <linux/kernel.h>
73 +#include <linux/module.h>
75 +static int crypto_blake2s_setkey(struct crypto_shash *tfm, const u8 *key,
76 + unsigned int keylen)
78 + struct blake2s_tfm_ctx *tctx = crypto_shash_ctx(tfm);
80 + if (keylen == 0 || keylen > BLAKE2S_KEY_SIZE) {
81 + crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
85 + memcpy(tctx->key, key, keylen);
86 + tctx->keylen = keylen;
91 +static int crypto_blake2s_init(struct shash_desc *desc)
93 + struct blake2s_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
94 + struct blake2s_state *state = shash_desc_ctx(desc);
95 + const int outlen = crypto_shash_digestsize(desc->tfm);
98 + blake2s_init_key(state, outlen, tctx->key, tctx->keylen);
100 + blake2s_init(state, outlen);
105 +static int crypto_blake2s_update(struct shash_desc *desc, const u8 *in,
106 + unsigned int inlen)
108 + struct blake2s_state *state = shash_desc_ctx(desc);
109 + const size_t fill = BLAKE2S_BLOCK_SIZE - state->buflen;
111 + if (unlikely(!inlen))
113 + if (inlen > fill) {
114 + memcpy(state->buf + state->buflen, in, fill);
115 + blake2s_compress_generic(state, state->buf, 1, BLAKE2S_BLOCK_SIZE);
120 + if (inlen > BLAKE2S_BLOCK_SIZE) {
121 + const size_t nblocks = DIV_ROUND_UP(inlen, BLAKE2S_BLOCK_SIZE);
122 + /* Hash one less (full) block than strictly possible */
123 + blake2s_compress_generic(state, in, nblocks - 1, BLAKE2S_BLOCK_SIZE);
124 + in += BLAKE2S_BLOCK_SIZE * (nblocks - 1);
125 + inlen -= BLAKE2S_BLOCK_SIZE * (nblocks - 1);
127 + memcpy(state->buf + state->buflen, in, inlen);
128 + state->buflen += inlen;
133 +static int crypto_blake2s_final(struct shash_desc *desc, u8 *out)
135 + struct blake2s_state *state = shash_desc_ctx(desc);
137 + blake2s_set_lastblock(state);
138 + memset(state->buf + state->buflen, 0,
139 + BLAKE2S_BLOCK_SIZE - state->buflen); /* Padding */
140 + blake2s_compress_generic(state, state->buf, 1, state->buflen);
141 + cpu_to_le32_array(state->h, ARRAY_SIZE(state->h));
142 + memcpy(out, state->h, state->outlen);
143 + memzero_explicit(state, sizeof(*state));
148 +static struct shash_alg blake2s_algs[] = {{
149 + .base.cra_name = "blake2s-128",
150 + .base.cra_driver_name = "blake2s-128-generic",
151 + .base.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
152 + .base.cra_ctxsize = sizeof(struct blake2s_tfm_ctx),
153 + .base.cra_priority = 200,
154 + .base.cra_blocksize = BLAKE2S_BLOCK_SIZE,
155 + .base.cra_module = THIS_MODULE,
157 + .digestsize = BLAKE2S_128_HASH_SIZE,
158 + .setkey = crypto_blake2s_setkey,
159 + .init = crypto_blake2s_init,
160 + .update = crypto_blake2s_update,
161 + .final = crypto_blake2s_final,
162 + .descsize = sizeof(struct blake2s_state),
164 + .base.cra_name = "blake2s-160",
165 + .base.cra_driver_name = "blake2s-160-generic",
166 + .base.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
167 + .base.cra_ctxsize = sizeof(struct blake2s_tfm_ctx),
168 + .base.cra_priority = 200,
169 + .base.cra_blocksize = BLAKE2S_BLOCK_SIZE,
170 + .base.cra_module = THIS_MODULE,
172 + .digestsize = BLAKE2S_160_HASH_SIZE,
173 + .setkey = crypto_blake2s_setkey,
174 + .init = crypto_blake2s_init,
175 + .update = crypto_blake2s_update,
176 + .final = crypto_blake2s_final,
177 + .descsize = sizeof(struct blake2s_state),
179 + .base.cra_name = "blake2s-224",
180 + .base.cra_driver_name = "blake2s-224-generic",
181 + .base.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
182 + .base.cra_ctxsize = sizeof(struct blake2s_tfm_ctx),
183 + .base.cra_priority = 200,
184 + .base.cra_blocksize = BLAKE2S_BLOCK_SIZE,
185 + .base.cra_module = THIS_MODULE,
187 + .digestsize = BLAKE2S_224_HASH_SIZE,
188 + .setkey = crypto_blake2s_setkey,
189 + .init = crypto_blake2s_init,
190 + .update = crypto_blake2s_update,
191 + .final = crypto_blake2s_final,
192 + .descsize = sizeof(struct blake2s_state),
194 + .base.cra_name = "blake2s-256",
195 + .base.cra_driver_name = "blake2s-256-generic",
196 + .base.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
197 + .base.cra_ctxsize = sizeof(struct blake2s_tfm_ctx),
198 + .base.cra_priority = 200,
199 + .base.cra_blocksize = BLAKE2S_BLOCK_SIZE,
200 + .base.cra_module = THIS_MODULE,
202 + .digestsize = BLAKE2S_256_HASH_SIZE,
203 + .setkey = crypto_blake2s_setkey,
204 + .init = crypto_blake2s_init,
205 + .update = crypto_blake2s_update,
206 + .final = crypto_blake2s_final,
207 + .descsize = sizeof(struct blake2s_state),
210 +static int __init blake2s_mod_init(void)
212 + return crypto_register_shashes(blake2s_algs, ARRAY_SIZE(blake2s_algs));
215 +static void __exit blake2s_mod_exit(void)
217 + crypto_unregister_shashes(blake2s_algs, ARRAY_SIZE(blake2s_algs));
220 +subsys_initcall(blake2s_mod_init);
221 +module_exit(blake2s_mod_exit);
223 +MODULE_ALIAS_CRYPTO("blake2s-128");
224 +MODULE_ALIAS_CRYPTO("blake2s-128-generic");
225 +MODULE_ALIAS_CRYPTO("blake2s-160");
226 +MODULE_ALIAS_CRYPTO("blake2s-160-generic");
227 +MODULE_ALIAS_CRYPTO("blake2s-224");
228 +MODULE_ALIAS_CRYPTO("blake2s-224-generic");
229 +MODULE_ALIAS_CRYPTO("blake2s-256");
230 +MODULE_ALIAS_CRYPTO("blake2s-256-generic");
231 +MODULE_LICENSE("GPL v2");
232 --- a/include/crypto/internal/blake2s.h
233 +++ b/include/crypto/internal/blake2s.h
236 #include <crypto/blake2s.h>
238 +struct blake2s_tfm_ctx {
239 + u8 key[BLAKE2S_KEY_SIZE];
240 + unsigned int keylen;
243 void blake2s_compress_generic(struct blake2s_state *state,const u8 *block,
244 size_t nblocks, const u32 inc);