1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * sha1_base.h - core logic for SHA-1 implementations 4 * 5 * Copyright (C) 2015 Linaro Ltd <ard.biesheuvel@linaro.org> 6 */ 7 8 #ifndef _CRYPTO_SHA1_BASE_H 9 #define _CRYPTO_SHA1_BASE_H 10 11 #include <crypto/internal/hash.h> 12 #include <crypto/sha1.h> 13 #include <linux/math.h> 14 #include <linux/string.h> 15 #include <linux/types.h> 16 #include <linux/unaligned.h> 17 18 typedef void (sha1_block_fn)(struct sha1_state *sst, u8 const *src, int blocks); 19 20 static inline int sha1_base_init(struct shash_desc *desc) 21 { 22 struct sha1_state *sctx = shash_desc_ctx(desc); 23 24 sctx->state[0] = SHA1_H0; 25 sctx->state[1] = SHA1_H1; 26 sctx->state[2] = SHA1_H2; 27 sctx->state[3] = SHA1_H3; 28 sctx->state[4] = SHA1_H4; 29 sctx->count = 0; 30 31 return 0; 32 } 33 34 static inline int sha1_base_do_update_blocks(struct shash_desc *desc, 35 const u8 *data, 36 unsigned int len, 37 sha1_block_fn *block_fn) 38 { 39 unsigned int remain = len - round_down(len, SHA1_BLOCK_SIZE); 40 struct sha1_state *sctx = shash_desc_ctx(desc); 41 42 sctx->count += len - remain; 43 block_fn(sctx, data, len / SHA1_BLOCK_SIZE); 44 return remain; 45 } 46 47 static inline int sha1_base_do_finup(struct shash_desc *desc, 48 const u8 *src, unsigned int len, 49 sha1_block_fn *block_fn) 50 { 51 unsigned int bit_offset = SHA1_BLOCK_SIZE / 8 - 1; 52 struct sha1_state *sctx = shash_desc_ctx(desc); 53 union { 54 __be64 b64[SHA1_BLOCK_SIZE / 4]; 55 u8 u8[SHA1_BLOCK_SIZE * 2]; 56 } block = {}; 57 58 if (len >= bit_offset * 8) 59 bit_offset += SHA1_BLOCK_SIZE / 8; 60 memcpy(&block, src, len); 61 block.u8[len] = 0x80; 62 sctx->count += len; 63 block.b64[bit_offset] = cpu_to_be64(sctx->count << 3); 64 block_fn(sctx, block.u8, (bit_offset + 1) * 8 / SHA1_BLOCK_SIZE); 65 memzero_explicit(&block, sizeof(block)); 66 67 return 0; 68 } 69 70 static inline int sha1_base_finish(struct shash_desc *desc, u8 *out) 71 { 72 struct sha1_state *sctx = shash_desc_ctx(desc); 73 __be32 *digest = (__be32 *)out; 74 int i; 75 76 for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(__be32); i++) 77 put_unaligned_be32(sctx->state[i], digest++); 78 79 return 0; 80 } 81 82 #endif /* _CRYPTO_SHA1_BASE_H */ 83