xref: /openbmc/linux/include/crypto/sha256_base.h (revision 2612e3bbc0386368a850140a6c9b990cd496a5ec)
1d2912cb1SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
211b8d5efSArd Biesheuvel /*
311b8d5efSArd Biesheuvel  * sha256_base.h - core logic for SHA-256 implementations
411b8d5efSArd Biesheuvel  *
511b8d5efSArd Biesheuvel  * Copyright (C) 2015 Linaro Ltd <ard.biesheuvel@linaro.org>
611b8d5efSArd Biesheuvel  */
711b8d5efSArd Biesheuvel 
868289c63SMasahiro Yamada #ifndef _CRYPTO_SHA256_BASE_H
968289c63SMasahiro Yamada #define _CRYPTO_SHA256_BASE_H
1068289c63SMasahiro Yamada 
11*6c19f3bfSHerbert Xu #include <asm/byteorder.h>
12*6c19f3bfSHerbert Xu #include <asm/unaligned.h>
1311b8d5efSArd Biesheuvel #include <crypto/internal/hash.h>
14a24d22b2SEric Biggers #include <crypto/sha2.h>
15458c0480SArvind Sankar #include <linux/string.h>
16*6c19f3bfSHerbert Xu #include <linux/types.h>
1711b8d5efSArd Biesheuvel 
1811b8d5efSArd Biesheuvel typedef void (sha256_block_fn)(struct sha256_state *sst, u8 const *src,
1911b8d5efSArd Biesheuvel 			       int blocks);
2011b8d5efSArd Biesheuvel 
sha224_base_init(struct shash_desc * desc)2111b8d5efSArd Biesheuvel static inline int sha224_base_init(struct shash_desc *desc)
2211b8d5efSArd Biesheuvel {
2311b8d5efSArd Biesheuvel 	struct sha256_state *sctx = shash_desc_ctx(desc);
2411b8d5efSArd Biesheuvel 
2513855fd8SEric Biggers 	sha224_init(sctx);
2613855fd8SEric Biggers 	return 0;
2711b8d5efSArd Biesheuvel }
2811b8d5efSArd Biesheuvel 
sha256_base_init(struct shash_desc * desc)2911b8d5efSArd Biesheuvel static inline int sha256_base_init(struct shash_desc *desc)
3011b8d5efSArd Biesheuvel {
3111b8d5efSArd Biesheuvel 	struct sha256_state *sctx = shash_desc_ctx(desc);
3211b8d5efSArd Biesheuvel 
3313855fd8SEric Biggers 	sha256_init(sctx);
3413855fd8SEric Biggers 	return 0;
3511b8d5efSArd Biesheuvel }
3611b8d5efSArd Biesheuvel 
lib_sha256_base_do_update(struct sha256_state * sctx,const u8 * data,unsigned int len,sha256_block_fn * block_fn)37*6c19f3bfSHerbert Xu static inline int lib_sha256_base_do_update(struct sha256_state *sctx,
3811b8d5efSArd Biesheuvel 					    const u8 *data,
3911b8d5efSArd Biesheuvel 					    unsigned int len,
4011b8d5efSArd Biesheuvel 					    sha256_block_fn *block_fn)
4111b8d5efSArd Biesheuvel {
4211b8d5efSArd Biesheuvel 	unsigned int partial = sctx->count % SHA256_BLOCK_SIZE;
4311b8d5efSArd Biesheuvel 
4411b8d5efSArd Biesheuvel 	sctx->count += len;
4511b8d5efSArd Biesheuvel 
4611b8d5efSArd Biesheuvel 	if (unlikely((partial + len) >= SHA256_BLOCK_SIZE)) {
4711b8d5efSArd Biesheuvel 		int blocks;
4811b8d5efSArd Biesheuvel 
4911b8d5efSArd Biesheuvel 		if (partial) {
5011b8d5efSArd Biesheuvel 			int p = SHA256_BLOCK_SIZE - partial;
5111b8d5efSArd Biesheuvel 
5211b8d5efSArd Biesheuvel 			memcpy(sctx->buf + partial, data, p);
5311b8d5efSArd Biesheuvel 			data += p;
5411b8d5efSArd Biesheuvel 			len -= p;
5511b8d5efSArd Biesheuvel 
5611b8d5efSArd Biesheuvel 			block_fn(sctx, sctx->buf, 1);
5711b8d5efSArd Biesheuvel 		}
5811b8d5efSArd Biesheuvel 
5911b8d5efSArd Biesheuvel 		blocks = len / SHA256_BLOCK_SIZE;
6011b8d5efSArd Biesheuvel 		len %= SHA256_BLOCK_SIZE;
6111b8d5efSArd Biesheuvel 
6211b8d5efSArd Biesheuvel 		if (blocks) {
6311b8d5efSArd Biesheuvel 			block_fn(sctx, data, blocks);
6411b8d5efSArd Biesheuvel 			data += blocks * SHA256_BLOCK_SIZE;
6511b8d5efSArd Biesheuvel 		}
6611b8d5efSArd Biesheuvel 		partial = 0;
6711b8d5efSArd Biesheuvel 	}
6811b8d5efSArd Biesheuvel 	if (len)
6911b8d5efSArd Biesheuvel 		memcpy(sctx->buf + partial, data, len);
7011b8d5efSArd Biesheuvel 
7111b8d5efSArd Biesheuvel 	return 0;
7211b8d5efSArd Biesheuvel }
7311b8d5efSArd Biesheuvel 
sha256_base_do_update(struct shash_desc * desc,const u8 * data,unsigned int len,sha256_block_fn * block_fn)74*6c19f3bfSHerbert Xu static inline int sha256_base_do_update(struct shash_desc *desc,
75*6c19f3bfSHerbert Xu 					const u8 *data,
76*6c19f3bfSHerbert Xu 					unsigned int len,
77*6c19f3bfSHerbert Xu 					sha256_block_fn *block_fn)
78*6c19f3bfSHerbert Xu {
79*6c19f3bfSHerbert Xu 	struct sha256_state *sctx = shash_desc_ctx(desc);
80*6c19f3bfSHerbert Xu 
81*6c19f3bfSHerbert Xu 	return lib_sha256_base_do_update(sctx, data, len, block_fn);
82*6c19f3bfSHerbert Xu }
83*6c19f3bfSHerbert Xu 
lib_sha256_base_do_finalize(struct sha256_state * sctx,sha256_block_fn * block_fn)84*6c19f3bfSHerbert Xu static inline int lib_sha256_base_do_finalize(struct sha256_state *sctx,
8511b8d5efSArd Biesheuvel 					      sha256_block_fn *block_fn)
8611b8d5efSArd Biesheuvel {
8711b8d5efSArd Biesheuvel 	const int bit_offset = SHA256_BLOCK_SIZE - sizeof(__be64);
8811b8d5efSArd Biesheuvel 	__be64 *bits = (__be64 *)(sctx->buf + bit_offset);
8911b8d5efSArd Biesheuvel 	unsigned int partial = sctx->count % SHA256_BLOCK_SIZE;
9011b8d5efSArd Biesheuvel 
9111b8d5efSArd Biesheuvel 	sctx->buf[partial++] = 0x80;
9211b8d5efSArd Biesheuvel 	if (partial > bit_offset) {
9311b8d5efSArd Biesheuvel 		memset(sctx->buf + partial, 0x0, SHA256_BLOCK_SIZE - partial);
9411b8d5efSArd Biesheuvel 		partial = 0;
9511b8d5efSArd Biesheuvel 
9611b8d5efSArd Biesheuvel 		block_fn(sctx, sctx->buf, 1);
9711b8d5efSArd Biesheuvel 	}
9811b8d5efSArd Biesheuvel 
9911b8d5efSArd Biesheuvel 	memset(sctx->buf + partial, 0x0, bit_offset - partial);
10011b8d5efSArd Biesheuvel 	*bits = cpu_to_be64(sctx->count << 3);
10111b8d5efSArd Biesheuvel 	block_fn(sctx, sctx->buf, 1);
10211b8d5efSArd Biesheuvel 
10311b8d5efSArd Biesheuvel 	return 0;
10411b8d5efSArd Biesheuvel }
10511b8d5efSArd Biesheuvel 
sha256_base_do_finalize(struct shash_desc * desc,sha256_block_fn * block_fn)106*6c19f3bfSHerbert Xu static inline int sha256_base_do_finalize(struct shash_desc *desc,
107*6c19f3bfSHerbert Xu 					  sha256_block_fn *block_fn)
10811b8d5efSArd Biesheuvel {
10911b8d5efSArd Biesheuvel 	struct sha256_state *sctx = shash_desc_ctx(desc);
110*6c19f3bfSHerbert Xu 
111*6c19f3bfSHerbert Xu 	return lib_sha256_base_do_finalize(sctx, block_fn);
112*6c19f3bfSHerbert Xu }
113*6c19f3bfSHerbert Xu 
lib_sha256_base_finish(struct sha256_state * sctx,u8 * out,unsigned int digest_size)114*6c19f3bfSHerbert Xu static inline int lib_sha256_base_finish(struct sha256_state *sctx, u8 *out,
115*6c19f3bfSHerbert Xu 					 unsigned int digest_size)
116*6c19f3bfSHerbert Xu {
11711b8d5efSArd Biesheuvel 	__be32 *digest = (__be32 *)out;
11811b8d5efSArd Biesheuvel 	int i;
11911b8d5efSArd Biesheuvel 
12011b8d5efSArd Biesheuvel 	for (i = 0; digest_size > 0; i++, digest_size -= sizeof(__be32))
12111b8d5efSArd Biesheuvel 		put_unaligned_be32(sctx->state[i], digest++);
12211b8d5efSArd Biesheuvel 
123458c0480SArvind Sankar 	memzero_explicit(sctx, sizeof(*sctx));
12411b8d5efSArd Biesheuvel 	return 0;
12511b8d5efSArd Biesheuvel }
12668289c63SMasahiro Yamada 
sha256_base_finish(struct shash_desc * desc,u8 * out)127*6c19f3bfSHerbert Xu static inline int sha256_base_finish(struct shash_desc *desc, u8 *out)
128*6c19f3bfSHerbert Xu {
129*6c19f3bfSHerbert Xu 	unsigned int digest_size = crypto_shash_digestsize(desc->tfm);
130*6c19f3bfSHerbert Xu 	struct sha256_state *sctx = shash_desc_ctx(desc);
131*6c19f3bfSHerbert Xu 
132*6c19f3bfSHerbert Xu 	return lib_sha256_base_finish(sctx, out, digest_size);
133*6c19f3bfSHerbert Xu }
134*6c19f3bfSHerbert Xu 
13568289c63SMasahiro Yamada #endif /* _CRYPTO_SHA256_BASE_H */
136