e25edf5dda84ddcc2fc886220cb8928700e27f12
[openwrt/staging/ldir.git] /
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
5
6 commit 7f9b0880925f1f9d7d59504ea0892d2ae9cfc233 upstream.
7
8 Wire up our newly added Blake2s implementation via the shash API.
9
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>
13 ---
14 crypto/Kconfig | 18 ++++
15 crypto/Makefile | 1 +
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
20
21 --- a/crypto/Kconfig
22 +++ b/crypto/Kconfig
23 @@ -639,6 +639,24 @@ config CRYPTO_XXHASH
24 xxHash non-cryptographic hash algorithm. Extremely fast, working at
25 speeds close to RAM limits.
26
27 +config CRYPTO_BLAKE2S
28 + tristate "BLAKE2s digest algorithm"
29 + select CRYPTO_LIB_BLAKE2S_GENERIC
30 + select CRYPTO_HASH
31 + help
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.
35 +
36 + This module provides the following algorithms:
37 +
38 + - blake2s-128
39 + - blake2s-160
40 + - blake2s-224
41 + - blake2s-256
42 +
43 + See https://blake2.net for further information.
44 +
45 config CRYPTO_CRCT10DIF
46 tristate "CRCT10DIF algorithm"
47 select CRYPTO_HASH
48 --- a/crypto/Makefile
49 +++ b/crypto/Makefile
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
58 --- /dev/null
59 +++ b/crypto/blake2s_generic.c
60 @@ -0,0 +1,171 @@
61 +// SPDX-License-Identifier: GPL-2.0 OR MIT
62 +/*
63 + * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
64 + */
65 +
66 +#include <crypto/internal/blake2s.h>
67 +#include <crypto/internal/simd.h>
68 +#include <crypto/internal/hash.h>
69 +
70 +#include <linux/types.h>
71 +#include <linux/jump_label.h>
72 +#include <linux/kernel.h>
73 +#include <linux/module.h>
74 +
75 +static int crypto_blake2s_setkey(struct crypto_shash *tfm, const u8 *key,
76 + unsigned int keylen)
77 +{
78 + struct blake2s_tfm_ctx *tctx = crypto_shash_ctx(tfm);
79 +
80 + if (keylen == 0 || keylen > BLAKE2S_KEY_SIZE) {
81 + crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
82 + return -EINVAL;
83 + }
84 +
85 + memcpy(tctx->key, key, keylen);
86 + tctx->keylen = keylen;
87 +
88 + return 0;
89 +}
90 +
91 +static int crypto_blake2s_init(struct shash_desc *desc)
92 +{
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);
96 +
97 + if (tctx->keylen)
98 + blake2s_init_key(state, outlen, tctx->key, tctx->keylen);
99 + else
100 + blake2s_init(state, outlen);
101 +
102 + return 0;
103 +}
104 +
105 +static int crypto_blake2s_update(struct shash_desc *desc, const u8 *in,
106 + unsigned int inlen)
107 +{
108 + struct blake2s_state *state = shash_desc_ctx(desc);
109 + const size_t fill = BLAKE2S_BLOCK_SIZE - state->buflen;
110 +
111 + if (unlikely(!inlen))
112 + return 0;
113 + if (inlen > fill) {
114 + memcpy(state->buf + state->buflen, in, fill);
115 + blake2s_compress_generic(state, state->buf, 1, BLAKE2S_BLOCK_SIZE);
116 + state->buflen = 0;
117 + in += fill;
118 + inlen -= fill;
119 + }
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);
126 + }
127 + memcpy(state->buf + state->buflen, in, inlen);
128 + state->buflen += inlen;
129 +
130 + return 0;
131 +}
132 +
133 +static int crypto_blake2s_final(struct shash_desc *desc, u8 *out)
134 +{
135 + struct blake2s_state *state = shash_desc_ctx(desc);
136 +
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));
144 +
145 + return 0;
146 +}
147 +
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,
156 +
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),
163 +}, {
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,
171 +
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),
178 +}, {
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,
186 +
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),
193 +}, {
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,
201 +
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),
208 +}};
209 +
210 +static int __init blake2s_mod_init(void)
211 +{
212 + return crypto_register_shashes(blake2s_algs, ARRAY_SIZE(blake2s_algs));
213 +}
214 +
215 +static void __exit blake2s_mod_exit(void)
216 +{
217 + crypto_unregister_shashes(blake2s_algs, ARRAY_SIZE(blake2s_algs));
218 +}
219 +
220 +subsys_initcall(blake2s_mod_init);
221 +module_exit(blake2s_mod_exit);
222 +
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
234 @@ -5,6 +5,11 @@
235
236 #include <crypto/blake2s.h>
237
238 +struct blake2s_tfm_ctx {
239 + u8 key[BLAKE2S_KEY_SIZE];
240 + unsigned int keylen;
241 +};
242 +
243 void blake2s_compress_generic(struct blake2s_state *state,const u8 *block,
244 size_t nblocks, const u32 inc);
245