1 // SPDX-License-Identifier: (GPL-2.0-only OR Apache-2.0) 2 /* 3 * Generic implementation of the BLAKE2b digest algorithm. Based on the BLAKE2b 4 * reference implementation, but it has been heavily modified for use in the 5 * kernel. The reference implementation was: 6 * 7 * Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under 8 * the terms of the CC0, the OpenSSL Licence, or the Apache Public License 9 * 2.0, at your option. The terms of these licenses can be found at: 10 * 11 * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 12 * - OpenSSL license : https://www.openssl.org/source/license.html 13 * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 14 * 15 * More information about BLAKE2 can be found at https://blake2.net. 16 */ 17 18 #include <asm/unaligned.h> 19 #include <linux/module.h> 20 #include <linux/kernel.h> 21 #include <linux/bitops.h> 22 #include <crypto/internal/blake2b.h> 23 #include <crypto/internal/hash.h> 24 25 static const u8 blake2b_sigma[12][16] = { 26 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, 27 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, 28 { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, 29 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 }, 30 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, 31 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 }, 32 { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 }, 33 { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 }, 34 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 }, 35 { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 }, 36 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, 37 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } 38 }; 39 40 static void blake2b_increment_counter(struct blake2b_state *S, const u64 inc) 41 { 42 S->t[0] += inc; 43 S->t[1] += (S->t[0] < inc); 44 } 45 46 #define G(r,i,a,b,c,d) \ 47 do { \ 48 a = a + b + m[blake2b_sigma[r][2*i+0]]; \ 49 d = ror64(d ^ a, 32); \ 50 c = c + d; \ 51 b = ror64(b ^ c, 24); \ 52 a = a + b + m[blake2b_sigma[r][2*i+1]]; \ 53 d = ror64(d ^ a, 16); \ 54 c = c + d; \ 55 b = ror64(b ^ c, 63); \ 56 } while (0) 57 58 #define ROUND(r) \ 59 do { \ 60 G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ 61 G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ 62 G(r,2,v[ 2],v[ 6],v[10],v[14]); \ 63 G(r,3,v[ 3],v[ 7],v[11],v[15]); \ 64 G(r,4,v[ 0],v[ 5],v[10],v[15]); \ 65 G(r,5,v[ 1],v[ 6],v[11],v[12]); \ 66 G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ 67 G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ 68 } while (0) 69 70 static void blake2b_compress_one_generic(struct blake2b_state *S, 71 const u8 block[BLAKE2B_BLOCK_SIZE]) 72 { 73 u64 m[16]; 74 u64 v[16]; 75 size_t i; 76 77 for (i = 0; i < 16; ++i) 78 m[i] = get_unaligned_le64(block + i * sizeof(m[i])); 79 80 for (i = 0; i < 8; ++i) 81 v[i] = S->h[i]; 82 83 v[ 8] = BLAKE2B_IV0; 84 v[ 9] = BLAKE2B_IV1; 85 v[10] = BLAKE2B_IV2; 86 v[11] = BLAKE2B_IV3; 87 v[12] = BLAKE2B_IV4 ^ S->t[0]; 88 v[13] = BLAKE2B_IV5 ^ S->t[1]; 89 v[14] = BLAKE2B_IV6 ^ S->f[0]; 90 v[15] = BLAKE2B_IV7 ^ S->f[1]; 91 92 ROUND(0); 93 ROUND(1); 94 ROUND(2); 95 ROUND(3); 96 ROUND(4); 97 ROUND(5); 98 ROUND(6); 99 ROUND(7); 100 ROUND(8); 101 ROUND(9); 102 ROUND(10); 103 ROUND(11); 104 #ifdef CONFIG_CC_IS_CLANG 105 #pragma nounroll /* https://llvm.org/pr45803 */ 106 #endif 107 for (i = 0; i < 8; ++i) 108 S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; 109 } 110 111 #undef G 112 #undef ROUND 113 114 void blake2b_compress_generic(struct blake2b_state *state, 115 const u8 *block, size_t nblocks, u32 inc) 116 { 117 do { 118 blake2b_increment_counter(state, inc); 119 blake2b_compress_one_generic(state, block); 120 block += BLAKE2B_BLOCK_SIZE; 121 } while (--nblocks); 122 } 123 EXPORT_SYMBOL(blake2b_compress_generic); 124 125 static int crypto_blake2b_update_generic(struct shash_desc *desc, 126 const u8 *in, unsigned int inlen) 127 { 128 return crypto_blake2b_update(desc, in, inlen, blake2b_compress_generic); 129 } 130 131 static int crypto_blake2b_final_generic(struct shash_desc *desc, u8 *out) 132 { 133 return crypto_blake2b_final(desc, out, blake2b_compress_generic); 134 } 135 136 #define BLAKE2B_ALG(name, driver_name, digest_size) \ 137 { \ 138 .base.cra_name = name, \ 139 .base.cra_driver_name = driver_name, \ 140 .base.cra_priority = 100, \ 141 .base.cra_flags = CRYPTO_ALG_OPTIONAL_KEY, \ 142 .base.cra_blocksize = BLAKE2B_BLOCK_SIZE, \ 143 .base.cra_ctxsize = sizeof(struct blake2b_tfm_ctx), \ 144 .base.cra_module = THIS_MODULE, \ 145 .digestsize = digest_size, \ 146 .setkey = crypto_blake2b_setkey, \ 147 .init = crypto_blake2b_init, \ 148 .update = crypto_blake2b_update_generic, \ 149 .final = crypto_blake2b_final_generic, \ 150 .descsize = sizeof(struct blake2b_state), \ 151 } 152 153 static struct shash_alg blake2b_algs[] = { 154 BLAKE2B_ALG("blake2b-160", "blake2b-160-generic", 155 BLAKE2B_160_HASH_SIZE), 156 BLAKE2B_ALG("blake2b-256", "blake2b-256-generic", 157 BLAKE2B_256_HASH_SIZE), 158 BLAKE2B_ALG("blake2b-384", "blake2b-384-generic", 159 BLAKE2B_384_HASH_SIZE), 160 BLAKE2B_ALG("blake2b-512", "blake2b-512-generic", 161 BLAKE2B_512_HASH_SIZE), 162 }; 163 164 static int __init blake2b_mod_init(void) 165 { 166 return crypto_register_shashes(blake2b_algs, ARRAY_SIZE(blake2b_algs)); 167 } 168 169 static void __exit blake2b_mod_fini(void) 170 { 171 crypto_unregister_shashes(blake2b_algs, ARRAY_SIZE(blake2b_algs)); 172 } 173 174 subsys_initcall(blake2b_mod_init); 175 module_exit(blake2b_mod_fini); 176 177 MODULE_AUTHOR("David Sterba <kdave@kernel.org>"); 178 MODULE_DESCRIPTION("BLAKE2b generic implementation"); 179 MODULE_LICENSE("GPL"); 180 MODULE_ALIAS_CRYPTO("blake2b-160"); 181 MODULE_ALIAS_CRYPTO("blake2b-160-generic"); 182 MODULE_ALIAS_CRYPTO("blake2b-256"); 183 MODULE_ALIAS_CRYPTO("blake2b-256-generic"); 184 MODULE_ALIAS_CRYPTO("blake2b-384"); 185 MODULE_ALIAS_CRYPTO("blake2b-384-generic"); 186 MODULE_ALIAS_CRYPTO("blake2b-512"); 187 MODULE_ALIAS_CRYPTO("blake2b-512-generic"); 188
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.