153964b9eSJeff Garzik /* 253964b9eSJeff Garzik * Cryptographic API. 353964b9eSJeff Garzik * 453964b9eSJeff Garzik * SHA-3, as specified in 553964b9eSJeff Garzik * http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf 653964b9eSJeff Garzik * 753964b9eSJeff Garzik * SHA-3 code by Jeff Garzik <jeff@garzik.org> 853964b9eSJeff Garzik * 953964b9eSJeff Garzik * This program is free software; you can redistribute it and/or modify it 1053964b9eSJeff Garzik * under the terms of the GNU General Public License as published by the Free 1153964b9eSJeff Garzik * Software Foundation; either version 2 of the License, or (at your option)• 1253964b9eSJeff Garzik * any later version. 1353964b9eSJeff Garzik * 1453964b9eSJeff Garzik */ 1553964b9eSJeff Garzik #include <crypto/internal/hash.h> 1653964b9eSJeff Garzik #include <linux/init.h> 1753964b9eSJeff Garzik #include <linux/module.h> 1853964b9eSJeff Garzik #include <linux/types.h> 1953964b9eSJeff Garzik #include <crypto/sha3.h> 2053964b9eSJeff Garzik #include <asm/byteorder.h> 21*c013cee9SArd Biesheuvel #include <asm/unaligned.h> 2253964b9eSJeff Garzik 2353964b9eSJeff Garzik #define KECCAK_ROUNDS 24 2453964b9eSJeff Garzik 2553964b9eSJeff Garzik #define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) 2653964b9eSJeff Garzik 2753964b9eSJeff Garzik static const u64 keccakf_rndc[24] = { 28f743e70eSGeert Uytterhoeven 0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808aULL, 29f743e70eSGeert Uytterhoeven 0x8000000080008000ULL, 0x000000000000808bULL, 0x0000000080000001ULL, 30f743e70eSGeert Uytterhoeven 0x8000000080008081ULL, 0x8000000000008009ULL, 0x000000000000008aULL, 31f743e70eSGeert Uytterhoeven 0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000aULL, 32f743e70eSGeert Uytterhoeven 0x000000008000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 33f743e70eSGeert Uytterhoeven 0x8000000000008003ULL, 0x8000000000008002ULL, 0x8000000000000080ULL, 34f743e70eSGeert Uytterhoeven 0x000000000000800aULL, 0x800000008000000aULL, 0x8000000080008081ULL, 35f743e70eSGeert Uytterhoeven 0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL 3653964b9eSJeff Garzik }; 3753964b9eSJeff Garzik 3853964b9eSJeff Garzik static const int keccakf_rotc[24] = { 3953964b9eSJeff Garzik 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 4053964b9eSJeff Garzik 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 4153964b9eSJeff Garzik }; 4253964b9eSJeff Garzik 4353964b9eSJeff Garzik static const int keccakf_piln[24] = { 4453964b9eSJeff Garzik 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 4553964b9eSJeff Garzik 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 4653964b9eSJeff Garzik }; 4753964b9eSJeff Garzik 4853964b9eSJeff Garzik /* update the state with given number of rounds */ 4953964b9eSJeff Garzik 5053964b9eSJeff Garzik static void keccakf(u64 st[25]) 5153964b9eSJeff Garzik { 5253964b9eSJeff Garzik int i, j, round; 5353964b9eSJeff Garzik u64 t, bc[5]; 5453964b9eSJeff Garzik 5553964b9eSJeff Garzik for (round = 0; round < KECCAK_ROUNDS; round++) { 5653964b9eSJeff Garzik 5753964b9eSJeff Garzik /* Theta */ 5853964b9eSJeff Garzik for (i = 0; i < 5; i++) 5953964b9eSJeff Garzik bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] 6053964b9eSJeff Garzik ^ st[i + 20]; 6153964b9eSJeff Garzik 6253964b9eSJeff Garzik for (i = 0; i < 5; i++) { 6353964b9eSJeff Garzik t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1); 6453964b9eSJeff Garzik for (j = 0; j < 25; j += 5) 6553964b9eSJeff Garzik st[j + i] ^= t; 6653964b9eSJeff Garzik } 6753964b9eSJeff Garzik 6853964b9eSJeff Garzik /* Rho Pi */ 6953964b9eSJeff Garzik t = st[1]; 7053964b9eSJeff Garzik for (i = 0; i < 24; i++) { 7153964b9eSJeff Garzik j = keccakf_piln[i]; 7253964b9eSJeff Garzik bc[0] = st[j]; 7353964b9eSJeff Garzik st[j] = ROTL64(t, keccakf_rotc[i]); 7453964b9eSJeff Garzik t = bc[0]; 7553964b9eSJeff Garzik } 7653964b9eSJeff Garzik 7753964b9eSJeff Garzik /* Chi */ 7853964b9eSJeff Garzik for (j = 0; j < 25; j += 5) { 7953964b9eSJeff Garzik for (i = 0; i < 5; i++) 8053964b9eSJeff Garzik bc[i] = st[j + i]; 8153964b9eSJeff Garzik for (i = 0; i < 5; i++) 8253964b9eSJeff Garzik st[j + i] ^= (~bc[(i + 1) % 5]) & 8353964b9eSJeff Garzik bc[(i + 2) % 5]; 8453964b9eSJeff Garzik } 8553964b9eSJeff Garzik 8653964b9eSJeff Garzik /* Iota */ 8753964b9eSJeff Garzik st[0] ^= keccakf_rndc[round]; 8853964b9eSJeff Garzik } 8953964b9eSJeff Garzik } 9053964b9eSJeff Garzik 9153964b9eSJeff Garzik static void sha3_init(struct sha3_state *sctx, unsigned int digest_sz) 9253964b9eSJeff Garzik { 9353964b9eSJeff Garzik memset(sctx, 0, sizeof(*sctx)); 9453964b9eSJeff Garzik sctx->md_len = digest_sz; 9553964b9eSJeff Garzik sctx->rsiz = 200 - 2 * digest_sz; 9653964b9eSJeff Garzik sctx->rsizw = sctx->rsiz / 8; 9753964b9eSJeff Garzik } 9853964b9eSJeff Garzik 9953964b9eSJeff Garzik static int sha3_224_init(struct shash_desc *desc) 10053964b9eSJeff Garzik { 10153964b9eSJeff Garzik struct sha3_state *sctx = shash_desc_ctx(desc); 10253964b9eSJeff Garzik 10353964b9eSJeff Garzik sha3_init(sctx, SHA3_224_DIGEST_SIZE); 10453964b9eSJeff Garzik return 0; 10553964b9eSJeff Garzik } 10653964b9eSJeff Garzik 10753964b9eSJeff Garzik static int sha3_256_init(struct shash_desc *desc) 10853964b9eSJeff Garzik { 10953964b9eSJeff Garzik struct sha3_state *sctx = shash_desc_ctx(desc); 11053964b9eSJeff Garzik 11153964b9eSJeff Garzik sha3_init(sctx, SHA3_256_DIGEST_SIZE); 11253964b9eSJeff Garzik return 0; 11353964b9eSJeff Garzik } 11453964b9eSJeff Garzik 11553964b9eSJeff Garzik static int sha3_384_init(struct shash_desc *desc) 11653964b9eSJeff Garzik { 11753964b9eSJeff Garzik struct sha3_state *sctx = shash_desc_ctx(desc); 11853964b9eSJeff Garzik 11953964b9eSJeff Garzik sha3_init(sctx, SHA3_384_DIGEST_SIZE); 12053964b9eSJeff Garzik return 0; 12153964b9eSJeff Garzik } 12253964b9eSJeff Garzik 12353964b9eSJeff Garzik static int sha3_512_init(struct shash_desc *desc) 12453964b9eSJeff Garzik { 12553964b9eSJeff Garzik struct sha3_state *sctx = shash_desc_ctx(desc); 12653964b9eSJeff Garzik 12753964b9eSJeff Garzik sha3_init(sctx, SHA3_512_DIGEST_SIZE); 12853964b9eSJeff Garzik return 0; 12953964b9eSJeff Garzik } 13053964b9eSJeff Garzik 13153964b9eSJeff Garzik static int sha3_update(struct shash_desc *desc, const u8 *data, 13253964b9eSJeff Garzik unsigned int len) 13353964b9eSJeff Garzik { 13453964b9eSJeff Garzik struct sha3_state *sctx = shash_desc_ctx(desc); 13553964b9eSJeff Garzik unsigned int done; 13653964b9eSJeff Garzik const u8 *src; 13753964b9eSJeff Garzik 13853964b9eSJeff Garzik done = 0; 13953964b9eSJeff Garzik src = data; 14053964b9eSJeff Garzik 14153964b9eSJeff Garzik if ((sctx->partial + len) > (sctx->rsiz - 1)) { 14253964b9eSJeff Garzik if (sctx->partial) { 14353964b9eSJeff Garzik done = -sctx->partial; 14453964b9eSJeff Garzik memcpy(sctx->buf + sctx->partial, data, 14553964b9eSJeff Garzik done + sctx->rsiz); 14653964b9eSJeff Garzik src = sctx->buf; 14753964b9eSJeff Garzik } 14853964b9eSJeff Garzik 14953964b9eSJeff Garzik do { 15053964b9eSJeff Garzik unsigned int i; 15153964b9eSJeff Garzik 15253964b9eSJeff Garzik for (i = 0; i < sctx->rsizw; i++) 153*c013cee9SArd Biesheuvel sctx->st[i] ^= get_unaligned_le64(src + 8 * i); 15453964b9eSJeff Garzik keccakf(sctx->st); 15553964b9eSJeff Garzik 15653964b9eSJeff Garzik done += sctx->rsiz; 15753964b9eSJeff Garzik src = data + done; 15853964b9eSJeff Garzik } while (done + (sctx->rsiz - 1) < len); 15953964b9eSJeff Garzik 16053964b9eSJeff Garzik sctx->partial = 0; 16153964b9eSJeff Garzik } 16253964b9eSJeff Garzik memcpy(sctx->buf + sctx->partial, src, len - done); 16353964b9eSJeff Garzik sctx->partial += (len - done); 16453964b9eSJeff Garzik 16553964b9eSJeff Garzik return 0; 16653964b9eSJeff Garzik } 16753964b9eSJeff Garzik 16853964b9eSJeff Garzik static int sha3_final(struct shash_desc *desc, u8 *out) 16953964b9eSJeff Garzik { 17053964b9eSJeff Garzik struct sha3_state *sctx = shash_desc_ctx(desc); 17153964b9eSJeff Garzik unsigned int i, inlen = sctx->partial; 17253964b9eSJeff Garzik 17353964b9eSJeff Garzik sctx->buf[inlen++] = 0x06; 17453964b9eSJeff Garzik memset(sctx->buf + inlen, 0, sctx->rsiz - inlen); 17553964b9eSJeff Garzik sctx->buf[sctx->rsiz - 1] |= 0x80; 17653964b9eSJeff Garzik 17753964b9eSJeff Garzik for (i = 0; i < sctx->rsizw; i++) 178*c013cee9SArd Biesheuvel sctx->st[i] ^= get_unaligned_le64(sctx->buf + 8 * i); 17953964b9eSJeff Garzik 18053964b9eSJeff Garzik keccakf(sctx->st); 18153964b9eSJeff Garzik 18253964b9eSJeff Garzik for (i = 0; i < sctx->rsizw; i++) 18353964b9eSJeff Garzik sctx->st[i] = cpu_to_le64(sctx->st[i]); 18453964b9eSJeff Garzik 18553964b9eSJeff Garzik memcpy(out, sctx->st, sctx->md_len); 18653964b9eSJeff Garzik 18753964b9eSJeff Garzik memset(sctx, 0, sizeof(*sctx)); 18853964b9eSJeff Garzik return 0; 18953964b9eSJeff Garzik } 19053964b9eSJeff Garzik 19153964b9eSJeff Garzik static struct shash_alg sha3_224 = { 19253964b9eSJeff Garzik .digestsize = SHA3_224_DIGEST_SIZE, 19353964b9eSJeff Garzik .init = sha3_224_init, 19453964b9eSJeff Garzik .update = sha3_update, 19553964b9eSJeff Garzik .final = sha3_final, 19653964b9eSJeff Garzik .descsize = sizeof(struct sha3_state), 19753964b9eSJeff Garzik .base = { 19853964b9eSJeff Garzik .cra_name = "sha3-224", 19953964b9eSJeff Garzik .cra_driver_name = "sha3-224-generic", 20053964b9eSJeff Garzik .cra_flags = CRYPTO_ALG_TYPE_SHASH, 20153964b9eSJeff Garzik .cra_blocksize = SHA3_224_BLOCK_SIZE, 20253964b9eSJeff Garzik .cra_module = THIS_MODULE, 20353964b9eSJeff Garzik } 20453964b9eSJeff Garzik }; 20553964b9eSJeff Garzik 20653964b9eSJeff Garzik static struct shash_alg sha3_256 = { 20753964b9eSJeff Garzik .digestsize = SHA3_256_DIGEST_SIZE, 20853964b9eSJeff Garzik .init = sha3_256_init, 20953964b9eSJeff Garzik .update = sha3_update, 21053964b9eSJeff Garzik .final = sha3_final, 21153964b9eSJeff Garzik .descsize = sizeof(struct sha3_state), 21253964b9eSJeff Garzik .base = { 21353964b9eSJeff Garzik .cra_name = "sha3-256", 21453964b9eSJeff Garzik .cra_driver_name = "sha3-256-generic", 21553964b9eSJeff Garzik .cra_flags = CRYPTO_ALG_TYPE_SHASH, 21653964b9eSJeff Garzik .cra_blocksize = SHA3_256_BLOCK_SIZE, 21753964b9eSJeff Garzik .cra_module = THIS_MODULE, 21853964b9eSJeff Garzik } 21953964b9eSJeff Garzik }; 22053964b9eSJeff Garzik 22153964b9eSJeff Garzik static struct shash_alg sha3_384 = { 22253964b9eSJeff Garzik .digestsize = SHA3_384_DIGEST_SIZE, 22353964b9eSJeff Garzik .init = sha3_384_init, 22453964b9eSJeff Garzik .update = sha3_update, 22553964b9eSJeff Garzik .final = sha3_final, 22653964b9eSJeff Garzik .descsize = sizeof(struct sha3_state), 22753964b9eSJeff Garzik .base = { 22853964b9eSJeff Garzik .cra_name = "sha3-384", 22953964b9eSJeff Garzik .cra_driver_name = "sha3-384-generic", 23053964b9eSJeff Garzik .cra_flags = CRYPTO_ALG_TYPE_SHASH, 23153964b9eSJeff Garzik .cra_blocksize = SHA3_384_BLOCK_SIZE, 23253964b9eSJeff Garzik .cra_module = THIS_MODULE, 23353964b9eSJeff Garzik } 23453964b9eSJeff Garzik }; 23553964b9eSJeff Garzik 23653964b9eSJeff Garzik static struct shash_alg sha3_512 = { 23753964b9eSJeff Garzik .digestsize = SHA3_512_DIGEST_SIZE, 23853964b9eSJeff Garzik .init = sha3_512_init, 23953964b9eSJeff Garzik .update = sha3_update, 24053964b9eSJeff Garzik .final = sha3_final, 24153964b9eSJeff Garzik .descsize = sizeof(struct sha3_state), 24253964b9eSJeff Garzik .base = { 24353964b9eSJeff Garzik .cra_name = "sha3-512", 24453964b9eSJeff Garzik .cra_driver_name = "sha3-512-generic", 24553964b9eSJeff Garzik .cra_flags = CRYPTO_ALG_TYPE_SHASH, 24653964b9eSJeff Garzik .cra_blocksize = SHA3_512_BLOCK_SIZE, 24753964b9eSJeff Garzik .cra_module = THIS_MODULE, 24853964b9eSJeff Garzik } 24953964b9eSJeff Garzik }; 25053964b9eSJeff Garzik 25153964b9eSJeff Garzik static int __init sha3_generic_mod_init(void) 25253964b9eSJeff Garzik { 25353964b9eSJeff Garzik int ret; 25453964b9eSJeff Garzik 25553964b9eSJeff Garzik ret = crypto_register_shash(&sha3_224); 25653964b9eSJeff Garzik if (ret < 0) 25753964b9eSJeff Garzik goto err_out; 25853964b9eSJeff Garzik ret = crypto_register_shash(&sha3_256); 25953964b9eSJeff Garzik if (ret < 0) 26053964b9eSJeff Garzik goto err_out_224; 26153964b9eSJeff Garzik ret = crypto_register_shash(&sha3_384); 26253964b9eSJeff Garzik if (ret < 0) 26353964b9eSJeff Garzik goto err_out_256; 26453964b9eSJeff Garzik ret = crypto_register_shash(&sha3_512); 26553964b9eSJeff Garzik if (ret < 0) 26653964b9eSJeff Garzik goto err_out_384; 26753964b9eSJeff Garzik 26853964b9eSJeff Garzik return 0; 26953964b9eSJeff Garzik 27053964b9eSJeff Garzik err_out_384: 27153964b9eSJeff Garzik crypto_unregister_shash(&sha3_384); 27253964b9eSJeff Garzik err_out_256: 27353964b9eSJeff Garzik crypto_unregister_shash(&sha3_256); 27453964b9eSJeff Garzik err_out_224: 27553964b9eSJeff Garzik crypto_unregister_shash(&sha3_224); 27653964b9eSJeff Garzik err_out: 27753964b9eSJeff Garzik return ret; 27853964b9eSJeff Garzik } 27953964b9eSJeff Garzik 28053964b9eSJeff Garzik static void __exit sha3_generic_mod_fini(void) 28153964b9eSJeff Garzik { 28253964b9eSJeff Garzik crypto_unregister_shash(&sha3_224); 28353964b9eSJeff Garzik crypto_unregister_shash(&sha3_256); 28453964b9eSJeff Garzik crypto_unregister_shash(&sha3_384); 28553964b9eSJeff Garzik crypto_unregister_shash(&sha3_512); 28653964b9eSJeff Garzik } 28753964b9eSJeff Garzik 28853964b9eSJeff Garzik module_init(sha3_generic_mod_init); 28953964b9eSJeff Garzik module_exit(sha3_generic_mod_fini); 29053964b9eSJeff Garzik 29153964b9eSJeff Garzik MODULE_LICENSE("GPL"); 29253964b9eSJeff Garzik MODULE_DESCRIPTION("SHA-3 Secure Hash Algorithm"); 29353964b9eSJeff Garzik 29453964b9eSJeff Garzik MODULE_ALIAS_CRYPTO("sha3-224"); 29553964b9eSJeff Garzik MODULE_ALIAS_CRYPTO("sha3-224-generic"); 29653964b9eSJeff Garzik MODULE_ALIAS_CRYPTO("sha3-256"); 29753964b9eSJeff Garzik MODULE_ALIAS_CRYPTO("sha3-256-generic"); 29853964b9eSJeff Garzik MODULE_ALIAS_CRYPTO("sha3-384"); 29953964b9eSJeff Garzik MODULE_ALIAS_CRYPTO("sha3-384-generic"); 30053964b9eSJeff Garzik MODULE_ALIAS_CRYPTO("sha3-512"); 30153964b9eSJeff Garzik MODULE_ALIAS_CRYPTO("sha3-512-generic"); 302