├── CMakeLists.txt ├── Makefile ├── README.md ├── aes.c ├── aes.h ├── aescrypt2 ├── aescrypt2.c ├── aescrypt2.dsp ├── aescrypt2.exe ├── sha256.c └── sha256.h /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.9) 2 | 3 | set( CMAKE_OSX_ARCHITECTURES i386 CACHE STRING "" ) 4 | 5 | project( aescrypt2 ) 6 | 7 | set( HEADER_FILES 8 | aes.h 9 | sha256.h ) 10 | 11 | set( SOURCE_FILES 12 | aes.c 13 | sha256.c ) 14 | 15 | add_executable( aescrypt2 aescrypt2.c ${SOURCE_FILES} ) 16 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | $(CC) -O -o aescrypt2 aescrypt2.c aes.c sha256.c -D_FILE_OFFSET_BITS=64 3 | 4 | clean: 5 | rm -f *.o aescrypt2 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## AESCrypt2 2 | 3 | The original tarball came from here [packetstormsecurity.com][2]. 4 | 5 | ### Get Fiber and the Huawei HG8245 6 | 7 | This router is used with Fiber customers in Oslo, Norway that are using [Get][3] as their ISP. 8 | 9 | In typical ISP fashion they can't just hand you an Ethernet jack and get out of your way, they want to give you a router that NATs and provides WiFi. In this case they've adopted the Huawei HG8245 which is large and provides terrible WiFi coverage within the apartment. Funny that they'll sell you 500/500Mbps Internet service on a router that cannot possibly deliver it to the majority of modern devices. They're at least nice enough to turn off the WiFi and set Bridge mode, but the box still takes over most of the electrical box in my apartment. Everytime I've had them make any change to my service-level they have turned off bridge-mode and then I have to make yet another call to turn it back on. So in summary I really wish they would replace the big box with a [Ubiquiti Nano G][4] and get out of the business of trying to do things they're terrible at. 10 | 11 | ### Exploring the device 12 | 13 | I began the exploration of the unit to be able to manage it myself. A bit of searching came up with a page that included a binary tool for Linux and Windows to encrypt/decrypt the configuration on the device [aescrypt2_huawei][1] and how to trick the router into allowing you to download the configuration. 14 | 15 | ### Get the Get configuration file 16 | 17 | The configuration from Get prevents you from downloading the config. To trick the router you'll do the following: 18 | 19 | 1) Unplug the fiber cable 20 | 2) Perform a factory reset in the web interface 21 | 3) Wait for it to reboot 22 | 4) Log back in using root/admin and you'll see your access level provides full access 23 | 5) Plug the fiber cable back in 24 | 6) And then download the config when the WAN light goes solid green 25 | 26 | ### Decrypting the configuration 27 | 28 | The configuration is stored as an encrypted XML file. Finding a decryption tool was easy enough, but unfortunately it was provided for Linux and Windows and not for Mac. So I really wanted to know what the encryption key being used was and be able to use it directly on my Mac. So I started looking at the binary with [IDA Pro][5]. 29 | 30 | Based upon the analysis of the program: 31 | 32 | Huawei's encryption key is `hex:13395537D2730554A176799F6D56A239` 33 | 34 | To recreate the functionality of the `aescrypt2_huawei` tool you need to compile the source code in this repo and do the following: 35 | 36 | 1) `echo -n 'hex:13395537D2730554A176799F6D56A239' > key.txt` 37 | 2) `dd if=config.encrypted of=config_no_header.encrypted bs=1 skip=8` 38 | 3) `./aescrypt2 1 config_no_header.encrypted config.decrypted.gz key.txt` 39 | 4) `gunzip config.decrypted.gz` 40 | 41 | After getting the encryption key and searching for it I found a spanish speaking forum that says they got the encryption key from a file found on the device in `/etc/wap/aes_string`. 42 | 43 | ### Looking at the config 44 | 45 | The config is pretty long but the main thing needed was to allow you to add a new user with super-user privileges or change the root/admin account to have the same access as Get provides themselves. In summary, passwords are hashed using 46 | 47 | `SHA256(MD5(admin))` which in this example yields `465c194afb65670f38322df087f0a9bb225cc257e43eb4ac5a0c98ef5b3173ac`. 48 | 49 | on the bash command-line this is accomplished like this: 50 | 51 | echo -n admin | md5 | tr -d '\n' | shasum -a 256 52 | 53 | You'll find this user in the config from Get and it has been given reduced privileges (level 1). 54 | 55 | ### Get user 56 | 57 | As defined in the configuration file Get added a user called 'getaccess' and with level 0 privileges (the highest) 58 | 59 | 60 | 61 | So you can modify the root user UserLevel to 0 and you're really root again. However, it probably makes more sense to add a new user since the root/admin combination is well known. 62 | 63 | ### One more thing 64 | 65 | The astute reader might have noticed I skipped the first 8-bytes before decrypting the file. The properly encrypted Huawei config file has some sort of header (4 bytes) and checksum (4 bytes) and I just ignored it. If you plan on uploading a modified config back to the router you'd need to recreate that header, so in that case I'd use the Linux and Windows tool to be safe. 66 | 67 | ### What about replacing the router? 68 | 69 | I replaced the Huawei box with a [Ubiquiti Nano G][6]. Get is using the Serial Number of the Huawei router as the method of authentication. This is a relatively common practice. So essentially, the OLT sees the Serial Number and lets it connect. So in the web interface set [Profile 2][9] for Huawei and then the device will reboot. Then SSH to the box and change the Serial Number. Username and password are `ubnt` by default. 70 | 71 | On the Nano G you issue the following commands discussed on [this website][7]: 72 | 73 | $ ssh ubnt@192.168.1.1 74 | 75 | > sh 76 | 77 | # cd bin 78 | # ./gponctl stop 79 | 80 | Stop ONU without sending dying gasp messages 81 | 82 | # ./gponctl setSnPwd --sn 41-4c-43-4c-xx-xx-xx-xx 83 | 84 | ======== Serial Number & Password ======== 85 | 86 | Serial Number: 41-4C-43-4C-xx-xx-xx-xx 87 | Password : 20-20-20-20-20-20-20-20-20-20 88 | 89 | ========================================== 90 | 91 | # ./gponctl init 92 | # ./gponctl start 93 | 94 | Start ONU with operational state: INIT (01) 95 | 96 | # ./gponctl getSnPwd 97 | 98 | ======== Serial Number & Password ======= 99 | 100 | Serial Number: 41-4C-43-4C-xx-xx-xx-xx 101 | Password : 20-20-20-20-20-20-20-20-20-20 102 | 103 | ========================================== 104 | 105 | This will not persist across reboots. 106 | 107 | ### Persisting the serial number by rewriting firmware 108 | 109 | It is pretty easy to rewrite the NVRAM and persist the change. Another security researcher wrote this up 110 | 111 | [Rewrite the Serial Number][10] 112 | 113 | Lastly, I bought the Nano G from [Senetic][8]. 114 | 115 | 116 | 117 | [1]: https://zedt.eu/tech/hardware/obtaining-administrator-access-huawei-hg8247h/ 118 | [2]: https://packetstormsecurity.com/files/35655/aescrypt2-1.0.tgz.html 119 | [3]: https://www.get.no 120 | [4]: https://www.ubnt.com/ufiber/ufiber-nano-g/ 121 | [5]: https://www.hex-rays.com 122 | [6]: https://www.ubnt.com/ufiber/ufiber-nano-g/ 123 | [7]: https://blog.onedefence.com/changing-the-gpon-serial-on-the-ubiquiti-ufiber-nano-g-part-one 124 | [8]: https://www.senetic.no/product/UF-NANO 125 | [9]: https://help.ubnt.com/hc/en-us/articles/115009335068-UFiber-GPON-Supported-Third-Party-OLTs 126 | [10]: https://blog.onedefence.com/changing-the-gpon-serial-on-the-ubiquiti-ufiber-nano-g-part-two/ 127 | -------------------------------------------------------------------------------- /aes.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FIPS-197 compliant AES implementation 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 | 21 | #include "aes.h" 22 | 23 | /* uncomment the following line to run the test suite */ 24 | 25 | /* #define TEST */ 26 | 27 | /* uncomment the following line to use pre-computed tables */ 28 | /* otherwise the tables will be generated at the first run */ 29 | 30 | /* #define FIXED_TABLES */ 31 | 32 | #ifndef FIXED_TABLES 33 | 34 | /* forward S-box & tables */ 35 | 36 | uint32 FSb[256]; 37 | uint32 FT0[256]; 38 | uint32 FT1[256]; 39 | uint32 FT2[256]; 40 | uint32 FT3[256]; 41 | 42 | /* reverse S-box & tables */ 43 | 44 | uint32 RSb[256]; 45 | uint32 RT0[256]; 46 | uint32 RT1[256]; 47 | uint32 RT2[256]; 48 | uint32 RT3[256]; 49 | 50 | /* round constants */ 51 | 52 | uint32 RCON[10]; 53 | 54 | /* tables generation flag */ 55 | 56 | int do_init = 1; 57 | 58 | /* tables generation routine */ 59 | 60 | #define ROTR8(x) ( ( ( x << 24 ) & 0xFFFFFFFF ) | \ 61 | ( ( x & 0xFFFFFFFF ) >> 8 ) ) 62 | 63 | #define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) ) 64 | #define MUL(x,y) ( ( x && y ) ? pow[(log[x] + log[y]) % 255] : 0 ) 65 | 66 | void aes_gen_tables( void ) 67 | { 68 | int i; 69 | uint8 x, y; 70 | uint8 pow[256]; 71 | uint8 log[256]; 72 | 73 | /* compute pow and log tables over GF(2^8) */ 74 | 75 | for( i = 0, x = 1; i < 256; i++, x ^= XTIME( x ) ) 76 | { 77 | pow[i] = x; 78 | log[x] = i; 79 | } 80 | 81 | /* calculate the round constants */ 82 | 83 | for( i = 0, x = 1; i < 10; i++, x = XTIME( x ) ) 84 | { 85 | RCON[i] = (uint32) x << 24; 86 | } 87 | 88 | /* generate the forward and reverse S-boxes */ 89 | 90 | FSb[0x00] = 0x63; 91 | RSb[0x63] = 0x00; 92 | 93 | for( i = 1; i < 256; i++ ) 94 | { 95 | x = pow[255 - log[i]]; 96 | 97 | y = x; y = ( y << 1 ) | ( y >> 7 ); 98 | x ^= y; y = ( y << 1 ) | ( y >> 7 ); 99 | x ^= y; y = ( y << 1 ) | ( y >> 7 ); 100 | x ^= y; y = ( y << 1 ) | ( y >> 7 ); 101 | x ^= y ^ 0x63; 102 | 103 | FSb[i] = x; 104 | RSb[x] = i; 105 | } 106 | 107 | /* generate the forward and reverse tables */ 108 | 109 | for( i = 0; i < 256; i++ ) 110 | { 111 | x = (unsigned char) FSb[i]; y = XTIME( x ); 112 | 113 | FT0[i] = (uint32) ( x ^ y ) ^ 114 | ( (uint32) x << 8 ) ^ 115 | ( (uint32) x << 16 ) ^ 116 | ( (uint32) y << 24 ); 117 | 118 | FT0[i] &= 0xFFFFFFFF; 119 | 120 | FT1[i] = ROTR8( FT0[i] ); 121 | FT2[i] = ROTR8( FT1[i] ); 122 | FT3[i] = ROTR8( FT2[i] ); 123 | 124 | y = (unsigned char) RSb[i]; 125 | 126 | RT0[i] = ( (uint32) MUL( 0x0B, y ) ) ^ 127 | ( (uint32) MUL( 0x0D, y ) << 8 ) ^ 128 | ( (uint32) MUL( 0x09, y ) << 16 ) ^ 129 | ( (uint32) MUL( 0x0E, y ) << 24 ); 130 | 131 | RT0[i] &= 0xFFFFFFFF; 132 | 133 | RT1[i] = ROTR8( RT0[i] ); 134 | RT2[i] = ROTR8( RT1[i] ); 135 | RT3[i] = ROTR8( RT2[i] ); 136 | } 137 | } 138 | 139 | #else 140 | 141 | /* forward S-box */ 142 | 143 | static const uint32 FSb[256] = 144 | { 145 | 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 146 | 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 147 | 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 148 | 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 149 | 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 150 | 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 151 | 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 152 | 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, 153 | 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 154 | 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 155 | 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 156 | 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 157 | 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 158 | 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, 159 | 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 160 | 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 161 | 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 162 | 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, 163 | 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 164 | 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, 165 | 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 166 | 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 167 | 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 168 | 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 169 | 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 170 | 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 171 | 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 172 | 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 173 | 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 174 | 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 175 | 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 176 | 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 177 | }; 178 | 179 | /* forward tables */ 180 | 181 | #define FT \ 182 | \ 183 | V(C6,63,63,A5), V(F8,7C,7C,84), V(EE,77,77,99), V(F6,7B,7B,8D), \ 184 | V(FF,F2,F2,0D), V(D6,6B,6B,BD), V(DE,6F,6F,B1), V(91,C5,C5,54), \ 185 | V(60,30,30,50), V(02,01,01,03), V(CE,67,67,A9), V(56,2B,2B,7D), \ 186 | V(E7,FE,FE,19), V(B5,D7,D7,62), V(4D,AB,AB,E6), V(EC,76,76,9A), \ 187 | V(8F,CA,CA,45), V(1F,82,82,9D), V(89,C9,C9,40), V(FA,7D,7D,87), \ 188 | V(EF,FA,FA,15), V(B2,59,59,EB), V(8E,47,47,C9), V(FB,F0,F0,0B), \ 189 | V(41,AD,AD,EC), V(B3,D4,D4,67), V(5F,A2,A2,FD), V(45,AF,AF,EA), \ 190 | V(23,9C,9C,BF), V(53,A4,A4,F7), V(E4,72,72,96), V(9B,C0,C0,5B), \ 191 | V(75,B7,B7,C2), V(E1,FD,FD,1C), V(3D,93,93,AE), V(4C,26,26,6A), \ 192 | V(6C,36,36,5A), V(7E,3F,3F,41), V(F5,F7,F7,02), V(83,CC,CC,4F), \ 193 | V(68,34,34,5C), V(51,A5,A5,F4), V(D1,E5,E5,34), V(F9,F1,F1,08), \ 194 | V(E2,71,71,93), V(AB,D8,D8,73), V(62,31,31,53), V(2A,15,15,3F), \ 195 | V(08,04,04,0C), V(95,C7,C7,52), V(46,23,23,65), V(9D,C3,C3,5E), \ 196 | V(30,18,18,28), V(37,96,96,A1), V(0A,05,05,0F), V(2F,9A,9A,B5), \ 197 | V(0E,07,07,09), V(24,12,12,36), V(1B,80,80,9B), V(DF,E2,E2,3D), \ 198 | V(CD,EB,EB,26), V(4E,27,27,69), V(7F,B2,B2,CD), V(EA,75,75,9F), \ 199 | V(12,09,09,1B), V(1D,83,83,9E), V(58,2C,2C,74), V(34,1A,1A,2E), \ 200 | V(36,1B,1B,2D), V(DC,6E,6E,B2), V(B4,5A,5A,EE), V(5B,A0,A0,FB), \ 201 | V(A4,52,52,F6), V(76,3B,3B,4D), V(B7,D6,D6,61), V(7D,B3,B3,CE), \ 202 | V(52,29,29,7B), V(DD,E3,E3,3E), V(5E,2F,2F,71), V(13,84,84,97), \ 203 | V(A6,53,53,F5), V(B9,D1,D1,68), V(00,00,00,00), V(C1,ED,ED,2C), \ 204 | V(40,20,20,60), V(E3,FC,FC,1F), V(79,B1,B1,C8), V(B6,5B,5B,ED), \ 205 | V(D4,6A,6A,BE), V(8D,CB,CB,46), V(67,BE,BE,D9), V(72,39,39,4B), \ 206 | V(94,4A,4A,DE), V(98,4C,4C,D4), V(B0,58,58,E8), V(85,CF,CF,4A), \ 207 | V(BB,D0,D0,6B), V(C5,EF,EF,2A), V(4F,AA,AA,E5), V(ED,FB,FB,16), \ 208 | V(86,43,43,C5), V(9A,4D,4D,D7), V(66,33,33,55), V(11,85,85,94), \ 209 | V(8A,45,45,CF), V(E9,F9,F9,10), V(04,02,02,06), V(FE,7F,7F,81), \ 210 | V(A0,50,50,F0), V(78,3C,3C,44), V(25,9F,9F,BA), V(4B,A8,A8,E3), \ 211 | V(A2,51,51,F3), V(5D,A3,A3,FE), V(80,40,40,C0), V(05,8F,8F,8A), \ 212 | V(3F,92,92,AD), V(21,9D,9D,BC), V(70,38,38,48), V(F1,F5,F5,04), \ 213 | V(63,BC,BC,DF), V(77,B6,B6,C1), V(AF,DA,DA,75), V(42,21,21,63), \ 214 | V(20,10,10,30), V(E5,FF,FF,1A), V(FD,F3,F3,0E), V(BF,D2,D2,6D), \ 215 | V(81,CD,CD,4C), V(18,0C,0C,14), V(26,13,13,35), V(C3,EC,EC,2F), \ 216 | V(BE,5F,5F,E1), V(35,97,97,A2), V(88,44,44,CC), V(2E,17,17,39), \ 217 | V(93,C4,C4,57), V(55,A7,A7,F2), V(FC,7E,7E,82), V(7A,3D,3D,47), \ 218 | V(C8,64,64,AC), V(BA,5D,5D,E7), V(32,19,19,2B), V(E6,73,73,95), \ 219 | V(C0,60,60,A0), V(19,81,81,98), V(9E,4F,4F,D1), V(A3,DC,DC,7F), \ 220 | V(44,22,22,66), V(54,2A,2A,7E), V(3B,90,90,AB), V(0B,88,88,83), \ 221 | V(8C,46,46,CA), V(C7,EE,EE,29), V(6B,B8,B8,D3), V(28,14,14,3C), \ 222 | V(A7,DE,DE,79), V(BC,5E,5E,E2), V(16,0B,0B,1D), V(AD,DB,DB,76), \ 223 | V(DB,E0,E0,3B), V(64,32,32,56), V(74,3A,3A,4E), V(14,0A,0A,1E), \ 224 | V(92,49,49,DB), V(0C,06,06,0A), V(48,24,24,6C), V(B8,5C,5C,E4), \ 225 | V(9F,C2,C2,5D), V(BD,D3,D3,6E), V(43,AC,AC,EF), V(C4,62,62,A6), \ 226 | V(39,91,91,A8), V(31,95,95,A4), V(D3,E4,E4,37), V(F2,79,79,8B), \ 227 | V(D5,E7,E7,32), V(8B,C8,C8,43), V(6E,37,37,59), V(DA,6D,6D,B7), \ 228 | V(01,8D,8D,8C), V(B1,D5,D5,64), V(9C,4E,4E,D2), V(49,A9,A9,E0), \ 229 | V(D8,6C,6C,B4), V(AC,56,56,FA), V(F3,F4,F4,07), V(CF,EA,EA,25), \ 230 | V(CA,65,65,AF), V(F4,7A,7A,8E), V(47,AE,AE,E9), V(10,08,08,18), \ 231 | V(6F,BA,BA,D5), V(F0,78,78,88), V(4A,25,25,6F), V(5C,2E,2E,72), \ 232 | V(38,1C,1C,24), V(57,A6,A6,F1), V(73,B4,B4,C7), V(97,C6,C6,51), \ 233 | V(CB,E8,E8,23), V(A1,DD,DD,7C), V(E8,74,74,9C), V(3E,1F,1F,21), \ 234 | V(96,4B,4B,DD), V(61,BD,BD,DC), V(0D,8B,8B,86), V(0F,8A,8A,85), \ 235 | V(E0,70,70,90), V(7C,3E,3E,42), V(71,B5,B5,C4), V(CC,66,66,AA), \ 236 | V(90,48,48,D8), V(06,03,03,05), V(F7,F6,F6,01), V(1C,0E,0E,12), \ 237 | V(C2,61,61,A3), V(6A,35,35,5F), V(AE,57,57,F9), V(69,B9,B9,D0), \ 238 | V(17,86,86,91), V(99,C1,C1,58), V(3A,1D,1D,27), V(27,9E,9E,B9), \ 239 | V(D9,E1,E1,38), V(EB,F8,F8,13), V(2B,98,98,B3), V(22,11,11,33), \ 240 | V(D2,69,69,BB), V(A9,D9,D9,70), V(07,8E,8E,89), V(33,94,94,A7), \ 241 | V(2D,9B,9B,B6), V(3C,1E,1E,22), V(15,87,87,92), V(C9,E9,E9,20), \ 242 | V(87,CE,CE,49), V(AA,55,55,FF), V(50,28,28,78), V(A5,DF,DF,7A), \ 243 | V(03,8C,8C,8F), V(59,A1,A1,F8), V(09,89,89,80), V(1A,0D,0D,17), \ 244 | V(65,BF,BF,DA), V(D7,E6,E6,31), V(84,42,42,C6), V(D0,68,68,B8), \ 245 | V(82,41,41,C3), V(29,99,99,B0), V(5A,2D,2D,77), V(1E,0F,0F,11), \ 246 | V(7B,B0,B0,CB), V(A8,54,54,FC), V(6D,BB,BB,D6), V(2C,16,16,3A) 247 | 248 | #define V(a,b,c,d) 0x##a##b##c##d 249 | static const uint32 FT0[256] = { FT }; 250 | #undef V 251 | 252 | #define V(a,b,c,d) 0x##d##a##b##c 253 | static const uint32 FT1[256] = { FT }; 254 | #undef V 255 | 256 | #define V(a,b,c,d) 0x##c##d##a##b 257 | static const uint32 FT2[256] = { FT }; 258 | #undef V 259 | 260 | #define V(a,b,c,d) 0x##b##c##d##a 261 | static const uint32 FT3[256] = { FT }; 262 | #undef V 263 | 264 | #undef FT 265 | 266 | /* reverse S-box */ 267 | 268 | static const uint32 RSb[256] = 269 | { 270 | 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 271 | 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, 272 | 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 273 | 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 274 | 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 275 | 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, 276 | 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 277 | 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, 278 | 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 279 | 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 280 | 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 281 | 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, 282 | 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 283 | 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, 284 | 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 285 | 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 286 | 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 287 | 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, 288 | 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 289 | 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, 290 | 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 291 | 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 292 | 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 293 | 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, 294 | 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 295 | 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, 296 | 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 297 | 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 298 | 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 299 | 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, 300 | 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 301 | 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D 302 | }; 303 | 304 | /* reverse tables */ 305 | 306 | #define RT \ 307 | \ 308 | V(51,F4,A7,50), V(7E,41,65,53), V(1A,17,A4,C3), V(3A,27,5E,96), \ 309 | V(3B,AB,6B,CB), V(1F,9D,45,F1), V(AC,FA,58,AB), V(4B,E3,03,93), \ 310 | V(20,30,FA,55), V(AD,76,6D,F6), V(88,CC,76,91), V(F5,02,4C,25), \ 311 | V(4F,E5,D7,FC), V(C5,2A,CB,D7), V(26,35,44,80), V(B5,62,A3,8F), \ 312 | V(DE,B1,5A,49), V(25,BA,1B,67), V(45,EA,0E,98), V(5D,FE,C0,E1), \ 313 | V(C3,2F,75,02), V(81,4C,F0,12), V(8D,46,97,A3), V(6B,D3,F9,C6), \ 314 | V(03,8F,5F,E7), V(15,92,9C,95), V(BF,6D,7A,EB), V(95,52,59,DA), \ 315 | V(D4,BE,83,2D), V(58,74,21,D3), V(49,E0,69,29), V(8E,C9,C8,44), \ 316 | V(75,C2,89,6A), V(F4,8E,79,78), V(99,58,3E,6B), V(27,B9,71,DD), \ 317 | V(BE,E1,4F,B6), V(F0,88,AD,17), V(C9,20,AC,66), V(7D,CE,3A,B4), \ 318 | V(63,DF,4A,18), V(E5,1A,31,82), V(97,51,33,60), V(62,53,7F,45), \ 319 | V(B1,64,77,E0), V(BB,6B,AE,84), V(FE,81,A0,1C), V(F9,08,2B,94), \ 320 | V(70,48,68,58), V(8F,45,FD,19), V(94,DE,6C,87), V(52,7B,F8,B7), \ 321 | V(AB,73,D3,23), V(72,4B,02,E2), V(E3,1F,8F,57), V(66,55,AB,2A), \ 322 | V(B2,EB,28,07), V(2F,B5,C2,03), V(86,C5,7B,9A), V(D3,37,08,A5), \ 323 | V(30,28,87,F2), V(23,BF,A5,B2), V(02,03,6A,BA), V(ED,16,82,5C), \ 324 | V(8A,CF,1C,2B), V(A7,79,B4,92), V(F3,07,F2,F0), V(4E,69,E2,A1), \ 325 | V(65,DA,F4,CD), V(06,05,BE,D5), V(D1,34,62,1F), V(C4,A6,FE,8A), \ 326 | V(34,2E,53,9D), V(A2,F3,55,A0), V(05,8A,E1,32), V(A4,F6,EB,75), \ 327 | V(0B,83,EC,39), V(40,60,EF,AA), V(5E,71,9F,06), V(BD,6E,10,51), \ 328 | V(3E,21,8A,F9), V(96,DD,06,3D), V(DD,3E,05,AE), V(4D,E6,BD,46), \ 329 | V(91,54,8D,B5), V(71,C4,5D,05), V(04,06,D4,6F), V(60,50,15,FF), \ 330 | V(19,98,FB,24), V(D6,BD,E9,97), V(89,40,43,CC), V(67,D9,9E,77), \ 331 | V(B0,E8,42,BD), V(07,89,8B,88), V(E7,19,5B,38), V(79,C8,EE,DB), \ 332 | V(A1,7C,0A,47), V(7C,42,0F,E9), V(F8,84,1E,C9), V(00,00,00,00), \ 333 | V(09,80,86,83), V(32,2B,ED,48), V(1E,11,70,AC), V(6C,5A,72,4E), \ 334 | V(FD,0E,FF,FB), V(0F,85,38,56), V(3D,AE,D5,1E), V(36,2D,39,27), \ 335 | V(0A,0F,D9,64), V(68,5C,A6,21), V(9B,5B,54,D1), V(24,36,2E,3A), \ 336 | V(0C,0A,67,B1), V(93,57,E7,0F), V(B4,EE,96,D2), V(1B,9B,91,9E), \ 337 | V(80,C0,C5,4F), V(61,DC,20,A2), V(5A,77,4B,69), V(1C,12,1A,16), \ 338 | V(E2,93,BA,0A), V(C0,A0,2A,E5), V(3C,22,E0,43), V(12,1B,17,1D), \ 339 | V(0E,09,0D,0B), V(F2,8B,C7,AD), V(2D,B6,A8,B9), V(14,1E,A9,C8), \ 340 | V(57,F1,19,85), V(AF,75,07,4C), V(EE,99,DD,BB), V(A3,7F,60,FD), \ 341 | V(F7,01,26,9F), V(5C,72,F5,BC), V(44,66,3B,C5), V(5B,FB,7E,34), \ 342 | V(8B,43,29,76), V(CB,23,C6,DC), V(B6,ED,FC,68), V(B8,E4,F1,63), \ 343 | V(D7,31,DC,CA), V(42,63,85,10), V(13,97,22,40), V(84,C6,11,20), \ 344 | V(85,4A,24,7D), V(D2,BB,3D,F8), V(AE,F9,32,11), V(C7,29,A1,6D), \ 345 | V(1D,9E,2F,4B), V(DC,B2,30,F3), V(0D,86,52,EC), V(77,C1,E3,D0), \ 346 | V(2B,B3,16,6C), V(A9,70,B9,99), V(11,94,48,FA), V(47,E9,64,22), \ 347 | V(A8,FC,8C,C4), V(A0,F0,3F,1A), V(56,7D,2C,D8), V(22,33,90,EF), \ 348 | V(87,49,4E,C7), V(D9,38,D1,C1), V(8C,CA,A2,FE), V(98,D4,0B,36), \ 349 | V(A6,F5,81,CF), V(A5,7A,DE,28), V(DA,B7,8E,26), V(3F,AD,BF,A4), \ 350 | V(2C,3A,9D,E4), V(50,78,92,0D), V(6A,5F,CC,9B), V(54,7E,46,62), \ 351 | V(F6,8D,13,C2), V(90,D8,B8,E8), V(2E,39,F7,5E), V(82,C3,AF,F5), \ 352 | V(9F,5D,80,BE), V(69,D0,93,7C), V(6F,D5,2D,A9), V(CF,25,12,B3), \ 353 | V(C8,AC,99,3B), V(10,18,7D,A7), V(E8,9C,63,6E), V(DB,3B,BB,7B), \ 354 | V(CD,26,78,09), V(6E,59,18,F4), V(EC,9A,B7,01), V(83,4F,9A,A8), \ 355 | V(E6,95,6E,65), V(AA,FF,E6,7E), V(21,BC,CF,08), V(EF,15,E8,E6), \ 356 | V(BA,E7,9B,D9), V(4A,6F,36,CE), V(EA,9F,09,D4), V(29,B0,7C,D6), \ 357 | V(31,A4,B2,AF), V(2A,3F,23,31), V(C6,A5,94,30), V(35,A2,66,C0), \ 358 | V(74,4E,BC,37), V(FC,82,CA,A6), V(E0,90,D0,B0), V(33,A7,D8,15), \ 359 | V(F1,04,98,4A), V(41,EC,DA,F7), V(7F,CD,50,0E), V(17,91,F6,2F), \ 360 | V(76,4D,D6,8D), V(43,EF,B0,4D), V(CC,AA,4D,54), V(E4,96,04,DF), \ 361 | V(9E,D1,B5,E3), V(4C,6A,88,1B), V(C1,2C,1F,B8), V(46,65,51,7F), \ 362 | V(9D,5E,EA,04), V(01,8C,35,5D), V(FA,87,74,73), V(FB,0B,41,2E), \ 363 | V(B3,67,1D,5A), V(92,DB,D2,52), V(E9,10,56,33), V(6D,D6,47,13), \ 364 | V(9A,D7,61,8C), V(37,A1,0C,7A), V(59,F8,14,8E), V(EB,13,3C,89), \ 365 | V(CE,A9,27,EE), V(B7,61,C9,35), V(E1,1C,E5,ED), V(7A,47,B1,3C), \ 366 | V(9C,D2,DF,59), V(55,F2,73,3F), V(18,14,CE,79), V(73,C7,37,BF), \ 367 | V(53,F7,CD,EA), V(5F,FD,AA,5B), V(DF,3D,6F,14), V(78,44,DB,86), \ 368 | V(CA,AF,F3,81), V(B9,68,C4,3E), V(38,24,34,2C), V(C2,A3,40,5F), \ 369 | V(16,1D,C3,72), V(BC,E2,25,0C), V(28,3C,49,8B), V(FF,0D,95,41), \ 370 | V(39,A8,01,71), V(08,0C,B3,DE), V(D8,B4,E4,9C), V(64,56,C1,90), \ 371 | V(7B,CB,84,61), V(D5,32,B6,70), V(48,6C,5C,74), V(D0,B8,57,42) 372 | 373 | #define V(a,b,c,d) 0x##a##b##c##d 374 | static const uint32 RT0[256] = { RT }; 375 | #undef V 376 | 377 | #define V(a,b,c,d) 0x##d##a##b##c 378 | static const uint32 RT1[256] = { RT }; 379 | #undef V 380 | 381 | #define V(a,b,c,d) 0x##c##d##a##b 382 | static const uint32 RT2[256] = { RT }; 383 | #undef V 384 | 385 | #define V(a,b,c,d) 0x##b##c##d##a 386 | static const uint32 RT3[256] = { RT }; 387 | #undef V 388 | 389 | #undef RT 390 | 391 | /* round constants */ 392 | 393 | static const uint32 RCON[10] = 394 | { 395 | 0x01000000, 0x02000000, 0x04000000, 0x08000000, 396 | 0x10000000, 0x20000000, 0x40000000, 0x80000000, 397 | 0x1B000000, 0x36000000 398 | }; 399 | 400 | int do_init = 0; 401 | 402 | void aes_gen_tables( void ) 403 | { 404 | } 405 | 406 | #endif 407 | 408 | /* platform-independant 32-bit integer manipulation macros */ 409 | 410 | #define GET_UINT32(n,b,i) \ 411 | { \ 412 | (n) = ( (uint32) (b)[(i) ] << 24 ) \ 413 | | ( (uint32) (b)[(i) + 1] << 16 ) \ 414 | | ( (uint32) (b)[(i) + 2] << 8 ) \ 415 | | ( (uint32) (b)[(i) + 3] ); \ 416 | } 417 | 418 | #define PUT_UINT32(n,b,i) \ 419 | { \ 420 | (b)[(i) ] = (uint8) ( (n) >> 24 ); \ 421 | (b)[(i) + 1] = (uint8) ( (n) >> 16 ); \ 422 | (b)[(i) + 2] = (uint8) ( (n) >> 8 ); \ 423 | (b)[(i) + 3] = (uint8) ( (n) ); \ 424 | } 425 | 426 | /* decryption key schedule tables */ 427 | 428 | int KT_init = 1; 429 | 430 | uint32 KT0[256]; 431 | uint32 KT1[256]; 432 | uint32 KT2[256]; 433 | uint32 KT3[256]; 434 | 435 | /* AES key scheduling routine */ 436 | 437 | int aes_set_key( aes_context *ctx, uint8 *key, int nbits ) 438 | { 439 | int i; 440 | uint32 *RK, *SK; 441 | 442 | if( do_init ) 443 | { 444 | aes_gen_tables(); 445 | 446 | do_init = 0; 447 | } 448 | 449 | switch( nbits ) 450 | { 451 | case 128: ctx->nr = 10; break; 452 | case 192: ctx->nr = 12; break; 453 | case 256: ctx->nr = 14; break; 454 | default : return( 1 ); 455 | } 456 | 457 | RK = ctx->erk; 458 | 459 | for( i = 0; i < (nbits >> 5); i++ ) 460 | { 461 | GET_UINT32( RK[i], key, i * 4 ); 462 | } 463 | 464 | /* setup encryption round keys */ 465 | 466 | switch( nbits ) 467 | { 468 | case 128: 469 | 470 | for( i = 0; i < 10; i++, RK += 4 ) 471 | { 472 | RK[4] = RK[0] ^ RCON[i] ^ 473 | ( FSb[ (uint8) ( RK[3] >> 16 ) ] << 24 ) ^ 474 | ( FSb[ (uint8) ( RK[3] >> 8 ) ] << 16 ) ^ 475 | ( FSb[ (uint8) ( RK[3] ) ] << 8 ) ^ 476 | ( FSb[ (uint8) ( RK[3] >> 24 ) ] ); 477 | 478 | RK[5] = RK[1] ^ RK[4]; 479 | RK[6] = RK[2] ^ RK[5]; 480 | RK[7] = RK[3] ^ RK[6]; 481 | } 482 | break; 483 | 484 | case 192: 485 | 486 | for( i = 0; i < 8; i++, RK += 6 ) 487 | { 488 | RK[6] = RK[0] ^ RCON[i] ^ 489 | ( FSb[ (uint8) ( RK[5] >> 16 ) ] << 24 ) ^ 490 | ( FSb[ (uint8) ( RK[5] >> 8 ) ] << 16 ) ^ 491 | ( FSb[ (uint8) ( RK[5] ) ] << 8 ) ^ 492 | ( FSb[ (uint8) ( RK[5] >> 24 ) ] ); 493 | 494 | RK[7] = RK[1] ^ RK[6]; 495 | RK[8] = RK[2] ^ RK[7]; 496 | RK[9] = RK[3] ^ RK[8]; 497 | RK[10] = RK[4] ^ RK[9]; 498 | RK[11] = RK[5] ^ RK[10]; 499 | } 500 | break; 501 | 502 | case 256: 503 | 504 | for( i = 0; i < 7; i++, RK += 8 ) 505 | { 506 | RK[8] = RK[0] ^ RCON[i] ^ 507 | ( FSb[ (uint8) ( RK[7] >> 16 ) ] << 24 ) ^ 508 | ( FSb[ (uint8) ( RK[7] >> 8 ) ] << 16 ) ^ 509 | ( FSb[ (uint8) ( RK[7] ) ] << 8 ) ^ 510 | ( FSb[ (uint8) ( RK[7] >> 24 ) ] ); 511 | 512 | RK[9] = RK[1] ^ RK[8]; 513 | RK[10] = RK[2] ^ RK[9]; 514 | RK[11] = RK[3] ^ RK[10]; 515 | 516 | RK[12] = RK[4] ^ 517 | ( FSb[ (uint8) ( RK[11] >> 24 ) ] << 24 ) ^ 518 | ( FSb[ (uint8) ( RK[11] >> 16 ) ] << 16 ) ^ 519 | ( FSb[ (uint8) ( RK[11] >> 8 ) ] << 8 ) ^ 520 | ( FSb[ (uint8) ( RK[11] ) ] ); 521 | 522 | RK[13] = RK[5] ^ RK[12]; 523 | RK[14] = RK[6] ^ RK[13]; 524 | RK[15] = RK[7] ^ RK[14]; 525 | } 526 | break; 527 | } 528 | 529 | /* setup decryption round keys */ 530 | 531 | if( KT_init ) 532 | { 533 | for( i = 0; i < 256; i++ ) 534 | { 535 | KT0[i] = RT0[ FSb[i] ]; 536 | KT1[i] = RT1[ FSb[i] ]; 537 | KT2[i] = RT2[ FSb[i] ]; 538 | KT3[i] = RT3[ FSb[i] ]; 539 | } 540 | 541 | KT_init = 0; 542 | } 543 | 544 | SK = ctx->drk; 545 | 546 | *SK++ = *RK++; 547 | *SK++ = *RK++; 548 | *SK++ = *RK++; 549 | *SK++ = *RK++; 550 | 551 | for( i = 1; i < ctx->nr; i++ ) 552 | { 553 | RK -= 8; 554 | 555 | *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^ 556 | KT1[ (uint8) ( *RK >> 16 ) ] ^ 557 | KT2[ (uint8) ( *RK >> 8 ) ] ^ 558 | KT3[ (uint8) ( *RK ) ]; RK++; 559 | 560 | *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^ 561 | KT1[ (uint8) ( *RK >> 16 ) ] ^ 562 | KT2[ (uint8) ( *RK >> 8 ) ] ^ 563 | KT3[ (uint8) ( *RK ) ]; RK++; 564 | 565 | *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^ 566 | KT1[ (uint8) ( *RK >> 16 ) ] ^ 567 | KT2[ (uint8) ( *RK >> 8 ) ] ^ 568 | KT3[ (uint8) ( *RK ) ]; RK++; 569 | 570 | *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^ 571 | KT1[ (uint8) ( *RK >> 16 ) ] ^ 572 | KT2[ (uint8) ( *RK >> 8 ) ] ^ 573 | KT3[ (uint8) ( *RK ) ]; RK++; 574 | } 575 | 576 | RK -= 8; 577 | 578 | *SK++ = *RK++; 579 | *SK++ = *RK++; 580 | *SK++ = *RK++; 581 | *SK++ = *RK++; 582 | 583 | return( 0 ); 584 | } 585 | 586 | /* AES 128-bit block encryption routine */ 587 | 588 | void aes_encrypt( aes_context *ctx, uint8 input[16], uint8 output[16] ) 589 | { 590 | uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; 591 | 592 | RK = ctx->erk; 593 | 594 | GET_UINT32( X0, input, 0 ); X0 ^= RK[0]; 595 | GET_UINT32( X1, input, 4 ); X1 ^= RK[1]; 596 | GET_UINT32( X2, input, 8 ); X2 ^= RK[2]; 597 | GET_UINT32( X3, input, 12 ); X3 ^= RK[3]; 598 | 599 | #define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ 600 | { \ 601 | RK += 4; \ 602 | \ 603 | X0 = RK[0] ^ FT0[ (uint8) ( Y0 >> 24 ) ] ^ \ 604 | FT1[ (uint8) ( Y1 >> 16 ) ] ^ \ 605 | FT2[ (uint8) ( Y2 >> 8 ) ] ^ \ 606 | FT3[ (uint8) ( Y3 ) ]; \ 607 | \ 608 | X1 = RK[1] ^ FT0[ (uint8) ( Y1 >> 24 ) ] ^ \ 609 | FT1[ (uint8) ( Y2 >> 16 ) ] ^ \ 610 | FT2[ (uint8) ( Y3 >> 8 ) ] ^ \ 611 | FT3[ (uint8) ( Y0 ) ]; \ 612 | \ 613 | X2 = RK[2] ^ FT0[ (uint8) ( Y2 >> 24 ) ] ^ \ 614 | FT1[ (uint8) ( Y3 >> 16 ) ] ^ \ 615 | FT2[ (uint8) ( Y0 >> 8 ) ] ^ \ 616 | FT3[ (uint8) ( Y1 ) ]; \ 617 | \ 618 | X3 = RK[3] ^ FT0[ (uint8) ( Y3 >> 24 ) ] ^ \ 619 | FT1[ (uint8) ( Y0 >> 16 ) ] ^ \ 620 | FT2[ (uint8) ( Y1 >> 8 ) ] ^ \ 621 | FT3[ (uint8) ( Y2 ) ]; \ 622 | } 623 | 624 | AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */ 625 | AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */ 626 | AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */ 627 | AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */ 628 | AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */ 629 | AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */ 630 | AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */ 631 | AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */ 632 | AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */ 633 | 634 | if( ctx->nr > 10 ) 635 | { 636 | AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 10 */ 637 | AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 11 */ 638 | } 639 | 640 | if( ctx->nr > 12 ) 641 | { 642 | AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 12 */ 643 | AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 13 */ 644 | } 645 | 646 | /* last round */ 647 | 648 | RK += 4; 649 | 650 | X0 = RK[0] ^ ( FSb[ (uint8) ( Y0 >> 24 ) ] << 24 ) ^ 651 | ( FSb[ (uint8) ( Y1 >> 16 ) ] << 16 ) ^ 652 | ( FSb[ (uint8) ( Y2 >> 8 ) ] << 8 ) ^ 653 | ( FSb[ (uint8) ( Y3 ) ] ); 654 | 655 | X1 = RK[1] ^ ( FSb[ (uint8) ( Y1 >> 24 ) ] << 24 ) ^ 656 | ( FSb[ (uint8) ( Y2 >> 16 ) ] << 16 ) ^ 657 | ( FSb[ (uint8) ( Y3 >> 8 ) ] << 8 ) ^ 658 | ( FSb[ (uint8) ( Y0 ) ] ); 659 | 660 | X2 = RK[2] ^ ( FSb[ (uint8) ( Y2 >> 24 ) ] << 24 ) ^ 661 | ( FSb[ (uint8) ( Y3 >> 16 ) ] << 16 ) ^ 662 | ( FSb[ (uint8) ( Y0 >> 8 ) ] << 8 ) ^ 663 | ( FSb[ (uint8) ( Y1 ) ] ); 664 | 665 | X3 = RK[3] ^ ( FSb[ (uint8) ( Y3 >> 24 ) ] << 24 ) ^ 666 | ( FSb[ (uint8) ( Y0 >> 16 ) ] << 16 ) ^ 667 | ( FSb[ (uint8) ( Y1 >> 8 ) ] << 8 ) ^ 668 | ( FSb[ (uint8) ( Y2 ) ] ); 669 | 670 | PUT_UINT32( X0, output, 0 ); 671 | PUT_UINT32( X1, output, 4 ); 672 | PUT_UINT32( X2, output, 8 ); 673 | PUT_UINT32( X3, output, 12 ); 674 | } 675 | 676 | /* AES 128-bit block decryption routine */ 677 | 678 | void aes_decrypt( aes_context *ctx, uint8 input[16], uint8 output[16] ) 679 | { 680 | uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; 681 | 682 | RK = ctx->drk; 683 | 684 | GET_UINT32( X0, input, 0 ); X0 ^= RK[0]; 685 | GET_UINT32( X1, input, 4 ); X1 ^= RK[1]; 686 | GET_UINT32( X2, input, 8 ); X2 ^= RK[2]; 687 | GET_UINT32( X3, input, 12 ); X3 ^= RK[3]; 688 | 689 | #define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ 690 | { \ 691 | RK += 4; \ 692 | \ 693 | X0 = RK[0] ^ RT0[ (uint8) ( Y0 >> 24 ) ] ^ \ 694 | RT1[ (uint8) ( Y3 >> 16 ) ] ^ \ 695 | RT2[ (uint8) ( Y2 >> 8 ) ] ^ \ 696 | RT3[ (uint8) ( Y1 ) ]; \ 697 | \ 698 | X1 = RK[1] ^ RT0[ (uint8) ( Y1 >> 24 ) ] ^ \ 699 | RT1[ (uint8) ( Y0 >> 16 ) ] ^ \ 700 | RT2[ (uint8) ( Y3 >> 8 ) ] ^ \ 701 | RT3[ (uint8) ( Y2 ) ]; \ 702 | \ 703 | X2 = RK[2] ^ RT0[ (uint8) ( Y2 >> 24 ) ] ^ \ 704 | RT1[ (uint8) ( Y1 >> 16 ) ] ^ \ 705 | RT2[ (uint8) ( Y0 >> 8 ) ] ^ \ 706 | RT3[ (uint8) ( Y3 ) ]; \ 707 | \ 708 | X3 = RK[3] ^ RT0[ (uint8) ( Y3 >> 24 ) ] ^ \ 709 | RT1[ (uint8) ( Y2 >> 16 ) ] ^ \ 710 | RT2[ (uint8) ( Y1 >> 8 ) ] ^ \ 711 | RT3[ (uint8) ( Y0 ) ]; \ 712 | } 713 | 714 | AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */ 715 | AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */ 716 | AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */ 717 | AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */ 718 | AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */ 719 | AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */ 720 | AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */ 721 | AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */ 722 | AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */ 723 | 724 | if( ctx->nr > 10 ) 725 | { 726 | AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 10 */ 727 | AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 11 */ 728 | } 729 | 730 | if( ctx->nr > 12 ) 731 | { 732 | AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 12 */ 733 | AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 13 */ 734 | } 735 | 736 | /* last round */ 737 | 738 | RK += 4; 739 | 740 | X0 = RK[0] ^ ( RSb[ (uint8) ( Y0 >> 24 ) ] << 24 ) ^ 741 | ( RSb[ (uint8) ( Y3 >> 16 ) ] << 16 ) ^ 742 | ( RSb[ (uint8) ( Y2 >> 8 ) ] << 8 ) ^ 743 | ( RSb[ (uint8) ( Y1 ) ] ); 744 | 745 | X1 = RK[1] ^ ( RSb[ (uint8) ( Y1 >> 24 ) ] << 24 ) ^ 746 | ( RSb[ (uint8) ( Y0 >> 16 ) ] << 16 ) ^ 747 | ( RSb[ (uint8) ( Y3 >> 8 ) ] << 8 ) ^ 748 | ( RSb[ (uint8) ( Y2 ) ] ); 749 | 750 | X2 = RK[2] ^ ( RSb[ (uint8) ( Y2 >> 24 ) ] << 24 ) ^ 751 | ( RSb[ (uint8) ( Y1 >> 16 ) ] << 16 ) ^ 752 | ( RSb[ (uint8) ( Y0 >> 8 ) ] << 8 ) ^ 753 | ( RSb[ (uint8) ( Y3 ) ] ); 754 | 755 | X3 = RK[3] ^ ( RSb[ (uint8) ( Y3 >> 24 ) ] << 24 ) ^ 756 | ( RSb[ (uint8) ( Y2 >> 16 ) ] << 16 ) ^ 757 | ( RSb[ (uint8) ( Y1 >> 8 ) ] << 8 ) ^ 758 | ( RSb[ (uint8) ( Y0 ) ] ); 759 | 760 | PUT_UINT32( X0, output, 0 ); 761 | PUT_UINT32( X1, output, 4 ); 762 | PUT_UINT32( X2, output, 8 ); 763 | PUT_UINT32( X3, output, 12 ); 764 | } 765 | 766 | #ifdef TEST 767 | 768 | #include 769 | #include 770 | 771 | /* 772 | * Rijndael Monte Carlo Test: ECB mode 773 | * source: NIST - rijndael-vals.zip 774 | */ 775 | 776 | static unsigned char AES_enc_test[3][16] = 777 | { 778 | { 0xA0, 0x43, 0x77, 0xAB, 0xE2, 0x59, 0xB0, 0xD0, 779 | 0xB5, 0xBA, 0x2D, 0x40, 0xA5, 0x01, 0x97, 0x1B }, 780 | { 0x4E, 0x46, 0xF8, 0xC5, 0x09, 0x2B, 0x29, 0xE2, 781 | 0x9A, 0x97, 0x1A, 0x0C, 0xD1, 0xF6, 0x10, 0xFB }, 782 | { 0x1F, 0x67, 0x63, 0xDF, 0x80, 0x7A, 0x7E, 0x70, 783 | 0x96, 0x0D, 0x4C, 0xD3, 0x11, 0x8E, 0x60, 0x1A } 784 | }; 785 | 786 | static unsigned char AES_dec_test[3][16] = 787 | { 788 | { 0xF5, 0xBF, 0x8B, 0x37, 0x13, 0x6F, 0x2E, 0x1F, 789 | 0x6B, 0xEC, 0x6F, 0x57, 0x20, 0x21, 0xE3, 0xBA }, 790 | { 0xF1, 0xA8, 0x1B, 0x68, 0xF6, 0xE5, 0xA6, 0x27, 791 | 0x1A, 0x8C, 0xB2, 0x4E, 0x7D, 0x94, 0x91, 0xEF }, 792 | { 0x4D, 0xE0, 0xC6, 0xDF, 0x7C, 0xB1, 0x69, 0x72, 793 | 0x84, 0x60, 0x4D, 0x60, 0x27, 0x1B, 0xC5, 0x9A } 794 | }; 795 | 796 | int main( void ) 797 | { 798 | int m, n, i, j; 799 | aes_context ctx; 800 | unsigned char buf[16]; 801 | unsigned char key[32]; 802 | 803 | for( m = 0; m < 2; m++ ) 804 | { 805 | printf( "\n Rijndael Monte Carlo Test (ECB mode) - " ); 806 | 807 | if( m == 0 ) printf( "encryption\n\n" ); 808 | if( m == 1 ) printf( "decryption\n\n" ); 809 | 810 | for( n = 0; n < 3; n++ ) 811 | { 812 | printf( " Test %d, key size = %3d bits: ", 813 | n + 1, 128 + n * 64 ); 814 | 815 | fflush( stdout ); 816 | 817 | memset( buf, 0, 16 ); 818 | memset( key, 0, 16 + n * 8 ); 819 | 820 | for( i = 0; i < 400; i++ ) 821 | { 822 | aes_set_key( &ctx, key, 128 + n * 64 ); 823 | 824 | for( j = 0; j < 9999; j++ ) 825 | { 826 | if( m == 0 ) aes_encrypt( &ctx, buf, buf ); 827 | if( m == 1 ) aes_decrypt( &ctx, buf, buf ); 828 | } 829 | 830 | if( n > 0 ) 831 | { 832 | for( j = 0; j < (n << 3); j++ ) 833 | { 834 | key[j] ^= buf[j + 16 - (n << 3)]; 835 | } 836 | } 837 | 838 | if( m == 0 ) aes_encrypt( &ctx, buf, buf ); 839 | if( m == 1 ) aes_decrypt( &ctx, buf, buf ); 840 | 841 | for( j = 0; j < 16; j++ ) 842 | { 843 | key[j + (n << 3)] ^= buf[j]; 844 | } 845 | } 846 | 847 | if( ( m == 0 && memcmp( buf, AES_enc_test[n], 16 ) != 0 ) || 848 | ( m == 1 && memcmp( buf, AES_dec_test[n], 16 ) != 0 ) ) 849 | { 850 | printf( "failed!\n" ); 851 | return( 1 ); 852 | } 853 | 854 | printf( "passed.\n" ); 855 | } 856 | } 857 | 858 | printf( "\n" ); 859 | 860 | return( 0 ); 861 | } 862 | 863 | #endif 864 | 865 | -------------------------------------------------------------------------------- /aes.h: -------------------------------------------------------------------------------- 1 | #ifndef _AES_H 2 | #define _AES_H 3 | 4 | #ifndef uint8 5 | #define uint8 unsigned char 6 | #endif 7 | 8 | #ifndef uint32 9 | #define uint32 unsigned long int 10 | #endif 11 | 12 | typedef struct 13 | { 14 | uint32 erk[64]; /* encryption round keys */ 15 | uint32 drk[64]; /* decryption round keys */ 16 | int nr; /* number of rounds */ 17 | } 18 | aes_context; 19 | 20 | int aes_set_key( aes_context *ctx, uint8 *key, int nbits ); 21 | void aes_encrypt( aes_context *ctx, uint8 input[16], uint8 output[16] ); 22 | void aes_decrypt( aes_context *ctx, uint8 input[16], uint8 output[16] ); 23 | 24 | #endif /* aes.h */ 25 | -------------------------------------------------------------------------------- /aescrypt2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palmerc/AESCrypt2/16da035f253ca9908311804b0a74acc4bd623eb1/aescrypt2 -------------------------------------------------------------------------------- /aescrypt2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * AES-CBC-256/HMAC-SHA256 file encryption 3 | * 4 | * Copyright (C) 2004,2005 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 | 21 | #ifndef WIN32 22 | #include 23 | #include 24 | #else 25 | #include 26 | #include 27 | #endif 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include "aes.h" 35 | #include "sha256.h" 36 | 37 | #define MODE_ENCRYPT 0 38 | #define MODE_DECRYPT 1 39 | 40 | /* miscellaneous utility routines */ 41 | 42 | void do_exit( int retcode ) 43 | { 44 | #ifdef WIN32 45 | int i; 46 | 47 | printf( "\nPress Ctrl-C to exit.\n" ); 48 | scanf( "%d", &i ); 49 | #endif 50 | 51 | exit( retcode ); 52 | } 53 | 54 | int my_fread( FILE *f, void *ptr, size_t size ) 55 | { 56 | if( fread( ptr, 1, size, f ) != size ) 57 | { 58 | if( ferror( f ) ) 59 | { 60 | fprintf( stderr, "fread(%d bytes) failed\n", size ); 61 | return( 1 ); 62 | } 63 | 64 | if( feof( f ) ) 65 | { 66 | fprintf( stderr, "fread(%d bytes): short file\n", size ); 67 | return( 1 ); 68 | } 69 | } 70 | 71 | return( 0 ); 72 | } 73 | 74 | int my_fwrite( FILE *f, void *ptr, size_t size ) 75 | { 76 | if( fwrite( ptr, 1, size, f ) != size ) 77 | { 78 | if( ferror( f ) ) 79 | { 80 | fprintf( stderr, "fwrite(%d bytes) failed\n", size ); 81 | return( 1 ); 82 | } 83 | 84 | if( feof( f ) ) 85 | { 86 | fprintf( stderr, "fwrite(%d bytes): short file\n", size ); 87 | return( 1 ); 88 | } 89 | } 90 | 91 | return( 0 ); 92 | } 93 | 94 | /* program entry point */ 95 | 96 | int main( int argc, char *argv[] ) 97 | { 98 | char user_key[512]; 99 | unsigned char IV[16]; 100 | unsigned char tmp[16]; 101 | unsigned char digest[32]; 102 | unsigned char k_ipad[64]; 103 | unsigned char k_opad[64]; 104 | unsigned char buffer[1024]; 105 | 106 | int i, n, mode, lastn; 107 | FILE *fkey, *fin, *fout; 108 | 109 | #ifndef WIN32 110 | off_t filesize, offset; 111 | #else 112 | __int64 filesize, offset; 113 | #endif 114 | 115 | aes_context aes_ctx; 116 | sha256_context sha_ctx; 117 | 118 | /* check the arguments */ 119 | 120 | if( argc != 5 ) 121 | { 122 | printf( "\n aescrypt2 \n\n mode 0 = encrypt, 1 = decrypt\n\n" ); 124 | 125 | #ifdef WIN32 126 | printf( "\n" ); 127 | 128 | printf( " mode -> " ); 129 | argv[1] = malloc( 1024 ); 130 | scanf( "%1023s", argv[1] ); 131 | 132 | printf( " infile -> " ); 133 | argv[2] = malloc( 1024 ); 134 | scanf( "%1023s", argv[2] ); 135 | 136 | printf( " outfile -> " ); 137 | argv[3] = malloc( 1024 ); 138 | scanf( "%1023s", argv[3] ); 139 | 140 | printf( " key -> " ); 141 | argv[4] = malloc( 1024 ); 142 | scanf( "%1023s", argv[4] ); 143 | 144 | printf( "\n" ); 145 | #else 146 | do_exit( 1 ); 147 | #endif 148 | } 149 | 150 | sscanf( argv[1], "%d", &mode ); 151 | 152 | if( mode != MODE_ENCRYPT && mode != MODE_DECRYPT ) 153 | { 154 | fprintf( stderr, "invalide mode \"%d\"\n", mode ); 155 | do_exit( 1 ); 156 | } 157 | 158 | if( ( fin = fopen( argv[2], "rb" ) ) == NULL ) 159 | { 160 | fprintf( stderr, "fopen(%s,rb) failed\n", argv[2] ); 161 | do_exit( 1 ); 162 | } 163 | 164 | if( ! ( fout = fopen( argv[3], "wb" ) ) ) 165 | { 166 | fprintf( stderr, "fopen(%s,wb) failed\n", argv[3] ); 167 | do_exit( 1 ); 168 | } 169 | 170 | /* read the secret key and clean the command line */ 171 | 172 | memset( user_key, 0, sizeof( user_key ) ); 173 | 174 | if( ( fkey = fopen( argv[4], "rb" ) ) != NULL ) 175 | { 176 | fread( user_key, 1, sizeof( user_key ) - 1, fkey ); 177 | fclose( fkey ); 178 | } 179 | else 180 | strncpy( user_key, argv[4], sizeof( user_key ) - 1 ); 181 | 182 | memset( argv[4], 0, strlen( argv[4] ) ); 183 | 184 | /* read the input file size */ 185 | 186 | #ifndef WIN32 187 | if( ( filesize = lseek( fileno( fin ), 0, SEEK_END ) ) < 0 ) 188 | { 189 | perror( "lseek" ); 190 | return( 1 ); 191 | } 192 | #else 193 | { 194 | LARGE_INTEGER li_size; 195 | 196 | li_size.QuadPart = 0; 197 | li_size.LowPart = SetFilePointer( 198 | (HANDLE) _get_osfhandle( fileno( fin ) ), 199 | li_size.LowPart, &li_size.HighPart, FILE_END ); 200 | 201 | if( li_size.LowPart == -1 && GetLastError() != NO_ERROR ) 202 | { 203 | fprintf( stderr, "SetFilePointer(0,FILE_END) failed\n" ); 204 | do_exit( 1 ); 205 | } 206 | 207 | filesize = li_size.QuadPart; 208 | } 209 | #endif 210 | 211 | if( fseek( fin, 0, SEEK_SET ) < 0 ) 212 | { 213 | fprintf( stderr, "fseek(0,SEEK_SET) failed\n" ); 214 | do_exit( 1 ); 215 | } 216 | 217 | if( mode == MODE_ENCRYPT ) 218 | { 219 | /* compute the initialization vector as: * 220 | * IV = SHA256( time + filesize + filename ) * 221 | * truncated to the AES block size (16) */ 222 | 223 | time_t cur_time = time( NULL ); 224 | 225 | for( i = 0; i < 8; i++ ) 226 | buffer[i ] = (unsigned char) ( cur_time >> (i * 8) ); 227 | 228 | for( i = 0; i < 8; i++ ) 229 | buffer[i + 8] = (unsigned char) ( filesize >> (i * 8) ); 230 | 231 | sha256_starts( &sha_ctx ); 232 | sha256_update( &sha_ctx, buffer, 16 ); 233 | sha256_update( &sha_ctx, (unsigned char *) argv[2], 234 | strlen( argv[2] ) ); 235 | sha256_finish( &sha_ctx, digest ); 236 | 237 | memcpy( IV, digest, 16 ); 238 | 239 | /* four bits in the IV are actually used to store * 240 | * the file size modulo the AES block size (16) */ 241 | 242 | lastn = (int) ( filesize & 0x0F ); 243 | 244 | IV[15] &= 0xF0; 245 | IV[15] |= lastn; 246 | 247 | /* append the IV at the beginning of the output */ 248 | 249 | if( my_fwrite( fout, IV, 16 ) != 0 ) 250 | do_exit( 1 ); 251 | 252 | /* hash the IV and the secret key together 8192 times * 253 | * using the result to setup the AES context and HMAC */ 254 | 255 | memset( digest, 0, 32 ); 256 | memcpy( digest, IV, 16 ); 257 | 258 | for( i = 0; i < 8192; i++ ) 259 | { 260 | sha256_starts( &sha_ctx ); 261 | sha256_update( &sha_ctx, digest, 32 ); 262 | sha256_update( &sha_ctx, (unsigned char *) user_key, 263 | strlen( user_key ) ); 264 | sha256_finish( &sha_ctx, digest ); 265 | } 266 | 267 | memset( user_key, 0, sizeof( user_key ) ); 268 | 269 | aes_set_key( &aes_ctx, digest, 256 ); 270 | 271 | memset( k_ipad, 0x36, 64 ); 272 | memset( k_opad, 0x5C, 64 ); 273 | 274 | for( i = 0; i < 32; i++ ) 275 | { 276 | k_ipad[i] ^= digest[i]; 277 | k_opad[i] ^= digest[i]; 278 | } 279 | 280 | /* encrypt and write the ciphertext */ 281 | 282 | sha256_starts( &sha_ctx ); 283 | sha256_update( &sha_ctx, k_ipad, 64 ); 284 | 285 | for( offset = 0; offset < filesize; offset += 16 ) 286 | { 287 | n = ( filesize - offset > 16 ) ? 16 : (int) 288 | ( filesize - offset ); 289 | 290 | if( my_fread( fin, buffer, n ) != 0 ) 291 | do_exit( 1 ); 292 | 293 | for( i = 0; i < 16; i++ ) 294 | buffer[i] ^= IV[i]; 295 | 296 | aes_encrypt( &aes_ctx, buffer, buffer ); 297 | sha256_update( &sha_ctx, buffer, 16 ); 298 | 299 | if( my_fwrite( fout, buffer, 16 ) != 0 ) 300 | do_exit( 1 ); 301 | 302 | memcpy( IV, buffer, 16 ); 303 | } 304 | 305 | /* finally write the HMAC */ 306 | 307 | sha256_finish( &sha_ctx, digest ); 308 | 309 | sha256_starts( &sha_ctx ); 310 | sha256_update( &sha_ctx, k_opad, 64 ); 311 | sha256_update( &sha_ctx, digest, 32 ); 312 | sha256_finish( &sha_ctx, digest ); 313 | 314 | if( my_fwrite( fout, digest, 32 ) != 0 ) 315 | do_exit( 1 ); 316 | } 317 | 318 | if( mode == MODE_DECRYPT ) 319 | { 320 | /* 321 | * The encrypted file shall be structured as: 322 | * 323 | * 00 : 15 Initialization Vector 324 | * 16 : 31 AES Encrypted Block #1 325 | * ... ... 326 | * N *16 : (N+1)*16 - 1 AES Encrypted Block #N 327 | * (N+1)*16 : (N+1)*16 + 32 HMAC-SHA256( Ciphertext ) 328 | */ 329 | 330 | if( filesize < 48 ) 331 | { 332 | fprintf( stderr, "file too short to be encrypted!\n" ); 333 | do_exit( 1 ); 334 | } 335 | 336 | if( ( filesize & 0x0F ) != 0 ) 337 | { 338 | fprintf( stderr, "file size not a multiple of 16!\n" ); 339 | do_exit( 1 ); 340 | } 341 | 342 | /* substract the IV + HMAC length */ 343 | 344 | filesize -= ( 16 + 32 ); 345 | 346 | /* read the IV and original filesize modulo 16 */ 347 | 348 | if( my_fread( fin, buffer, 16 ) != 0 ) 349 | do_exit( 1 ); 350 | 351 | memcpy( IV, buffer, 16 ); 352 | 353 | lastn = IV[15] & 0x0F; 354 | 355 | /* hash the IV and the secret key together 8192 times * 356 | * using the result to setup the AES context and HMAC */ 357 | 358 | memset( digest, 0, 32 ); 359 | memcpy( digest, IV, 16 ); 360 | 361 | for( i = 0; i < 8192; i++ ) 362 | { 363 | sha256_starts( &sha_ctx ); 364 | sha256_update( &sha_ctx, digest, 32 ); 365 | sha256_update( &sha_ctx, (unsigned char *) user_key, 366 | strlen( user_key ) ); 367 | sha256_finish( &sha_ctx, digest ); 368 | } 369 | 370 | memset( user_key, 0, sizeof( user_key ) ); 371 | 372 | aes_set_key( &aes_ctx, digest, 256 ); 373 | 374 | memset( k_ipad, 0x36, 64 ); 375 | memset( k_opad, 0x5C, 64 ); 376 | 377 | for( i = 0; i < 32; i++ ) 378 | { 379 | k_ipad[i] ^= digest[i]; 380 | k_opad[i] ^= digest[i]; 381 | } 382 | 383 | /* now decrypt and write the plaintext */ 384 | 385 | sha256_starts( &sha_ctx ); 386 | sha256_update( &sha_ctx, k_ipad, 64 ); 387 | 388 | for( offset = 0; offset < filesize; offset += 16 ) 389 | { 390 | if( my_fread( fin, buffer, 16 ) != 0 ) 391 | do_exit( 1 ); 392 | 393 | memcpy( tmp, buffer, 16 ); 394 | 395 | sha256_update( &sha_ctx, buffer, 16 ); 396 | aes_decrypt( &aes_ctx, buffer, buffer ); 397 | 398 | for( i = 0; i < 16; i++ ) 399 | buffer[i] ^= IV[i]; 400 | 401 | memcpy( IV, tmp, 16 ); 402 | 403 | n = ( lastn > 0 && offset == filesize - 16 ) 404 | ? lastn : 16; 405 | 406 | if( my_fwrite( fout, buffer, n ) != 0 ) 407 | do_exit( 1 ); 408 | } 409 | 410 | /* verify the message authentication code */ 411 | 412 | sha256_finish( &sha_ctx, digest ); 413 | 414 | sha256_starts( &sha_ctx ); 415 | sha256_update( &sha_ctx, k_opad, 64 ); 416 | sha256_update( &sha_ctx, digest, 32 ); 417 | sha256_finish( &sha_ctx, digest ); 418 | 419 | if( my_fread( fin, buffer, 32 ) != 0 ) 420 | do_exit( 1 ); 421 | 422 | if( memcmp( digest, buffer, 32 ) != 0 ) 423 | { 424 | fprintf( stderr, "HMAC check failed: wrong key, " 425 | "or file corrupted.\n" ); 426 | do_exit( 1 ); 427 | } 428 | } 429 | 430 | return( 0 ); 431 | } 432 | -------------------------------------------------------------------------------- /aescrypt2.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="aescrypt2" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Console Application" 0x0103 6 | 7 | CFG=aescrypt2 - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "aescrypt2.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "aescrypt2.mak" CFG="aescrypt2 - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "aescrypt2 - Win32 Release" (based on "Win32 (x86) Console Application") 21 | !MESSAGE "aescrypt2 - Win32 Debug" (based on "Win32 (x86) Console Application") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | RSC=rc.exe 30 | 31 | !IF "$(CFG)" == "aescrypt2 - Win32 Release" 32 | 33 | # PROP BASE Use_MFC 0 34 | # PROP BASE Use_Debug_Libraries 0 35 | # PROP BASE Output_Dir "Release" 36 | # PROP BASE Intermediate_Dir "Release" 37 | # PROP BASE Target_Dir "" 38 | # PROP Use_MFC 0 39 | # PROP Use_Debug_Libraries 0 40 | # PROP Output_Dir "Release" 41 | # PROP Intermediate_Dir "Release" 42 | # PROP Target_Dir "" 43 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 44 | # ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 45 | # ADD BASE RSC /l 0x40c /d "NDEBUG" 46 | # ADD RSC /l 0x40c /d "NDEBUG" 47 | BSC32=bscmake.exe 48 | # ADD BASE BSC32 /nologo 49 | # ADD BSC32 /nologo 50 | LINK32=link.exe 51 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 52 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 53 | 54 | !ELSEIF "$(CFG)" == "aescrypt2 - Win32 Debug" 55 | 56 | # PROP BASE Use_MFC 0 57 | # PROP BASE Use_Debug_Libraries 1 58 | # PROP BASE Output_Dir "Debug" 59 | # PROP BASE Intermediate_Dir "Debug" 60 | # PROP BASE Target_Dir "" 61 | # PROP Use_MFC 0 62 | # PROP Use_Debug_Libraries 1 63 | # PROP Output_Dir "Debug" 64 | # PROP Intermediate_Dir "Debug" 65 | # PROP Target_Dir "" 66 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c 67 | # ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c 68 | # ADD BASE RSC /l 0x40c /d "_DEBUG" 69 | # ADD RSC /l 0x40c /d "_DEBUG" 70 | BSC32=bscmake.exe 71 | # ADD BASE BSC32 /nologo 72 | # ADD BSC32 /nologo 73 | LINK32=link.exe 74 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 75 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 76 | 77 | !ENDIF 78 | 79 | # Begin Target 80 | 81 | # Name "aescrypt2 - Win32 Release" 82 | # Name "aescrypt2 - Win32 Debug" 83 | # Begin Group "Source Files" 84 | 85 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 86 | # Begin Source File 87 | 88 | SOURCE=.\aes.c 89 | # End Source File 90 | # Begin Source File 91 | 92 | SOURCE=.\aescrypt2.c 93 | # End Source File 94 | # Begin Source File 95 | 96 | SOURCE=.\sha256.c 97 | # End Source File 98 | # End Group 99 | # Begin Group "Header Files" 100 | 101 | # PROP Default_Filter "h;hpp;hxx;hm;inl" 102 | # Begin Source File 103 | 104 | SOURCE=.\aes.h 105 | # End Source File 106 | # Begin Source File 107 | 108 | SOURCE=.\sha256.h 109 | # End Source File 110 | # End Group 111 | # Begin Group "Resource Files" 112 | 113 | # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" 114 | # End Group 115 | # End Target 116 | # End Project 117 | -------------------------------------------------------------------------------- /aescrypt2.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palmerc/AESCrypt2/16da035f253ca9908311804b0a74acc4bd623eb1/aescrypt2.exe -------------------------------------------------------------------------------- /sha256.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FIPS-180-2 compliant SHA-256 implementation 3 | * 4 | * Copyright (C) 2001-2003 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 | 21 | #include 22 | 23 | #include "sha256.h" 24 | 25 | #define GET_UINT32(n,b,i) \ 26 | { \ 27 | (n) = ( (uint32) (b)[(i) ] << 24 ) \ 28 | | ( (uint32) (b)[(i) + 1] << 16 ) \ 29 | | ( (uint32) (b)[(i) + 2] << 8 ) \ 30 | | ( (uint32) (b)[(i) + 3] ); \ 31 | } 32 | 33 | #define PUT_UINT32(n,b,i) \ 34 | { \ 35 | (b)[(i) ] = (uint8) ( (n) >> 24 ); \ 36 | (b)[(i) + 1] = (uint8) ( (n) >> 16 ); \ 37 | (b)[(i) + 2] = (uint8) ( (n) >> 8 ); \ 38 | (b)[(i) + 3] = (uint8) ( (n) ); \ 39 | } 40 | 41 | void sha256_starts( sha256_context *ctx ) 42 | { 43 | ctx->total[0] = 0; 44 | ctx->total[1] = 0; 45 | 46 | ctx->state[0] = 0x6A09E667; 47 | ctx->state[1] = 0xBB67AE85; 48 | ctx->state[2] = 0x3C6EF372; 49 | ctx->state[3] = 0xA54FF53A; 50 | ctx->state[4] = 0x510E527F; 51 | ctx->state[5] = 0x9B05688C; 52 | ctx->state[6] = 0x1F83D9AB; 53 | ctx->state[7] = 0x5BE0CD19; 54 | } 55 | 56 | void sha256_process( sha256_context *ctx, uint8 data[64] ) 57 | { 58 | uint32 temp1, temp2, W[64]; 59 | uint32 A, B, C, D, E, F, G, H; 60 | 61 | GET_UINT32( W[0], data, 0 ); 62 | GET_UINT32( W[1], data, 4 ); 63 | GET_UINT32( W[2], data, 8 ); 64 | GET_UINT32( W[3], data, 12 ); 65 | GET_UINT32( W[4], data, 16 ); 66 | GET_UINT32( W[5], data, 20 ); 67 | GET_UINT32( W[6], data, 24 ); 68 | GET_UINT32( W[7], data, 28 ); 69 | GET_UINT32( W[8], data, 32 ); 70 | GET_UINT32( W[9], data, 36 ); 71 | GET_UINT32( W[10], data, 40 ); 72 | GET_UINT32( W[11], data, 44 ); 73 | GET_UINT32( W[12], data, 48 ); 74 | GET_UINT32( W[13], data, 52 ); 75 | GET_UINT32( W[14], data, 56 ); 76 | GET_UINT32( W[15], data, 60 ); 77 | 78 | #define SHR(x,n) ((x & 0xFFFFFFFF) >> n) 79 | #define ROTR(x,n) (SHR(x,n) | (x << (32 - n))) 80 | 81 | #define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) 82 | #define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) 83 | 84 | #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) 85 | #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) 86 | 87 | #define F0(x,y,z) ((x & y) | (z & (x | y))) 88 | #define F1(x,y,z) (z ^ (x & (y ^ z))) 89 | 90 | #define R(t) \ 91 | ( \ 92 | W[t] = S1(W[t - 2]) + W[t - 7] + \ 93 | S0(W[t - 15]) + W[t - 16] \ 94 | ) 95 | 96 | #define P(a,b,c,d,e,f,g,h,x,K) \ 97 | { \ 98 | temp1 = h + S3(e) + F1(e,f,g) + K + x; \ 99 | temp2 = S2(a) + F0(a,b,c); \ 100 | d += temp1; h = temp1 + temp2; \ 101 | } 102 | 103 | A = ctx->state[0]; 104 | B = ctx->state[1]; 105 | C = ctx->state[2]; 106 | D = ctx->state[3]; 107 | E = ctx->state[4]; 108 | F = ctx->state[5]; 109 | G = ctx->state[6]; 110 | H = ctx->state[7]; 111 | 112 | P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98 ); 113 | P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491 ); 114 | P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF ); 115 | P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5 ); 116 | P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B ); 117 | P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1 ); 118 | P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4 ); 119 | P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5 ); 120 | P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98 ); 121 | P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01 ); 122 | P( G, H, A, B, C, D, E, F, W[10], 0x243185BE ); 123 | P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3 ); 124 | P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74 ); 125 | P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE ); 126 | P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7 ); 127 | P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174 ); 128 | P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1 ); 129 | P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786 ); 130 | P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6 ); 131 | P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC ); 132 | P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F ); 133 | P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA ); 134 | P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC ); 135 | P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA ); 136 | P( A, B, C, D, E, F, G, H, R(24), 0x983E5152 ); 137 | P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D ); 138 | P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8 ); 139 | P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7 ); 140 | P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3 ); 141 | P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147 ); 142 | P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351 ); 143 | P( B, C, D, E, F, G, H, A, R(31), 0x14292967 ); 144 | P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85 ); 145 | P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138 ); 146 | P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC ); 147 | P( F, G, H, A, B, C, D, E, R(35), 0x53380D13 ); 148 | P( E, F, G, H, A, B, C, D, R(36), 0x650A7354 ); 149 | P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB ); 150 | P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E ); 151 | P( B, C, D, E, F, G, H, A, R(39), 0x92722C85 ); 152 | P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1 ); 153 | P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B ); 154 | P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70 ); 155 | P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3 ); 156 | P( E, F, G, H, A, B, C, D, R(44), 0xD192E819 ); 157 | P( D, E, F, G, H, A, B, C, R(45), 0xD6990624 ); 158 | P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585 ); 159 | P( B, C, D, E, F, G, H, A, R(47), 0x106AA070 ); 160 | P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116 ); 161 | P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08 ); 162 | P( G, H, A, B, C, D, E, F, R(50), 0x2748774C ); 163 | P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5 ); 164 | P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3 ); 165 | P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A ); 166 | P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F ); 167 | P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3 ); 168 | P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE ); 169 | P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F ); 170 | P( G, H, A, B, C, D, E, F, R(58), 0x84C87814 ); 171 | P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208 ); 172 | P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA ); 173 | P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB ); 174 | P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7 ); 175 | P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2 ); 176 | 177 | ctx->state[0] += A; 178 | ctx->state[1] += B; 179 | ctx->state[2] += C; 180 | ctx->state[3] += D; 181 | ctx->state[4] += E; 182 | ctx->state[5] += F; 183 | ctx->state[6] += G; 184 | ctx->state[7] += H; 185 | } 186 | 187 | void sha256_update( sha256_context *ctx, uint8 *input, uint32 length ) 188 | { 189 | uint32 left, fill; 190 | 191 | if( ! length ) return; 192 | 193 | left = ctx->total[0] & 0x3F; 194 | fill = 64 - left; 195 | 196 | ctx->total[0] += length; 197 | ctx->total[0] &= 0xFFFFFFFF; 198 | 199 | if( ctx->total[0] < length ) 200 | ctx->total[1]++; 201 | 202 | if( left && length >= fill ) 203 | { 204 | memcpy( (void *) (ctx->buffer + left), 205 | (void *) input, fill ); 206 | sha256_process( ctx, ctx->buffer ); 207 | length -= fill; 208 | input += fill; 209 | left = 0; 210 | } 211 | 212 | while( length >= 64 ) 213 | { 214 | sha256_process( ctx, input ); 215 | length -= 64; 216 | input += 64; 217 | } 218 | 219 | if( length ) 220 | { 221 | memcpy( (void *) (ctx->buffer + left), 222 | (void *) input, length ); 223 | } 224 | } 225 | 226 | static uint8 sha256_padding[64] = 227 | { 228 | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 229 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 231 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 232 | }; 233 | 234 | void sha256_finish( sha256_context *ctx, uint8 digest[32] ) 235 | { 236 | uint32 last, padn; 237 | uint32 high, low; 238 | uint8 msglen[8]; 239 | 240 | high = ( ctx->total[0] >> 29 ) 241 | | ( ctx->total[1] << 3 ); 242 | low = ( ctx->total[0] << 3 ); 243 | 244 | PUT_UINT32( high, msglen, 0 ); 245 | PUT_UINT32( low, msglen, 4 ); 246 | 247 | last = ctx->total[0] & 0x3F; 248 | padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); 249 | 250 | sha256_update( ctx, sha256_padding, padn ); 251 | sha256_update( ctx, msglen, 8 ); 252 | 253 | PUT_UINT32( ctx->state[0], digest, 0 ); 254 | PUT_UINT32( ctx->state[1], digest, 4 ); 255 | PUT_UINT32( ctx->state[2], digest, 8 ); 256 | PUT_UINT32( ctx->state[3], digest, 12 ); 257 | PUT_UINT32( ctx->state[4], digest, 16 ); 258 | PUT_UINT32( ctx->state[5], digest, 20 ); 259 | PUT_UINT32( ctx->state[6], digest, 24 ); 260 | PUT_UINT32( ctx->state[7], digest, 28 ); 261 | } 262 | 263 | #ifdef TEST 264 | 265 | #include 266 | #include 267 | 268 | /* 269 | * those are the standard FIPS-180-2 test vectors 270 | */ 271 | 272 | static char *msg[] = 273 | { 274 | "abc", 275 | "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 276 | NULL 277 | }; 278 | 279 | static char *val[] = 280 | { 281 | "ba7816bf8f01cfea414140de5dae2223" \ 282 | "b00361a396177a9cb410ff61f20015ad", 283 | "248d6a61d20638b8e5c026930c3e6039" \ 284 | "a33ce45964ff2167f6ecedd419db06c1", 285 | "cdc76e5c9914fb9281a1c7e284d73e67" \ 286 | "f1809a48a497200e046d39ccc7112cd0" 287 | }; 288 | 289 | int main( int argc, char *argv[] ) 290 | { 291 | FILE *f; 292 | int i, j; 293 | char output[65]; 294 | sha256_context ctx; 295 | unsigned char buf[1000]; 296 | unsigned char sha256sum[32]; 297 | 298 | if( argc < 2 ) 299 | { 300 | printf( "\n SHA-256 Validation Tests:\n\n" ); 301 | 302 | for( i = 0; i < 3; i++ ) 303 | { 304 | printf( " Test %d ", i + 1 ); 305 | 306 | sha256_starts( &ctx ); 307 | 308 | if( i < 2 ) 309 | { 310 | sha256_update( &ctx, (uint8 *) msg[i], 311 | strlen( msg[i] ) ); 312 | } 313 | else 314 | { 315 | memset( buf, 'a', 1000 ); 316 | 317 | for( j = 0; j < 1000; j++ ) 318 | { 319 | sha256_update( &ctx, (uint8 *) buf, 1000 ); 320 | } 321 | } 322 | 323 | sha256_finish( &ctx, sha256sum ); 324 | 325 | for( j = 0; j < 32; j++ ) 326 | { 327 | sprintf( output + j * 2, "%02x", sha256sum[j] ); 328 | } 329 | 330 | if( memcmp( output, val[i], 64 ) ) 331 | { 332 | printf( "failed!\n" ); 333 | return( 1 ); 334 | } 335 | 336 | printf( "passed.\n" ); 337 | } 338 | 339 | printf( "\n" ); 340 | } 341 | else 342 | { 343 | if( ! ( f = fopen( argv[1], "rb" ) ) ) 344 | { 345 | perror( "fopen" ); 346 | return( 1 ); 347 | } 348 | 349 | sha256_starts( &ctx ); 350 | 351 | while( ( i = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) 352 | { 353 | sha256_update( &ctx, buf, i ); 354 | } 355 | 356 | sha256_finish( &ctx, sha256sum ); 357 | 358 | for( j = 0; j < 32; j++ ) 359 | { 360 | printf( "%02x", sha256sum[j] ); 361 | } 362 | 363 | printf( " %s\n", argv[1] ); 364 | } 365 | 366 | return( 0 ); 367 | } 368 | 369 | #endif 370 | -------------------------------------------------------------------------------- /sha256.h: -------------------------------------------------------------------------------- 1 | #ifndef _SHA256_H 2 | #define _SHA256_H 3 | 4 | #ifndef uint8 5 | #define uint8 unsigned char 6 | #endif 7 | 8 | #ifndef uint32 9 | #define uint32 unsigned long int 10 | #endif 11 | 12 | typedef struct 13 | { 14 | uint32 total[2]; 15 | uint32 state[8]; 16 | uint8 buffer[64]; 17 | } 18 | sha256_context; 19 | 20 | void sha256_starts( sha256_context *ctx ); 21 | void sha256_update( sha256_context *ctx, uint8 *input, uint32 length ); 22 | void sha256_finish( sha256_context *ctx, uint8 digest[32] ); 23 | 24 | #endif /* sha256.h */ 25 | --------------------------------------------------------------------------------