├── .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 | 
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
--------------------------------------------------------------------------------