17db96d56Sopenharmony_ci/* MD5 module */ 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_ci/* This module provides an interface to the MD5 algorithm */ 47db96d56Sopenharmony_ci 57db96d56Sopenharmony_ci/* See below for information about the original code this module was 67db96d56Sopenharmony_ci based upon. Additional work performed by: 77db96d56Sopenharmony_ci 87db96d56Sopenharmony_ci Andrew Kuchling (amk@amk.ca) 97db96d56Sopenharmony_ci Greg Stein (gstein@lyra.org) 107db96d56Sopenharmony_ci Trevor Perrin (trevp@trevp.net) 117db96d56Sopenharmony_ci 127db96d56Sopenharmony_ci Copyright (C) 2005-2007 Gregory P. Smith (greg@krypto.org) 137db96d56Sopenharmony_ci Licensed to PSF under a Contributor Agreement. 147db96d56Sopenharmony_ci 157db96d56Sopenharmony_ci*/ 167db96d56Sopenharmony_ci 177db96d56Sopenharmony_ci/* MD5 objects */ 187db96d56Sopenharmony_ci#ifndef Py_BUILD_CORE_BUILTIN 197db96d56Sopenharmony_ci# define Py_BUILD_CORE_MODULE 1 207db96d56Sopenharmony_ci#endif 217db96d56Sopenharmony_ci 227db96d56Sopenharmony_ci#include "Python.h" 237db96d56Sopenharmony_ci#include "hashlib.h" 247db96d56Sopenharmony_ci#include "pycore_strhex.h" // _Py_strhex() 257db96d56Sopenharmony_ci 267db96d56Sopenharmony_ci/*[clinic input] 277db96d56Sopenharmony_cimodule _md5 287db96d56Sopenharmony_ciclass MD5Type "MD5object *" "&PyType_Type" 297db96d56Sopenharmony_ci[clinic start generated code]*/ 307db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6e5261719957a912]*/ 317db96d56Sopenharmony_ci 327db96d56Sopenharmony_ci/* Some useful types */ 337db96d56Sopenharmony_ci 347db96d56Sopenharmony_ci#if SIZEOF_INT == 4 357db96d56Sopenharmony_citypedef unsigned int MD5_INT32; /* 32-bit integer */ 367db96d56Sopenharmony_citypedef long long MD5_INT64; /* 64-bit integer */ 377db96d56Sopenharmony_ci#else 387db96d56Sopenharmony_ci/* not defined. compilation will die. */ 397db96d56Sopenharmony_ci#endif 407db96d56Sopenharmony_ci 417db96d56Sopenharmony_ci/* The MD5 block size and message digest sizes, in bytes */ 427db96d56Sopenharmony_ci 437db96d56Sopenharmony_ci#define MD5_BLOCKSIZE 64 447db96d56Sopenharmony_ci#define MD5_DIGESTSIZE 16 457db96d56Sopenharmony_ci 467db96d56Sopenharmony_ci/* The structure for storing MD5 info */ 477db96d56Sopenharmony_ci 487db96d56Sopenharmony_cistruct md5_state { 497db96d56Sopenharmony_ci MD5_INT64 length; 507db96d56Sopenharmony_ci MD5_INT32 state[4], curlen; 517db96d56Sopenharmony_ci unsigned char buf[MD5_BLOCKSIZE]; 527db96d56Sopenharmony_ci}; 537db96d56Sopenharmony_ci 547db96d56Sopenharmony_citypedef struct { 557db96d56Sopenharmony_ci PyObject_HEAD 567db96d56Sopenharmony_ci 577db96d56Sopenharmony_ci struct md5_state hash_state; 587db96d56Sopenharmony_ci} MD5object; 597db96d56Sopenharmony_ci 607db96d56Sopenharmony_ci#include "clinic/md5module.c.h" 617db96d56Sopenharmony_ci 627db96d56Sopenharmony_ci/* ------------------------------------------------------------------------ 637db96d56Sopenharmony_ci * 647db96d56Sopenharmony_ci * This code for the MD5 algorithm was noted as public domain. The 657db96d56Sopenharmony_ci * original headers are pasted below. 667db96d56Sopenharmony_ci * 677db96d56Sopenharmony_ci * Several changes have been made to make it more compatible with the 687db96d56Sopenharmony_ci * Python environment and desired interface. 697db96d56Sopenharmony_ci * 707db96d56Sopenharmony_ci */ 717db96d56Sopenharmony_ci 727db96d56Sopenharmony_ci/* LibTomCrypt, modular cryptographic library -- Tom St Denis 737db96d56Sopenharmony_ci * 747db96d56Sopenharmony_ci * LibTomCrypt is a library that provides various cryptographic 757db96d56Sopenharmony_ci * algorithms in a highly modular and flexible manner. 767db96d56Sopenharmony_ci * 777db96d56Sopenharmony_ci * The library is free for all purposes without any express 787db96d56Sopenharmony_ci * guarantee it works. 797db96d56Sopenharmony_ci * 807db96d56Sopenharmony_ci * Tom St Denis, tomstdenis@gmail.com, https://www.libtom.net 817db96d56Sopenharmony_ci */ 827db96d56Sopenharmony_ci 837db96d56Sopenharmony_ci/* rotate the hard way (platform optimizations could be done) */ 847db96d56Sopenharmony_ci#define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) 857db96d56Sopenharmony_ci 867db96d56Sopenharmony_ci/* Endian Neutral macros that work on all platforms */ 877db96d56Sopenharmony_ci 887db96d56Sopenharmony_ci#define STORE32L(x, y) \ 897db96d56Sopenharmony_ci { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ 907db96d56Sopenharmony_ci (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } 917db96d56Sopenharmony_ci 927db96d56Sopenharmony_ci#define LOAD32L(x, y) \ 937db96d56Sopenharmony_ci { x = ((unsigned long)((y)[3] & 255)<<24) | \ 947db96d56Sopenharmony_ci ((unsigned long)((y)[2] & 255)<<16) | \ 957db96d56Sopenharmony_ci ((unsigned long)((y)[1] & 255)<<8) | \ 967db96d56Sopenharmony_ci ((unsigned long)((y)[0] & 255)); } 977db96d56Sopenharmony_ci 987db96d56Sopenharmony_ci#define STORE64L(x, y) \ 997db96d56Sopenharmony_ci { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ 1007db96d56Sopenharmony_ci (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ 1017db96d56Sopenharmony_ci (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ 1027db96d56Sopenharmony_ci (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } 1037db96d56Sopenharmony_ci 1047db96d56Sopenharmony_ci 1057db96d56Sopenharmony_ci/* MD5 macros */ 1067db96d56Sopenharmony_ci 1077db96d56Sopenharmony_ci#define F(x,y,z) (z ^ (x & (y ^ z))) 1087db96d56Sopenharmony_ci#define G(x,y,z) (y ^ (z & (y ^ x))) 1097db96d56Sopenharmony_ci#define H(x,y,z) (x^y^z) 1107db96d56Sopenharmony_ci#define I(x,y,z) (y^(x|(~z))) 1117db96d56Sopenharmony_ci 1127db96d56Sopenharmony_ci#define FF(a,b,c,d,M,s,t) \ 1137db96d56Sopenharmony_ci a = (a + F(b,c,d) + M + t); a = ROLc(a, s) + b; 1147db96d56Sopenharmony_ci 1157db96d56Sopenharmony_ci#define GG(a,b,c,d,M,s,t) \ 1167db96d56Sopenharmony_ci a = (a + G(b,c,d) + M + t); a = ROLc(a, s) + b; 1177db96d56Sopenharmony_ci 1187db96d56Sopenharmony_ci#define HH(a,b,c,d,M,s,t) \ 1197db96d56Sopenharmony_ci a = (a + H(b,c,d) + M + t); a = ROLc(a, s) + b; 1207db96d56Sopenharmony_ci 1217db96d56Sopenharmony_ci#define II(a,b,c,d,M,s,t) \ 1227db96d56Sopenharmony_ci a = (a + I(b,c,d) + M + t); a = ROLc(a, s) + b; 1237db96d56Sopenharmony_ci 1247db96d56Sopenharmony_ci 1257db96d56Sopenharmony_cistatic void md5_compress(struct md5_state *md5, const unsigned char *buf) 1267db96d56Sopenharmony_ci{ 1277db96d56Sopenharmony_ci MD5_INT32 i, W[16], a, b, c, d; 1287db96d56Sopenharmony_ci 1297db96d56Sopenharmony_ci assert(md5 != NULL); 1307db96d56Sopenharmony_ci assert(buf != NULL); 1317db96d56Sopenharmony_ci 1327db96d56Sopenharmony_ci /* copy the state into 512-bits into W[0..15] */ 1337db96d56Sopenharmony_ci for (i = 0; i < 16; i++) { 1347db96d56Sopenharmony_ci LOAD32L(W[i], buf + (4*i)); 1357db96d56Sopenharmony_ci } 1367db96d56Sopenharmony_ci 1377db96d56Sopenharmony_ci /* copy state */ 1387db96d56Sopenharmony_ci a = md5->state[0]; 1397db96d56Sopenharmony_ci b = md5->state[1]; 1407db96d56Sopenharmony_ci c = md5->state[2]; 1417db96d56Sopenharmony_ci d = md5->state[3]; 1427db96d56Sopenharmony_ci 1437db96d56Sopenharmony_ci FF(a,b,c,d,W[0],7,0xd76aa478UL) 1447db96d56Sopenharmony_ci FF(d,a,b,c,W[1],12,0xe8c7b756UL) 1457db96d56Sopenharmony_ci FF(c,d,a,b,W[2],17,0x242070dbUL) 1467db96d56Sopenharmony_ci FF(b,c,d,a,W[3],22,0xc1bdceeeUL) 1477db96d56Sopenharmony_ci FF(a,b,c,d,W[4],7,0xf57c0fafUL) 1487db96d56Sopenharmony_ci FF(d,a,b,c,W[5],12,0x4787c62aUL) 1497db96d56Sopenharmony_ci FF(c,d,a,b,W[6],17,0xa8304613UL) 1507db96d56Sopenharmony_ci FF(b,c,d,a,W[7],22,0xfd469501UL) 1517db96d56Sopenharmony_ci FF(a,b,c,d,W[8],7,0x698098d8UL) 1527db96d56Sopenharmony_ci FF(d,a,b,c,W[9],12,0x8b44f7afUL) 1537db96d56Sopenharmony_ci FF(c,d,a,b,W[10],17,0xffff5bb1UL) 1547db96d56Sopenharmony_ci FF(b,c,d,a,W[11],22,0x895cd7beUL) 1557db96d56Sopenharmony_ci FF(a,b,c,d,W[12],7,0x6b901122UL) 1567db96d56Sopenharmony_ci FF(d,a,b,c,W[13],12,0xfd987193UL) 1577db96d56Sopenharmony_ci FF(c,d,a,b,W[14],17,0xa679438eUL) 1587db96d56Sopenharmony_ci FF(b,c,d,a,W[15],22,0x49b40821UL) 1597db96d56Sopenharmony_ci GG(a,b,c,d,W[1],5,0xf61e2562UL) 1607db96d56Sopenharmony_ci GG(d,a,b,c,W[6],9,0xc040b340UL) 1617db96d56Sopenharmony_ci GG(c,d,a,b,W[11],14,0x265e5a51UL) 1627db96d56Sopenharmony_ci GG(b,c,d,a,W[0],20,0xe9b6c7aaUL) 1637db96d56Sopenharmony_ci GG(a,b,c,d,W[5],5,0xd62f105dUL) 1647db96d56Sopenharmony_ci GG(d,a,b,c,W[10],9,0x02441453UL) 1657db96d56Sopenharmony_ci GG(c,d,a,b,W[15],14,0xd8a1e681UL) 1667db96d56Sopenharmony_ci GG(b,c,d,a,W[4],20,0xe7d3fbc8UL) 1677db96d56Sopenharmony_ci GG(a,b,c,d,W[9],5,0x21e1cde6UL) 1687db96d56Sopenharmony_ci GG(d,a,b,c,W[14],9,0xc33707d6UL) 1697db96d56Sopenharmony_ci GG(c,d,a,b,W[3],14,0xf4d50d87UL) 1707db96d56Sopenharmony_ci GG(b,c,d,a,W[8],20,0x455a14edUL) 1717db96d56Sopenharmony_ci GG(a,b,c,d,W[13],5,0xa9e3e905UL) 1727db96d56Sopenharmony_ci GG(d,a,b,c,W[2],9,0xfcefa3f8UL) 1737db96d56Sopenharmony_ci GG(c,d,a,b,W[7],14,0x676f02d9UL) 1747db96d56Sopenharmony_ci GG(b,c,d,a,W[12],20,0x8d2a4c8aUL) 1757db96d56Sopenharmony_ci HH(a,b,c,d,W[5],4,0xfffa3942UL) 1767db96d56Sopenharmony_ci HH(d,a,b,c,W[8],11,0x8771f681UL) 1777db96d56Sopenharmony_ci HH(c,d,a,b,W[11],16,0x6d9d6122UL) 1787db96d56Sopenharmony_ci HH(b,c,d,a,W[14],23,0xfde5380cUL) 1797db96d56Sopenharmony_ci HH(a,b,c,d,W[1],4,0xa4beea44UL) 1807db96d56Sopenharmony_ci HH(d,a,b,c,W[4],11,0x4bdecfa9UL) 1817db96d56Sopenharmony_ci HH(c,d,a,b,W[7],16,0xf6bb4b60UL) 1827db96d56Sopenharmony_ci HH(b,c,d,a,W[10],23,0xbebfbc70UL) 1837db96d56Sopenharmony_ci HH(a,b,c,d,W[13],4,0x289b7ec6UL) 1847db96d56Sopenharmony_ci HH(d,a,b,c,W[0],11,0xeaa127faUL) 1857db96d56Sopenharmony_ci HH(c,d,a,b,W[3],16,0xd4ef3085UL) 1867db96d56Sopenharmony_ci HH(b,c,d,a,W[6],23,0x04881d05UL) 1877db96d56Sopenharmony_ci HH(a,b,c,d,W[9],4,0xd9d4d039UL) 1887db96d56Sopenharmony_ci HH(d,a,b,c,W[12],11,0xe6db99e5UL) 1897db96d56Sopenharmony_ci HH(c,d,a,b,W[15],16,0x1fa27cf8UL) 1907db96d56Sopenharmony_ci HH(b,c,d,a,W[2],23,0xc4ac5665UL) 1917db96d56Sopenharmony_ci II(a,b,c,d,W[0],6,0xf4292244UL) 1927db96d56Sopenharmony_ci II(d,a,b,c,W[7],10,0x432aff97UL) 1937db96d56Sopenharmony_ci II(c,d,a,b,W[14],15,0xab9423a7UL) 1947db96d56Sopenharmony_ci II(b,c,d,a,W[5],21,0xfc93a039UL) 1957db96d56Sopenharmony_ci II(a,b,c,d,W[12],6,0x655b59c3UL) 1967db96d56Sopenharmony_ci II(d,a,b,c,W[3],10,0x8f0ccc92UL) 1977db96d56Sopenharmony_ci II(c,d,a,b,W[10],15,0xffeff47dUL) 1987db96d56Sopenharmony_ci II(b,c,d,a,W[1],21,0x85845dd1UL) 1997db96d56Sopenharmony_ci II(a,b,c,d,W[8],6,0x6fa87e4fUL) 2007db96d56Sopenharmony_ci II(d,a,b,c,W[15],10,0xfe2ce6e0UL) 2017db96d56Sopenharmony_ci II(c,d,a,b,W[6],15,0xa3014314UL) 2027db96d56Sopenharmony_ci II(b,c,d,a,W[13],21,0x4e0811a1UL) 2037db96d56Sopenharmony_ci II(a,b,c,d,W[4],6,0xf7537e82UL) 2047db96d56Sopenharmony_ci II(d,a,b,c,W[11],10,0xbd3af235UL) 2057db96d56Sopenharmony_ci II(c,d,a,b,W[2],15,0x2ad7d2bbUL) 2067db96d56Sopenharmony_ci II(b,c,d,a,W[9],21,0xeb86d391UL) 2077db96d56Sopenharmony_ci 2087db96d56Sopenharmony_ci md5->state[0] = md5->state[0] + a; 2097db96d56Sopenharmony_ci md5->state[1] = md5->state[1] + b; 2107db96d56Sopenharmony_ci md5->state[2] = md5->state[2] + c; 2117db96d56Sopenharmony_ci md5->state[3] = md5->state[3] + d; 2127db96d56Sopenharmony_ci} 2137db96d56Sopenharmony_ci 2147db96d56Sopenharmony_ci 2157db96d56Sopenharmony_ci/** 2167db96d56Sopenharmony_ci Initialize the hash state 2177db96d56Sopenharmony_ci @param md5 The hash state you wish to initialize 2187db96d56Sopenharmony_ci*/ 2197db96d56Sopenharmony_cistatic void 2207db96d56Sopenharmony_cimd5_init(struct md5_state *md5) 2217db96d56Sopenharmony_ci{ 2227db96d56Sopenharmony_ci assert(md5 != NULL); 2237db96d56Sopenharmony_ci md5->state[0] = 0x67452301UL; 2247db96d56Sopenharmony_ci md5->state[1] = 0xefcdab89UL; 2257db96d56Sopenharmony_ci md5->state[2] = 0x98badcfeUL; 2267db96d56Sopenharmony_ci md5->state[3] = 0x10325476UL; 2277db96d56Sopenharmony_ci md5->curlen = 0; 2287db96d56Sopenharmony_ci md5->length = 0; 2297db96d56Sopenharmony_ci} 2307db96d56Sopenharmony_ci 2317db96d56Sopenharmony_ci/** 2327db96d56Sopenharmony_ci Process a block of memory though the hash 2337db96d56Sopenharmony_ci @param md5 The hash state 2347db96d56Sopenharmony_ci @param in The data to hash 2357db96d56Sopenharmony_ci @param inlen The length of the data (octets) 2367db96d56Sopenharmony_ci*/ 2377db96d56Sopenharmony_cistatic void 2387db96d56Sopenharmony_cimd5_process(struct md5_state *md5, const unsigned char *in, Py_ssize_t inlen) 2397db96d56Sopenharmony_ci{ 2407db96d56Sopenharmony_ci Py_ssize_t n; 2417db96d56Sopenharmony_ci 2427db96d56Sopenharmony_ci assert(md5 != NULL); 2437db96d56Sopenharmony_ci assert(in != NULL); 2447db96d56Sopenharmony_ci assert(md5->curlen <= sizeof(md5->buf)); 2457db96d56Sopenharmony_ci 2467db96d56Sopenharmony_ci while (inlen > 0) { 2477db96d56Sopenharmony_ci if (md5->curlen == 0 && inlen >= MD5_BLOCKSIZE) { 2487db96d56Sopenharmony_ci md5_compress(md5, in); 2497db96d56Sopenharmony_ci md5->length += MD5_BLOCKSIZE * 8; 2507db96d56Sopenharmony_ci in += MD5_BLOCKSIZE; 2517db96d56Sopenharmony_ci inlen -= MD5_BLOCKSIZE; 2527db96d56Sopenharmony_ci } else { 2537db96d56Sopenharmony_ci n = Py_MIN(inlen, (Py_ssize_t)(MD5_BLOCKSIZE - md5->curlen)); 2547db96d56Sopenharmony_ci memcpy(md5->buf + md5->curlen, in, (size_t)n); 2557db96d56Sopenharmony_ci md5->curlen += (MD5_INT32)n; 2567db96d56Sopenharmony_ci in += n; 2577db96d56Sopenharmony_ci inlen -= n; 2587db96d56Sopenharmony_ci if (md5->curlen == MD5_BLOCKSIZE) { 2597db96d56Sopenharmony_ci md5_compress(md5, md5->buf); 2607db96d56Sopenharmony_ci md5->length += 8*MD5_BLOCKSIZE; 2617db96d56Sopenharmony_ci md5->curlen = 0; 2627db96d56Sopenharmony_ci } 2637db96d56Sopenharmony_ci } 2647db96d56Sopenharmony_ci } 2657db96d56Sopenharmony_ci} 2667db96d56Sopenharmony_ci 2677db96d56Sopenharmony_ci/** 2687db96d56Sopenharmony_ci Terminate the hash to get the digest 2697db96d56Sopenharmony_ci @param md5 The hash state 2707db96d56Sopenharmony_ci @param out [out] The destination of the hash (16 bytes) 2717db96d56Sopenharmony_ci*/ 2727db96d56Sopenharmony_cistatic void 2737db96d56Sopenharmony_cimd5_done(struct md5_state *md5, unsigned char *out) 2747db96d56Sopenharmony_ci{ 2757db96d56Sopenharmony_ci int i; 2767db96d56Sopenharmony_ci 2777db96d56Sopenharmony_ci assert(md5 != NULL); 2787db96d56Sopenharmony_ci assert(out != NULL); 2797db96d56Sopenharmony_ci assert(md5->curlen < sizeof(md5->buf)); 2807db96d56Sopenharmony_ci 2817db96d56Sopenharmony_ci /* increase the length of the message */ 2827db96d56Sopenharmony_ci md5->length += md5->curlen * 8; 2837db96d56Sopenharmony_ci 2847db96d56Sopenharmony_ci /* append the '1' bit */ 2857db96d56Sopenharmony_ci md5->buf[md5->curlen++] = (unsigned char)0x80; 2867db96d56Sopenharmony_ci 2877db96d56Sopenharmony_ci /* if the length is currently above 56 bytes we append zeros 2887db96d56Sopenharmony_ci * then compress. Then we can fall back to padding zeros and length 2897db96d56Sopenharmony_ci * encoding like normal. 2907db96d56Sopenharmony_ci */ 2917db96d56Sopenharmony_ci if (md5->curlen > 56) { 2927db96d56Sopenharmony_ci while (md5->curlen < 64) { 2937db96d56Sopenharmony_ci md5->buf[md5->curlen++] = (unsigned char)0; 2947db96d56Sopenharmony_ci } 2957db96d56Sopenharmony_ci md5_compress(md5, md5->buf); 2967db96d56Sopenharmony_ci md5->curlen = 0; 2977db96d56Sopenharmony_ci } 2987db96d56Sopenharmony_ci 2997db96d56Sopenharmony_ci /* pad up to 56 bytes of zeroes */ 3007db96d56Sopenharmony_ci while (md5->curlen < 56) { 3017db96d56Sopenharmony_ci md5->buf[md5->curlen++] = (unsigned char)0; 3027db96d56Sopenharmony_ci } 3037db96d56Sopenharmony_ci 3047db96d56Sopenharmony_ci /* store length */ 3057db96d56Sopenharmony_ci STORE64L(md5->length, md5->buf+56); 3067db96d56Sopenharmony_ci md5_compress(md5, md5->buf); 3077db96d56Sopenharmony_ci 3087db96d56Sopenharmony_ci /* copy output */ 3097db96d56Sopenharmony_ci for (i = 0; i < 4; i++) { 3107db96d56Sopenharmony_ci STORE32L(md5->state[i], out+(4*i)); 3117db96d56Sopenharmony_ci } 3127db96d56Sopenharmony_ci} 3137db96d56Sopenharmony_ci 3147db96d56Sopenharmony_ci/* .Source: /cvs/libtom/libtomcrypt/src/hashes/md5.c,v $ */ 3157db96d56Sopenharmony_ci/* .Revision: 1.10 $ */ 3167db96d56Sopenharmony_ci/* .Date: 2007/05/12 14:25:28 $ */ 3177db96d56Sopenharmony_ci 3187db96d56Sopenharmony_ci/* 3197db96d56Sopenharmony_ci * End of copied MD5 code. 3207db96d56Sopenharmony_ci * 3217db96d56Sopenharmony_ci * ------------------------------------------------------------------------ 3227db96d56Sopenharmony_ci */ 3237db96d56Sopenharmony_ci 3247db96d56Sopenharmony_citypedef struct { 3257db96d56Sopenharmony_ci PyTypeObject* md5_type; 3267db96d56Sopenharmony_ci} MD5State; 3277db96d56Sopenharmony_ci 3287db96d56Sopenharmony_cistatic inline MD5State* 3297db96d56Sopenharmony_cimd5_get_state(PyObject *module) 3307db96d56Sopenharmony_ci{ 3317db96d56Sopenharmony_ci void *state = PyModule_GetState(module); 3327db96d56Sopenharmony_ci assert(state != NULL); 3337db96d56Sopenharmony_ci return (MD5State *)state; 3347db96d56Sopenharmony_ci} 3357db96d56Sopenharmony_ci 3367db96d56Sopenharmony_cistatic MD5object * 3377db96d56Sopenharmony_cinewMD5object(MD5State * st) 3387db96d56Sopenharmony_ci{ 3397db96d56Sopenharmony_ci MD5object *md5 = (MD5object *)PyObject_GC_New(MD5object, st->md5_type); 3407db96d56Sopenharmony_ci PyObject_GC_Track(md5); 3417db96d56Sopenharmony_ci return md5; 3427db96d56Sopenharmony_ci} 3437db96d56Sopenharmony_ci 3447db96d56Sopenharmony_ci/* Internal methods for a hash object */ 3457db96d56Sopenharmony_cistatic int 3467db96d56Sopenharmony_ciMD5_traverse(PyObject *ptr, visitproc visit, void *arg) 3477db96d56Sopenharmony_ci{ 3487db96d56Sopenharmony_ci Py_VISIT(Py_TYPE(ptr)); 3497db96d56Sopenharmony_ci return 0; 3507db96d56Sopenharmony_ci} 3517db96d56Sopenharmony_ci 3527db96d56Sopenharmony_cistatic void 3537db96d56Sopenharmony_ciMD5_dealloc(PyObject *ptr) 3547db96d56Sopenharmony_ci{ 3557db96d56Sopenharmony_ci PyTypeObject *tp = Py_TYPE(ptr); 3567db96d56Sopenharmony_ci PyObject_GC_UnTrack(ptr); 3577db96d56Sopenharmony_ci PyObject_GC_Del(ptr); 3587db96d56Sopenharmony_ci Py_DECREF(tp); 3597db96d56Sopenharmony_ci} 3607db96d56Sopenharmony_ci 3617db96d56Sopenharmony_ci 3627db96d56Sopenharmony_ci/* External methods for a hash object */ 3637db96d56Sopenharmony_ci 3647db96d56Sopenharmony_ci/*[clinic input] 3657db96d56Sopenharmony_ciMD5Type.copy 3667db96d56Sopenharmony_ci 3677db96d56Sopenharmony_ci cls: defining_class 3687db96d56Sopenharmony_ci 3697db96d56Sopenharmony_ciReturn a copy of the hash object. 3707db96d56Sopenharmony_ci[clinic start generated code]*/ 3717db96d56Sopenharmony_ci 3727db96d56Sopenharmony_cistatic PyObject * 3737db96d56Sopenharmony_ciMD5Type_copy_impl(MD5object *self, PyTypeObject *cls) 3747db96d56Sopenharmony_ci/*[clinic end generated code: output=bf055e08244bf5ee input=d89087dcfb2a8620]*/ 3757db96d56Sopenharmony_ci{ 3767db96d56Sopenharmony_ci MD5State *st = PyType_GetModuleState(cls); 3777db96d56Sopenharmony_ci 3787db96d56Sopenharmony_ci MD5object *newobj; 3797db96d56Sopenharmony_ci if ((newobj = newMD5object(st))==NULL) 3807db96d56Sopenharmony_ci return NULL; 3817db96d56Sopenharmony_ci 3827db96d56Sopenharmony_ci newobj->hash_state = self->hash_state; 3837db96d56Sopenharmony_ci return (PyObject *)newobj; 3847db96d56Sopenharmony_ci} 3857db96d56Sopenharmony_ci 3867db96d56Sopenharmony_ci/*[clinic input] 3877db96d56Sopenharmony_ciMD5Type.digest 3887db96d56Sopenharmony_ci 3897db96d56Sopenharmony_ciReturn the digest value as a bytes object. 3907db96d56Sopenharmony_ci[clinic start generated code]*/ 3917db96d56Sopenharmony_ci 3927db96d56Sopenharmony_cistatic PyObject * 3937db96d56Sopenharmony_ciMD5Type_digest_impl(MD5object *self) 3947db96d56Sopenharmony_ci/*[clinic end generated code: output=eb691dc4190a07ec input=bc0c4397c2994be6]*/ 3957db96d56Sopenharmony_ci{ 3967db96d56Sopenharmony_ci unsigned char digest[MD5_DIGESTSIZE]; 3977db96d56Sopenharmony_ci struct md5_state temp; 3987db96d56Sopenharmony_ci 3997db96d56Sopenharmony_ci temp = self->hash_state; 4007db96d56Sopenharmony_ci md5_done(&temp, digest); 4017db96d56Sopenharmony_ci return PyBytes_FromStringAndSize((const char *)digest, MD5_DIGESTSIZE); 4027db96d56Sopenharmony_ci} 4037db96d56Sopenharmony_ci 4047db96d56Sopenharmony_ci/*[clinic input] 4057db96d56Sopenharmony_ciMD5Type.hexdigest 4067db96d56Sopenharmony_ci 4077db96d56Sopenharmony_ciReturn the digest value as a string of hexadecimal digits. 4087db96d56Sopenharmony_ci[clinic start generated code]*/ 4097db96d56Sopenharmony_ci 4107db96d56Sopenharmony_cistatic PyObject * 4117db96d56Sopenharmony_ciMD5Type_hexdigest_impl(MD5object *self) 4127db96d56Sopenharmony_ci/*[clinic end generated code: output=17badced1f3ac932 input=b60b19de644798dd]*/ 4137db96d56Sopenharmony_ci{ 4147db96d56Sopenharmony_ci unsigned char digest[MD5_DIGESTSIZE]; 4157db96d56Sopenharmony_ci struct md5_state temp; 4167db96d56Sopenharmony_ci 4177db96d56Sopenharmony_ci /* Get the raw (binary) digest value */ 4187db96d56Sopenharmony_ci temp = self->hash_state; 4197db96d56Sopenharmony_ci md5_done(&temp, digest); 4207db96d56Sopenharmony_ci 4217db96d56Sopenharmony_ci return _Py_strhex((const char*)digest, MD5_DIGESTSIZE); 4227db96d56Sopenharmony_ci} 4237db96d56Sopenharmony_ci 4247db96d56Sopenharmony_ci/*[clinic input] 4257db96d56Sopenharmony_ciMD5Type.update 4267db96d56Sopenharmony_ci 4277db96d56Sopenharmony_ci obj: object 4287db96d56Sopenharmony_ci / 4297db96d56Sopenharmony_ci 4307db96d56Sopenharmony_ciUpdate this hash object's state with the provided string. 4317db96d56Sopenharmony_ci[clinic start generated code]*/ 4327db96d56Sopenharmony_ci 4337db96d56Sopenharmony_cistatic PyObject * 4347db96d56Sopenharmony_ciMD5Type_update(MD5object *self, PyObject *obj) 4357db96d56Sopenharmony_ci/*[clinic end generated code: output=f6ad168416338423 input=6e1efcd9ecf17032]*/ 4367db96d56Sopenharmony_ci{ 4377db96d56Sopenharmony_ci Py_buffer buf; 4387db96d56Sopenharmony_ci 4397db96d56Sopenharmony_ci GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); 4407db96d56Sopenharmony_ci 4417db96d56Sopenharmony_ci md5_process(&self->hash_state, buf.buf, buf.len); 4427db96d56Sopenharmony_ci 4437db96d56Sopenharmony_ci PyBuffer_Release(&buf); 4447db96d56Sopenharmony_ci Py_RETURN_NONE; 4457db96d56Sopenharmony_ci} 4467db96d56Sopenharmony_ci 4477db96d56Sopenharmony_cistatic PyMethodDef MD5_methods[] = { 4487db96d56Sopenharmony_ci MD5TYPE_COPY_METHODDEF 4497db96d56Sopenharmony_ci MD5TYPE_DIGEST_METHODDEF 4507db96d56Sopenharmony_ci MD5TYPE_HEXDIGEST_METHODDEF 4517db96d56Sopenharmony_ci MD5TYPE_UPDATE_METHODDEF 4527db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 4537db96d56Sopenharmony_ci}; 4547db96d56Sopenharmony_ci 4557db96d56Sopenharmony_cistatic PyObject * 4567db96d56Sopenharmony_ciMD5_get_block_size(PyObject *self, void *closure) 4577db96d56Sopenharmony_ci{ 4587db96d56Sopenharmony_ci return PyLong_FromLong(MD5_BLOCKSIZE); 4597db96d56Sopenharmony_ci} 4607db96d56Sopenharmony_ci 4617db96d56Sopenharmony_cistatic PyObject * 4627db96d56Sopenharmony_ciMD5_get_name(PyObject *self, void *closure) 4637db96d56Sopenharmony_ci{ 4647db96d56Sopenharmony_ci return PyUnicode_FromStringAndSize("md5", 3); 4657db96d56Sopenharmony_ci} 4667db96d56Sopenharmony_ci 4677db96d56Sopenharmony_cistatic PyObject * 4687db96d56Sopenharmony_cimd5_get_digest_size(PyObject *self, void *closure) 4697db96d56Sopenharmony_ci{ 4707db96d56Sopenharmony_ci return PyLong_FromLong(MD5_DIGESTSIZE); 4717db96d56Sopenharmony_ci} 4727db96d56Sopenharmony_ci 4737db96d56Sopenharmony_cistatic PyGetSetDef MD5_getseters[] = { 4747db96d56Sopenharmony_ci {"block_size", 4757db96d56Sopenharmony_ci (getter)MD5_get_block_size, NULL, 4767db96d56Sopenharmony_ci NULL, 4777db96d56Sopenharmony_ci NULL}, 4787db96d56Sopenharmony_ci {"name", 4797db96d56Sopenharmony_ci (getter)MD5_get_name, NULL, 4807db96d56Sopenharmony_ci NULL, 4817db96d56Sopenharmony_ci NULL}, 4827db96d56Sopenharmony_ci {"digest_size", 4837db96d56Sopenharmony_ci (getter)md5_get_digest_size, NULL, 4847db96d56Sopenharmony_ci NULL, 4857db96d56Sopenharmony_ci NULL}, 4867db96d56Sopenharmony_ci {NULL} /* Sentinel */ 4877db96d56Sopenharmony_ci}; 4887db96d56Sopenharmony_ci 4897db96d56Sopenharmony_cistatic PyType_Slot md5_type_slots[] = { 4907db96d56Sopenharmony_ci {Py_tp_dealloc, MD5_dealloc}, 4917db96d56Sopenharmony_ci {Py_tp_methods, MD5_methods}, 4927db96d56Sopenharmony_ci {Py_tp_getset, MD5_getseters}, 4937db96d56Sopenharmony_ci {Py_tp_traverse, MD5_traverse}, 4947db96d56Sopenharmony_ci {0,0} 4957db96d56Sopenharmony_ci}; 4967db96d56Sopenharmony_ci 4977db96d56Sopenharmony_cistatic PyType_Spec md5_type_spec = { 4987db96d56Sopenharmony_ci .name = "_md5.md5", 4997db96d56Sopenharmony_ci .basicsize = sizeof(MD5object), 5007db96d56Sopenharmony_ci .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | 5017db96d56Sopenharmony_ci Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC), 5027db96d56Sopenharmony_ci .slots = md5_type_slots 5037db96d56Sopenharmony_ci}; 5047db96d56Sopenharmony_ci 5057db96d56Sopenharmony_ci/* The single module-level function: new() */ 5067db96d56Sopenharmony_ci 5077db96d56Sopenharmony_ci/*[clinic input] 5087db96d56Sopenharmony_ci_md5.md5 5097db96d56Sopenharmony_ci 5107db96d56Sopenharmony_ci string: object(c_default="NULL") = b'' 5117db96d56Sopenharmony_ci * 5127db96d56Sopenharmony_ci usedforsecurity: bool = True 5137db96d56Sopenharmony_ci 5147db96d56Sopenharmony_ciReturn a new MD5 hash object; optionally initialized with a string. 5157db96d56Sopenharmony_ci[clinic start generated code]*/ 5167db96d56Sopenharmony_ci 5177db96d56Sopenharmony_cistatic PyObject * 5187db96d56Sopenharmony_ci_md5_md5_impl(PyObject *module, PyObject *string, int usedforsecurity) 5197db96d56Sopenharmony_ci/*[clinic end generated code: output=587071f76254a4ac input=7a144a1905636985]*/ 5207db96d56Sopenharmony_ci{ 5217db96d56Sopenharmony_ci MD5object *new; 5227db96d56Sopenharmony_ci Py_buffer buf; 5237db96d56Sopenharmony_ci 5247db96d56Sopenharmony_ci if (string) 5257db96d56Sopenharmony_ci GET_BUFFER_VIEW_OR_ERROUT(string, &buf); 5267db96d56Sopenharmony_ci 5277db96d56Sopenharmony_ci MD5State *st = md5_get_state(module); 5287db96d56Sopenharmony_ci if ((new = newMD5object(st)) == NULL) { 5297db96d56Sopenharmony_ci if (string) 5307db96d56Sopenharmony_ci PyBuffer_Release(&buf); 5317db96d56Sopenharmony_ci return NULL; 5327db96d56Sopenharmony_ci } 5337db96d56Sopenharmony_ci 5347db96d56Sopenharmony_ci md5_init(&new->hash_state); 5357db96d56Sopenharmony_ci 5367db96d56Sopenharmony_ci if (PyErr_Occurred()) { 5377db96d56Sopenharmony_ci Py_DECREF(new); 5387db96d56Sopenharmony_ci if (string) 5397db96d56Sopenharmony_ci PyBuffer_Release(&buf); 5407db96d56Sopenharmony_ci return NULL; 5417db96d56Sopenharmony_ci } 5427db96d56Sopenharmony_ci if (string) { 5437db96d56Sopenharmony_ci md5_process(&new->hash_state, buf.buf, buf.len); 5447db96d56Sopenharmony_ci PyBuffer_Release(&buf); 5457db96d56Sopenharmony_ci } 5467db96d56Sopenharmony_ci 5477db96d56Sopenharmony_ci return (PyObject *)new; 5487db96d56Sopenharmony_ci} 5497db96d56Sopenharmony_ci 5507db96d56Sopenharmony_ci 5517db96d56Sopenharmony_ci/* List of functions exported by this module */ 5527db96d56Sopenharmony_ci 5537db96d56Sopenharmony_cistatic struct PyMethodDef MD5_functions[] = { 5547db96d56Sopenharmony_ci _MD5_MD5_METHODDEF 5557db96d56Sopenharmony_ci {NULL, NULL} /* Sentinel */ 5567db96d56Sopenharmony_ci}; 5577db96d56Sopenharmony_ci 5587db96d56Sopenharmony_cistatic int 5597db96d56Sopenharmony_ci_md5_traverse(PyObject *module, visitproc visit, void *arg) 5607db96d56Sopenharmony_ci{ 5617db96d56Sopenharmony_ci MD5State *state = md5_get_state(module); 5627db96d56Sopenharmony_ci Py_VISIT(state->md5_type); 5637db96d56Sopenharmony_ci return 0; 5647db96d56Sopenharmony_ci} 5657db96d56Sopenharmony_ci 5667db96d56Sopenharmony_cistatic int 5677db96d56Sopenharmony_ci_md5_clear(PyObject *module) 5687db96d56Sopenharmony_ci{ 5697db96d56Sopenharmony_ci MD5State *state = md5_get_state(module); 5707db96d56Sopenharmony_ci Py_CLEAR(state->md5_type); 5717db96d56Sopenharmony_ci return 0; 5727db96d56Sopenharmony_ci} 5737db96d56Sopenharmony_ci 5747db96d56Sopenharmony_cistatic void 5757db96d56Sopenharmony_ci_md5_free(void *module) 5767db96d56Sopenharmony_ci{ 5777db96d56Sopenharmony_ci _md5_clear((PyObject *)module); 5787db96d56Sopenharmony_ci} 5797db96d56Sopenharmony_ci 5807db96d56Sopenharmony_ci/* Initialize this module. */ 5817db96d56Sopenharmony_cistatic int 5827db96d56Sopenharmony_cimd5_exec(PyObject *m) 5837db96d56Sopenharmony_ci{ 5847db96d56Sopenharmony_ci MD5State *st = md5_get_state(m); 5857db96d56Sopenharmony_ci 5867db96d56Sopenharmony_ci st->md5_type = (PyTypeObject *)PyType_FromModuleAndSpec( 5877db96d56Sopenharmony_ci m, &md5_type_spec, NULL); 5887db96d56Sopenharmony_ci 5897db96d56Sopenharmony_ci if (st->md5_type == NULL) { 5907db96d56Sopenharmony_ci return -1; 5917db96d56Sopenharmony_ci } 5927db96d56Sopenharmony_ci 5937db96d56Sopenharmony_ci Py_INCREF((PyObject *)st->md5_type); 5947db96d56Sopenharmony_ci if (PyModule_AddObject(m, "MD5Type", (PyObject *)st->md5_type) < 0) { 5957db96d56Sopenharmony_ci Py_DECREF(st->md5_type); 5967db96d56Sopenharmony_ci return -1; 5977db96d56Sopenharmony_ci } 5987db96d56Sopenharmony_ci 5997db96d56Sopenharmony_ci return 0; 6007db96d56Sopenharmony_ci} 6017db96d56Sopenharmony_ci 6027db96d56Sopenharmony_cistatic PyModuleDef_Slot _md5_slots[] = { 6037db96d56Sopenharmony_ci {Py_mod_exec, md5_exec}, 6047db96d56Sopenharmony_ci {0, NULL} 6057db96d56Sopenharmony_ci}; 6067db96d56Sopenharmony_ci 6077db96d56Sopenharmony_ci 6087db96d56Sopenharmony_cistatic struct PyModuleDef _md5module = { 6097db96d56Sopenharmony_ci PyModuleDef_HEAD_INIT, 6107db96d56Sopenharmony_ci .m_name = "_md5", 6117db96d56Sopenharmony_ci .m_size = sizeof(MD5State), 6127db96d56Sopenharmony_ci .m_methods = MD5_functions, 6137db96d56Sopenharmony_ci .m_slots = _md5_slots, 6147db96d56Sopenharmony_ci .m_traverse = _md5_traverse, 6157db96d56Sopenharmony_ci .m_clear = _md5_clear, 6167db96d56Sopenharmony_ci .m_free = _md5_free, 6177db96d56Sopenharmony_ci}; 6187db96d56Sopenharmony_ci 6197db96d56Sopenharmony_ciPyMODINIT_FUNC 6207db96d56Sopenharmony_ciPyInit__md5(void) 6217db96d56Sopenharmony_ci{ 6227db96d56Sopenharmony_ci return PyModuleDef_Init(&_md5module); 6237db96d56Sopenharmony_ci} 624