1*d2912cb1SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */ 2c4d5b9ffSArd Biesheuvel /* 3c4d5b9ffSArd Biesheuvel * sha1_base.h - core logic for SHA-1 implementations 4c4d5b9ffSArd Biesheuvel * 5c4d5b9ffSArd Biesheuvel * Copyright (C) 2015 Linaro Ltd <ard.biesheuvel@linaro.org> 6c4d5b9ffSArd Biesheuvel */ 7c4d5b9ffSArd Biesheuvel 8c4d5b9ffSArd Biesheuvel #include <crypto/internal/hash.h> 9c4d5b9ffSArd Biesheuvel #include <crypto/sha.h> 10c4d5b9ffSArd Biesheuvel #include <linux/crypto.h> 11c4d5b9ffSArd Biesheuvel #include <linux/module.h> 12c4d5b9ffSArd Biesheuvel 13c4d5b9ffSArd Biesheuvel #include <asm/unaligned.h> 14c4d5b9ffSArd Biesheuvel 15c4d5b9ffSArd Biesheuvel typedef void (sha1_block_fn)(struct sha1_state *sst, u8 const *src, int blocks); 16c4d5b9ffSArd Biesheuvel 17c4d5b9ffSArd Biesheuvel static inline int sha1_base_init(struct shash_desc *desc) 18c4d5b9ffSArd Biesheuvel { 19c4d5b9ffSArd Biesheuvel struct sha1_state *sctx = shash_desc_ctx(desc); 20c4d5b9ffSArd Biesheuvel 21c4d5b9ffSArd Biesheuvel sctx->state[0] = SHA1_H0; 22c4d5b9ffSArd Biesheuvel sctx->state[1] = SHA1_H1; 23c4d5b9ffSArd Biesheuvel sctx->state[2] = SHA1_H2; 24c4d5b9ffSArd Biesheuvel sctx->state[3] = SHA1_H3; 25c4d5b9ffSArd Biesheuvel sctx->state[4] = SHA1_H4; 26c4d5b9ffSArd Biesheuvel sctx->count = 0; 27c4d5b9ffSArd Biesheuvel 28c4d5b9ffSArd Biesheuvel return 0; 29c4d5b9ffSArd Biesheuvel } 30c4d5b9ffSArd Biesheuvel 31c4d5b9ffSArd Biesheuvel static inline int sha1_base_do_update(struct shash_desc *desc, 32c4d5b9ffSArd Biesheuvel const u8 *data, 33c4d5b9ffSArd Biesheuvel unsigned int len, 34c4d5b9ffSArd Biesheuvel sha1_block_fn *block_fn) 35c4d5b9ffSArd Biesheuvel { 36c4d5b9ffSArd Biesheuvel struct sha1_state *sctx = shash_desc_ctx(desc); 37c4d5b9ffSArd Biesheuvel unsigned int partial = sctx->count % SHA1_BLOCK_SIZE; 38c4d5b9ffSArd Biesheuvel 39c4d5b9ffSArd Biesheuvel sctx->count += len; 40c4d5b9ffSArd Biesheuvel 41c4d5b9ffSArd Biesheuvel if (unlikely((partial + len) >= SHA1_BLOCK_SIZE)) { 42c4d5b9ffSArd Biesheuvel int blocks; 43c4d5b9ffSArd Biesheuvel 44c4d5b9ffSArd Biesheuvel if (partial) { 45c4d5b9ffSArd Biesheuvel int p = SHA1_BLOCK_SIZE - partial; 46c4d5b9ffSArd Biesheuvel 47c4d5b9ffSArd Biesheuvel memcpy(sctx->buffer + partial, data, p); 48c4d5b9ffSArd Biesheuvel data += p; 49c4d5b9ffSArd Biesheuvel len -= p; 50c4d5b9ffSArd Biesheuvel 51c4d5b9ffSArd Biesheuvel block_fn(sctx, sctx->buffer, 1); 52c4d5b9ffSArd Biesheuvel } 53c4d5b9ffSArd Biesheuvel 54c4d5b9ffSArd Biesheuvel blocks = len / SHA1_BLOCK_SIZE; 55c4d5b9ffSArd Biesheuvel len %= SHA1_BLOCK_SIZE; 56c4d5b9ffSArd Biesheuvel 57c4d5b9ffSArd Biesheuvel if (blocks) { 58c4d5b9ffSArd Biesheuvel block_fn(sctx, data, blocks); 59c4d5b9ffSArd Biesheuvel data += blocks * SHA1_BLOCK_SIZE; 60c4d5b9ffSArd Biesheuvel } 61c4d5b9ffSArd Biesheuvel partial = 0; 62c4d5b9ffSArd Biesheuvel } 63c4d5b9ffSArd Biesheuvel if (len) 64c4d5b9ffSArd Biesheuvel memcpy(sctx->buffer + partial, data, len); 65c4d5b9ffSArd Biesheuvel 66c4d5b9ffSArd Biesheuvel return 0; 67c4d5b9ffSArd Biesheuvel } 68c4d5b9ffSArd Biesheuvel 69c4d5b9ffSArd Biesheuvel static inline int sha1_base_do_finalize(struct shash_desc *desc, 70c4d5b9ffSArd Biesheuvel sha1_block_fn *block_fn) 71c4d5b9ffSArd Biesheuvel { 72c4d5b9ffSArd Biesheuvel const int bit_offset = SHA1_BLOCK_SIZE - sizeof(__be64); 73c4d5b9ffSArd Biesheuvel struct sha1_state *sctx = shash_desc_ctx(desc); 74c4d5b9ffSArd Biesheuvel __be64 *bits = (__be64 *)(sctx->buffer + bit_offset); 75c4d5b9ffSArd Biesheuvel unsigned int partial = sctx->count % SHA1_BLOCK_SIZE; 76c4d5b9ffSArd Biesheuvel 77c4d5b9ffSArd Biesheuvel sctx->buffer[partial++] = 0x80; 78c4d5b9ffSArd Biesheuvel if (partial > bit_offset) { 79c4d5b9ffSArd Biesheuvel memset(sctx->buffer + partial, 0x0, SHA1_BLOCK_SIZE - partial); 80c4d5b9ffSArd Biesheuvel partial = 0; 81c4d5b9ffSArd Biesheuvel 82c4d5b9ffSArd Biesheuvel block_fn(sctx, sctx->buffer, 1); 83c4d5b9ffSArd Biesheuvel } 84c4d5b9ffSArd Biesheuvel 85c4d5b9ffSArd Biesheuvel memset(sctx->buffer + partial, 0x0, bit_offset - partial); 86c4d5b9ffSArd Biesheuvel *bits = cpu_to_be64(sctx->count << 3); 87c4d5b9ffSArd Biesheuvel block_fn(sctx, sctx->buffer, 1); 88c4d5b9ffSArd Biesheuvel 89c4d5b9ffSArd Biesheuvel return 0; 90c4d5b9ffSArd Biesheuvel } 91c4d5b9ffSArd Biesheuvel 92c4d5b9ffSArd Biesheuvel static inline int sha1_base_finish(struct shash_desc *desc, u8 *out) 93c4d5b9ffSArd Biesheuvel { 94c4d5b9ffSArd Biesheuvel struct sha1_state *sctx = shash_desc_ctx(desc); 95c4d5b9ffSArd Biesheuvel __be32 *digest = (__be32 *)out; 96c4d5b9ffSArd Biesheuvel int i; 97c4d5b9ffSArd Biesheuvel 98c4d5b9ffSArd Biesheuvel for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(__be32); i++) 99c4d5b9ffSArd Biesheuvel put_unaligned_be32(sctx->state[i], digest++); 100c4d5b9ffSArd Biesheuvel 101c4d5b9ffSArd Biesheuvel *sctx = (struct sha1_state){}; 102c4d5b9ffSArd Biesheuvel return 0; 103c4d5b9ffSArd Biesheuvel } 104