1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Crypto API support for BLAKE2b 4 * 5 * Copyright 2025 Google LLC 6 */ 7 #include <crypto/blake2b.h> 8 #include <crypto/internal/hash.h> 9 #include <linux/kernel.h> 10 #include <linux/module.h> 11 12 struct blake2b_tfm_ctx { 13 unsigned int keylen; 14 u8 key[BLAKE2B_KEY_SIZE]; 15 }; 16 17 static int crypto_blake2b_setkey(struct crypto_shash *tfm, 18 const u8 *key, unsigned int keylen) 19 { 20 struct blake2b_tfm_ctx *tctx = crypto_shash_ctx(tfm); 21 22 if (keylen > BLAKE2B_KEY_SIZE) 23 return -EINVAL; 24 memcpy(tctx->key, key, keylen); 25 tctx->keylen = keylen; 26 return 0; 27 } 28 29 #define BLAKE2B_CTX(desc) ((struct blake2b_ctx *)shash_desc_ctx(desc)) 30 31 static int crypto_blake2b_init(struct shash_desc *desc) 32 { 33 const struct blake2b_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm); 34 unsigned int digestsize = crypto_shash_digestsize(desc->tfm); 35 36 blake2b_init_key(BLAKE2B_CTX(desc), digestsize, 37 tctx->key, tctx->keylen); 38 return 0; 39 } 40 41 static int crypto_blake2b_update(struct shash_desc *desc, 42 const u8 *data, unsigned int len) 43 { 44 blake2b_update(BLAKE2B_CTX(desc), data, len); 45 return 0; 46 } 47 48 static int crypto_blake2b_final(struct shash_desc *desc, u8 *out) 49 { 50 blake2b_final(BLAKE2B_CTX(desc), out); 51 return 0; 52 } 53 54 static int crypto_blake2b_digest(struct shash_desc *desc, 55 const u8 *data, unsigned int len, u8 *out) 56 { 57 const struct blake2b_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm); 58 unsigned int digestsize = crypto_shash_digestsize(desc->tfm); 59 60 blake2b(tctx->key, tctx->keylen, data, len, out, digestsize); 61 return 0; 62 } 63 64 #define BLAKE2B_ALG(name, digest_size) \ 65 { \ 66 .base.cra_name = name, \ 67 .base.cra_driver_name = name "-lib", \ 68 .base.cra_priority = 300, \ 69 .base.cra_flags = CRYPTO_ALG_OPTIONAL_KEY, \ 70 .base.cra_blocksize = BLAKE2B_BLOCK_SIZE, \ 71 .base.cra_ctxsize = sizeof(struct blake2b_tfm_ctx), \ 72 .base.cra_module = THIS_MODULE, \ 73 .digestsize = digest_size, \ 74 .setkey = crypto_blake2b_setkey, \ 75 .init = crypto_blake2b_init, \ 76 .update = crypto_blake2b_update, \ 77 .final = crypto_blake2b_final, \ 78 .digest = crypto_blake2b_digest, \ 79 .descsize = sizeof(struct blake2b_ctx), \ 80 } 81 82 static struct shash_alg algs[] = { 83 BLAKE2B_ALG("blake2b-160", BLAKE2B_160_HASH_SIZE), 84 BLAKE2B_ALG("blake2b-256", BLAKE2B_256_HASH_SIZE), 85 BLAKE2B_ALG("blake2b-384", BLAKE2B_384_HASH_SIZE), 86 BLAKE2B_ALG("blake2b-512", BLAKE2B_512_HASH_SIZE), 87 }; 88 89 static int __init crypto_blake2b_mod_init(void) 90 { 91 return crypto_register_shashes(algs, ARRAY_SIZE(algs)); 92 } 93 module_init(crypto_blake2b_mod_init); 94 95 static void __exit crypto_blake2b_mod_exit(void) 96 { 97 crypto_unregister_shashes(algs, ARRAY_SIZE(algs)); 98 } 99 module_exit(crypto_blake2b_mod_exit); 100 101 MODULE_LICENSE("GPL"); 102 MODULE_DESCRIPTION("Crypto API support for BLAKE2b"); 103 104 MODULE_ALIAS_CRYPTO("blake2b-160"); 105 MODULE_ALIAS_CRYPTO("blake2b-160-lib"); 106 MODULE_ALIAS_CRYPTO("blake2b-256"); 107 MODULE_ALIAS_CRYPTO("blake2b-256-lib"); 108 MODULE_ALIAS_CRYPTO("blake2b-384"); 109 MODULE_ALIAS_CRYPTO("blake2b-384-lib"); 110 MODULE_ALIAS_CRYPTO("blake2b-512"); 111 MODULE_ALIAS_CRYPTO("blake2b-512-lib"); 112