├── .github └── FUNDING.yml ├── .gitignore ├── CHANGELOG ├── COPYING ├── MANIFEST.in ├── Pyrit-logo.ai ├── Pyrit-logo.png ├── README.md ├── cpyrit ├── __init__.py ├── _cpyrit_cpu.c ├── _cpyrit_cpu.h ├── _cpyrit_cpu_sse2.S ├── config.py ├── cpufeatures.h ├── cpyrit.py ├── network.py ├── pckttools.py ├── storage.py └── util.py ├── modules ├── cpyrit_calpp │ ├── COPYING │ ├── MANIFEST.in │ ├── _cpyrit_calpp.cpp │ ├── _cpyrit_calpp.h │ ├── _cpyrit_calpp_kernel.cpp │ ├── _cpyrit_calpp_kernel_generator.cpp │ ├── convert_optimized.sed │ ├── generate_optimized_kernel │ └── setup.py ├── cpyrit_cuda │ ├── .gitignore │ ├── COPYING │ ├── MANIFEST.in │ ├── _cpyrit_cuda.c │ ├── _cpyrit_cuda.h │ ├── _cpyrit_cudakernel.cu │ └── setup.py └── cpyrit_opencl │ ├── COPYING │ ├── MANIFEST.in │ ├── _cpyrit_oclkernel.cl │ ├── _cpyrit_opencl.c │ ├── _cpyrit_opencl.h │ └── setup.py ├── pyrit ├── pyrit_cli.py ├── setup.py └── test ├── dict.gz ├── test_pyrit.py ├── wpa2psk-2WIRE972.dump.gz ├── wpa2psk-MOM1.dump.gz ├── wpa2psk-Red_Apple.dump.gz ├── wpa2psk-linksys.dump.gz ├── wpapsk-linksys.dump.gz └── wpapsk-virgin_broadband.dump.gz /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: JPaulMora 4 | patreon: JPaulMora 5 | custom: ['https://app.recurrente.com/s/juan-pablo-mora/support-jpaulmora'] 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | Whats new in 0.5.1: 2 | * Fixed missing import (#479 and #481), thanks llazzaro 3 | * PEP8 improvements, thanks llazzaro 4 | * Better arch detection,thanks leitao 5 | * Pyrit CUDA now compiles in OSX 6 | * Updated wiki 7 | 8 | Changes since 0.5.0: 9 | * Added use_CUDA and use_OpenCL in config file 10 | * Improved cores listing and managing 11 | * Updated Wiki and ported to GitHub 12 | * limit_ncpus now disables all CPUs when set to value below 0 13 | * Improve CCMP packet identification, thanks to yannayl 14 | 15 | Changes since 0.4.0: 16 | * Fixed an error in Pyrit server/client mode 17 | 18 | Changes since 0.3.0: 19 | * Added CPyrit-CAL++ 20 | * Added CLI-function 'check_db' 21 | * Added CLI-option '-h' 22 | * Added option to batch-create ESSIDs by reading them for a file 23 | * Complete rework of packet-parsing and handshake detection 24 | * Make default workunit-size configureable (workunit_size) 25 | * Make maximum number of used CPUs configurable (limit_ncpus) 26 | * Use GPU-native bitwise rotation with OpenCL if possible 27 | * Use libpcap to access capture-devices/files 28 | * CUDA-plugin now compatible with Fermi-GPUs 29 | * OpenCL-plugin now builds on MacOS 10.6 30 | * Link with libcrypto instead of libssl 31 | * Fixed CUDA-plugin on MacOS 10.6 32 | * Fixed SSE2-detection on old CPUs 33 | * Fixed database-indices 34 | * Fixed rare IndexError in EAPOLCracker 35 | * Numerous fixes in storage-relay code 36 | * Fix deprecation-warning with sqlalchemy.Binary 37 | * Various API-changes 38 | 39 | Changes since 0.2.4: 40 | * Removed CPyrit-Stream in favor of OpenCL 41 | * Added Network-Core 42 | * Added SQL-Storage 43 | * Added Remote-Storage 44 | * Added CLI-function 'stripLive' 45 | * Added CLI-function 'attack_cowpatty' 46 | * Added CLI-function 'import_unique_passwords' 47 | * Added CLI-function 'relay' 48 | * Added CLI-function 'serve' 49 | * Added SSE2-support for EAPOLCracker 50 | * Added output-option to all attack-modes 51 | * Fixed EAPOLCracker picking the wrong KeyScheme 52 | * Improved lazy-loading of files 53 | * Sourcecode now almost completely PEP8-compliant 54 | 55 | Changes since 0.2.3: 56 | * Added module 'pckttools' 57 | * Added CLI-function 'analyze' 58 | * Added CLI-function 'attack_batch' 59 | * Added CLI-function 'attack_db' 60 | * Added CLI-function 'attack_passthrough' 61 | * Added CLI-function 'strip' 62 | * Fixed SSE2 on MacOS 63 | * Fixed SSE2 with SELinux 64 | * Fixed handling of passwords containing NULLs 65 | * Improved 'benchmark' 66 | * Most functions can now handle gzip-compressed files (-f) 67 | 68 | Changes since 0.2.2: 69 | * Added docstrings 70 | * Added CLI-function 'delete_essid' 71 | * Added CLI-function 'verify' 72 | * Added CLI-function 'selftest' 73 | * Added Core for OpenCL 74 | * Added SSE2-path to CPU-Core 75 | * Fixed 'CUDA_ERROR_INVALID_IMAGE' when using CUDA 2.2 76 | * Fixed process exit codes 77 | * Improved scheduling between client and hardware 78 | * Improved storage-code 79 | * Improved performance for almost all CLI-functions 80 | * Builds from SVN-directories now carry their revision-number 81 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include CHANGELOG 2 | include COPYING 3 | include README 4 | include MANIFEST.in 5 | include cpyrit/_cpyrit_cpu.h 6 | include cpyrit/cpufeatures.h 7 | include test/dict.gz 8 | include test/wpa2psk-linksys.dump.gz 9 | include test/wpapsk-linksys.dump.gz 10 | include test/wpa2psk-MOM1.dump.gz 11 | include test/wpa2psk-2WIRE972.dump.gz 12 | include test/wpapsk-virgin_broadband.dump.gz 13 | include test/wpa2psk-Red_Apple.dump.gz 14 | include test/test_pyrit.py 15 | -------------------------------------------------------------------------------- /Pyrit-logo.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JPaulMora/Pyrit/b0a0dce7a000e51ef2f76684d3de2a41cd93d848/Pyrit-logo.ai -------------------------------------------------------------------------------- /Pyrit-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JPaulMora/Pyrit/b0a0dce7a000e51ef2f76684d3de2a41cd93d848/Pyrit-logo.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Please Read 2 | 3 | Pyrit is old, is outdated and it's still Python2 I am currently attempting to rewrite it from scratch, so thanks for all the stars but remember to keep an eye for Python3 version. 4 | 5 | # Pyrit # 6 | 7 | ![Pyrit logo](https://github.com/JPaulMora/Pyrit/blob/master/Pyrit-logo.png) 8 | 9 | 10 | Pyrit allows you to create massive databases of pre-computed [WPA/WPA2-PSK](https://secure.wikimedia.org/wikipedia/en/wiki/Wi-Fi_Protected_Access) authentication phase in a space-time-tradeoff. 11 | By using the computational power of Multi-Core CPUs and other platforms through [ATI-Stream](http://ati.amd.com/technology/streamcomputing/),[Nvidia CUDA](http://www.nvidia.com/object/cuda_home_new.html) and [OpenCL](http://www.khronos.org/opencl/), 12 | it is currently by far the most powerful attack against one of the world's most used security-protocols. 13 | 14 | WPA/WPA2-PSK is a subset of [IEEE 802.11 WPA/WPA2](https://secure.wikimedia.org/wikipedia/en/wiki/Wi-Fi_Protected_Access) that skips the complex task of key distribution and client authentication by assigning every participating party the same _pre shared key_. 15 | This _master key_ is derived from a password which the administrating user has to pre-configure e.g. on his laptop and the Access Point. When the laptop creates a connection to the Access Point, a new _session key_ is derived from the _master key_ to encrypt and authenticate following traffic. 16 | The "shortcut" of using a single _master key_ instead of _per-user keys_ eases deployment of WPA/WPA2-protected networks for home- and small-office-use at the cost of making the protocol vulnerable to brute-force-attacks against it's key negotiation phase; 17 | it allows to ultimately reveal the password that protects the network. This vulnerability has to be considered exceptionally disastrous as the protocol allows much of the key derivation to be pre-computed, making simple brute-force-attacks even more alluring to the attacker. 18 | For more background see [this article](http://pyrit.wordpress.com/the-twilight-of-wi-fi-protected-access/) on the project's [blog](http://pyrit.wordpress.com) *_(Outdated)_*. 19 | 20 | The author does not encourage or support using _Pyrit_ for the infringement of peoples' communication-privacy. 21 | The exploration and realization of the technology discussed here motivate as a purpose of their own; this is documented by the open development, 22 | strictly sourcecode-based distribution and 'copyleft'-licensing. 23 | 24 | _Pyrit_ is free software - free as in freedom. Everyone can inspect, copy or modify it and share derived work under the GNU General Public License v3+. 25 | It compiles and executes on a wide variety of platforms including FreeBSD, MacOS X and Linux as operation-system and x86-, alpha-, arm-, hppa-, mips-, powerpc-, s390 and sparc-processors. 26 | 27 | 28 | Attacking WPA/WPA2 by brute-force boils down to to computing _Pairwise Master Keys_ as fast as possible. 29 | Every _Pairwise Master Key_ is 'worth' exactly one megabyte of data getting pushed through [PBKDF2](http://en.wikipedia.org/wiki/PBKDF2)-[HMAC](http://en.wikipedia.org/wiki/Hmac)-[SHA1](http://en.wikipedia.org/wiki/SHA_hash_functions). 30 | In turn, computing 10.000 PMKs per second is equivalent to hashing 9,8 gigabyte of data with [SHA1](http://en.wikipedia.org/wiki/SHA_hash_functions) in one second. 31 | 32 | 33 | These are examples of how multiple computational nodes can access a single storage server over various ways provided by Pyrit: 34 | 35 | * A single storage (e.g. a MySQL-server) 36 | * A local network that can access the storage-server directly and provide four computational nodes on various levels with only one node actually accessing the storage server itself. 37 | * Another, untrusted network can access the storage through Pyrit's RPC-interface and provides three computional nodes, two of which actually access the RPC-interface. 38 | 39 | # What's new # 40 | 41 | * Fixed #479 and #481 42 | * Pyrit CUDA now compiles in OSX with Toolkit 7.5 43 | * Added use_CUDA and use_OpenCL in config file 44 | * Improved cores listing and managing 45 | * limit_ncpus now disables all CPUs when set to value <= 0 46 | * Improve CCMP packet identification, thanks to yannayl 47 | 48 | See [CHANGELOG](https://github.com/JPaulMora/Pyrit/blob/master/CHANGELOG) file for a better description. 49 | 50 | 51 | # How to use # 52 | 53 | _Pyrit_ compiles and runs fine on Linux, MacOS X and BSD. I don't care about Windows; drop me a line (read: patch) if you make _Pyrit_ work without copying half of GNU ... 54 | A guide for installing _Pyrit_ on your system can be found in the [wiki](https://github.com/JPaulMora/Pyrit/wiki). There is also a [Tutorial](https://github.com/JPaulMora/Pyrit/wiki/Usage) and a [reference manual](https://github.com/JPaulMora/Pyrit/wiki/ReferenceManual) for the commandline-client. 55 | 56 | 57 | # How to participate # 58 | 59 | You may want to read [this wiki-entry](https://github.com/JPaulMora/Pyrit/wiki/ExtendPyrit) if interested in porting Pyrit to new hardware-platform. 60 | Contributions or bug reports you should [submit an Issue] (https://github.com/JPaulMora/Pyrit/issues). 61 | -------------------------------------------------------------------------------- /cpyrit/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = [] 2 | -------------------------------------------------------------------------------- /cpyrit/_cpyrit_cpu.h: -------------------------------------------------------------------------------- 1 | /* 2 | # 3 | # Copyright 2008-2011, Lukas Lueg, lukas.lueg@gmail.com 4 | # 5 | # This file is part of Pyrit. 6 | # 7 | # Pyrit is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # Pyrit is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Pyrit. If not, see . 19 | */ 20 | 21 | #ifndef CPYRIT 22 | 23 | #define CPYRIT 24 | 25 | #if (defined(__x86_64__)) 26 | #define cpuid(func, ax, bx, cx, dx) \ 27 | __asm__ __volatile__ ("cpuid;":\ 28 | "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) : "a" (func)); 29 | #elif (defined(__i386__)) 30 | #define cpuid(func, ax, bx, cx, dx) \ 31 | __asm__ __volatile__ ("pushl %%ebx; cpuid; movl %%ebx, %1; popl %%ebx":\ 32 | "=a" (ax), "=r" (bx), "=c" (cx), "=d" (dx) : "a" (func)); 33 | #endif 34 | 35 | #define HAVE_AESNI 0x2000000 /* CPUID.01H:ECX.AES[bit 25] */ 36 | #define HAVE_SSE2 0x4000000 /* CPUID.01H:EDX.AES[bit 26] */ 37 | 38 | #define HMAC_MD5_RC4 0 39 | #define HMAC_SHA1_AES 1 40 | 41 | typedef struct { 42 | uint32_t h0[4]; 43 | uint32_t h1[4]; 44 | uint32_t h2[4]; 45 | uint32_t h3[4]; 46 | uint32_t h4[4]; 47 | uint32_t cst[6][4]; 48 | } fourwise_sha1_ctx; 49 | 50 | typedef struct { 51 | uint32_t a[4]; 52 | uint32_t b[4]; 53 | uint32_t c[4]; 54 | uint32_t d[4]; 55 | } fourwise_md5_ctx; 56 | 57 | struct pmk_ctr 58 | { 59 | SHA_CTX ctx_ipad; 60 | SHA_CTX ctx_opad; 61 | uint32_t e1[5]; 62 | uint32_t e2[5]; 63 | }; 64 | 65 | typedef struct 66 | { 67 | PyObject_HEAD 68 | char keyscheme; 69 | unsigned char *pke; 70 | unsigned char keymic[16]; 71 | size_t eapolframe_size; 72 | unsigned char *eapolframe; 73 | } EAPOLCracker; 74 | 75 | struct ccm_nonce 76 | { 77 | unsigned char priority; 78 | unsigned char a2[6]; 79 | unsigned char pn[6]; 80 | }; 81 | 82 | struct A_i 83 | { 84 | unsigned char flags; 85 | struct ccm_nonce nonce; 86 | unsigned short counter; 87 | }; 88 | 89 | typedef struct 90 | { 91 | PyObject_HEAD 92 | unsigned char *pke1; 93 | unsigned char *pke2; 94 | unsigned char S0[6]; 95 | struct A_i A0; 96 | } CCMPCracker; 97 | 98 | typedef struct 99 | { 100 | PyObject_HEAD 101 | } CPUDevice; 102 | 103 | typedef struct 104 | { 105 | PyObject_HEAD 106 | } CowpattyFile; 107 | 108 | typedef struct 109 | { 110 | PyObject_HEAD 111 | unsigned char *buffer, *current_ptr; 112 | Py_ssize_t buffersize; 113 | int current_idx, itemcount; 114 | } CowpattyResult; 115 | 116 | typedef struct 117 | { 118 | PyObject_HEAD 119 | PyObject *device_name; 120 | PyObject *type; 121 | PyObject *datalink_name; 122 | pcap_t *p; 123 | int datalink; 124 | char status; 125 | } PcapDevice; 126 | 127 | #endif /* CPYRIT */ 128 | -------------------------------------------------------------------------------- /cpyrit/_cpyrit_cpu_sse2.S: -------------------------------------------------------------------------------- 1 | /* 2 | # 3 | # Copyright 2009-2011, Lukas Lueg, lukas.lueg@gmail.com 4 | # 5 | # SHA-1 SSE2 Copyright 2008, 2009, Alvaro Salmador, naplam33@msn.com, 6 | # included here with permission, under the licensing terms specified below. 7 | # ported from SHA-1 MMX by Simon Marechal, simon@banquise.net, 8 | # included here with permission, under the licensing terms specified below. 9 | # 10 | # This file is part of Pyrit. 11 | # 12 | # Pyrit is free software: you can redistribute it and/or modify 13 | # it under the terms of the GNU General Public License as published by 14 | # the Free Software Foundation, either version 3 of the License, or 15 | # (at your option) any later version. 16 | # 17 | # Pyrit is distributed in the hope that it will be useful, 18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | # GNU General Public License for more details. 21 | # 22 | # You should have received a copy of the GNU General Public License 23 | # along with Pyrit. If not, see . 24 | # 25 | # Additional permission under GNU GPL version 3 section 7 26 | # 27 | # If you modify this Program, or any covered work, by linking or 28 | # combining it with the OpenSSL project's "OpenSSL" library (or a 29 | # modified version of that library), containing parts covered by 30 | # the terms of OpenSSL/SSLeay license, the licensors of this 31 | # Program grant you additional permission to convey the resulting 32 | # work. Corresponding Source for a non-source form of such a 33 | # combination shall include the source code for the parts of the 34 | # OpenSSL library used as well as that of the covered work. 35 | */ 36 | 37 | #include "cpufeatures.h" 38 | 39 | #ifdef COMPILE_SSE2 40 | 41 | #define ctxa %xmm0 42 | #define ctxb %xmm1 43 | #define ctxc %xmm2 44 | #define ctxd %xmm3 45 | #define ctxe %xmm4 46 | #define tmp1 %xmm5 47 | #define tmp2 %xmm6 48 | #define tmp3 %xmm7 49 | #define tmp4 ctxa 50 | #define tmp5 ctxb 51 | 52 | #ifdef __x86_64__ 53 | #define eax_rdi %rdi 54 | #define ebx_rbx %rbx 55 | #define ecx_rcx %rcx 56 | #define ecx_rdx %rdx 57 | #define edx_rdx %rdx 58 | #define edx_rsi %rsi 59 | #else 60 | #define eax_rdi %eax 61 | #define ebx_rbx %ebx 62 | #define ecx_rcx %ecx 63 | #define ecx_rdx %ecx 64 | #define edx_rdx %edx 65 | #define edx_rsi %edx 66 | #endif 67 | 68 | #define sha1_cst_stage0 4*5*4 + 4*0*4 69 | #define sha1_cst_stage1 4*5*4 + 4*1*4 70 | #define sha1_cst_stage2 4*5*4 + 4*2*4 71 | #define sha1_cst_stage3 4*5*4 + 4*3*4 72 | #define sha1_cst_ff00 4*5*4 + 4*4*4 73 | #define sha1_cst_00ff 4*5*4 + 4*5*4 74 | 75 | #define SHA1_F0(x,y,z) \ 76 | movdqa x, tmp2; \ 77 | movdqa x, tmp1; \ 78 | pand y, tmp2; \ 79 | pandn z, tmp1; \ 80 | por tmp2, tmp1; 81 | 82 | #define SHA1_F1(x,y,z) \ 83 | movdqa z, tmp1; \ 84 | pxor y, tmp1; \ 85 | pxor x, tmp1; 86 | 87 | #define SHA1_F2(x,y,z) \ 88 | movdqa x, tmp1; \ 89 | movdqa x, tmp2; \ 90 | pand y, tmp1; \ 91 | por y, tmp2; \ 92 | pand z, tmp2; \ 93 | por tmp2, tmp1; 94 | 95 | #define SHA1_subRoundX(a, b, c, d, e, f, k, data) \ 96 | f(b,c,d); \ 97 | movdqa a, tmp2; \ 98 | movdqa a, tmp3; \ 99 | paddd tmp1, e; \ 100 | pslld $5, tmp2; \ 101 | psrld $27, tmp3; \ 102 | por tmp3, tmp2; \ 103 | paddd tmp2, e; \ 104 | movdqa b, tmp2; \ 105 | pslld $30, b; \ 106 | paddd k, e; \ 107 | psrld $2, tmp2; \ 108 | por tmp2, b; \ 109 | movdqa (data*16)(edx_rsi), tmp1; \ 110 | movdqa tmp1, tmp2; \ 111 | pand sha1_cst_ff00(eax_rdi), tmp1; \ 112 | pand sha1_cst_00ff(eax_rdi), tmp2; \ 113 | psrld $8, tmp1; \ 114 | pslld $8, tmp2; \ 115 | por tmp2, tmp1; \ 116 | movdqa tmp1, tmp2; \ 117 | psrld $16, tmp1; \ 118 | pslld $16, tmp2; \ 119 | por tmp2, tmp1; \ 120 | movdqa tmp1, (data*16)(ecx_rdx); \ 121 | paddd tmp1, e; 122 | 123 | #define SHA1_subRoundY(a, b, c, d, e, f, k, data) \ 124 | movdqa ((data- 3)*16)(ecx_rdx), tmp1; \ 125 | pxor ((data- 8)*16)(ecx_rdx), tmp1; \ 126 | pxor ((data-14)*16)(ecx_rdx), tmp1; \ 127 | pxor ((data-16)*16)(ecx_rdx), tmp1; \ 128 | movdqa tmp1, tmp2; \ 129 | pslld $1, tmp1; \ 130 | psrld $31, tmp2; \ 131 | por tmp2, tmp1; \ 132 | movdqa tmp1, (data*16)(ecx_rdx); \ 133 | paddd tmp1, e; \ 134 | f(b,c,d); \ 135 | movdqa a, tmp2; \ 136 | movdqa a, tmp3; \ 137 | paddd tmp1, e; \ 138 | pslld $5, tmp2; \ 139 | psrld $27, tmp3; \ 140 | por tmp3, tmp2; \ 141 | paddd tmp2, e; \ 142 | movdqa b, tmp2; \ 143 | pslld $30, b; \ 144 | paddd k, e; \ 145 | psrld $2, tmp2; \ 146 | por tmp2, b; 147 | 148 | #define MD5_F(b, c, d) \ 149 | movapd c, tmp1; \ 150 | pxor d, tmp1; \ 151 | pand b, tmp1; \ 152 | pxor d, tmp1 153 | 154 | #define MD5_G(b, c, d) \ 155 | movapd c, tmp1; \ 156 | pxor b, tmp1; \ 157 | pand d, tmp1; \ 158 | pxor c, tmp1 159 | 160 | #define MD5_H(b, c, d) \ 161 | movapd b, tmp1; \ 162 | pxor c, tmp1; \ 163 | pxor d, tmp1 164 | 165 | #define MD5_I(b, c, d) \ 166 | movapd d, tmp1; \ 167 | pandn tmp2, tmp1; \ 168 | por b, tmp1; \ 169 | pxor c, tmp1; 170 | 171 | #define MD5_subRound(f, a, b, c, d, x, t, s) \ 172 | f(b, c, d); \ 173 | paddd (x * 4*4)(edx_rsi), tmp1; \ 174 | paddd (t * 4*4)(ecx_rdx), a; \ 175 | paddd tmp1, a; \ 176 | movapd a, tmp3; \ 177 | psrld $(32 - s), tmp3; \ 178 | pslld $s, a; \ 179 | por tmp3, a; \ 180 | paddd b, a 181 | 182 | .globl detect_sse2, _detect_sse2;; 183 | .globl sse2_sha1_update, _sse2_sha1_update; 184 | .globl sse2_sha1_finalize, _sse2_sha1_finalize; 185 | .globl sse2_md5_update, _sse2_md5_update 186 | 187 | .text 188 | 189 | // arg 1 (eax) (64bit: rdi): context + constants (4*5*4 + 4*6*4 bytes) 190 | // arg 2 (edx) (64bit: rsi): digests (4*5*4 bytes) 191 | _sse2_sha1_finalize: 192 | sse2_sha1_finalize: 193 | 194 | movdqa 0(eax_rdi), ctxa 195 | movdqa 16(eax_rdi), ctxb 196 | movdqa 32(eax_rdi), ctxc 197 | movdqa 48(eax_rdi), ctxd 198 | movdqa 64(eax_rdi), ctxe 199 | 200 | movdqa sha1_cst_ff00(eax_rdi), tmp3 201 | movdqa ctxa, tmp1 202 | movdqa ctxb, tmp2 203 | pand tmp3, ctxa 204 | pand tmp3, ctxb 205 | movdqa sha1_cst_00ff(eax_rdi), tmp3 206 | pand tmp3, tmp1 207 | pand tmp3, tmp2 208 | psrld $8, ctxa 209 | psrld $8, ctxb 210 | pslld $8, tmp1 211 | pslld $8, tmp2 212 | por tmp1, ctxa 213 | por tmp2, ctxb 214 | movdqa ctxa, tmp1 215 | movdqa ctxb, tmp2 216 | psrld $16, ctxa 217 | psrld $16, ctxb 218 | pslld $16, tmp1 219 | pslld $16, tmp2 220 | por tmp1, ctxa 221 | por tmp2, ctxb 222 | movdqa ctxa, 0(edx_rsi) 223 | movdqa ctxb, 16(edx_rsi) 224 | 225 | movdqa sha1_cst_ff00(eax_rdi), tmp5 226 | movdqa ctxc, tmp1 227 | movdqa ctxd, tmp2 228 | movdqa ctxe, tmp3 229 | pand tmp5, ctxc 230 | pand tmp5, ctxd 231 | pand tmp5, ctxe 232 | movdqa sha1_cst_00ff(eax_rdi), tmp5 233 | pand tmp5, tmp1 234 | pand tmp5, tmp2 235 | pand tmp5, tmp3 236 | psrld $8, ctxc 237 | psrld $8, ctxd 238 | psrld $8, ctxe 239 | pslld $8, tmp1 240 | pslld $8, tmp2 241 | pslld $8, tmp3 242 | por tmp1, ctxc 243 | por tmp2, ctxd 244 | por tmp3, ctxe 245 | movdqa ctxc, tmp1 246 | movdqa ctxd, tmp2 247 | movdqa ctxe, tmp3 248 | psrld $16, ctxc 249 | psrld $16, ctxd 250 | psrld $16, ctxe 251 | pslld $16, tmp1 252 | pslld $16, tmp2 253 | pslld $16, tmp3 254 | por tmp1, ctxc 255 | por tmp2, ctxd 256 | por tmp3, ctxe 257 | 258 | movdqa ctxc, 32(edx_rsi) 259 | movdqa ctxd, 48(edx_rsi) 260 | movdqa ctxe, 64(edx_rsi) 261 | 262 | ret 263 | 264 | // arg 1 (eax) (64bit: rdi): context + constants (4*5*4 + 4*6*4 bytes) 265 | // arg 2 (edx) (64bit: rsi): input data (4*64 bytes) 266 | // arg 3 (ecx) (64bit: rdx): workspace (4*80*4 bytes) 267 | _sse2_sha1_update: 268 | sse2_sha1_update: 269 | 270 | movdqa 0(eax_rdi), ctxa 271 | movdqa 16(eax_rdi), ctxb 272 | movdqa 32(eax_rdi), ctxc 273 | movdqa 48(eax_rdi), ctxd 274 | movdqa 64(eax_rdi), ctxe 275 | 276 | prefetchnta (edx_rsi) 277 | 278 | /* round0 */ 279 | SHA1_subRoundX( ctxa, ctxb, ctxc, ctxd, ctxe, SHA1_F0, sha1_cst_stage0(eax_rdi), 0 ); 280 | SHA1_subRoundX( ctxe, ctxa, ctxb, ctxc, ctxd, SHA1_F0, sha1_cst_stage0(eax_rdi), 1 ); 281 | SHA1_subRoundX( ctxd, ctxe, ctxa, ctxb, ctxc, SHA1_F0, sha1_cst_stage0(eax_rdi), 2 ); 282 | SHA1_subRoundX( ctxc, ctxd, ctxe, ctxa, ctxb, SHA1_F0, sha1_cst_stage0(eax_rdi), 3 ); 283 | SHA1_subRoundX( ctxb, ctxc, ctxd, ctxe, ctxa, SHA1_F0, sha1_cst_stage0(eax_rdi), 4 ); 284 | SHA1_subRoundX( ctxa, ctxb, ctxc, ctxd, ctxe, SHA1_F0, sha1_cst_stage0(eax_rdi), 5 ); 285 | SHA1_subRoundX( ctxe, ctxa, ctxb, ctxc, ctxd, SHA1_F0, sha1_cst_stage0(eax_rdi), 6 ); 286 | SHA1_subRoundX( ctxd, ctxe, ctxa, ctxb, ctxc, SHA1_F0, sha1_cst_stage0(eax_rdi), 7 ); 287 | SHA1_subRoundX( ctxc, ctxd, ctxe, ctxa, ctxb, SHA1_F0, sha1_cst_stage0(eax_rdi), 8 ); 288 | SHA1_subRoundX( ctxb, ctxc, ctxd, ctxe, ctxa, SHA1_F0, sha1_cst_stage0(eax_rdi), 9 ); 289 | SHA1_subRoundX( ctxa, ctxb, ctxc, ctxd, ctxe, SHA1_F0, sha1_cst_stage0(eax_rdi), 10 ); 290 | SHA1_subRoundX( ctxe, ctxa, ctxb, ctxc, ctxd, SHA1_F0, sha1_cst_stage0(eax_rdi), 11 ); 291 | SHA1_subRoundX( ctxd, ctxe, ctxa, ctxb, ctxc, SHA1_F0, sha1_cst_stage0(eax_rdi), 12 ); 292 | SHA1_subRoundX( ctxc, ctxd, ctxe, ctxa, ctxb, SHA1_F0, sha1_cst_stage0(eax_rdi), 13 ); 293 | SHA1_subRoundX( ctxb, ctxc, ctxd, ctxe, ctxa, SHA1_F0, sha1_cst_stage0(eax_rdi), 14 ); 294 | SHA1_subRoundX( ctxa, ctxb, ctxc, ctxd, ctxe, SHA1_F0, sha1_cst_stage0(eax_rdi), 15 ); 295 | SHA1_subRoundY( ctxe, ctxa, ctxb, ctxc, ctxd, SHA1_F0, sha1_cst_stage0(eax_rdi), 16 ); 296 | SHA1_subRoundY( ctxd, ctxe, ctxa, ctxb, ctxc, SHA1_F0, sha1_cst_stage0(eax_rdi), 17 ); 297 | SHA1_subRoundY( ctxc, ctxd, ctxe, ctxa, ctxb, SHA1_F0, sha1_cst_stage0(eax_rdi), 18 ); 298 | SHA1_subRoundY( ctxb, ctxc, ctxd, ctxe, ctxa, SHA1_F0, sha1_cst_stage0(eax_rdi), 19 ); 299 | 300 | /* round1 */ 301 | SHA1_subRoundY( ctxa, ctxb, ctxc, ctxd, ctxe, SHA1_F1, sha1_cst_stage1(eax_rdi), 20 ); 302 | SHA1_subRoundY( ctxe, ctxa, ctxb, ctxc, ctxd, SHA1_F1, sha1_cst_stage1(eax_rdi), 21 ); 303 | SHA1_subRoundY( ctxd, ctxe, ctxa, ctxb, ctxc, SHA1_F1, sha1_cst_stage1(eax_rdi), 22 ); 304 | SHA1_subRoundY( ctxc, ctxd, ctxe, ctxa, ctxb, SHA1_F1, sha1_cst_stage1(eax_rdi), 23 ); 305 | SHA1_subRoundY( ctxb, ctxc, ctxd, ctxe, ctxa, SHA1_F1, sha1_cst_stage1(eax_rdi), 24 ); 306 | SHA1_subRoundY( ctxa, ctxb, ctxc, ctxd, ctxe, SHA1_F1, sha1_cst_stage1(eax_rdi), 25 ); 307 | SHA1_subRoundY( ctxe, ctxa, ctxb, ctxc, ctxd, SHA1_F1, sha1_cst_stage1(eax_rdi), 26 ); 308 | SHA1_subRoundY( ctxd, ctxe, ctxa, ctxb, ctxc, SHA1_F1, sha1_cst_stage1(eax_rdi), 27 ); 309 | SHA1_subRoundY( ctxc, ctxd, ctxe, ctxa, ctxb, SHA1_F1, sha1_cst_stage1(eax_rdi), 28 ); 310 | SHA1_subRoundY( ctxb, ctxc, ctxd, ctxe, ctxa, SHA1_F1, sha1_cst_stage1(eax_rdi), 29 ); 311 | SHA1_subRoundY( ctxa, ctxb, ctxc, ctxd, ctxe, SHA1_F1, sha1_cst_stage1(eax_rdi), 30 ); 312 | SHA1_subRoundY( ctxe, ctxa, ctxb, ctxc, ctxd, SHA1_F1, sha1_cst_stage1(eax_rdi), 31 ); 313 | SHA1_subRoundY( ctxd, ctxe, ctxa, ctxb, ctxc, SHA1_F1, sha1_cst_stage1(eax_rdi), 32 ); 314 | SHA1_subRoundY( ctxc, ctxd, ctxe, ctxa, ctxb, SHA1_F1, sha1_cst_stage1(eax_rdi), 33 ); 315 | SHA1_subRoundY( ctxb, ctxc, ctxd, ctxe, ctxa, SHA1_F1, sha1_cst_stage1(eax_rdi), 34 ); 316 | SHA1_subRoundY( ctxa, ctxb, ctxc, ctxd, ctxe, SHA1_F1, sha1_cst_stage1(eax_rdi), 35 ); 317 | SHA1_subRoundY( ctxe, ctxa, ctxb, ctxc, ctxd, SHA1_F1, sha1_cst_stage1(eax_rdi), 36 ); 318 | SHA1_subRoundY( ctxd, ctxe, ctxa, ctxb, ctxc, SHA1_F1, sha1_cst_stage1(eax_rdi), 37 ); 319 | SHA1_subRoundY( ctxc, ctxd, ctxe, ctxa, ctxb, SHA1_F1, sha1_cst_stage1(eax_rdi), 38 ); 320 | SHA1_subRoundY( ctxb, ctxc, ctxd, ctxe, ctxa, SHA1_F1, sha1_cst_stage1(eax_rdi), 39 ); 321 | 322 | /* round2 */ 323 | SHA1_subRoundY( ctxa, ctxb, ctxc, ctxd, ctxe, SHA1_F2, sha1_cst_stage2(eax_rdi), 40 ); 324 | SHA1_subRoundY( ctxe, ctxa, ctxb, ctxc, ctxd, SHA1_F2, sha1_cst_stage2(eax_rdi), 41 ); 325 | SHA1_subRoundY( ctxd, ctxe, ctxa, ctxb, ctxc, SHA1_F2, sha1_cst_stage2(eax_rdi), 42 ); 326 | SHA1_subRoundY( ctxc, ctxd, ctxe, ctxa, ctxb, SHA1_F2, sha1_cst_stage2(eax_rdi), 43 ); 327 | SHA1_subRoundY( ctxb, ctxc, ctxd, ctxe, ctxa, SHA1_F2, sha1_cst_stage2(eax_rdi), 44 ); 328 | SHA1_subRoundY( ctxa, ctxb, ctxc, ctxd, ctxe, SHA1_F2, sha1_cst_stage2(eax_rdi), 45 ); 329 | SHA1_subRoundY( ctxe, ctxa, ctxb, ctxc, ctxd, SHA1_F2, sha1_cst_stage2(eax_rdi), 46 ); 330 | SHA1_subRoundY( ctxd, ctxe, ctxa, ctxb, ctxc, SHA1_F2, sha1_cst_stage2(eax_rdi), 47 ); 331 | SHA1_subRoundY( ctxc, ctxd, ctxe, ctxa, ctxb, SHA1_F2, sha1_cst_stage2(eax_rdi), 48 ); 332 | SHA1_subRoundY( ctxb, ctxc, ctxd, ctxe, ctxa, SHA1_F2, sha1_cst_stage2(eax_rdi), 49 ); 333 | SHA1_subRoundY( ctxa, ctxb, ctxc, ctxd, ctxe, SHA1_F2, sha1_cst_stage2(eax_rdi), 50 ); 334 | SHA1_subRoundY( ctxe, ctxa, ctxb, ctxc, ctxd, SHA1_F2, sha1_cst_stage2(eax_rdi), 51 ); 335 | SHA1_subRoundY( ctxd, ctxe, ctxa, ctxb, ctxc, SHA1_F2, sha1_cst_stage2(eax_rdi), 52 ); 336 | SHA1_subRoundY( ctxc, ctxd, ctxe, ctxa, ctxb, SHA1_F2, sha1_cst_stage2(eax_rdi), 53 ); 337 | SHA1_subRoundY( ctxb, ctxc, ctxd, ctxe, ctxa, SHA1_F2, sha1_cst_stage2(eax_rdi), 54 ); 338 | SHA1_subRoundY( ctxa, ctxb, ctxc, ctxd, ctxe, SHA1_F2, sha1_cst_stage2(eax_rdi), 55 ); 339 | SHA1_subRoundY( ctxe, ctxa, ctxb, ctxc, ctxd, SHA1_F2, sha1_cst_stage2(eax_rdi), 56 ); 340 | SHA1_subRoundY( ctxd, ctxe, ctxa, ctxb, ctxc, SHA1_F2, sha1_cst_stage2(eax_rdi), 57 ); 341 | SHA1_subRoundY( ctxc, ctxd, ctxe, ctxa, ctxb, SHA1_F2, sha1_cst_stage2(eax_rdi), 58 ); 342 | SHA1_subRoundY( ctxb, ctxc, ctxd, ctxe, ctxa, SHA1_F2, sha1_cst_stage2(eax_rdi), 59 ); 343 | 344 | /* round3 */ 345 | SHA1_subRoundY( ctxa, ctxb, ctxc, ctxd, ctxe, SHA1_F1, sha1_cst_stage3(eax_rdi), 60 ); 346 | SHA1_subRoundY( ctxe, ctxa, ctxb, ctxc, ctxd, SHA1_F1, sha1_cst_stage3(eax_rdi), 61 ); 347 | SHA1_subRoundY( ctxd, ctxe, ctxa, ctxb, ctxc, SHA1_F1, sha1_cst_stage3(eax_rdi), 62 ); 348 | SHA1_subRoundY( ctxc, ctxd, ctxe, ctxa, ctxb, SHA1_F1, sha1_cst_stage3(eax_rdi), 63 ); 349 | SHA1_subRoundY( ctxb, ctxc, ctxd, ctxe, ctxa, SHA1_F1, sha1_cst_stage3(eax_rdi), 64 ); 350 | SHA1_subRoundY( ctxa, ctxb, ctxc, ctxd, ctxe, SHA1_F1, sha1_cst_stage3(eax_rdi), 65 ); 351 | SHA1_subRoundY( ctxe, ctxa, ctxb, ctxc, ctxd, SHA1_F1, sha1_cst_stage3(eax_rdi), 66 ); 352 | SHA1_subRoundY( ctxd, ctxe, ctxa, ctxb, ctxc, SHA1_F1, sha1_cst_stage3(eax_rdi), 67 ); 353 | SHA1_subRoundY( ctxc, ctxd, ctxe, ctxa, ctxb, SHA1_F1, sha1_cst_stage3(eax_rdi), 68 ); 354 | SHA1_subRoundY( ctxb, ctxc, ctxd, ctxe, ctxa, SHA1_F1, sha1_cst_stage3(eax_rdi), 69 ); 355 | SHA1_subRoundY( ctxa, ctxb, ctxc, ctxd, ctxe, SHA1_F1, sha1_cst_stage3(eax_rdi), 70 ); 356 | SHA1_subRoundY( ctxe, ctxa, ctxb, ctxc, ctxd, SHA1_F1, sha1_cst_stage3(eax_rdi), 71 ); 357 | SHA1_subRoundY( ctxd, ctxe, ctxa, ctxb, ctxc, SHA1_F1, sha1_cst_stage3(eax_rdi), 72 ); 358 | SHA1_subRoundY( ctxc, ctxd, ctxe, ctxa, ctxb, SHA1_F1, sha1_cst_stage3(eax_rdi), 73 ); 359 | SHA1_subRoundY( ctxb, ctxc, ctxd, ctxe, ctxa, SHA1_F1, sha1_cst_stage3(eax_rdi), 74 ); 360 | SHA1_subRoundY( ctxa, ctxb, ctxc, ctxd, ctxe, SHA1_F1, sha1_cst_stage3(eax_rdi), 75 ); 361 | SHA1_subRoundY( ctxe, ctxa, ctxb, ctxc, ctxd, SHA1_F1, sha1_cst_stage3(eax_rdi), 76 ); 362 | SHA1_subRoundY( ctxd, ctxe, ctxa, ctxb, ctxc, SHA1_F1, sha1_cst_stage3(eax_rdi), 77 ); 363 | SHA1_subRoundY( ctxc, ctxd, ctxe, ctxa, ctxb, SHA1_F1, sha1_cst_stage3(eax_rdi), 78 ); 364 | SHA1_subRoundY( ctxb, ctxc, ctxd, ctxe, ctxa, SHA1_F1, sha1_cst_stage3(eax_rdi), 79 ); 365 | 366 | paddd 0(eax_rdi), ctxa 367 | paddd 16(eax_rdi), ctxb 368 | paddd 32(eax_rdi), ctxc 369 | paddd 48(eax_rdi), ctxd 370 | paddd 64(eax_rdi), ctxe 371 | 372 | movdqa ctxa, 0(eax_rdi) 373 | movdqa ctxb, 16(eax_rdi) 374 | movdqa ctxc, 32(eax_rdi) 375 | movdqa ctxd, 48(eax_rdi) 376 | movdqa ctxe, 64(eax_rdi) 377 | 378 | ret 379 | 380 | // arg 1 (eax) (64bit: rdi): context (4*4*4 bytes) 381 | // arg 2 (edx) (64bit: rsi): input data (4*64 bytes) 382 | // arg 3 (ecx) (64bit: rdx): constants (4*64*4 bytes) 383 | _sse2_md5_update: 384 | sse2_md5_update: 385 | 386 | movdqa 0(eax_rdi), ctxa 387 | movdqa 16(eax_rdi), ctxb 388 | movdqa 32(eax_rdi), ctxc 389 | movdqa 48(eax_rdi), ctxd 390 | 391 | prefetchnta (edx_rsi) 392 | 393 | MD5_subRound( MD5_F, ctxa, ctxb, ctxc, ctxd, 0, 0, 7 ) 394 | MD5_subRound( MD5_F, ctxd, ctxa, ctxb, ctxc, 1, 1, 12 ) 395 | MD5_subRound( MD5_F, ctxc, ctxd, ctxa, ctxb, 2, 2, 17 ) 396 | MD5_subRound( MD5_F, ctxb, ctxc, ctxd, ctxa, 3, 3, 22 ) 397 | MD5_subRound( MD5_F, ctxa, ctxb, ctxc, ctxd, 4, 4, 7 ) 398 | MD5_subRound( MD5_F, ctxd, ctxa, ctxb, ctxc, 5, 5, 12 ) 399 | MD5_subRound( MD5_F, ctxc, ctxd, ctxa, ctxb, 6, 6, 17 ) 400 | MD5_subRound( MD5_F, ctxb, ctxc, ctxd, ctxa, 7, 7, 22 ) 401 | MD5_subRound( MD5_F, ctxa, ctxb, ctxc, ctxd, 8, 8, 7 ) 402 | MD5_subRound( MD5_F, ctxd, ctxa, ctxb, ctxc, 9, 9, 12 ) 403 | MD5_subRound( MD5_F, ctxc, ctxd, ctxa, ctxb, 10, 10, 17 ) 404 | MD5_subRound( MD5_F, ctxb, ctxc, ctxd, ctxa, 11, 11, 22 ) 405 | MD5_subRound( MD5_F, ctxa, ctxb, ctxc, ctxd, 12, 12, 7 ) 406 | MD5_subRound( MD5_F, ctxd, ctxa, ctxb, ctxc, 13, 13, 12 ) 407 | MD5_subRound( MD5_F, ctxc, ctxd, ctxa, ctxb, 14, 14, 17 ) 408 | MD5_subRound( MD5_F, ctxb, ctxc, ctxd, ctxa, 15, 15, 22 ) 409 | 410 | MD5_subRound( MD5_G, ctxa, ctxb, ctxc, ctxd, 1, 16, 5 ) 411 | MD5_subRound( MD5_G, ctxd, ctxa, ctxb, ctxc, 6, 17, 9 ) 412 | MD5_subRound( MD5_G, ctxc, ctxd, ctxa, ctxb, 11, 18, 14 ) 413 | MD5_subRound( MD5_G, ctxb, ctxc, ctxd, ctxa, 0, 19, 20 ) 414 | MD5_subRound( MD5_G, ctxa, ctxb, ctxc, ctxd, 5, 20, 5 ) 415 | MD5_subRound( MD5_G, ctxd, ctxa, ctxb, ctxc, 10, 21, 9 ) 416 | MD5_subRound( MD5_G, ctxc, ctxd, ctxa, ctxb, 15, 22, 14 ) 417 | MD5_subRound( MD5_G, ctxb, ctxc, ctxd, ctxa, 4, 23, 20 ) 418 | MD5_subRound( MD5_G, ctxa, ctxb, ctxc, ctxd, 9, 24, 5 ) 419 | MD5_subRound( MD5_G, ctxd, ctxa, ctxb, ctxc, 14, 25, 9 ) 420 | MD5_subRound( MD5_G, ctxc, ctxd, ctxa, ctxb, 3, 26, 14 ) 421 | MD5_subRound( MD5_G, ctxb, ctxc, ctxd, ctxa, 8, 27, 20 ) 422 | MD5_subRound( MD5_G, ctxa, ctxb, ctxc, ctxd, 13, 28, 5 ) 423 | MD5_subRound( MD5_G, ctxd, ctxa, ctxb, ctxc, 2, 29, 9 ) 424 | MD5_subRound( MD5_G, ctxc, ctxd, ctxa, ctxb, 7, 30, 14 ) 425 | MD5_subRound( MD5_G, ctxb, ctxc, ctxd, ctxa, 12, 31, 20 ) 426 | 427 | MD5_subRound( MD5_H, ctxa, ctxb, ctxc, ctxd, 5, 32, 4 ) 428 | MD5_subRound( MD5_H, ctxd, ctxa, ctxb, ctxc, 8, 33, 11 ) 429 | MD5_subRound( MD5_H, ctxc, ctxd, ctxa, ctxb, 11, 34, 16 ) 430 | MD5_subRound( MD5_H, ctxb, ctxc, ctxd, ctxa, 14, 35, 23 ) 431 | MD5_subRound( MD5_H, ctxa, ctxb, ctxc, ctxd, 1, 36, 4 ) 432 | MD5_subRound( MD5_H, ctxd, ctxa, ctxb, ctxc, 4, 37, 11 ) 433 | MD5_subRound( MD5_H, ctxc, ctxd, ctxa, ctxb, 7, 38, 16 ) 434 | MD5_subRound( MD5_H, ctxb, ctxc, ctxd, ctxa, 10, 39, 23 ) 435 | MD5_subRound( MD5_H, ctxa, ctxb, ctxc, ctxd, 13, 40, 4 ) 436 | MD5_subRound( MD5_H, ctxd, ctxa, ctxb, ctxc, 0, 41, 11 ) 437 | MD5_subRound( MD5_H, ctxc, ctxd, ctxa, ctxb, 3, 42, 16 ) 438 | MD5_subRound( MD5_H, ctxb, ctxc, ctxd, ctxa, 6, 43, 23 ) 439 | MD5_subRound( MD5_H, ctxa, ctxb, ctxc, ctxd, 9, 44, 4 ) 440 | MD5_subRound( MD5_H, ctxd, ctxa, ctxb, ctxc, 12, 45, 11 ) 441 | MD5_subRound( MD5_H, ctxc, ctxd, ctxa, ctxb, 15, 46, 16 ) 442 | MD5_subRound( MD5_H, ctxb, ctxc, ctxd, ctxa, 2, 47, 23 ) 443 | 444 | pcmpeqd tmp2, tmp2; // Bitmask for logical NOT in MD5_I 445 | MD5_subRound( MD5_I, ctxa, ctxb, ctxc, ctxd, 0, 48, 6 ) 446 | MD5_subRound( MD5_I, ctxd, ctxa, ctxb, ctxc, 7, 49, 10 ) 447 | MD5_subRound( MD5_I, ctxc, ctxd, ctxa, ctxb, 14, 50, 15 ) 448 | MD5_subRound( MD5_I, ctxb, ctxc, ctxd, ctxa, 5, 51, 21 ) 449 | MD5_subRound( MD5_I, ctxa, ctxb, ctxc, ctxd, 12, 52, 6 ) 450 | MD5_subRound( MD5_I, ctxd, ctxa, ctxb, ctxc, 3, 53, 10 ) 451 | MD5_subRound( MD5_I, ctxc, ctxd, ctxa, ctxb, 10, 54, 15 ) 452 | MD5_subRound( MD5_I, ctxb, ctxc, ctxd, ctxa, 1, 55, 21 ) 453 | MD5_subRound( MD5_I, ctxa, ctxb, ctxc, ctxd, 8, 56, 6 ) 454 | MD5_subRound( MD5_I, ctxd, ctxa, ctxb, ctxc, 15, 57, 10 ) 455 | MD5_subRound( MD5_I, ctxc, ctxd, ctxa, ctxb, 6, 58, 15 ) 456 | MD5_subRound( MD5_I, ctxb, ctxc, ctxd, ctxa, 13, 59, 21 ) 457 | MD5_subRound( MD5_I, ctxa, ctxb, ctxc, ctxd, 4, 60, 6 ) 458 | MD5_subRound( MD5_I, ctxd, ctxa, ctxb, ctxc, 11, 61, 10 ) 459 | MD5_subRound( MD5_I, ctxc, ctxd, ctxa, ctxb, 2, 62, 15 ) 460 | MD5_subRound( MD5_I, ctxb, ctxc, ctxd, ctxa, 9, 63, 21 ) 461 | 462 | paddd 0(eax_rdi), ctxa 463 | paddd 16(eax_rdi), ctxb 464 | paddd 32(eax_rdi), ctxc 465 | paddd 48(eax_rdi), ctxd 466 | 467 | movdqa ctxa, 0(eax_rdi) 468 | movdqa ctxb, 16(eax_rdi) 469 | movdqa ctxc, 32(eax_rdi) 470 | movdqa ctxd, 48(eax_rdi) 471 | 472 | ret 473 | 474 | #endif /* COMPILE_SSE2 */ 475 | 476 | #if defined(__linux__) && defined(__ELF__) 477 | .section .note.GNU-stack,"",%progbits 478 | #endif 479 | -------------------------------------------------------------------------------- /cpyrit/config.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | # 3 | # Copyright 2015, John Mora, johmora12@engineer.com 4 | # Original Work by Lukas Lueg (c) 2008-2011. 5 | # 6 | # This file is part of Pyrit. 7 | # 8 | # Pyrit is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # Pyrit is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with Pyrit. If not, see . 20 | 21 | from __future__ import with_statement 22 | 23 | import os 24 | import sys 25 | 26 | 27 | def default_config(): 28 | config = {'default_storage': 'file://', 29 | 'use_CUDA': 'false', 30 | 'use_OpenCL': 'false', 31 | 'rpc_server': 'false', 32 | 'rpc_announce': 'true', 33 | 'rpc_announce_broadcast': 'false', 34 | 'rpc_knownclients': '', 35 | 'workunit_size': '75000', 36 | 'limit_ncpus': 0} 37 | return config 38 | 39 | 40 | def read_configfile(filename): 41 | config = default_config() 42 | with open(filename, 'rb') as f: 43 | for line in f: 44 | if line.startswith('#') or '=' not in line: 45 | continue 46 | option, value = map(str.strip, line.split('=', 1)) 47 | if option in config: 48 | config[option] = value 49 | else: 50 | print >> sys.stderr, "WARNING: Unknown option '%s' " \ 51 | "in configfile '%s'" % (option, filename) 52 | return config 53 | 54 | 55 | def write_configfile(config, filename): 56 | with open(filename, 'wb') as f: 57 | for option, value in sorted(config.items()): 58 | f.write("%s = %s\n" % (option, value)) 59 | 60 | 61 | configpath = os.path.expanduser(os.path.join('~', '.pyrit')) 62 | default_configfile = os.path.join(configpath, 'config') 63 | 64 | if os.path.exists(default_configfile): 65 | cfg = read_configfile(default_configfile) 66 | else: 67 | cfg = default_config() 68 | if not os.path.exists(configpath): 69 | os.makedirs(configpath) 70 | write_configfile(cfg, default_configfile) 71 | -------------------------------------------------------------------------------- /cpyrit/cpufeatures.h: -------------------------------------------------------------------------------- 1 | /* 2 | # 3 | # Copyright 2008-2011, Lukas Lueg, lukas.lueg@gmail.com 4 | # 5 | # This file is part of Pyrit. 6 | # 7 | # Pyrit is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # Pyrit is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Pyrit. If not, see . 19 | */ 20 | 21 | #ifndef CPUFEATURES 22 | 23 | #define CPUFEATURES 24 | 25 | #if (defined(__i386__) || defined(__x86_64__)) 26 | #define COMPILE_SSE2 27 | #define PUT_BE(n,b,i) \ 28 | { \ 29 | (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ 30 | (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ 31 | (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ 32 | (b)[(i) + 3] = (unsigned char) ( (n) ); \ 33 | } 34 | #endif 35 | 36 | #if (defined(__AES__) && defined(__PCLMUL__)) 37 | #define COMPILE_AESNI 38 | #endif 39 | 40 | #endif /* CPUFEATURES */ 41 | -------------------------------------------------------------------------------- /cpyrit/network.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | # 3 | # Copyright 2015, John Mora, johmora12@engineer.com 4 | # Original Work by Lukas Lueg (c) 2008-2011. 5 | # 6 | # This file is part of Pyrit. 7 | # 8 | # Pyrit is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # Pyrit is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with Pyrit. If not, see . 20 | 21 | from __future__ import with_statement 22 | 23 | import hashlib 24 | import socket 25 | import time 26 | import threading 27 | import xmlrpclib 28 | 29 | import storage 30 | import util 31 | 32 | 33 | class NetworkClient(util.Thread): 34 | 35 | class NetworkGatherer(threading.Thread): 36 | 37 | def __init__(self, client): 38 | threading.Thread.__init__(self) 39 | self.client = client 40 | self.server = xmlrpclib.ServerProxy("http://%s:%s" % \ 41 | client.srv_addr) 42 | self.shallStop = False 43 | self.setDaemon(True) 44 | self.start() 45 | 46 | def run(self): 47 | while not self.shallStop: 48 | #TODO calculate optimal max buffersize 49 | try: 50 | essid, pwbuffer = \ 51 | self.server.gather(self.client.uuid, 5000) 52 | except socket.error: 53 | break 54 | if essid != '' or pwbuffer != '': 55 | pwlist = storage.PAW2_Buffer(pwbuffer.data) 56 | self.client.enqueue(essid, pwlist) 57 | else: 58 | time.sleep(1) 59 | self.client.ping() 60 | 61 | def shutdown(self): 62 | self.shallStop = True 63 | self.join() 64 | 65 | def __init__(self, srv_addr, enqueue_callback, known_uuids): 66 | util.Thread.__init__(self) 67 | self.server = xmlrpclib.ServerProxy("http://%s:%s" % srv_addr) 68 | self.srv_uuid, self.uuid = self.server.register(";".join(known_uuids)) 69 | if not self.uuid: 70 | raise KeyError("Loop detected to %s" % self.srv_uuid) 71 | self.srv_addr = srv_addr 72 | self.enqueue_callback = enqueue_callback 73 | self.cv = threading.Condition() 74 | self.stat_received = self.stat_enqueued = 0 75 | self.stat_scattered = self.stat_sent = 0 76 | self.results = [] 77 | self.lastseen = time.time() 78 | self.setDaemon(True) 79 | 80 | def run(self): 81 | self.gatherer = self.NetworkGatherer(self) 82 | try: 83 | while self.gatherer.isAlive() and self.shallStop is False: 84 | with self.cv: 85 | while len(self.results) == 0 and self.shallStop is False \ 86 | and self.gatherer.isAlive(): 87 | self.cv.wait(1) 88 | if self.shallStop is not False \ 89 | or not self.gatherer.isAlive(): 90 | break 91 | solvedPMKs = self.results.pop(0) 92 | buf = ''.join(solvedPMKs) 93 | md = hashlib.sha1() 94 | md.update(buf) 95 | encoded_buf = xmlrpclib.Binary(md.digest() + buf) 96 | self.server.scatter(self.uuid, encoded_buf) 97 | self.stat_sent += len(solvedPMKs) 98 | self.ping() 99 | finally: 100 | self.gatherer.shutdown() 101 | 102 | def enqueue(self, essid, pwlist): 103 | self.stat_received += len(pwlist) 104 | self.enqueue_callback(self.uuid, (essid, pwlist)) 105 | self.stat_enqueued += len(pwlist) 106 | 107 | def scatter(self, results): 108 | with self.cv: 109 | self.results.append(results) 110 | self.cv.notifyAll() 111 | self.stat_scattered += len(results) 112 | 113 | def ping(self): 114 | self.lastseen = time.time() 115 | 116 | 117 | class NetworkServer(util.Thread): 118 | 119 | def __init__(self): 120 | util.Thread.__init__(self) 121 | import cpyrit 122 | self.cp = cpyrit.CPyrit() 123 | self.clients_lock = threading.Lock() 124 | self.clients = {} 125 | self.pending_clients = [] 126 | self.stat_gathered = self.stat_enqueued = 0 127 | self.stat_scattered = 0 128 | self.enqueue_lock = threading.Lock() 129 | self.setDaemon(True) 130 | self.start() 131 | 132 | def addClient(self, srv_addr): 133 | with self.clients_lock: 134 | if any(c.srv_addr == srv_addr for c in self.clients.itervalues()): 135 | return 136 | known_uuids = set(c.srv_uuid for c in self.clients.itervalues()) 137 | if self.cp.ncore_uuid is not None: 138 | known_uuids.add(self.cp.ncore_uuid) 139 | try: 140 | client = NetworkClient(srv_addr, self.enqueue, known_uuids) 141 | except KeyError: 142 | pass 143 | else: 144 | client.start() 145 | self.clients[client.uuid] = client 146 | 147 | def enqueue(self, uuid, (essid, pwlist)): 148 | with self.clients_lock: 149 | if uuid not in self.clients: 150 | raise KeyError("Client unknown or timed-out") 151 | self.stat_gathered += len(pwlist) 152 | with self.enqueue_lock: 153 | self.pending_clients.append(uuid) 154 | self.cp.enqueue(essid, pwlist) 155 | self.stat_enqueued += len(pwlist) 156 | 157 | def run(self): 158 | while not self.shallStop: 159 | solvedPMKs = self.cp.dequeue(block=True, timeout=3.0) 160 | if solvedPMKs is None: 161 | time.sleep(1) 162 | else: 163 | uuid = self.pending_clients.pop(0) 164 | with self.clients_lock: 165 | if uuid in self.clients: 166 | client = self.clients[uuid] 167 | client.scatter(solvedPMKs) 168 | self.stat_scattered += len(solvedPMKs) 169 | with self.clients_lock: 170 | for client in self.clients.values(): 171 | if not client.isAlive() or \ 172 | time.time() - client.lastseen > 15.0: 173 | del self.clients[client.uuid] 174 | if not self.cp.isAlive(): 175 | self.shallStop == True 176 | raise RuntimeError 177 | 178 | def __contains__(self, srv_addr): 179 | with self.clients_lock: 180 | i = self.clients.itervalues() 181 | return any(c.srv_addr == srv_addr for c in i) 182 | 183 | def __len__(self): 184 | with self.clients_lock: 185 | return len(self.clients) 186 | 187 | def __iter__(self): 188 | with self.clients_lock: 189 | return self.clients.values().__iter__() 190 | 191 | def shutdown(self): 192 | self.shallStop = True 193 | with self.clients_lock: 194 | for client in self.clients.itervalues(): 195 | client.shutdown() 196 | self.join() 197 | 198 | 199 | class NetworkAnnouncer(util.Thread): 200 | """Announce the existence of a server via UDP-unicast and -broadcast""" 201 | 202 | def __init__(self, port=17935, clients=[], broadcast=True): 203 | util.Thread.__init__(self) 204 | self.port = port 205 | self.clients = clients 206 | msg = '\x00'.join(["PyritServerAnnouncement", 207 | '', 208 | str(port)]) 209 | md = hashlib.sha1() 210 | md.update(msg) 211 | self.msg = msg + md.digest() 212 | self.ucast_sckt = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 213 | if broadcast: 214 | self.bcast_sckt = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 215 | self.bcast_sckt.bind(('', 0)) 216 | self.bcast_sckt.setsockopt(socket.SOL_SOCKET, \ 217 | socket.SO_BROADCAST, 1) 218 | else: 219 | self.bcast_sckt = None 220 | self.setDaemon(True) 221 | self.start() 222 | 223 | def run(self): 224 | while self.shallStop is False: 225 | for client in self.clients: 226 | self.ucast_sckt.sendto(self.msg, (client, 17935)) 227 | if self.bcast_sckt: 228 | self.bcast_sckt.sendto(self.msg, ('', 17935)) 229 | time.sleep(1) 230 | 231 | 232 | class NetworkAnnouncementListener(util.Thread): 233 | 234 | def __init__(self): 235 | util.Thread.__init__(self) 236 | self.cv = threading.Condition() 237 | self.servers = [] 238 | self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 239 | self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 240 | self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) 241 | self.sock.bind(('', 17935)) 242 | self.setDaemon(True) 243 | self.start() 244 | 245 | def run(self): 246 | while self.shallStop is False: 247 | buf, (host, port) = self.sock.recvfrom(4096) 248 | if buf.startswith("PyritServerAnnouncement"): 249 | md = hashlib.sha1() 250 | msg = buf[:-md.digest_size] 251 | md.update(msg) 252 | if md.digest() == buf[-md.digest_size:]: 253 | msg_ann, msg_host, msg_port = msg.split('\x00') 254 | if msg_host == '': 255 | addr = (host, msg_port) 256 | else: 257 | addr = (msg_host, msg_port) 258 | with self.cv: 259 | if addr not in self.servers: 260 | self.servers.append(addr) 261 | self.cv.notifyAll() 262 | 263 | def waitForAnnouncement(self, block=True, timeout=None): 264 | t = time.time() 265 | with self.cv: 266 | while True: 267 | if len(self.servers) == 0: 268 | if block: 269 | if timeout is not None: 270 | d = time.time() - t 271 | if d < timeout: 272 | self.cv.wait(d) 273 | else: 274 | return None 275 | else: 276 | self.cv.wait(1) 277 | else: 278 | return None 279 | else: 280 | return self.servers.pop(0) 281 | 282 | def __iter__(self): 283 | return self 284 | 285 | def next(self): 286 | return self.waitForAnnouncement(block=True) 287 | 288 | def shutdown(self): 289 | try: 290 | self.sock.shutdown(socket.SHUT_RDWR) 291 | except socket.error: 292 | pass 293 | util.Thread.shutdown(self) 294 | -------------------------------------------------------------------------------- /cpyrit/util.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | # 3 | # Copyright 2015, John Mora, johmora12@engineer.com 4 | # Original Work by Lukas Lueg (c) 2008-2011. 5 | # 6 | # This file is part of Pyrit. 7 | # 8 | # Pyrit is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # Pyrit is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with Pyrit. If not, see . 20 | 21 | """Various utility- and backend-related classes and data for Pyrit. 22 | 23 | AsyncFileWriter is used for threaded, buffered output. 24 | 25 | CowpattyFile eases reading/writing files in cowpatty's binary format. 26 | 27 | ncpus equals the number of available CPUs in the system. 28 | 29 | Thread is a subclass of threading.Thread that adds a context-manager to 30 | make it 'stoppable'. 31 | 32 | AsyncXMLRPCServer is a stoppable (incl. 'serve_forever') subclass of 33 | SimpleXMLRPCServer. 34 | 35 | PMK_TESTVECTORS has two ESSIDs and ten password:PMK pairs each to verify 36 | local installations. 37 | """ 38 | 39 | from __future__ import with_statement 40 | 41 | import bisect 42 | import io 43 | import gzip 44 | import os 45 | import queue 46 | import random 47 | import socket 48 | import xmlrpc.server 49 | import sys 50 | import struct 51 | import time 52 | import threading 53 | 54 | import _cpyrit_cpu 55 | from _cpyrit_cpu import VERSION, grouper 56 | import config 57 | 58 | __version__ = VERSION 59 | 60 | 61 | def _detect_ncpus(): 62 | """Detect the number of effective CPUs in the system""" 63 | # Snippet taken from ParallelPython 64 | # For Linux, Unix and MacOS 65 | if hasattr(os, "sysconf"): 66 | if "SC_NPROCESSORS_ONLN" in os.sysconf_names: 67 | #Linux and Unix 68 | ncpus = os.sysconf("SC_NPROCESSORS_ONLN") 69 | if isinstance(ncpus, int) and ncpus > 0: 70 | return ncpus 71 | else: 72 | #MacOS X 73 | return int(os.popen2("sysctl -n hw.ncpu")[1].read()) 74 | #for Windows 75 | if "NUMBER_OF_PROCESSORS" in os.environ: 76 | ncpus = int(os.environ["NUMBER_OF_PROCESSORS"]) 77 | if ncpus > 0: 78 | return ncpus 79 | #return the default value 80 | return 1 81 | 82 | 83 | def _limit_ncpus(): 84 | """Limit the number of reported CPUs if so requested""" 85 | detected_ncpus = _detect_ncpus() 86 | try: 87 | limited_ncpus = int(config.cfg['limit_ncpus']) 88 | except ValueError: 89 | raise ValueError("Invalid 'limit_ncpus' in configuration") 90 | if limited_ncpus < 0: 91 | #raise ValueError("Invalid 'limit_ncpus' in configuration") 92 | return 0; 93 | if 0 < limited_ncpus < detected_ncpus: 94 | return limited_ncpus 95 | return detected_ncpus 96 | 97 | 98 | ncpus = _limit_ncpus() 99 | """ Number of effective CPUs (in the moment the module was loaded).""" 100 | 101 | 102 | def str2hex(string): 103 | """Convert a string to it's hex-decimal representation.""" 104 | return ''.join('%02x' % c for c in map(ord, string)) 105 | 106 | 107 | class ScapyImportError(ImportError): 108 | """ ScapyImportError is used to indicate failure to import scapy's modules. 109 | Used to o separate other ImportErrors so code that tries to 110 | import pckttools can continue in case Scapy is simply not installed. 111 | """ 112 | pass 113 | 114 | 115 | class SqlalchemyImportError(ImportError): 116 | """" Indicates that sqlalchemy is not available """ 117 | pass 118 | 119 | 120 | class SortedCollection(object): 121 | '''Sequence sorted by a key function. 122 | 123 | Taken from http://code.activestate.com/recipes/577197-sortedcollection/ 124 | ''' 125 | 126 | def __init__(self, iterable=(), key=None): 127 | self._given_key = key 128 | key = (lambda x: x) if key is None else key 129 | decorated = sorted((key(item), item) for item in iterable) 130 | self._keys = [k for k, item in decorated] 131 | self._items = [item for k, item in decorated] 132 | self._key = key 133 | 134 | def _getkey(self): 135 | return self._key 136 | 137 | def _setkey(self, key): 138 | if key is not self._key: 139 | self.__init__(self._items, key=key) 140 | 141 | def _delkey(self): 142 | self._setkey(None) 143 | 144 | key = property(_getkey, _setkey, _delkey, 'key function') 145 | 146 | def __len__(self): 147 | return len(self._items) 148 | 149 | def __getitem__(self, i): 150 | return self._items[i] 151 | 152 | def __iter__(self): 153 | return iter(self._items) 154 | 155 | def __reversed__(self): 156 | return reversed(self._items) 157 | 158 | def __repr__(self): 159 | return '%s(%r, key=%s)' % ( 160 | self.__class__.__name__, 161 | self._items, 162 | getattr(self._given_key, '__name__', repr(self._given_key)) 163 | ) 164 | 165 | def __reduce__(self): 166 | return self.__class__, (self._items, self._given_key) 167 | 168 | def __contains__(self, item): 169 | k = self._key(item) 170 | i = bisect.bisect_left(self._keys, k) 171 | j = bisect.bisect_right(self._keys, k) 172 | return item in self._items[i:j] 173 | 174 | def index(self, item): 175 | 'Find the position of an item. Raise ValueError if not found.' 176 | k = self._key(item) 177 | i = bisect.bisect_left(self._keys, k) 178 | j = bisect.bisect_right(self._keys, k) 179 | return self._items[i:j].index(item) + i 180 | 181 | def count(self, item): 182 | 'Return number of occurrences of item' 183 | k = self._key(item) 184 | i = bisect.bisect_left(self._keys, k) 185 | j = bisect.bisect_right(self._keys, k) 186 | return self._items[i:j].count(item) 187 | 188 | def insert(self, item): 189 | 'Insert a new item. If equal keys are found, add to the left' 190 | k = self._key(item) 191 | i = bisect.bisect_left(self._keys, k) 192 | self._keys.insert(i, k) 193 | self._items.insert(i, item) 194 | 195 | def insert_right(self, item): 196 | 'Insert a new item. If equal keys are found, add to the right' 197 | k = self._key(item) 198 | i = bisect.bisect_right(self._keys, k) 199 | self._keys.insert(i, k) 200 | self._items.insert(i, item) 201 | 202 | def remove(self, item): 203 | 'Remove first occurence of item. Raise ValueError if not found' 204 | i = self.index(item) 205 | del self._keys[i] 206 | del self._items[i] 207 | 208 | def find(self, k): 209 | 'Return first item with a key == k. Raise ValueError if not found.' 210 | i = bisect.bisect_left(self._keys, k) 211 | if i != len(self) and self._keys[i] == k: 212 | return self._items[i] 213 | raise ValueError('No item found with key equal to: %r' % (k,)) 214 | 215 | def find_le(self, k): 216 | 'Return last item with a key <= k. Raise ValueError if not found.' 217 | i = bisect.bisect_right(self._keys, k) 218 | if i: 219 | return self._items[i-1] 220 | raise ValueError('No item found with key at or below: %r' % (k,)) 221 | 222 | def find_lt(self, k): 223 | 'Return last item with a key < k. Raise ValueError if not found.' 224 | i = bisect.bisect_left(self._keys, k) 225 | if i: 226 | return self._items[i-1] 227 | raise ValueError('No item found with key below: %r' % (k,)) 228 | 229 | def find_ge(self, k): 230 | 'Return first item with a key >= equal to k. Raise ValueError if not found' 231 | i = bisect.bisect_left(self._keys, k) 232 | if i != len(self): 233 | return self._items[i] 234 | raise ValueError('No item found with key at or above: %r' % (k,)) 235 | 236 | def find_gt(self, k): 237 | 'Return first item with a key > k. Raise ValueError if not found' 238 | i = bisect.bisect_right(self._keys, k) 239 | if i != len(self): 240 | return self._items[i] 241 | raise ValueError('No item found with key above: %r' % (k,)) 242 | 243 | 244 | class FileWrapper(object): 245 | """A wrapper for easy stdin/stdout/gzip-handling""" 246 | 247 | def __init__(self, filename, mode='rb'): 248 | if isinstance(filename, str): 249 | if filename == '-': 250 | if 'r' in mode: 251 | self.f = sys.stdin 252 | elif 'w' in mode or 'a' in mode: 253 | self.f = sys.stdout 254 | else: 255 | raise ValueError("Unknown filemode '%s'" % mode) 256 | elif filename.endswith('.gz'): 257 | self.f = gzip.open(filename, mode, 6) 258 | else: 259 | self.f = open(filename, mode) 260 | else: 261 | self.f = filename 262 | self.isclosed = False 263 | 264 | def read(self, size=None): 265 | return self.f.read(size) 266 | 267 | def write(self, buf): 268 | self.f.write(buf) 269 | 270 | def seek(self, offset, whence=None): 271 | self.f.seek(offset, whence) 272 | 273 | def flush(self): 274 | self.f.flush() 275 | 276 | def close(self): 277 | if not self.isclosed: 278 | try: 279 | self.f.close() 280 | finally: 281 | self.isclosed = True 282 | 283 | def readlines(self): 284 | return self.f.readlines() 285 | 286 | def __enter__(self): 287 | return self 288 | 289 | def __exit__(self, type, value, traceback): 290 | self.close() 291 | 292 | def __iter__(self): 293 | return self.f.__iter__() 294 | 295 | 296 | class CowpattyFile(_cpyrit_cpu.CowpattyFile): 297 | """A file-like object to read and write cowpatty-like files.""" 298 | 299 | def __init__(self, filename, mode='r', essid=None): 300 | _cpyrit_cpu.CowpattyFile.__init__(self) 301 | if mode == 'r': 302 | self.f = FileWrapper(filename, 'r') 303 | magic, essidlen, essid = struct.unpack(">4si32s", self.f.read(40)) 304 | if magic != 'APWC': 305 | raise RuntimeError("Not a cowpatty-file.") 306 | if essidlen < 1 or essidlen > 32: 307 | raise ValueError("Invalid ESSID") 308 | self.essid = essid[:essidlen] 309 | elif mode == 'w': 310 | if essid is None: 311 | raise TypeError("ESSID must be specified when writing.") 312 | if len(essid) < 1 or len(essid) > 32: 313 | raise ValueError("Invalid ESSID.") 314 | self.essid = essid 315 | self.f = FileWrapper(filename, 'wb') 316 | self.f.write("APWC\00\00\00" + \ 317 | chr(len(essid)) + essid + \ 318 | '\00' * (32 - len(essid))) 319 | else: 320 | raise RuntimeError("Invalid mode.") 321 | self.tail = '' 322 | self.eof = False 323 | self.mode = mode 324 | 325 | def __iter__(self): 326 | if self.mode != 'r': 327 | raise TypeError("Can't read from write-only file.") 328 | self.f.seek(40, os.SEEK_SET) 329 | self.tail = '' 330 | return self 331 | 332 | def __enter__(self): 333 | return self 334 | 335 | def __exit__(self, type, value, traceback): 336 | self.close() 337 | 338 | def write(self, results): 339 | if self.mode != 'w': 340 | raise TypeError("Can't write to read-only file.") 341 | self.f.write(self.genCowpEntries(results)) 342 | 343 | def close(self): 344 | self.f.close() 345 | 346 | def next(self): 347 | if self.mode != 'r': 348 | raise TypeError("Can't read from write-only file.") 349 | self.tail = self.tail + self.f.read(512 * 1024) 350 | if len(self.tail) == 0: 351 | self.eof = True 352 | raise StopIteration 353 | results, self.tail = self.unpackCowpEntries(self.tail) 354 | return results 355 | 356 | 357 | class AsyncFileWriter(threading.Thread): 358 | """A buffered, asynchronous file-like object. 359 | 360 | Writing to this object will only block if the internal buffer 361 | exceeded it's maximum size. The call to .write() is done in a seperate 362 | thread. 363 | """ 364 | 365 | def __init__(self, f, maxsize=10 * 1024 ** 2): 366 | """Create a instance writing to the given file-like-object and 367 | buffering maxsize before blocking. 368 | """ 369 | threading.Thread.__init__(self) 370 | self.filehndl = FileWrapper(f, 'wb') 371 | self.shallstop = False 372 | self.hasstopped = False 373 | self.maxsize = maxsize 374 | self.excp = None 375 | self.buf = cStringIO.StringIO() 376 | self.cv = threading.Condition() 377 | self.start() 378 | 379 | def __enter__(self): 380 | with self.cv: 381 | if self.shallstop: 382 | raise RuntimeError("Writer has already been closed") 383 | return self 384 | 385 | def __exit__(self, type, value, traceback): 386 | self.close() 387 | 388 | def close(self): 389 | """Stop the writer and wait for it to finish. 390 | 391 | The file handle that was used for initialization is closed. 392 | Exceptions in the writer-thread are re-raised after the writer is 393 | closed. 394 | """ 395 | with self.cv: 396 | self.shallstop = True 397 | self.cv.notifyAll() 398 | while not self.hasstopped: 399 | self.cv.wait() 400 | self.filehndl.close() 401 | self._raise() 402 | 403 | def write(self, data): 404 | """Write data to the buffer, block if necessary. 405 | 406 | Exceptions in the writer-thread are re-raised in the caller's thread 407 | before the data is written. 408 | """ 409 | with self.cv: 410 | self._raise() 411 | while self.buf.tell() > self.maxsize: 412 | self.cv.wait() 413 | if self.shallstop: 414 | raise RuntimeError("Writer has already been closed.") 415 | self.buf.write(data) 416 | self.cv.notifyAll() 417 | 418 | def closeAsync(self): 419 | """Signal the writer to stop and return to caller immediately. 420 | 421 | The file handle that was used for initialization is not closed by a 422 | call to closeAsync(). 423 | The caller must call join() before trying to close the file handle 424 | to prevent this instance from writing to a closed file handle. 425 | Exceptions are not re-raised. 426 | """ 427 | with self.cv: 428 | self.shallstop = True 429 | self.cv.notifyAll() 430 | 431 | def join(self): 432 | """Wait for the writer to stop. 433 | 434 | Exceptions in the writer-thread are re-raised in the caller's thread 435 | after writer has stopped. 436 | """ 437 | with self.cv: 438 | while not self.hasstopped: 439 | self.cv.wait() 440 | self._raise() 441 | 442 | def _raise(self): 443 | # Assumes we hold self.cv 444 | if self.excp: 445 | e = self.excp 446 | self.excp = None 447 | self.shallstop = True 448 | self.cv.notifyAll() 449 | raise e 450 | 451 | def run(self): 452 | try: 453 | while True: 454 | with self.cv: 455 | data = None 456 | if self.buf.tell() == 0: 457 | if self.shallstop: 458 | break 459 | else: 460 | self.cv.wait() 461 | else: 462 | data = self.buf.getvalue() 463 | self.buf = cStringIO.StringIO() 464 | self.cv.notifyAll() 465 | if data: 466 | self.filehndl.write(data) 467 | self.filehndl.flush() 468 | except Exception as e: 469 | # Re-create a 'trans-thread-safe' instance 470 | self.excp = type(e)(str(e)) 471 | finally: 472 | with self.cv: 473 | self.shallstop = self.hasstopped = True 474 | self.cv.notifyAll() 475 | 476 | 477 | class PerformanceCounter(object): 478 | 479 | def __init__(self, window=60.0): 480 | self.window = window 481 | self.datapoints = [[time.time(), 0.0]] 482 | self.total = 0 483 | 484 | def addRelativePoint(self, p): 485 | self.total += p 486 | t = time.time() 487 | if len(self.datapoints) < 1 \ 488 | or t - self.datapoints[-1][0] > 0.5 \ 489 | or self.datapoints[-1][1] == 0.0: 490 | self.datapoints.append([time.time(), p]) 491 | else: 492 | self.datapoints[-1][1] += p 493 | self.__purge() 494 | 495 | def addAbsolutePoint(self, p): 496 | self.addRelativePoint(p - self.total) 497 | 498 | def __iadd__(self, p): 499 | self.addRelativePoint(p) 500 | return self 501 | 502 | def __purge(self): 503 | t = time.time() 504 | if t - self.datapoints[0][0] > self.window: 505 | self.datapoints = filter(lambda x: (t - x[0]) < self.window, \ 506 | self.datapoints) 507 | 508 | def getAvg(self): 509 | self.__purge() 510 | if len(self.datapoints) < 2: 511 | return 0.0 512 | t = self.datapoints[-1][0] - self.datapoints[0][0] 513 | if t > 0.0: 514 | return sum(x[1] for x in self.datapoints) / t 515 | else: 516 | return 0.0 517 | 518 | def __str__(self): 519 | return str(self.value()) 520 | 521 | avg = property(fget=getAvg) 522 | 523 | 524 | class Thread(threading.Thread): 525 | """A stoppable subclass of threading.Thread""" 526 | 527 | def __init__(self): 528 | threading.Thread.__init__(self) 529 | self.shallStop = False 530 | 531 | def __enter__(self): 532 | return self 533 | 534 | def __exit__(self, exc_type, exc_val, exc_tb): 535 | self.shutdown() 536 | 537 | def shutdown(self): 538 | self.shallStop = True 539 | self.join() 540 | 541 | 542 | class AsyncXMLRPCServer(xmlrpc.server.SimpleXMLRPCServer, Thread): 543 | """A stoppable XMLRPCServer 544 | 545 | The main socket is made non-blocking so we can check on 546 | self.shallStop from time to time. 547 | 548 | Sub-classes should add (name:function)-entries to self.methods 549 | """ 550 | 551 | def __init__(self, iface='', port=17934): 552 | xmlrpc.server.SimpleXMLRPCServer.__init__(self, (iface, port), \ 553 | logRequests=False) 554 | Thread.__init__(self) 555 | self.setDaemon(True) 556 | # Make the main socket non-blocking (for accept()) 557 | self.socket.settimeout(1) 558 | self.methods = {} 559 | self.register_instance(self) 560 | 561 | def run(self): 562 | while not self.shallStop: 563 | self.handle_request() 564 | 565 | def get_request(self): 566 | while not self.shallStop: 567 | try: 568 | sock, addr = self.socket.accept() 569 | except socket.timeout: 570 | pass 571 | else: 572 | # Accepted connections are made blocking again 573 | sock.settimeout(None) 574 | return sock, addr 575 | raise socket.timeout("Server has stopped.") 576 | 577 | def serve_forever(self): 578 | while not self.shallStop: 579 | time.sleep(1) 580 | 581 | def shutdown(self): 582 | Thread.shutdown(self) 583 | self.socket.close() 584 | 585 | def _dispatch(self, method, params): 586 | if method not in self.methods: 587 | raise AttributeError 588 | else: 589 | return self.methods[method](*params) 590 | 591 | 592 | PMK_TESTVECTORS = { 593 | 'foo': { 594 | 'soZcEvntHVrGRDIxNaBCyUL': 595 | (247, 210, 173, 42, 68, 187, 144, 253, 145, 93, 126, 250, 16, 188, 596 | 100, 55, 89, 153, 135, 155, 198, 86, 124, 33, 45, 16, 9, 54, 113, 597 | 194, 159, 211), 598 | 'EVuYtpQCAZzBXyWNRGTI': 599 | (5, 48, 168, 39, 10, 98, 151, 201, 8, 80, 23, 138, 19, 24, 24, 50, 600 | 66, 214, 189, 180, 159, 97, 194, 27, 212, 124, 114, 100, 253, 62, 601 | 50, 170), 602 | 'XNuwoiGMnjlkxBHfhyRgZrJItFDqQVESm': 603 | (248, 208, 207, 115, 247, 35, 170, 203, 214, 228, 228, 21, 40, 214, 604 | 165, 0, 98, 194, 136, 62, 110, 253, 69, 205, 67, 215, 119, 109, 605 | 72, 226, 255, 199), 606 | 'bdzPWNTaIol': 607 | (228, 236, 73, 0, 189, 244, 21, 141, 84, 247, 3, 144, 2, 164, 99, 608 | 205, 37, 72, 218, 202, 182, 246, 227, 84, 24, 58, 147, 114, 206, 609 | 221, 40, 127), 610 | 'nwUaVYhRbvsH': 611 | (137, 21, 14, 210, 213, 68, 210, 123, 35, 143, 108, 57, 196, 47, 612 | 62, 161, 150, 35, 165, 197, 154, 61, 76, 14, 212, 88, 125, 234, 613 | 51, 38, 159, 208), 614 | 'gfeuvPBbaDrQHldZzRtXykjFWwAhS': 615 | (88, 127, 99, 35, 137, 177, 147, 161, 244, 32, 197, 233, 178, 1, 616 | 96, 247, 5, 109, 163, 250, 35, 222, 188, 143, 155, 70, 106, 1, 617 | 253, 79, 109, 135), 618 | 'QcbpRkAJerVqHz': 619 | (158, 124, 37, 190, 197, 150, 225, 165, 3, 34, 104, 147, 107, 253, 620 | 233, 127, 33, 239, 75, 11, 169, 187, 127, 171, 187, 165, 166, 187, 621 | 95, 107, 137, 212), 622 | 'EbYJsCNiwXDmHtgkFVacuOv': 623 | (136, 5, 34, 189, 145, 60, 145, 54, 179, 198, 195, 223, 34, 180, 624 | 144, 3, 116, 102, 39, 134, 68, 82, 210, 185, 190, 199, 36, 25, 625 | 136, 152, 0, 111), 626 | 'GpIMrFZwLcqyt': 627 | (28, 144, 175, 10, 200, 46, 253, 227, 219, 35, 98, 208, 220, 11, 628 | 101, 95, 62, 244, 80, 221, 111, 49, 206, 255, 174, 100, 240, 240, 629 | 33, 229, 172, 207), 630 | 'tKxgswlaOMLeZVScGDW': 631 | (237, 62, 117, 60, 38, 107, 65, 166, 113, 174, 196, 221, 128, 227, 632 | 69, 89, 23, 77, 119, 234, 41, 176, 145, 105, 92, 40, 157, 151, 633 | 229, 50, 81, 65)}, 634 | 'bar': { 635 | 'zLwSfveNskZoR': 636 | (38, 93, 196, 77, 112, 65, 163, 197, 249, 158, 180, 107, 231, 140, 637 | 188, 60, 254, 77, 12, 210, 77, 185, 233, 59, 79, 212, 222, 181, 638 | 44, 19, 127, 220), 639 | 'lxsvOCeZXop': 640 | (91, 39, 98, 36, 82, 2, 162, 106, 12, 244, 4, 113, 155, 120, 131, 641 | 133, 11, 209, 12, 12, 240, 213, 203, 156, 129, 148, 28, 64, 31, 642 | 61, 162, 13), 643 | 'tfHrgLLOA': 644 | (110, 72, 123, 80, 222, 233, 150, 54, 40, 99, 205, 155, 177, 157, 645 | 174, 172, 87, 11, 247, 164, 87, 85, 136, 165, 21, 107, 93, 212, 646 | 71, 133, 145, 211), 647 | 'vBgsaSJrlqajUlQJM': 648 | (113, 110, 180, 150, 204, 221, 61, 202, 238, 142, 147, 118, 177, 649 | 196, 65, 79, 102, 47, 179, 80, 175, 95, 251, 35, 227, 220, 47, 650 | 121, 50, 125, 55, 16), 651 | 'daDIHwIMKSUaKWXS': 652 | (33, 87, 211, 99, 26, 70, 123, 19, 254, 229, 148, 97, 252, 182, 3, 653 | 44, 228, 125, 85, 141, 247, 223, 166, 133, 246, 37, 204, 145, 100, 654 | 218, 66, 70), 655 | 'agHOeAjOpK': 656 | (226, 163, 62, 215, 250, 63, 6, 32, 130, 34, 117, 116, 189, 178, 657 | 245, 172, 74, 26, 138, 10, 106, 119, 15, 214, 210, 114, 51, 94, 658 | 254, 57, 81, 200), 659 | 'vRfEagJIzSohxsakj': 660 | (61, 71, 159, 35, 233, 27, 138, 30, 228, 121, 38, 201, 57, 83, 192, 661 | 211, 248, 207, 149, 12, 147, 70, 190, 216, 52, 14, 165, 190, 226, 662 | 180, 62, 210), 663 | 'PuDomzkiwsejblaXs': 664 | (227, 164, 137, 231, 16, 31, 222, 169, 134, 1, 238, 190, 55, 126, 665 | 255, 88, 178, 118, 148, 119, 244, 130, 183, 219, 124, 249, 194, 666 | 96, 94, 159, 163, 185), 667 | 'RErvpNrOsW': 668 | (24, 145, 197, 137, 14, 154, 1, 36, 73, 148, 9, 192, 138, 157, 164, 669 | 81, 47, 184, 41, 75, 225, 34, 71, 153, 59, 253, 127, 179, 242, 670 | 193, 246, 177), 671 | 'ipptbpKkCCep': 672 | (81, 34, 253, 39, 124, 19, 234, 163, 32, 10, 104, 88, 249, 29, 40, 673 | 142, 24, 173, 1, 68, 187, 212, 21, 189, 74, 88, 83, 228, 7, 100, 674 | 23, 244)}} 675 | for essid in PMK_TESTVECTORS: 676 | for pw in PMK_TESTVECTORS[essid]: 677 | PMK_TESTVECTORS[essid][pw] = \ 678 | ''.join(map(chr, PMK_TESTVECTORS[essid][pw])) 679 | del essid 680 | del pw 681 | -------------------------------------------------------------------------------- /modules/cpyrit_calpp/MANIFEST.in: -------------------------------------------------------------------------------- 1 | include COPYING 2 | include README 3 | include generate_optimized_kernel 4 | include convert_optimized.sed 5 | include _cpyrit_calpp.h 6 | include _cpyrit_calpp_kernel_generator.cpp 7 | -------------------------------------------------------------------------------- /modules/cpyrit_calpp/_cpyrit_calpp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | # 3 | # Copyright 2008, 2009, 2010, 2011 Artur Kornacki, hazeman11@gmail.com, Lukas Lueg, lukas.lueg@gmail.com 4 | # 5 | # This file is part of Pyrit. 6 | # 7 | # Pyrit is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # Pyrit is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Pyrit. If not, see . 19 | # 20 | # Additional permission under GNU GPL version 3 section 7 21 | # 22 | # If you modify this Program, or any covered work, by linking or 23 | # combining it with the OpenSSL project's "OpenSSL" library (or a 24 | # modified version of that library), containing parts covered by 25 | # the terms of OpenSSL/SSLeay license, the licensors of this 26 | # Program grant you additional permission to convey the resulting 27 | # work. Corresponding Source for a non-source form of such a 28 | # combination shall include the source code for the parts of the 29 | # OpenSSL library used as well as that of the covered work. 30 | */ 31 | 32 | //#define __DEBUG_PYRIT_PREPROCESS_PERFORMANCE 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #ifdef __DEBUG_PYRIT_PREPROCESS_PERFORMANCE 44 | #include 45 | #include 46 | #endif 47 | 48 | #include "_cpyrit_calpp.h" 49 | 50 | #define _offsetof( type, field ) ( ((uint8_t*)(&((type*)&calDevCount)->field)) - (uint8_t*)&calDevCount ) 51 | 52 | #define BUFFER_SIZE 2 53 | 54 | std::string calpp_create_pmk_kernel( cal::Device& device ); 55 | 56 | struct WorkItem 57 | { 58 | boost::array g_in; 59 | boost::array g_out; 60 | 61 | cal::Event event; 62 | 63 | gpu_inbuffer *in; 64 | gpu_outbuffer *out; 65 | 66 | int size; 67 | 68 | #ifdef __DEBUG_PYRIT_PREPROCESS_PERFORMANCE 69 | boost::posix_time::ptime start_time; 70 | #endif 71 | 72 | WorkItem() : g_in(), g_out(), event(), in(NULL), out(NULL), size(0) 73 | { 74 | } 75 | 76 | WorkItem& 77 | operator=( const WorkItem& v ) 78 | { 79 | in = v.in; 80 | out = v.out; 81 | g_in = v.g_in; 82 | g_out = v.g_out; 83 | event = v.event; 84 | size = v.size; 85 | #ifdef __DEBUG_PYRIT_PREPROCESS_PERFORMANCE 86 | start_time = v.start_time; 87 | #endif 88 | 89 | return *this; 90 | } 91 | }; 92 | 93 | class ThreadUnlocker 94 | { 95 | protected: 96 | PyThreadState *_save; 97 | 98 | public: 99 | ThreadUnlocker() { Py_UNBLOCK_THREADS } 100 | ~ThreadUnlocker() { Py_BLOCK_THREADS } 101 | }; 102 | 103 | extern "C" typedef struct 104 | { 105 | PyObject_HEAD 106 | int dev_idx; 107 | PyObject* dev_name; 108 | 109 | cal::Context dev_context; 110 | cal::Program dev_prog; 111 | cal::Kernel dev_kernel; 112 | cal::CommandQueue dev_queue; 113 | int dev_maxheight; 114 | 115 | boost::array buffer; 116 | int work_count; 117 | 118 | #ifdef __DEBUG_PYRIT_PREPROCESS_PERFORMANCE 119 | boost::uint64_t exec_time; 120 | boost::uint64_t item_count; 121 | boost::posix_time::ptime last_time; 122 | #endif 123 | } CALDevice; 124 | 125 | static int calDevCount; 126 | static cal::Context calContext; 127 | 128 | static int 129 | caldev_init( CALDevice *self, PyObject *args, PyObject *kwds ) 130 | { 131 | int dev_idx; 132 | 133 | self->dev_idx = 0; 134 | self->dev_name = NULL; 135 | new(&self->dev_context) cal::Context(); 136 | new(&self->dev_prog) cal::Program(); 137 | new(&self->dev_kernel) cal::Kernel(); 138 | new(&self->dev_queue) cal::CommandQueue(); 139 | new(&self->buffer) boost::array(); 140 | self->work_count = 0; 141 | #ifdef __DEBUG_PYRIT_PREPROCESS_PERFORMANCE 142 | self->exec_time = 0; 143 | self->item_count = 0; 144 | new(&self->last_time) boost::posix_time::ptime(); 145 | #endif 146 | 147 | if (!PyArg_ParseTuple(args, "i:CALDevice", &dev_idx)) 148 | return -1; 149 | 150 | if (dev_idx < 0 || dev_idx > calDevCount-1) 151 | { 152 | PyErr_SetString(PyExc_SystemError, "Invalid device number"); 153 | return -1; 154 | } 155 | 156 | try { 157 | cal::Device device; 158 | std::string source; 159 | 160 | device = calContext.getInfo()[dev_idx]; 161 | 162 | self->dev_context = cal::Context(device); 163 | 164 | source = calpp_create_pmk_kernel(device); 165 | 166 | //std::cout << source; 167 | 168 | self->dev_idx = dev_idx; 169 | self->dev_name = PyString_FromString(device.getInfo().c_str()); 170 | 171 | try { 172 | self->dev_prog = cal::Program(self->dev_context, source.c_str(), source.length() ); 173 | self->dev_prog.build(device); 174 | //self->dev_prog.disassemble(std::cout); 175 | } catch( cal::Error& e ) { 176 | PyErr_SetString(PyExc_SystemError, "CAL++ kernel compilation error"); 177 | return -1; 178 | } 179 | 180 | self->dev_kernel = cal::Kernel(self->dev_prog, "main"); 181 | self->dev_kernel.setArgBind(0, "i0"); 182 | self->dev_kernel.setArgBind(1, "i1"); 183 | self->dev_kernel.setArgBind(2, "i2"); 184 | self->dev_kernel.setArgBind(3, "i3"); 185 | self->dev_kernel.setArgBind(4, "i4"); 186 | self->dev_kernel.setArgBind(5, "o0"); 187 | self->dev_kernel.setArgBind(6, "o1"); 188 | 189 | self->dev_queue = cal::CommandQueue(self->dev_context,device); 190 | self->dev_maxheight = device.getInfo(); 191 | } catch( cal::Error& e ) { 192 | PyErr_SetString(PyExc_SystemError, e.what()); 193 | return -1; 194 | } 195 | 196 | return 0; 197 | } 198 | 199 | static void 200 | caldev_dealloc(CALDevice *self) 201 | { 202 | for(int i=0;ibuffer[i].in); 204 | PyMem_Free(self->buffer[i].out); 205 | } 206 | 207 | self->buffer.~array(); 208 | self->dev_queue.~CommandQueue(); 209 | self->dev_kernel.~Kernel(); 210 | self->dev_prog.~Program(); 211 | self->dev_context.~Context(); 212 | 213 | Py_XDECREF(self->dev_name); 214 | self->ob_type->tp_free((PyObject*)self); 215 | } 216 | 217 | static PyObject* 218 | cpyrit_listDevices(PyObject* self, PyObject* args) 219 | { 220 | int i; 221 | PyObject* result; 222 | std::vector devices; 223 | 224 | devices = calContext.getInfo(); 225 | 226 | result = PyTuple_New(calDevCount); 227 | for (i = 0; i < calDevCount; i++) 228 | PyTuple_SetItem(result, i, Py_BuildValue("(s)", devices[i].getInfo().c_str())); 229 | 230 | return result; 231 | } 232 | 233 | static void 234 | copy_gpu_inbuffer(CALDevice* self, const gpu_inbuffer* inbuffer, boost::array& in, int size ) 235 | { 236 | CALuint pitch; 237 | uint32_t *p[5]; 238 | int i; 239 | 240 | for(i = 0; i < 5; i++) 241 | p[i] = (uint32_t*)self->dev_queue.mapMemObject(in[i],pitch); 242 | 243 | for(i = 0; i < size; i++) 244 | { 245 | std::memcpy(p[0], &inbuffer[i].ctx_ipad.h0, 4*4); 246 | std::memcpy(p[1], &inbuffer[i].ctx_ipad.h4, 4*4); 247 | std::memcpy(p[2], &inbuffer[i].ctx_opad.h3, 4*4); 248 | std::memcpy(p[3], &inbuffer[i].e1.h2, 4*4); 249 | std::memcpy(p[4], &inbuffer[i].e2.h1, 4*4); 250 | 251 | p[0] += 4; p[1] += 4; 252 | p[2] += 4; p[3] += 4; 253 | p[4] += 4; 254 | } 255 | 256 | for(i = 0; i < 5; i++) 257 | self->dev_queue.unmapMemObject(in[i]); 258 | } 259 | 260 | static void 261 | copy_gpu_outbuffer(CALDevice* self, gpu_outbuffer* outbuffer, boost::array& out, int size) 262 | { 263 | CALuint pitch; 264 | uint32_t *p[2]; 265 | int i; 266 | 267 | for(i = 0; i < 2; i++) 268 | p[i] = (uint32_t*)self->dev_queue.mapMemObject(out[i],pitch); 269 | 270 | for(i = 0; i < size; i++) 271 | { 272 | std::memcpy(&outbuffer[i].pmk1.h0, p[0], 4*4); 273 | std::memcpy(&outbuffer[i].pmk1.h4, p[1], 4*4); 274 | 275 | p[0] += 4; p[1] += 4; 276 | } 277 | 278 | for(i = 0; i < 2; i++) 279 | self->dev_queue.unmapMemObject(out[i]); 280 | } 281 | 282 | static void 283 | start_kernel( CALDevice* self, int idx ) 284 | { 285 | int size, w, h; 286 | 287 | size = self->buffer[idx].size; 288 | 289 | h = (size + CALPP_BLOCK_WIDTH - 1) / CALPP_BLOCK_WIDTH; 290 | w = CALPP_BLOCK_WIDTH * ((h + self->dev_maxheight - 1) / self->dev_maxheight); 291 | h = (size + w - 1) / w; 292 | 293 | for(int i=0;i<5;i++) { 294 | if( !self->buffer[idx].g_in[i].isValid() || self->buffer[idx].g_in[i].getWidth()!=w || self->buffer[idx].g_in[i].getHeight()!=h ) { 295 | self->buffer[idx].g_in[i] = cal::Image2D(self->dev_context, w, h, CAL_FORMAT_UINT_4, 0); 296 | } 297 | } 298 | for(int i=0;i<2;i++) { 299 | if( !self->buffer[idx].g_out[i].isValid() || self->buffer[idx].g_out[i].getWidth()!=w || self->buffer[idx].g_out[i].getWidth()!=h ) { 300 | self->buffer[idx].g_out[i] = cal::Image2D(self->dev_context, w, h, CAL_FORMAT_UINT_4, 0); 301 | } 302 | } 303 | 304 | copy_gpu_inbuffer( self, self->buffer[idx].in, self->buffer[idx].g_in, size ); 305 | 306 | #ifdef __DEBUG_PYRIT_PREPROCESS_PERFORMANCE 307 | boost::posix_time::ptime t2 = boost::posix_time::microsec_clock::local_time(); 308 | boost::uint64_t tm = boost::posix_time::time_period(self->last_time,t2).length().total_microseconds(); 309 | if( tm>1000 ) 310 | std::cout << boost::format("Not fast enough data preparation for GPU: lost time %i ms\n") % (tm/1000); 311 | self->buffer[idx].start_time = boost::posix_time::microsec_clock::local_time(); 312 | #endif 313 | 314 | for(int i=0;i<5;i++) 315 | self->dev_kernel.setArg(0+i, self->buffer[idx].g_in[i]); 316 | for(int i=0;i<2;i++) 317 | self->dev_kernel.setArg(5+i, self->buffer[idx].g_out[i]); 318 | 319 | self->dev_queue.enqueueNDRangeKernel(self->dev_kernel, cal::NDRange(w,h), &(self->buffer[idx].event)); 320 | self->dev_queue.flush(); 321 | self->dev_queue.isEventDone(self->buffer[idx].event); 322 | } 323 | 324 | static PyObject* 325 | cpyrit_send(CALDevice *self, PyObject *args) 326 | { 327 | unsigned char essid[32+4], *passwd, pad[64], temp[32]; 328 | int i, idx, size, essidlen, passwdlen; 329 | PyObject *essid_obj, *passwd_seq, *passwd_obj; 330 | gpu_inbuffer *c_inbuffer; 331 | SHA_CTX ctx_pad; 332 | 333 | if (!PyArg_ParseTuple(args, "OO", &essid_obj, &passwd_seq)) 334 | return NULL; 335 | 336 | if( self->work_count>=BUFFER_SIZE ) 337 | Py_RETURN_FALSE; 338 | 339 | size = PySequence_Size(passwd_seq); 340 | if( size<=0 ) 341 | { 342 | PyErr_SetString(PyExc_SystemError, "send: not enough data"); 343 | return NULL; 344 | } 345 | 346 | passwd_seq = PyObject_GetIter(passwd_seq); 347 | if (!passwd_seq) 348 | return NULL; 349 | 350 | essidlen = PyString_Size(essid_obj); 351 | if (essidlen < 1 || essidlen > 32) 352 | { 353 | Py_DECREF(passwd_seq); 354 | PyErr_SetString(PyExc_ValueError, "The ESSID must be a string between 1 and 32 characters"); 355 | return NULL; 356 | } 357 | memcpy(essid, PyString_AsString(essid_obj), essidlen); 358 | memset(essid + essidlen, 0, sizeof(essid) - essidlen); 359 | 360 | self->buffer[self->work_count].in = (gpu_inbuffer*) PyMem_Realloc( self->buffer[self->work_count].in, sizeof(gpu_inbuffer)*size ); 361 | self->buffer[self->work_count].out = (gpu_outbuffer*) PyMem_Realloc( self->buffer[self->work_count].out, sizeof(gpu_outbuffer)*size ); 362 | self->buffer[self->work_count].size = size; 363 | 364 | if( !self->buffer[self->work_count].in || !self->buffer[self->work_count].out ) 365 | { 366 | Py_DECREF(passwd_seq); 367 | PyErr_NoMemory(); 368 | return NULL; 369 | } 370 | 371 | idx = 0; 372 | c_inbuffer = self->buffer[self->work_count].in; 373 | while ((passwd_obj = PyIter_Next(passwd_seq))) 374 | { 375 | if( idx>=size ) 376 | { 377 | Py_DECREF(passwd_obj); 378 | Py_DECREF(passwd_seq); 379 | PyErr_SetString(PyExc_ValueError, "Invalid sequence length"); 380 | return NULL; 381 | } 382 | 383 | passwd = (unsigned char*)PyString_AsString(passwd_obj); 384 | passwdlen = PyString_Size(passwd_obj); 385 | if (passwd == NULL || passwdlen < 8 || passwdlen > 63) 386 | { 387 | Py_DECREF(passwd_obj); 388 | Py_DECREF(passwd_seq); 389 | PyErr_SetString(PyExc_ValueError, "All passwords must be strings between 8 and 63 characters"); 390 | return NULL; 391 | } 392 | 393 | memcpy(pad, passwd, passwdlen); 394 | memset(pad + passwdlen, 0, sizeof(pad) - passwdlen); 395 | for (i = 0; i < 16; i++) 396 | ((unsigned int*)pad)[i] ^= 0x36363636; 397 | SHA1_Init(&ctx_pad); 398 | SHA1_Update(&ctx_pad, pad, sizeof(pad)); 399 | CPY_DEVCTX(ctx_pad, c_inbuffer[idx].ctx_ipad); 400 | for (i = 0; i < 16; i++) 401 | ((unsigned int*)pad)[i] ^= 0x6A6A6A6A; 402 | SHA1_Init(&ctx_pad); 403 | SHA1_Update(&ctx_pad, pad, sizeof(pad)); 404 | CPY_DEVCTX(ctx_pad, c_inbuffer[idx].ctx_opad); 405 | 406 | essid[essidlen + 4 - 1] = '\1'; 407 | HMAC(EVP_sha1(), passwd, passwdlen, essid, essidlen + 4, temp, NULL); 408 | GET_BE(c_inbuffer[idx].e1.h0, temp, 0); 409 | GET_BE(c_inbuffer[idx].e1.h1, temp, 4); 410 | GET_BE(c_inbuffer[idx].e1.h2, temp, 8); 411 | GET_BE(c_inbuffer[idx].e1.h3, temp, 12); 412 | GET_BE(c_inbuffer[idx].e1.h4, temp, 16); 413 | 414 | essid[essidlen + 4 - 1] = '\2'; 415 | HMAC(EVP_sha1(), passwd, passwdlen, essid, essidlen + 4, temp, NULL); 416 | GET_BE(c_inbuffer[idx].e2.h0, temp, 0); 417 | GET_BE(c_inbuffer[idx].e2.h1, temp, 4); 418 | GET_BE(c_inbuffer[idx].e2.h2, temp, 8); 419 | GET_BE(c_inbuffer[idx].e2.h3, temp, 12); 420 | GET_BE(c_inbuffer[idx].e2.h4, temp, 16); 421 | 422 | Py_DECREF(passwd_obj); 423 | idx++; 424 | } 425 | Py_DECREF(passwd_seq); 426 | 427 | self->work_count++; 428 | if( self->work_count==1 ) 429 | { 430 | try { 431 | ThreadUnlocker unlock; 432 | start_kernel(self,0); 433 | } catch( cal::Error& e ) { 434 | PyErr_SetString(PyExc_SystemError, e.what()); 435 | return NULL; 436 | } 437 | } 438 | 439 | Py_RETURN_TRUE; 440 | } 441 | 442 | static PyObject* 443 | cpyrit_receive(CALDevice *self, PyObject *args) 444 | { 445 | unsigned char temp[32]; 446 | PyObject *result; 447 | gpu_outbuffer *c_outbuffer; 448 | int wait_for_data,event_done; 449 | 450 | if (!PyArg_ParseTuple(args, "i", &wait_for_data)) 451 | return NULL; 452 | 453 | if( self->work_count<=0 ) 454 | Py_RETURN_NONE; 455 | 456 | try { 457 | ThreadUnlocker unlock; 458 | #ifdef __DEBUG_PYRIT_PREPROCESS_PERFORMANCE 459 | boost::posix_time::ptime t1 = boost::posix_time::microsec_clock::local_time(); 460 | #endif 461 | if( wait_for_data ) 462 | self->dev_queue.waitForEvent(self->buffer[0].event); 463 | event_done = self->dev_queue.isEventDone(self->buffer[0].event); 464 | 465 | if( event_done ) 466 | { 467 | #ifdef __DEBUG_PYRIT_PREPROCESS_PERFORMANCE 468 | boost::posix_time::ptime t2 = boost::posix_time::microsec_clock::local_time(); 469 | if( boost::posix_time::time_period(t1,t2).length().total_microseconds()>=200000 ) 470 | { 471 | // cpu was waiting >=0.2s for gpu 472 | // data were prepared fast enough and cpu had spare time 473 | self->item_count += self->buffer[0].size; 474 | self->exec_time += boost::posix_time::time_period(self->buffer[0].start_time,t2).length().total_microseconds(); 475 | } 476 | else 477 | { 478 | // cpu was waiting <0.2s for gpu 479 | // or most probable case gpu was waiting for cpu 480 | if( self->item_count>0 ) 481 | { 482 | boost::int64_t perf = (1000*self->exec_time)/self->item_count; 483 | boost::int64_t lost_time = boost::posix_time::time_period(self->buffer[0].start_time,t2).length().total_microseconds() - 484 | perf*self->buffer[0].size/1000; 485 | std::cout << boost::format("Not fast enough data preparation for GPU: estimated lost time %i ms\n") % (lost_time/1000); 486 | } 487 | else 488 | std::cout << "Not fast enough data preparation for GPU: unknown lost time\n"; 489 | } 490 | self->last_time = t2; 491 | #endif 492 | copy_gpu_outbuffer( self, self->buffer[0].out, self->buffer[0].g_out, self->buffer[0].size ); 493 | if( self->work_count>1 ) start_kernel(self,1); 494 | } 495 | } catch( cal::Error& e ) { 496 | PyErr_SetString(PyExc_SystemError, e.what()); 497 | return NULL; 498 | } 499 | 500 | if( event_done ) 501 | { 502 | c_outbuffer = self->buffer[0].out; 503 | 504 | result = PyTuple_New(self->buffer[0].size); 505 | for (int i = 0; i < self->buffer[0].size; i++) 506 | { 507 | PUT_BE(c_outbuffer[i].pmk1.h0, temp, 0); PUT_BE(c_outbuffer[i].pmk1.h1, temp, 4); 508 | PUT_BE(c_outbuffer[i].pmk1.h2, temp, 8); PUT_BE(c_outbuffer[i].pmk1.h3, temp, 12); 509 | PUT_BE(c_outbuffer[i].pmk1.h4, temp, 16);PUT_BE(c_outbuffer[i].pmk2.h0, temp, 20); 510 | PUT_BE(c_outbuffer[i].pmk2.h1, temp, 24);PUT_BE(c_outbuffer[i].pmk2.h2, temp, 28); 511 | PyTuple_SetItem(result, i, PyString_FromStringAndSize((char*)temp, 32)); 512 | } 513 | 514 | WorkItem tmp = self->buffer[0]; 515 | for(int i=0;i<(BUFFER_SIZE-1);i++) 516 | self->buffer[i] = self->buffer[i+1]; 517 | self->buffer[BUFFER_SIZE-1] = tmp; 518 | self->work_count--; 519 | 520 | return result; 521 | } 522 | 523 | Py_RETURN_NONE; 524 | } 525 | 526 | static PyObject* 527 | cpyrit_sizes(CALDevice *self, PyObject *args) 528 | { 529 | cal::Device device; 530 | int min_size,avg_size,max_size,div_size; 531 | int target,simd,avg_speed,max_speed; 532 | 533 | device = self->dev_context.getInfo()[0]; 534 | target = device.getInfo(); 535 | simd = device.getInfo(); 536 | 537 | if( target>=CAL_TARGET_CYPRESS ) 538 | { 539 | avg_speed = 3500; 540 | max_speed = 5000; 541 | } 542 | else 543 | { 544 | avg_speed = 2000; 545 | max_speed = 3000; 546 | } 547 | 548 | div_size = 8*64*2*simd; // 8 threads per simd * thread size * 2 elements per thread * number of simds 549 | min_size = 4096; 550 | avg_size = div_size*((1*avg_speed*simd + div_size - 1)/div_size); 551 | max_size = div_size*((3*max_speed*simd + div_size - 1)/div_size); 552 | 553 | return Py_BuildValue("iiii",min_size,avg_size,max_size,div_size); 554 | } 555 | 556 | static PyMemberDef CALDevice_members[] = 557 | { 558 | {(char*)"deviceName", T_OBJECT, _offsetof(CALDevice, dev_name), 0}, 559 | {NULL} 560 | }; 561 | 562 | static PyMethodDef CALDevice_methods[] = 563 | { 564 | {"send", (PyCFunction)cpyrit_send, METH_VARARGS, "Enqueue calculation of PMKs from ESSID and iterable of strings."}, 565 | {"receive", (PyCFunction)cpyrit_receive, METH_VARARGS, "Gather result of calculation PMKs from ESSID and iterable of strings."}, 566 | {"workSizes", (PyCFunction)cpyrit_sizes, METH_VARARGS, "Return tuple with core min,avg,max,div sizes."}, 567 | {NULL, NULL} 568 | }; 569 | 570 | static PyTypeObject CALDevice_type = { 571 | PyObject_HEAD_INIT(NULL) 572 | 0, /*ob_size*/ 573 | "_cpyrit_calpp.CALDevice", /*tp_name*/ 574 | sizeof(CALDevice), /*tp_basicsize*/ 575 | 0, /*tp_itemsize*/ 576 | (destructor)caldev_dealloc, /*tp_dealloc*/ 577 | 0, /*tp_print*/ 578 | 0, /*tp_getattr*/ 579 | 0, /*tp_setattr*/ 580 | 0, /*tp_compare*/ 581 | 0, /*tp_repr*/ 582 | 0, /*tp_as_number*/ 583 | 0, /*tp_as_sequence*/ 584 | 0, /*tp_as_mapping*/ 585 | 0, /*tp_hash*/ 586 | 0, /*tp_call*/ 587 | 0, /*tp_str*/ 588 | 0, /*tp_getattro*/ 589 | 0, /*tp_setattro*/ 590 | 0, /*tp_as_buffer*/ 591 | Py_TPFLAGS_DEFAULT /*tp_flags*/ 592 | | Py_TPFLAGS_BASETYPE, 593 | 0, /*tp_doc*/ 594 | 0, /*tp_traverse*/ 595 | 0, /*tp_clear*/ 596 | 0, /*tp_richcompare*/ 597 | 0, /*tp_weaklistoffset*/ 598 | 0, /*tp_iter*/ 599 | 0, /*tp_iternext*/ 600 | CALDevice_methods, /*tp_methods*/ 601 | CALDevice_members, /*tp_members*/ 602 | 0, /*tp_getset*/ 603 | 0, /*tp_base*/ 604 | 0, /*tp_dict*/ 605 | 0, /*tp_descr_get*/ 606 | 0, /*tp_descr_set*/ 607 | 0, /*tp_dictoffset*/ 608 | (initproc)caldev_init, /*tp_init*/ 609 | 0, /*tp_alloc*/ 610 | 0, /*tp_new*/ 611 | 0, /*tp_free*/ 612 | 0, /*tp_is_gc*/ 613 | }; 614 | 615 | static PyMethodDef CPyritCAL_methods[] = { 616 | {"listDevices", cpyrit_listDevices, METH_NOARGS, "Returns a tuple of tuples, each describing a CAL++ capable device."}, 617 | {NULL, NULL, 0, NULL} 618 | }; 619 | 620 | extern "C" PyMODINIT_FUNC init_cpyrit_calpp(void) 621 | { 622 | PyObject *m; 623 | 624 | cal::Init(); 625 | 626 | calContext = cal::Context(CAL_DEVICE_TYPE_GPU); 627 | calDevCount = calContext.getInfo().size(); 628 | 629 | CALDevice_type.tp_getattro = PyObject_GenericGetAttr; 630 | CALDevice_type.tp_setattro = PyObject_GenericSetAttr; 631 | CALDevice_type.tp_alloc = PyType_GenericAlloc; 632 | CALDevice_type.tp_new = PyType_GenericNew; 633 | CALDevice_type.tp_free = PyObject_Del; 634 | if (PyType_Ready(&CALDevice_type) < 0) 635 | return; 636 | 637 | m = Py_InitModule("_cpyrit_calpp", CPyritCAL_methods); 638 | 639 | Py_INCREF(&CALDevice_type); 640 | PyModule_AddObject(m, "CALDevice", (PyObject*)&CALDevice_type); 641 | PyModule_AddStringConstant(m, "VERSION", VERSION); 642 | } 643 | -------------------------------------------------------------------------------- /modules/cpyrit_calpp/_cpyrit_calpp.h: -------------------------------------------------------------------------------- 1 | /* 2 | # 3 | # Copyright 2008-2011 Lukas Lueg, lukas.lueg@gmail.com 4 | # 5 | # This file is part of Pyrit. 6 | # 7 | # Pyrit is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # Pyrit is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Pyrit. If not, see . 19 | */ 20 | 21 | #ifndef CPYRIT_CALPP 22 | #define CPYRIT_CALPP 23 | 24 | #ifndef uint32_t 25 | #define uint32_t boost::uint32_t 26 | #endif 27 | 28 | #define CALPP_BLOCK_WIDTH 64 29 | 30 | #define GET_BE(n,b,i) \ 31 | { \ 32 | (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ 33 | | ( (uint32_t) (b)[(i) + 1] << 16 ) \ 34 | | ( (uint32_t) (b)[(i) + 2] << 8 ) \ 35 | | ( (uint32_t) (b)[(i) + 3] ); \ 36 | } 37 | 38 | #define PUT_BE(n,b,i) \ 39 | { \ 40 | (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ 41 | (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ 42 | (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ 43 | (b)[(i) + 3] = (unsigned char) ( (n) ); \ 44 | } 45 | 46 | #define CPY_DEVCTX(src, dst) \ 47 | { \ 48 | dst.h0 = src.h0; dst.h1 = src.h1; \ 49 | dst.h2 = src.h2; dst.h3 = src.h3; \ 50 | dst.h4 = src.h4; \ 51 | } 52 | 53 | typedef struct { 54 | uint32_t h0,h1,h2,h3,h4; 55 | } SHA_DEV_CTX; 56 | 57 | typedef struct { 58 | SHA_DEV_CTX ctx_ipad; 59 | SHA_DEV_CTX ctx_opad; 60 | SHA_DEV_CTX e1; 61 | SHA_DEV_CTX e2; 62 | } gpu_inbuffer; 63 | 64 | typedef struct { 65 | SHA_DEV_CTX pmk1; 66 | SHA_DEV_CTX pmk2; 67 | } gpu_outbuffer; 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /modules/cpyrit_calpp/_cpyrit_calpp_kernel.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | # 3 | # Copyright 2010, 2011 Artur Kornacki, hazeman11@gmail.com 4 | # 5 | # This file is part of Pyrit. 6 | # 7 | # Pyrit is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # Pyrit is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Pyrit. If not, see . 19 | */ 20 | 21 | #include 22 | #include 23 | 24 | using namespace cal::il; 25 | 26 | struct SHA_DEV_CTX 27 | { 28 | uint2 h0,h1,h2,h3,h4; 29 | 30 | void assign( const uint2& a, const uint2& b, const uint2& c, const uint2& d, const uint2& e ) 31 | { 32 | h0 = a; h1 = b; h2 = c; h3 = d; h4 = e; 33 | } 34 | 35 | SHA_DEV_CTX& operator^=( const SHA_DEV_CTX& v ) 36 | { 37 | h0 = h0 ^ v.h0; 38 | h1 = h1 ^ v.h1; 39 | h2 = h2 ^ v.h2; 40 | h3 = h3 ^ v.h3; 41 | h4 = h4 ^ v.h4; 42 | 43 | return *this; 44 | } 45 | }; 46 | 47 | /* This function is generated by generate_optimized_kernel script */ 48 | static void sha1_process( const SHA_DEV_CTX& ctx, SHA_DEV_CTX& data ) 49 | { 50 | uint2 temp693; 51 | uint2 D690; 52 | uint2 B689; 53 | uint2 temp683; 54 | uint2 E680; 55 | uint2 C679; 56 | uint2 temp673; 57 | uint2 A670; 58 | uint2 D669; 59 | uint2 temp668; 60 | uint2 temp663; 61 | uint2 B660; 62 | uint2 E659; 63 | uint2 temp658; 64 | uint2 temp653; 65 | uint2 C650; 66 | uint2 A649; 67 | uint2 temp648; 68 | uint2 temp643; 69 | uint2 D640; 70 | uint2 B639; 71 | uint2 temp638; 72 | uint2 temp633; 73 | uint2 E630; 74 | uint2 C629; 75 | uint2 temp628; 76 | uint2 temp623; 77 | uint2 A620; 78 | uint2 D619; 79 | uint2 temp618; 80 | uint2 temp613; 81 | uint2 B610; 82 | uint2 E609; 83 | uint2 temp608; 84 | uint2 temp603; 85 | uint2 C600; 86 | uint2 A599; 87 | uint2 temp598; 88 | uint2 temp593; 89 | uint2 D590; 90 | uint2 B589; 91 | uint2 temp588; 92 | uint2 temp583; 93 | uint2 E580; 94 | uint2 C579; 95 | uint2 temp578; 96 | uint2 temp573; 97 | uint2 A570; 98 | uint2 D569; 99 | uint2 temp568; 100 | uint2 temp563; 101 | uint2 B560; 102 | uint2 E559; 103 | uint2 temp558; 104 | uint2 temp553; 105 | uint2 C550; 106 | uint2 A549; 107 | uint2 temp548; 108 | uint2 temp543; 109 | uint2 D540; 110 | uint2 B539; 111 | uint2 temp538; 112 | uint2 temp533; 113 | uint2 E530; 114 | uint2 C529; 115 | uint2 temp528; 116 | uint2 temp523; 117 | uint2 A520; 118 | uint2 D519; 119 | uint2 temp518; 120 | uint2 temp513; 121 | uint2 B510; 122 | uint2 E509; 123 | uint2 temp508; 124 | uint2 temp503; 125 | uint2 C500; 126 | uint2 A499; 127 | uint2 temp498; 128 | uint2 temp491; 129 | uint2 D488; 130 | uint2 B487; 131 | uint2 temp486; 132 | uint2 temp479; 133 | uint2 E476; 134 | uint2 C475; 135 | uint2 temp474; 136 | uint2 temp467; 137 | uint2 A464; 138 | uint2 D463; 139 | uint2 temp462; 140 | uint2 temp455; 141 | uint2 B452; 142 | uint2 E451; 143 | uint2 temp450; 144 | uint2 temp443; 145 | uint2 C440; 146 | uint2 A439; 147 | uint2 temp438; 148 | uint2 temp431; 149 | uint2 D428; 150 | uint2 B427; 151 | uint2 temp426; 152 | uint2 temp419; 153 | uint2 E416; 154 | uint2 C415; 155 | uint2 temp414; 156 | uint2 temp407; 157 | uint2 A404; 158 | uint2 D403; 159 | uint2 temp402; 160 | uint2 temp395; 161 | uint2 B392; 162 | uint2 E391; 163 | uint2 temp390; 164 | uint2 temp383; 165 | uint2 C380; 166 | uint2 A379; 167 | uint2 temp378; 168 | uint2 temp371; 169 | uint2 D368; 170 | uint2 B367; 171 | uint2 temp366; 172 | uint2 temp359; 173 | uint2 E356; 174 | uint2 C355; 175 | uint2 temp354; 176 | uint2 temp347; 177 | uint2 A344; 178 | uint2 D343; 179 | uint2 temp342; 180 | uint2 temp335; 181 | uint2 B332; 182 | uint2 E331; 183 | uint2 temp330; 184 | uint2 temp323; 185 | uint2 C320; 186 | uint2 A319; 187 | uint2 temp318; 188 | uint2 temp316; 189 | uint2 D314; 190 | uint2 B313; 191 | uint2 temp312; 192 | uint2 temp310; 193 | uint2 E308; 194 | uint2 C307; 195 | uint2 temp306; 196 | uint2 temp304; 197 | uint2 A302; 198 | uint2 D301; 199 | uint2 temp300; 200 | uint2 temp298; 201 | uint2 B296; 202 | uint2 E295; 203 | uint2 temp294; 204 | uint2 temp292; 205 | uint2 C290; 206 | uint2 A289; 207 | uint2 temp288; 208 | uint2 temp283; 209 | uint2 D281; 210 | uint2 B280; 211 | uint2 temp279; 212 | uint2 temp274; 213 | uint2 E273; 214 | uint2 C272; 215 | uint2 temp271; 216 | uint2 temp266; 217 | uint2 A265; 218 | uint2 D264; 219 | uint2 temp263; 220 | uint2 temp258; 221 | uint2 B257; 222 | uint2 E256; 223 | uint2 temp255; 224 | uint2 temp250; 225 | uint2 C248; 226 | uint2 A247; 227 | uint2 temp246; 228 | uint2 temp241; 229 | uint2 D239; 230 | uint2 B238; 231 | uint2 temp237; 232 | uint2 temp232; 233 | uint2 E231; 234 | uint2 C230; 235 | uint2 temp229; 236 | uint2 temp224; 237 | uint2 A223; 238 | uint2 D222; 239 | uint2 temp221; 240 | uint2 temp216; 241 | uint2 B215; 242 | uint2 E214; 243 | uint2 temp213; 244 | uint2 C208; 245 | uint2 A207; 246 | uint2 temp206; 247 | uint2 D201; 248 | uint2 B200; 249 | uint2 temp199; 250 | uint2 E194; 251 | uint2 C193; 252 | uint2 temp192; 253 | uint2 A187; 254 | uint2 D186; 255 | uint2 temp185; 256 | uint2 B180; 257 | uint2 E179; 258 | uint2 temp178; 259 | uint2 C173; 260 | uint2 A172; 261 | uint2 temp171; 262 | uint2 D168; 263 | uint2 B167; 264 | uint2 temp166; 265 | uint2 E163; 266 | uint2 C162; 267 | uint2 temp161; 268 | uint2 A158; 269 | uint2 D157; 270 | uint2 temp156; 271 | uint2 temp153; 272 | uint2 B152; 273 | uint2 E151; 274 | uint2 temp150; 275 | uint2 temp147; 276 | uint2 C146; 277 | uint2 A145; 278 | uint2 temp144; 279 | uint2 temp138; 280 | uint2 D137; 281 | uint2 B136; 282 | uint2 temp135; 283 | uint2 E128; 284 | uint2 C127; 285 | uint2 temp126; 286 | uint2 A119; 287 | uint2 D118; 288 | uint2 B112; 289 | uint2 E111; 290 | uint2 C106; 291 | uint2 A105; 292 | uint2 D99; 293 | uint2 B98; 294 | uint2 E92; 295 | uint2 C91; 296 | uint2 A85; 297 | uint2 D84; 298 | uint2 B78; 299 | uint2 E77; 300 | uint2 C71; 301 | uint2 A70; 302 | uint2 D64; 303 | uint2 B63; 304 | uint2 E57; 305 | uint2 C56; 306 | uint2 A50; 307 | uint2 D49; 308 | uint2 B43; 309 | uint2 E42; 310 | uint2 C37; 311 | uint2 A36; 312 | uint2 D35; 313 | uint2 B34; 314 | uint2 E33; 315 | uint2 C32; 316 | uint2 A31; 317 | uint2 D30; 318 | uint2 B29; 319 | uint2 E28; 320 | uint2 D; 321 | uint2 C; 322 | uint2 B; 323 | uint2 A; 324 | uint2 D2315; 325 | uint2 D2313; 326 | uint2 D2311; 327 | uint2 D2309; 328 | uint2 D2307; 329 | uint2 D2305; 330 | uint2 D2303; 331 | uint2 D2301; 332 | uint2 D2299; 333 | uint2 D2297; 334 | uint2 D2295; 335 | uint2 D2293; 336 | uint2 D2291; 337 | uint2 D2289; 338 | uint2 D2287; 339 | uint2 D2285; 340 | uint2 D2283; 341 | uint2 D2281; 342 | uint2 D2279; 343 | uint2 D2277; 344 | uint2 D2275; 345 | uint2 D2273; 346 | uint2 D2271; 347 | uint2 D2269; 348 | uint2 D2267; 349 | uint2 D2265; 350 | uint2 D2263; 351 | uint2 D2261; 352 | uint2 D2259; 353 | uint2 D2257; 354 | uint2 D2255; 355 | uint2 D2253; 356 | uint2 D2251; 357 | uint2 D2249; 358 | uint2 D2247; 359 | uint2 D2245; 360 | uint2 D2238; 361 | uint2 D2231; 362 | uint2 D2224; 363 | uint2 D2217; 364 | uint2 D2210; 365 | uint2 D2208; 366 | uint2 D2206; 367 | uint2 D2204; 368 | uint2 D2202; 369 | uint2 D2200; 370 | uint2 D2198; 371 | uint2 D2196; 372 | uint2 D2194; 373 | uint2 D2190; 374 | uint2 D2188; 375 | uint2 D2186; 376 | uint2 D2184; 377 | uint2 D2182; 378 | uint2 D2179; 379 | uint2 D2178; 380 | uint2 D2175; 381 | uint2 D2174; 382 | uint2 D2171; 383 | uint2 D2170; 384 | uint2 D2167; 385 | uint2 D2166; 386 | uint2 D2161; 387 | uint2 D2160; 388 | uint2 D2155; 389 | uint2 D2154; 390 | uint2 D2148; 391 | uint2 D2142; 392 | uint2 D2136; 393 | uint2 D2132; 394 | uint2 D2128; 395 | uint2 D2124; 396 | uint2 D2122; 397 | uint2 D2119; 398 | uint2 D2116; 399 | uint2 D2113; 400 | uint2 D2110; 401 | uint2 D2107; 402 | uint2 D2104; 403 | uint2 D2101; 404 | uint2 D2098; 405 | uint2 D2095; 406 | uint2 D2092; 407 | uint2 D2089; 408 | uint2 D2086; 409 | uint2 D2078; 410 | uint2 D2070; 411 | uint2 D2062; 412 | uint2 D2054; 413 | uint2 D2046; 414 | uint2 D2045; 415 | uint2 D2044; 416 | uint2 D2043; 417 | uint2 D2042; 418 | 419 | D2042 = data.h0; 420 | D2043 = data.h1; 421 | D2044 = data.h2; 422 | D2045 = data.h3; 423 | D2046 = data.h4; 424 | A = ctx.h0; 425 | B = ctx.h1; 426 | C = ctx.h2; 427 | D = ctx.h3; 428 | D2054 = ((D2042 + ctx.h4) + 0x5A827999) + rotate(A,32-27); 429 | E28 = D2054 + ((D ^ C) & B ^ D); 430 | B29 = rotate(B,32-2); 431 | D2062 = ((D2043 + D) + 0x5A827999) + ((B29 ^ C) & A ^ C); 432 | D30 = D2062 + rotate(E28,32-27); 433 | A31 = rotate(A,32-2); 434 | D2070 = ((D2044 + C) + 0x5A827999) + (E28 & (A31 ^ B29) ^ B29); 435 | C32 = D2070 + rotate(D30,32-27); 436 | E33 = rotate(E28,32-2); 437 | D2078 = ((D2045 + 0x5A827999) + B29) + ((E33 ^ A31) & D30 ^ A31); 438 | B34 = D2078 + rotate(C32,32-27); 439 | D35 = rotate(D30,32-2); 440 | D2086 = ((D2046 + 0x5A827999) + A31) + ((D35 ^ E33) & C32 ^ E33); 441 | A36 = D2086 + rotate(B34,32-27); 442 | C37 = rotate(C32,32-2); 443 | D2089 = (E33 + 3665983897) + ((C37 ^ D35) & B34 ^ D35); 444 | E42 = D2089 + rotate(A36,32-27); 445 | B43 = rotate(B34,32-2); 446 | D2092 = (D35 + 0x5A827999) + ((B43 ^ C37) & A36 ^ C37); 447 | D49 = D2092 + rotate(E42,32-27); 448 | A50 = rotate(A36,32-2); 449 | D2095 = (C37 + 0x5A827999) + ((A50 ^ B43) & E42 ^ B43); 450 | C56 = D2095 + rotate(D49,32-27); 451 | E57 = rotate(E42,32-2); 452 | D2098 = (B43 + 0x5A827999) + ((E57 ^ A50) & D49 ^ A50); 453 | B63 = D2098 + rotate(C56,32-27); 454 | D64 = rotate(D49,32-2); 455 | D2101 = (A50 + 0x5A827999) + ((D64 ^ E57) & C56 ^ E57); 456 | A70 = D2101 + rotate(B63,32-27); 457 | C71 = rotate(C56,32-2); 458 | D2104 = (E57 + 0x5A827999) + ((C71 ^ D64) & B63 ^ D64); 459 | E77 = D2104 + rotate(A70,32-27); 460 | B78 = rotate(B63,32-2); 461 | D2107 = (D64 + 0x5A827999) + ((B78 ^ C71) & A70 ^ C71); 462 | D84 = D2107 + rotate(E77,32-27); 463 | A85 = rotate(A70,32-2); 464 | D2110 = (C71 + 0x5A827999) + ((A85 ^ B78) & E77 ^ B78); 465 | C91 = D2110 + rotate(D84,32-27); 466 | E92 = rotate(E77,32-2); 467 | D2113 = (B78 + 0x5A827999) + ((E92 ^ A85) & D84 ^ A85); 468 | B98 = D2113 + rotate(C91,32-27); 469 | D99 = rotate(D84,32-2); 470 | D2116 = (A85 + 0x5A827999) + ((D99 ^ E92) & C91 ^ E92); 471 | A105 = D2116 + rotate(B98,32-27); 472 | C106 = rotate(C91,32-2); 473 | D2119 = (E92 + 1518500921) + ((C106 ^ D99) & B98 ^ D99); 474 | E111 = D2119 + rotate(A105,32-27); 475 | B112 = rotate(B98,32-2); 476 | D2122 = rotate((D2044 ^ D2042),32-31); 477 | D2124 = ((D2122 + 0x5A827999) + D99) + ((B112 ^ C106) & A105 ^ C106); 478 | D118 = D2124 + rotate(E111,32-27); 479 | A119 = rotate(A105,32-2); 480 | temp126 = rotate((D2045 ^ D2043),32-31); 481 | D2128 = ((temp126 + 0x5A827999) + C106) + ((A119 ^ B112) & E111 ^ B112); 482 | C127 = D2128 + rotate(D118,32-27); 483 | E128 = rotate(E111,32-2); 484 | temp135 = rotate(((D2044 ^ D2046) ^ 672),32-31); 485 | D2132 = ((temp135 + 0x5A827999) + B112) + ((E128 ^ A119) & D118 ^ A119); 486 | B136 = D2132 + rotate(C127,32-27); 487 | D137 = rotate(D118,32-2); 488 | temp138 = (D2045 ^ 0x80000000) ^ D2122; 489 | temp144 = rotate(temp138,32-31); 490 | D2136 = ((temp144 + 0x5A827999) + A119) + ((D137 ^ E128) & C127 ^ E128); 491 | A145 = D2136 + rotate(B136,32-27); 492 | C146 = rotate(C127,32-2); 493 | temp147 = temp126 ^ D2046; 494 | temp150 = rotate(temp147,32-31); 495 | D2142 = ((temp150 + 0x6ED9EBA1) + E128) + ((C146 ^ D137) ^ B136); 496 | E151 = D2142 + rotate(A145,32-27); 497 | B152 = rotate(B136,32-2); 498 | temp153 = temp135 ^ 0x80000000; 499 | temp156 = rotate(temp153,32-31); 500 | D2148 = ((temp156 + 0x6ED9EBA1) + D137) + ((B152 ^ C146) ^ A145); 501 | D157 = D2148 + rotate(E151,32-27); 502 | A158 = rotate(A145,32-2); 503 | temp161 = rotate(temp144,32-31); 504 | D2154 = ((temp161 + 0x6ED9EBA1) + C146) + ((A158 ^ B152) ^ E151); 505 | C162 = D2154 + rotate(D157,32-27); 506 | E163 = rotate(E151,32-2); 507 | D2155 = temp150 ^ 672; 508 | temp166 = rotate(D2155,32-31); 509 | D2160 = ((temp166 + 0x6ED9EBA1) + B152) + ((E163 ^ A158) ^ D157); 510 | B167 = D2160 + rotate(C162,32-27); 511 | D168 = rotate(D157,32-2); 512 | D2161 = temp156 ^ D2122; 513 | temp171 = rotate(D2161,32-31); 514 | D2166 = ((temp171 + 0x6ED9EBA1) + A158) + ((D168 ^ E163) ^ C162); 515 | A172 = D2166 + rotate(B167,32-27); 516 | C173 = rotate(C162,32-2); 517 | D2167 = temp161 ^ temp126; 518 | temp178 = rotate(D2167,32-31); 519 | D2170 = ((temp178 + 0x6ED9EBA1) + E163) + ((C173 ^ D168) ^ B167); 520 | E179 = D2170 + rotate(A172,32-27); 521 | B180 = rotate(B167,32-2); 522 | D2171 = temp166 ^ temp135; 523 | temp185 = rotate(D2171,32-31); 524 | D2174 = ((temp185 + 0x6ED9EBA1) + D168) + ((B180 ^ C173) ^ A172); 525 | D186 = D2174 + rotate(E179,32-27); 526 | A187 = rotate(A172,32-2); 527 | D2175 = temp171 ^ temp144; 528 | temp192 = rotate(D2175,32-31); 529 | D2178 = ((temp192 + 0x6ED9EBA1) + C173) + ((A187 ^ B180) ^ E179); 530 | C193 = D2178 + rotate(D186,32-27); 531 | E194 = rotate(E179,32-2); 532 | D2179 = temp178 ^ temp150; 533 | temp199 = rotate(D2179,32-31); 534 | D2182 = ((temp199 + 0x6ED9EBA1) + B180) + ((E194 ^ A187) ^ D186); 535 | B200 = D2182 + rotate(C193,32-27); 536 | D201 = rotate(D186,32-2); 537 | D2184 = (temp156 ^ 672) ^ temp185; 538 | temp206 = rotate(D2184,32-31); 539 | D2186 = ((temp206 + 0x6ED9EBA1) + A187) + ((D201 ^ E194) ^ C193); 540 | A207 = D2186 + rotate(B200,32-27); 541 | C208 = rotate(C193,32-2); 542 | D2188 = (temp161 ^ D2122) ^ temp192; 543 | temp213 = rotate(D2188,32-31); 544 | D2190 = ((temp213 + 0x6ED9EBA1) + E194) + ((C208 ^ D201) ^ B200); 545 | E214 = D2190 + rotate(A207,32-27); 546 | B215 = rotate(B200,32-2); 547 | temp216 = ((temp126 ^ 672) ^ temp166) ^ temp199; 548 | temp221 = rotate(temp216,32-31); 549 | D2194 = ((temp221 + 0x6ED9EBA1) + D201) + ((B215 ^ C208) ^ A207); 550 | D222 = D2194 + rotate(E214,32-27); 551 | A223 = rotate(A207,32-2); 552 | temp224 = ((temp135 ^ D2122) ^ temp171) ^ temp206; 553 | temp229 = rotate(temp224,32-31); 554 | D2196 = ((temp229 + 0x6ED9EBA1) + C208) + ((A223 ^ B215) ^ E214); 555 | C230 = D2196 + rotate(D222,32-27); 556 | E231 = rotate(E214,32-2); 557 | temp232 = ((temp144 ^ temp126) ^ temp178) ^ temp213; 558 | temp237 = rotate(temp232,32-31); 559 | D2198 = ((temp237 + 0x6ED9EBA1) + B215) + ((E231 ^ A223) ^ D222); 560 | B238 = D2198 + rotate(C230,32-27); 561 | D239 = rotate(D222,32-2); 562 | temp241 = ((temp150 ^ temp135) ^ temp185) ^ temp221; 563 | temp246 = rotate(temp241,32-31); 564 | D2200 = ((temp246 + 0x6ED9EBA1) + A223) + ((D239 ^ E231) ^ C230); 565 | A247 = D2200 + rotate(B238,32-27); 566 | C248 = rotate(C230,32-2); 567 | temp250 = ((temp156 ^ temp144) ^ temp192) ^ temp229; 568 | temp255 = rotate(temp250,32-31); 569 | D2202 = ((temp255 + 0x6ED9EBA1) + E231) + ((C248 ^ D239) ^ B238); 570 | E256 = D2202 + rotate(A247,32-27); 571 | B257 = rotate(B238,32-2); 572 | temp258 = ((temp161 ^ temp150) ^ temp199) ^ temp237; 573 | temp263 = rotate(temp258,32-31); 574 | D2204 = ((temp263 + 0x6ED9EBA1) + D239) + ((B257 ^ C248) ^ A247); 575 | D264 = D2204 + rotate(E256,32-27); 576 | A265 = rotate(A247,32-2); 577 | temp266 = ((temp166 ^ temp156) ^ temp206) ^ temp246; 578 | temp271 = rotate(temp266,32-31); 579 | D2206 = ((temp271 + 0x6ED9EBA1) + C248) + ((A265 ^ B257) ^ E256); 580 | C272 = D2206 + rotate(D264,32-27); 581 | E273 = rotate(E256,32-2); 582 | temp274 = ((temp171 ^ temp161) ^ temp213) ^ temp255; 583 | temp279 = rotate(temp274,32-31); 584 | D2208 = ((temp279 + 0x6ED9EBA1) + B257) + ((E273 ^ A265) ^ D264); 585 | B280 = D2208 + rotate(C272,32-27); 586 | D281 = rotate(D264,32-2); 587 | temp283 = ((temp178 ^ temp166) ^ temp221) ^ temp263; 588 | temp288 = rotate(temp283,32-31); 589 | D2210 = ((temp288 + 0x6ED9EBA1) + A265) + ((D281 ^ E273) ^ C272); 590 | A289 = D2210 + rotate(B280,32-27); 591 | C290 = rotate(C272,32-2); 592 | temp292 = ((temp185 ^ temp171) ^ temp229) ^ temp271; 593 | temp294 = rotate(temp292,32-31); 594 | D2217 = ((temp294 + 0x8F1BBCDC) + E273) + rotate(A289,32-27); 595 | E295 = D2217 + ((B280 | C290) & D281 | B280 & C290); 596 | B296 = rotate(B280,32-2); 597 | temp298 = ((temp192 ^ temp178) ^ temp237) ^ temp279; 598 | temp300 = rotate(temp298,32-31); 599 | D2224 = ((temp300 + 0x8F1BBCDC) + D281) + ((A289 | B296) & C290 | A289 & B296); 600 | D301 = D2224 + rotate(E295,32-27); 601 | A302 = rotate(A289,32-2); 602 | temp304 = ((temp199 ^ temp185) ^ temp246) ^ temp288; 603 | temp306 = rotate(temp304,32-31); 604 | D2231 = ((temp306 + 0x8F1BBCDC) + C290) + rotate(D301,32-27); 605 | C307 = D2231 + ((E295 | A302) & B296 | E295 & A302); 606 | E308 = rotate(E295,32-2); 607 | temp310 = ((temp206 ^ temp192) ^ temp255) ^ temp294; 608 | temp312 = rotate(temp310,32-31); 609 | D2238 = ((temp312 + 0x8F1BBCDC) + B296) + ((D301 | E308) & A302 | D301 & E308); 610 | B313 = D2238 + rotate(C307,32-27); 611 | D314 = rotate(D301,32-2); 612 | temp316 = ((temp213 ^ temp199) ^ temp263) ^ temp300; 613 | temp318 = rotate(temp316,32-31); 614 | D2245 = ((temp318 + 0x8F1BBCDC) + A302) + rotate(B313,32-27); 615 | A319 = D2245 + ((C307 | D314) & E308 | C307 & D314); 616 | C320 = rotate(C307,32-2); 617 | temp323 = ((temp221 ^ temp206) ^ temp271) ^ temp306; 618 | temp330 = rotate(temp323,32-31); 619 | D2247 = ((temp330 + 0x8F1BBCDC) + E308) + ((B313 | C320) & D314 | B313 & C320); 620 | E331 = D2247 + rotate(A319,32-27); 621 | B332 = rotate(B313,32-2); 622 | temp335 = ((temp229 ^ temp213) ^ temp279) ^ temp312; 623 | temp342 = rotate(temp335,32-31); 624 | D2249 = ((temp342 + 0x8F1BBCDC) + D314) + rotate(E331,32-27); 625 | D343 = D2249 + ((A319 | B332) & C320 | A319 & B332); 626 | A344 = rotate(A319,32-2); 627 | temp347 = ((temp237 ^ temp221) ^ temp288) ^ temp318; 628 | temp354 = rotate(temp347,32-31); 629 | D2251 = ((temp354 + 0x8F1BBCDC) + C320) + ((E331 | A344) & B332 | E331 & A344); 630 | C355 = D2251 + rotate(D343,32-27); 631 | E356 = rotate(E331,32-2); 632 | temp359 = ((temp246 ^ temp229) ^ temp294) ^ temp330; 633 | temp366 = rotate(temp359,32-31); 634 | D2253 = ((temp366 + 0x8F1BBCDC) + B332) + rotate(C355,32-27); 635 | B367 = D2253 + ((D343 | E356) & A344 | D343 & E356); 636 | D368 = rotate(D343,32-2); 637 | temp371 = ((temp255 ^ temp237) ^ temp300) ^ temp342; 638 | temp378 = rotate(temp371,32-31); 639 | D2255 = ((temp378 + 0x8F1BBCDC) + A344) + ((C355 | D368) & E356 | C355 & D368); 640 | A379 = D2255 + rotate(B367,32-27); 641 | C380 = rotate(C355,32-2); 642 | temp383 = ((temp263 ^ temp246) ^ temp306) ^ temp354; 643 | temp390 = rotate(temp383,32-31); 644 | D2257 = ((temp390 + 0x8F1BBCDC) + E356) + rotate(A379,32-27); 645 | E391 = D2257 + ((B367 | C380) & D368 | B367 & C380); 646 | B392 = rotate(B367,32-2); 647 | temp395 = ((temp271 ^ temp255) ^ temp312) ^ temp366; 648 | temp402 = rotate(temp395,32-31); 649 | D2259 = ((temp402 + 0x8F1BBCDC) + D368) + ((A379 | B392) & C380 | A379 & B392); 650 | D403 = D2259 + rotate(E391,32-27); 651 | A404 = rotate(A379,32-2); 652 | temp407 = ((temp279 ^ temp263) ^ temp318) ^ temp378; 653 | temp414 = rotate(temp407,32-31); 654 | D2261 = ((temp414 + 0x8F1BBCDC) + C380) + rotate(D403,32-27); 655 | C415 = D2261 + ((E391 | A404) & B392 | E391 & A404); 656 | E416 = rotate(E391,32-2); 657 | temp419 = ((temp288 ^ temp271) ^ temp330) ^ temp390; 658 | temp426 = rotate(temp419,32-31); 659 | D2263 = ((temp426 + 0x8F1BBCDC) + B392) + ((D403 | E416) & A404 | D403 & E416); 660 | B427 = D2263 + rotate(C415,32-27); 661 | D428 = rotate(D403,32-2); 662 | temp431 = ((temp294 ^ temp279) ^ temp342) ^ temp402; 663 | temp438 = rotate(temp431,32-31); 664 | D2265 = ((temp438 + 0x8F1BBCDC) + A404) + rotate(B427,32-27); 665 | A439 = D2265 + ((C415 | D428) & E416 | C415 & D428); 666 | C440 = rotate(C415,32-2); 667 | temp443 = ((temp300 ^ temp288) ^ temp354) ^ temp414; 668 | temp450 = rotate(temp443,32-31); 669 | D2267 = ((temp450 + 0x8F1BBCDC) + E416) + ((B427 | C440) & D428 | B427 & C440); 670 | E451 = D2267 + rotate(A439,32-27); 671 | B452 = rotate(B427,32-2); 672 | temp455 = ((temp306 ^ temp294) ^ temp366) ^ temp426; 673 | temp462 = rotate(temp455,32-31); 674 | D2269 = ((temp462 + 0x8F1BBCDC) + D428) + rotate(E451,32-27); 675 | D463 = D2269 + ((A439 | B452) & C440 | A439 & B452); 676 | A464 = rotate(A439,32-2); 677 | temp467 = ((temp312 ^ temp300) ^ temp378) ^ temp438; 678 | temp474 = rotate(temp467,32-31); 679 | D2271 = ((temp474 + 0x8F1BBCDC) + C440) + ((E451 | A464) & B452 | E451 & A464); 680 | C475 = D2271 + rotate(D463,32-27); 681 | E476 = rotate(E451,32-2); 682 | temp479 = ((temp318 ^ temp306) ^ temp390) ^ temp450; 683 | temp486 = rotate(temp479,32-31); 684 | D2273 = ((temp486 + 0x8F1BBCDC) + B452) + rotate(C475,32-27); 685 | B487 = D2273 + ((D463 | E476) & A464 | D463 & E476); 686 | D488 = rotate(D463,32-2); 687 | temp491 = ((temp330 ^ temp312) ^ temp402) ^ temp462; 688 | temp498 = rotate(temp491,32-31); 689 | D2275 = ((temp498 + 0x8F1BBCDC) + A464) + ((C475 | D488) & E476 | C475 & D488); 690 | A499 = D2275 + rotate(B487,32-27); 691 | C500 = rotate(C475,32-2); 692 | temp503 = ((temp342 ^ temp318) ^ temp414) ^ temp474; 693 | temp508 = rotate(temp503,32-31); 694 | D2277 = ((temp508 + 0xCA62C1D6) + E476) + ((C500 ^ D488) ^ B487); 695 | E509 = D2277 + rotate(A499,32-27); 696 | B510 = rotate(B487,32-2); 697 | temp513 = ((temp354 ^ temp330) ^ temp426) ^ temp486; 698 | temp518 = rotate(temp513,32-31); 699 | D2279 = ((temp518 + 0xCA62C1D6) + D488) + ((B510 ^ C500) ^ A499); 700 | D519 = D2279 + rotate(E509,32-27); 701 | A520 = rotate(A499,32-2); 702 | temp523 = ((temp366 ^ temp342) ^ temp438) ^ temp498; 703 | temp528 = rotate(temp523,32-31); 704 | D2281 = ((temp528 + 0xCA62C1D6) + C500) + ((A520 ^ B510) ^ E509); 705 | C529 = D2281 + rotate(D519,32-27); 706 | E530 = rotate(E509,32-2); 707 | temp533 = ((temp378 ^ temp354) ^ temp450) ^ temp508; 708 | temp538 = rotate(temp533,32-31); 709 | D2283 = ((temp538 + 0xCA62C1D6) + B510) + ((E530 ^ A520) ^ D519); 710 | B539 = D2283 + rotate(C529,32-27); 711 | D540 = rotate(D519,32-2); 712 | temp543 = ((temp390 ^ temp366) ^ temp462) ^ temp518; 713 | temp548 = rotate(temp543,32-31); 714 | D2285 = ((temp548 + 0xCA62C1D6) + A520) + ((D540 ^ E530) ^ C529); 715 | A549 = D2285 + rotate(B539,32-27); 716 | C550 = rotate(C529,32-2); 717 | temp553 = ((temp402 ^ temp378) ^ temp474) ^ temp528; 718 | temp558 = rotate(temp553,32-31); 719 | D2287 = ((temp558 + 0xCA62C1D6) + E530) + ((C550 ^ D540) ^ B539); 720 | E559 = D2287 + rotate(A549,32-27); 721 | B560 = rotate(B539,32-2); 722 | temp563 = ((temp414 ^ temp390) ^ temp486) ^ temp538; 723 | temp568 = rotate(temp563,32-31); 724 | D2289 = ((temp568 + 0xCA62C1D6) + D540) + ((B560 ^ C550) ^ A549); 725 | D569 = D2289 + rotate(E559,32-27); 726 | A570 = rotate(A549,32-2); 727 | temp573 = ((temp426 ^ temp402) ^ temp498) ^ temp548; 728 | temp578 = rotate(temp573,32-31); 729 | D2291 = ((temp578 + 0xCA62C1D6) + C550) + ((A570 ^ B560) ^ E559); 730 | C579 = D2291 + rotate(D569,32-27); 731 | E580 = rotate(E559,32-2); 732 | temp583 = ((temp438 ^ temp414) ^ temp508) ^ temp558; 733 | temp588 = rotate(temp583,32-31); 734 | D2293 = ((temp588 + 0xCA62C1D6) + B560) + ((E580 ^ A570) ^ D569); 735 | B589 = D2293 + rotate(C579,32-27); 736 | D590 = rotate(D569,32-2); 737 | temp593 = ((temp450 ^ temp426) ^ temp518) ^ temp568; 738 | temp598 = rotate(temp593,32-31); 739 | D2295 = ((temp598 + 0xCA62C1D6) + A570) + ((D590 ^ E580) ^ C579); 740 | A599 = D2295 + rotate(B589,32-27); 741 | C600 = rotate(C579,32-2); 742 | temp603 = ((temp462 ^ temp438) ^ temp528) ^ temp578; 743 | temp608 = rotate(temp603,32-31); 744 | D2297 = ((temp608 + 0xCA62C1D6) + E580) + ((C600 ^ D590) ^ B589); 745 | E609 = D2297 + rotate(A599,32-27); 746 | B610 = rotate(B589,32-2); 747 | temp613 = ((temp474 ^ temp450) ^ temp538) ^ temp588; 748 | temp618 = rotate(temp613,32-31); 749 | D2299 = ((temp618 + 0xCA62C1D6) + D590) + ((B610 ^ C600) ^ A599); 750 | D619 = D2299 + rotate(E609,32-27); 751 | A620 = rotate(A599,32-2); 752 | temp623 = ((temp486 ^ temp462) ^ temp548) ^ temp598; 753 | temp628 = rotate(temp623,32-31); 754 | D2301 = ((temp628 + 0xCA62C1D6) + C600) + ((A620 ^ B610) ^ E609); 755 | C629 = D2301 + rotate(D619,32-27); 756 | E630 = rotate(E609,32-2); 757 | temp633 = ((temp498 ^ temp474) ^ temp558) ^ temp608; 758 | temp638 = rotate(temp633,32-31); 759 | D2303 = ((temp638 + 0xCA62C1D6) + B610) + ((E630 ^ A620) ^ D619); 760 | B639 = D2303 + rotate(C629,32-27); 761 | D640 = rotate(D619,32-2); 762 | temp643 = ((temp508 ^ temp486) ^ temp568) ^ temp618; 763 | temp648 = rotate(temp643,32-31); 764 | D2305 = ((temp648 + 0xCA62C1D6) + A620) + ((D640 ^ E630) ^ C629); 765 | A649 = D2305 + rotate(B639,32-27); 766 | C650 = rotate(C629,32-2); 767 | temp653 = ((temp518 ^ temp498) ^ temp578) ^ temp628; 768 | temp658 = rotate(temp653,32-31); 769 | D2307 = ((temp658 + 0xCA62C1D6) + E630) + ((C650 ^ D640) ^ B639); 770 | E659 = D2307 + rotate(A649,32-27); 771 | B660 = rotate(B639,32-2); 772 | temp663 = ((temp528 ^ temp508) ^ temp588) ^ temp638; 773 | temp668 = rotate(temp663,32-31); 774 | D2309 = ((temp668 + 0xCA62C1D6) + D640) + ((B660 ^ C650) ^ A649); 775 | D669 = D2309 + rotate(E659,32-27); 776 | A670 = rotate(A649,32-2); 777 | temp673 = ((temp538 ^ temp518) ^ temp598) ^ temp648; 778 | D2311 = ((rotate(temp673,32-31) + 0xCA62C1D6) + C650) + ((A670 ^ B660) ^ E659); 779 | C679 = D2311 + rotate(D669,32-27); 780 | E680 = rotate(E659,32-2); 781 | temp683 = ((temp548 ^ temp528) ^ temp608) ^ temp658; 782 | D2313 = ((rotate(temp683,32-31) + 0xCA62C1D6) + B660) + ((E680 ^ A670) ^ D669); 783 | B689 = D2313 + rotate(C679,32-27); 784 | D690 = rotate(D669,32-2); 785 | temp693 = ((temp558 ^ temp538) ^ temp618) ^ temp668; 786 | D2315 = ((A + 0xCA62C1D6) + rotate(temp693,32-31)) + A670; 787 | data.h0 = (D2315 + ((D690 ^ E680) ^ C679)) + rotate(B689,32-27); 788 | data.h1 = B689 + ctx.h1; 789 | data.h2 = rotate(C679,32-2) + ctx.h2; 790 | data.h3 = D690 + ctx.h3; 791 | data.h4 = E680 + ctx.h4; 792 | } 793 | 794 | static void calpp_pmk_kernel( const input2d& inbuffer0, const input2d& inbuffer1, const input2d& inbuffer2, const input2d& inbuffer3, const input2d& inbuffer4, 795 | named_variable& outbuffer0, named_variable& outbuffer1 ) 796 | { 797 | SHA_DEV_CTX temp_ctx, pmk_ctx, ctx_ipad, ctx_opad; 798 | uint4 iv0,iv1,iv2,iv3,iv4; 799 | int1 i; 800 | 801 | float2 idx = named_variable("vWinCoord0.xy"); 802 | 803 | // loading ipad,opad,temp_ctx 804 | iv0 = inbuffer0[idx]; 805 | iv1 = inbuffer1[idx]; 806 | iv2 = inbuffer2[idx]; 807 | iv3 = inbuffer3[idx]; 808 | iv4 = inbuffer4[idx]; 809 | 810 | // unpacking data from input buffers 811 | ctx_ipad.assign( iv0.xx(), iv0.yy(), iv0.zz(), iv0.ww(), iv1.xx() ); 812 | ctx_opad.assign( iv1.yy(), iv1.zz(), iv1.ww(), iv2.xx(), iv2.yy() ); 813 | temp_ctx.assign( uint2(iv2.z(),iv3.w()), 814 | uint2(iv2.w(),iv4.x()), 815 | uint2(iv3.x(),iv4.y()), 816 | uint2(iv3.y(),iv4.z()), 817 | uint2(iv3.z(),iv4.w()) ); 818 | 819 | pmk_ctx = temp_ctx; 820 | i = 4096; 821 | il_whileloop { 822 | i += -1; 823 | il_breakc( !i ); 824 | 825 | sha1_process( ctx_ipad, temp_ctx ); 826 | sha1_process( ctx_opad, temp_ctx ); 827 | pmk_ctx ^= temp_ctx; 828 | } il_endloop 829 | 830 | outbuffer0 = uint4( pmk_ctx.h0.x(), pmk_ctx.h1.x(), pmk_ctx.h2.x(), pmk_ctx.h3.x() ); 831 | outbuffer1 = uint4( pmk_ctx.h4.x(), pmk_ctx.h0.y(), pmk_ctx.h1.y(), pmk_ctx.h2.y() ); 832 | } 833 | 834 | std::string calpp_create_pmk_kernel( cal::Device& device ) 835 | { 836 | std::stringstream code; 837 | 838 | code << "il_ps_2_0\n"; 839 | code << "dcl_input_position_interp(linear_noperspective) vWinCoord0.xy__\n"; 840 | 841 | Source::begin(device); 842 | 843 | input2d inbuffer0(0),inbuffer1(1),inbuffer2(2),inbuffer3(3),inbuffer4(4); 844 | named_variable outbuffer0("o0"),outbuffer1("o1"); 845 | 846 | calpp_pmk_kernel(inbuffer0,inbuffer1,inbuffer2,inbuffer3,inbuffer4, 847 | outbuffer0,outbuffer1); 848 | 849 | Source::end(); 850 | 851 | Source::emitHeader(code); 852 | Source::emitCode(code); 853 | 854 | code << "end\n"; 855 | 856 | return code.str(); 857 | } 858 | -------------------------------------------------------------------------------- /modules/cpyrit_calpp/_cpyrit_calpp_kernel_generator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | # 3 | # Copyright 2008-2011 Lukas Lueg, lukas.lueg@gmail.com 4 | # 5 | # This file is part of Pyrit. 6 | # 7 | # Pyrit is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # Pyrit is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Pyrit. If not, see . 19 | */ 20 | 21 | 22 | struct SHA_DEV_CTX 23 | { 24 | unsigned h0,h1,h2,h3,h4; 25 | }; 26 | 27 | /* This is a 'special-version' of the SHA1 round function. *ctx is the current state, 28 | that gets updated by *data. Notice the lack of endianess-changes here. 29 | This SHA1-implementation follows the more-instructions-less-space paradigm, since registers 30 | and (fast) memory on the device are precious, threads are not. Only the starting values 31 | of W[0] to W[4] are defined by parameters. We fix the rest to invariant values and leave 32 | the possible register allocation optimization to the compiler. 33 | */ 34 | void sha1_process( SHA_DEV_CTX& ctx, SHA_DEV_CTX& data) 35 | { 36 | unsigned temp, W[16], A, B, C, D, E; 37 | 38 | W[ 0] = data.h0; W[ 1] = data.h1; 39 | W[ 2] = data.h2; W[ 3] = data.h3; 40 | W[ 4] = data.h4; W[ 5] = unsigned(0x80000000); 41 | W[ 6] = unsigned(0); W[ 7] = unsigned(0); 42 | W[ 8] = unsigned(0); W[ 9] = unsigned(0); 43 | W[10] = unsigned(0); W[11] = unsigned(0); 44 | W[12] = unsigned(0); W[13] = unsigned(0); 45 | W[14] = unsigned(0); W[15] = unsigned((64+20)*8); 46 | 47 | A = ctx.h0; 48 | B = ctx.h1; 49 | C = ctx.h2; 50 | D = ctx.h3; 51 | E = ctx.h4; 52 | 53 | #undef S 54 | #define S(x,n) ((x << n) | (x >> (32 - n))) 55 | 56 | #undef R 57 | #define R(t) \ 58 | ( \ 59 | temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \ 60 | W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \ 61 | ( W[t & 0x0F] = S(temp,1) ) \ 62 | ) 63 | 64 | #undef P 65 | #define P(a,b,c,d,e,x) \ 66 | { \ 67 | e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ 68 | } 69 | 70 | #define F(x,y,z) (z ^ (x & (y ^ z))) 71 | #define K 0x5A827999 72 | 73 | P( A, B, C, D, E, W[0] ); 74 | P( E, A, B, C, D, W[1] ); 75 | P( D, E, A, B, C, W[2] ); 76 | P( C, D, E, A, B, W[3] ); 77 | P( B, C, D, E, A, W[4] ); 78 | P( A, B, C, D, E, W[5] ); 79 | P( E, A, B, C, D, W[6] ); 80 | P( D, E, A, B, C, W[7] ); 81 | P( C, D, E, A, B, W[8] ); 82 | P( B, C, D, E, A, W[9] ); 83 | P( A, B, C, D, E, W[10] ); 84 | P( E, A, B, C, D, W[11] ); 85 | P( D, E, A, B, C, W[12] ); 86 | P( C, D, E, A, B, W[13] ); 87 | P( B, C, D, E, A, W[14] ); 88 | P( A, B, C, D, E, W[15] ); 89 | P( E, A, B, C, D, R(16) ); 90 | P( D, E, A, B, C, R(17) ); 91 | P( C, D, E, A, B, R(18) ); 92 | P( B, C, D, E, A, R(19) ); 93 | 94 | #undef K 95 | #undef F 96 | 97 | #define F(x,y,z) (x ^ y ^ z) 98 | #define K 0x6ED9EBA1 99 | 100 | P( A, B, C, D, E, R(20) ); 101 | P( E, A, B, C, D, R(21) ); 102 | P( D, E, A, B, C, R(22) ); 103 | P( C, D, E, A, B, R(23) ); 104 | P( B, C, D, E, A, R(24) ); 105 | P( A, B, C, D, E, R(25) ); 106 | P( E, A, B, C, D, R(26) ); 107 | P( D, E, A, B, C, R(27) ); 108 | P( C, D, E, A, B, R(28) ); 109 | P( B, C, D, E, A, R(29) ); 110 | P( A, B, C, D, E, R(30) ); 111 | P( E, A, B, C, D, R(31) ); 112 | P( D, E, A, B, C, R(32) ); 113 | P( C, D, E, A, B, R(33) ); 114 | P( B, C, D, E, A, R(34) ); 115 | P( A, B, C, D, E, R(35) ); 116 | P( E, A, B, C, D, R(36) ); 117 | P( D, E, A, B, C, R(37) ); 118 | P( C, D, E, A, B, R(38) ); 119 | P( B, C, D, E, A, R(39) ); 120 | 121 | #undef K 122 | #undef F 123 | 124 | #define F(x,y,z) ((x & y) | (z & (x | y))) 125 | #define K 0x8F1BBCDC 126 | 127 | P( A, B, C, D, E, R(40) ); 128 | P( E, A, B, C, D, R(41) ); 129 | P( D, E, A, B, C, R(42) ); 130 | P( C, D, E, A, B, R(43) ); 131 | P( B, C, D, E, A, R(44) ); 132 | P( A, B, C, D, E, R(45) ); 133 | P( E, A, B, C, D, R(46) ); 134 | P( D, E, A, B, C, R(47) ); 135 | P( C, D, E, A, B, R(48) ); 136 | P( B, C, D, E, A, R(49) ); 137 | P( A, B, C, D, E, R(50) ); 138 | P( E, A, B, C, D, R(51) ); 139 | P( D, E, A, B, C, R(52) ); 140 | P( C, D, E, A, B, R(53) ); 141 | P( B, C, D, E, A, R(54) ); 142 | P( A, B, C, D, E, R(55) ); 143 | P( E, A, B, C, D, R(56) ); 144 | P( D, E, A, B, C, R(57) ); 145 | P( C, D, E, A, B, R(58) ); 146 | P( B, C, D, E, A, R(59) ); 147 | 148 | #undef K 149 | #undef F 150 | 151 | #define F(x,y,z) (x ^ y ^ z) 152 | #define K 0xCA62C1D6 153 | 154 | P( A, B, C, D, E, R(60) ); 155 | P( E, A, B, C, D, R(61) ); 156 | P( D, E, A, B, C, R(62) ); 157 | P( C, D, E, A, B, R(63) ); 158 | P( B, C, D, E, A, R(64) ); 159 | P( A, B, C, D, E, R(65) ); 160 | P( E, A, B, C, D, R(66) ); 161 | P( D, E, A, B, C, R(67) ); 162 | P( C, D, E, A, B, R(68) ); 163 | P( B, C, D, E, A, R(69) ); 164 | P( A, B, C, D, E, R(70) ); 165 | P( E, A, B, C, D, R(71) ); 166 | P( D, E, A, B, C, R(72) ); 167 | P( C, D, E, A, B, R(73) ); 168 | P( B, C, D, E, A, R(74) ); 169 | P( A, B, C, D, E, R(75) ); 170 | P( E, A, B, C, D, R(76) ); 171 | P( D, E, A, B, C, R(77) ); 172 | P( C, D, E, A, B, R(78) ); 173 | P( B, C, D, E, A, R(79) ); 174 | 175 | #undef K 176 | #undef F 177 | 178 | data.h0 = ctx.h0 + A; 179 | data.h1 = ctx.h1 + B; 180 | data.h2 = ctx.h2 + C; 181 | data.h3 = ctx.h3 + D; 182 | data.h4 = ctx.h4 + E; 183 | } 184 | -------------------------------------------------------------------------------- /modules/cpyrit_calpp/convert_optimized.sed: -------------------------------------------------------------------------------- 1 | s/\([a-zA-Z]\+\)\.\([0-9]\+\)/\1\2/g 2 | s/(\([a-zA-Z0-9]\+\) r>> \([0-9]\+\))/rotate(\1,32-\2)/g 3 | s/ \([a-zA-Z0-9]\+\) r>> \([0-9]\+\);/ rotate(\1,32-\2);/ 4 | s/ (\(.\+\)) r>> \([0-9]\+\);/ rotate((\1),32-\2);/ 5 | s/data->/data./g 6 | s/ctx->/ctx./g 7 | s/unsigned int/uint2/g 8 | -------------------------------------------------------------------------------- /modules/cpyrit_calpp/generate_optimized_kernel: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | # 3 | # Copyright 2010, 2011 Artur Kornacki, hazeman11@gmail.com 4 | # 5 | # This file is part of Pyrit. 6 | # 7 | # Pyrit is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # Pyrit is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Pyrit. If not, see . 19 | # 20 | 21 | gcc -fdump-tree-optimized -O3 -c _cpyrit_calpp_kernel_generator.cpp 22 | sed -f convert_optimized.sed _cpyrit_calpp_kernel_generator.cpp.*.optimized > _cpyrit_calpp_kernel_optimized.cpp -------------------------------------------------------------------------------- /modules/cpyrit_calpp/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: UTF-8 -*- 3 | # 4 | # Copyright 2008-2011, Lukas Lueg, lukas.lueg@gmail.com 5 | # 6 | # This file is part of Pyrit. 7 | # 8 | # Pyrit is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # Pyrit is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with Pyrit. If not, see . 20 | 21 | from distutils.core import setup, Extension 22 | from distutils.command.build_ext import build_ext 23 | from distutils.command.clean import clean 24 | import os 25 | import re 26 | import subprocess 27 | import sys 28 | 29 | VERSION = '0.5.0' 30 | 31 | 32 | CALPP_INC_DIRS = [] 33 | 34 | try: 35 | CALPP_INC_DIR = os.environ['ATISTREAMSDKROOT'] 36 | except KeyError: 37 | print >>sys.stderr, "unavailable enviroment variable ATISTREAMSDKROOT" 38 | raise 39 | else: 40 | if os.path.exists(CALPP_INC_DIR): 41 | CALPP_INC_DIRS.append(os.path.join(CALPP_INC_DIR, 'include')) 42 | else: 43 | print >>sys.stderr, "The headers required to build CAL++ kernel" \ 44 | "were not found. Trying to continue anyway..." 45 | 46 | 47 | EXTRA_COMPILE_ARGS = ['-Wall', '-fno-strict-aliasing', \ 48 | '-DVERSION="%s"' % (VERSION,)] 49 | 50 | 51 | class GPUBuilder(build_ext): 52 | def run(self): 53 | print "Building modules..." 54 | build_ext.run(self) 55 | 56 | 57 | class GPUCleaner(clean): 58 | 59 | def _unlink(self, node): 60 | try: 61 | if os.path.isdir(node): 62 | os.rmdir(node) 63 | else: 64 | os.unlink(node) 65 | except OSError: 66 | pass 67 | 68 | def run(self): 69 | print "Removing temporary files and pre-built GPU-kernels..." 70 | clean.run(self) 71 | 72 | 73 | calpp_extension = Extension('cpyrit._cpyrit_calpp', 74 | libraries = ['crypto', 'aticalrt', 'aticalcl'], 75 | sources = ['_cpyrit_calpp.cpp', '_cpyrit_calpp_kernel.cpp'], 76 | include_dirs = CALPP_INC_DIRS, 77 | extra_compile_args = EXTRA_COMPILE_ARGS) 78 | 79 | setup_args = dict( 80 | name = 'cpyrit-calpp', 81 | version = VERSION, 82 | description = 'GPU-accelerated attack against WPA-PSK authentication', 83 | long_description = \ 84 | "Pyrit allows to create massive databases, pre-computing part " \ 85 | "of the WPA/WPA2-PSK authentication phase in a space-time-" \ 86 | "tradeoff. Exploiting the computational power of Many-Core- " \ 87 | "and other platforms through ATI-Stream, Nvidia CUDA, OpenCL " \ 88 | "and VIA Padlock, it is currently by far the most powerful " \ 89 | "attack against one of the world's most used security-protocols.", 90 | license = 'GNU General Public License v3', 91 | author = 'Lukas Lueg, Artur Kornacki', 92 | author_email = 'lukas.lueg@gmail.com', 93 | url = 'https://github.com/JPaulMora/Pyrit', 94 | maintainer = 'John Mora', 95 | maintainer_email = 'johmora12@engineer.com', 96 | classifiers = \ 97 | ['Development Status :: 4 - Beta', 98 | 'Environment :: Console', 99 | 'License :: OSI Approved :: GNU General Public License (GPL)', 100 | 'Natural Language :: English', 101 | 'Operating System :: OS Independent', 102 | 'Programming Language :: Python', 103 | 'Topic :: Security'], 104 | platforms = ['any'], 105 | ext_modules = [calpp_extension], 106 | cmdclass = {'build_ext': GPUBuilder, 'clean': GPUCleaner}, 107 | options = {'install': {'optimize': 1}, \ 108 | 'bdist_rpm': {'requires': 'pyrit = 0.4.0-1'}}) 109 | 110 | if __name__ == "__main__": 111 | setup(**setup_args) 112 | -------------------------------------------------------------------------------- /modules/cpyrit_cuda/.gitignore: -------------------------------------------------------------------------------- 1 | temp* 2 | *cudakernel* 3 | -------------------------------------------------------------------------------- /modules/cpyrit_cuda/MANIFEST.in: -------------------------------------------------------------------------------- 1 | include COPYING 2 | include README 3 | include MANIFEST.in 4 | include _cpyrit_cuda.h 5 | include _cpyrit_cudakernel.cu 6 | -------------------------------------------------------------------------------- /modules/cpyrit_cuda/_cpyrit_cuda.c: -------------------------------------------------------------------------------- 1 | /* 2 | # 3 | # Copyright 2008-2011, Lukas Lueg, lukas.lueg@gmail.com 4 | # 5 | # This file is part of Pyrit. 6 | # 7 | # Pyrit is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # Pyrit is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Pyrit. If not, see . 19 | # 20 | # Additional permission under GNU GPL version 3 section 7 21 | # 22 | # If you modify this Program, or any covered work, by linking or 23 | # combining it with the OpenSSL project's "OpenSSL" library (or a 24 | # modified version of that library), containing parts covered by 25 | # the terms of OpenSSL/SSLeay license, the licensors of this 26 | # Program grant you additional permission to convey the resulting 27 | # work. Corresponding Source for a non-source form of such a 28 | # combination shall include the source code for the parts of the 29 | # OpenSSL library used as well as that of the covered work. 30 | # 31 | # If you modify this Program, or any covered work, by linking or 32 | # combining it with NVIDIA Corporation's CUDA libraries from the 33 | # NVIDIA CUDA Toolkit (or a modified version of those libraries), 34 | # containing parts covered by the terms of NVIDIA CUDA Toolkit 35 | # EULA, the licensors of this Program grant you additional 36 | # permission to convey the resulting work. 37 | */ 38 | 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include "_cpyrit_cuda.h" 45 | 46 | // Created by NVCC and setup.py 47 | #include "_cpyrit_cudakernel.ptx.h" 48 | 49 | static PyTypeObject CUDADevice_type; 50 | 51 | typedef struct 52 | { 53 | PyObject_HEAD 54 | int dev_idx; 55 | PyObject* dev_name; 56 | CUmodule mod; 57 | CUfunction kernel; 58 | CUcontext dev_ctx; 59 | } CUDADevice; 60 | 61 | int cudaDevCount; 62 | unsigned char *cudakernel_module; 63 | 64 | static char* 65 | getCUresultMsg(CUresult error) 66 | { 67 | switch (error) 68 | { 69 | case CUDA_SUCCESS : return "CUDA_SUCCESS"; 70 | case CUDA_ERROR_INVALID_VALUE : return "CUDA_ERROR_INVALID_VALUE"; 71 | case CUDA_ERROR_OUT_OF_MEMORY : return "CUDA_ERROR_OUT_OF_MEMORY"; 72 | case CUDA_ERROR_NOT_INITIALIZED : return "CUDA_ERROR_NOT_INITIALIZED"; 73 | case CUDA_ERROR_DEINITIALIZED : return "CUDA_ERROR_DEINITIALIZED"; 74 | case CUDA_ERROR_NO_DEVICE : return "CUDA_ERROR_NO_DEVICE"; 75 | case CUDA_ERROR_INVALID_DEVICE : return "CUDA_ERROR_INVALID_DEVICE"; 76 | case CUDA_ERROR_INVALID_IMAGE : return "CUDA_ERROR_INVALID_IMAGE"; 77 | case CUDA_ERROR_INVALID_CONTEXT : return "CUDA_ERROR_INVALID_CONTEXT"; 78 | case CUDA_ERROR_CONTEXT_ALREADY_CURRENT : return "CUDA_ERROR_CONTEXT_ALREADY_CURRENT"; 79 | case CUDA_ERROR_MAP_FAILED : return "CUDA_ERROR_MAP_FAILED"; 80 | case CUDA_ERROR_UNMAP_FAILED : return "CUDA_ERROR_UNMAP_FAILED"; 81 | case CUDA_ERROR_ARRAY_IS_MAPPED : return "CUDA_ERROR_ARRAY_IS_MAPPED"; 82 | case CUDA_ERROR_ALREADY_MAPPED : return "CUDA_ERROR_ALREADY_MAPPED"; 83 | case CUDA_ERROR_NO_BINARY_FOR_GPU : return "CUDA_ERROR_NO_BINARY_FOR_GPU"; 84 | case CUDA_ERROR_ALREADY_ACQUIRED : return "CUDA_ERROR_ALREADY_ACQUIRED"; 85 | case CUDA_ERROR_NOT_MAPPED : return "CUDA_ERROR_NOT_MAPPED"; 86 | case CUDA_ERROR_INVALID_SOURCE : return "CUDA_ERROR_INVALID_SOURCE"; 87 | case CUDA_ERROR_FILE_NOT_FOUND : return "CUDA_ERROR_FILE_NOT_FOUND"; 88 | case CUDA_ERROR_INVALID_HANDLE : return "CASE_ERROR_INVALID_HANDLE"; 89 | case CUDA_ERROR_NOT_FOUND : return "CUDA_ERROR_NOT_FOUND"; 90 | case CUDA_ERROR_NOT_READY : return "CUDA_ERROR_NOT_READY"; 91 | case CUDA_ERROR_LAUNCH_FAILED : return "CUDA_ERROR_LAUNCH_FAILED"; 92 | case CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES : return "CUDA_ERROR_LAUNCH_OUT_OF_RESOUCES"; 93 | case CUDA_ERROR_LAUNCH_TIMEOUT : return "CUDA_ERROR_LAUNCH_TIMEOUT"; 94 | case CUDA_ERROR_LAUNCH_INCOMPATIBLE_TEXTURING : return "CUDA_ERROR_LAUNCH_INCOMPATIBLE_TEXTURING"; 95 | case CUDA_ERROR_UNKNOWN : return "CUDA_ERROR_UNKNOWN"; 96 | default : return "Unknown CUresult."; 97 | } 98 | } 99 | 100 | static int 101 | cudadev_init(CUDADevice *self, PyObject *args, PyObject *kwds) 102 | { 103 | int dev_idx; 104 | CUresult ret; 105 | char dev_name[64]; 106 | 107 | if (!PyArg_ParseTuple(args, "i:CUDADevice", &dev_idx)) 108 | return -1; 109 | 110 | if (dev_idx < 0 || dev_idx > cudaDevCount-1) 111 | { 112 | PyErr_SetString(PyExc_SystemError, "Invalid device number"); 113 | return -1; 114 | } 115 | self->dev_idx = dev_idx; 116 | self->dev_name = NULL; 117 | self->mod = NULL; 118 | self->dev_ctx = NULL; 119 | 120 | CUSAFECALL(cuDeviceGetName(dev_name, sizeof(dev_name), self->dev_idx)); 121 | self->dev_name = PyString_FromString(dev_name); 122 | if (!self->dev_name) 123 | { 124 | PyErr_NoMemory(); 125 | return -1; 126 | } 127 | 128 | CUSAFECALL(cuCtxCreate(&self->dev_ctx, CU_CTX_SCHED_YIELD, self->dev_idx)); 129 | 130 | CUSAFECALL(cuModuleLoadDataEx(&self->mod, cudakernel_module, 0, 0, 0)); 131 | 132 | CUSAFECALL(cuModuleGetFunction(&self->kernel, self->mod, "cuda_pmk_kernel")); 133 | 134 | CUSAFECALL(cuFuncSetBlockShape(self->kernel, THREADS_PER_BLOCK, 1, 1)); 135 | 136 | CUSAFECALL(cuCtxPopCurrent(NULL)); 137 | 138 | return 0; 139 | 140 | errout: 141 | PyErr_SetString(PyExc_SystemError, getCUresultMsg(ret)); 142 | return -1; 143 | 144 | } 145 | 146 | static void 147 | cudadev_dealloc(CUDADevice *self) 148 | { 149 | if (self->mod) 150 | cuModuleUnload(self->mod); 151 | if (self->dev_ctx) 152 | cuCtxDestroy(self->dev_ctx); 153 | Py_XDECREF(self->dev_name); 154 | self->ob_type->tp_free((PyObject*)self); 155 | } 156 | 157 | static PyObject* 158 | cpyrit_listDevices(PyObject* self, PyObject* args) 159 | { 160 | int i; 161 | PyObject* result; 162 | char dev_name[64]; 163 | 164 | if (!PyArg_ParseTuple(args, "")) return NULL; 165 | 166 | result = PyTuple_New(cudaDevCount); 167 | for (i = 0; i < cudaDevCount; i++) 168 | { 169 | cuDeviceGetName(dev_name, sizeof(dev_name), i); 170 | PyTuple_SetItem(result, i, Py_BuildValue("(s)", &dev_name)); 171 | } 172 | 173 | return result; 174 | } 175 | 176 | static CUresult 177 | calc_pmklist(CUDADevice *self, gpu_inbuffer *inbuffer, gpu_outbuffer* outbuffer, int size) 178 | { 179 | CUdeviceptr g_inbuffer, g_outbuffer; 180 | CUresult ret; 181 | int buffersize, offset; 182 | void* ptr; 183 | 184 | // Align size of memory allocation and operations to full threadblocks. Threadblocks should be aligned to warp-size. 185 | buffersize = (size / THREADS_PER_BLOCK + (size % THREADS_PER_BLOCK == 0 ? 0 : 1)) * THREADS_PER_BLOCK; 186 | g_inbuffer = 0; 187 | g_outbuffer = 0; 188 | 189 | CUSAFECALL(cuMemAlloc(&g_inbuffer, buffersize*sizeof(gpu_inbuffer))); 190 | 191 | CUSAFECALL(cuMemAlloc(&g_outbuffer, buffersize*sizeof(gpu_outbuffer))); 192 | 193 | CUSAFECALL(cuMemcpyHtoD(g_inbuffer, inbuffer, size*sizeof(gpu_inbuffer))); 194 | 195 | offset = 0; 196 | 197 | ptr = (void*)(size_t)g_inbuffer; 198 | ALIGN_UP(offset, __alignof(ptr)); 199 | cuParamSetv(self->kernel, offset, &ptr, sizeof(ptr)); 200 | offset += sizeof(ptr); 201 | 202 | ptr = (void*)(size_t)g_outbuffer; 203 | ALIGN_UP(offset, __alignof(ptr)); 204 | cuParamSetv(self->kernel, offset, &ptr, sizeof(ptr)); 205 | offset += sizeof(ptr); 206 | 207 | cuParamSetSize(self->kernel, offset); 208 | CUSAFECALL(cuLaunchGrid(self->kernel, buffersize / THREADS_PER_BLOCK, 1)); 209 | 210 | CUSAFECALL(cuMemcpyDtoH(outbuffer, g_outbuffer, size*sizeof(gpu_outbuffer))); 211 | 212 | cuMemFree(g_inbuffer); 213 | cuMemFree(g_outbuffer); 214 | 215 | return CUDA_SUCCESS; 216 | 217 | errout: 218 | if (g_inbuffer != 0) 219 | cuMemFree(g_inbuffer); 220 | if (g_outbuffer != 0) 221 | cuMemFree(g_outbuffer); 222 | return ret; 223 | } 224 | 225 | static PyObject* 226 | cpyrit_solve(CUDADevice *self, PyObject *args) 227 | { 228 | unsigned char essid[32+4], *passwd, pad[64], temp[32]; 229 | int i, arraysize, essidlen, passwdlen; 230 | PyObject *essid_obj, *passwd_seq, *passwd_obj, *result; 231 | gpu_inbuffer *c_inbuffer, *t; 232 | gpu_outbuffer *c_outbuffer; 233 | SHA_CTX ctx_pad; 234 | 235 | if (!PyArg_ParseTuple(args, "OO", &essid_obj, &passwd_seq)) return NULL; 236 | passwd_seq = PyObject_GetIter(passwd_seq); 237 | if (!passwd_seq) return NULL; 238 | 239 | essidlen = PyString_Size(essid_obj); 240 | if (essidlen < 1 || essidlen > 32) 241 | { 242 | Py_DECREF(passwd_seq); 243 | PyErr_SetString(PyExc_ValueError, "The ESSID must be a string between 1 and 32 characters"); 244 | return NULL; 245 | } 246 | memcpy(essid, PyString_AsString(essid_obj), essidlen); 247 | memset(essid + essidlen, 0, sizeof(essid) - essidlen); 248 | 249 | arraysize = 0; 250 | c_inbuffer = NULL; 251 | c_outbuffer = NULL; 252 | while ((passwd_obj = PyIter_Next(passwd_seq))) 253 | { 254 | if (arraysize % 1000 == 0) 255 | { 256 | t = PyMem_Realloc(c_inbuffer, sizeof(gpu_inbuffer)*(arraysize+1000)); 257 | if (!t) 258 | { 259 | Py_DECREF(passwd_obj); 260 | Py_DECREF(passwd_seq); 261 | PyMem_Free(c_inbuffer); 262 | PyErr_NoMemory(); 263 | return NULL; 264 | } 265 | c_inbuffer = t; 266 | } 267 | passwd = (unsigned char*)PyString_AsString(passwd_obj); 268 | passwdlen = PyString_Size(passwd_obj); 269 | if (passwd == NULL || passwdlen < 8 || passwdlen > 63) 270 | { 271 | Py_DECREF(passwd_obj); 272 | Py_DECREF(passwd_seq); 273 | PyMem_Free(c_inbuffer); 274 | PyErr_SetString(PyExc_ValueError, "All passwords must be strings between 8 and 63 characters"); 275 | return NULL; 276 | } 277 | 278 | memcpy(pad, passwd, passwdlen); 279 | memset(pad + passwdlen, 0, sizeof(pad) - passwdlen); 280 | for (i = 0; i < 16; i++) 281 | ((unsigned int*)pad)[i] ^= 0x36363636; 282 | SHA1_Init(&ctx_pad); 283 | SHA1_Update(&ctx_pad, pad, sizeof(pad)); 284 | CPY_DEVCTX(ctx_pad, c_inbuffer[arraysize].ctx_ipad); 285 | for (i = 0; i < 16; i++) 286 | ((unsigned int*)pad)[i] ^= 0x6A6A6A6A; 287 | SHA1_Init(&ctx_pad); 288 | SHA1_Update(&ctx_pad, pad, sizeof(pad)); 289 | CPY_DEVCTX(ctx_pad, c_inbuffer[arraysize].ctx_opad); 290 | 291 | essid[essidlen + 4 - 1] = '\1'; 292 | HMAC(EVP_sha1(), passwd, passwdlen, essid, essidlen + 4, temp, NULL); 293 | GET_BE(c_inbuffer[arraysize].e1.h0, temp, 0); 294 | GET_BE(c_inbuffer[arraysize].e1.h1, temp, 4); 295 | GET_BE(c_inbuffer[arraysize].e1.h2, temp, 8); 296 | GET_BE(c_inbuffer[arraysize].e1.h3, temp, 12); 297 | GET_BE(c_inbuffer[arraysize].e1.h4, temp, 16); 298 | 299 | essid[essidlen + 4 - 1] = '\2'; 300 | HMAC(EVP_sha1(), passwd, passwdlen, essid, essidlen + 4, temp, NULL); 301 | GET_BE(c_inbuffer[arraysize].e2.h0, temp, 0); 302 | GET_BE(c_inbuffer[arraysize].e2.h1, temp, 4); 303 | GET_BE(c_inbuffer[arraysize].e2.h2, temp, 8); 304 | GET_BE(c_inbuffer[arraysize].e2.h3, temp, 12); 305 | GET_BE(c_inbuffer[arraysize].e2.h4, temp, 16); 306 | 307 | Py_DECREF(passwd_obj); 308 | arraysize++; 309 | } 310 | Py_DECREF(passwd_seq); 311 | 312 | if (arraysize == 0) 313 | { 314 | PyMem_Free(c_inbuffer); 315 | return PyTuple_New(0); 316 | } 317 | 318 | c_outbuffer = PyMem_New(gpu_outbuffer, arraysize); 319 | if (c_outbuffer == NULL) 320 | { 321 | PyMem_Free(c_inbuffer); 322 | return PyErr_NoMemory(); 323 | } 324 | 325 | i = cuCtxPushCurrent(self->dev_ctx); 326 | if (i != CUDA_SUCCESS) 327 | { 328 | PyErr_SetString(PyExc_SystemError, getCUresultMsg(i)); 329 | PyMem_Free(c_inbuffer); 330 | PyMem_Free(c_outbuffer); 331 | return NULL; 332 | } 333 | 334 | Py_BEGIN_ALLOW_THREADS; 335 | i = calc_pmklist(self, c_inbuffer, c_outbuffer, arraysize); 336 | Py_END_ALLOW_THREADS; 337 | cuCtxPopCurrent(NULL); 338 | PyMem_Free(c_inbuffer); 339 | 340 | if (i != CUDA_SUCCESS) 341 | { 342 | PyMem_Free(c_outbuffer); 343 | PyErr_SetString(PyExc_SystemError, getCUresultMsg(i)); 344 | return NULL; 345 | } 346 | 347 | result = PyTuple_New(arraysize); 348 | for (i = 0; i < arraysize; i++) 349 | { 350 | PUT_BE(c_outbuffer[i].pmk1.h0, temp, 0); PUT_BE(c_outbuffer[i].pmk1.h1, temp, 4); 351 | PUT_BE(c_outbuffer[i].pmk1.h2, temp, 8); PUT_BE(c_outbuffer[i].pmk1.h3, temp, 12); 352 | PUT_BE(c_outbuffer[i].pmk1.h4, temp, 16);PUT_BE(c_outbuffer[i].pmk2.h0, temp, 20); 353 | PUT_BE(c_outbuffer[i].pmk2.h1, temp, 24);PUT_BE(c_outbuffer[i].pmk2.h2, temp, 28); 354 | PyTuple_SetItem(result, i, PyString_FromStringAndSize((char*)temp, 32)); 355 | } 356 | 357 | PyMem_Free(c_outbuffer); 358 | 359 | return result; 360 | } 361 | 362 | static PyMemberDef CUDADevice_members[] = 363 | { 364 | {"deviceName", T_OBJECT, offsetof(CUDADevice, dev_name), 0}, 365 | {NULL} 366 | }; 367 | 368 | static PyMethodDef CUDADevice_methods[] = 369 | { 370 | {"solve", (PyCFunction)cpyrit_solve, METH_VARARGS, "Calculate PMKs from ESSID and iterable of strings."}, 371 | {NULL, NULL} 372 | }; 373 | 374 | static PyTypeObject CUDADevice_type = { 375 | PyObject_HEAD_INIT(NULL) 376 | 0, /*ob_size*/ 377 | "_cpyrit_cuda.CUDADevice", /*tp_name*/ 378 | sizeof(CUDADevice), /*tp_basicsize*/ 379 | 0, /*tp_itemsize*/ 380 | (destructor)cudadev_dealloc,/*tp_dealloc*/ 381 | 0, /*tp_print*/ 382 | 0, /*tp_getattr*/ 383 | 0, /*tp_setattr*/ 384 | 0, /*tp_compare*/ 385 | 0, /*tp_repr*/ 386 | 0, /*tp_as_number*/ 387 | 0, /*tp_as_sequence*/ 388 | 0, /*tp_as_mapping*/ 389 | 0, /*tp_hash*/ 390 | 0, /*tp_call*/ 391 | 0, /*tp_str*/ 392 | 0, /*tp_getattro*/ 393 | 0, /*tp_setattro*/ 394 | 0, /*tp_as_buffer*/ 395 | Py_TPFLAGS_DEFAULT /*tp_flags*/ 396 | | Py_TPFLAGS_BASETYPE, 397 | 0, /*tp_doc*/ 398 | 0, /*tp_traverse*/ 399 | 0, /*tp_clear*/ 400 | 0, /*tp_richcompare*/ 401 | 0, /*tp_weaklistoffset*/ 402 | 0, /*tp_iter*/ 403 | 0, /*tp_iternext*/ 404 | CUDADevice_methods, /*tp_methods*/ 405 | CUDADevice_members, /*tp_members*/ 406 | 0, /*tp_getset*/ 407 | 0, /*tp_base*/ 408 | 0, /*tp_dict*/ 409 | 0, /*tp_descr_get*/ 410 | 0, /*tp_descr_set*/ 411 | 0, /*tp_dictoffset*/ 412 | (initproc)cudadev_init, /*tp_init*/ 413 | 0, /*tp_alloc*/ 414 | 0, /*tp_new*/ 415 | 0, /*tp_free*/ 416 | 0, /*tp_is_gc*/ 417 | }; 418 | 419 | 420 | static PyMethodDef CPyritCUDA_methods[] = { 421 | {"listDevices", cpyrit_listDevices, METH_VARARGS, "Returns a tuple of tuples, each describing a CUDA-capable device."}, 422 | {NULL, NULL, 0, NULL} 423 | }; 424 | 425 | PyMODINIT_FUNC 426 | init_cpyrit_cuda(void) 427 | { 428 | PyObject *m; 429 | z_stream zst; 430 | 431 | if (cuInit(0) != CUDA_SUCCESS || cuDeviceGetCount(&cudaDevCount) != CUDA_SUCCESS || cudaDevCount < 1) 432 | { 433 | PyErr_SetString(PyExc_ImportError, "CUDA seems to be unavailable or no device reported."); 434 | return; 435 | } 436 | 437 | cudakernel_module = PyMem_Malloc(cudakernel_modulesize); 438 | if (!cudakernel_module) 439 | { 440 | PyErr_NoMemory(); 441 | return; 442 | } 443 | zst.zalloc = Z_NULL; 444 | zst.zfree = Z_NULL; 445 | zst.opaque = Z_NULL; 446 | zst.avail_in = sizeof(__cudakernel_packedmodule); 447 | zst.next_in = __cudakernel_packedmodule; 448 | if (inflateInit(&zst) != Z_OK) 449 | { 450 | PyMem_Free(cudakernel_module); 451 | PyErr_SetString(PyExc_IOError, "Failed to initialize zlib."); 452 | return; 453 | } 454 | zst.avail_out = cudakernel_modulesize; 455 | zst.next_out = cudakernel_module; 456 | if (inflate(&zst, Z_FINISH) != Z_STREAM_END) 457 | { 458 | inflateEnd(&zst); 459 | PyMem_Free(cudakernel_module); 460 | PyErr_SetString(PyExc_IOError, "Failed to decompress CUDA-kernel."); 461 | return; 462 | } 463 | inflateEnd(&zst); 464 | 465 | CUDADevice_type.tp_getattro = PyObject_GenericGetAttr; 466 | CUDADevice_type.tp_setattro = PyObject_GenericSetAttr; 467 | CUDADevice_type.tp_alloc = PyType_GenericAlloc; 468 | CUDADevice_type.tp_new = PyType_GenericNew; 469 | CUDADevice_type.tp_free = PyObject_Del; 470 | if (PyType_Ready(&CUDADevice_type) < 0) 471 | return; 472 | 473 | m = Py_InitModule("_cpyrit_cuda", CPyritCUDA_methods); 474 | 475 | Py_INCREF(&CUDADevice_type); 476 | PyModule_AddObject(m, "CUDADevice", (PyObject*)&CUDADevice_type); 477 | PyModule_AddStringConstant(m, "VERSION", VERSION); 478 | } 479 | 480 | -------------------------------------------------------------------------------- /modules/cpyrit_cuda/_cpyrit_cuda.h: -------------------------------------------------------------------------------- 1 | /* 2 | # 3 | # Copyright 2008-2011, Lukas Lueg, lukas.lueg@gmail.com 4 | # 5 | # This file is part of Pyrit. 6 | # 7 | # Pyrit is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # Pyrit is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Pyrit. If not, see . 19 | */ 20 | 21 | #include 22 | #include 23 | 24 | #ifndef CPYRIT_CUDA 25 | #define CPYRIT_CUDA 26 | 27 | #define THREADS_PER_BLOCK 64 28 | 29 | #define GET_BE(n,b,i) \ 30 | { \ 31 | (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ 32 | | ( (uint32_t) (b)[(i) + 1] << 16 ) \ 33 | | ( (uint32_t) (b)[(i) + 2] << 8 ) \ 34 | | ( (uint32_t) (b)[(i) + 3] ); \ 35 | } 36 | 37 | #define PUT_BE(n,b,i) \ 38 | { \ 39 | (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ 40 | (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ 41 | (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ 42 | (b)[(i) + 3] = (unsigned char) ( (n) ); \ 43 | } 44 | 45 | typedef struct { 46 | uint32_t h0,h1,h2,h3,h4; 47 | } SHA_DEV_CTX; 48 | 49 | #define CPY_DEVCTX(src, dst) \ 50 | { \ 51 | dst.h0 = src.h0; dst.h1 = src.h1; \ 52 | dst.h2 = src.h2; dst.h3 = src.h3; \ 53 | dst.h4 = src.h4; \ 54 | } 55 | 56 | #define CUSAFECALL(cmd) \ 57 | { \ 58 | ret = (cmd); \ 59 | if (ret != CUDA_SUCCESS) \ 60 | goto errout; \ 61 | } 62 | 63 | #define ALIGN_UP(offset, alignment) \ 64 | (offset) = ((offset) + (alignment) - 1) & ~((alignment) - 1) 65 | 66 | typedef struct { 67 | SHA_DEV_CTX ctx_ipad; 68 | SHA_DEV_CTX ctx_opad; 69 | SHA_DEV_CTX e1; 70 | SHA_DEV_CTX e2; 71 | } gpu_inbuffer; 72 | 73 | typedef struct { 74 | SHA_DEV_CTX pmk1; 75 | SHA_DEV_CTX pmk2; 76 | } gpu_outbuffer; 77 | 78 | #endif 79 | 80 | -------------------------------------------------------------------------------- /modules/cpyrit_cuda/_cpyrit_cudakernel.cu: -------------------------------------------------------------------------------- 1 | /* 2 | # 3 | # Copyright 2008-2011 Lukas Lueg, lukas.lueg@gmail.com 4 | # 5 | # This file is part of Pyrit. 6 | # 7 | # Pyrit is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # Pyrit is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Pyrit. If not, see . 19 | # 20 | # Additional permission under GNU GPL version 3 section 7 21 | # 22 | # If you modify this Program, or any covered work, by linking or 23 | # combining it with NVIDIA Corporation's CUDA libraries from the 24 | # NVIDIA CUDA Toolkit (or a modified version of those libraries), 25 | # containing parts covered by the terms of NVIDIA CUDA Toolkit 26 | # EULA, the licensors of this Program grant you additional 27 | # permission to convey the resulting work. 28 | */ 29 | 30 | #include "_cpyrit_cuda.h" 31 | 32 | /* This is a 'special-version' of the SHA1 round function. *ctx is the current state, 33 | that gets updated by *data. Notice the lack of endianess-changes here. 34 | This SHA1-implementation follows the more-instructions-less-space paradigm, since registers 35 | and (fast) memory on the device are precious, threads are not. Only the starting values 36 | of W[0] to W[4] are defined by parameters. We fix the rest to invariant values and leave 37 | the possible register allocation optimization to the compiler. 38 | */ 39 | __device__ 40 | void sha1_process( const SHA_DEV_CTX *ctx, SHA_DEV_CTX *data) { 41 | 42 | uint32_t temp, W[16], A, B, C, D, E; 43 | 44 | W[ 0] = data->h0; W[ 1] = data->h1; 45 | W[ 2] = data->h2; W[ 3] = data->h3; 46 | W[ 4] = data->h4; W[ 5] = 0x80000000; 47 | W[ 6] = 0; W[ 7] = 0; 48 | W[ 8] = 0; W[ 9] = 0; 49 | W[10] = 0; W[11] = 0; 50 | W[12] = 0; W[13] = 0; 51 | W[14] = 0; W[15] = (64+20)*8; 52 | 53 | A = ctx->h0; 54 | B = ctx->h1; 55 | C = ctx->h2; 56 | D = ctx->h3; 57 | E = ctx->h4; 58 | 59 | #undef S 60 | #define S(x,n) ((x << n) | (x >> (32 - n))) 61 | 62 | #undef R 63 | #define R(t) \ 64 | ( \ 65 | temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \ 66 | W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \ 67 | ( W[t & 0x0F] = S(temp,1) ) \ 68 | ) 69 | 70 | #undef P 71 | #define P(a,b,c,d,e,x) \ 72 | { \ 73 | e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ 74 | } 75 | 76 | #define F(x,y,z) (z ^ (x & (y ^ z))) 77 | #define K 0x5A827999 78 | 79 | P( A, B, C, D, E, W[0] ); 80 | P( E, A, B, C, D, W[1] ); 81 | P( D, E, A, B, C, W[2] ); 82 | P( C, D, E, A, B, W[3] ); 83 | P( B, C, D, E, A, W[4] ); 84 | P( A, B, C, D, E, W[5] ); 85 | P( E, A, B, C, D, W[6] ); 86 | P( D, E, A, B, C, W[7] ); 87 | P( C, D, E, A, B, W[8] ); 88 | P( B, C, D, E, A, W[9] ); 89 | P( A, B, C, D, E, W[10] ); 90 | P( E, A, B, C, D, W[11] ); 91 | P( D, E, A, B, C, W[12] ); 92 | P( C, D, E, A, B, W[13] ); 93 | P( B, C, D, E, A, W[14] ); 94 | P( A, B, C, D, E, W[15] ); 95 | P( E, A, B, C, D, R(16) ); 96 | P( D, E, A, B, C, R(17) ); 97 | P( C, D, E, A, B, R(18) ); 98 | P( B, C, D, E, A, R(19) ); 99 | 100 | #undef K 101 | #undef F 102 | 103 | #define F(x,y,z) (x ^ y ^ z) 104 | #define K 0x6ED9EBA1 105 | 106 | P( A, B, C, D, E, R(20) ); 107 | P( E, A, B, C, D, R(21) ); 108 | P( D, E, A, B, C, R(22) ); 109 | P( C, D, E, A, B, R(23) ); 110 | P( B, C, D, E, A, R(24) ); 111 | P( A, B, C, D, E, R(25) ); 112 | P( E, A, B, C, D, R(26) ); 113 | P( D, E, A, B, C, R(27) ); 114 | P( C, D, E, A, B, R(28) ); 115 | P( B, C, D, E, A, R(29) ); 116 | P( A, B, C, D, E, R(30) ); 117 | P( E, A, B, C, D, R(31) ); 118 | P( D, E, A, B, C, R(32) ); 119 | P( C, D, E, A, B, R(33) ); 120 | P( B, C, D, E, A, R(34) ); 121 | P( A, B, C, D, E, R(35) ); 122 | P( E, A, B, C, D, R(36) ); 123 | P( D, E, A, B, C, R(37) ); 124 | P( C, D, E, A, B, R(38) ); 125 | P( B, C, D, E, A, R(39) ); 126 | 127 | #undef K 128 | #undef F 129 | 130 | #define F(x,y,z) ((x & y) | (z & (x | y))) 131 | #define K 0x8F1BBCDC 132 | 133 | P( A, B, C, D, E, R(40) ); 134 | P( E, A, B, C, D, R(41) ); 135 | P( D, E, A, B, C, R(42) ); 136 | P( C, D, E, A, B, R(43) ); 137 | P( B, C, D, E, A, R(44) ); 138 | P( A, B, C, D, E, R(45) ); 139 | P( E, A, B, C, D, R(46) ); 140 | P( D, E, A, B, C, R(47) ); 141 | P( C, D, E, A, B, R(48) ); 142 | P( B, C, D, E, A, R(49) ); 143 | P( A, B, C, D, E, R(50) ); 144 | P( E, A, B, C, D, R(51) ); 145 | P( D, E, A, B, C, R(52) ); 146 | P( C, D, E, A, B, R(53) ); 147 | P( B, C, D, E, A, R(54) ); 148 | P( A, B, C, D, E, R(55) ); 149 | P( E, A, B, C, D, R(56) ); 150 | P( D, E, A, B, C, R(57) ); 151 | P( C, D, E, A, B, R(58) ); 152 | P( B, C, D, E, A, R(59) ); 153 | 154 | #undef K 155 | #undef F 156 | 157 | #define F(x,y,z) (x ^ y ^ z) 158 | #define K 0xCA62C1D6 159 | 160 | P( A, B, C, D, E, R(60) ); 161 | P( E, A, B, C, D, R(61) ); 162 | P( D, E, A, B, C, R(62) ); 163 | P( C, D, E, A, B, R(63) ); 164 | P( B, C, D, E, A, R(64) ); 165 | P( A, B, C, D, E, R(65) ); 166 | P( E, A, B, C, D, R(66) ); 167 | P( D, E, A, B, C, R(67) ); 168 | P( C, D, E, A, B, R(68) ); 169 | P( B, C, D, E, A, R(69) ); 170 | P( A, B, C, D, E, R(70) ); 171 | P( E, A, B, C, D, R(71) ); 172 | P( D, E, A, B, C, R(72) ); 173 | P( C, D, E, A, B, R(73) ); 174 | P( B, C, D, E, A, R(74) ); 175 | P( A, B, C, D, E, R(75) ); 176 | P( E, A, B, C, D, R(76) ); 177 | P( D, E, A, B, C, R(77) ); 178 | P( C, D, E, A, B, R(78) ); 179 | P( B, C, D, E, A, R(79) ); 180 | 181 | #undef K 182 | #undef F 183 | 184 | data->h0 = ctx->h0 + A; 185 | data->h1 = ctx->h1 + B; 186 | data->h2 = ctx->h2 + C; 187 | data->h3 = ctx->h3 + D; 188 | data->h4 = ctx->h4 + E; 189 | 190 | } 191 | 192 | /* This is the kernel called by the cpu. */ 193 | extern "C" __global__ 194 | void cuda_pmk_kernel( gpu_inbuffer *inbuffer, gpu_outbuffer *outbuffer) { 195 | int i; 196 | SHA_DEV_CTX temp_ctx, pmk_ctx; 197 | 198 | const int idx = blockIdx.x * blockDim.x + threadIdx.x; 199 | 200 | CPY_DEVCTX(inbuffer[idx].e1, temp_ctx); 201 | CPY_DEVCTX(temp_ctx, pmk_ctx); 202 | for( i = 0; i < 4096-1; i++ ) 203 | { 204 | sha1_process( &inbuffer[idx].ctx_ipad, &temp_ctx); 205 | sha1_process( &inbuffer[idx].ctx_opad, &temp_ctx); 206 | pmk_ctx.h0 ^= temp_ctx.h0; pmk_ctx.h1 ^= temp_ctx.h1; 207 | pmk_ctx.h2 ^= temp_ctx.h2; pmk_ctx.h3 ^= temp_ctx.h3; 208 | pmk_ctx.h4 ^= temp_ctx.h4; 209 | } 210 | CPY_DEVCTX(pmk_ctx, outbuffer[idx].pmk1); 211 | 212 | CPY_DEVCTX(inbuffer[idx].e2, temp_ctx); 213 | CPY_DEVCTX(temp_ctx, pmk_ctx); 214 | for( i = 0; i < 4096-1; i++ ) 215 | { 216 | sha1_process( &inbuffer[idx].ctx_ipad, &temp_ctx); 217 | sha1_process( &inbuffer[idx].ctx_opad, &temp_ctx); 218 | pmk_ctx.h0 ^= temp_ctx.h0; pmk_ctx.h1 ^= temp_ctx.h1; 219 | pmk_ctx.h2 ^= temp_ctx.h2; pmk_ctx.h3 ^= temp_ctx.h3; 220 | pmk_ctx.h4 ^= temp_ctx.h4; 221 | } 222 | CPY_DEVCTX(pmk_ctx, outbuffer[idx].pmk2); 223 | } 224 | 225 | -------------------------------------------------------------------------------- /modules/cpyrit_cuda/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: UTF-8 -*- 3 | # 4 | # Copyright 2008-2011 Lukas Lueg, lukas.lueg@gmail.com 5 | # 6 | # This file is part of Pyrit. 7 | # 8 | # Pyrit is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # Pyrit is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with Pyrit. If not, see . 20 | import os 21 | import sys 22 | import zlib 23 | import platform 24 | import subprocess 25 | 26 | from distutils.core import setup, Extension 27 | from distutils.command.build_ext import build_ext 28 | from distutils.command.clean import clean 29 | 30 | VERSION = '0.5.0' 31 | 32 | NVIDIA_INC_DIRS = [] 33 | NVCC = 'nvcc' 34 | for path in ('/usr/local/cuda', '/opt/cuda'): 35 | if os.path.exists(path): 36 | NVIDIA_INC_DIRS.append(os.path.join(path, 'include')) 37 | NVCC = os.path.join(path, 'bin', 'nvcc') 38 | break 39 | else: 40 | print >>sys.stderr, "The CUDA compiler and headers required to build " \ 41 | "kernel were not found. Trying to continue anyway..." 42 | 43 | 44 | EXTRA_COMPILE_ARGS = ['-Wall', '-fno-strict-aliasing', 45 | '-DVERSION="%s"' % (VERSION,)] 46 | 47 | 48 | class GPUBuilder(build_ext): 49 | 50 | def _call(self, comm): 51 | p = subprocess.Popen(comm, stdout=subprocess.PIPE, shell=True) 52 | stdo, stde = p.communicate() 53 | if p.returncode == 0: 54 | return stdo 55 | else: 56 | print >>sys.stderr, "%s\nFailed to execute command '%s'" % \ 57 | (stde, comm) 58 | return None 59 | 60 | def _makedirs(self, pathname): 61 | try: 62 | os.makedirs(pathname) 63 | except OSError: 64 | pass 65 | 66 | def run(self): 67 | if '_cpyrit_cudakernel.ptx.h' in os.listdir('./'): 68 | print "Skipping rebuild of Nvidia CUDA kernel ..." 69 | else: 70 | nvcc_o = self._call(NVCC + ' -V') 71 | if nvcc_o is not None: 72 | nvcc_version = nvcc_o.split('release ')[-1].strip() 73 | else: 74 | raise SystemError("Nvidia's CUDA-compiler 'nvcc' can't be " \ 75 | "found.") 76 | print "Compiling CUDA module using nvcc %s..." % nvcc_version 77 | 78 | # We need to hardcode arch at least for MacOS 10.6 / CUDA 3.1 79 | bits, linkage = platform.architecture() 80 | if bits == '32bit': 81 | bit_flag = ' -m32' 82 | elif bits == '64bit': 83 | bit_flag = ' -m64' 84 | else: 85 | print >>sys.stderr, "Can't detect platform, using 32bit" 86 | bit_flag = ' -m32' 87 | 88 | nvcc_cmd = NVCC + bit_flag + ' -ccbin clang -Xcompiler "-fPIC" --ptx ./_cpyrit_cudakernel.cu' 89 | 90 | print "Executing '%s'" % nvcc_cmd 91 | subprocess.check_call(nvcc_cmd, shell=True) 92 | 93 | with open("_cpyrit_cudakernel.ptx", "rb") as fid: 94 | ptx = fid.read() + '\x00' 95 | ptx_inc = ["0x%02X" % ord(c) for c in zlib.compress(ptx)] 96 | with open("_cpyrit_cudakernel.ptx.h", "wb") as fid: 97 | fid.write("unsigned char __cudakernel_packedmodule[] = {") 98 | fid.write(','.join(ptx_inc)) 99 | fid.write("};\nsize_t cudakernel_modulesize = %i;\n" % len(ptx)) 100 | print "Building modules..." 101 | build_ext.run(self) 102 | 103 | 104 | class GPUCleaner(clean): 105 | 106 | def _unlink(self, node): 107 | try: 108 | if os.path.isdir(node): 109 | os.rmdir(node) 110 | else: 111 | os.unlink(node) 112 | except OSError: 113 | pass 114 | 115 | def run(self): 116 | print "Removing temporary files and pre-built GPU-kernels..." 117 | try: 118 | for f in ('_cpyrit_cudakernel.linkinfo', \ 119 | '_cpyrit_cudakernel.ptx', \ 120 | '_cpyrit_cudakernel.ptx.h'): 121 | self._unlink(f) 122 | except Exception, (errno, sterrno): 123 | print >>sys.stderr, "Exception while cleaning temporary " \ 124 | "files ('%s')" % sterrno 125 | clean.run(self) 126 | 127 | 128 | cuda_extension = Extension('cpyrit._cpyrit_cuda', 129 | libraries = ['crypto','cuda','z'], 130 | sources = ['_cpyrit_cuda.c'], 131 | include_dirs = NVIDIA_INC_DIRS, 132 | extra_compile_args = EXTRA_COMPILE_ARGS) 133 | 134 | setup_args = dict( 135 | name = 'cpyrit-cuda', 136 | version = VERSION, 137 | description = 'GPU-accelerated attack against WPA-PSK authentication', 138 | long_description = \ 139 | "Pyrit allows to create massive databases, pre-computing part " \ 140 | "of the WPA/WPA2-PSK authentication phase in a space-time-" \ 141 | "tradeoff. Exploiting the computational power of Many-Core- " \ 142 | "and other platforms through ATI-Stream, Nvidia CUDA, OpenCL " \ 143 | "and VIA Padlock, it is currently by far the most powerful " \ 144 | "attack against one of the world's most used security-protocols.", 145 | license = 'GNU General Public License v3', 146 | author = 'Lukas Lueg', 147 | author_email = 'lukas.lueg@gmail.com', 148 | url = 'https://github.com/JPaulMora/Pyrit', 149 | maintainer = 'John Mora', 150 | maintainer_email = 'johmora12@engineer.com', 151 | classifiers = \ 152 | ['Development Status :: 4 - Beta', 153 | 'Environment :: Console', 154 | 'License :: OSI Approved :: GNU General Public License (GPL)', 155 | 'Natural Language :: English', 156 | 'Operating System :: OS Independent', 157 | 'Programming Language :: Python', 158 | 'Topic :: Security'], 159 | platforms = ['any'], 160 | ext_modules = [cuda_extension], 161 | cmdclass = {'build_ext': GPUBuilder, 'clean': GPUCleaner}, 162 | options = {'install': {'optimize': 1}, \ 163 | 'bdist_rpm': {'requires': 'pyrit >= 0.4.0'}}) 164 | 165 | if __name__ == "__main__": 166 | setup(**setup_args) 167 | -------------------------------------------------------------------------------- /modules/cpyrit_opencl/MANIFEST.in: -------------------------------------------------------------------------------- 1 | include COPYING 2 | include README 3 | include MANIFEST.in 4 | include _cpyrit_opencl.h 5 | include _cpyrit_oclkernel.cl 6 | -------------------------------------------------------------------------------- /modules/cpyrit_opencl/_cpyrit_oclkernel.cl: -------------------------------------------------------------------------------- 1 | /* 2 | # 3 | # Copyright 2008-2011 Lukas Lueg, lukas.lueg@gmail.com 4 | # 5 | # This file is part of Pyrit. 6 | # 7 | # Pyrit is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # Pyrit is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Pyrit. If not, see . 19 | # 20 | # Additional permission under GNU GPL version 3 section 7 21 | # 22 | # If you modify this Program, or any covered work, by linking or 23 | # combining it with any library or libraries implementing the 24 | # Khronos Group OpenCL Standard v1.0 or later (or modified 25 | # versions of those libraries), containing parts covered by the 26 | # terms of the licenses of their respective copyright owners, 27 | # the licensors of this Program grant you additional permission 28 | # to convey the resulting work. 29 | */ 30 | 31 | void sha1_process(__private const SHA_DEV_CTX ctx, __private SHA_DEV_CTX *data) 32 | { 33 | 34 | uint32_t temp, W[16], A, B, C, D, E; 35 | 36 | W[ 0] = data->h0; W[ 1] = data->h1; 37 | W[ 2] = data->h2; W[ 3] = data->h3; 38 | W[ 4] = data->h4; W[ 5] = 0x80000000; 39 | W[ 6] = 0; W[ 7] = 0; 40 | W[ 8] = 0; W[ 9] = 0; 41 | W[10] = 0; W[11] = 0; 42 | W[12] = 0; W[13] = 0; 43 | W[14] = 0; W[15] = (64+20)*8; 44 | 45 | A = ctx.h0; 46 | B = ctx.h1; 47 | C = ctx.h2; 48 | D = ctx.h3; 49 | E = ctx.h4; 50 | 51 | #undef R 52 | #define R(t) \ 53 | ( \ 54 | temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \ 55 | W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \ 56 | ( W[t & 0x0F] = rotate((int)temp,1) ) \ 57 | ) 58 | 59 | #undef P 60 | #define P(a,b,c,d,e,x) \ 61 | { \ 62 | e += rotate((int)a,5) + F(b,c,d) + K + x; b = rotate((int)b,30);\ 63 | } 64 | 65 | #define F(x,y,z) (z ^ (x & (y ^ z))) 66 | #define K 0x5A827999 67 | 68 | P( A, B, C, D, E, W[0] ); 69 | P( E, A, B, C, D, W[1] ); 70 | P( D, E, A, B, C, W[2] ); 71 | P( C, D, E, A, B, W[3] ); 72 | P( B, C, D, E, A, W[4] ); 73 | P( A, B, C, D, E, W[5] ); 74 | P( E, A, B, C, D, W[6] ); 75 | P( D, E, A, B, C, W[7] ); 76 | P( C, D, E, A, B, W[8] ); 77 | P( B, C, D, E, A, W[9] ); 78 | P( A, B, C, D, E, W[10] ); 79 | P( E, A, B, C, D, W[11] ); 80 | P( D, E, A, B, C, W[12] ); 81 | P( C, D, E, A, B, W[13] ); 82 | P( B, C, D, E, A, W[14] ); 83 | P( A, B, C, D, E, W[15] ); 84 | P( E, A, B, C, D, R(16) ); 85 | P( D, E, A, B, C, R(17) ); 86 | P( C, D, E, A, B, R(18) ); 87 | P( B, C, D, E, A, R(19) ); 88 | 89 | #undef K 90 | #undef F 91 | 92 | #define F(x,y,z) (x ^ y ^ z) 93 | #define K 0x6ED9EBA1 94 | 95 | P( A, B, C, D, E, R(20) ); 96 | P( E, A, B, C, D, R(21) ); 97 | P( D, E, A, B, C, R(22) ); 98 | P( C, D, E, A, B, R(23) ); 99 | P( B, C, D, E, A, R(24) ); 100 | P( A, B, C, D, E, R(25) ); 101 | P( E, A, B, C, D, R(26) ); 102 | P( D, E, A, B, C, R(27) ); 103 | P( C, D, E, A, B, R(28) ); 104 | P( B, C, D, E, A, R(29) ); 105 | P( A, B, C, D, E, R(30) ); 106 | P( E, A, B, C, D, R(31) ); 107 | P( D, E, A, B, C, R(32) ); 108 | P( C, D, E, A, B, R(33) ); 109 | P( B, C, D, E, A, R(34) ); 110 | P( A, B, C, D, E, R(35) ); 111 | P( E, A, B, C, D, R(36) ); 112 | P( D, E, A, B, C, R(37) ); 113 | P( C, D, E, A, B, R(38) ); 114 | P( B, C, D, E, A, R(39) ); 115 | 116 | #undef K 117 | #undef F 118 | 119 | #define F(x,y,z) ((x & y) | (z & (x | y))) 120 | #define K 0x8F1BBCDC 121 | 122 | P( A, B, C, D, E, R(40) ); 123 | P( E, A, B, C, D, R(41) ); 124 | P( D, E, A, B, C, R(42) ); 125 | P( C, D, E, A, B, R(43) ); 126 | P( B, C, D, E, A, R(44) ); 127 | P( A, B, C, D, E, R(45) ); 128 | P( E, A, B, C, D, R(46) ); 129 | P( D, E, A, B, C, R(47) ); 130 | P( C, D, E, A, B, R(48) ); 131 | P( B, C, D, E, A, R(49) ); 132 | P( A, B, C, D, E, R(50) ); 133 | P( E, A, B, C, D, R(51) ); 134 | P( D, E, A, B, C, R(52) ); 135 | P( C, D, E, A, B, R(53) ); 136 | P( B, C, D, E, A, R(54) ); 137 | P( A, B, C, D, E, R(55) ); 138 | P( E, A, B, C, D, R(56) ); 139 | P( D, E, A, B, C, R(57) ); 140 | P( C, D, E, A, B, R(58) ); 141 | P( B, C, D, E, A, R(59) ); 142 | 143 | #undef K 144 | #undef F 145 | 146 | #define F(x,y,z) (x ^ y ^ z) 147 | #define K 0xCA62C1D6 148 | 149 | P( A, B, C, D, E, R(60) ); 150 | P( E, A, B, C, D, R(61) ); 151 | P( D, E, A, B, C, R(62) ); 152 | P( C, D, E, A, B, R(63) ); 153 | P( B, C, D, E, A, R(64) ); 154 | P( A, B, C, D, E, R(65) ); 155 | P( E, A, B, C, D, R(66) ); 156 | P( D, E, A, B, C, R(67) ); 157 | P( C, D, E, A, B, R(68) ); 158 | P( B, C, D, E, A, R(69) ); 159 | P( A, B, C, D, E, R(70) ); 160 | P( E, A, B, C, D, R(71) ); 161 | P( D, E, A, B, C, R(72) ); 162 | P( C, D, E, A, B, R(73) ); 163 | P( B, C, D, E, A, R(74) ); 164 | P( A, B, C, D, E, R(75) ); 165 | P( E, A, B, C, D, R(76) ); 166 | P( D, E, A, B, C, R(77) ); 167 | P( C, D, E, A, B, R(78) ); 168 | P( B, C, D, E, A, R(79) ); 169 | 170 | #undef K 171 | #undef F 172 | 173 | data->h0 = ctx.h0 + A; 174 | data->h1 = ctx.h1 + B; 175 | data->h2 = ctx.h2 + C; 176 | data->h3 = ctx.h3 + D; 177 | data->h4 = ctx.h4 + E; 178 | 179 | } 180 | 181 | __kernel 182 | void opencl_pmk_kernel(__global gpu_inbuffer *inbuffer, __global gpu_outbuffer *outbuffer) { 183 | int i; 184 | const int idx = get_global_id(0); 185 | SHA_DEV_CTX temp_ctx; 186 | SHA_DEV_CTX pmk_ctx; 187 | SHA_DEV_CTX ipad; 188 | SHA_DEV_CTX opad; 189 | 190 | CPY_DEVCTX(inbuffer[idx].ctx_ipad, ipad); 191 | CPY_DEVCTX(inbuffer[idx].ctx_opad, opad); 192 | 193 | CPY_DEVCTX(inbuffer[idx].e1, temp_ctx); 194 | CPY_DEVCTX(temp_ctx, pmk_ctx); 195 | for( i = 0; i < 4096-1; i++ ) 196 | { 197 | sha1_process(ipad, &temp_ctx); 198 | sha1_process(opad, &temp_ctx); 199 | pmk_ctx.h0 ^= temp_ctx.h0; pmk_ctx.h1 ^= temp_ctx.h1; 200 | pmk_ctx.h2 ^= temp_ctx.h2; pmk_ctx.h3 ^= temp_ctx.h3; 201 | pmk_ctx.h4 ^= temp_ctx.h4; 202 | } 203 | CPY_DEVCTX(pmk_ctx, outbuffer[idx].pmk1); 204 | 205 | 206 | CPY_DEVCTX(inbuffer[idx].e2, temp_ctx); 207 | CPY_DEVCTX(temp_ctx, pmk_ctx); 208 | for( i = 0; i < 4096-1; i++ ) 209 | { 210 | sha1_process(ipad, &temp_ctx); 211 | sha1_process(opad, &temp_ctx); 212 | pmk_ctx.h0 ^= temp_ctx.h0; pmk_ctx.h1 ^= temp_ctx.h1; 213 | pmk_ctx.h2 ^= temp_ctx.h2; pmk_ctx.h3 ^= temp_ctx.h3; 214 | pmk_ctx.h4 ^= temp_ctx.h4; 215 | } 216 | CPY_DEVCTX(pmk_ctx, outbuffer[idx].pmk2); 217 | } 218 | -------------------------------------------------------------------------------- /modules/cpyrit_opencl/_cpyrit_opencl.h: -------------------------------------------------------------------------------- 1 | /* 2 | # 3 | # Copyright 2008-2011 Lukas Lueg, lukas.lueg@gmail.com 4 | # 5 | # This file is part of Pyrit. 6 | # 7 | # Pyrit is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # Pyrit is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Pyrit. If not, see . 19 | */ 20 | 21 | #ifndef CPYRIT_OPENCL 22 | #define CPYRIT_OPENCL 23 | 24 | #ifndef uint32_t 25 | #define uint32_t unsigned int 26 | #endif 27 | 28 | #define GET_BE(n,b,i) \ 29 | { \ 30 | (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ 31 | | ( (uint32_t) (b)[(i) + 1] << 16 ) \ 32 | | ( (uint32_t) (b)[(i) + 2] << 8 ) \ 33 | | ( (uint32_t) (b)[(i) + 3] ); \ 34 | } 35 | 36 | #define PUT_BE(n,b,i) \ 37 | { \ 38 | (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ 39 | (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ 40 | (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ 41 | (b)[(i) + 3] = (unsigned char) ( (n) ); \ 42 | } 43 | 44 | typedef struct { 45 | uint32_t h0,h1,h2,h3,h4; 46 | } SHA_DEV_CTX; 47 | 48 | #define CPY_DEVCTX(src, dst) \ 49 | { \ 50 | dst.h0 = src.h0; dst.h1 = src.h1; \ 51 | dst.h2 = src.h2; dst.h3 = src.h3; \ 52 | dst.h4 = src.h4; \ 53 | } 54 | 55 | typedef struct { 56 | SHA_DEV_CTX ctx_ipad; 57 | SHA_DEV_CTX ctx_opad; 58 | SHA_DEV_CTX e1; 59 | SHA_DEV_CTX e2; 60 | } gpu_inbuffer; 61 | 62 | typedef struct { 63 | SHA_DEV_CTX pmk1; 64 | SHA_DEV_CTX pmk2; 65 | } gpu_outbuffer; 66 | 67 | #endif 68 | 69 | -------------------------------------------------------------------------------- /modules/cpyrit_opencl/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: UTF-8 -*- 3 | # 4 | # Copyright 2008-2011, Lukas Lueg, lukas.lueg@gmail.com 5 | # 6 | # This file is part of Pyrit. 7 | # 8 | # Pyrit is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # Pyrit is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with Pyrit. If not, see . 20 | 21 | from __future__ import with_statement 22 | from distutils.core import setup, Extension 23 | from distutils.command.build_ext import build_ext 24 | from distutils.command.clean import clean 25 | import os 26 | import re 27 | import subprocess 28 | import sys 29 | import zlib 30 | 31 | VERSION = '0.5.0' 32 | 33 | OPENCL_INC_DIRS = [] 34 | OPENCL_LIB_DIRS = [] 35 | EXTRA_LINK_ARGS = [] 36 | LIBRARIES = ['crypto', 'z'] 37 | if sys.platform == 'darwin': 38 | # Use the built-in framework on MacOS 39 | EXTRA_LINK_ARGS.extend(('-framework', 'OpenCL')) 40 | OPENCL_INC_DIRS.append('/System/Library/Frameworks/OpenCL.framework/Headers') 41 | else: 42 | LIBRARIES.append('OpenCL') 43 | try: 44 | if os.path.exists(os.environ['ATISTREAMSDKROOT']): 45 | OPENCL_INC_DIRS.append(os.path.join(os.environ['ATISTREAMSDKROOT'], 'include')) 46 | for path in ('lib/x86_64','lib/x86'): 47 | if os.path.exists(os.path.join(os.environ['ATISTREAMSDKROOT'], path)): 48 | OPENCL_LIB_DIRS.append(os.path.join(os.environ['ATISTREAMSDKROOT'], path)) 49 | break 50 | except: 51 | pass 52 | for path in ('/usr/local/opencl/OpenCL/common/inc', \ 53 | '/opt/opencl/OpenCL/common/inc', \ 54 | '/usr/local/opencl/include', \ 55 | '/usr/local/cuda/include'): 56 | if os.path.exists(path): 57 | OPENCL_INC_DIRS.append(path) 58 | break 59 | else: 60 | print >>sys.stderr, "The headers required to build the OpenCL-kernel " \ 61 | "were not found. Trying to continue anyway..." 62 | 63 | 64 | EXTRA_COMPILE_ARGS = ['-Wall', '-fno-strict-aliasing', \ 65 | '-DVERSION="%s"' % (VERSION,)] 66 | 67 | 68 | class GPUBuilder(build_ext): 69 | def run(self): 70 | with open("_cpyrit_opencl.h", 'rb') as f: 71 | header = f.read() 72 | with open("_cpyrit_oclkernel.cl", 'rb') as f: 73 | kernel = f.read() 74 | oclkernel_code = header + '\n' + kernel + '\x00' 75 | oclkernel_inc = zlib.compress(oclkernel_code) 76 | with open("_cpyrit_oclkernel.cl.h", 'wb') as f: 77 | f.write("unsigned char oclkernel_packedprogram[] = {") 78 | f.write(",".join(("0x%02X" % ord(c) for c in oclkernel_inc))) 79 | f.write("};\nsize_t oclkernel_size = %i;\n" % len(oclkernel_code)) 80 | print "Building modules..." 81 | build_ext.run(self) 82 | 83 | 84 | class GPUCleaner(clean): 85 | def _unlink(self, node): 86 | try: 87 | if os.path.isdir(node): 88 | os.rmdir(node) 89 | else: 90 | os.unlink(node) 91 | except OSError: 92 | pass 93 | 94 | def run(self): 95 | print "Removing temporary files and pre-built GPU-kernels..." 96 | try: 97 | for f in ('_cpyrit_oclkernel.cl.h',): 98 | self._unlink(f) 99 | except Exception, (errno, sterrno): 100 | print >>sys.stderr, "Exception while cleaning temporary " \ 101 | "files ('%s')" % sterrno 102 | clean.run(self) 103 | 104 | 105 | opencl_extension = Extension('cpyrit._cpyrit_opencl', 106 | libraries = LIBRARIES, 107 | sources = ['_cpyrit_opencl.c'], 108 | include_dirs = OPENCL_INC_DIRS, 109 | library_dirs = OPENCL_LIB_DIRS, 110 | extra_compile_args = EXTRA_COMPILE_ARGS, 111 | extra_link_args = EXTRA_LINK_ARGS) 112 | 113 | setup_args = dict( 114 | name = 'cpyrit-opencl', 115 | version = VERSION, 116 | description = 'GPU-accelerated attack against WPA-PSK authentication', 117 | long_description = \ 118 | "Pyrit allows to create massive databases, pre-computing part " \ 119 | "of the WPA/WPA2-PSK authentication phase in a space-time-" \ 120 | "tradeoff. Exploiting the computational power of Many-Core- " \ 121 | "and other platforms through ATI-Stream, Nvidia CUDA, OpenCL " \ 122 | "and VIA Padlock, it is currently by far the most powerful " \ 123 | "attack against one of the world's most used security-protocols.", 124 | license = 'GNU General Public License v3', 125 | author = 'Lukas Lueg', 126 | author_email = 'lukas.lueg@gmail.com', 127 | url = 'https://github.com/JPaulMora/Pyrit', 128 | maintainer = 'John Mora', 129 | maintainer_email = 'johmora12@engineer.com', 130 | classifiers = \ 131 | ['Development Status :: 4 - Beta', 132 | 'Environment :: Console', 133 | 'License :: OSI Approved :: GNU General Public License (GPL)', 134 | 'Natural Language :: English', 135 | 'Operating System :: OS Independent', 136 | 'Programming Language :: Python', 137 | 'Topic :: Security'], 138 | platforms = ['any'], 139 | ext_modules = [opencl_extension], 140 | cmdclass = {'build_ext': GPUBuilder, 'clean': GPUCleaner}, 141 | options = {'install': {'optimize': 1}, \ 142 | 'bdist_rpm': {'requires': 'pyrit = 0.4.0-1'}} 143 | ) 144 | 145 | if __name__ == "__main__": 146 | setup(**setup_args) 147 | -------------------------------------------------------------------------------- /pyrit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | if __name__ == "__main__": 3 | import sys 4 | import pyrit_cli 5 | try: 6 | pyrit_cli.Pyrit_CLI().initFromArgv() 7 | except (KeyboardInterrupt, SystemExit): 8 | print("Interrupted...", file=sys.stderr) 9 | except pyrit_cli.PyritRuntimeError as e: 10 | sys.exit(e) 11 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: UTF-8 -*- 3 | # 4 | # Copyright 2015, John Mora, johmora12@engineer.com 5 | # Original Work by Lukas Lueg (c) 2008-2011. 6 | # 7 | # This file is part of Pyrit. 8 | # 9 | # Pyrit is free software: you can redistribute it and/or modify 10 | # it under the terms of the GNU General Public License as published by 11 | # the Free Software Foundation, either version 3 of the License, or 12 | # (at your option) any later version. 13 | # 14 | # Pyrit is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | # GNU General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU General Public License 20 | # along with Pyrit. If not, see . 21 | 22 | import sys 23 | import platform 24 | from distutils.core import setup, Extension 25 | from distutils.command.build_ext import build_ext 26 | from distutils.unixccompiler import UnixCCompiler 27 | from distutils.errors import CompileError 28 | 29 | 30 | VERSION = '0.5.1' 31 | 32 | UnixCCompiler.src_extensions.append('.S') 33 | 34 | 35 | EXTRA_COMPILE_ARGS = ['-Wall', '-fno-strict-aliasing', 36 | '-DVERSION="%s"' % (VERSION,)] 37 | # Support for AES-NI-intrinsics is not found everyhwere 38 | if sys.platform in ('darwin', 'linux2') and \ 39 | platform.machine() in ('x86_64', 'i386'): 40 | EXTRA_COMPILE_ARGS.extend(('-maes', '-mpclmul')) 41 | 42 | 43 | class LazyBuilder(build_ext): 44 | '''The LazyBuilder-class tries to build the cpyrit_cpu-extension with 45 | -maes and -mpclmul first. If that fails, it simply re-tries with 46 | those flags disabled. 47 | This is not exactly elegant but probably the most portable solution 48 | given the limited capabilities of distutils to detect compiler-versions. 49 | ''' 50 | 51 | def build_extension(self, ext): 52 | try: 53 | return super().build_extension(ext) 54 | except CompileError: 55 | if ext.extra_compile_args and '-maes' in ext.extra_compile_args: 56 | print("Failed to build; Compiling without AES-NI") 57 | ext.extra_compile_args.remove('-maes') 58 | ext.extra_compile_args.remove('-mpclmul') 59 | return super().build_extension(ext) 60 | else: 61 | raise 62 | 63 | 64 | cpu_extension = Extension(name='cpyrit._cpyrit_cpu', 65 | sources = ['cpyrit/_cpyrit_cpu.c', 66 | 'cpyrit/_cpyrit_cpu_sse2.S'], 67 | libraries = ['crypto', 'pcap'], 68 | extra_compile_args=EXTRA_COMPILE_ARGS) 69 | 70 | setup_args = { 71 | 'name': 'pyrit', 72 | 'version': VERSION, 73 | 'description': 'GPU-accelerated attack against WPA-PSK authentication', 74 | 'long_description': \ 75 | "Pyrit allows to create massive databases, pre-computing part " \ 76 | "of the WPA/WPA2-PSK authentication phase in a space-time-" \ 77 | "tradeoff. Exploiting the computational power of Many-Core- " \ 78 | "and other platforms through ATI-Stream, Nvidia CUDA and OpenCL " \ 79 | ", it is currently by far the most powerful attack against one " \ 80 | "of the world's most used security-protocols.", 81 | 'license': 'GNU General Public License v3', 82 | 'author': 'Lukas Lueg', 83 | 'author_email': 'lukas.lueg@gmail.com', 84 | 'url': 'https://github.com/JPaulMora/Pyrit', 85 | 'maintainer': 'John Mora', 86 | 'maintainer_email': 'johmora12@engineer.com', 87 | 'classifiers': \ 88 | ['Development Status :: 4 - Beta', 89 | 'Environment :: Console', 90 | 'License :: OSI Approved :: GNU General Public License (GPL)', 91 | 'Natural Language :: English', 92 | 'Operating System :: OS Independent', 93 | 'Programming Language :: Python', 94 | 'Topic :: Security'], 95 | 'platforms': ['any'], 96 | 'packages': ['cpyrit'], 97 | 'py_modules': ['pyrit_cli', 'cpyrit.cpyrit', 98 | 'cpyrit.util', 'cpyrit.pckttools', 99 | 'cpyrit.config', 'cpyrit.network'], 100 | 'scripts': ['pyrit'], 101 | 'ext_modules': [cpu_extension], 102 | 'cmdclass': {'build_ext': LazyBuilder}, 103 | 'options': {'install': {'optimize': 1}} 104 | } 105 | 106 | if __name__ == '__main__': 107 | setup(**setup_args) 108 | -------------------------------------------------------------------------------- /test/dict.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JPaulMora/Pyrit/b0a0dce7a000e51ef2f76684d3de2a41cd93d848/test/dict.gz -------------------------------------------------------------------------------- /test/test_pyrit.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: UTF-8 -*- 3 | # 4 | # Copyright 2008-2011, Lukas Lueg, lukas.lueg@gmail.com 5 | # 6 | # This file is part of Pyrit. 7 | # 8 | # Pyrit is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # Pyrit is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with Pyrit. If not, see . 20 | 21 | 22 | """A test-suite for Pyrit. 23 | 24 | Tests are done by creating a sandbox and executing the cli-functions 25 | normally executed by the user. 26 | 27 | Please notice that the tests backed by the storage-relay open a TCP 28 | socket bound to localhost. 29 | """ 30 | 31 | 32 | from __future__ import with_statement 33 | 34 | import os 35 | import shutil 36 | import random 37 | import unittest 38 | import sys 39 | import tempfile 40 | 41 | import cpyrit.config 42 | import cpyrit.storage 43 | import cpyrit.util 44 | import pyrit_cli 45 | 46 | cpyrit.config.cfg["rpc_server"] = "false" 47 | 48 | 49 | def requires_pckttools(*params): 50 | """Decorate a function to check for cpyrit.cpyrit_pckttools 51 | before execution. 52 | """ 53 | 54 | def check_pkttools(f): 55 | 56 | def new_f(*args, **kwds): 57 | import cpyrit.util 58 | try: 59 | import cpyrit.pckttools 60 | except cpyrit.util.ScapyImportError: 61 | sys.stderr.write("(Skipped: Scapy not installed) ") 62 | else: 63 | f(*args, **kwds) 64 | new_f.func_name = f.func_name 65 | new_f.__doc__ = f.__doc__ 66 | return new_f 67 | return check_pkttools 68 | 69 | 70 | class FilesystemFunctions(object): 71 | 72 | def getStorage(self): 73 | return cpyrit.storage.getStorage('file://' + self.storage_path) 74 | 75 | def corrupt(self, storage): 76 | # Destroy some passwords 77 | keys = list(storage.passwords.iterkeys()) 78 | for i in xrange(13): 79 | key = random.choice(keys) 80 | # This is specific to storage.FSPasswordStore 81 | filename = os.path.join(storage.passwords.pwfiles[key], key) 82 | filename += '.pw' 83 | if i % 3 == 0: 84 | # Delete the workunit without deleting the results. 85 | # Should cause a reference error 86 | del storage.passwords[key] 87 | else: 88 | with open(filename, 'r+b') as f: 89 | # Overwrite either part of the header or part of the file 90 | if i % 2 == 0: 91 | f.seek(4) 92 | f.write('x') 93 | keys.remove(key) 94 | if len(keys) == 0: 95 | break 96 | # Destroy some results 97 | keys = list(storage.essids.iterkeys('test')) 98 | for i in xrange(13): 99 | key = random.choice(keys) 100 | # This is specific to storage.FSEssidStore 101 | filename = os.path.join(storage.essids.essids['test'][0], key) 102 | filename += '.pyr' 103 | with open(filename, 'r+b') as f: 104 | if i % 2 == 0: 105 | f.seek(4) 106 | f.write('x') 107 | keys.remove(key) 108 | if len(keys) == 0: 109 | break 110 | 111 | 112 | class BaseTestCase(unittest.TestCase): 113 | 114 | handshakes = (('wpapsk-linksys.dump.gz', 'linksys', 115 | '00:0b:86:c2:a4:85', '00:13:ce:55:98:ef', 'dictionary'), 116 | ('wpa2psk-linksys.dump.gz', 'linksys', 117 | '00:0b:86:c2:a4:85', '00:13:ce:55:98:ef', 'dictionary'), 118 | ('wpa2psk-2WIRE972.dump.gz', '2WIRE972', 119 | '00:40:10:20:00:03', '00:18:41:9c:a4:a0', 'helium02'), 120 | ('wpa2psk-MOM1.dump.gz', 'MOM1', 121 | '00:21:29:72:a3:19', '00:21:00:ab:55:a9', 'MOM12345'), 122 | ('wpa2psk-Red_Apple.dump.gz', 'Red Apple', 123 | '00:1d:7e:2c:b1:af', '00:0e:35:72:1a:98', 'password'), 124 | ('wpapsk-virgin_broadband.dump.gz', 'virgin broadband', 125 | '00:22:3f:1b:2e:e6', '00:1f:e2:a0:a1:21', 'preinstall')) 126 | 127 | def setUp(self): 128 | self.storage_path = tempfile.mkdtemp() 129 | self.tempfile1 = os.path.join(self.storage_path, 'testfile1') 130 | self.tempfile2 = os.path.join(self.storage_path, 'testfile2') 131 | self.cli = pyrit_cli.Pyrit_CLI() 132 | self.cli.verbose = False 133 | 134 | def tearDown(self): 135 | shutil.rmtree(self.storage_path) 136 | 137 | def _createPasswords(self, filename): 138 | test_passwds = ['test123%i' % i for i in xrange(5000 - 5)] 139 | test_passwds += ['dictionary', 'helium02', 'MOM12345', \ 140 | 'preinstall', 'password'] 141 | random.shuffle(test_passwds) 142 | with cpyrit.util.AsyncFileWriter(filename) as f: 143 | f.write('\n'.join(test_passwds)) 144 | return test_passwds 145 | 146 | def _createDatabase(self, storage): 147 | self.cli.create_essid(storage, 'linksys') 148 | self._createPasswords(self.tempfile1) 149 | self.cli.import_passwords(storage, self.tempfile1) 150 | 151 | def _computeFakeDatabase(self, storage, essid): 152 | self.cli.create_essid(storage, essid) 153 | for key, passwords in storage.passwords.iteritems(): 154 | storage.essids[essid, key] = [(pw, 'x' * 32) for pw in passwords] 155 | 156 | def _computeDatabase(self, storage, essid): 157 | self.cli.create_essid(storage, essid) 158 | l = 0 159 | with cpyrit.cpyrit.StorageIterator(storage, essid) as dbiter: 160 | for results in dbiter: 161 | l += len(results) 162 | self.assertEqual(l, 5000) 163 | 164 | def _testHandshake(self, filename, essid, ap, sta, passwd, aes=False): 165 | parser = cpyrit.pckttools.PacketParser(filename) 166 | with cpyrit.cpyrit.PassthroughIterator(essid, (passwd,)) as cp: 167 | solution = cp.next() 168 | auths = parser[ap][sta].getAuthentications() 169 | for auth in parser[ap][sta].getAuthentications(): 170 | with cpyrit.pckttools.AuthCracker(auth, aes) as cracker: 171 | cracker.enqueue(solution) 172 | if cracker.solution == passwd: 173 | break 174 | else: 175 | self.fail('Did not detect passphrase in "%s"' % filename) 176 | 177 | 178 | class TestCase(BaseTestCase): 179 | 180 | def testListEssids(self): 181 | storage = self.getStorage() 182 | self._createDatabase(storage) 183 | self.cli.list_essids(storage) 184 | 185 | def testCreateAndDeleteEssid(self): 186 | storage = self.getStorage() 187 | # EssidStore should be empty 188 | self.assertEqual(len(storage.essids), 0) 189 | self.assertFalse('testessid' in storage.essids) 190 | # Add one ESSID 191 | self.cli.create_essid(storage, essid='testessid') 192 | self.assertEqual(len(storage.essids), 1) 193 | self.assertTrue('testessid' in storage.essids) 194 | # Adding it second time should not cause an error 195 | self.cli.create_essid(storage, 'testessid') 196 | self.cli.delete_essid(storage, 'testessid', confirm=False) 197 | # EssidStore should be empty again 198 | self.assertEqual(len(storage.essids), 0) 199 | self.assertTrue('testessid' not in storage.essids) 200 | 201 | def testImportPasswords(self): 202 | storage = self.getStorage() 203 | self.assertEqual(len(storage.passwords), 0) 204 | # valid_passwds should get accepted, short_passwds ignored 205 | valid_passwds = ['test123%i' % i for i in xrange(100000)] 206 | short_passwds = ['x%i' % i for i in xrange(30000)] 207 | test_passwds = valid_passwds + short_passwds 208 | random.shuffle(test_passwds) 209 | with cpyrit.util.AsyncFileWriter(self.tempfile1) as f: 210 | f.write('\n'.join(test_passwds)) 211 | self.cli.import_passwords(storage, self.tempfile1) 212 | new_passwds = set() 213 | for key, pwset in storage.passwords.iteritems(): 214 | new_passwds.update(pwset) 215 | self.assertEqual(new_passwds, set(valid_passwds)) 216 | # There should be no duplicates 217 | random.shuffle(test_passwds) 218 | with cpyrit.util.FileWrapper(self.tempfile1, 'a') as f: 219 | f.write('\n') 220 | f.write('\n'.join(test_passwds)) 221 | self.cli.import_passwords(storage, self.tempfile1) 222 | new_passwds = set() 223 | i = 0 224 | for key, pwset in storage.passwords.iteritems(): 225 | new_passwds.update(pwset) 226 | i += len(pwset) 227 | self.assertEqual(i, len(valid_passwds)) 228 | self.assertEqual(new_passwds, set(valid_passwds)) 229 | 230 | @requires_pckttools() 231 | def testAttackDB(self): 232 | storage = self.getStorage() 233 | self._createDatabase(storage) 234 | self._computeDatabase(storage, 'linksys') 235 | self.cli.attack_db(storage, 'wpapsk-linksys.dump.gz') 236 | 237 | @requires_pckttools() 238 | def testAttackCowpatty(self): 239 | storage = self.getStorage() 240 | self._createDatabase(storage) 241 | self._computeDatabase(storage, 'linksys') 242 | self.cli.export_cowpatty(storage, 'linksys', self.tempfile1) 243 | self.cli.attack_cowpatty('wpapsk-linksys.dump.gz', self.tempfile1) 244 | 245 | @requires_pckttools() 246 | def testAttackBatch(self): 247 | storage = self.getStorage() 248 | self._createPasswords(self.tempfile1) 249 | self.cli.import_passwords(storage, self.tempfile1) 250 | self.cli.attack_batch(storage, 'wpapsk-linksys.dump.gz') 251 | 252 | def testPassthrough(self): 253 | storage = self.getStorage() 254 | self._createDatabase(storage) 255 | self.cli.passthrough('linksys', self.tempfile1, self.tempfile2) 256 | fileresults = [] 257 | for results in cpyrit.util.CowpattyFile(self.tempfile2): 258 | fileresults.extend(results) 259 | dbresults = [] 260 | with cpyrit.cpyrit.StorageIterator(storage, 'linksys', \ 261 | yieldNewResults=True) as dbiter: 262 | for results in dbiter: 263 | dbresults.extend(results) 264 | self.assertEqual(sorted(fileresults), sorted(dbresults)) 265 | 266 | def testBatch(self): 267 | storage = self.getStorage() 268 | test_passwds = self._createPasswords(self.tempfile1) 269 | self.cli.import_passwords(storage, self.tempfile1) 270 | self.cli.create_essid(storage, 'test1234') 271 | self.cli.batchprocess(storage) 272 | self.assertEqual(len(storage.passwords), \ 273 | storage.essids.keycount('test1234')) 274 | keys = list(storage.essids.iterkeys('test1234')) 275 | for key in keys: 276 | self.assertTrue(key in storage.passwords) 277 | for key in storage.passwords: 278 | self.assertTrue(key in keys) 279 | passwds = storage.passwords[key] 280 | r = storage.essids['test1234', key] 281 | self.assertTrue(sorted((pw for pw, pmk in r)) == sorted(passwds)) 282 | 283 | def testBatchWithFile(self): 284 | storage = self.getStorage() 285 | test_passwds = self._createPasswords(self.tempfile1) 286 | self.cli.import_passwords(storage, self.tempfile1) 287 | self.cli.create_essid(storage, 'test1234') 288 | self.cli.batchprocess(storage, 'test1234', self.tempfile1) 289 | self.assertEqual(len(storage.passwords), \ 290 | storage.essids.keycount('test1234')) 291 | fileresults = [] 292 | for results in cpyrit.util.CowpattyFile(self.tempfile1): 293 | fileresults.extend(results) 294 | dbresults = [] 295 | with cpyrit.cpyrit.StorageIterator(storage, 'test1234', \ 296 | yieldNewResults=False) as dbiter: 297 | for results in dbiter: 298 | dbresults.extend(results) 299 | self.assertEqual(sorted(fileresults), sorted(dbresults)) 300 | 301 | def testEval(self): 302 | storage = self.getStorage() 303 | self._createDatabase(storage) 304 | self._computeFakeDatabase(storage, 'test1') 305 | self._computeFakeDatabase(storage, 'test2') 306 | self.cli.eval_results(storage) 307 | 308 | def testVerify(self): 309 | storage = self.getStorage() 310 | self._createDatabase(storage) 311 | self._computeDatabase(storage, 'test') 312 | # Should be OK 313 | self.cli.verify(storage) 314 | keys = list(storage.essids.iterkeys('test')) 315 | for i in xrange(25): 316 | key = random.choice(keys) 317 | results = storage.essids['test', key] 318 | corrupted = tuple((pw, 'x' * 32) for pw, pmk in results) 319 | storage.essids['test', key] = corrupted 320 | # Should fail 321 | self.assertRaises(pyrit_cli.PyritRuntimeError, \ 322 | self.cli.verify, storage) 323 | 324 | def testCheckDB(self): 325 | storage = self.getStorage() 326 | self._createDatabase(storage) 327 | self._computeFakeDatabase(storage, 'test') 328 | self.corrupt(storage) 329 | # Should fail but repair 330 | self.assertRaises(pyrit_cli.PyritRuntimeError, \ 331 | self.cli.checkdb, storage, False) 332 | # Should now be OK 333 | self.cli.checkdb(storage, False) 334 | 335 | def testExportPasswords(self): 336 | storage = self.getStorage() 337 | test_passwds = self._createPasswords(self.tempfile1) 338 | self.cli.import_passwords(storage, self.tempfile1) 339 | self.cli.export_passwords(storage, self.tempfile1) 340 | with cpyrit.util.FileWrapper(self.tempfile1) as f: 341 | new_passwds = map(str.strip, f.readlines()) 342 | self.assertEqual(sorted(test_passwds), sorted(new_passwds)) 343 | 344 | def testExportCowpatty(self): 345 | storage = self.getStorage() 346 | self._createDatabase(storage) 347 | self._computeDatabase(storage, 'test') 348 | self.cli.export_cowpatty(storage, 'test', self.tempfile1) 349 | fileresults = [] 350 | for results in cpyrit.util.CowpattyFile(self.tempfile1): 351 | fileresults.extend(results) 352 | dbresults = [] 353 | with cpyrit.cpyrit.StorageIterator(storage, 'test', \ 354 | yieldNewResults=False) as dbiter: 355 | for results in dbiter: 356 | dbresults.extend(results) 357 | self.assertEqual(sorted(fileresults), sorted(dbresults)) 358 | 359 | def testExportHashdb(self): 360 | storage = self.getStorage() 361 | self._createDatabase(storage) 362 | self._computeFakeDatabase(storage, 'test') 363 | os.unlink(self.tempfile1) 364 | self.cli.export_hashdb(storage, self.tempfile1) 365 | 366 | 367 | class RPCTestCase(TestCase, FilesystemFunctions): 368 | 369 | def getStorage(self): 370 | return cpyrit.storage.getStorage('http://127.0.0.1:17934') 371 | 372 | def setUp(self): 373 | TestCase.setUp(self) 374 | self.backend = FilesystemFunctions.getStorage(self) 375 | self.server = cpyrit.storage.StorageRelay(self.backend, \ 376 | iface='127.0.0.1') 377 | 378 | def tearDown(self): 379 | self.server.shutdown() 380 | TestCase.tearDown(self) 381 | 382 | def corrupt(self, storage): 383 | # Corrupt backing storage instead... 384 | FilesystemFunctions.corrupt(self, self.backend) 385 | 386 | 387 | class DatabaseTestCase(TestCase): 388 | 389 | def getStorage(self): 390 | return cpyrit.storage.getStorage('sqlite:///:memory:') 391 | 392 | def corrupt(self, storage): 393 | conn = storage.engine.connect() 394 | # Destroy some passwords 395 | keys = list(storage.passwords.iterkeys()) 396 | tbl = cpyrit.storage.passwords_table 397 | for i in xrange(13): 398 | key = random.choice(keys) 399 | sql = tbl.update().where(tbl.c._key == key) 400 | if i % 2 == 0: 401 | buf = 'x' 402 | else: 403 | buf = 'PAW2x' 404 | sql = sql.values(collection_buffer=buf) 405 | conn.execute(sql) 406 | keys.remove(key) 407 | if len(keys) == 0: 408 | break 409 | # Destroy some results 410 | keys = list(storage.essids.iterkeys('test')) 411 | tbl = cpyrit.storage.results_table 412 | for i in xrange(13): 413 | key = random.choice(keys) 414 | if i % 3 == 0: 415 | # Delete workunit 416 | # Should cause a reference-error 417 | sql = tbl.delete().where(tbl.c._key == key) 418 | else: 419 | # Corrupt it 420 | sql = tbl.update().where(tbl.c._key == key) 421 | if i % 2 == 0: 422 | buf = 'x' 423 | else: 424 | buf = 'PYR2xxxxxyyyyyzzz' 425 | sql = sql.values(results_buffer=buf) 426 | conn.execute(sql) 427 | keys.remove(key) 428 | if len(keys) == 0: 429 | break 430 | 431 | 432 | class FilesystemTestCase(TestCase, FilesystemFunctions): 433 | 434 | def testListCores(self): 435 | self.cli.list_cores() 436 | 437 | def testPrintHelp(self): 438 | self.cli.print_help() 439 | 440 | def testSelfTest(self): 441 | self.cli.selftest(timeout=3) 442 | 443 | def testBenchmark(self): 444 | self.cli.benchmark(timeout=3) 445 | 446 | @requires_pckttools() 447 | def testHandshakes(self): 448 | for filename, essid, ap, sta, passwd in self.handshakes: 449 | self._testHandshake(filename, essid, ap, sta, passwd) 450 | 451 | @requires_pckttools() 452 | def testAnalyze(self): 453 | self.cli.analyze(capturefile='wpapsk-linksys.dump.gz') 454 | self.cli.analyze(capturefile='wpa2psk-linksys.dump.gz') 455 | self.cli.analyze(capturefile='wpa2psk-MOM1.dump.gz') 456 | self.cli.analyze(capturefile='wpa2psk-2WIRE972.dump.gz') 457 | self.cli.analyze(capturefile='wpapsk-virgin_broadband.dump.gz') 458 | 459 | @requires_pckttools() 460 | def testStripCapture(self): 461 | self.cli.stripCapture('wpapsk-linksys.dump.gz', self.tempfile1) 462 | parser = self.cli._getParser(self.tempfile1) 463 | self.assertTrue('00:0b:86:c2:a4:85' in parser) 464 | self.assertEqual(parser['00:0b:86:c2:a4:85'].essid, 'linksys') 465 | self.assertTrue('00:13:ce:55:98:ef' in parser['00:0b:86:c2:a4:85']) 466 | self.assertTrue(parser['00:0b:86:c2:a4:85'].isCompleted()) 467 | for filename, essid, ap, sta, passwd in self.handshakes: 468 | self.cli.stripCapture(filename, self.tempfile1) 469 | self._testHandshake(self.tempfile1, essid, ap, sta, passwd) 470 | 471 | @requires_pckttools() 472 | def testStripLive(self): 473 | self.cli.stripLive('wpa2psk-linksys.dump.gz', self.tempfile1) 474 | parser = self.cli._getParser(self.tempfile1) 475 | self.assertTrue('00:0b:86:c2:a4:85' in parser) 476 | self.assertEqual(parser['00:0b:86:c2:a4:85'].essid, 'linksys') 477 | self.assertTrue('00:13:ce:55:98:ef' in parser['00:0b:86:c2:a4:85']) 478 | self.assertTrue(parser['00:0b:86:c2:a4:85'].isCompleted()) 479 | for filename, essid, ap, sta, passwd in self.handshakes: 480 | self.cli.stripLive(filename, self.tempfile1) 481 | self._testHandshake(self.tempfile1, essid, ap, sta, passwd) 482 | 483 | @requires_pckttools() 484 | def testAttackPassthrough(self): 485 | self._createPasswords(self.tempfile1) 486 | self.cli.attack_passthrough(self.tempfile1, 'wpapsk-linksys.dump.gz') 487 | self.cli.attack_passthrough(self.tempfile1, 'wpa2psk-linksys.dump.gz', \ 488 | use_aes=True) 489 | 490 | 491 | def _runTests(case): 492 | loader = unittest.TestLoader() 493 | suite = loader.loadTestsFromTestCase(case) 494 | return unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful() 495 | 496 | if __name__ == "__main__": 497 | print "Testing with filesystem-storage..." 498 | if not _runTests(FilesystemTestCase): 499 | sys.exit(1) 500 | 501 | # should have been imported by cpyrit.storage 502 | if 'sqlalchemy' not in sys.modules: 503 | print "SQLAlchemy seems to be unavailable; skipping all tests..." 504 | else: 505 | print "Testing with database-storage..." 506 | if not _runTests(DatabaseTestCase): 507 | sys.exit(1) 508 | 509 | print "Testing with RPC-storage..." 510 | if not _runTests(RPCTestCase): 511 | sys.exit(1) 512 | -------------------------------------------------------------------------------- /test/wpa2psk-2WIRE972.dump.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JPaulMora/Pyrit/b0a0dce7a000e51ef2f76684d3de2a41cd93d848/test/wpa2psk-2WIRE972.dump.gz -------------------------------------------------------------------------------- /test/wpa2psk-MOM1.dump.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JPaulMora/Pyrit/b0a0dce7a000e51ef2f76684d3de2a41cd93d848/test/wpa2psk-MOM1.dump.gz -------------------------------------------------------------------------------- /test/wpa2psk-Red_Apple.dump.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JPaulMora/Pyrit/b0a0dce7a000e51ef2f76684d3de2a41cd93d848/test/wpa2psk-Red_Apple.dump.gz -------------------------------------------------------------------------------- /test/wpa2psk-linksys.dump.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JPaulMora/Pyrit/b0a0dce7a000e51ef2f76684d3de2a41cd93d848/test/wpa2psk-linksys.dump.gz -------------------------------------------------------------------------------- /test/wpapsk-linksys.dump.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JPaulMora/Pyrit/b0a0dce7a000e51ef2f76684d3de2a41cd93d848/test/wpapsk-linksys.dump.gz -------------------------------------------------------------------------------- /test/wpapsk-virgin_broadband.dump.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JPaulMora/Pyrit/b0a0dce7a000e51ef2f76684d3de2a41cd93d848/test/wpapsk-virgin_broadband.dump.gz --------------------------------------------------------------------------------