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