1 // SPDX-License-Identifier: GPL-2.0 OR MIT
3 * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
6 #include <crypto/internal/blake2s.h>
7 #include <crypto/internal/simd.h>
8 #include <crypto/internal/hash.h>
10 #include <linux/types.h>
11 #include <linux/jump_label.h>
12 #include <linux/kernel.h>
13 #include <linux/module.h>
15 static int crypto_blake2s_setkey(struct crypto_shash
*tfm
, const u8
*key
,
18 struct blake2s_tfm_ctx
*tctx
= crypto_shash_ctx(tfm
);
20 if (keylen
== 0 || keylen
> BLAKE2S_KEY_SIZE
) {
21 crypto_shash_set_flags(tfm
, CRYPTO_TFM_RES_BAD_KEY_LEN
);
25 memcpy(tctx
->key
, key
, keylen
);
26 tctx
->keylen
= keylen
;
31 static int crypto_blake2s_init(struct shash_desc
*desc
)
33 struct blake2s_tfm_ctx
*tctx
= crypto_shash_ctx(desc
->tfm
);
34 struct blake2s_state
*state
= shash_desc_ctx(desc
);
35 const int outlen
= crypto_shash_digestsize(desc
->tfm
);
38 blake2s_init_key(state
, outlen
, tctx
->key
, tctx
->keylen
);
40 blake2s_init(state
, outlen
);
45 static int crypto_blake2s_update(struct shash_desc
*desc
, const u8
*in
,
48 struct blake2s_state
*state
= shash_desc_ctx(desc
);
49 const size_t fill
= BLAKE2S_BLOCK_SIZE
- state
->buflen
;
54 memcpy(state
->buf
+ state
->buflen
, in
, fill
);
55 blake2s_compress_generic(state
, state
->buf
, 1, BLAKE2S_BLOCK_SIZE
);
60 if (inlen
> BLAKE2S_BLOCK_SIZE
) {
61 const size_t nblocks
= DIV_ROUND_UP(inlen
, BLAKE2S_BLOCK_SIZE
);
62 /* Hash one less (full) block than strictly possible */
63 blake2s_compress_generic(state
, in
, nblocks
- 1, BLAKE2S_BLOCK_SIZE
);
64 in
+= BLAKE2S_BLOCK_SIZE
* (nblocks
- 1);
65 inlen
-= BLAKE2S_BLOCK_SIZE
* (nblocks
- 1);
67 memcpy(state
->buf
+ state
->buflen
, in
, inlen
);
68 state
->buflen
+= inlen
;
73 static int crypto_blake2s_final(struct shash_desc
*desc
, u8
*out
)
75 struct blake2s_state
*state
= shash_desc_ctx(desc
);
77 blake2s_set_lastblock(state
);
78 memset(state
->buf
+ state
->buflen
, 0,
79 BLAKE2S_BLOCK_SIZE
- state
->buflen
); /* Padding */
80 blake2s_compress_generic(state
, state
->buf
, 1, state
->buflen
);
81 cpu_to_le32_array(state
->h
, ARRAY_SIZE(state
->h
));
82 memcpy(out
, state
->h
, state
->outlen
);
83 memzero_explicit(state
, sizeof(*state
));
88 static struct shash_alg blake2s_algs
[] = {{
89 .base
.cra_name
= "blake2s-128",
90 .base
.cra_driver_name
= "blake2s-128-generic",
91 .base
.cra_flags
= CRYPTO_ALG_OPTIONAL_KEY
,
92 .base
.cra_ctxsize
= sizeof(struct blake2s_tfm_ctx
),
93 .base
.cra_priority
= 200,
94 .base
.cra_blocksize
= BLAKE2S_BLOCK_SIZE
,
95 .base
.cra_module
= THIS_MODULE
,
97 .digestsize
= BLAKE2S_128_HASH_SIZE
,
98 .setkey
= crypto_blake2s_setkey
,
99 .init
= crypto_blake2s_init
,
100 .update
= crypto_blake2s_update
,
101 .final
= crypto_blake2s_final
,
102 .descsize
= sizeof(struct blake2s_state
),
104 .base
.cra_name
= "blake2s-160",
105 .base
.cra_driver_name
= "blake2s-160-generic",
106 .base
.cra_flags
= CRYPTO_ALG_OPTIONAL_KEY
,
107 .base
.cra_ctxsize
= sizeof(struct blake2s_tfm_ctx
),
108 .base
.cra_priority
= 200,
109 .base
.cra_blocksize
= BLAKE2S_BLOCK_SIZE
,
110 .base
.cra_module
= THIS_MODULE
,
112 .digestsize
= BLAKE2S_160_HASH_SIZE
,
113 .setkey
= crypto_blake2s_setkey
,
114 .init
= crypto_blake2s_init
,
115 .update
= crypto_blake2s_update
,
116 .final
= crypto_blake2s_final
,
117 .descsize
= sizeof(struct blake2s_state
),
119 .base
.cra_name
= "blake2s-224",
120 .base
.cra_driver_name
= "blake2s-224-generic",
121 .base
.cra_flags
= CRYPTO_ALG_OPTIONAL_KEY
,
122 .base
.cra_ctxsize
= sizeof(struct blake2s_tfm_ctx
),
123 .base
.cra_priority
= 200,
124 .base
.cra_blocksize
= BLAKE2S_BLOCK_SIZE
,
125 .base
.cra_module
= THIS_MODULE
,
127 .digestsize
= BLAKE2S_224_HASH_SIZE
,
128 .setkey
= crypto_blake2s_setkey
,
129 .init
= crypto_blake2s_init
,
130 .update
= crypto_blake2s_update
,
131 .final
= crypto_blake2s_final
,
132 .descsize
= sizeof(struct blake2s_state
),
134 .base
.cra_name
= "blake2s-256",
135 .base
.cra_driver_name
= "blake2s-256-generic",
136 .base
.cra_flags
= CRYPTO_ALG_OPTIONAL_KEY
,
137 .base
.cra_ctxsize
= sizeof(struct blake2s_tfm_ctx
),
138 .base
.cra_priority
= 200,
139 .base
.cra_blocksize
= BLAKE2S_BLOCK_SIZE
,
140 .base
.cra_module
= THIS_MODULE
,
142 .digestsize
= BLAKE2S_256_HASH_SIZE
,
143 .setkey
= crypto_blake2s_setkey
,
144 .init
= crypto_blake2s_init
,
145 .update
= crypto_blake2s_update
,
146 .final
= crypto_blake2s_final
,
147 .descsize
= sizeof(struct blake2s_state
),
150 static int __init
blake2s_mod_init(void)
152 return crypto_register_shashes(blake2s_algs
, ARRAY_SIZE(blake2s_algs
));
155 static void __exit
blake2s_mod_exit(void)
157 crypto_unregister_shashes(blake2s_algs
, ARRAY_SIZE(blake2s_algs
));
160 subsys_initcall(blake2s_mod_init
);
161 module_exit(blake2s_mod_exit
);
163 MODULE_ALIAS_CRYPTO("blake2s-128");
164 MODULE_ALIAS_CRYPTO("blake2s-128-generic");
165 MODULE_ALIAS_CRYPTO("blake2s-160");
166 MODULE_ALIAS_CRYPTO("blake2s-160-generic");
167 MODULE_ALIAS_CRYPTO("blake2s-224");
168 MODULE_ALIAS_CRYPTO("blake2s-224-generic");
169 MODULE_ALIAS_CRYPTO("blake2s-256");
170 MODULE_ALIAS_CRYPTO("blake2s-256-generic");
171 MODULE_LICENSE("GPL v2");