forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
crypto: blake2s - implement generic shash driver
Wire up our newly added Blake2s implementation via the shash API. Signed-off-by: Ard Biesheuvel <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
- Loading branch information
1 parent
17e1df6
commit 7f9b088
Showing
4 changed files
with
195 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
// SPDX-License-Identifier: GPL-2.0 OR MIT | ||
/* | ||
* Copyright (C) 2015-2019 Jason A. Donenfeld <[email protected]>. All Rights Reserved. | ||
*/ | ||
|
||
#include <crypto/internal/blake2s.h> | ||
#include <crypto/internal/simd.h> | ||
#include <crypto/internal/hash.h> | ||
|
||
#include <linux/types.h> | ||
#include <linux/jump_label.h> | ||
#include <linux/kernel.h> | ||
#include <linux/module.h> | ||
|
||
static int crypto_blake2s_setkey(struct crypto_shash *tfm, const u8 *key, | ||
unsigned int keylen) | ||
{ | ||
struct blake2s_tfm_ctx *tctx = crypto_shash_ctx(tfm); | ||
|
||
if (keylen == 0 || keylen > BLAKE2S_KEY_SIZE) { | ||
crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); | ||
return -EINVAL; | ||
} | ||
|
||
memcpy(tctx->key, key, keylen); | ||
tctx->keylen = keylen; | ||
|
||
return 0; | ||
} | ||
|
||
static int crypto_blake2s_init(struct shash_desc *desc) | ||
{ | ||
struct blake2s_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm); | ||
struct blake2s_state *state = shash_desc_ctx(desc); | ||
const int outlen = crypto_shash_digestsize(desc->tfm); | ||
|
||
if (tctx->keylen) | ||
blake2s_init_key(state, outlen, tctx->key, tctx->keylen); | ||
else | ||
blake2s_init(state, outlen); | ||
|
||
return 0; | ||
} | ||
|
||
static int crypto_blake2s_update(struct shash_desc *desc, const u8 *in, | ||
unsigned int inlen) | ||
{ | ||
struct blake2s_state *state = shash_desc_ctx(desc); | ||
const size_t fill = BLAKE2S_BLOCK_SIZE - state->buflen; | ||
|
||
if (unlikely(!inlen)) | ||
return 0; | ||
if (inlen > fill) { | ||
memcpy(state->buf + state->buflen, in, fill); | ||
blake2s_compress_generic(state, state->buf, 1, BLAKE2S_BLOCK_SIZE); | ||
state->buflen = 0; | ||
in += fill; | ||
inlen -= fill; | ||
} | ||
if (inlen > BLAKE2S_BLOCK_SIZE) { | ||
const size_t nblocks = DIV_ROUND_UP(inlen, BLAKE2S_BLOCK_SIZE); | ||
/* Hash one less (full) block than strictly possible */ | ||
blake2s_compress_generic(state, in, nblocks - 1, BLAKE2S_BLOCK_SIZE); | ||
in += BLAKE2S_BLOCK_SIZE * (nblocks - 1); | ||
inlen -= BLAKE2S_BLOCK_SIZE * (nblocks - 1); | ||
} | ||
memcpy(state->buf + state->buflen, in, inlen); | ||
state->buflen += inlen; | ||
|
||
return 0; | ||
} | ||
|
||
static int crypto_blake2s_final(struct shash_desc *desc, u8 *out) | ||
{ | ||
struct blake2s_state *state = shash_desc_ctx(desc); | ||
|
||
blake2s_set_lastblock(state); | ||
memset(state->buf + state->buflen, 0, | ||
BLAKE2S_BLOCK_SIZE - state->buflen); /* Padding */ | ||
blake2s_compress_generic(state, state->buf, 1, state->buflen); | ||
cpu_to_le32_array(state->h, ARRAY_SIZE(state->h)); | ||
memcpy(out, state->h, state->outlen); | ||
memzero_explicit(state, sizeof(*state)); | ||
|
||
return 0; | ||
} | ||
|
||
static struct shash_alg blake2s_algs[] = {{ | ||
.base.cra_name = "blake2s-128", | ||
.base.cra_driver_name = "blake2s-128-generic", | ||
.base.cra_flags = CRYPTO_ALG_OPTIONAL_KEY, | ||
.base.cra_ctxsize = sizeof(struct blake2s_tfm_ctx), | ||
.base.cra_priority = 200, | ||
.base.cra_blocksize = BLAKE2S_BLOCK_SIZE, | ||
.base.cra_module = THIS_MODULE, | ||
|
||
.digestsize = BLAKE2S_128_HASH_SIZE, | ||
.setkey = crypto_blake2s_setkey, | ||
.init = crypto_blake2s_init, | ||
.update = crypto_blake2s_update, | ||
.final = crypto_blake2s_final, | ||
.descsize = sizeof(struct blake2s_state), | ||
}, { | ||
.base.cra_name = "blake2s-160", | ||
.base.cra_driver_name = "blake2s-160-generic", | ||
.base.cra_flags = CRYPTO_ALG_OPTIONAL_KEY, | ||
.base.cra_ctxsize = sizeof(struct blake2s_tfm_ctx), | ||
.base.cra_priority = 200, | ||
.base.cra_blocksize = BLAKE2S_BLOCK_SIZE, | ||
.base.cra_module = THIS_MODULE, | ||
|
||
.digestsize = BLAKE2S_160_HASH_SIZE, | ||
.setkey = crypto_blake2s_setkey, | ||
.init = crypto_blake2s_init, | ||
.update = crypto_blake2s_update, | ||
.final = crypto_blake2s_final, | ||
.descsize = sizeof(struct blake2s_state), | ||
}, { | ||
.base.cra_name = "blake2s-224", | ||
.base.cra_driver_name = "blake2s-224-generic", | ||
.base.cra_flags = CRYPTO_ALG_OPTIONAL_KEY, | ||
.base.cra_ctxsize = sizeof(struct blake2s_tfm_ctx), | ||
.base.cra_priority = 200, | ||
.base.cra_blocksize = BLAKE2S_BLOCK_SIZE, | ||
.base.cra_module = THIS_MODULE, | ||
|
||
.digestsize = BLAKE2S_224_HASH_SIZE, | ||
.setkey = crypto_blake2s_setkey, | ||
.init = crypto_blake2s_init, | ||
.update = crypto_blake2s_update, | ||
.final = crypto_blake2s_final, | ||
.descsize = sizeof(struct blake2s_state), | ||
}, { | ||
.base.cra_name = "blake2s-256", | ||
.base.cra_driver_name = "blake2s-256-generic", | ||
.base.cra_flags = CRYPTO_ALG_OPTIONAL_KEY, | ||
.base.cra_ctxsize = sizeof(struct blake2s_tfm_ctx), | ||
.base.cra_priority = 200, | ||
.base.cra_blocksize = BLAKE2S_BLOCK_SIZE, | ||
.base.cra_module = THIS_MODULE, | ||
|
||
.digestsize = BLAKE2S_256_HASH_SIZE, | ||
.setkey = crypto_blake2s_setkey, | ||
.init = crypto_blake2s_init, | ||
.update = crypto_blake2s_update, | ||
.final = crypto_blake2s_final, | ||
.descsize = sizeof(struct blake2s_state), | ||
}}; | ||
|
||
static int __init blake2s_mod_init(void) | ||
{ | ||
return crypto_register_shashes(blake2s_algs, ARRAY_SIZE(blake2s_algs)); | ||
} | ||
|
||
static void __exit blake2s_mod_exit(void) | ||
{ | ||
crypto_unregister_shashes(blake2s_algs, ARRAY_SIZE(blake2s_algs)); | ||
} | ||
|
||
subsys_initcall(blake2s_mod_init); | ||
module_exit(blake2s_mod_exit); | ||
|
||
MODULE_ALIAS_CRYPTO("blake2s-128"); | ||
MODULE_ALIAS_CRYPTO("blake2s-128-generic"); | ||
MODULE_ALIAS_CRYPTO("blake2s-160"); | ||
MODULE_ALIAS_CRYPTO("blake2s-160-generic"); | ||
MODULE_ALIAS_CRYPTO("blake2s-224"); | ||
MODULE_ALIAS_CRYPTO("blake2s-224-generic"); | ||
MODULE_ALIAS_CRYPTO("blake2s-256"); | ||
MODULE_ALIAS_CRYPTO("blake2s-256-generic"); | ||
MODULE_LICENSE("GPL v2"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters