1 | /* SHA512 module */ |
2 | |
3 | /* This module provides an interface to NIST's SHA-512 and SHA-384 Algorithms */ |
4 | |
5 | /* See below for information about the original code this module was |
6 | based upon. Additional work performed by: |
7 | |
8 | Andrew Kuchling ([email protected]) |
9 | Greg Stein ([email protected]) |
10 | Trevor Perrin ([email protected]) |
11 | |
12 | Copyright (C) 2005-2007 Gregory P. Smith ([email protected]) |
13 | Licensed to PSF under a Contributor Agreement. |
14 | |
15 | */ |
16 | |
17 | /* SHA objects */ |
18 | |
19 | #include "Python.h" |
20 | #include "pycore_bitutils.h" // _Py_bswap64() |
21 | #include "structmember.h" // PyMemberDef |
22 | #include "hashlib.h" |
23 | #include "pystrhex.h" |
24 | |
25 | /*[clinic input] |
26 | module _sha512 |
27 | class SHA512Type "SHAobject *" "&PyType_Type" |
28 | [clinic start generated code]*/ |
29 | /*[clinic end generated code: output=da39a3ee5e6b4b0d input=81a3ccde92bcfe8d]*/ |
30 | |
31 | /* Some useful types */ |
32 | |
33 | typedef unsigned char SHA_BYTE; |
34 | typedef uint32_t SHA_INT32; /* 32-bit integer */ |
35 | typedef uint64_t SHA_INT64; /* 64-bit integer */ |
36 | |
37 | /* The SHA block size and message digest sizes, in bytes */ |
38 | |
39 | #define SHA_BLOCKSIZE 128 |
40 | #define SHA_DIGESTSIZE 64 |
41 | |
42 | /* The structure for storing SHA info */ |
43 | |
44 | typedef struct { |
45 | PyObject_HEAD |
46 | SHA_INT64 digest[8]; /* Message digest */ |
47 | SHA_INT32 count_lo, count_hi; /* 64-bit bit count */ |
48 | SHA_BYTE data[SHA_BLOCKSIZE]; /* SHA data buffer */ |
49 | int local; /* unprocessed amount in data */ |
50 | int digestsize; |
51 | } SHAobject; |
52 | |
53 | #include "clinic/sha512module.c.h" |
54 | |
55 | /* When run on a little-endian CPU we need to perform byte reversal on an |
56 | array of longwords. */ |
57 | |
58 | #if PY_LITTLE_ENDIAN |
59 | static void longReverse(SHA_INT64 *buffer, int byteCount) |
60 | { |
61 | byteCount /= sizeof(*buffer); |
62 | for (; byteCount--; buffer++) { |
63 | *buffer = _Py_bswap64(*buffer); |
64 | } |
65 | } |
66 | #endif |
67 | |
68 | static void SHAcopy(SHAobject *src, SHAobject *dest) |
69 | { |
70 | dest->local = src->local; |
71 | dest->digestsize = src->digestsize; |
72 | dest->count_lo = src->count_lo; |
73 | dest->count_hi = src->count_hi; |
74 | memcpy(dest->digest, src->digest, sizeof(src->digest)); |
75 | memcpy(dest->data, src->data, sizeof(src->data)); |
76 | } |
77 | |
78 | |
79 | /* ------------------------------------------------------------------------ |
80 | * |
81 | * This code for the SHA-512 algorithm was noted as public domain. The |
82 | * original headers are pasted below. |
83 | * |
84 | * Several changes have been made to make it more compatible with the |
85 | * Python environment and desired interface. |
86 | * |
87 | */ |
88 | |
89 | /* LibTomCrypt, modular cryptographic library -- Tom St Denis |
90 | * |
91 | * LibTomCrypt is a library that provides various cryptographic |
92 | * algorithms in a highly modular and flexible manner. |
93 | * |
94 | * The library is free for all purposes without any express |
95 | * guarantee it works. |
96 | * |
97 | * Tom St Denis, [email protected], https://www.libtom.net |
98 | */ |
99 | |
100 | |
101 | /* SHA512 by Tom St Denis */ |
102 | |
103 | /* Various logical functions */ |
104 | #define ROR64(x, y) \ |
105 | ( ((((x) & 0xFFFFFFFFFFFFFFFFULL)>>((unsigned long long)(y) & 63)) | \ |
106 | ((x)<<((unsigned long long)(64-((y) & 63))))) & 0xFFFFFFFFFFFFFFFFULL) |
107 | #define Ch(x,y,z) (z ^ (x & (y ^ z))) |
108 | #define Maj(x,y,z) (((x | y) & z) | (x & y)) |
109 | #define S(x, n) ROR64((x),(n)) |
110 | #define R(x, n) (((x) & 0xFFFFFFFFFFFFFFFFULL) >> ((unsigned long long)n)) |
111 | #define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39)) |
112 | #define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41)) |
113 | #define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7)) |
114 | #define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6)) |
115 | |
116 | |
117 | static void |
118 | sha512_transform(SHAobject *sha_info) |
119 | { |
120 | int i; |
121 | SHA_INT64 S[8], W[80], t0, t1; |
122 | |
123 | memcpy(W, sha_info->data, sizeof(sha_info->data)); |
124 | #if PY_LITTLE_ENDIAN |
125 | longReverse(W, (int)sizeof(sha_info->data)); |
126 | #endif |
127 | |
128 | for (i = 16; i < 80; ++i) { |
129 | W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; |
130 | } |
131 | for (i = 0; i < 8; ++i) { |
132 | S[i] = sha_info->digest[i]; |
133 | } |
134 | |
135 | /* Compress */ |
136 | #define RND(a,b,c,d,e,f,g,h,i,ki) \ |
137 | t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \ |
138 | t1 = Sigma0(a) + Maj(a, b, c); \ |
139 | d += t0; \ |
140 | h = t0 + t1; |
141 | |
142 | RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98d728ae22ULL); |
143 | RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x7137449123ef65cdULL); |
144 | RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcfec4d3b2fULL); |
145 | RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba58189dbbcULL); |
146 | RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25bf348b538ULL); |
147 | RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1b605d019ULL); |
148 | RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4af194f9bULL); |
149 | RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5da6d8118ULL); |
150 | RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98a3030242ULL); |
151 | RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b0145706fbeULL); |
152 | RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be4ee4b28cULL); |
153 | RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3d5ffb4e2ULL); |
154 | RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74f27b896fULL); |
155 | RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe3b1696b1ULL); |
156 | RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a725c71235ULL); |
157 | RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174cf692694ULL); |
158 | RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c19ef14ad2ULL); |
159 | RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786384f25e3ULL); |
160 | RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc68b8cd5b5ULL); |
161 | RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc77ac9c65ULL); |
162 | RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f592b0275ULL); |
163 | RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa6ea6e483ULL); |
164 | RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dcbd41fbd4ULL); |
165 | RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da831153b5ULL); |
166 | RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152ee66dfabULL); |
167 | RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d2db43210ULL); |
168 | RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c898fb213fULL); |
169 | RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7beef0ee4ULL); |
170 | RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf33da88fc2ULL); |
171 | RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147930aa725ULL); |
172 | RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351e003826fULL); |
173 | RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x142929670a0e6e70ULL); |
174 | RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a8546d22ffcULL); |
175 | RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b21385c26c926ULL); |
176 | RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc5ac42aedULL); |
177 | RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d139d95b3dfULL); |
178 | RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a73548baf63deULL); |
179 | RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb3c77b2a8ULL); |
180 | RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e47edaee6ULL); |
181 | RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c851482353bULL); |
182 | RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a14cf10364ULL); |
183 | RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664bbc423001ULL); |
184 | RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70d0f89791ULL); |
185 | RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a30654be30ULL); |
186 | RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819d6ef5218ULL); |
187 | RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd69906245565a910ULL); |
188 | RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e35855771202aULL); |
189 | RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa07032bbd1b8ULL); |
190 | RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116b8d2d0c8ULL); |
191 | RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c085141ab53ULL); |
192 | RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774cdf8eeb99ULL); |
193 | RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5e19b48a8ULL); |
194 | RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3c5c95a63ULL); |
195 | RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4ae3418acbULL); |
196 | RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f7763e373ULL); |
197 | RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3d6b2b8a3ULL); |
198 | RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee5defb2fcULL); |
199 | RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f43172f60ULL); |
200 | RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814a1f0ab72ULL); |
201 | RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc702081a6439ecULL); |
202 | RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa23631e28ULL); |
203 | RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506cebde82bde9ULL); |
204 | RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7b2c67915ULL); |
205 | RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2e372532bULL); |
206 | RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],64,0xca273eceea26619cULL); |
207 | RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],65,0xd186b8c721c0c207ULL); |
208 | RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],66,0xeada7dd6cde0eb1eULL); |
209 | RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],67,0xf57d4f7fee6ed178ULL); |
210 | RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],68,0x06f067aa72176fbaULL); |
211 | RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],69,0x0a637dc5a2c898a6ULL); |
212 | RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],70,0x113f9804bef90daeULL); |
213 | RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],71,0x1b710b35131c471bULL); |
214 | RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],72,0x28db77f523047d84ULL); |
215 | RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],73,0x32caab7b40c72493ULL); |
216 | RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],74,0x3c9ebe0a15c9bebcULL); |
217 | RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],75,0x431d67c49c100d4cULL); |
218 | RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],76,0x4cc5d4becb3e42b6ULL); |
219 | RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],77,0x597f299cfc657e2aULL); |
220 | RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],78,0x5fcb6fab3ad6faecULL); |
221 | RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],79,0x6c44198c4a475817ULL); |
222 | |
223 | #undef RND |
224 | |
225 | /* feedback */ |
226 | for (i = 0; i < 8; i++) { |
227 | sha_info->digest[i] = sha_info->digest[i] + S[i]; |
228 | } |
229 | |
230 | } |
231 | |
232 | |
233 | |
234 | /* initialize the SHA digest */ |
235 | |
236 | static void |
237 | sha512_init(SHAobject *sha_info) |
238 | { |
239 | sha_info->digest[0] = Py_ULL(0x6a09e667f3bcc908); |
240 | sha_info->digest[1] = Py_ULL(0xbb67ae8584caa73b); |
241 | sha_info->digest[2] = Py_ULL(0x3c6ef372fe94f82b); |
242 | sha_info->digest[3] = Py_ULL(0xa54ff53a5f1d36f1); |
243 | sha_info->digest[4] = Py_ULL(0x510e527fade682d1); |
244 | sha_info->digest[5] = Py_ULL(0x9b05688c2b3e6c1f); |
245 | sha_info->digest[6] = Py_ULL(0x1f83d9abfb41bd6b); |
246 | sha_info->digest[7] = Py_ULL(0x5be0cd19137e2179); |
247 | sha_info->count_lo = 0L; |
248 | sha_info->count_hi = 0L; |
249 | sha_info->local = 0; |
250 | sha_info->digestsize = 64; |
251 | } |
252 | |
253 | static void |
254 | sha384_init(SHAobject *sha_info) |
255 | { |
256 | sha_info->digest[0] = Py_ULL(0xcbbb9d5dc1059ed8); |
257 | sha_info->digest[1] = Py_ULL(0x629a292a367cd507); |
258 | sha_info->digest[2] = Py_ULL(0x9159015a3070dd17); |
259 | sha_info->digest[3] = Py_ULL(0x152fecd8f70e5939); |
260 | sha_info->digest[4] = Py_ULL(0x67332667ffc00b31); |
261 | sha_info->digest[5] = Py_ULL(0x8eb44a8768581511); |
262 | sha_info->digest[6] = Py_ULL(0xdb0c2e0d64f98fa7); |
263 | sha_info->digest[7] = Py_ULL(0x47b5481dbefa4fa4); |
264 | sha_info->count_lo = 0L; |
265 | sha_info->count_hi = 0L; |
266 | sha_info->local = 0; |
267 | sha_info->digestsize = 48; |
268 | } |
269 | |
270 | |
271 | /* update the SHA digest */ |
272 | |
273 | static void |
274 | sha512_update(SHAobject *sha_info, SHA_BYTE *buffer, Py_ssize_t count) |
275 | { |
276 | Py_ssize_t i; |
277 | SHA_INT32 clo; |
278 | |
279 | clo = sha_info->count_lo + ((SHA_INT32) count << 3); |
280 | if (clo < sha_info->count_lo) { |
281 | ++sha_info->count_hi; |
282 | } |
283 | sha_info->count_lo = clo; |
284 | sha_info->count_hi += (SHA_INT32) count >> 29; |
285 | if (sha_info->local) { |
286 | i = SHA_BLOCKSIZE - sha_info->local; |
287 | if (i > count) { |
288 | i = count; |
289 | } |
290 | memcpy(((SHA_BYTE *) sha_info->data) + sha_info->local, buffer, i); |
291 | count -= i; |
292 | buffer += i; |
293 | sha_info->local += (int)i; |
294 | if (sha_info->local == SHA_BLOCKSIZE) { |
295 | sha512_transform(sha_info); |
296 | } |
297 | else { |
298 | return; |
299 | } |
300 | } |
301 | while (count >= SHA_BLOCKSIZE) { |
302 | memcpy(sha_info->data, buffer, SHA_BLOCKSIZE); |
303 | buffer += SHA_BLOCKSIZE; |
304 | count -= SHA_BLOCKSIZE; |
305 | sha512_transform(sha_info); |
306 | } |
307 | memcpy(sha_info->data, buffer, count); |
308 | sha_info->local = (int)count; |
309 | } |
310 | |
311 | /* finish computing the SHA digest */ |
312 | |
313 | static void |
314 | sha512_final(unsigned char digest[SHA_DIGESTSIZE], SHAobject *sha_info) |
315 | { |
316 | int count; |
317 | SHA_INT32 lo_bit_count, hi_bit_count; |
318 | |
319 | lo_bit_count = sha_info->count_lo; |
320 | hi_bit_count = sha_info->count_hi; |
321 | count = (int) ((lo_bit_count >> 3) & 0x7f); |
322 | ((SHA_BYTE *) sha_info->data)[count++] = 0x80; |
323 | if (count > SHA_BLOCKSIZE - 16) { |
324 | memset(((SHA_BYTE *) sha_info->data) + count, 0, |
325 | SHA_BLOCKSIZE - count); |
326 | sha512_transform(sha_info); |
327 | memset((SHA_BYTE *) sha_info->data, 0, SHA_BLOCKSIZE - 16); |
328 | } |
329 | else { |
330 | memset(((SHA_BYTE *) sha_info->data) + count, 0, |
331 | SHA_BLOCKSIZE - 16 - count); |
332 | } |
333 | |
334 | /* GJS: note that we add the hi/lo in big-endian. sha512_transform will |
335 | swap these values into host-order. */ |
336 | sha_info->data[112] = 0; |
337 | sha_info->data[113] = 0; |
338 | sha_info->data[114] = 0; |
339 | sha_info->data[115] = 0; |
340 | sha_info->data[116] = 0; |
341 | sha_info->data[117] = 0; |
342 | sha_info->data[118] = 0; |
343 | sha_info->data[119] = 0; |
344 | sha_info->data[120] = (hi_bit_count >> 24) & 0xff; |
345 | sha_info->data[121] = (hi_bit_count >> 16) & 0xff; |
346 | sha_info->data[122] = (hi_bit_count >> 8) & 0xff; |
347 | sha_info->data[123] = (hi_bit_count >> 0) & 0xff; |
348 | sha_info->data[124] = (lo_bit_count >> 24) & 0xff; |
349 | sha_info->data[125] = (lo_bit_count >> 16) & 0xff; |
350 | sha_info->data[126] = (lo_bit_count >> 8) & 0xff; |
351 | sha_info->data[127] = (lo_bit_count >> 0) & 0xff; |
352 | sha512_transform(sha_info); |
353 | digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 56) & 0xff); |
354 | digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 48) & 0xff); |
355 | digest[ 2] = (unsigned char) ((sha_info->digest[0] >> 40) & 0xff); |
356 | digest[ 3] = (unsigned char) ((sha_info->digest[0] >> 32) & 0xff); |
357 | digest[ 4] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff); |
358 | digest[ 5] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff); |
359 | digest[ 6] = (unsigned char) ((sha_info->digest[0] >> 8) & 0xff); |
360 | digest[ 7] = (unsigned char) ((sha_info->digest[0] ) & 0xff); |
361 | digest[ 8] = (unsigned char) ((sha_info->digest[1] >> 56) & 0xff); |
362 | digest[ 9] = (unsigned char) ((sha_info->digest[1] >> 48) & 0xff); |
363 | digest[10] = (unsigned char) ((sha_info->digest[1] >> 40) & 0xff); |
364 | digest[11] = (unsigned char) ((sha_info->digest[1] >> 32) & 0xff); |
365 | digest[12] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff); |
366 | digest[13] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff); |
367 | digest[14] = (unsigned char) ((sha_info->digest[1] >> 8) & 0xff); |
368 | digest[15] = (unsigned char) ((sha_info->digest[1] ) & 0xff); |
369 | digest[16] = (unsigned char) ((sha_info->digest[2] >> 56) & 0xff); |
370 | digest[17] = (unsigned char) ((sha_info->digest[2] >> 48) & 0xff); |
371 | digest[18] = (unsigned char) ((sha_info->digest[2] >> 40) & 0xff); |
372 | digest[19] = (unsigned char) ((sha_info->digest[2] >> 32) & 0xff); |
373 | digest[20] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff); |
374 | digest[21] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff); |
375 | digest[22] = (unsigned char) ((sha_info->digest[2] >> 8) & 0xff); |
376 | digest[23] = (unsigned char) ((sha_info->digest[2] ) & 0xff); |
377 | digest[24] = (unsigned char) ((sha_info->digest[3] >> 56) & 0xff); |
378 | digest[25] = (unsigned char) ((sha_info->digest[3] >> 48) & 0xff); |
379 | digest[26] = (unsigned char) ((sha_info->digest[3] >> 40) & 0xff); |
380 | digest[27] = (unsigned char) ((sha_info->digest[3] >> 32) & 0xff); |
381 | digest[28] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff); |
382 | digest[29] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff); |
383 | digest[30] = (unsigned char) ((sha_info->digest[3] >> 8) & 0xff); |
384 | digest[31] = (unsigned char) ((sha_info->digest[3] ) & 0xff); |
385 | digest[32] = (unsigned char) ((sha_info->digest[4] >> 56) & 0xff); |
386 | digest[33] = (unsigned char) ((sha_info->digest[4] >> 48) & 0xff); |
387 | digest[34] = (unsigned char) ((sha_info->digest[4] >> 40) & 0xff); |
388 | digest[35] = (unsigned char) ((sha_info->digest[4] >> 32) & 0xff); |
389 | digest[36] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff); |
390 | digest[37] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff); |
391 | digest[38] = (unsigned char) ((sha_info->digest[4] >> 8) & 0xff); |
392 | digest[39] = (unsigned char) ((sha_info->digest[4] ) & 0xff); |
393 | digest[40] = (unsigned char) ((sha_info->digest[5] >> 56) & 0xff); |
394 | digest[41] = (unsigned char) ((sha_info->digest[5] >> 48) & 0xff); |
395 | digest[42] = (unsigned char) ((sha_info->digest[5] >> 40) & 0xff); |
396 | digest[43] = (unsigned char) ((sha_info->digest[5] >> 32) & 0xff); |
397 | digest[44] = (unsigned char) ((sha_info->digest[5] >> 24) & 0xff); |
398 | digest[45] = (unsigned char) ((sha_info->digest[5] >> 16) & 0xff); |
399 | digest[46] = (unsigned char) ((sha_info->digest[5] >> 8) & 0xff); |
400 | digest[47] = (unsigned char) ((sha_info->digest[5] ) & 0xff); |
401 | digest[48] = (unsigned char) ((sha_info->digest[6] >> 56) & 0xff); |
402 | digest[49] = (unsigned char) ((sha_info->digest[6] >> 48) & 0xff); |
403 | digest[50] = (unsigned char) ((sha_info->digest[6] >> 40) & 0xff); |
404 | digest[51] = (unsigned char) ((sha_info->digest[6] >> 32) & 0xff); |
405 | digest[52] = (unsigned char) ((sha_info->digest[6] >> 24) & 0xff); |
406 | digest[53] = (unsigned char) ((sha_info->digest[6] >> 16) & 0xff); |
407 | digest[54] = (unsigned char) ((sha_info->digest[6] >> 8) & 0xff); |
408 | digest[55] = (unsigned char) ((sha_info->digest[6] ) & 0xff); |
409 | digest[56] = (unsigned char) ((sha_info->digest[7] >> 56) & 0xff); |
410 | digest[57] = (unsigned char) ((sha_info->digest[7] >> 48) & 0xff); |
411 | digest[58] = (unsigned char) ((sha_info->digest[7] >> 40) & 0xff); |
412 | digest[59] = (unsigned char) ((sha_info->digest[7] >> 32) & 0xff); |
413 | digest[60] = (unsigned char) ((sha_info->digest[7] >> 24) & 0xff); |
414 | digest[61] = (unsigned char) ((sha_info->digest[7] >> 16) & 0xff); |
415 | digest[62] = (unsigned char) ((sha_info->digest[7] >> 8) & 0xff); |
416 | digest[63] = (unsigned char) ((sha_info->digest[7] ) & 0xff); |
417 | } |
418 | |
419 | /* |
420 | * End of copied SHA code. |
421 | * |
422 | * ------------------------------------------------------------------------ |
423 | */ |
424 | |
425 | typedef struct { |
426 | PyTypeObject* sha384_type; |
427 | PyTypeObject* sha512_type; |
428 | } SHA512State; |
429 | |
430 | static inline SHA512State* |
431 | sha512_get_state(PyObject *module) |
432 | { |
433 | void *state = PyModule_GetState(module); |
434 | assert(state != NULL); |
435 | return (SHA512State *)state; |
436 | } |
437 | |
438 | static SHAobject * |
439 | newSHA384object(SHA512State *st) |
440 | { |
441 | SHAobject *sha = (SHAobject *)PyObject_GC_New(SHAobject, st->sha384_type); |
442 | PyObject_GC_Track(sha); |
443 | return sha; |
444 | } |
445 | |
446 | static SHAobject * |
447 | newSHA512object(SHA512State *st) |
448 | { |
449 | SHAobject *sha = (SHAobject *)PyObject_GC_New(SHAobject, st->sha512_type); |
450 | PyObject_GC_Track(sha); |
451 | return sha; |
452 | } |
453 | |
454 | /* Internal methods for a hash object */ |
455 | static int |
456 | SHA_traverse(PyObject *ptr, visitproc visit, void *arg) |
457 | { |
458 | Py_VISIT(Py_TYPE(ptr)); |
459 | return 0; |
460 | } |
461 | |
462 | static void |
463 | SHA512_dealloc(PyObject *ptr) |
464 | { |
465 | PyTypeObject *tp = Py_TYPE(ptr); |
466 | PyObject_GC_UnTrack(ptr); |
467 | PyObject_GC_Del(ptr); |
468 | Py_DECREF(tp); |
469 | } |
470 | |
471 | |
472 | /* External methods for a hash object */ |
473 | |
474 | /*[clinic input] |
475 | SHA512Type.copy |
476 | |
477 | cls: defining_class |
478 | |
479 | Return a copy of the hash object. |
480 | [clinic start generated code]*/ |
481 | |
482 | static PyObject * |
483 | SHA512Type_copy_impl(SHAobject *self, PyTypeObject *cls) |
484 | /*[clinic end generated code: output=85ea5b47837a08e6 input=f673a18f66527c90]*/ |
485 | { |
486 | SHAobject *newobj; |
487 | SHA512State *st = PyType_GetModuleState(cls); |
488 | |
489 | if (Py_IS_TYPE((PyObject*)self, st->sha512_type)) { |
490 | if ( (newobj = newSHA512object(st))==NULL) { |
491 | return NULL; |
492 | } |
493 | } |
494 | else { |
495 | if ( (newobj = newSHA384object(st))==NULL) { |
496 | return NULL; |
497 | } |
498 | } |
499 | |
500 | SHAcopy(self, newobj); |
501 | return (PyObject *)newobj; |
502 | } |
503 | |
504 | /*[clinic input] |
505 | SHA512Type.digest |
506 | |
507 | Return the digest value as a bytes object. |
508 | [clinic start generated code]*/ |
509 | |
510 | static PyObject * |
511 | SHA512Type_digest_impl(SHAobject *self) |
512 | /*[clinic end generated code: output=1080bbeeef7dde1b input=f6470dd359071f4b]*/ |
513 | { |
514 | unsigned char digest[SHA_DIGESTSIZE]; |
515 | SHAobject temp; |
516 | |
517 | SHAcopy(self, &temp); |
518 | sha512_final(digest, &temp); |
519 | return PyBytes_FromStringAndSize((const char *)digest, self->digestsize); |
520 | } |
521 | |
522 | /*[clinic input] |
523 | SHA512Type.hexdigest |
524 | |
525 | Return the digest value as a string of hexadecimal digits. |
526 | [clinic start generated code]*/ |
527 | |
528 | static PyObject * |
529 | SHA512Type_hexdigest_impl(SHAobject *self) |
530 | /*[clinic end generated code: output=7373305b8601e18b input=498b877b25cbe0a2]*/ |
531 | { |
532 | unsigned char digest[SHA_DIGESTSIZE]; |
533 | SHAobject temp; |
534 | |
535 | /* Get the raw (binary) digest value */ |
536 | SHAcopy(self, &temp); |
537 | sha512_final(digest, &temp); |
538 | |
539 | return _Py_strhex((const char *)digest, self->digestsize); |
540 | } |
541 | |
542 | /*[clinic input] |
543 | SHA512Type.update |
544 | |
545 | obj: object |
546 | / |
547 | |
548 | Update this hash object's state with the provided string. |
549 | [clinic start generated code]*/ |
550 | |
551 | static PyObject * |
552 | SHA512Type_update(SHAobject *self, PyObject *obj) |
553 | /*[clinic end generated code: output=1cf333e73995a79e input=ded2b46656566283]*/ |
554 | { |
555 | Py_buffer buf; |
556 | |
557 | GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); |
558 | |
559 | sha512_update(self, buf.buf, buf.len); |
560 | |
561 | PyBuffer_Release(&buf); |
562 | Py_RETURN_NONE; |
563 | } |
564 | |
565 | static PyMethodDef SHA_methods[] = { |
566 | SHA512TYPE_COPY_METHODDEF |
567 | SHA512TYPE_DIGEST_METHODDEF |
568 | SHA512TYPE_HEXDIGEST_METHODDEF |
569 | SHA512TYPE_UPDATE_METHODDEF |
570 | {NULL, NULL} /* sentinel */ |
571 | }; |
572 | |
573 | static PyObject * |
574 | SHA512_get_block_size(PyObject *self, void *closure) |
575 | { |
576 | return PyLong_FromLong(SHA_BLOCKSIZE); |
577 | } |
578 | |
579 | static PyObject * |
580 | SHA512_get_name(PyObject *self, void *closure) |
581 | { |
582 | if (((SHAobject *)self)->digestsize == 64) |
583 | return PyUnicode_FromStringAndSize("sha512" , 6); |
584 | else |
585 | return PyUnicode_FromStringAndSize("sha384" , 6); |
586 | } |
587 | |
588 | static PyGetSetDef SHA_getseters[] = { |
589 | {"block_size" , |
590 | (getter)SHA512_get_block_size, NULL, |
591 | NULL, |
592 | NULL}, |
593 | {"name" , |
594 | (getter)SHA512_get_name, NULL, |
595 | NULL, |
596 | NULL}, |
597 | {NULL} /* Sentinel */ |
598 | }; |
599 | |
600 | static PyMemberDef SHA_members[] = { |
601 | {"digest_size" , T_INT, offsetof(SHAobject, digestsize), READONLY, NULL}, |
602 | {NULL} /* Sentinel */ |
603 | }; |
604 | |
605 | static PyType_Slot sha512_sha384_type_slots[] = { |
606 | {Py_tp_dealloc, SHA512_dealloc}, |
607 | {Py_tp_methods, SHA_methods}, |
608 | {Py_tp_members, SHA_members}, |
609 | {Py_tp_getset, SHA_getseters}, |
610 | {Py_tp_traverse, SHA_traverse}, |
611 | {0,0} |
612 | }; |
613 | |
614 | static PyType_Spec sha512_sha384_type_spec = { |
615 | .name = "_sha512.sha384" , |
616 | .basicsize = sizeof(SHAobject), |
617 | .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | |
618 | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC), |
619 | .slots = sha512_sha384_type_slots |
620 | }; |
621 | |
622 | static PyType_Slot sha512_sha512_type_slots[] = { |
623 | {Py_tp_dealloc, SHA512_dealloc}, |
624 | {Py_tp_methods, SHA_methods}, |
625 | {Py_tp_members, SHA_members}, |
626 | {Py_tp_getset, SHA_getseters}, |
627 | {Py_tp_traverse, SHA_traverse}, |
628 | {0,0} |
629 | }; |
630 | |
631 | // Using PyType_GetModuleState() on this type is safe since |
632 | // it cannot be subclassed: it does not have the Py_TPFLAGS_BASETYPE flag. |
633 | static PyType_Spec sha512_sha512_type_spec = { |
634 | .name = "_sha512.sha512" , |
635 | .basicsize = sizeof(SHAobject), |
636 | .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | |
637 | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC), |
638 | .slots = sha512_sha512_type_slots |
639 | }; |
640 | |
641 | /* The single module-level function: new() */ |
642 | |
643 | /*[clinic input] |
644 | _sha512.sha512 |
645 | |
646 | string: object(c_default="NULL") = b'' |
647 | * |
648 | usedforsecurity: bool = True |
649 | |
650 | Return a new SHA-512 hash object; optionally initialized with a string. |
651 | [clinic start generated code]*/ |
652 | |
653 | static PyObject * |
654 | _sha512_sha512_impl(PyObject *module, PyObject *string, int usedforsecurity) |
655 | /*[clinic end generated code: output=a8d9e5f9e6a0831c input=23b4daebc2ebb9c9]*/ |
656 | { |
657 | SHAobject *new; |
658 | Py_buffer buf; |
659 | |
660 | SHA512State *st = sha512_get_state(module); |
661 | |
662 | if (string) |
663 | GET_BUFFER_VIEW_OR_ERROUT(string, &buf); |
664 | |
665 | if ((new = newSHA512object(st)) == NULL) { |
666 | if (string) |
667 | PyBuffer_Release(&buf); |
668 | return NULL; |
669 | } |
670 | |
671 | sha512_init(new); |
672 | |
673 | if (PyErr_Occurred()) { |
674 | Py_DECREF(new); |
675 | if (string) |
676 | PyBuffer_Release(&buf); |
677 | return NULL; |
678 | } |
679 | if (string) { |
680 | sha512_update(new, buf.buf, buf.len); |
681 | PyBuffer_Release(&buf); |
682 | } |
683 | |
684 | return (PyObject *)new; |
685 | } |
686 | |
687 | /*[clinic input] |
688 | _sha512.sha384 |
689 | |
690 | string: object(c_default="NULL") = b'' |
691 | * |
692 | usedforsecurity: bool = True |
693 | |
694 | Return a new SHA-384 hash object; optionally initialized with a string. |
695 | [clinic start generated code]*/ |
696 | |
697 | static PyObject * |
698 | _sha512_sha384_impl(PyObject *module, PyObject *string, int usedforsecurity) |
699 | /*[clinic end generated code: output=da7d594a08027ac3 input=59ef72f039a6b431]*/ |
700 | { |
701 | SHAobject *new; |
702 | Py_buffer buf; |
703 | |
704 | SHA512State *st = sha512_get_state(module); |
705 | |
706 | if (string) |
707 | GET_BUFFER_VIEW_OR_ERROUT(string, &buf); |
708 | |
709 | if ((new = newSHA384object(st)) == NULL) { |
710 | if (string) |
711 | PyBuffer_Release(&buf); |
712 | return NULL; |
713 | } |
714 | |
715 | sha384_init(new); |
716 | |
717 | if (PyErr_Occurred()) { |
718 | Py_DECREF(new); |
719 | if (string) |
720 | PyBuffer_Release(&buf); |
721 | return NULL; |
722 | } |
723 | if (string) { |
724 | sha512_update(new, buf.buf, buf.len); |
725 | PyBuffer_Release(&buf); |
726 | } |
727 | |
728 | return (PyObject *)new; |
729 | } |
730 | |
731 | |
732 | /* List of functions exported by this module */ |
733 | |
734 | static struct PyMethodDef SHA_functions[] = { |
735 | _SHA512_SHA512_METHODDEF |
736 | _SHA512_SHA384_METHODDEF |
737 | {NULL, NULL} /* Sentinel */ |
738 | }; |
739 | |
740 | static int |
741 | _sha512_traverse(PyObject *module, visitproc visit, void *arg) |
742 | { |
743 | SHA512State *state = sha512_get_state(module); |
744 | Py_VISIT(state->sha384_type); |
745 | Py_VISIT(state->sha512_type); |
746 | return 0; |
747 | } |
748 | |
749 | static int |
750 | _sha512_clear(PyObject *module) |
751 | { |
752 | SHA512State *state = sha512_get_state(module); |
753 | Py_CLEAR(state->sha384_type); |
754 | Py_CLEAR(state->sha512_type); |
755 | return 0; |
756 | } |
757 | |
758 | static void |
759 | _sha512_free(void *module) |
760 | { |
761 | _sha512_clear((PyObject *)module); |
762 | } |
763 | |
764 | |
765 | /* Initialize this module. */ |
766 | static int |
767 | _sha512_exec(PyObject *m) |
768 | { |
769 | SHA512State* st = sha512_get_state(m); |
770 | |
771 | st->sha384_type = (PyTypeObject *)PyType_FromModuleAndSpec( |
772 | m, &sha512_sha384_type_spec, NULL); |
773 | |
774 | st->sha512_type = (PyTypeObject *)PyType_FromModuleAndSpec( |
775 | m, &sha512_sha512_type_spec, NULL); |
776 | |
777 | if (st->sha384_type == NULL || st->sha512_type == NULL) { |
778 | return -1; |
779 | } |
780 | |
781 | Py_INCREF(st->sha384_type); |
782 | if (PyModule_AddObject(m, "SHA384Type" , (PyObject *)st->sha384_type) < 0) { |
783 | Py_DECREF(st->sha384_type); |
784 | return -1; |
785 | } |
786 | |
787 | Py_INCREF(st->sha512_type); |
788 | if (PyModule_AddObject(m, "SHA384Type" , (PyObject *)st->sha512_type) < 0) { |
789 | Py_DECREF(st->sha512_type); |
790 | return -1; |
791 | } |
792 | |
793 | return 0; |
794 | } |
795 | |
796 | static PyModuleDef_Slot _sha512_slots[] = { |
797 | {Py_mod_exec, _sha512_exec}, |
798 | {0, NULL} |
799 | }; |
800 | |
801 | static struct PyModuleDef _sha512module = { |
802 | PyModuleDef_HEAD_INIT, |
803 | .m_name = "_sha512" , |
804 | .m_size = sizeof(SHA512State), |
805 | .m_methods = SHA_functions, |
806 | .m_slots = _sha512_slots, |
807 | .m_traverse = _sha512_traverse, |
808 | .m_clear = _sha512_clear, |
809 | .m_free = _sha512_free |
810 | }; |
811 | |
812 | PyMODINIT_FUNC |
813 | PyInit__sha512(void) |
814 | { |
815 | return PyModuleDef_Init(&_sha512module); |
816 | } |
817 | |