xref: /linux/lib/crypto/sha256.c (revision 4c855d5069ee2edbcf62fafc7f1a5d4cfea1bce1)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * SHA-256, as specified in
4  * http://csrc.nist.gov/groups/STM/cavp/documents/shs/sha256-384-512.pdf
5  *
6  * SHA-256 code by Jean-Luc Cooke <jlcooke@certainkey.com>.
7  *
8  * Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com>
9  * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
10  * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
11  * Copyright (c) 2014 Red Hat Inc.
12  */
13 
14 #include <crypto/internal/blockhash.h>
15 #include <crypto/internal/sha2.h>
16 #include <linux/export.h>
17 #include <linux/kernel.h>
18 #include <linux/module.h>
19 #include <linux/string.h>
20 
21 static const struct sha256_block_state sha224_iv = {
22 	.h = {
23 		SHA224_H0, SHA224_H1, SHA224_H2, SHA224_H3,
24 		SHA224_H4, SHA224_H5, SHA224_H6, SHA224_H7,
25 	},
26 };
27 
28 static const struct sha256_block_state sha256_iv = {
29 	.h = {
30 		SHA256_H0, SHA256_H1, SHA256_H2, SHA256_H3,
31 		SHA256_H4, SHA256_H5, SHA256_H6, SHA256_H7,
32 	},
33 };
34 
35 /*
36  * If __DISABLE_EXPORTS is defined, then this file is being compiled for a
37  * pre-boot environment.  In that case, ignore the kconfig options, pull the
38  * generic code into the same translation unit, and use that only.
39  */
40 #ifdef __DISABLE_EXPORTS
41 #include "sha256-generic.c"
42 #endif
43 
44 static inline bool sha256_purgatory(void)
45 {
46 	return __is_defined(__DISABLE_EXPORTS);
47 }
48 
49 static inline void sha256_blocks(struct sha256_block_state *state,
50 				 const u8 *data, size_t nblocks)
51 {
52 	sha256_choose_blocks(state->h, data, nblocks, sha256_purgatory(), false);
53 }
54 
55 static void __sha256_init(struct __sha256_ctx *ctx,
56 			  const struct sha256_block_state *iv,
57 			  u64 initial_bytecount)
58 {
59 	ctx->state = *iv;
60 	ctx->bytecount = initial_bytecount;
61 }
62 
63 void sha224_init(struct sha224_ctx *ctx)
64 {
65 	__sha256_init(&ctx->ctx, &sha224_iv, 0);
66 }
67 EXPORT_SYMBOL_GPL(sha224_init);
68 
69 void sha256_init(struct sha256_ctx *ctx)
70 {
71 	__sha256_init(&ctx->ctx, &sha256_iv, 0);
72 }
73 EXPORT_SYMBOL_GPL(sha256_init);
74 
75 void __sha256_update(struct __sha256_ctx *ctx, const u8 *data, size_t len)
76 {
77 	size_t partial = ctx->bytecount % SHA256_BLOCK_SIZE;
78 
79 	ctx->bytecount += len;
80 	BLOCK_HASH_UPDATE_BLOCKS(sha256_blocks, &ctx->state, data, len,
81 				 SHA256_BLOCK_SIZE, ctx->buf, partial);
82 }
83 EXPORT_SYMBOL(__sha256_update);
84 
85 static void __sha256_final(struct __sha256_ctx *ctx,
86 			   u8 *out, size_t digest_size)
87 {
88 	u64 bitcount = ctx->bytecount << 3;
89 	size_t partial = ctx->bytecount % SHA256_BLOCK_SIZE;
90 
91 	ctx->buf[partial++] = 0x80;
92 	if (partial > SHA256_BLOCK_SIZE - 8) {
93 		memset(&ctx->buf[partial], 0, SHA256_BLOCK_SIZE - partial);
94 		sha256_blocks(&ctx->state, ctx->buf, 1);
95 		partial = 0;
96 	}
97 	memset(&ctx->buf[partial], 0, SHA256_BLOCK_SIZE - 8 - partial);
98 	*(__be64 *)&ctx->buf[SHA256_BLOCK_SIZE - 8] = cpu_to_be64(bitcount);
99 	sha256_blocks(&ctx->state, ctx->buf, 1);
100 
101 	for (size_t i = 0; i < digest_size; i += 4)
102 		put_unaligned_be32(ctx->state.h[i / 4], out + i);
103 }
104 
105 void sha224_final(struct sha224_ctx *ctx, u8 out[SHA224_DIGEST_SIZE])
106 {
107 	__sha256_final(&ctx->ctx, out, SHA224_DIGEST_SIZE);
108 	memzero_explicit(ctx, sizeof(*ctx));
109 }
110 EXPORT_SYMBOL(sha224_final);
111 
112 void sha256_final(struct sha256_ctx *ctx, u8 out[SHA256_DIGEST_SIZE])
113 {
114 	__sha256_final(&ctx->ctx, out, SHA256_DIGEST_SIZE);
115 	memzero_explicit(ctx, sizeof(*ctx));
116 }
117 EXPORT_SYMBOL(sha256_final);
118 
119 void sha224(const u8 *data, size_t len, u8 out[SHA224_DIGEST_SIZE])
120 {
121 	struct sha224_ctx ctx;
122 
123 	sha224_init(&ctx);
124 	sha224_update(&ctx, data, len);
125 	sha224_final(&ctx, out);
126 }
127 EXPORT_SYMBOL(sha224);
128 
129 void sha256(const u8 *data, size_t len, u8 out[SHA256_DIGEST_SIZE])
130 {
131 	struct sha256_ctx ctx;
132 
133 	sha256_init(&ctx);
134 	sha256_update(&ctx, data, len);
135 	sha256_final(&ctx, out);
136 }
137 EXPORT_SYMBOL(sha256);
138 
139 MODULE_DESCRIPTION("SHA-256 Algorithm");
140 MODULE_LICENSE("GPL");
141