├── .gitignore ├── Makefile ├── README.md ├── aes.c ├── interrogate.c ├── interrogate.h ├── license.txt ├── rsa.c ├── serpent.c ├── stat.c ├── twofish.c ├── util.c └── virtmem.c /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | 4 | # Libraries 5 | *.lib 6 | *.a 7 | 8 | # Shared objects (inc. Windows DLLs) 9 | *.dll 10 | *.so 11 | *.so.* 12 | *.dylib 13 | 14 | # Executables 15 | *.exe 16 | *.out 17 | *.app 18 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # =========================================================================== 2 | # Makefile 3 | # 4 | # Makefile for Interrogate 5 | # 6 | # Author: Carsten Maartmann-Moe 7 | # =========================================================================== 8 | 9 | .SUFFIXES: 10 | .SUFFIXES: .c .o .do 11 | CC=gcc 12 | CFLAGS=-Wall 13 | LDFLAGS= 14 | DEBUGFLAGS=-Wall -DDEBUG -g 15 | LIBS=-lm 16 | OBJS=interrogate.o stat.o rsa.o aes.o serpent.o twofish.o util.o virtmem.o 17 | DBOBJS=interrogate.do stat.do rsa.do aes.do serpent.do twofish.do util.do virtmem.do 18 | EXECNAME=interrogate 19 | 20 | .c.do:; $(CC) -c -o $@ $(DEBUGFLAGS) $< 21 | 22 | all: interrogate 23 | 24 | interrogate: $(OBJS) 25 | $(CC) $(CFLAGS) -o $(EXECNAME) $(OBJS) $(LIBS) 26 | rm -f *.o *.do *.bak *.der 27 | 28 | debug: $(DBOBJS) 29 | $(CC) $(DEBUGFLAGS) -o $(EXECNAME) $(DBOBJS) $(LIBS) 30 | rm -f *.o *.do *.bak *.der 31 | 32 | clean: 33 | rm -f *.o *.do *.bak *.der interrogate 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Interrogate 2 | =========== 3 | 4 | Interrogate is a proof-of-concept tool for identification of cryptographic keys 5 | in binary material (regardless of target operating system), first and foremost 6 | for memory dump analysis and forensic usage. Able to identify AES, Serpent, 7 | Twofish and DER-encoded RSA keys as of version 0.0.4. 8 | 9 | The tool was written as a part of my Master’s Thesis at NTNU. 10 | 11 | 12 | Key data 13 | -------- 14 | 15 | * Version: 0.0.4 16 | * License: GPL 17 | * Author: Carsten Maartmann-Moe (carsten@carmaa.com) 18 | * Twitter: @MaartmannMoe 19 | * Source: https://github.com/carmaa/interrogate 20 | 21 | 22 | Requirements 23 | ------------ 24 | 25 | Interrogate requires: 26 | 27 | * Linux or Mac OS X 28 | 29 | 30 | Installation 31 | ------------ 32 | 33 | Interrogate has no dependencies, installation consists of downloading and 34 | compiling: 35 | 36 | ### Download and install 37 | 38 | git clone https://github.com/carmaa/interrogate.git 39 | cd interrogate 40 | make 41 | 42 | 43 | Usage 44 | ----- 45 | 46 | 1. Dump memory from the target machine 47 | 2. Run Interrogate against the memory dump 48 | 49 | For a more complete and up-to-date description, please run: 50 | 51 | ./interrogate -h 52 | 53 | 54 | Known bugs / caveats 55 | -------------------- 56 | 57 | This is a Proof of Concept tool only. Don't expect too much. 58 | 59 | 60 | Troubleshooting 61 | --------------- 62 | 63 | Please see my master's thesis: https://ntnuopen.ntnu.no/ntnu-xmlui/handle/11250/261742 64 | 65 | And the related paper: https://dfrws.org/sites/default/files/session-files/paper-the_persistence_of_memory_-_forensic_identification_and_extraction_of_cryptographic_keys.pdf 66 | 67 | 68 | Planned features 69 | ---------------- 70 | 71 | * None 72 | 73 | 74 | Development history 75 | ------------------- 76 | 77 | * 0.0.1 - First version 78 | * 0.0.2 - Added TwoFish and Serpent key search functionality 79 | * 0.0.3 - The version that was released with my Master's thesis 80 | * 0.0.4 - Small bug fixes in conjunction with DFRWS 2009 81 | 82 | 83 | Disclaimer 84 | ---------- 85 | Do no evil with this tool. Also, I am a pentester, not a developer. So if you 86 | see weird code that bugs your purity senses, drop me a note on howI can improve 87 | it. Or even better, fork my code, change it and issue a pull request. 88 | -------------------------------------------------------------------------------- /aes.c: -------------------------------------------------------------------------------- 1 | /* ========================================================================== 2 | * aes.c 3 | * 4 | * AES key schedule implementation for Interrogate 5 | * 6 | * Code by Sam Trenholme (http://www.samiam.org/rijndael.html) 7 | * 8 | * Errors corrected and code modified for use in Interrogate by 9 | * Carsten Maartmann-Moe 10 | * ========================================================================== 11 | */ 12 | 13 | #include 14 | 15 | #include "interrogate.h" 16 | 17 | /* Log table using 0xe5 (229) as the generator */ 18 | unsigned char ltable[256] = { 19 | 0x00, 0xff, 0xc8, 0x08, 0x91, 0x10, 0xd0, 0x36, 20 | 0x5a, 0x3e, 0xd8, 0x43, 0x99, 0x77, 0xfe, 0x18, 21 | 0x23, 0x20, 0x07, 0x70, 0xa1, 0x6c, 0x0c, 0x7f, 22 | 0x62, 0x8b, 0x40, 0x46, 0xc7, 0x4b, 0xe0, 0x0e, 23 | 0xeb, 0x16, 0xe8, 0xad, 0xcf, 0xcd, 0x39, 0x53, 24 | 0x6a, 0x27, 0x35, 0x93, 0xd4, 0x4e, 0x48, 0xc3, 25 | 0x2b, 0x79, 0x54, 0x28, 0x09, 0x78, 0x0f, 0x21, 26 | 0x90, 0x87, 0x14, 0x2a, 0xa9, 0x9c, 0xd6, 0x74, 27 | 0xb4, 0x7c, 0xde, 0xed, 0xb1, 0x86, 0x76, 0xa4, 28 | 0x98, 0xe2, 0x96, 0x8f, 0x02, 0x32, 0x1c, 0xc1, 29 | 0x33, 0xee, 0xef, 0x81, 0xfd, 0x30, 0x5c, 0x13, 30 | 0x9d, 0x29, 0x17, 0xc4, 0x11, 0x44, 0x8c, 0x80, 31 | 0xf3, 0x73, 0x42, 0x1e, 0x1d, 0xb5, 0xf0, 0x12, 32 | 0xd1, 0x5b, 0x41, 0xa2, 0xd7, 0x2c, 0xe9, 0xd5, 33 | 0x59, 0xcb, 0x50, 0xa8, 0xdc, 0xfc, 0xf2, 0x56, 34 | 0x72, 0xa6, 0x65, 0x2f, 0x9f, 0x9b, 0x3d, 0xba, 35 | 0x7d, 0xc2, 0x45, 0x82, 0xa7, 0x57, 0xb6, 0xa3, 36 | 0x7a, 0x75, 0x4f, 0xae, 0x3f, 0x37, 0x6d, 0x47, 37 | 0x61, 0xbe, 0xab, 0xd3, 0x5f, 0xb0, 0x58, 0xaf, 38 | 0xca, 0x5e, 0xfa, 0x85, 0xe4, 0x4d, 0x8a, 0x05, 39 | 0xfb, 0x60, 0xb7, 0x7b, 0xb8, 0x26, 0x4a, 0x67, 40 | 0xc6, 0x1a, 0xf8, 0x69, 0x25, 0xb3, 0xdb, 0xbd, 41 | 0x66, 0xdd, 0xf1, 0xd2, 0xdf, 0x03, 0x8d, 0x34, 42 | 0xd9, 0x92, 0x0d, 0x63, 0x55, 0xaa, 0x49, 0xec, 43 | 0xbc, 0x95, 0x3c, 0x84, 0x0b, 0xf5, 0xe6, 0xe7, 44 | 0xe5, 0xac, 0x7e, 0x6e, 0xb9, 0xf9, 0xda, 0x8e, 45 | 0x9a, 0xc9, 0x24, 0xe1, 0x0a, 0x15, 0x6b, 0x3a, 46 | 0xa0, 0x51, 0xf4, 0xea, 0xb2, 0x97, 0x9e, 0x5d, 47 | 0x22, 0x88, 0x94, 0xce, 0x19, 0x01, 0x71, 0x4c, 48 | 0xa5, 0xe3, 0xc5, 0x31, 0xbb, 0xcc, 0x1f, 0x2d, 49 | 0x3b, 0x52, 0x6f, 0xf6, 0x2e, 0x89, 0xf7, 0xc0, 50 | 0x68, 0x1b, 0x64, 0x04, 0x06, 0xbf, 0x83, 0x38 }; 51 | 52 | /* Anti-log table: */ 53 | unsigned char atable[256] = { 54 | 0x01, 0xe5, 0x4c, 0xb5, 0xfb, 0x9f, 0xfc, 0x12, 55 | 0x03, 0x34, 0xd4, 0xc4, 0x16, 0xba, 0x1f, 0x36, 56 | 0x05, 0x5c, 0x67, 0x57, 0x3a, 0xd5, 0x21, 0x5a, 57 | 0x0f, 0xe4, 0xa9, 0xf9, 0x4e, 0x64, 0x63, 0xee, 58 | 0x11, 0x37, 0xe0, 0x10, 0xd2, 0xac, 0xa5, 0x29, 59 | 0x33, 0x59, 0x3b, 0x30, 0x6d, 0xef, 0xf4, 0x7b, 60 | 0x55, 0xeb, 0x4d, 0x50, 0xb7, 0x2a, 0x07, 0x8d, 61 | 0xff, 0x26, 0xd7, 0xf0, 0xc2, 0x7e, 0x09, 0x8c, 62 | 0x1a, 0x6a, 0x62, 0x0b, 0x5d, 0x82, 0x1b, 0x8f, 63 | 0x2e, 0xbe, 0xa6, 0x1d, 0xe7, 0x9d, 0x2d, 0x8a, 64 | 0x72, 0xd9, 0xf1, 0x27, 0x32, 0xbc, 0x77, 0x85, 65 | 0x96, 0x70, 0x08, 0x69, 0x56, 0xdf, 0x99, 0x94, 66 | 0xa1, 0x90, 0x18, 0xbb, 0xfa, 0x7a, 0xb0, 0xa7, 67 | 0xf8, 0xab, 0x28, 0xd6, 0x15, 0x8e, 0xcb, 0xf2, 68 | 0x13, 0xe6, 0x78, 0x61, 0x3f, 0x89, 0x46, 0x0d, 69 | 0x35, 0x31, 0x88, 0xa3, 0x41, 0x80, 0xca, 0x17, 70 | 0x5f, 0x53, 0x83, 0xfe, 0xc3, 0x9b, 0x45, 0x39, 71 | 0xe1, 0xf5, 0x9e, 0x19, 0x5e, 0xb6, 0xcf, 0x4b, 72 | 0x38, 0x04, 0xb9, 0x2b, 0xe2, 0xc1, 0x4a, 0xdd, 73 | 0x48, 0x0c, 0xd0, 0x7d, 0x3d, 0x58, 0xde, 0x7c, 74 | 0xd8, 0x14, 0x6b, 0x87, 0x47, 0xe8, 0x79, 0x84, 75 | 0x73, 0x3c, 0xbd, 0x92, 0xc9, 0x23, 0x8b, 0x97, 76 | 0x95, 0x44, 0xdc, 0xad, 0x40, 0x65, 0x86, 0xa2, 77 | 0xa4, 0xcc, 0x7f, 0xec, 0xc0, 0xaf, 0x91, 0xfd, 78 | 0xf7, 0x4f, 0x81, 0x2f, 0x5b, 0xea, 0xa8, 0x1c, 79 | 0x02, 0xd1, 0x98, 0x71, 0xed, 0x25, 0xe3, 0x24, 80 | 0x06, 0x68, 0xb3, 0x93, 0x2c, 0x6f, 0x3e, 0x6c, 81 | 0x0a, 0xb8, 0xce, 0xae, 0x74, 0xb1, 0x42, 0xb4, 82 | 0x1e, 0xd3, 0x49, 0xe9, 0x9c, 0xc8, 0xc6, 0xc7, 83 | 0x22, 0x6e, 0xdb, 0x20, 0xbf, 0x43, 0x51, 0x52, 84 | 0x66, 0xb2, 0x76, 0x60, 0xda, 0xc5, 0xf3, 0xf6, 85 | 0xaa, 0xcd, 0x9a, 0xa0, 0x75, 0x54, 0x0e, 0x01 }; 86 | 87 | /* Circular rotate */ 88 | void rotate(unsigned char *in) { 89 | unsigned char a,c; 90 | a = in[0]; 91 | for(c=0;c<3;c++) 92 | in[c] = in[c + 1]; 93 | in[3] = a; 94 | return; 95 | } 96 | 97 | /* Calculate the rcon used in key expansion */ 98 | unsigned char rcon(unsigned char in) { 99 | unsigned char c=1; 100 | if(in == 0) 101 | return 0; 102 | while(in != 1) { 103 | c = gmul(c,2); 104 | in--; 105 | } 106 | return c; 107 | } 108 | 109 | /* Galois field multiplication */ 110 | unsigned char gmul(unsigned char a, unsigned char b) { 111 | int s; 112 | int q; 113 | int z = 0; 114 | s = ltable[a] + ltable[b]; 115 | s %= 255; 116 | /* Get the antilog */ 117 | s = atable[s]; 118 | /* Now, we have some fancy code that returns 0 if either 119 | a or b are zero; we write the code this way so that the 120 | code will (hopefully) run at a constant speed in order to 121 | minimize the risk of timing attacks */ 122 | q = s; 123 | if(a == 0) { 124 | s = z; 125 | } else { 126 | s = q; 127 | } 128 | if(b == 0) { 129 | s = z; 130 | } else { 131 | q = z; 132 | } 133 | return s; 134 | } 135 | 136 | /* Inverse Galois field multiplication */ 137 | unsigned char gmul_inverse(unsigned char in) { 138 | /* 0 is self inverting */ 139 | if(in == 0) 140 | return 0; 141 | else 142 | return atable[(255 - ltable[in])]; 143 | } 144 | 145 | /* Calculate the s-box for a given number */ 146 | unsigned char sbox(unsigned char in) { 147 | unsigned char c, s, x; 148 | s = x = gmul_inverse(in); 149 | for(c = 0; c < 4; c++) { 150 | /* One bit circular rotate to the left */ 151 | s = (s << 1) | (s >> 7); 152 | /* xor with x */ 153 | x ^= s; 154 | } 155 | x ^= 99; /* 0x63 */ 156 | return x; 157 | } 158 | 159 | /* This is the core key expansion, which, given a 4-byte value, 160 | * does some scrambling */ 161 | void schedule_core(unsigned char *in, unsigned char i) { 162 | unsigned char a; 163 | /* Rotate the input 8 bits to the left */ 164 | rotate(in); 165 | /* Apply Rijndael's s-box on all 4 bytes */ 166 | for(a = 0; a < 4; a++) 167 | in[a] = sbox(in[a]); 168 | /* On just the first byte, add 2^i to the byte */ 169 | in[0] ^= rcon(i); 170 | } 171 | 172 | /* Key expansion function for 128-bit keys */ 173 | void expand_key(unsigned char *in) { 174 | unsigned char t[4]; 175 | /* c is 16 because the first sub-key is the user-supplied key */ 176 | unsigned char c = 16; 177 | unsigned char i = 1; 178 | unsigned char a; 179 | 180 | /* We need 11 sets of sixteen bytes each for 128-bit mode */ 181 | while(c < 176) { 182 | /* Copy the temporary variable over from the last 4-byte 183 | * block */ 184 | for(a = 0; a < 4; a++) 185 | t[a] = in[a + c - 4]; 186 | /* Every four blocks (of four bytes), 187 | * do a complex calculation */ 188 | if(c % 16 == 0) { 189 | schedule_core(t,i); 190 | i++; 191 | } 192 | for(a = 0; a < 4; a++) { 193 | in[c] = in[c - 16] ^ t[a]; 194 | c++; 195 | } 196 | } 197 | } 198 | 199 | /* Key expansion function for 192-bit keys */ 200 | void expand_key_192(unsigned char *in) { 201 | unsigned char t[4]; 202 | unsigned char c = 24; 203 | unsigned char i = 1; 204 | unsigned char a; 205 | while(c < 208) { 206 | /* Copy the temporary variable over */ 207 | for(a = 0; a < 4; a++) 208 | t[a] = in[a + c - 4]; 209 | /* Every six sets, do a complex calculation */ 210 | if(c % 24 == 0) { 211 | schedule_core(t,i); 212 | i++; 213 | } 214 | for(a = 0; a < 4; a++) { 215 | in[c] = in[c - 24] ^ t[a]; 216 | c++; 217 | } 218 | } 219 | } 220 | 221 | /* Key expansion function for 256-bit keys */ 222 | void expand_key_256(unsigned char *in) { 223 | unsigned char t[4]; 224 | unsigned char c = 32; 225 | unsigned char i = 1; 226 | unsigned char a; 227 | while(c < 240) { 228 | /* Copy the temporary variable over */ 229 | for(a = 0; a < 4; a++) 230 | t[a] = in[a + c - 4]; 231 | /* Every eight sets, do a complex calculation */ 232 | if(c % 32 == 0) { 233 | schedule_core(t,i); 234 | i++; 235 | } 236 | /* For 256-bit keys, we add an extra sbox to the 237 | * calculation */ 238 | if(c % 32 == 16) { 239 | for(a = 0; a < 4; a++) 240 | t[a] = sbox(t[a]); 241 | } 242 | for(a = 0; a < 4; a++) { 243 | in[c] = in[c - 32] ^ t[a]; 244 | c++; 245 | } 246 | } 247 | } 248 | 249 | -------------------------------------------------------------------------------- /interrogate.c: -------------------------------------------------------------------------------- 1 | /* ========================================================================== 2 | * interrogate.c 3 | * 4 | * Structural and entropy-based search for crypto keys in binary files or 5 | * memory dumps. 6 | * 7 | * http://interrogate.sourceforge.net 8 | * 9 | * Copyright (C) 2008 Carsten Maartmann-Moe 10 | * 11 | * This program is free software: you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation, either version 3 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License 22 | * along with this program. If not, see . 23 | * ========================================================================== 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #ifdef _WIN32 34 | #include 35 | #include 36 | #else 37 | #include 38 | #endif 39 | 40 | #include "interrogate.h" 41 | 42 | /* 43 | * Main search method. 44 | * 45 | * Reads entire file (memory dump) into memory and searches file for 46 | * cryptographic keys. Dispatches appropriate searching method based on user 47 | * input (e.g., the switches set at the command line. Also prints some 48 | * headers for entropy searches. 49 | */ 50 | void keysearch(interrogate_context *ctx, unsigned char *buffer) { 51 | 52 | printf("Success, starting search.\n\n"); 53 | 54 | if ((ctx->keytype == NO_KEYTYPE)) { 55 | printf(" Interval | Size | Windows | %s\n", 56 | (ctx->naivemode) ? "Entropy" : "Byte Count"); 57 | } 58 | printf("----------------------------------------" 59 | "----------------------------------------\n"); 60 | 61 | /* Set filelen to be the interval ending point if interval mode is 62 | * set */ 63 | if (ctx->interval) 64 | ctx->filelen = ctx->to; 65 | 66 | /* Search */ 67 | switch (ctx->keytype) { 68 | case RSA: 69 | rsa_search(ctx, buffer); 70 | break; 71 | case AES: 72 | aes_search(ctx, buffer); 73 | break; 74 | case SERPENT: 75 | serpent_search(ctx, buffer); 76 | break; 77 | case TWOFISH: 78 | twofish_search(ctx, buffer); 79 | break; 80 | case TWOFISH_TC: 81 | twofish_search_old(ctx, buffer); 82 | break; 83 | case RSAWIN: 84 | rsa_win_search(ctx, buffer); 85 | break; 86 | default: 87 | if (ctx->quickmode) { 88 | quicksearch(ctx, buffer); 89 | } else { 90 | search(ctx, buffer); 91 | } 92 | break; 93 | } 94 | 95 | free(buffer); 96 | } 97 | 98 | /* ============================================================= 99 | * Search functions for RSA, AES, SERPENT and TWOFISH key types. 100 | * ============================================================= 101 | */ 102 | 103 | void rsa_search(interrogate_context *ctx, unsigned char *buffer) { 104 | int i; 105 | 106 | /* Calculate der-encoding parameters like lenght of data blob etc. 107 | * according to PKCS #8 */ 108 | int FLAG1 = 0x30; 109 | int FLAG2 = 0x82; 110 | 111 | /* Set interval parameter */ 112 | 113 | if (ctx->interval) 114 | ctx->filelen = ctx->to; 115 | 116 | for (i = ctx->from; i < ctx->filelen - 1; i += 2) { 117 | unsigned char c1, c2, c3; 118 | int foundAt = -1; 119 | c1 = (unsigned char) buffer[i]; 120 | c2 = (unsigned char) buffer[i + 1]; 121 | if (c1 == FLAG1) { 122 | if (c2 == FLAG2) { 123 | foundAt = i; 124 | } 125 | } else if (c2 == FLAG1) { 126 | c3 = (unsigned char) buffer[i + 2]; 127 | if (c3 == FLAG2) { 128 | foundAt = i + 1; 129 | } 130 | } 131 | if (foundAt != -1) { 132 | if (ctx->verbose) 133 | printf("Signature hit..."); 134 | int derLength; 135 | if ((derLength = parse_der(buffer, foundAt))) { 136 | ctx->count++; 137 | output_der(buffer, foundAt, derLength, &(ctx->count)); 138 | //Skip the bytes containing the key 139 | i += derLength; 140 | } else { 141 | if (ctx->verbose) 142 | printf("not a key.\n"); 143 | } 144 | } 145 | } 146 | } 147 | 148 | void rsa_win_search(interrogate_context *ctx, unsigned char *buffer) { 149 | int i; 150 | int R = 0x52; 151 | int S = 0x53; 152 | int A = 0x41; 153 | int TWO = 0x32; 154 | 155 | if (ctx->interval) 156 | ctx->filelen = ctx->to; 157 | 158 | for (i = ctx->from; i < ctx->filelen - 1; i++) { 159 | if (buffer[i] == R && buffer[i+1] == S && buffer[i+2] == A && buffer[i+3] == TWO) 160 | printf("Signature hit at %.8x\n", i); 161 | } 162 | } 163 | 164 | void aes_search(interrogate_context *ctx, unsigned char *buffer) { 165 | int i; 166 | 167 | /* Set key schedule sizes */ 168 | int kssize = 176; 169 | if (ctx->keysize == 192) { 170 | kssize = 208; 171 | } else if (ctx->keysize == 256) { 172 | kssize = 240; 173 | } 174 | 175 | unsigned char *ks = malloc(kssize * sizeof(unsigned char)); 176 | 177 | for (i = ctx->from; i < ctx->filelen - kssize; i++) { 178 | /* Copy a chunk of data from buffer, expand it using AES key 179 | * schedule routines */ 180 | ks = memcpy(ks, &buffer[i], kssize); 181 | if ((ctx->keysize == 128)) 182 | expand_key(ks); 183 | else if ((ctx->keysize == 192)) 184 | expand_key_192(ks); 185 | else 186 | expand_key_256(ks); 187 | /* Compare expanded key schedule to the data proceeding the chunk */ 188 | if (memcmp(ks, &buffer[i], kssize) == 0) { 189 | ctx->count++; 190 | printf("Found (probable) AES key at offset %.8x:\n", i); 191 | print_hex_array(ks, ctx->keysize / 8, 16); 192 | printf("Expanded key:\n"); 193 | print_hex_array(ks, kssize, 16); 194 | } 195 | } 196 | 197 | } 198 | 199 | void serpent_search(interrogate_context *ctx, unsigned char *buffer) { 200 | int i; 201 | /* Key schedule size for SERPENT is always 560 bytes*/ 202 | int kssize = 560; 203 | 204 | unsigned char *ks = calloc(kssize, sizeof(unsigned char)); 205 | 206 | /* Iterate byte by byte through memory */ 207 | for (i = ctx->from; i < ctx->filelen - kssize; i++) { 208 | /* Copy chunk of data from buffer, and expand with SERPENT key 209 | * schedule expansion */ 210 | ks = memcpy(ks, &buffer[i], kssize); 211 | serpent_set_key(ks, ctx->keysize, ks); 212 | /* Compare result to the original buffer data */ 213 | if (memcmp(ks, &buffer[i], kssize) == 0) { 214 | ctx->count++; 215 | printf("Found (probable) SERPENT key at offset %.8x:\n", i); 216 | print_hex_array(ks, ctx->keysize / 8, ctx->keysize / 8); 217 | printf("Expanded key:\n"); 218 | print_hex_array(ks, kssize, 16); 219 | } 220 | } 221 | } 222 | 223 | void twofish_search(interrogate_context *ctx, unsigned char *buffer) { 224 | int i, firstrun, lastrun; 225 | /* Override user selected window size */ 226 | ctx->wsize = 4096; 227 | 228 | /* Check that the input file can actually hold a full key schedule */ 229 | size_t tfi_size = sizeof(twofish_tc); // Largest key schedule 230 | if (ctx->filelen < tfi_size) { 231 | fprintf(stderr, "Filesize too small to hold a TwoFish key.\n"); 232 | return; 233 | } 234 | 235 | int run[TF_RUNS]; 236 | firstrun = lastrun = 0; 237 | /* Check first window and initialize */ 238 | i = ctx->from; 239 | runs(ctx, &buffer[i], run, TF_RUNS, &firstrun, &lastrun); 240 | if (is_mk_tab(run)) { 241 | validate_tf_ks(ctx, buffer, i); 242 | } 243 | 244 | /* Check each sequential window */ 245 | for (; i < ctx->filelen; i++) { 246 | runs_opt(ctx, &buffer[i], run, TF_RUNS, &firstrun, &lastrun); 247 | if (is_mk_tab(run)) { 248 | validate_tf_ks(ctx, buffer, i); 249 | } 250 | } 251 | 252 | } 253 | 254 | /* 255 | * Deprecated. Old twofish key search method. Use twofish_search() instead. 256 | * This method will only work for truecrypt-like implementations. 257 | */ 258 | void twofish_search_old(interrogate_context *ctx, unsigned char *buffer) { 259 | twofish_tc *instance = malloc(sizeof(twofish_tc)); 260 | int i; 261 | float entropy; 262 | 263 | /* Check that the input file can actually hold a full key schedule */ 264 | size_t tfi_size = sizeof(twofish_tc); 265 | if (ctx->filelen < tfi_size) { 266 | fprintf(stderr, "Filesize too small to hold a TwoFish key.\n"); 267 | return; 268 | } 269 | 270 | /* For each byte in memory, interpret it as the start of a 271 | * twofish_nstance struct, and check whether it has 2, 3 or 4 as the 272 | * twofish key_len. If so, perform structural and statistical tests to 273 | * verify that it is a valid TWOFISH key schedule */ 274 | for (i = ctx->from; i < ctx->filelen - tfi_size; i++) { 275 | instance = (twofish_tc *)&buffer[i]; 276 | switch (instance->k_len) { 277 | case 2: 278 | /* Potential 128-bit key. 279 | * If key_len is 2, only the two leftmost s_keys are non-zero */ 280 | if ((instance->s_key[2] == 0) && (instance->s_key[3] == 0) 281 | && (instance->l_key[0] != 0)) { 282 | entropy = ent(ctx, (unsigned char *)instance->mk_tab, 283 | sizeof(instance->mk_tab)); 284 | /* The entropy of mk_tab is awlways maximum (8) */ 285 | if (entropy == 8) { 286 | /* Calculate entropy of the l_keys */ 287 | entropy = ent(ctx, (unsigned char *)instance->l_key, 288 | sizeof(instance->l_key)); 289 | if ((entropy > 6) && (entropy < 7.2)) { 290 | ctx->count++; 291 | printf("Found (probable) TwoFish key at " 292 | "offset %.8x:\n", i); 293 | printf("Expanded key:\n"); 294 | print_hex_words((unsigned int *)instance, 295 | tfi_size / 4, 4); 296 | } 297 | } 298 | } 299 | break; 300 | case 3: 301 | /* Potential 198-bit key. 302 | * If key_len is 3, only the leftmost s_key is non-zero */ 303 | if ((instance->s_key[3] == 0) && (instance->l_key[0] != 0)) { 304 | entropy = ent(ctx, (unsigned char *)instance->mk_tab, 305 | sizeof(instance->mk_tab)); 306 | /* The entropy of mk_tab is awlways maximum (8) */ 307 | if (entropy == 8) { 308 | /* Calculate entropy of the l_keys */ 309 | entropy = ent(ctx, (unsigned char *)instance->l_key, 310 | sizeof(instance->l_key)); 311 | if ((entropy > 4)) { 312 | ctx->count++; 313 | printf("Found (probable) TwoFish key at " 314 | "offset %.8x:\n", i); 315 | printf("Expanded key:\n"); 316 | print_hex_words((unsigned int *)instance, 317 | tfi_size / 4, 4); 318 | } 319 | } 320 | } 321 | break; 322 | case 4: 323 | /* Potential 256-bit key */ 324 | entropy = ent(ctx, (unsigned char *)instance->mk_tab, 325 | sizeof(instance->mk_tab)); 326 | if ((entropy == 8)) { 327 | /* Calculate entropy of the l_keys */ 328 | entropy = ent(ctx, (unsigned char *)instance->l_key, 329 | sizeof(instance->l_key)); 330 | if ((entropy > 6) && (entropy < 7.2)) { 331 | /* Calculate entropy of the l_keys */ 332 | entropy = ent(ctx, (unsigned char *)instance->s_key, 333 | sizeof(instance->s_key)); 334 | ctx->count++; 335 | printf("Found (probable) TwoFish key at " 336 | "offset %.8x:\n", i); 337 | printf("Expanded key:\n"); 338 | print_hex_words((unsigned int *)instance, 339 | tfi_size / 4, 4); 340 | } 341 | } 342 | break; 343 | } 344 | } 345 | } 346 | 347 | /* ------------------------------------------ 348 | * Search functions for entropy-based search. 349 | * ------------------------------------------ 350 | */ 351 | 352 | void search(interrogate_context *ctx, unsigned char *buffer) { 353 | int i, found, start, end; 354 | float entropy, cent; 355 | found = FALSE; 356 | entropy = cent = 0.0; 357 | start = ctx->from; 358 | 359 | //TODO: Change from continous sections to only windows of entropy 360 | for (i = ctx->from; i < ctx->filelen - ctx->wsize; i++) { 361 | /* Calculate entropy (if naivemode) or simply count unique bytes */ 362 | entropy = (ctx->naivemode) ? ent(ctx, &buffer[i], ctx->wsize) 363 | : countbytes(ctx, &buffer[i]); 364 | /* Print value to file if the -p switch is set */ 365 | if (ctx->output_fp != NULL) 366 | print_to_file(ctx->output_fp, entropy); 367 | 368 | if (entropy >= ctx->threshold) { 369 | if (!found) { 370 | start = i; 371 | ctx->count++; 372 | found = TRUE; 373 | } 374 | cent += entropy; 375 | } else { 376 | if (found) { 377 | end = i + ctx->wsize - 1; /* Ended at previous round */ 378 | int bytes = end - start; 379 | float numblocks = (float) bytes / ctx->wsize; 380 | printblobinfo(start, end, bytes, numblocks, cent / (bytes 381 | - ctx->wsize + 1)); 382 | cent = 0; 383 | found = FALSE; 384 | } 385 | } 386 | } 387 | 388 | /* If found is true here, we found something in the last round, print 389 | * it */ 390 | if (found) { 391 | end = i + ctx->wsize; 392 | int bytes = end - start; 393 | float numblocks = (float) bytes / ctx->wsize; 394 | printblobinfo(start, end, bytes, numblocks, 395 | cent / (bytes - ctx->wsize)); 396 | } 397 | 398 | } 399 | 400 | void quicksearch(interrogate_context *ctx, unsigned char *buffer) { 401 | /* Move window over file and calculate entropy for each window 402 | * position */ 403 | int i; 404 | float entropy = 0.0; 405 | int eof= FALSE; 406 | int found= FALSE; 407 | float cent = 0; /* Cumulative entropy */ 408 | int start, end; 409 | start = i = ctx->from; 410 | int oldwsize = ctx->wsize; 411 | 412 | while (!eof) { /* Last round, make sure the window fits */ 413 | if ((i >= ctx->filelen - ctx->wsize)) { 414 | eof = TRUE; 415 | ctx->wsize = ctx->filelen - i; 416 | } 417 | /* The end of the current search window */ 418 | end = i + ctx->wsize; 419 | 420 | /* Calculate entropy (if naivemode) or simply count unique bytes */ 421 | entropy = (ctx->naivemode) ? ent(ctx, &buffer[i], ctx->wsize) 422 | : countbytes(ctx, &buffer[i]); 423 | /* Print value to file if the -p switch is set */ 424 | if (ctx->output_fp != NULL) 425 | print_to_file(ctx->output_fp, entropy); 426 | 427 | if (entropy >= ctx->threshold) { 428 | /* If found is false, the last block did not contain high 429 | * entropy. In that case, mark the start of a new block, 430 | * increment block counter and set fount to true */ 431 | if (!found) { 432 | start = i; 433 | ctx->count++; 434 | found = TRUE; 435 | } 436 | 437 | /* Accumulate total entropy */ 438 | cent += entropy; 439 | 440 | if (eof) { // If this is the last round, print it right away 441 | int bytes = end - start; 442 | float numblocks = (float) bytes / oldwsize; 443 | printblobinfo(start, end, bytes, numblocks, 444 | cent / numblocks); 445 | } 446 | } else { 447 | /* If found is true, the last block examined contained high 448 | * entropy, but the current block did not. In that case 449 | * the entropy blob has reached its end after the previous 450 | * block, and we'll print its data. */ 451 | if (found) { 452 | int prevend = end - ctx->wsize; 453 | int bytes = prevend - start; 454 | float numblocks = (float) bytes / oldwsize; 455 | printblobinfo(start, prevend, bytes, numblocks, cent 456 | / numblocks); 457 | cent = 0; 458 | found = FALSE; 459 | } 460 | } 461 | i += ctx->wsize; // Increment counter, move wsize bytes each round 462 | } 463 | ctx->wsize = oldwsize; // Restore window size 464 | } 465 | 466 | /* ----------------------- 467 | * Main program functions. 468 | * ----------------------- 469 | */ 470 | 471 | /* 472 | * Prints usage and help info 473 | */ 474 | void help() { 475 | printf("Usage: interrogate [OPTION]... [FILE]...\n" 476 | "Search for cryptographic keys in the FILEs (memory dumps).\n" 477 | "\n" 478 | " -a algorithm search for keys of a certain type (algorithm).\n" 479 | " Valid parameters: aes, rsa, win-rsa, serpent,\n" 480 | " [tc-]twofish. Use the -k switch to specify AES\n" 481 | " key lengths (128, 198, or 256 bits). RSA keys are\n" 482 | " found independent of their length, while SERPENT\n" 483 | " and TWOFISH keys are required to be 256 bits.\n" 484 | " The rsa parameter specifies DER-encoded rsa keys,\n" 485 | " while win-rsa requires Private Key BLOB (Windows)\n" 486 | " structure.\n" 487 | " -h prints usage and help information (this message).\n" 488 | " -i interval only search within interval. Format of interval is\n" 489 | " from_offset:to_offset where the offset values\n" 490 | " are interpreted as hexadecimal values. Omitting\n" 491 | " one of the offsets will indicate the start or\n" 492 | " the end of the FILEs, respectively. Used with\n" 493 | " the -r switch, the interval will be interpreted\n" 494 | " as the virtual address space that are to be\n" 495 | " reconstructed.\n" 496 | " -k keylength length of key to be searched for (NB: in BITS)\n" 497 | " -n naive mode, calculates true entropy instead of\n" 498 | " counting unique bytes (which is the normal\n" 499 | " mode). This may be useful if you get bad quality\n" 500 | " results, but may yield some performance\n" 501 | " degradation.\n" 502 | " -p filename print entropy values for each window separated\n" 503 | " by newlines to file specified by filename. This\n" 504 | " may be used as input to plotting tools (gnuplot)\n" 505 | " WARNING: Slow and generates large files, one\n" 506 | " input byte maps to potentially six output bytes.\n" 507 | " -q quick mode, does not use overlapping windows. The\n" 508 | " larger the window size, the quicker. Use -w to\n" 509 | " specify window size.\n" 510 | " -r CR3 reconstructs the virtual address space for the\n" 511 | " process at offset PDB. The PDB is the location of\n" 512 | " the page directory base, and can be found by\n" 513 | " scanning for EPROCESSes using PTfinder,\n" 514 | " Volatility or other similar tools. The\n" 515 | " regonstructed memory is written to file\n" 516 | " 'pages', and are searched subsequently for\n" 517 | " keys. The -i option may be used to specify a\n" 518 | " virtual address space interval.\n" 519 | " -t threshold sets the entropy threshold (default = 7.0).\n" 520 | " -w windowsize sets the window size. Not compatible with the -a\n" 521 | " option.\n"); 522 | } 523 | 524 | /* 525 | * Initializes the context of Interrogate. 526 | */ 527 | void initialize(interrogate_context *ctx) { 528 | ctx->keytype = NO_KEYTYPE; /* No keytype by default */ 529 | ctx->keysize = 0; /* Size of key to (in bits) */ 530 | ctx->wsize = WINDOWSIZE; /* Size of search window */ 531 | ctx->nofs = NOFSYMBOLS; /* Size of our alphabet */ 532 | ctx->threshold = THRESHOLD; /* Default entropy threshold */ 533 | ctx->bitmode = FALSE; /* Bit-mode is false by default */ 534 | ctx->naivemode = FALSE; /* Naive mode is false by default */ 535 | ctx->quickmode = FALSE; /* Quickmode turned off by default */ 536 | ctx->interval = FALSE; /* Interval turned off by default */ 537 | ctx->verbose = FALSE; /* Verbose mode is per def false */ 538 | ctx->from = ctx->to = 0; /* Interval is zero by default */ 539 | ctx->cr3 = 0; /* Don't reconstruct (default) */ 540 | ctx->filelen = 0; /* Zero file length */ 541 | ctx->count = 0; /* Set key counter to zero */ 542 | } 543 | 544 | /* 545 | * Main program, parse parameters and set context 546 | */ 547 | int main(int argc, char **argv) { 548 | int c; /* Stores argument options */ 549 | int i; /* Counter */ 550 | FILE *fp; /* Pointer to input file */ 551 | interrogate_context *ctx = 552 | malloc(sizeof(interrogate_context)); /* Program context */ 553 | 554 | printf( 555 | "Interrogate 0.0.4 Copyright (C) 2008 Carsten Maartmann-Moe " 556 | "keytype = AES; 570 | } else if (strncmp(optarg, "rsa-win", 7) == 0) { 571 | ctx->keytype = RSAWIN; 572 | } else if (strncmp(optarg, "rsa", 3) == 0) { 573 | ctx->keytype = RSA; 574 | } else if (strncmp(optarg, "serpent", 7) == 0) { 575 | ctx->keytype = SERPENT; 576 | /* We only have support for 256-bit SERPENT keys */ 577 | ctx->keysize = 256; 578 | } else if (strncmp(optarg, "twofish", 7) == 0) { 579 | ctx->keytype = TWOFISH; 580 | /* We only have support for 256-bit TWOFISH keys */ 581 | ctx->keysize = 256; 582 | } else if (strncmp(optarg, "tc-twofish", 10) == 0) { 583 | ctx->keytype = TWOFISH_TC; 584 | /* We only have support for 256-bit Truecrypt TWOFISH keys */ 585 | ctx->keysize = 256; 586 | } else { 587 | fprintf(stderr, "Invalid keytype.\n"); 588 | help(); 589 | exit(-1); 590 | } 591 | break; 592 | case 'h': 593 | help(); 594 | exit(0); 595 | case 'i': 596 | ctx->interval = TRUE; 597 | /* Do ugly parsing of argument :-/ */ 598 | char *to_ptr = strstr(optarg, ":"); // Find ':' 599 | *to_ptr = '\0'; // Replace with string terminator 600 | to_ptr++; 601 | /* Convert from hexadecimal ASCII */ 602 | ctx->from = (int)strtol(optarg, (char**)NULL, 16); 603 | ctx->to = (int)strtol(to_ptr, (char **)NULL, 16); 604 | if (ctx->to < ctx->from && ctx->to != 0) { 605 | fprintf(stderr, "Error in interval, the start offset " 606 | "is bigger than the end offset.\n"); 607 | exit(-1); 608 | } 609 | break; 610 | case 'k': 611 | ctx->keysize = atoi(optarg); 612 | printf("Using key size: %i bits.\n", ctx->keysize); 613 | break; 614 | case 'n': 615 | ctx->naivemode = TRUE; 616 | printf("Using naive mode, searching for true entropy.\n"); 617 | break; 618 | case 'p': 619 | ctx->output_fp = open_file(ctx, optarg, "w"); 620 | break; 621 | case 'q': 622 | ctx->quickmode = TRUE; 623 | printf("Using quickmode.\n"); 624 | break; 625 | case 'r': 626 | ctx->cr3 = (int)strtol(optarg, (char**)NULL, 16); 627 | break; 628 | case 't': 629 | ctx->threshold = atof(optarg); 630 | printf("Using entropy threshold: %f bits per symbol.\n", 631 | ctx->threshold); 632 | break; 633 | case 'v': 634 | ctx->verbose = TRUE; 635 | printf("Verbose mode.\n"); 636 | break; 637 | case 'w': 638 | ctx->wsize = atoi(optarg); 639 | printf("Using window size: %i bytes.\n", ctx->wsize); 640 | break; 641 | case '?': 642 | if (optopt == 'c' || optopt == 'w') { 643 | fprintf(stderr, "Option -%c requires an " 644 | "argument.\n", optopt); 645 | } else if (isprint(optopt)) { 646 | fprintf(stderr, "Unknown option `-%c'.\n", 647 | optopt); 648 | } else { 649 | fprintf(stderr, "Unknown option character " 650 | "`\\x%x'.\n", optopt); 651 | } 652 | return 1; 653 | default: 654 | exit(-1); 655 | } 656 | } 657 | /* Check that the windowsize is reasonable */ 658 | if (ctx->naivemode && (ctx->wsize < (ctx->nofs / 2))) { 659 | printf("WARNING: You're using a windowsize smaller than half of the " 660 | "number of symbols together with naive mode, this might not " 661 | "yield a good result. Try dropping -n.\n"); 662 | } 663 | /* Check that keytypes match supported key lengths */ 664 | switch (ctx->keytype) { 665 | case AES: 666 | if (!(ctx->keysize == 128 || 667 | ctx->keysize == 192 || 668 | ctx->keysize == 256)) { 669 | fprintf(stderr, "A key size of 128, 192 or 256 bits are " 670 | "required for AES search.\n"); 671 | exit(-1); 672 | } 673 | break; 674 | case SERPENT: 675 | if (!(ctx->keysize == 256)) { 676 | fprintf(stderr, "A key size of 256 bits are required for " 677 | "SERPENT search.\n"); 678 | exit(-1); 679 | } 680 | break; 681 | case TWOFISH: 682 | if (!(ctx->keysize == 256)) { 683 | fprintf(stderr, "A key size of 256 bits are required for " 684 | "TWOFISH search.\n"); 685 | exit(-1); 686 | } 687 | break; 688 | } 689 | 690 | if ((!ctx->naivemode) 691 | && (ctx->keytype == NO_KEYTYPE && ctx->threshold == 7)) { 692 | /* Set relaxed byte count threshold since the user didn't 693 | * specify one*/ 694 | ctx->threshold = floor((ctx->wsize / NOFSYMBOLS) * ctx->threshold 695 | * BCMOD); 696 | printf("WARNING: No -t option specified, bytecount threshold was " 697 | "set to %f. This may yield inaccurate results.\n", 698 | ctx->threshold); 699 | } 700 | 701 | /* The rest of the args are treated as files */ 702 | if (optind < argc) { 703 | for (i = optind; i < argc; i++) { 704 | /* Check and open file for reading */ 705 | fp = open_file(ctx, argv[i], "rb"); 706 | printf("Using input file: %s.\n", argv[i]); 707 | if (ctx->interval) { 708 | /* Check if intervals are out of bounds */ 709 | if (ctx->from < 0) { 710 | ctx->from = 0; 711 | printf("WARNING: Interval out of bounds, changed it " 712 | "for you:\n"); 713 | } 714 | /* If the upper bound is too big, set it to filelenght */ 715 | if (ctx->to > ctx->filelen) { 716 | ctx->to = ctx->filelen; 717 | /* If the lower bound is too low, set it to zero */ 718 | if (ctx->to < ctx->from) 719 | ctx->from = 0; 720 | printf("WARNING: Interval out of bounds, changed it " 721 | "for you:\n"); 722 | } 723 | /* If no upper bound is given, set it to filelength */ 724 | if (ctx->to == 0) { 725 | ctx->to = ctx->filelen; 726 | } 727 | printf("Searching in interval 0x%08X - 0x%08X.\n", 728 | ctx->from, ctx->to); 729 | } 730 | 731 | unsigned char *buffer = 732 | malloc(ctx->filelen * sizeof(unsigned char)); 733 | buffer = read_file(ctx, fp); 734 | 735 | /* Reconstruct memory if the -r switch is on */ 736 | if(ctx->cr3 != 0) { 737 | printf("Reconstructing virtual memory for process with PDB " 738 | "at %08x, please stand by...\n", ctx->cr3); 739 | reconstruct(ctx, buffer); 740 | printf("Using recontructed virtual memory file " 741 | "'pages' for search.\n"); 742 | fp = open_file(ctx, "pages", "rb"); 743 | buffer = 744 | realloc(buffer, ctx->filelen * sizeof(unsigned char)); 745 | buffer = read_file(ctx, fp); 746 | } 747 | 748 | /* Perform search */ 749 | keysearch(ctx, buffer); 750 | 751 | /* Clean up */ 752 | if (ctx->output_fp != NULL) { 753 | fclose(ctx->output_fp); 754 | } 755 | fclose(fp); 756 | } 757 | printf("\nA total of %li %s found.\n", ctx->count, (ctx->keytype 758 | == NO_KEYTYPE) ? "entropy blobs" : "keys"); 759 | printf("Spent %li seconds of your day looking for the key.\n", 760 | clock() / CLOCKS_PER_SEC); 761 | } else { 762 | fprintf(stderr, "Missing input file.\n"); 763 | help(); 764 | } 765 | free(ctx); 766 | return 0; 767 | } 768 | -------------------------------------------------------------------------------- /interrogate.h: -------------------------------------------------------------------------------- 1 | /* ========================================================================== 2 | * interrogate.h 3 | * 4 | * Main header file for Interrogate: Structural and entropy-based search for 5 | * crypto keys in binary files or memory dumps. 6 | * 7 | * http://interrogate.sourceforge.net 8 | * 9 | * Copyright (C) 2008 Carsten Maartmann-Moe 10 | * 11 | * This program is free software: you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation, either version 3 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License 22 | * along with this program. If not, see . 23 | * ========================================================================== 24 | */ 25 | 26 | #define NOFSYMBOLS 256 /* Number of symbols in alphabet (ASCII=256) */ 27 | #define WINDOWSIZE 256 /* Windowsize in BYTES */ 28 | #define KEYSIZE 256 /* Default keysize in BITS */ 29 | #define THRESHOLD 7.0 /* Default entropy threshold */ 30 | #define BCMOD 20 /* Modifier for byte count threshold */ 31 | #define TRUE 1 32 | #define FALSE 0 33 | 34 | #define NO_KEYTYPE -1 /* Keytype definitions below */ 35 | #define AES 0 36 | #define RSA 1 37 | #define SERPENT 2 38 | #define TWOFISH 3 39 | #define TWOFISH_TC 4 40 | #define RSAWIN 5 41 | #define NOF_KEYTYPES 6 42 | 43 | #define LEFT 0 44 | #define RIGHT 1 45 | 46 | #define rotlFixed(x,n) (((x) << (n)) | ((x) >> (32 - (n)))) 47 | #define rotrFixed(x,n) (((x) >> (n)) | ((x) << (32 - (n)))) 48 | 49 | #define NOF_TF_IMP 4; /* Number of Twofish implementations */ 50 | #define TF_SBOX_SIZE 4096; 51 | #define TF_RUNS 6 /* Runs to measure */ 52 | 53 | /* ---------------------------- 54 | * Twofish key structures below 55 | * ---------------------------- 56 | */ 57 | 58 | /* Twofish key structure, taken from TrueCrypt implementation */ 59 | typedef struct { 60 | unsigned int l_key[40]; 61 | unsigned int s_key[4]; 62 | unsigned int mk_tab[4 * 256]; 63 | unsigned int k_len; 64 | } 65 | twofish_tc; 66 | 67 | /* Twofish key sructure from Linux and GPG implementations 68 | * Isomorphic with SSH impelentation below as far as we are concered. */ 69 | typedef struct { 70 | unsigned int s[4][256], w[8], k[32]; 71 | } 72 | twofish_gpg; 73 | 74 | /* SSH twofish key schedule */ 75 | typedef struct { 76 | unsigned int s[4][256]; /* Key-dependant S-Boxes */ 77 | unsigned int k[40]; /* Expanded key words */ 78 | int for_encryption; /* encrypt / decrypt */ 79 | } 80 | twofish_ssh; 81 | 82 | /* Twofish key structure taken from Nettle */ 83 | typedef struct { 84 | unsigned int k[40]; 85 | unsigned int s[4][256]; 86 | } 87 | twofish_nettle; 88 | 89 | /* Twofish optimized implementation */ 90 | typedef struct { 91 | unsigned int K[40]; 92 | unsigned int k_len; 93 | unsigned int QF[4][256]; 94 | } 95 | twofish_opt; 96 | 97 | /* Page Table Entry struct (PTE). Note that Windows uses the 98 | * same structure for Page Directory Entries (PDEs). 99 | */ 100 | typedef struct { 101 | unsigned int valid : 102 | 1; 103 | unsigned int write : 104 | 1; 105 | unsigned int owner : 106 | 1; 107 | unsigned int write_through : 108 | 1; 109 | unsigned int cache_disabled : 110 | 1; 111 | unsigned int accessed : 112 | 1; 113 | unsigned int dirty : 114 | 1; 115 | unsigned int large_page : 116 | 1; 117 | unsigned int global : 118 | 1; 119 | unsigned int copy_on_write : 120 | 1; 121 | unsigned int transition : 122 | 1; 123 | unsigned int prototype : 124 | 1; 125 | unsigned int pfn : 126 | 20; 127 | } 128 | pte; 129 | 130 | /* Virtual address for 32-bit x86 Windows systems */ 131 | typedef struct { 132 | unsigned int byte_offset : 133 | 12; 134 | unsigned int pt_index : 135 | 10; 136 | unsigned int pd_index : 137 | 10; 138 | } 139 | virtual_address; 140 | 141 | /* DWORD and WORD type definitions */ 142 | typedef unsigned long DWORD; 143 | typedef unsigned short WORD; 144 | 145 | /* Interrogate context */ 146 | typedef struct { 147 | int keytype, /* Keytype to be searched for */ 148 | keysize, /* The key size that are to be searched for */ 149 | wsize, /* The search window size */ 150 | nofs, /* The number of symbols in our alphabet */ 151 | bitmode, /* Bitmode boolean */ 152 | verbose, /* Verbose mode */ 153 | naivemode, /* Calculate true entropy */ 154 | quickmode, /* Non-overlapping entropy windows */ 155 | interval, /* Only search in interval (boolean) */ 156 | from, /* Starting point */ 157 | to, /* End point */ 158 | cr3, /* CR3 offset in case recunstruction of mem */ 159 | filelen, /* Input file length in bytes */ 160 | bytethreshold; /* Threshold for bytecount */ 161 | FILE *output_fp; /* Pointer to output file for statistics */ 162 | float threshold; /* Entropy threshold */ 163 | long count; /* Number of keys found */ 164 | } 165 | interrogate_context; 166 | 167 | /* ------------------- 168 | * Function prototypes 169 | * ------------------- 170 | */ 171 | 172 | /* interrogate.c: Main Program */ 173 | void init(float *ek); 174 | void initialize(); 175 | void keysearch(interrogate_context *ctx, unsigned char *buffer); 176 | void search(interrogate_context *ctx, unsigned char *buffer); 177 | void quicksearch(interrogate_context *ctx, unsigned char *buffer); 178 | void rsa_search(interrogate_context *ctx, unsigned char *buffer); 179 | void rsa_win_search(interrogate_context *ctx, unsigned char *buffer); 180 | void aes_search(interrogate_context *ctx, unsigned char *buffer); 181 | void serpent_search(interrogate_context *ctx, unsigned char *buffer); 182 | void twofish_search(interrogate_context *ctx, unsigned char *buffer); 183 | void twofish_search_old(interrogate_context *ctx, unsigned char *buffer); 184 | 185 | /* stat.c: Statistics */ 186 | double approxlog2(double x); 187 | float ent(interrogate_context *ctx, unsigned char *buffer, int length); 188 | float *ent_opt(unsigned char *buffer); 189 | int countbytes(interrogate_context *ctx, unsigned char *buffer); 190 | void runs(interrogate_context *ctx, unsigned char *buffer, int *runs_count, 191 | int run_length, int *firstrun, int *lastrun); 192 | void runs_opt(interrogate_context *ctx, unsigned char *buffer, 193 | int *runs_count, int run_length, int *firstrun, int *lastrun); 194 | 195 | /* rsa.c: RSA functions */ 196 | int parse_der(unsigned char *buffer, int offset); 197 | void output_der(unsigned char *buffer, int offset, size_t size, long *count); 198 | 199 | /* aes.c: AES functions */ 200 | void rotate(unsigned char *in); 201 | unsigned char rcon(unsigned char in); 202 | unsigned char gmul(unsigned char a, unsigned char b); 203 | unsigned char gmul_inverse(unsigned char in); 204 | unsigned char sbox(unsigned char in); 205 | void schedule_core(unsigned char *in, unsigned char i); 206 | void expand_key(unsigned char *in); 207 | void expand_key_192(unsigned char *in); 208 | void expand_key_256(unsigned char *in); 209 | 210 | /* serpent.c: Serpent functions */ 211 | void serpent_set_key(const unsigned char userKey[], int keylen, 212 | unsigned char *ks); 213 | 214 | /* twofish.c TwoFish functions */ 215 | void twofish_set_key(twofish_tc *instance, const unsigned int in_key[], 216 | const unsigned int key_len); 217 | unsigned int mds_rem(unsigned int p0, unsigned int p1); 218 | void gen_mk_tab(twofish_tc *instance, unsigned int key[]); 219 | 220 | /* nppool.c Nonpaged Pool functions */ 221 | void reconstruct(interrogate_context *ctx, unsigned char *buffer); 222 | void print_pte(virtual_address *addr, pte *pd, pte *pde, pte *pt, pte *pte, 223 | unsigned char *page); 224 | 225 | /* util.c: Utility functions */ 226 | unsigned char *read_file(interrogate_context *ctx, FILE *fp); 227 | FILE *open_file(interrogate_context *ctx, char *filename, char *mode); 228 | int checkbyte(unsigned char index, int *array); 229 | void printblobinfo(int start, int end, int bytes, float wins, float entropy); 230 | void print_hex_array(unsigned char *buffer, int length, int columns); 231 | void print_hex_words(unsigned int *buffer, int length, int columns); 232 | int validkeytype(char *keytype, int length); 233 | int min(int a, int b); 234 | void print_to_file(FILE *fp, float value); 235 | unsigned getbits(unsigned x, int p, int n); 236 | unsigned int byteshift(unsigned int x, int direction, int n); 237 | int is_mk_tab(int *run); 238 | void validate_tf_ks(interrogate_context *ctx, unsigned char *buffer, 239 | int offset); 240 | double format(double Value, int nPrecision); 241 | 242 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | -------------------------------------------------------------------------------- /rsa.c: -------------------------------------------------------------------------------- 1 | /* ========================================================================== 2 | * rsa.c 3 | * 4 | * RSA-specific methods for Interrogate. Parses DER-encoded blobs and ouputs 5 | * to file in the format privkey-00x.der 6 | * 7 | * Author: Carsten Maartmann-Moe 8 | * ========================================================================== 9 | */ 10 | 11 | #include 12 | #include 13 | 14 | #include "interrogate.h" 15 | 16 | /* Perform basic structural check on possible DER-encoded private key. 17 | * Returns 0 if invalid, and the length of the DER blob if it is valid. Also 18 | * prints some info about the key. 19 | */ 20 | int parse_der(unsigned char *buffer, int offset) { 21 | if (buffer[offset + 4] == 0x02 && 22 | buffer[offset + 5] == 0x01 && 23 | buffer[offset + 6] == 0x00 && 24 | buffer[offset + 7] == 0x02) { 25 | int length = (buffer[offset+2] << 8) | 26 | (unsigned char) buffer[offset+3]; 27 | int end = 4 + length; 28 | int pub_exp_field_length = 0; 29 | int modlength, asn1length = (unsigned char) buffer[offset + 8]; 30 | if ((asn1length & 0x80) == 0) { 31 | modlength = asn1length; 32 | pub_exp_field_length = 1; 33 | } else { 34 | int numbytes = asn1length & 0x7F; 35 | if (numbytes <= 8) { 36 | int i; 37 | pub_exp_field_length = 1 + numbytes; 38 | modlength = (unsigned char) buffer[offset + 9]; 39 | for (i = 1; i < numbytes; i++) { 40 | modlength = (modlength << 8) | 41 | (unsigned char) buffer[offset + 9 + i]; 42 | } 43 | } else { 44 | printf("Found modulus length > 64 bits, this is not " 45 | "supported."); 46 | return 0; 47 | } 48 | } 49 | int pub_exp_offset = offset + 8 + pub_exp_field_length + modlength; 50 | int pub_exp = 0; 51 | if (buffer[pub_exp_offset] == 0x02) { 52 | if (buffer[pub_exp_offset + 1] == 0x01 && 53 | buffer[pub_exp_offset + 2] == 0x01) { 54 | pub_exp = 1; 55 | } else if (buffer[pub_exp_offset + 1] == 0x03 && 56 | buffer[pub_exp_offset + 2] == 0x01 && 57 | buffer[pub_exp_offset + 3] == 0x00 && 58 | buffer[pub_exp_offset + 4] == 0x01) { 59 | pub_exp = 65537; 60 | } else { 61 | printf("Could not find public exponent, not a valid " 62 | "key.\n"); 63 | return 0; 64 | } 65 | } 66 | if (pub_exp != 0) { 67 | printf("%08x: Key: %i bits, public exponent %i.\n", offset, 68 | (modlength - 1) * 8, pub_exp); 69 | return end; 70 | } else { 71 | return 0; 72 | } 73 | } else { 74 | #if DEGUG 75 | printf("Invalid key found."); 76 | #endif 77 | 78 | return 0; 79 | } 80 | } 81 | /* 82 | * Output DER information at offset 'offs'. 83 | */ 84 | void output_der(unsigned char *buffer, int offs, size_t size, long *count) { 85 | char filename[15]; 86 | sprintf(filename, "privkey-%02li.der", *count); 87 | FILE *fp = fopen(filename, "wb"); 88 | if (fp == NULL) { 89 | perror("fopen()"); 90 | fprintf(stderr, "Failed to open %s.\n", filename); 91 | exit(-1); 92 | } else { 93 | fwrite(&buffer[offs], 1, size, fp); 94 | printf("Wrote key to file %s.\n", filename); 95 | } 96 | 97 | fclose(fp); 98 | } 99 | 100 | -------------------------------------------------------------------------------- /serpent.c: -------------------------------------------------------------------------------- 1 | /* ========================================================================== 2 | * serpent.c 3 | * 4 | * Serpent key schedule implementation for Interrogate 5 | * 6 | * Adapted from serpent.cpp -- written and placed in the public domain by Wei 7 | * Dai. Interrogate version by Carsten Maartmann-Moe 8 | * ========================================================================== 9 | */ 10 | 11 | #include 12 | #include 13 | #include "interrogate.h" 14 | 15 | /* ------- 16 | * S-boxes 17 | * ------- 18 | */ 19 | static void S0f (unsigned int *r0, unsigned int *r1, unsigned int *r2, 20 | unsigned int *r3, unsigned int *r4) { 21 | *r3 ^= *r0; 22 | *r4 = *r1; 23 | *r1 &= *r3; 24 | *r4 ^= *r2; 25 | *r1 ^= *r0; 26 | *r0 |= *r3; 27 | *r0 ^= *r4; 28 | *r4 ^= *r3; 29 | *r3 ^= *r2; 30 | *r2 |= *r1; 31 | *r2 ^= *r4; 32 | *r4 = ~*r4; 33 | *r4 |= *r1; 34 | *r1 ^= *r3; 35 | *r1 ^= *r4; 36 | *r3 |= *r0; 37 | *r1 ^= *r3; 38 | *r4 ^= *r3; 39 | } 40 | 41 | static void S1f (unsigned int *r0, unsigned int *r1, unsigned int *r2, 42 | unsigned int *r3, unsigned int *r4) { 43 | *r0 = ~*r0; 44 | *r2 = ~*r2; 45 | *r4 = *r0; 46 | *r0 &= *r1; 47 | *r2 ^= *r0; 48 | *r0 |= *r3; 49 | *r3 ^= *r2; 50 | *r1 ^= *r0; 51 | *r0 ^= *r4; 52 | *r4 |= *r1; 53 | *r1 ^= *r3; 54 | *r2 |= *r0; 55 | *r2 &= *r4; 56 | *r0 ^= *r1; 57 | *r1 &= *r2; 58 | *r1 ^= *r0; 59 | *r0 &= *r2; 60 | *r0 ^= *r4; 61 | } 62 | 63 | static void S2f (unsigned int *r0, unsigned int *r1, unsigned int *r2, 64 | unsigned int *r3, unsigned int *r4) { 65 | *r4 = *r0; 66 | *r0 &= *r2; 67 | *r0 ^= *r3; 68 | *r2 ^= *r1; 69 | *r2 ^= *r0; 70 | *r3 |= *r4; 71 | *r3 ^= *r1; 72 | *r4 ^= *r2; 73 | *r1 = *r3; 74 | *r3 |= *r4; 75 | *r3 ^= *r0; 76 | *r0 &= *r1; 77 | *r4 ^= *r0; 78 | *r1 ^= *r3; 79 | *r1 ^= *r4; 80 | *r4 = ~*r4; 81 | } 82 | 83 | static void S3f (unsigned int *r0, unsigned int *r1, unsigned int *r2, 84 | unsigned int *r3, unsigned int *r4) { 85 | *r4 = *r0; 86 | *r0 |= *r3; 87 | *r3 ^= *r1; 88 | *r1 &= *r4; 89 | *r4 ^= *r2; 90 | *r2 ^= *r3; 91 | *r3 &= *r0; 92 | *r4 |= *r1; 93 | *r3 ^= *r4; 94 | *r0 ^= *r1; 95 | *r4 &= *r0; 96 | *r1 ^= *r3; 97 | *r4 ^= *r2; 98 | *r1 |= *r0; 99 | *r1 ^= *r2; 100 | *r0 ^= *r3; 101 | *r2 = *r1; 102 | *r1 |= *r3; 103 | *r1 ^= *r0; 104 | } 105 | 106 | static void S4f (unsigned int *r0, unsigned int *r1, unsigned int *r2, 107 | unsigned int *r3, unsigned int *r4) { 108 | *r1 ^= *r3; 109 | *r3 = ~*r3; 110 | *r2 ^= *r3; 111 | *r3 ^= *r0; 112 | *r4 = *r1; 113 | *r1 &= *r3; 114 | *r1 ^= *r2; 115 | *r4 ^= *r3; 116 | *r0 ^= *r4; 117 | *r2 &= *r4; 118 | *r2 ^= *r0; 119 | *r0 &= *r1; 120 | *r3 ^= *r0; 121 | *r4 |= *r1; 122 | *r4 ^= *r0; 123 | *r0 |= *r3; 124 | *r0 ^= *r2; 125 | *r2 &= *r3; 126 | *r0 = ~*r0; 127 | *r4 ^= *r2; 128 | } 129 | 130 | static void S5f (unsigned int *r0, unsigned int *r1, unsigned int *r2, 131 | unsigned int *r3, unsigned int *r4) { 132 | *r0 ^= *r1; 133 | *r1 ^= *r3; 134 | *r3 = ~*r3; 135 | *r4 = *r1; 136 | *r1 &= *r0; 137 | *r2 ^= *r3; 138 | *r1 ^= *r2; 139 | *r2 |= *r4; 140 | *r4 ^= *r3; 141 | *r3 &= *r1; 142 | *r3 ^= *r0; 143 | *r4 ^= *r1; 144 | *r4 ^= *r2; 145 | *r2 ^= *r0; 146 | *r0 &= *r3; 147 | *r2 = ~*r2; 148 | *r0 ^= *r4; 149 | *r4 |= *r3; 150 | *r2 ^= *r4; 151 | } 152 | 153 | static void S6f (unsigned int *r0, unsigned int *r1, unsigned int *r2, 154 | unsigned int *r3, unsigned int *r4) { 155 | *r2 = ~*r2; 156 | *r4 = *r3; 157 | *r3 &= *r0; 158 | *r0 ^= *r4; 159 | *r3 ^= *r2; 160 | *r2 |= *r4; 161 | *r1 ^= *r3; 162 | *r2 ^= *r0; 163 | *r0 |= *r1; 164 | *r2 ^= *r1; 165 | *r4 ^= *r0; 166 | *r0 |= *r3; 167 | *r0 ^= *r2; 168 | *r4 ^= *r3; 169 | *r4 ^= *r0; 170 | *r3 = ~*r3; 171 | *r2 &= *r4; 172 | *r2 ^= *r3; 173 | } 174 | 175 | static void S7f (unsigned int *r0, unsigned int *r1, unsigned int *r2, 176 | unsigned int *r3, unsigned int *r4) { 177 | *r4 = *r2; 178 | *r2 &= *r1; 179 | *r2 ^= *r3; 180 | *r3 &= *r1; 181 | *r4 ^= *r2; 182 | *r2 ^= *r1; 183 | *r1 ^= *r0; 184 | *r0 |= *r4; 185 | *r0 ^= *r2; 186 | *r3 ^= *r1; 187 | *r2 ^= *r3; 188 | *r3 &= *r0; 189 | *r3 ^= *r4; 190 | *r4 ^= *r2; 191 | *r2 &= *r0; 192 | *r4 = ~*r4; 193 | *r2 ^= *r4; 194 | *r4 &= *r0; 195 | *r1 ^= *r3; 196 | *r4 ^= *r1; 197 | } 198 | 199 | static void LKf (unsigned int *k, unsigned int r, unsigned int *a, 200 | unsigned int *b, unsigned int *c, unsigned int *d) { 201 | *a = k[r]; 202 | *b = k[r + 1]; 203 | *c = k[r + 2]; 204 | *d = k[r + 3]; 205 | } 206 | 207 | static void SKf (unsigned int *k, unsigned int r, unsigned int *a, 208 | unsigned int *b, unsigned int *c, unsigned int *d) { 209 | k[r + 4] = *a; 210 | k[r + 5] = *b; 211 | k[r + 6] = *c; 212 | k[r + 7] = *d; 213 | } 214 | 215 | unsigned int LE32 (unsigned int x) { 216 | unsigned int n = (unsigned char) x; 217 | n <<= 8; 218 | n |= (unsigned char) (x >> 8); 219 | n <<= 8; 220 | n |= (unsigned char) (x >> 16); 221 | return (n << 8) | (unsigned char) (x >> 24); 222 | } 223 | 224 | /* 225 | * Sets the Serpent key schedule. Input: User supplied key, keysize in bytes, 226 | * pointer to the key schedule storage. 227 | */ 228 | void serpent_set_key(const unsigned char userKey[], int keylen, 229 | unsigned char *ks) { 230 | unsigned int a,b,c,d,e; 231 | unsigned int *k = (unsigned int *)ks; 232 | unsigned int t; 233 | int i; 234 | 235 | for (i = 0; i < keylen / (int)sizeof(int); i++) 236 | k[i] = ((unsigned int*)userKey)[i]; 237 | 238 | if (keylen < 32) 239 | k[keylen/4] |= (unsigned int)1 << ((keylen%4)*8); 240 | 241 | k += 8; 242 | t = k[-1]; 243 | for (i = 0; i < 132; ++i) 244 | k[i] = t = rotlFixed(k[i-8] ^ k[i-5] ^ k[i-3] ^ t ^ 0x9e3779b9 ^ i, 245 | 11); 246 | k -= 20; 247 | 248 | for (i=0; i<4; i++) { 249 | LKf (k, 20, &a, &e, &b, &d); 250 | S3f (&a, &e, &b, &d, &c); 251 | SKf (k, 16, &e, &b, &d, &c); 252 | 253 | LKf (k, 24, &c, &b, &a, &e); 254 | S2f (&c, &b, &a, &e, &d); 255 | SKf (k, 20, &a, &e, &b, &d); 256 | 257 | LKf (k, 28, &b, &e, &c, &a); 258 | S1f (&b, &e, &c, &a, &d); 259 | SKf (k, 24, &c, &b, &a, &e); 260 | 261 | LKf (k, 32, &a, &b, &c, &d); 262 | S0f (&a, &b, &c, &d, &e); 263 | SKf (k, 28, &b, &e, &c, &a); 264 | 265 | k += 8*4; 266 | 267 | LKf (k, 4, &a, &c, &d, &b); 268 | S7f (&a, &c, &d, &b, &e); 269 | SKf (k, 0, &d, &e, &b, &a); 270 | 271 | LKf (k, 8, &a, &c, &b, &e); 272 | S6f (&a, &c, &b, &e, &d); 273 | SKf (k, 4, &a, &c, &d, &b); 274 | 275 | LKf (k, 12, &b, &a, &e, &c); 276 | S5f (&b, &a, &e, &c, &d); 277 | SKf (k, 8, &a, &c, &b, &e); 278 | 279 | LKf (k, 16, &e, &b, &d, &c); 280 | S4f (&e, &b, &d, &c, &a); 281 | SKf (k, 12, &b, &a, &e, &c); 282 | } 283 | LKf (k, 20, &a, &e, &b, &d); 284 | S3f (&a, &e, &b, &d, &c); 285 | SKf (k, 16, &e, &b, &d, &c); 286 | } 287 | 288 | -------------------------------------------------------------------------------- /stat.c: -------------------------------------------------------------------------------- 1 | /* ========================================================================== 2 | * stat.c 3 | * 4 | * Statistcal functions used in Interrogate 5 | * 6 | * Author: Carsten Maartmann-Moe 7 | * ========================================================================== 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "interrogate.h" 16 | 17 | #define LOG2OF10 3.32192809488736234787 18 | 19 | int r[6] = {0, 0, 0, 0, 0, 0}; 20 | 21 | /* 22 | * Calculate log2 23 | */ 24 | double approxlog2(double x) { 25 | return LOG2OF10 * log10(x); 26 | } 27 | 28 | /* 29 | * Calculates entropy of char array, with length window size and 'nofs' 30 | * symbols. 31 | */ 32 | float ent(interrogate_context *ctx, unsigned char *buffer, int length) { 33 | int i, count = 0; /* Counters */ 34 | float entropy = 0.0; /* The entropy */ 35 | unsigned char c; /* Char read from file buffer */ 36 | int *ccount; /* Bins for counting chars */ 37 | float *p; /* Bins for char probabilities */ 38 | 39 | /* Reserve space. ccount is zeroed out, p is not (we're iterating through 40 | * p later anyways).*/ 41 | ccount = (int *) calloc(ctx->nofs, sizeof(int)); 42 | p = (float *) malloc(ctx->nofs * sizeof(float)); 43 | 44 | /* Count occurrences of each char and the total count within window */ 45 | while (count < length) { 46 | c = (unsigned char) *buffer++; 47 | ccount[c]++; 48 | count++; 49 | } 50 | 51 | /* Calculate probabilitiy of each char, and update entropy */ 52 | for (i = 0; i < ctx->nofs; i++) { 53 | p[i] = ((float) ccount[i]) / length; 54 | if (p[i] > 0.0) 55 | entropy -= (float) p[i] * approxlog2(p[i]); 56 | } 57 | free(ccount); 58 | free(p); 59 | return entropy; 60 | } 61 | 62 | /* 63 | * Returns the minimum value of two ints 64 | */ 65 | int min(int a, int b) { 66 | return (a < b)? a : b; 67 | } 68 | 69 | /* 70 | * Checks if a byte in an array is set. The unsigned char is simply 71 | * the index in the array that has to be checked. 72 | */ 73 | int checkbyte(unsigned char index, int *array) { 74 | return array[index]; 75 | } 76 | 77 | /* 78 | * Counts number of unique bytes within a non-overlapping window. 79 | */ 80 | int countbytes(interrogate_context *ctx, unsigned char *buffer) { 81 | int count = 0; /* Window counter */ 82 | int bytecount = 0; /* The unique byte counter */ 83 | int *ccount; /* Bins for already discovered bytes */ 84 | unsigned char c; /* Char read from file buffer */ 85 | 86 | ccount = (int *) calloc(ctx->nofs, sizeof(int)); 87 | 88 | while ( count < ctx->wsize ) { 89 | c = (unsigned char) *buffer++; 90 | if (ccount[c] == 0) { 91 | ccount[c]++; 92 | bytecount++; 93 | } 94 | count++; 95 | } 96 | free(ccount); 97 | return bytecount; 98 | } 99 | 100 | /* 101 | * Count byte runs. A one-byte run is defined as two sequential bytes of 102 | * equal value. Thus, a six-byte run of 0x41 is actually seven sequential 103 | * 0x41s. All runs longer than 'run_length' are counted in the last bin, e.g. 104 | * as a 'run_length'-byte run. A call to this method is required to 105 | * initialize the optimized runs method 'runs_opt'. 106 | */ 107 | void runs(interrogate_context *ctx, unsigned char *buffer, int *runs_count, 108 | int run_length, int *firstrun, int *lastrun) { 109 | int i; 110 | int overflow = 0; 111 | unsigned char last = 0; 112 | int current_run = 0; 113 | memset(runs_count, 0, run_length * sizeof(int)); 114 | for (i = 0; i < ctx->wsize; i++) { 115 | unsigned char c = buffer[i]; 116 | /* Don't count the first char as a run */ 117 | if (i != 0) { 118 | if (c == last) { 119 | if (current_run < run_length) { 120 | /* Only decrement counter if such a bin exists */ 121 | if (current_run != 0) 122 | runs_count[current_run - 1]--; 123 | runs_count[current_run]++; 124 | current_run++; 125 | } else { 126 | overflow++; 127 | } 128 | } else { 129 | /* Check if the run went on from the start; if so save */ 130 | if (i == current_run + overflow + 1) { 131 | *firstrun = current_run; 132 | } 133 | /* Reset runs counters */ 134 | current_run = overflow = 0; 135 | } 136 | } 137 | last = c; 138 | } 139 | /* Save if the last char was a part of a run */ 140 | *lastrun = current_run; 141 | } 142 | 143 | /* 144 | * Optimized 'runs' method. See runs(). Needs to be initialized by a call 145 | * to runs() before excecution; to count runs in the initial window, and 146 | * set lastrun and firstrun counters. The algorithm basically keeps track of 147 | * the runs in the ends of the buffer, and increments and decrements run 148 | * counts as needed. It is intended to work on a unsigned char buffer, and be 149 | * fed sub-buffers of this buffer in a sequential fashion. For example, a 150 | * call procedure like this will work: 151 | * 152 | * int *runs_count = {0, 0, 0, 0, 0, 0}; // Initalize array for storage 153 | * lastrun = firstrun = 0; // Initialize counters 154 | * runs(...); // Initialize by calling 'runs()' function 155 | * for (i = 0; i < buffersize; i++) { 156 | * runs_opt(context, &buffer[i], runs_count, ...); 157 | * } 158 | * 159 | * This method has a significant performance gain compared to calling runs 160 | * sequentially, typically linear vs. exponential time complexity. For some 161 | * reason, this method is known to not work with gcc optimization e.g., no 162 | * -Ox options. 163 | */ 164 | void runs_opt(interrogate_context *ctx, unsigned char *buffer, 165 | int *runs_count, int run_length, int *firstrun, int *lastrun) { 166 | unsigned char *buf_ptr = buffer; 167 | int new_firstrun = 0; 168 | /* Count the new first run */ 169 | while((*buf_ptr == *++buf_ptr) && new_firstrun < run_length) { 170 | new_firstrun++; 171 | } 172 | if (ctx->wsize < 2 * run_length) { 173 | fprintf(stderr, "A window size of at least two times the run " 174 | "length is required for this function to work.\n"); 175 | exit(-1); 176 | } 177 | /* Since C indexes runs from 0 we need to subtract one from every 178 | * count to form indices in the runs_count table. If the new firs run 179 | * is its maximum, it implies that the counts should not be 180 | * decremented 181 | */ 182 | if (*firstrun > 0 && !(new_firstrun == 6)) { 183 | /* Decrement bin count for the byte that "fell out" */ 184 | runs_count[*firstrun - 1]--; 185 | /* Subract the byte that "fell out" of the buffer */ 186 | (*firstrun)--; 187 | /* If there exists a bin for a smaller run, increment it */ 188 | if (*firstrun != 0) 189 | runs_count[*firstrun - 1]++; 190 | } else { 191 | /* Count an eventual new run */ 192 | *firstrun = new_firstrun; 193 | } 194 | /* Check if the last two chars in the buffer match */ 195 | if (buffer[ctx->wsize - 2] == buffer[ctx->wsize - 1]) { 196 | /* Decrement the count for the previous run */ 197 | if (*lastrun > 0) 198 | runs_count[*lastrun - 1]--; 199 | /* Increment lastrun if its less than max run length */ 200 | if (*lastrun < run_length) 201 | (*lastrun)++; 202 | /* Increment bin for current count */ 203 | runs_count[*lastrun - 1]++; 204 | } else { 205 | /* Reset lastrun if the two last chars doesn't match */ 206 | *lastrun = 0; 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /twofish.c: -------------------------------------------------------------------------------- 1 | /* ========================================================================== 2 | * twofish.c 3 | * 4 | * Twofish key schedule implementation for Interrogate 5 | * 6 | * Adapted for Interrogate use by Carsten Maartmann-Moe 7 | * , see full licencing details for original code 8 | * below. 9 | * ========================================================================== 10 | */ 11 | 12 | /* 13 | --------------------------------------------------------------------------- 14 | Copyright (c) 1999, Dr Brian Gladman, Worcester, UK. All rights reserved. 15 | 16 | LICENSE TERMS 17 | 18 | The free distribution and use of this software is allowed (with or without 19 | changes) provided that: 20 | 21 | 1. source code distributions include the above copyright notice, this 22 | list of conditions and the following disclaimer; 23 | 24 | 2. binary distributions include the above copyright notice, this list 25 | of conditions and the following disclaimer in their documentation; 26 | 27 | 3. the name of the copyright holder is not used to endorse products 28 | built using this software without specific written permission. 29 | 30 | DISCLAIMER 31 | 32 | This software is provided 'as is' with no explicit or implied warranties 33 | in respect of its properties, including, but not limited to, correctness 34 | and/or fitness for purpose. 35 | --------------------------------------------------------------------------- 36 | 37 | My thanks to Doug Whiting and Niels Ferguson for comments that led 38 | to improvements in this implementation. 39 | 40 | Issue Date: 14th January 1999 41 | */ 42 | 43 | #include 44 | #include 45 | #include "interrogate.h" 46 | 47 | #define extract_byte(x,n) ((unsigned char)((x) >> (8 * n))) 48 | 49 | #define G_M 0x0169 50 | 51 | unsigned char RS[4][8] = 52 | { 53 | { 0x01, 0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E, }, 54 | { 0xA4, 0x56, 0x82, 0xF3, 0x1E, 0xC6, 0x68, 0xE5, }, 55 | { 0x02, 0xA1, 0xFC, 0xC1, 0x47, 0xAE, 0x3D, 0x19, }, 56 | { 0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E, 0x03, }, 57 | }; 58 | 59 | static unsigned char tab_5b[4] = 60 | { 0, G_M >> 2, G_M >> 1, (G_M >> 1) ^ (G_M >> 2) }; 61 | static unsigned char tab_ef[4] = 62 | { 0, (G_M >> 1) ^ (G_M >> 2), G_M >> 1, G_M >> 2 }; 63 | 64 | #define ffm_01(x) (x) 65 | #define ffm_5b(x) ((x) ^ ((x) >> 2) ^ tab_5b[(x) & 3]) 66 | #define ffm_ef(x) ((x) ^ ((x) >> 1) ^ ((x) >> 2) ^ tab_ef[(x) & 3]) 67 | 68 | static unsigned char ror4[16] = { 0, 8, 1, 9, 2, 10, 3, 11, 69 | 4, 12, 5, 13, 6, 14, 7, 15 }; 70 | static unsigned char ashx[16] = { 0, 9, 2, 11, 4, 13, 6, 15, 71 | 8, 1, 10, 3, 12, 5, 14, 7 }; 72 | 73 | static unsigned char qt0[2][16] = 74 | { { 8, 1, 7, 13, 6, 15, 3, 2, 0, 11, 5, 9, 14, 12, 10, 4 }, 75 | { 2, 8, 11, 13, 15, 7, 6, 14, 3, 1, 9, 4, 0, 10, 12, 5 } 76 | }; 77 | 78 | static unsigned char qt1[2][16] = 79 | { { 14, 12, 11, 8, 1, 2, 3, 5, 15, 4, 10, 6, 7, 0, 9, 13 }, 80 | { 1, 14, 2, 11, 4, 12, 3, 7, 6, 13, 10, 5, 15, 9, 0, 8 } 81 | }; 82 | 83 | static unsigned char qt2[2][16] = 84 | { { 11, 10, 5, 14, 6, 13, 9, 0, 12, 8, 15, 3, 2, 4, 7, 1 }, 85 | { 4, 12, 7, 5, 1, 6, 9, 10, 0, 14, 13, 8, 2, 11, 3, 15 } 86 | }; 87 | 88 | static unsigned char qt3[2][16] = 89 | { { 13, 7, 15, 4, 1, 2, 6, 14, 9, 11, 3, 0, 8, 5, 12, 10 }, 90 | { 11, 9, 5, 1, 12, 3, 13, 14, 6, 4, 7, 15, 2, 0, 8, 10 } 91 | }; 92 | 93 | 94 | static unsigned char qp(const unsigned int n, const unsigned char x) { 95 | unsigned char a0, a1, a2, a3, a4, b0, b1, b2, b3, b4; 96 | 97 | a0 = x >> 4; 98 | b0 = x & 15; 99 | a1 = a0 ^ b0; 100 | b1 = ror4[b0] ^ ashx[a0]; 101 | a2 = qt0[n][a1]; 102 | b2 = qt1[n][b1]; 103 | a3 = a2 ^ b2; 104 | b3 = ror4[b2] ^ ashx[a2]; 105 | a4 = qt2[n][a3]; 106 | b4 = qt3[n][b3]; 107 | return (b4 << 4) | a4; 108 | }; 109 | 110 | /* Q tables */ 111 | 112 | static unsigned int qt_gen = 0; 113 | static unsigned char q_tab[2][256]; 114 | 115 | #define q(n,x) q_tab[n][x] 116 | 117 | static void gen_qtab(void) { 118 | unsigned int i; 119 | 120 | for(i = 0; i < 256; ++i) { 121 | q(0,i) = qp(0, (unsigned char)i); 122 | q(1,i) = qp(1, (unsigned char)i); 123 | } 124 | }; 125 | 126 | /* M tables */ 127 | static unsigned int mt_gen = 0; 128 | static unsigned int m_tab[4][256]; 129 | 130 | static void gen_mtab(void) { 131 | unsigned int i, f01, f5b, fef; 132 | 133 | for(i = 0; i < 256; ++i) { 134 | f01 = q(1,i); 135 | f5b = ffm_5b(f01); 136 | fef = ffm_ef(f01); 137 | m_tab[0][i] = f01 + (f5b << 8) + (fef << 16) + (fef << 24); 138 | m_tab[2][i] = f5b + (fef << 8) + (f01 << 16) + (fef << 24); 139 | 140 | f01 = q(0,i); 141 | f5b = ffm_5b(f01); 142 | fef = ffm_ef(f01); 143 | m_tab[1][i] = fef + (fef << 8) + (f5b << 16) + (f01 << 24); 144 | m_tab[3][i] = f5b + (f01 << 8) + (fef << 16) + (f5b << 24); 145 | } 146 | }; 147 | 148 | #define mds(n,x) m_tab[n][x] 149 | 150 | static unsigned int h_fun(twofish_tc *instance, const unsigned int x, 151 | const unsigned int key[]) { 152 | unsigned int b0, b1, b2, b3; 153 | 154 | b0 = extract_byte(x, 0); 155 | b1 = extract_byte(x, 1); 156 | b2 = extract_byte(x, 2); 157 | b3 = extract_byte(x, 3); 158 | 159 | switch(instance->k_len) { 160 | case 4: 161 | b0 = q(1, (unsigned char) b0) ^ extract_byte(key[3],0); 162 | b1 = q(0, (unsigned char) b1) ^ extract_byte(key[3],1); 163 | b2 = q(0, (unsigned char) b2) ^ extract_byte(key[3],2); 164 | b3 = q(1, (unsigned char) b3) ^ extract_byte(key[3],3); 165 | case 3: 166 | b0 = q(1, (unsigned char) b0) ^ extract_byte(key[2],0); 167 | b1 = q(1, (unsigned char) b1) ^ extract_byte(key[2],1); 168 | b2 = q(0, (unsigned char) b2) ^ extract_byte(key[2],2); 169 | b3 = q(0, (unsigned char) b3) ^ extract_byte(key[2],3); 170 | case 2: 171 | b0 = q(0, (unsigned char) (q(0, (unsigned char) b0) ^ 172 | extract_byte(key[1],0))) ^ 173 | extract_byte(key[0],0); 174 | b1 = q(0, (unsigned char) (q(1, (unsigned char) b1) ^ 175 | extract_byte(key[1],1))) ^ 176 | extract_byte(key[0],1); 177 | b2 = q(1, (unsigned char) (q(0, (unsigned char) b2) ^ 178 | extract_byte(key[1],2))) ^ 179 | extract_byte(key[0],2); 180 | b3 = q(1, (unsigned char) (q(1, (unsigned char) b3) ^ 181 | extract_byte(key[1],3))) ^ 182 | extract_byte(key[0],3); 183 | } 184 | 185 | return mds(0, b0) ^ mds(1, b1) ^ mds(2, b2) ^ mds(3, b3); 186 | }; 187 | 188 | #define q20(x) q(0,q(0,x) ^ extract_byte(key[1],0)) ^ extract_byte(key[0],0) 189 | #define q21(x) q(0,q(1,x) ^ extract_byte(key[1],1)) ^ extract_byte(key[0],1) 190 | #define q22(x) q(1,q(0,x) ^ extract_byte(key[1],2)) ^ extract_byte(key[0],2) 191 | #define q23(x) q(1,q(1,x) ^ extract_byte(key[1],3)) ^ extract_byte(key[0],3) 192 | 193 | #define q30(x) q(0,q(0,q(1, x) ^ extract_byte(key[2],0)) ^ extract_byte(key[1],0)) ^ extract_byte(key[0],0) 194 | #define q31(x) q(0,q(1,q(1, x) ^ extract_byte(key[2],1)) ^ extract_byte(key[1],1)) ^ extract_byte(key[0],1) 195 | #define q32(x) q(1,q(0,q(0, x) ^ extract_byte(key[2],2)) ^ extract_byte(key[1],2)) ^ extract_byte(key[0],2) 196 | #define q33(x) q(1,q(1,q(0, x) ^ extract_byte(key[2],3)) ^ extract_byte(key[1],3)) ^ extract_byte(key[0],3) 197 | 198 | #define q40(x) q(0,q(0,q(1, q(1, x) ^ extract_byte(key[3],0)) ^ extract_byte(key[2],0)) ^ extract_byte(key[1],0)) ^ extract_byte(key[0],0) 199 | #define q41(x) q(0,q(1,q(1, q(0, x) ^ extract_byte(key[3],1)) ^ extract_byte(key[2],1)) ^ extract_byte(key[1],1)) ^ extract_byte(key[0],1) 200 | #define q42(x) q(1,q(0,q(0, q(0, x) ^ extract_byte(key[3],2)) ^ extract_byte(key[2],2)) ^ extract_byte(key[1],2)) ^ extract_byte(key[0],2) 201 | #define q43(x) q(1,q(1,q(0, q(1, x) ^ extract_byte(key[3],3)) ^ extract_byte(key[2],3)) ^ extract_byte(key[1],3)) ^ extract_byte(key[0],3) 202 | 203 | void gen_mk_tab(twofish_tc *instance, unsigned int key[]) { 204 | unsigned int i; 205 | unsigned char by; 206 | 207 | unsigned int *mk_tab = instance->mk_tab; 208 | 209 | switch(instance->k_len) { 210 | case 2: 211 | for(i = 0; i < 256; ++i) { 212 | by = (unsigned char)i; 213 | 214 | mk_tab[0 + 4*i] = mds(0, q20(by)); 215 | mk_tab[1 + 4*i] = mds(1, q21(by)); 216 | 217 | mk_tab[2 + 4*i] = mds(2, q22(by)); 218 | mk_tab[3 + 4*i] = mds(3, q23(by)); 219 | 220 | } 221 | break; 222 | 223 | case 3: 224 | for(i = 0; i < 256; ++i) { 225 | by = (unsigned char)i; 226 | 227 | mk_tab[0 + 4*i] = mds(0, q30(by)); 228 | mk_tab[1 + 4*i] = mds(1, q31(by)); 229 | 230 | } 231 | break; 232 | 233 | case 4: 234 | for(i = 0; i < 256; ++i) { 235 | by = (unsigned char)i; 236 | 237 | mk_tab[0 + 4*i] = mds(0, q40(by)); 238 | mk_tab[1 + 4*i] = mds(1, q41(by)); 239 | 240 | mk_tab[2 + 4*i] = mds(2, q42(by)); 241 | mk_tab[3 + 4*i] = mds(3, q43(by)); 242 | 243 | } 244 | } 245 | }; 246 | 247 | # define g0_fun(x) ( mk_tab[0 + 4*extract_byte(x,0)] ^ mk_tab[1 + 4*extract_byte(x,1)] \ 248 | ^ mk_tab[2 + 4*extract_byte(x,2)] ^ mk_tab[3 + 4*extract_byte(x,3)] ) 249 | # define g1_fun(x) ( mk_tab[0 + 4*extract_byte(x,3)] ^ mk_tab[1 + 4*extract_byte(x,0)] \ 250 | ^ mk_tab[2 + 4*extract_byte(x,1)] ^ mk_tab[3 + 4*extract_byte(x,2)] ) 251 | 252 | #define G_MOD 0x0000014d 253 | 254 | unsigned int mds_rem(unsigned int p0, unsigned int p1) { 255 | unsigned int i, t, u; 256 | 257 | for(i = 0; i < 8; ++i) { 258 | t = p1 >> 24; // get most significant coefficient 259 | p1 = (p1 << 8) | (p0 >> 24); 260 | p0 <<= 8; // shift others up 261 | // multiply t by a (the primitive element - i.e. left shift) 262 | u = (t << 1); 263 | if(t & 0x80) // subtract modular polynomial on overflow 264 | u ^= G_MOD; 265 | p1 ^= t ^ (u << 16); // remove t * (a * x^2 + 1) 266 | u ^= (t >> 1); // form u = a * t + t / a = t * (a + 1 / a); 267 | if(t & 0x01) // add the modular polynomial on underflow 268 | u ^= G_MOD >> 1; 269 | p1 ^= (u << 24) | (u << 8); // remove t * (a + 1/a) * (x^3 + x) 270 | } 271 | 272 | return p1; 273 | }; 274 | 275 | /* Initialise the key schedule from the user supplied key */ 276 | void twofish_set_key(twofish_tc *instance, const unsigned int in_key[], const unsigned int key_len) { 277 | unsigned int i, a, b, me_key[4], mo_key[4]; 278 | unsigned int *l_key, *s_key; 279 | 280 | l_key = instance->l_key; 281 | s_key = instance->s_key; 282 | 283 | if(!qt_gen) { 284 | gen_qtab(); 285 | qt_gen = 1; 286 | } 287 | 288 | if(!mt_gen) { 289 | gen_mtab(); 290 | mt_gen = 1; 291 | } 292 | 293 | instance->k_len = key_len / 64; /* 2, 3 or 4 */ 294 | 295 | for(i = 0; i < instance->k_len; ++i) { 296 | a = in_key[i + i]; 297 | me_key[i] = a; 298 | b = in_key[i + i + 1]; 299 | mo_key[i] = b; 300 | s_key[instance->k_len - i - 1] = mds_rem(a, b); 301 | } 302 | 303 | for(i = 0; i < 40; i += 2) { 304 | a = 0x01010101 * i; 305 | b = a + 0x01010101; 306 | a = h_fun(instance, a, me_key); 307 | b = rotlFixed(h_fun(instance, b, mo_key), 8); 308 | l_key[i] = a + b; 309 | l_key[i + 1] = rotlFixed(a + 2 * b, 9); 310 | } 311 | gen_mk_tab(instance, s_key); 312 | 313 | return; 314 | }; 315 | 316 | -------------------------------------------------------------------------------- /util.c: -------------------------------------------------------------------------------- 1 | /* ========================================================================== 2 | * util.c 3 | * 4 | * Utility toolbox for Interrogate 5 | * 6 | * Author: Carsten Maartmann-Moe 7 | * ========================================================================== 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "interrogate.h" 16 | 17 | /* 18 | * Open file, return pointer 19 | */ 20 | FILE *open_file(interrogate_context *ctx, char *filename, char *mode) { 21 | struct stat st; /* Stat struct for input file */ 22 | FILE *fp; /* Pointer to input file */ 23 | if (stat(filename, &st) == -1) { 24 | perror("stat()"); 25 | fprintf(stderr, "Failed to stat %s.\n", filename); 26 | exit(-1); 27 | } else { 28 | ctx->filelen = st.st_size; 29 | } 30 | 31 | fp = fopen(filename, mode); 32 | if (fp == NULL) { 33 | perror("fopen()"); 34 | fprintf(stderr, "Failed to open %s.\n", filename); 35 | exit(-1); 36 | } 37 | return fp; 38 | } 39 | 40 | /* 41 | * Reads entire file into memory and returns buffer 42 | */ 43 | unsigned char *read_file(interrogate_context *ctx, FILE *fp) { 44 | unsigned char *buffer; /* Buffer (entire file) */ 45 | 46 | /* Get the length of the file and rewind */ 47 | fseek(fp, 0L, SEEK_END); 48 | ctx->filelen = ftell(fp); 49 | rewind(fp); 50 | 51 | /* Try to allocate enough memory for entire file. Should work for 52 | * large files if the system uses virtual memory. calloc() 53 | * initializes all bytes to 0, so we don't have to worry about 54 | * setting the NULL-terminator. */ 55 | buffer = calloc(ctx->filelen + 1, sizeof(unsigned char)); 56 | if (buffer == NULL) { 57 | fprintf(stderr, "Not enough memory to read entire file.\n"); 58 | exit(1); 59 | } 60 | 61 | /* Read file into buffer */ 62 | printf("Attempting to load entire file into memory, please stand " 63 | "by...\n"); 64 | size_t res = fread(buffer, 1, ctx->filelen, fp); 65 | if (res != ctx->filelen) { 66 | fprintf(stderr, "Reading error.\n"); 67 | exit(3); 68 | } 69 | 70 | return buffer; 71 | } 72 | 73 | /* 74 | * Prints info about entropy blobs 75 | */ 76 | void printblobinfo(int start, int end, int bytes, float wins, float ent) { 77 | printf(" %.8x - %.8x | %8i | %7.2f | %f \n", 78 | start, end, bytes, wins, ent); 79 | } 80 | 81 | /* 82 | * Prints raw data in hexadecimal form to stdout. Bytes are separated wiht 83 | * spaces, and linefeeds are inserted after 'column' bytes 84 | */ 85 | void print_hex_array(unsigned char *buffer, int length, int columns) { 86 | int i; 87 | for (i = 0; i < length; i++) { 88 | if ((i % columns) == 0) 89 | printf("\n"); 90 | printf("%02x ", buffer[i]); 91 | } 92 | printf("\n\n"); 93 | } 94 | 95 | /* 96 | * Prints raw data in hexadecimal, 32-bit word, little-endian form to stdout. 97 | * Words are separated with spaces, and linefeeds are inserted after 98 | * 'columns' words 99 | */ 100 | void print_hex_words(unsigned int *buffer, int length, int columns) { 101 | int i; 102 | for (i = 0; i < length; i++) { 103 | if ((i % columns) == 0) 104 | printf("\n"); 105 | printf("%08x ", buffer[i]); 106 | } 107 | printf("\n\n"); 108 | } 109 | 110 | /* 111 | * Windows getopt() :-/ 112 | */ 113 | #ifdef _WIN32 114 | static int optind = 1; 115 | 116 | static int getopt(int argc, char *argv[], char *opts) { 117 | static char *opp = NULL; 118 | int o; 119 | 120 | while (opp == NULL) { 121 | if ((optind >= argc) || (*argv[optind] != '-')) { 122 | return -1; 123 | } 124 | opp = argv[optind] + 1; 125 | optind++; 126 | if (*opp == 0) { 127 | opp = NULL; 128 | } 129 | } 130 | o = *opp++; 131 | if (*opp == 0) { 132 | opp = NULL; 133 | } 134 | return strchr(opts, o) == NULL ? '?' : o; 135 | } 136 | #endif 137 | 138 | void print_to_file(FILE *fp, float value) { 139 | char str[30]; 140 | snprintf(str, 30, "%.4g", value); 141 | strncat(str, "\n", 1); 142 | fputs(str, fp); 143 | } 144 | 145 | unsigned getbits(unsigned x, int p, int n) { 146 | return (x >> (p + 1 - n)) & ~(~0 << n); 147 | } 148 | 149 | /* 150 | * Truncates of the nPrecision last digits of a float 151 | */ 152 | double format(double Value, int nPrecision) { 153 | char *buffer = malloc(128*sizeof(char)); 154 | snprintf(buffer,127,"%0.*f",nPrecision,Value); 155 | double d = atof(buffer); 156 | free(buffer); 157 | return d; 158 | } 159 | 160 | /* 161 | * Checks if the runs lies within a relaxed set of heuristic values. 162 | */ 163 | int is_mk_tab(int *run) { 164 | return (run[0] < 520 && 165 | run[0] > 485 && 166 | run[1] == 0 && 167 | run[2] <= 12 && 168 | run[2] >= 1 && 169 | run[3] == 0 && 170 | run[4] == 0 && 171 | run[5] <= 1 && 172 | run[5] >= 0); 173 | } 174 | 175 | /* 176 | * Heuristic check for Twofish sub- and whitening keys 177 | */ 178 | int is_l_key(interrogate_context *ctx, unsigned int *l_key) { 179 | float entropy = ent(ctx, (unsigned char *)l_key, 160); 180 | return (entropy < 7.2 && entropy > 6.3); 181 | } 182 | 183 | /* 184 | * Heuristic check for Twofish S-box keys 185 | */ 186 | int is_s_key(interrogate_context *ctx, unsigned int *s_key) { 187 | float entropy = format(ent(ctx, (unsigned char *)s_key, 16), 4); 188 | return (entropy == 4.0000 || 189 | entropy == 3.8750 || 190 | entropy == 3.7500 || 191 | entropy == 3.7028 || 192 | entropy == 3.6250 || 193 | entropy == 3.5778 || 194 | entropy == 3.5000 || 195 | entropy == 3.4528 || 196 | entropy == 3.4056 || 197 | entropy == 3.3750 || 198 | entropy == 3.3278 || 199 | entropy == 3.2806 || 200 | entropy == 3.2744 || 201 | entropy == 3.2500 || 202 | entropy == 3.2028 || 203 | entropy == 3.1556 || 204 | entropy == 3.1494 || 205 | entropy == 3.1250 || 206 | entropy == 3.0778 || 207 | entropy == 3.0306 || 208 | entropy == 3.0244 || 209 | ((entropy <= 3.0000) && 210 | (entropy >= 2.0000))); 211 | } 212 | 213 | /* 214 | * Validates a Twofish key schedule by structural checkups. Prints info. 215 | */ 216 | void validate_tf_ks(interrogate_context *ctx, unsigned char *buffer, 217 | int offset) { 218 | float entropy; 219 | /* Try each of the different structs, and return the first match */ 220 | 221 | /* Truecrypt */ 222 | int tc_offs = offset - (44 * sizeof(unsigned int)); 223 | if (tc_offs >= 0) { 224 | twofish_tc *tc = (twofish_tc *) (buffer + tc_offs); 225 | entropy = ent(ctx, (unsigned char *)tc->mk_tab, 226 | sizeof(tc->mk_tab)); 227 | if (entropy == 8 && tc->k_len == 4) { 228 | if (is_l_key(ctx, tc->l_key)) { 229 | if(is_s_key(ctx, tc->s_key)) { 230 | printf("Truecrypt Twofish key found at %08x. " 231 | "Expanded key:\n", tc_offs); 232 | printf("Key words:"); 233 | print_hex_words((unsigned int *)tc->l_key, 234 | (sizeof(tc->l_key)) / 4, 4); 235 | printf("S-box keys:"); 236 | print_hex_words((unsigned int *)tc->s_key, 237 | sizeof(tc->s_key) / 4, 4); 238 | printf("S-box array:"); 239 | print_hex_words((unsigned int *)tc->mk_tab, 240 | sizeof(tc->mk_tab) / 4, 4); 241 | printf("Key length:"); 242 | print_hex_words(&tc->k_len, 243 | sizeof(tc->k_len) / 4, 4); 244 | ctx->count++; 245 | } 246 | } 247 | } 248 | } 249 | 250 | /* Optimized */ 251 | int opt_offs = offset - (41 * sizeof(unsigned int)); 252 | if (opt_offs >= 0) { 253 | twofish_opt *tc4 = (twofish_opt *) (buffer + opt_offs); 254 | entropy = ent(ctx, (unsigned char *)tc4->QF, 255 | sizeof(tc4->QF)); 256 | if (entropy == 8 && (tc4->k_len == 0 || tc4->k_len == 1) ) { 257 | if (is_l_key(ctx, tc4->K)) { 258 | printf("Twofish key found at %08x. Expanded key:\n\n", 259 | opt_offs); 260 | printf("Key words:"); 261 | print_hex_words((unsigned int *)tc4->K, 262 | (sizeof(tc4->K)) / 4, 4); 263 | printf("S-box array:"); 264 | print_hex_words((unsigned int *)tc4->QF, 265 | (sizeof(tc4->QF)) / 4, 4); 266 | ctx->count++; 267 | } 268 | } 269 | } 270 | 271 | /* GPG/Linux and SSH */ 272 | twofish_gpg *tc2 = (twofish_gpg *) (buffer + offset); 273 | entropy = ent(ctx, (unsigned char *)tc2->s, 274 | sizeof(tc2->s)); 275 | if (entropy == 8) { 276 | if (is_l_key(ctx, tc2->w)) { 277 | printf("GPG or SSH Twofish key found at %08x. Expanded key:\n", 278 | offset); 279 | printf("Key words:"); 280 | print_hex_words((unsigned int *)tc2->w, 281 | (sizeof(tc2->w) + sizeof(tc2->k)) / 4, 4); 282 | printf("S-box array:"); 283 | print_hex_words((unsigned int *)tc2->s, 284 | (sizeof(tc2->s)) / 4, 4); 285 | ctx->count++; 286 | } 287 | } 288 | 289 | /* Nettle */ 290 | int nettle_offs = offset - (40 * sizeof(unsigned int)); 291 | if (nettle_offs >= 0) { 292 | twofish_nettle *tc3 = (twofish_nettle *) (buffer + nettle_offs); 293 | entropy = ent(ctx, (unsigned char *)tc3->s, 294 | sizeof(tc3->s)); 295 | if (entropy == 8) { 296 | if (is_l_key(ctx, tc3->k)) { 297 | printf("Nettle Twofish key found at %08x. Expanded key:\n\n", 298 | nettle_offs); 299 | printf("Key words:"); 300 | print_hex_words((unsigned int *)tc3->k, 301 | (sizeof(tc3->k)) / 4, 4); 302 | printf("S-box array:"); 303 | print_hex_words((unsigned int *)tc3->s, 304 | (sizeof(tc3->s)) / 4, 4); 305 | ctx->count++; 306 | } 307 | } 308 | } 309 | 310 | 311 | } 312 | -------------------------------------------------------------------------------- /virtmem.c: -------------------------------------------------------------------------------- 1 | /* ========================================================================= 2 | * virtmem.c 3 | * 4 | * Utility to reconstruct virtual memory from the Nonpaged Pool of a 5 | * process. Part of Interrogate 6 | * 7 | * Author: Carsten Maartmann-Moe 8 | * ========================================================================= 9 | */ 10 | #include 11 | #include 12 | 13 | #include "interrogate.h" 14 | 15 | /* Iterate through the virtual addresses in the Nonpaged Pool virtual 16 | * address space and fetch pages from the physical memory, using the 17 | * CR3 address as Page Directory base. 18 | */ 19 | void reconstruct(interrogate_context *ctx, unsigned char *buffer) { 20 | pte *pd, *pt; /* Page directory and table pointers */ 21 | pte pd_entry, pt_entry; /* Page directory and table entries */ 22 | virtual_address *addr; /* Virtual address */ 23 | FILE *fp = fopen("pages", "wb"); /* Output file */ 24 | unsigned int *frames; /* Fetched page frame numbers */ 25 | unsigned long this_pagesize; /* The current pagesize (large page) */ 26 | unsigned char *page; /* Current page */ 27 | unsigned int i, last_i, l_pc, pc; /* (Page) counters */ 28 | unsigned int lim_low; /* Lower virtual address space bound */ 29 | unsigned int lim_high; /* Upper virtual address space bound */ 30 | 31 | pd = malloc(sizeof(pte) * 1024); 32 | pt = malloc(sizeof(pte) * 1024); 33 | addr = malloc(sizeof(virtual_address)); 34 | long memorysize = ctx->filelen; 35 | l_pc = pc = last_i = 0; 36 | 37 | /* Assume standard pagesize */ 38 | int pagesize = 4096; 39 | 40 | /* Allocate and zero out memory for already fetched pages db */ 41 | frames = calloc(memorysize / pagesize, sizeof(unsigned int)); 42 | 43 | /* The page directory is located at the offset pointed to by CR3 */ 44 | pd = (pte *)&buffer[ctx->cr3]; 45 | 46 | if (ctx->interval) { 47 | lim_low = ctx->from; 48 | lim_high = ctx->to; 49 | ctx->interval = FALSE; // To prevent interval-search in main 50 | } else { 51 | /* A bit more dirty; use the whole virtual address space :-/ */ 52 | lim_low = 0x00000000; 53 | lim_high = 0xffffffff; 54 | } 55 | printf("Reconstructing virtual memory from %08x to %08x. To change " 56 | "this, use the -i switch.\n", lim_low, lim_high); 57 | 58 | /* Large pages are only available with physical memory size > 255 MB */ 59 | int large_pages = (memorysize > (255 * 1024)); 60 | if (large_pages) { 61 | page = malloc(pagesize * 1024 * sizeof(unsigned char)); // 4 MB pages 62 | } else { 63 | page = malloc(pagesize * sizeof(unsigned char)); // 4 KB pages 64 | } 65 | 66 | for (i = lim_low; i < lim_high; i += pagesize) { 67 | /* Break if 'i' wraps around e.g. integer overflow */ 68 | if (i < last_i) 69 | break; 70 | 71 | addr = (virtual_address *)&i; 72 | pd_entry = pd[addr->pd_index]; 73 | /* Skip NULL entries */ 74 | if (!*(unsigned int *)&pd_entry) 75 | continue; 76 | 77 | /* The target page table is found via the pfn of the pde */ 78 | unsigned long pde_offset = pd_entry.pfn * pagesize; 79 | /* Check that the page is in memory, and that it is within bounds */ 80 | if ((pde_offset < memorysize) && 81 | pd_entry.valid) { 82 | pt = (pte *)&buffer[pde_offset]; 83 | if (!pt) 84 | continue; // Null pointer 85 | pt_entry = pt[addr->pt_index]; 86 | /* Skip NULL entries */ 87 | if (!*(unsigned int *)&pt_entry) 88 | continue; 89 | } 90 | 91 | unsigned long pte_offset = pt_entry.pfn * pagesize; 92 | /* Check that the page is in memory, and that it is within bounds */ 93 | if ((pte_offset < memorysize) && 94 | pt_entry.valid) { 95 | if (!frames[pt_entry.pfn]) { // If the page (frame) is new 96 | /* Mark page as found, and fetch from buffer */ 97 | frames[pt_entry.pfn] = 1; 98 | page = &buffer[pte_offset]; 99 | 100 | if (ctx->verbose) { 101 | print_pte(addr, pd, &pd_entry, pt, &pt_entry, page); 102 | } 103 | 104 | /* Set proper pagesize for current page */ 105 | if (pt_entry.large_page && large_pages) { 106 | l_pc++; 107 | this_pagesize = pagesize * 1024; 108 | } else { 109 | pc++; 110 | this_pagesize = pagesize; 111 | } 112 | 113 | /* Place each page fetched sequentially in a new file */ 114 | fwrite(page, sizeof(unsigned char), this_pagesize, fp); 115 | } 116 | } 117 | last_i = i; // Update the last value of 'i' 118 | } 119 | printf("Wrote %i pages to disk, %i normal and %i large, a total of " 120 | "%.2f MB.\n", l_pc + pc, pc, l_pc, 121 | ((double)ftell(fp) / (1024*1024))); 122 | fclose(fp); 123 | } 124 | 125 | void print_pte(virtual_address *addr, pte *pd, pte *pde, pte *pt, pte *pte, 126 | unsigned char *page) { 127 | printf( "Vitual address: %08x\n" 128 | "PD index: %08x -> Byte offset: %08x\n" 129 | "PDE value: %08x -> Page frame number: %08x\n" 130 | "PT index: %08x -> Byte offset: %08x\n" 131 | "PTE value: %08x -> Page frame number: %08x\n" 132 | "Flags: %c%c%c%c%c%c%c%c%c%c\n" 133 | "First 16 bytes of page: ", 134 | *(unsigned int *)addr, addr->pd_index, addr->pd_index * 4, 135 | *(unsigned int *)&pde, pde->pfn, 136 | addr->pt_index, addr->pt_index * 4, 137 | *(unsigned int*)&pte, pte->pfn, 138 | (pte->copy_on_write)?'C':'-', (pte->global)?'G':'-', 139 | (pte->large_page)?'L':'-', (pte->dirty)?'D':'-', 140 | (pte->accessed)?'A':'-', (pte->cache_disabled)?'N':'-', 141 | (pte->write_through)?'T':'-', (pte->owner)?'U':'K', 142 | (pte->write)?'W':'R', (pte->valid)?'V':'-' 143 | ); 144 | /* Print first 16 bytes of page */ 145 | print_hex_array(page, 16, 16); 146 | } 147 | 148 | --------------------------------------------------------------------------------