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