• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
3  *
4  *  Licensed under the Apache License, Version 2.0 (the License); you may
5  *  not use this file except in compliance with the License.
6  *
7  *  http://www.apache.org/licenses/LICENSE-2.0
8  */
9 
10 
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <gmssl/sha2.h>
15 #include <gmssl/endian.h>
16 
17 
18 static void sha512_compress_blocks(uint64_t state[8],
19 	const unsigned char *data, size_t blocks);
20 
sha512_init(SHA512_CTX * ctx)21 void sha512_init(SHA512_CTX *ctx)
22 {
23 	memset(ctx, 0, sizeof(*ctx));
24 	ctx->state[0] = 0x6a09e667f3bcc908;
25 	ctx->state[1] = 0xbb67ae8584caa73b;
26 	ctx->state[2] = 0x3c6ef372fe94f82b;
27 	ctx->state[3] = 0xa54ff53a5f1d36f1;
28 	ctx->state[4] = 0x510e527fade682d1;
29 	ctx->state[5] = 0x9b05688c2b3e6c1f;
30 	ctx->state[6] = 0x1f83d9abfb41bd6b;
31 	ctx->state[7] = 0x5be0cd19137e2179;
32 }
33 
sha512_update(SHA512_CTX * ctx,const unsigned char * data,size_t datalen)34 void sha512_update(SHA512_CTX *ctx, const unsigned char *data, size_t datalen)
35 {
36 	size_t blocks;
37 
38 	if (ctx->num) {
39 		unsigned int left = SHA512_BLOCK_SIZE - ctx->num;
40 		if (datalen < left) {
41 			memcpy(ctx->block + ctx->num, data, datalen);
42 			ctx->num += datalen;
43 			return;
44 		} else {
45 			memcpy(ctx->block + ctx->num, data, left);
46 			sha512_compress_blocks(ctx->state, ctx->block, 1);
47 			ctx->nblocks++;
48 			data += left;
49 			datalen -= left;
50 		}
51 	}
52 
53 	blocks = datalen / SHA512_BLOCK_SIZE;
54 	sha512_compress_blocks(ctx->state, data, blocks);
55 	ctx->nblocks += blocks;
56 	data += SHA512_BLOCK_SIZE * blocks;
57 	datalen -= SHA512_BLOCK_SIZE * blocks;
58 
59 	ctx->num = datalen;
60 	if (datalen) {
61 		memcpy(ctx->block, data, datalen);
62 	}
63 }
64 
sha512_finish(SHA512_CTX * ctx,unsigned char dgst[SHA512_DIGEST_SIZE])65 void sha512_finish(SHA512_CTX *ctx, unsigned char dgst[SHA512_DIGEST_SIZE])
66 {
67 	int i;
68 
69 	ctx->block[ctx->num] = 0x80;
70 
71 	if (ctx->num + 17 <= SHA512_BLOCK_SIZE) {
72 		memset(ctx->block + ctx->num + 1, 0, SHA512_BLOCK_SIZE - ctx->num - 17);
73 	} else {
74 		memset(ctx->block + ctx->num + 1, 0, SHA512_BLOCK_SIZE - ctx->num - 1);
75 		sha512_compress_blocks(ctx->state, ctx->block, 1);
76 		memset(ctx->block, 0, SHA512_BLOCK_SIZE - 16);
77 	}
78 	PUTU64(ctx->block + 112, ctx->nblocks >> 54);
79 	PUTU64(ctx->block + 120, (ctx->nblocks << 10) + (ctx->num << 3));
80 
81 	sha512_compress_blocks(ctx->state, ctx->block, 1);
82 	for (i = 0; i < 8; i++) {
83 		PUTU64(dgst, ctx->state[i]);
84 		dgst += sizeof(uint64_t);
85 	}
86 	memset(ctx, 0, sizeof(SHA512_CTX));
87 }
88 
89 #define Ch(X, Y, Z)	(((X) & (Y)) ^ ((~(X)) & (Z)))
90 #define Maj(X, Y, Z)	(((X) & (Y)) ^ ((X) & (Z)) ^ ((Y) & (Z)))
91 #define Sigma0(X)	(ROR64((X), 28) ^ ROR64((X), 34) ^ ROR64((X), 39))
92 #define Sigma1(X)	(ROR64((X), 14) ^ ROR64((X), 18) ^ ROR64((X), 41))
93 #define sigma0(X)	(ROR64((X),  1) ^ ROR64((X),  8) ^ ((X) >> 7))
94 #define sigma1(X)	(ROR64((X), 19) ^ ROR64((X), 61) ^ ((X) >> 6))
95 
96 static const uint64_t K[80] = {
97 	0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,
98 	0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118,
99 	0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
100 	0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694,
101 	0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
102 	0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
103 	0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4,
104 	0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70,
105 	0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
106 	0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,
107 	0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30,
108 	0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
109 	0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8,
110 	0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3,
111 	0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
112 	0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b,
113 	0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178,
114 	0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
115 	0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,
116 	0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817,
117 };
118 
sha512_compress_blocks(uint64_t state[8],const unsigned char * data,size_t blocks)119 static void sha512_compress_blocks(uint64_t state[8],
120 	const unsigned char *data, size_t blocks)
121 {
122 	uint64_t A;
123 	uint64_t B;
124 	uint64_t C;
125 	uint64_t D;
126 	uint64_t E;
127 	uint64_t F;
128 	uint64_t G;
129 	uint64_t H;
130 	uint64_t W[80];
131 	uint64_t T1, T2;
132 	int i;
133 
134 	while (blocks--) {
135 
136 		A = state[0];
137 		B = state[1];
138 		C = state[2];
139 		D = state[3];
140 		E = state[4];
141 		F = state[5];
142 		G = state[6];
143 		H = state[7];
144 
145 		for (i = 0; i < 16; i++) {
146 			W[i] = GETU64(data);
147 			data += sizeof(uint64_t);
148 		}
149 		for (; i < 80; i++) {
150 			W[i] = sigma1(W[i-2]) + W[i-7] + sigma0(W[i-15]) + W[i-16];
151 		}
152 
153 		for (i = 0; i < 80; i++) {
154 			T1 = H + Sigma1(E) + Ch(E, F, G) + K[i] + W[i];
155 			T2 = Sigma0(A) + Maj(A, B, C);
156 			H = G;
157 			G = F;
158 			F = E;
159 			E = D + T1;
160 			D = C;
161 			C = B;
162 			B = A;
163 			A = T1 + T2;
164 		}
165 
166 		state[0] += A;
167 		state[1] += B;
168 		state[2] += C;
169 		state[3] += D;
170 		state[4] += E;
171 		state[5] += F;
172 		state[6] += G;
173 		state[7] += H;
174 	}
175 }
176 
sha512_compress(uint64_t state[8],const unsigned char block[64])177 void sha512_compress(uint64_t state[8], const unsigned char block[64])
178 {
179 	sha512_compress_blocks(state, block, 1);
180 }
181 
sha512_digest(const unsigned char * data,size_t datalen,unsigned char dgst[SHA512_DIGEST_SIZE])182 void sha512_digest(const unsigned char *data, size_t datalen,
183 	unsigned char dgst[SHA512_DIGEST_SIZE])
184 {
185 	SHA512_CTX ctx;
186 	sha512_init(&ctx);
187 	sha512_update(&ctx, data, datalen);
188 	sha512_finish(&ctx, dgst);
189 }
190 
191 
sha384_init(SHA384_CTX * ctx)192 void sha384_init(SHA384_CTX *ctx)
193 {
194 	memset(ctx, 0, sizeof(*ctx));
195 	ctx->state[0] = 0xcbbb9d5dc1059ed8;
196 	ctx->state[1] = 0x629a292a367cd507;
197 	ctx->state[2] = 0x9159015a3070dd17;
198 	ctx->state[3] = 0x152fecd8f70e5939;
199 	ctx->state[4] = 0x67332667ffc00b31;
200 	ctx->state[5] = 0x8eb44a8768581511;
201 	ctx->state[6] = 0xdb0c2e0d64f98fa7;
202 	ctx->state[7] = 0x47b5481dbefa4fa4;
203 }
204 
sha384_update(SHA384_CTX * ctx,const unsigned char * data,size_t datalen)205 void sha384_update(SHA384_CTX *ctx, const unsigned char *data, size_t datalen)
206 {
207 	sha512_update((SHA512_CTX *)ctx, data, datalen);
208 }
209 
sha384_finish(SHA384_CTX * ctx,unsigned char dgst[SHA384_DIGEST_SIZE])210 void sha384_finish(SHA384_CTX *ctx, unsigned char dgst[SHA384_DIGEST_SIZE])
211 {
212 	unsigned char buf[SHA512_DIGEST_SIZE];
213 	sha512_finish((SHA512_CTX *)ctx, buf);
214 	memcpy(dgst, buf, SHA384_DIGEST_SIZE);
215 	memset(buf, 0, sizeof(buf));
216 }
217 
sha384_compress(uint64_t state[8],const unsigned char block[64])218 void sha384_compress(uint64_t state[8], const unsigned char block[64])
219 {
220 	sha512_compress_blocks(state, block, 1);
221 }
222 
sha384_digest(const unsigned char * data,size_t datalen,unsigned char dgst[SHA384_DIGEST_SIZE])223 void sha384_digest(const unsigned char *data, size_t datalen,
224 	unsigned char dgst[SHA384_DIGEST_SIZE])
225 {
226 	SHA384_CTX ctx;
227 	sha384_init(&ctx);
228 	sha384_update(&ctx, data, datalen);
229 	sha384_finish(&ctx, dgst);
230 }
231 
232