Line data Source code
1 : /* SHA256 module */
2 :
3 : /* This module provides an interface to NIST's SHA-256 and SHA-224 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 (amk@amk.ca)
9 : Greg Stein (gstein@lyra.org)
10 : Trevor Perrin (trevp@trevp.net)
11 :
12 : Copyright (C) 2005-2007 Gregory P. Smith (greg@krypto.org)
13 : Licensed to PSF under a Contributor Agreement.
14 :
15 : */
16 :
17 : /* SHA objects */
18 :
19 : #include "Python.h"
20 : #include "structmember.h"
21 : #include "hashlib.h"
22 :
23 :
24 : /* Endianness testing and definitions */
25 : #define TestEndianness(variable) {int i=1; variable=PCT_BIG_ENDIAN;\
26 : if (*((char*)&i)==1) variable=PCT_LITTLE_ENDIAN;}
27 :
28 : #define PCT_LITTLE_ENDIAN 1
29 : #define PCT_BIG_ENDIAN 0
30 :
31 : /* Some useful types */
32 :
33 : typedef unsigned char SHA_BYTE;
34 :
35 : #if SIZEOF_INT == 4
36 : typedef unsigned int SHA_INT32; /* 32-bit integer */
37 : #else
38 : /* not defined. compilation will die. */
39 : #endif
40 :
41 : /* The SHA block size and message digest sizes, in bytes */
42 :
43 : #define SHA_BLOCKSIZE 64
44 : #define SHA_DIGESTSIZE 32
45 :
46 : /* The structure for storing SHA info */
47 :
48 : typedef struct {
49 : PyObject_HEAD
50 : SHA_INT32 digest[8]; /* Message digest */
51 : SHA_INT32 count_lo, count_hi; /* 64-bit bit count */
52 : SHA_BYTE data[SHA_BLOCKSIZE]; /* SHA data buffer */
53 : int Endianness;
54 : int local; /* unprocessed amount in data */
55 : int digestsize;
56 : } SHAobject;
57 :
58 : /* When run on a little-endian CPU we need to perform byte reversal on an
59 : array of longwords. */
60 :
61 0 : static void longReverse(SHA_INT32 *buffer, int byteCount, int Endianness)
62 : {
63 : SHA_INT32 value;
64 :
65 0 : if ( Endianness == PCT_BIG_ENDIAN )
66 0 : return;
67 :
68 0 : byteCount /= sizeof(*buffer);
69 0 : while (byteCount--) {
70 0 : value = *buffer;
71 0 : value = ( ( value & 0xFF00FF00L ) >> 8 ) | \
72 0 : ( ( value & 0x00FF00FFL ) << 8 );
73 0 : *buffer++ = ( value << 16 ) | ( value >> 16 );
74 : }
75 : }
76 :
77 0 : static void SHAcopy(SHAobject *src, SHAobject *dest)
78 : {
79 0 : dest->Endianness = src->Endianness;
80 0 : dest->local = src->local;
81 0 : dest->digestsize = src->digestsize;
82 0 : dest->count_lo = src->count_lo;
83 0 : dest->count_hi = src->count_hi;
84 0 : memcpy(dest->digest, src->digest, sizeof(src->digest));
85 0 : memcpy(dest->data, src->data, sizeof(src->data));
86 0 : }
87 :
88 :
89 : /* ------------------------------------------------------------------------
90 : *
91 : * This code for the SHA-256 algorithm was noted as public domain. The
92 : * original headers are pasted below.
93 : *
94 : * Several changes have been made to make it more compatible with the
95 : * Python environment and desired interface.
96 : *
97 : */
98 :
99 : /* LibTomCrypt, modular cryptographic library -- Tom St Denis
100 : *
101 : * LibTomCrypt is a library that provides various cryptographic
102 : * algorithms in a highly modular and flexible manner.
103 : *
104 : * The library is free for all purposes without any express
105 : * gurantee it works.
106 : *
107 : * Tom St Denis, tomstdenis@iahu.ca, http://libtom.org
108 : */
109 :
110 :
111 : /* SHA256 by Tom St Denis */
112 :
113 : /* Various logical functions */
114 : #define ROR(x, y)\
115 : ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | \
116 : ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
117 : #define Ch(x,y,z) (z ^ (x & (y ^ z)))
118 : #define Maj(x,y,z) (((x | y) & z) | (x & y))
119 : #define S(x, n) ROR((x),(n))
120 : #define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
121 : #define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
122 : #define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
123 : #define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
124 : #define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
125 :
126 :
127 : static void
128 0 : sha_transform(SHAobject *sha_info)
129 : {
130 : int i;
131 : SHA_INT32 S[8], W[64], t0, t1;
132 :
133 0 : memcpy(W, sha_info->data, sizeof(sha_info->data));
134 0 : longReverse(W, (int)sizeof(sha_info->data), sha_info->Endianness);
135 :
136 0 : for (i = 16; i < 64; ++i) {
137 0 : W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
138 : }
139 0 : for (i = 0; i < 8; ++i) {
140 0 : S[i] = sha_info->digest[i];
141 : }
142 :
143 : /* Compress */
144 : #define RND(a,b,c,d,e,f,g,h,i,ki) \
145 : t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \
146 : t1 = Sigma0(a) + Maj(a, b, c); \
147 : d += t0; \
148 : h = t0 + t1;
149 :
150 0 : RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98);
151 0 : RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491);
152 0 : RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf);
153 0 : RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5);
154 0 : RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b);
155 0 : RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1);
156 0 : RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4);
157 0 : RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5);
158 0 : RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98);
159 0 : RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01);
160 0 : RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be);
161 0 : RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3);
162 0 : RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74);
163 0 : RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe);
164 0 : RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7);
165 0 : RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174);
166 0 : RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1);
167 0 : RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786);
168 0 : RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6);
169 0 : RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc);
170 0 : RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f);
171 0 : RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa);
172 0 : RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc);
173 0 : RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da);
174 0 : RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152);
175 0 : RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d);
176 0 : RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8);
177 0 : RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7);
178 0 : RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3);
179 0 : RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147);
180 0 : RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351);
181 0 : RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967);
182 0 : RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85);
183 0 : RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138);
184 0 : RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc);
185 0 : RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13);
186 0 : RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354);
187 0 : RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb);
188 0 : RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e);
189 0 : RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85);
190 0 : RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1);
191 0 : RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b);
192 0 : RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70);
193 0 : RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3);
194 0 : RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819);
195 0 : RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624);
196 0 : RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585);
197 0 : RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070);
198 0 : RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116);
199 0 : RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08);
200 0 : RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c);
201 0 : RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5);
202 0 : RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3);
203 0 : RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a);
204 0 : RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f);
205 0 : RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3);
206 0 : RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee);
207 0 : RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f);
208 0 : RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814);
209 0 : RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208);
210 0 : RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa);
211 0 : RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb);
212 0 : RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7);
213 0 : RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2);
214 :
215 : #undef RND
216 :
217 : /* feedback */
218 0 : for (i = 0; i < 8; i++) {
219 0 : sha_info->digest[i] = sha_info->digest[i] + S[i];
220 : }
221 :
222 0 : }
223 :
224 :
225 :
226 : /* initialize the SHA digest */
227 :
228 : static void
229 0 : sha_init(SHAobject *sha_info)
230 : {
231 0 : TestEndianness(sha_info->Endianness)
232 0 : sha_info->digest[0] = 0x6A09E667L;
233 0 : sha_info->digest[1] = 0xBB67AE85L;
234 0 : sha_info->digest[2] = 0x3C6EF372L;
235 0 : sha_info->digest[3] = 0xA54FF53AL;
236 0 : sha_info->digest[4] = 0x510E527FL;
237 0 : sha_info->digest[5] = 0x9B05688CL;
238 0 : sha_info->digest[6] = 0x1F83D9ABL;
239 0 : sha_info->digest[7] = 0x5BE0CD19L;
240 0 : sha_info->count_lo = 0L;
241 0 : sha_info->count_hi = 0L;
242 0 : sha_info->local = 0;
243 0 : sha_info->digestsize = 32;
244 0 : }
245 :
246 : static void
247 0 : sha224_init(SHAobject *sha_info)
248 : {
249 0 : TestEndianness(sha_info->Endianness)
250 0 : sha_info->digest[0] = 0xc1059ed8L;
251 0 : sha_info->digest[1] = 0x367cd507L;
252 0 : sha_info->digest[2] = 0x3070dd17L;
253 0 : sha_info->digest[3] = 0xf70e5939L;
254 0 : sha_info->digest[4] = 0xffc00b31L;
255 0 : sha_info->digest[5] = 0x68581511L;
256 0 : sha_info->digest[6] = 0x64f98fa7L;
257 0 : sha_info->digest[7] = 0xbefa4fa4L;
258 0 : sha_info->count_lo = 0L;
259 0 : sha_info->count_hi = 0L;
260 0 : sha_info->local = 0;
261 0 : sha_info->digestsize = 28;
262 0 : }
263 :
264 :
265 : /* update the SHA digest */
266 :
267 : static void
268 0 : sha_update(SHAobject *sha_info, SHA_BYTE *buffer, Py_ssize_t count)
269 : {
270 : Py_ssize_t i;
271 : SHA_INT32 clo;
272 :
273 0 : clo = sha_info->count_lo + ((SHA_INT32) count << 3);
274 0 : if (clo < sha_info->count_lo) {
275 0 : ++sha_info->count_hi;
276 : }
277 0 : sha_info->count_lo = clo;
278 0 : sha_info->count_hi += (SHA_INT32) count >> 29;
279 0 : if (sha_info->local) {
280 0 : i = SHA_BLOCKSIZE - sha_info->local;
281 0 : if (i > count) {
282 0 : i = count;
283 : }
284 0 : memcpy(((SHA_BYTE *) sha_info->data) + sha_info->local, buffer, i);
285 0 : count -= i;
286 0 : buffer += i;
287 0 : sha_info->local += i;
288 0 : if (sha_info->local == SHA_BLOCKSIZE) {
289 0 : sha_transform(sha_info);
290 : }
291 : else {
292 0 : return;
293 : }
294 : }
295 0 : while (count >= SHA_BLOCKSIZE) {
296 0 : memcpy(sha_info->data, buffer, SHA_BLOCKSIZE);
297 0 : buffer += SHA_BLOCKSIZE;
298 0 : count -= SHA_BLOCKSIZE;
299 0 : sha_transform(sha_info);
300 : }
301 0 : memcpy(sha_info->data, buffer, count);
302 0 : sha_info->local = count;
303 : }
304 :
305 : /* finish computing the SHA digest */
306 :
307 : static void
308 0 : sha_final(unsigned char digest[SHA_DIGESTSIZE], SHAobject *sha_info)
309 : {
310 : int count;
311 : SHA_INT32 lo_bit_count, hi_bit_count;
312 :
313 0 : lo_bit_count = sha_info->count_lo;
314 0 : hi_bit_count = sha_info->count_hi;
315 0 : count = (int) ((lo_bit_count >> 3) & 0x3f);
316 0 : ((SHA_BYTE *) sha_info->data)[count++] = 0x80;
317 0 : if (count > SHA_BLOCKSIZE - 8) {
318 0 : memset(((SHA_BYTE *) sha_info->data) + count, 0,
319 0 : SHA_BLOCKSIZE - count);
320 0 : sha_transform(sha_info);
321 0 : memset((SHA_BYTE *) sha_info->data, 0, SHA_BLOCKSIZE - 8);
322 : }
323 : else {
324 0 : memset(((SHA_BYTE *) sha_info->data) + count, 0,
325 0 : SHA_BLOCKSIZE - 8 - count);
326 : }
327 :
328 : /* GJS: note that we add the hi/lo in big-endian. sha_transform will
329 : swap these values into host-order. */
330 0 : sha_info->data[56] = (hi_bit_count >> 24) & 0xff;
331 0 : sha_info->data[57] = (hi_bit_count >> 16) & 0xff;
332 0 : sha_info->data[58] = (hi_bit_count >> 8) & 0xff;
333 0 : sha_info->data[59] = (hi_bit_count >> 0) & 0xff;
334 0 : sha_info->data[60] = (lo_bit_count >> 24) & 0xff;
335 0 : sha_info->data[61] = (lo_bit_count >> 16) & 0xff;
336 0 : sha_info->data[62] = (lo_bit_count >> 8) & 0xff;
337 0 : sha_info->data[63] = (lo_bit_count >> 0) & 0xff;
338 0 : sha_transform(sha_info);
339 0 : digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff);
340 0 : digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff);
341 0 : digest[ 2] = (unsigned char) ((sha_info->digest[0] >> 8) & 0xff);
342 0 : digest[ 3] = (unsigned char) ((sha_info->digest[0] ) & 0xff);
343 0 : digest[ 4] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff);
344 0 : digest[ 5] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff);
345 0 : digest[ 6] = (unsigned char) ((sha_info->digest[1] >> 8) & 0xff);
346 0 : digest[ 7] = (unsigned char) ((sha_info->digest[1] ) & 0xff);
347 0 : digest[ 8] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff);
348 0 : digest[ 9] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff);
349 0 : digest[10] = (unsigned char) ((sha_info->digest[2] >> 8) & 0xff);
350 0 : digest[11] = (unsigned char) ((sha_info->digest[2] ) & 0xff);
351 0 : digest[12] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff);
352 0 : digest[13] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff);
353 0 : digest[14] = (unsigned char) ((sha_info->digest[3] >> 8) & 0xff);
354 0 : digest[15] = (unsigned char) ((sha_info->digest[3] ) & 0xff);
355 0 : digest[16] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff);
356 0 : digest[17] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff);
357 0 : digest[18] = (unsigned char) ((sha_info->digest[4] >> 8) & 0xff);
358 0 : digest[19] = (unsigned char) ((sha_info->digest[4] ) & 0xff);
359 0 : digest[20] = (unsigned char) ((sha_info->digest[5] >> 24) & 0xff);
360 0 : digest[21] = (unsigned char) ((sha_info->digest[5] >> 16) & 0xff);
361 0 : digest[22] = (unsigned char) ((sha_info->digest[5] >> 8) & 0xff);
362 0 : digest[23] = (unsigned char) ((sha_info->digest[5] ) & 0xff);
363 0 : digest[24] = (unsigned char) ((sha_info->digest[6] >> 24) & 0xff);
364 0 : digest[25] = (unsigned char) ((sha_info->digest[6] >> 16) & 0xff);
365 0 : digest[26] = (unsigned char) ((sha_info->digest[6] >> 8) & 0xff);
366 0 : digest[27] = (unsigned char) ((sha_info->digest[6] ) & 0xff);
367 0 : digest[28] = (unsigned char) ((sha_info->digest[7] >> 24) & 0xff);
368 0 : digest[29] = (unsigned char) ((sha_info->digest[7] >> 16) & 0xff);
369 0 : digest[30] = (unsigned char) ((sha_info->digest[7] >> 8) & 0xff);
370 0 : digest[31] = (unsigned char) ((sha_info->digest[7] ) & 0xff);
371 0 : }
372 :
373 : /*
374 : * End of copied SHA code.
375 : *
376 : * ------------------------------------------------------------------------
377 : */
378 :
379 : static PyTypeObject SHA224type;
380 : static PyTypeObject SHA256type;
381 :
382 :
383 : static SHAobject *
384 0 : newSHA224object(void)
385 : {
386 0 : return (SHAobject *)PyObject_New(SHAobject, &SHA224type);
387 : }
388 :
389 : static SHAobject *
390 0 : newSHA256object(void)
391 : {
392 0 : return (SHAobject *)PyObject_New(SHAobject, &SHA256type);
393 : }
394 :
395 : /* Internal methods for a hash object */
396 :
397 : static void
398 0 : SHA_dealloc(PyObject *ptr)
399 : {
400 0 : PyObject_Del(ptr);
401 0 : }
402 :
403 :
404 : /* External methods for a hash object */
405 :
406 : PyDoc_STRVAR(SHA256_copy__doc__, "Return a copy of the hash object.");
407 :
408 : static PyObject *
409 0 : SHA256_copy(SHAobject *self, PyObject *unused)
410 : {
411 : SHAobject *newobj;
412 :
413 0 : if (Py_TYPE(self) == &SHA256type) {
414 0 : if ( (newobj = newSHA256object())==NULL)
415 0 : return NULL;
416 : } else {
417 0 : if ( (newobj = newSHA224object())==NULL)
418 0 : return NULL;
419 : }
420 :
421 0 : SHAcopy(self, newobj);
422 0 : return (PyObject *)newobj;
423 : }
424 :
425 : PyDoc_STRVAR(SHA256_digest__doc__,
426 : "Return the digest value as a string of binary data.");
427 :
428 : static PyObject *
429 0 : SHA256_digest(SHAobject *self, PyObject *unused)
430 : {
431 : unsigned char digest[SHA_DIGESTSIZE];
432 : SHAobject temp;
433 :
434 0 : SHAcopy(self, &temp);
435 0 : sha_final(digest, &temp);
436 0 : return PyBytes_FromStringAndSize((const char *)digest, self->digestsize);
437 : }
438 :
439 : PyDoc_STRVAR(SHA256_hexdigest__doc__,
440 : "Return the digest value as a string of hexadecimal digits.");
441 :
442 : static PyObject *
443 0 : SHA256_hexdigest(SHAobject *self, PyObject *unused)
444 : {
445 : unsigned char digest[SHA_DIGESTSIZE];
446 : SHAobject temp;
447 : PyObject *retval;
448 : Py_UCS1 *hex_digest;
449 : int i, j;
450 :
451 : /* Get the raw (binary) digest value */
452 0 : SHAcopy(self, &temp);
453 0 : sha_final(digest, &temp);
454 :
455 : /* Create a new string */
456 0 : retval = PyUnicode_New(self->digestsize * 2, 127);
457 0 : if (!retval)
458 0 : return NULL;
459 0 : hex_digest = PyUnicode_1BYTE_DATA(retval);
460 :
461 : /* Make hex version of the digest */
462 0 : for(i=j=0; i<self->digestsize; i++) {
463 : unsigned char c;
464 0 : c = (digest[i] >> 4) & 0xf;
465 0 : hex_digest[j++] = Py_hexdigits[c];
466 0 : c = (digest[i] & 0xf);
467 0 : hex_digest[j++] = Py_hexdigits[c];
468 : }
469 : assert(_PyUnicode_CheckConsistency(retval, 1));
470 0 : return retval;
471 : }
472 :
473 : PyDoc_STRVAR(SHA256_update__doc__,
474 : "Update this hash object's state with the provided string.");
475 :
476 : static PyObject *
477 0 : SHA256_update(SHAobject *self, PyObject *args)
478 : {
479 : PyObject *obj;
480 : Py_buffer buf;
481 :
482 0 : if (!PyArg_ParseTuple(args, "O:update", &obj))
483 0 : return NULL;
484 :
485 0 : GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
486 :
487 0 : sha_update(self, buf.buf, buf.len);
488 :
489 0 : PyBuffer_Release(&buf);
490 0 : Py_INCREF(Py_None);
491 0 : return Py_None;
492 : }
493 :
494 : static PyMethodDef SHA_methods[] = {
495 : {"copy", (PyCFunction)SHA256_copy, METH_NOARGS, SHA256_copy__doc__},
496 : {"digest", (PyCFunction)SHA256_digest, METH_NOARGS, SHA256_digest__doc__},
497 : {"hexdigest", (PyCFunction)SHA256_hexdigest, METH_NOARGS, SHA256_hexdigest__doc__},
498 : {"update", (PyCFunction)SHA256_update, METH_VARARGS, SHA256_update__doc__},
499 : {NULL, NULL} /* sentinel */
500 : };
501 :
502 : static PyObject *
503 0 : SHA256_get_block_size(PyObject *self, void *closure)
504 : {
505 0 : return PyLong_FromLong(SHA_BLOCKSIZE);
506 : }
507 :
508 : static PyObject *
509 0 : SHA256_get_name(PyObject *self, void *closure)
510 : {
511 0 : if (((SHAobject *)self)->digestsize == 32)
512 0 : return PyUnicode_FromStringAndSize("SHA256", 6);
513 : else
514 0 : return PyUnicode_FromStringAndSize("SHA224", 6);
515 : }
516 :
517 : static PyGetSetDef SHA_getseters[] = {
518 : {"block_size",
519 : (getter)SHA256_get_block_size, NULL,
520 : NULL,
521 : NULL},
522 : {"name",
523 : (getter)SHA256_get_name, NULL,
524 : NULL,
525 : NULL},
526 : {NULL} /* Sentinel */
527 : };
528 :
529 : static PyMemberDef SHA_members[] = {
530 : {"digest_size", T_INT, offsetof(SHAobject, digestsize), READONLY, NULL},
531 : {NULL} /* Sentinel */
532 : };
533 :
534 : static PyTypeObject SHA224type = {
535 : PyVarObject_HEAD_INIT(NULL, 0)
536 : "_sha256.sha224", /*tp_name*/
537 : sizeof(SHAobject), /*tp_size*/
538 : 0, /*tp_itemsize*/
539 : /* methods */
540 : SHA_dealloc, /*tp_dealloc*/
541 : 0, /*tp_print*/
542 : 0, /*tp_getattr*/
543 : 0, /*tp_setattr*/
544 : 0, /*tp_reserved*/
545 : 0, /*tp_repr*/
546 : 0, /*tp_as_number*/
547 : 0, /*tp_as_sequence*/
548 : 0, /*tp_as_mapping*/
549 : 0, /*tp_hash*/
550 : 0, /*tp_call*/
551 : 0, /*tp_str*/
552 : 0, /*tp_getattro*/
553 : 0, /*tp_setattro*/
554 : 0, /*tp_as_buffer*/
555 : Py_TPFLAGS_DEFAULT, /*tp_flags*/
556 : 0, /*tp_doc*/
557 : 0, /*tp_traverse*/
558 : 0, /*tp_clear*/
559 : 0, /*tp_richcompare*/
560 : 0, /*tp_weaklistoffset*/
561 : 0, /*tp_iter*/
562 : 0, /*tp_iternext*/
563 : SHA_methods, /* tp_methods */
564 : SHA_members, /* tp_members */
565 : SHA_getseters, /* tp_getset */
566 : };
567 :
568 : static PyTypeObject SHA256type = {
569 : PyVarObject_HEAD_INIT(NULL, 0)
570 : "_sha256.sha256", /*tp_name*/
571 : sizeof(SHAobject), /*tp_size*/
572 : 0, /*tp_itemsize*/
573 : /* methods */
574 : SHA_dealloc, /*tp_dealloc*/
575 : 0, /*tp_print*/
576 : 0, /*tp_getattr*/
577 : 0, /*tp_setattr*/
578 : 0, /*tp_reserved*/
579 : 0, /*tp_repr*/
580 : 0, /*tp_as_number*/
581 : 0, /*tp_as_sequence*/
582 : 0, /*tp_as_mapping*/
583 : 0, /*tp_hash*/
584 : 0, /*tp_call*/
585 : 0, /*tp_str*/
586 : 0, /*tp_getattro*/
587 : 0, /*tp_setattro*/
588 : 0, /*tp_as_buffer*/
589 : Py_TPFLAGS_DEFAULT, /*tp_flags*/
590 : 0, /*tp_doc*/
591 : 0, /*tp_traverse*/
592 : 0, /*tp_clear*/
593 : 0, /*tp_richcompare*/
594 : 0, /*tp_weaklistoffset*/
595 : 0, /*tp_iter*/
596 : 0, /*tp_iternext*/
597 : SHA_methods, /* tp_methods */
598 : SHA_members, /* tp_members */
599 : SHA_getseters, /* tp_getset */
600 : };
601 :
602 :
603 : /* The single module-level function: new() */
604 :
605 : PyDoc_STRVAR(SHA256_new__doc__,
606 : "Return a new SHA-256 hash object; optionally initialized with a string.");
607 :
608 : static PyObject *
609 0 : SHA256_new(PyObject *self, PyObject *args, PyObject *kwdict)
610 : {
611 : static char *kwlist[] = {"string", NULL};
612 : SHAobject *new;
613 0 : PyObject *data_obj = NULL;
614 : Py_buffer buf;
615 :
616 0 : if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|O:new", kwlist,
617 : &data_obj)) {
618 0 : return NULL;
619 : }
620 :
621 0 : if (data_obj)
622 0 : GET_BUFFER_VIEW_OR_ERROUT(data_obj, &buf);
623 :
624 0 : if ((new = newSHA256object()) == NULL) {
625 0 : if (data_obj)
626 0 : PyBuffer_Release(&buf);
627 0 : return NULL;
628 : }
629 :
630 0 : sha_init(new);
631 :
632 0 : if (PyErr_Occurred()) {
633 0 : Py_DECREF(new);
634 0 : if (data_obj)
635 0 : PyBuffer_Release(&buf);
636 0 : return NULL;
637 : }
638 0 : if (data_obj) {
639 0 : sha_update(new, buf.buf, buf.len);
640 0 : PyBuffer_Release(&buf);
641 : }
642 :
643 0 : return (PyObject *)new;
644 : }
645 :
646 : PyDoc_STRVAR(SHA224_new__doc__,
647 : "Return a new SHA-224 hash object; optionally initialized with a string.");
648 :
649 : static PyObject *
650 0 : SHA224_new(PyObject *self, PyObject *args, PyObject *kwdict)
651 : {
652 : static char *kwlist[] = {"string", NULL};
653 : SHAobject *new;
654 0 : PyObject *data_obj = NULL;
655 : Py_buffer buf;
656 :
657 0 : if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|O:new", kwlist,
658 : &data_obj)) {
659 0 : return NULL;
660 : }
661 :
662 0 : if (data_obj)
663 0 : GET_BUFFER_VIEW_OR_ERROUT(data_obj, &buf);
664 :
665 0 : if ((new = newSHA224object()) == NULL) {
666 0 : if (data_obj)
667 0 : PyBuffer_Release(&buf);
668 0 : return NULL;
669 : }
670 :
671 0 : sha224_init(new);
672 :
673 0 : if (PyErr_Occurred()) {
674 0 : Py_DECREF(new);
675 0 : if (data_obj)
676 0 : PyBuffer_Release(&buf);
677 0 : return NULL;
678 : }
679 0 : if (data_obj) {
680 0 : sha_update(new, buf.buf, buf.len);
681 0 : PyBuffer_Release(&buf);
682 : }
683 :
684 0 : return (PyObject *)new;
685 : }
686 :
687 :
688 : /* List of functions exported by this module */
689 :
690 : static struct PyMethodDef SHA_functions[] = {
691 : {"sha256", (PyCFunction)SHA256_new, METH_VARARGS|METH_KEYWORDS, SHA256_new__doc__},
692 : {"sha224", (PyCFunction)SHA224_new, METH_VARARGS|METH_KEYWORDS, SHA224_new__doc__},
693 : {NULL, NULL} /* Sentinel */
694 : };
695 :
696 :
697 : /* Initialize this module. */
698 :
699 : #define insint(n,v) { PyModule_AddIntConstant(m,n,v); }
700 :
701 :
702 : static struct PyModuleDef _sha256module = {
703 : PyModuleDef_HEAD_INIT,
704 : "_sha256",
705 : NULL,
706 : -1,
707 : SHA_functions,
708 : NULL,
709 : NULL,
710 : NULL,
711 : NULL
712 : };
713 :
714 : PyMODINIT_FUNC
715 0 : PyInit__sha256(void)
716 : {
717 0 : Py_TYPE(&SHA224type) = &PyType_Type;
718 0 : if (PyType_Ready(&SHA224type) < 0)
719 0 : return NULL;
720 0 : Py_TYPE(&SHA256type) = &PyType_Type;
721 0 : if (PyType_Ready(&SHA256type) < 0)
722 0 : return NULL;
723 0 : return PyModule_Create(&_sha256module);
724 : }
|