1 /*
2 * 7-Zip cracker patch for JtR. Hacked together during June of 2013 by Dhiru
3 * Kholia <dhiru at openwall.com>. Unicode support and other fixes by magnum.
4 *
5 * This software is Copyright (c) 2013 Dhiru Kholia <dhiru at openwall.com>
6 * and Copyright (c) 2013-2017 magnum, and it is hereby released to the general
7 * public under the following terms:
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted.
11 */
12
13 #if FMT_EXTERNS_H
14 extern struct fmt_main fmt_sevenzip;
15 #elif FMT_REGISTERS_H
16 john_register_one(&fmt_sevenzip);
17 #else
18
19 #include <string.h>
20
21 #include "arch.h"
22 #if !AC_BUILT
23 #define HAVE_LIBZ 1 /* legacy build has -lz in LDFLAGS */
24 #endif
25 #if HAVE_LIBZ
26 #include <zlib.h>
27 #endif
28
29 #ifdef _OPENMP
30 #include <omp.h>
31 #endif
32
33 #if !ARCH_LITTLE_ENDIAN
34 #undef SIMD_COEF_32
35 #undef SIMD_PARA_SHA256
36 #endif
37
38 #include "johnswap.h"
39 #include "misc.h"
40 #include "common.h"
41 #include "formats.h"
42 #include "params.h"
43 #include "options.h"
44 #include "aes.h"
45 #include "sha2.h"
46 #include "crc32.h"
47 #include "unicode.h"
48 #include "dyna_salt.h"
49 #include "config.h"
50 #include "lzma/LzmaDec.h"
51 #include "lzma/Lzma2Dec.h"
52 #include "simd-intrinsics.h"
53
54 #define FORMAT_LABEL "7z"
55 #define FORMAT_NAME "7-Zip"
56 #define FORMAT_TAG "$7z$"
57 #define TAG_LENGTH (sizeof(FORMAT_TAG)-1)
58 #define BENCHMARK_COMMENT " (512K iterations)"
59 #define BENCHMARK_LENGTH 7
60 #define BINARY_SIZE 0
61 #define BINARY_ALIGN 1
62 #define SALT_SIZE sizeof(struct custom_salt*)
63 #define SALT_ALIGN sizeof(struct custom_salt*)
64
65 #ifdef SIMD_COEF_32
66
67 #define NBKEYS (SIMD_COEF_32*SIMD_PARA_SHA256)
68 #define GETPOS(i,idx) ( (idx&(SIMD_COEF_32-1))*4 + ((i)&(0xffffffff-3))*SIMD_COEF_32 + (3-((i)&3)) + (unsigned int)idx/SIMD_COEF_32*SHA_BUF_SIZ*4*SIMD_COEF_32 )
69 #define HASH_IDX_IN(idx) (((unsigned int)idx&(SIMD_COEF_32-1))+(unsigned int)idx/SIMD_COEF_32*SHA_BUF_SIZ*SIMD_COEF_32)
70 #define HASH_IDX_OUT(idx) (((unsigned int)idx&(SIMD_COEF_32-1))+(unsigned int)idx/SIMD_COEF_32*8*SIMD_COEF_32)
71
72 #define ALGORITHM_NAME "SHA256 " SHA256_ALGORITHM_NAME " AES"
73 #define PLAINTEXT_LENGTH 28
74 #define MIN_KEYS_PER_CRYPT NBKEYS
75 #define MAX_KEYS_PER_CRYPT NBKEYS
76 #else
77 #define ALGORITHM_NAME "SHA256 32/" ARCH_BITS_STR " AES"
78 #define PLAINTEXT_LENGTH 125
79 #define MIN_KEYS_PER_CRYPT 1
80 #define MAX_KEYS_PER_CRYPT 1
81 #endif
82
83 #ifndef OMP_SCALE
84 #define OMP_SCALE 1 // tuned w/ MKPC for core i7
85 #endif
86
87 static struct fmt_tests sevenzip_tests[] = {
88 /* CRC checks passes for this hash (4 bytes of padding) */
89 {"$7z$128$19$0$1122$8$a264c94f2cd72bec0000000000000000$725883103$112$108$64749c0963e20c74602379ca740165b9511204619859d1914819bc427b7e5f0f8fc67f53a0b53c114f6fcf4542a28e4a9d3914b4bc76baaa616d6a7ec9efc3f051cb330b682691193e6fa48159208329460c3025fb273232b82450645f2c12a9ea38b53a2331a1d0858813c8bf25a831", "openwall"},
90 /* LZMA before CRC (9 bytes of padding) */
91 {"$7z$1$19$0$1122$8$732b59fd26896e410000000000000000$2955316379$192$183$7544a3a7ec3eb99a33d80e57907e28fb8d0e140ec85123cf90740900429136dcc8ba0692b7e356a4d4e30062da546a66b92ec04c64c0e85b22e3c9a823abef0b57e8d7b8564760611442ecceb2ca723033766d9f7c848e5d234ca6c7863a2683f38d4605322320765938049305655f7fb0ad44d8781fec1bf7a2cb3843f269c6aca757e509577b5592b60b8977577c20aef4f990d2cb665de948004f16da9bf5507bf27b60805f16a9fcc4983208297d3affc4455ca44f9947221216f58c337f$232$5d00000100", "password"},
92 /* CRC checks passes for this hash (no padding) */
93 {"$7z$0$19$0$1122$8$d1f50227759415890000000000000000$1412385885$112$112$5e5b8b734adf52a64c541a5a5369023d7cccb78bd910c0092535dfb013a5df84ac692c5311d2e7bbdc580f5b867f7b5dd43830f7b4f37e41c7277e228fb92a6dd854a31646ad117654182253706dae0c069d3f4ce46121d52b6f20741a0bb39fc61113ce14d22f9184adafd6b5333fb1", "password"},
94 /* This requires LZMA (no padding) */
95 {"$7z$1$19$0$1122$8$5fdbec1569ff58060000000000000000$2465353234$112$112$58ba7606aafc7918e3db7f6e0920f410f61f01e9c1533c40850992fee4c5e5215bc6b4ea145313d0ac065b8ec5b47d9fb895bb7f97609be46107d71e219544cfd24b52c2ecd65477f72c466915dcd71b80782b1ac46678ab7f437fd9f7b8e9d9fad54281d252de2a7ae386a65fc69eda$176$5d00000100", "password"},
96 /* Length checks */
97 {"$7z$128$19$0$1122$8$94fb9024fdd3e6c40000000000000000$3965424295$112$99$1127828817ff126bc45ff3c5225d9d0c5d00a52094909674e6ed3dc431546d9a672738f2fa07556340d604d2efd2901b9d2ac2c0686c25af9c520c137b16c50c54df8703fd0b0606fa721ad70aafb9c4e3b288ef49864e6034021969b4ce11e3b8e269a92090ccf593c6a0da06262116", ""},
98 {"$7z$128$19$0$1122$8$6fd059d516d5490f0000000000000000$460747259$112$99$af163eb5532c557efca78fbb448aa04f348cd258c94233e6669f4e5025f220274c244d4f2347a7512571d9b6015a1e1a90e281983b743da957437b33092eddb55a5bc76f3ab6c7dbabb001578d1043285f5fa791fd94dd9779b461e44cbfe869f891007335b766774ccee3813ec8cd57", "&"},
99 {"$7z$128$19$0$1122$8$6d4a12af68d83bfe0000000000000000$993697592$112$99$7c308faa36b667599ee4418435ab621884c5c115ee3b70be454fe99236422f4f2d5cd9c8fcfbe6b6b0805ee602ce8488a08f7ea14a4f5c0c060fc685bff187720a402b23a5cfe3c9c5a5ae07f91209031b8f9804ac10459e15a0158031f6c58e507401ec6e1e6de8f64d94201159432b", "&'"},
100 {"$7z$128$19$0$1122$8$7527d758a59181830000000000000000$3917710544$112$99$61a9ca9e835bd0f2dc474b34d5d89bcf8cd1bb071a984ee1dcf224174a60bcee140fcf2fde8927fe4f3f4eb4a2cc39faff73f1898ae25cc92bd02939f4317ebb173bf3b6f01eef183163ddd533ad5c076f87341bd8b86d8460c68fc390aa8df89fc4076bdfd24e157f6c07e105c07612", "&'("},
101 {"$7z$128$19$0$1122$8$68928bade860a2b80000000000000000$3235890186$112$99$4b685a569c3aed78d217bae9ec64fa06b614df55c1cb0d160563d87efe38813accb38dd7037f86cebc91751c2488769c7398dfefaf491c024f2d640dcb388a56404cd5ac475ba16b5f8206fa45d5923b3a0c8dd0f24460ccee0d93bea03ad58b8a8db502a55ba1775560b3d194f342f7", "&'()"},
102 {"$7z$128$19$0$1122$8$81931b9ba0b069820000000000000000$3094344848$112$99$fdbb2622143d25b13992b1467ce9edce4e3df8ca07535735b76e8abcb0791e384a1d5547483e19c3bd6e5a0742d29c403cfc8b3a003b285e80b350ea9157600eb91c49b329903de9ec9b17d1c95b0e136b579e165a6e80550464fa99830bfd9ee58fc14516b614ff9f84ec80e6880a36", "&'()*"},
103 {"$7z$128$19$0$1122$8$ccf696913989510d0000000000000000$1238556212$112$99$647264fbc665e73ecfe3ef7055fef0d91cb86833d6df08b2f7a3c1c89cf7cdaa09a802c8bfb2e5c6b55143a315df74d841b349fc8b43613d0f87cc90325fd56fc17ee08df7ce76cdc9cda61bd4d5632e20af3db16e921c755174f291c0aa6581844def4547380e2dd4a574435d17e1e8", "&'()*+"},
104 {"$7z$128$19$0$1122$8$d618bd3ec8bafd800000000000000000$1349785$112$99$6514e2e7468e6f0ed63796cfc0588ac2d75f024c4a0fa03778bd252d316d03e48a08ffcc0011725ad4f867e9a9666630dff4f352c59bcbadb94b9d0e2c42d653b80f480005ce868a0b1a075b2e00abd743de0867d69cdc8b56c7f9770537d50e6bb11eb0d2d7d8b6af5dd8ecb50ab553", "&'()*+,"},
105 {"$7z$128$19$0$1122$8$1c1586d191f190890000000000000000$642253888$112$99$f55cf9ab802b10a83471abe9319711ae79906cd6921365167c389470a3a8a72b0d877379daae2c24ea2258e8586f12d5036aff9ddc8e26861467b0843ffb72e4410c2be76ec111d37f875c81b244ed172f1f4765a220d830a9615787e9d07f8582146556e9c566b64897a47d18a82b36", "&'()*+,-"},
106 /* Some older versions of 7z2john.pl could generate hashes with negative CRC values. Explicitly test the support for such hashes. */
107 {"$7z$2$19$0$$8$bce330349dd1378f0000000000000000$-647422963$48$36$2c5e6c91d54bfbbbc77b9774544f35fe55fe2483f33296582b8fb5a5aae05b82b0b78ae6ee8b051d5ca4290d2e177051$32$00", "openwall"},
108 #if DEBUG
109 {"$7z$128$19$0$1122$8$0df03cbdbc73e22a0000000000000000$3194757927$112$99$df53e9d8b4e02cf2962ad87912021508a36910c399a7abc4a3a5423fa2184816af7172418eb4763924ec8b099b7ca95abdc6faac9aaa6e181ffa60b7e8bdb2bf576536ca69152e3b6b97302c796bbc9dec78db6ba7a4a58e68f8ee28f27dea26bd4f848dc3a3315e97e1463b5c171ce5", "&'()*+,-."},
110 {"$7z$128$19$0$1122$8$7785351cf9fe5dfa0000000000000000$1304801610$112$99$7b35280384726da8521fee0786ef43e0aa621394a6f015b65cbd7f1329f43c4543b8a451a0007c03a3ce3f61e639c54ede3e580600b113777822b6d562390d14ed236e5bac3d3af63ae23015148a95e7ccbc9eea653b52c606ca09ec51fd2b0c4cfc2b760fccc1fe0ccdd9ee3fcb8129", "&'()*+,-./"},
111 {"$7z$128$19$0$1122$8$70eb7f4b821cf5310000000000000000$3381356868$112$99$c26db2cb89df1237f323d92044726d03cfc7ba83115e789243c3b2570ae674d8356a23e004b103638b1ea9fe6ff5db844a1ddcaaed8a71a8d8e343f73868b4acafd34d493345439b0e0be87d2cf52eb4cceaafcff0dfaf9cf25080693ede267460320e1282b869a5f0b6c8789e769640", "&'()*+,-./0"},
112 {"$7z$128$19$0$1122$8$2ac0f1307794d8e10000000000000000$2871514580$112$99$4783d91fa72c377310654e961120e71ecdd27ec2e67366e83291daefcea03514ca9ecea031fcbd25c0759c1f242219e673cee093ef361664f18dacf85ca0620fd7092477ceeff7c548df0a475ce93278a564fe4ddb4ee2e4695cbe417a792e822204390ca5a530208a8ed51bc01f79e6", "&'()*+,-./01"},
113 {"$7z$128$19$0$1122$8$5bc4988c71cba8b70000000000000000$2815498089$112$99$0e4368dde66925e2bfac9a450291f8f817beaa891f08c4d2735d20b3147df581e2f3c53abfe2b0971186ac39280eb354ca5989f9043ad0288302d0ac59a3c8fa99d26c9619b81d22996f24eec1dba361afdd5e50060c2599a40a00c83c4ee0bc4ebe6e3126a64a743af95d9b22ee5867", "&'()*+,-./012"},
114 {"$7z$128$19$0$1122$8$33ab0ad513b7d6910000000000000000$107430285$112$99$f9f1195a4210eadc5b23f046f81c8cfaec3b90d8b6b67893f10bd9bedd0d859d0695bca5ce315cecbc2910dce27e4c1a1416675d841901c8d84846360b1919ebcba91143713c6b755758d3db64d39344da18222341818220cc43f3ee3a91cbc288f1aafe377b53def310d3b83d32aee3", "&'()*+,-./0123"},
115 {"$7z$128$19$0$1122$8$dd490a165c1b90f90000000000000000$2897354864$112$99$51efe41b67875503acebe2e199cb542a279520b468a61ba67b54612e317a84e95879a34eaad82124798f32c19f9c0786e8faaac768da5f6b2c91e3ba9f97a03a992c18b5b9b21a5f2b67ae9daeef37ec115f44bfb8b10ac3cb7862b6c024413a2ee801aa674df05e8b56bd8654f279f5", "&'()*+,-./01234"},
116 {"$7z$128$19$0$1122$8$9077cb191a5969b40000000000000000$3637063426$112$99$1e74746c59bdfe6b3f3d957493c9d5b92ba358f97e19d30e20443cb2fbac0501e07a162344ac7cf7cfa727c70a2bcf52593accc5c2c070c2331863ac76da5ad2f5de374292a87c6af67ab561f9cf71ae472ed1267d481c250f5b4d82d0ec0b2b8531db1fe4637c3f4e3a08de1b9b5418", "&'()*+,-./012345"},
117 {"$7z$128$19$0$1122$8$adc090d27b0343d30000000000000000$1147570982$112$99$ac14b9dc3751cfe6c1c719ceef3d73946fff2b0f924e06cd3177883df770e5505551bcf5598277801f46584a4f41530f50007c776d2bb91fd160148042275dfe4e420ff72244409f59c687a5bb2d0fc1bb29138689094fe40bb0f22785c63c631cd05abf4f7f3c9b6832e192e103d2f1", "&'()*+,-./0123456"},
118 {"$7z$128$19$0$1122$8$8dee69dc35517a2a0000000000000000$87427823$112$99$ea36cf8b577a0b5f31115f8550987f05f174b347a8a6433a08c013ecd816c8ecaad163c62db9bae6c57ace3c2a6ce0b36f78ad4723328cc022906400eed55e0e3685a5e8e6b369df780ee72f3d25ccd49d7f40d013052e080723dd4c0b1c75302c884ea956e3b6fd27261eb8c49dea51", "&'()*+,-./01234567"},
119 {"$7z$128$19$0$1122$8$200ce603d6f355f10000000000000000$3012105149$112$99$0ae42342f52172ad921178a25df3666e34e5a217d0afb3655088806f821d374bf522c197e59b131dbc574d4c936472f59f8892f69e47724ea52ecc5dc7d3ed734c557c9698a6f01519039714c065ad25008003c93cb7f694ee07267d5fcdebab5d149d5404023a0112faec2264d33ff6", "&'()*+,-./012345678"},
120 {"$7z$128$19$0$1122$8$a5007fc77fa5cc0b0000000000000000$1082728565$112$99$32c404c9633e9c61b76556e169695248008c51ca8f7f0f79c4a271ac6eb1d905a2622132f2f6988f9f3f5e375c592ec63d92d7b183b5801b149595ed440b23a083633de9f1cb5b6ac3238b7523b23141e686e6cbe9d4d3a28fc6489e902c17aeff6cd4cb516bef5cd5c6def78cb88ad4", "&'()*+,-./0123456789"},
121 {"$7z$128$19$0$1122$8$fd531c4e580be9a60000000000000000$1843420503$112$99$704289830b1add1c8ee6fd622ecf5b8da01988580bdb52f6269cc61c21838849d3a04299eaee15e0cae0eff9f6c3c82f71e434b3aa1c0ca824b90438c1c983130218acd128d9186e5dc2d19a8db602a0382cb60dadb4641b46fe532b799d29a4b882beaa9217f48ddccc99578617f8a0", "&'()*+,-./0123456789:"},
122 {"$7z$128$19$0$1122$8$7f94a95f71c1b0df0000000000000000$141406606$112$99$1a510a6fda9788b4f4b2274ea929044c00b61b23946bc417ead90ad64dcc9a55378f9ab74f7d693a5dcf455c00f82f6c2a885b664f4ab10c9969026714ce2773030f1c5872ca3948cd612e21b321826c2a561104d57a3ba2055f03aa9cc264821544ec4bccc41f4ac76aab97accb8f9c", "&'()*+,-./0123456789:;"},
123 {"$7z$128$19$0$1122$8$e24e93c7a9ebde080000000000000000$718561925$112$99$580bf36388526c932c22e3227b51774b6963a9c5b96fc8e2ac70a4302864fa88f50e7c00d9a79e0bca0f07a236e51200dc23435b7680e6fa99b19d790ac093af615a972f8b232686c21279234a2582f9714c5a1a2d326084158eba3e81b4f8ad40784d84baa8ddbed19f1c6603156d2c", "&'()*+,-./0123456789:;<"},
124 {"$7z$128$19$0$1122$8$6fbd519735b131710000000000000000$1248418560$112$99$cc9e3c97073d7fd37f04d4e6983b386e3ac00f6292dedb0f566dccf22cdbbb55fee8669edade383e96aa0a740e2b42aa7fddbe5831cac10828c624ee03a1a256c6e777c3d714c55296cb815c509a252b9426fe8d4566c944efe3fac5ea94910e55a390aef2c729a031e832c406049810", "&'()*+,-./0123456789:;<="},
125 {"$7z$128$19$0$1122$8$3ce1b899fc03d9c30000000000000000$1452122600$112$99$d4be60d5ab390713c7189f0dd808227c01f15f71fcf4bbccce6cb9238d6418c115eff59784d96ff8944575710a5799c7bcb761e8f1bfb7646a0e8fac3728ba4cca44fb82e5dd9f87bb26828566af64374b512fa094d35af8d743bded88b6257ec98a99b50dd225d4608b283bf035ac08", "&'()*+,-./0123456789:;<=>"},
126 {"$7z$128$19$0$1122$8$656e2285aabed25b0000000000000000$3885982465$112$99$77f2871e556e7f5278a9e896e91cd386ca8935128957d31fdce0603ea0e71c08b908a4c2d9f2d279757ced848be9482067c9d7935c88e5233aaa94a101d29908f7f015646758029d2078d25d0886bb9f0cdc0dd5136d72e90ceeea678564b199866dd8c9e5fe927102ee2dcf1cd4167f", "&'()*+,-./0123456789:;<=>?"},
127 {"$7z$128$19$0$1122$8$44ffefa48fa5a5b00000000000000000$1011653568$112$99$5d2504a1eb819218b9ad552e377d37e811ffccb64a554f404d982d209edfafb893b679cc881bbcbc606e67ffa055f712d7f140b554769511bc00321765830ea7c5db810fa2000ae7f4250b74aa61d881db66ae6f30e4c8e71887960c117b268d9934b8b5d52d4abdcb42b0e4ff40b805", "&'()*+,-./0123456789:;<=>?@"},
128 {"$7z$128$19$0$1122$8$b6e089dd0c52b6b80000000000000000$1229766981$112$99$49a8334d64d9cc7d710fe3b9c35f5d7cb0ec44d5db8a90966fbee93f85fdeeeca859c55519addb20c4628c9204dd24d1169b34dc53a2a685440fae7ed6748c172a8e9dcc42c8dffe60196818ad17a6f9314fcfd4d97cab3c18cf279df344e00fd04eaff32f29cbfcdb6832cfb69fe351", "&'()*+,-./0123456789:;<=>?@A"},
129 #endif /* DEBUG */
130 {NULL}
131 };
132
133 static int trust_padding;
134 static UTF16 (*saved_key)[PLAINTEXT_LENGTH + 1];
135 static int *saved_len;
136 static int *cracked;
137 static int new_keys;
138 static int max_kpc;
139 static unsigned char (*master)[32];
140 #ifdef SIMD_COEF_32
141 static uint32_t (*vec_in)[2][NBKEYS*16];
142 static uint32_t (*vec_out)[NBKEYS*8];
143 static int *indices;
144 #endif
145
146 static struct custom_salt {
147 dyna_salt dsalt;
148 size_t length; /* used in decryption */
149 size_t unpacksize; /* used in padding check */
150 size_t crc_len; /* used in CRC calculation */
151 int NumCyclesPower;
152 int SaltSize;
153 int ivSize;
154 int type;
155 unsigned char iv[16];
156 unsigned char salt[16];
157 unsigned int crc;
158 unsigned char props[LZMA_PROPS_SIZE];
159 unsigned char data[1];
160 } *cur_salt;
161
init(struct fmt_main * self)162 static void init(struct fmt_main *self)
163 {
164 CRC32_t crc;
165
166 omp_autotune(self, OMP_SCALE);
167
168 // allocate 1 more slot to handle the tail of vector buffer
169 max_kpc = self->params.max_keys_per_crypt + 1;
170
171 saved_key = mem_calloc(max_kpc, sizeof(*saved_key));
172 saved_len = mem_calloc(max_kpc, sizeof(*saved_len));
173 cracked = mem_calloc(max_kpc, sizeof(*cracked));
174 #ifdef SIMD_COEF_32
175 vec_in = mem_calloc_align(self->params.max_keys_per_crypt,
176 sizeof(*vec_in), MEM_ALIGN_CACHE);
177 vec_out = mem_calloc_align(self->params.max_keys_per_crypt,
178 sizeof(*vec_out), MEM_ALIGN_CACHE);
179 #endif
180 CRC32_Init(&crc);
181
182 if (options.target_enc == UTF_8)
183 self->params.plaintext_length = MIN(125, 3 * PLAINTEXT_LENGTH);
184
185 if (cfg_get_bool(SECTION_FORMATS, "7z", "TrustPadding", 0))
186 trust_padding = 1;
187 }
188
done(void)189 static void done(void)
190 {
191 MEM_FREE(cracked);
192 MEM_FREE(saved_key);
193 MEM_FREE(saved_len);
194 MEM_FREE(master);
195 #ifdef SIMD_COEF_32
196 MEM_FREE(vec_in);
197 MEM_FREE(vec_out);
198 MEM_FREE(indices);
199 #endif
200 }
201
valid(char * ciphertext,struct fmt_main * self)202 static int valid(char *ciphertext, struct fmt_main *self)
203 {
204 char *ctcopy, *keeptr, *p;
205 int type, len, NumCyclesPower;
206
207 if (strncmp(ciphertext, FORMAT_TAG, TAG_LENGTH) != 0)
208 return 0;
209
210 ctcopy = strdup(ciphertext);
211 keeptr = ctcopy;
212 ctcopy += TAG_LENGTH;
213 if ((p = strtokm(ctcopy, "$")) == NULL)
214 goto err;
215 if (strlen(p) > 3 || !isdec(p))
216 goto err;
217 type = atoi(p);
218 if (strlen(p) == 0 || type < 0 || type > 128) /* Compression type */
219 goto err;
220 if (type > 2 /* LZMA or LZMA2 */
221 #if HAVE_LIBZ
222 && type != 7 /* deflate */
223 #endif
224 && type != 128) /* none */
225 goto err;
226 if ((p = strtokm(NULL, "$")) == NULL) /* NumCyclesPower */
227 goto err;
228 if (strlen(p) > 2)
229 goto err;
230 if (!isdec(p))
231 goto err;
232 NumCyclesPower = atoi(p);
233 if (NumCyclesPower > 24 || NumCyclesPower < 1)
234 goto err;
235 if ((p = strtokm(NULL, "$")) == NULL) /* salt length */
236 goto err;
237 if (!isdec(p))
238 goto err;
239 len = atoi(p);
240 if (len > 16) /* salt length */
241 goto err;
242 if ((p = strtokm(NULL, "$")) == NULL) /* salt */
243 goto err;
244 if ((p = strtokm(NULL, "$")) == NULL) /* iv length */
245 goto err;
246 if (strlen(p) > 2)
247 goto err;
248 if (!isdec(p))
249 goto err;
250 len = atoi(p);
251 if (len > 16) /* iv length */
252 goto err;
253 if ((p = strtokm(NULL, "$")) == NULL) /* iv */
254 goto err;
255 if (!ishexlc(p))
256 goto err;
257 if (strlen(p) / 2 > len && strcmp(p+len*2, "0000000000000000"))
258 goto err;
259 if ((p = strtokm(NULL, "$")) == NULL) /* crc */
260 goto err;
261 if (!isdecu(p) && !isdec_negok(p))
262 goto err;
263 if ((p = strtokm(NULL, "$")) == NULL) /* data length */
264 goto err;
265 if (!isdec(p))
266 goto err;
267 len = atoi(p);
268 if ((p = strtokm(NULL, "$")) == NULL) /* unpacksize */
269 goto err;
270 if (!isdec(p)) /* no way to validate, other than atoi() works for it */
271 goto err;
272 if ((p = strtokm(NULL, "$")) == NULL) /* data */
273 goto err;
274 if (strlen(p) / 2 != len) /* validates data_len atoi() */
275 goto err;
276 if (!ishexlc(p))
277 goto err;
278 if (type && type != 128) {
279 if ((p = strtokm(NULL, "$")) == NULL) /* CRC len */
280 goto err;
281 if (!isdec(p))
282 goto err;
283 if (type < 7) {
284 if ((p = strtokm(NULL, "$")) == NULL) /* Coder props */
285 goto err;
286 if (!ishexlc(p))
287 goto err;
288 if (type == 1 && strlen(p) != 10)
289 goto err;
290 else if (type == 2 && strlen(p) != 2)
291 goto err;
292 }
293 }
294
295 MEM_FREE(keeptr);
296 return 1;
297
298 err:
299 MEM_FREE(keeptr);
300 return 0;
301 }
302
get_salt(char * ciphertext)303 static void *get_salt(char *ciphertext)
304 {
305 struct custom_salt cs;
306 struct custom_salt *psalt;
307 static void *ptr;
308 char *ctcopy = strdup(ciphertext);
309 char *keeptr = ctcopy;
310 int i;
311 char *p;
312
313 if (!ptr)
314 ptr = mem_alloc_tiny(sizeof(struct custom_salt*),
315 sizeof(struct custom_salt*));
316 memset(&cs, 0, sizeof(cs));
317 ctcopy += TAG_LENGTH;
318 p = strtokm(ctcopy, "$");
319 cs.type = atoi(p);
320 p = strtokm(NULL, "$");
321 cs.NumCyclesPower = atoi(p);
322 p = strtokm(NULL, "$");
323 cs.SaltSize = atoi(p);
324 p = strtokm(NULL, "$"); /* salt */
325 p = strtokm(NULL, "$");
326 cs.ivSize = atoi(p);
327 p = strtokm(NULL, "$"); /* iv */
328 for (i = 0; i < cs.ivSize; i++)
329 cs.iv[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16
330 + atoi16[ARCH_INDEX(p[i * 2 + 1])];
331 p = strtokm(NULL, "$"); /* crc */
332 if (p[0] == '-')
333 cs.crc = (unsigned int)atoi(p); /* signed function, cast to unsigned */
334 else
335 cs.crc = atou(p); /* unsigned function */
336 p = strtokm(NULL, "$");
337 cs.length = atoll(p);
338 psalt = malloc(sizeof(struct custom_salt) + cs.length - 1);
339 memcpy(psalt, &cs, sizeof(cs));
340 p = strtokm(NULL, "$");
341 psalt->unpacksize = atoll(p);
342 p = strtokm(NULL, "$"); /* data */
343 for (i = 0; i < psalt->length; i++)
344 psalt->data[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16
345 + atoi16[ARCH_INDEX(p[i * 2 + 1])];
346 if (cs.type && cs.type != 128) {
347 p = strtokm(NULL, "$"); /* CRC length */
348 psalt->crc_len = atoi(p);
349 if (cs.type < 7) {
350 p = strtokm(NULL, "$"); /* Coder properties */
351 for (i = 0; p[i * 2] ; i++)
352 psalt->props[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16
353 + atoi16[ARCH_INDEX(p[i * 2 + 1])];
354 }
355 }
356
357 MEM_FREE(keeptr);
358 psalt->dsalt.salt_cmp_offset = SALT_CMP_OFF(struct custom_salt, length);
359 psalt->dsalt.salt_cmp_size = SALT_CMP_SIZE(struct custom_salt, length, data, psalt->length);
360 psalt->dsalt.salt_alloc_needs_free = 1;
361
362 memcpy(ptr, &psalt, sizeof(void*));
363 return ptr;
364 }
365
set_salt(void * salt)366 static void set_salt(void *salt)
367 {
368 static int old_power;
369
370 cur_salt = *((struct custom_salt**)salt);
371
372 if (old_power != cur_salt->NumCyclesPower) {
373 new_keys = 1;
374 old_power = cur_salt->NumCyclesPower;
375 }
376 }
377
salt_compare(const void * x,const void * y)378 static int salt_compare(const void *x, const void *y)
379 {
380 int c;
381 const struct custom_salt *s1 = *((struct custom_salt**)x);
382 const struct custom_salt *s2 = *((struct custom_salt**)y);
383
384 // we had to make the salt order deterministic, so that intersalt-restore works
385 if (s1->NumCyclesPower != s2->NumCyclesPower)
386 return (s1->NumCyclesPower - s2->NumCyclesPower);
387 c = memcmp(s1->salt, s2->salt, 16);
388 if (c) return c;
389 return memcmp(s1->iv, s2->iv, 16);
390 }
391
SzAlloc(void * p,size_t size)392 static void *SzAlloc(void *p, size_t size) { return mem_alloc(size); }
SzFree(void * p,void * address)393 static void SzFree(void *p, void *address) { MEM_FREE(address) };
394
sevenzip_decrypt(unsigned char * derived_key)395 static int sevenzip_decrypt(unsigned char *derived_key)
396 {
397 unsigned char *out = NULL;
398 AES_KEY akey;
399 unsigned char iv[16];
400 union {
401 unsigned char crcc[4];
402 unsigned int crci;
403 } _crc_out;
404 unsigned char *crc_out = _crc_out.crcc;
405 unsigned int ccrc;
406 CRC32_t crc;
407 int i;
408 int nbytes, pad_size;
409 size_t crc_len = cur_salt->unpacksize;
410 size_t aes_len = cur_salt->crc_len ?
411 (cur_salt->crc_len * 11 + 150) / 160 * 16 : crc_len;
412
413 pad_size = nbytes = cur_salt->length - cur_salt->unpacksize;
414
415 /*
416 * Early rejection (only decrypt last 16 bytes). We don't seem to
417 * be able to trust this, see #2532, so we only do it for truncated
418 * hashes (it's the only thing we can do!).
419 */
420 if ((cur_salt->type == 0x80 || trust_padding) &&
421 pad_size > 0 && cur_salt->length >= 32) {
422 uint8_t buf[16];
423
424 memcpy(iv, cur_salt->data + cur_salt->length - 32, 16);
425 AES_set_decrypt_key(derived_key, 256, &akey);
426 AES_cbc_encrypt(cur_salt->data + cur_salt->length - 16, buf,
427 16, &akey, iv, AES_DECRYPT);
428 i = 15;
429 while (nbytes > 0) {
430 if (buf[i] != 0)
431 return 0;
432 nbytes--;
433 i--;
434 }
435
436 if (cur_salt->type == 0x80) /* We only have truncated data */
437 return 1;
438 }
439
440 /* Complete decryption, or partial if possible */
441 aes_len = nbytes ? cur_salt->length : MIN(aes_len, cur_salt->length);
442 out = mem_alloc(aes_len);
443 memcpy(iv, cur_salt->iv, 16);
444 AES_set_decrypt_key(derived_key, 256, &akey);
445 AES_cbc_encrypt(cur_salt->data, out, aes_len, &akey, iv, AES_DECRYPT);
446
447 /* Padding check unless we already did the quick one */
448 if (trust_padding && nbytes) {
449 i = cur_salt->length - 1;
450 while (nbytes > 0) {
451 if (out[i] != 0)
452 goto exit_bad;
453 nbytes--;
454 i--;
455 }
456 }
457
458 if (cur_salt->type == 0x80) /* We only have truncated data */
459 goto exit_good;
460
461 /* Optional decompression before CRC */
462 if (cur_salt->type == 1) {
463 ISzAlloc st_alloc = {SzAlloc, SzFree};
464 ELzmaStatus status;
465 size_t in_size = aes_len;
466 uint8_t *new_out;
467 SRes rc;
468 size_t out_size = cur_salt->crc_len;
469
470 new_out = mem_alloc(out_size);
471 if ((rc = LzmaDecode(new_out, &out_size, out, &in_size,
472 cur_salt->props, LZMA_PROPS_SIZE,
473 LZMA_FINISH_ANY, &status,
474 &st_alloc)) == SZ_OK &&
475 out_size == cur_salt->crc_len) {
476 MEM_FREE(out);
477 out = new_out;
478 crc_len = cur_salt->crc_len;
479 } else {
480 MEM_FREE(new_out);
481 goto exit_bad;
482 }
483 }
484 else if (cur_salt->type == 2) {
485 Byte prop = cur_salt->props[0];
486 ISzAlloc st_alloc = {SzAlloc, SzFree};
487 ELzmaStatus status;
488 size_t in_size = aes_len;
489 uint8_t *new_out;
490 SRes rc;
491 size_t out_size = cur_salt->crc_len;
492
493 new_out = mem_alloc(out_size);
494 if ((rc = Lzma2Decode((Byte*)new_out, &out_size, out, &in_size,
495 prop, LZMA_FINISH_ANY, &status,
496 &st_alloc)) == SZ_OK &&
497 out_size == cur_salt->crc_len) {
498 MEM_FREE(out);
499 out = new_out;
500 crc_len = cur_salt->crc_len;
501 } else {
502 MEM_FREE(new_out);
503 goto exit_bad;
504 }
505 }
506 #if HAVE_LIBZ
507 else if (cur_salt->type == 7) {
508 uint8_t *new_out;
509 int ret;
510 z_stream inf_stream;
511
512 new_out = mem_alloc(cur_salt->crc_len);
513
514 inf_stream.zalloc = Z_NULL;
515 inf_stream.zfree = Z_NULL;
516 inf_stream.opaque = Z_NULL;
517
518 inf_stream.avail_in = aes_len;
519 inf_stream.next_in = out;
520
521 inf_stream.avail_out = cur_salt->crc_len;
522 inf_stream.next_out = new_out;
523
524 inflateInit2(&inf_stream, -MAX_WBITS);
525
526 ret = inflate(&inf_stream, Z_NO_FLUSH);
527
528 inflateEnd(&inf_stream);
529
530 if (ret == Z_OK || ret == Z_STREAM_END) {
531 MEM_FREE(out);
532 out = new_out;
533 crc_len = cur_salt->crc_len;
534 } else {
535 MEM_FREE(new_out);
536 goto exit_bad;
537 }
538 }
539 #endif
540
541 /* CRC test */
542 CRC32_Init(&crc);
543 CRC32_Update(&crc, out, crc_len);
544 CRC32_Final(crc_out, crc);
545 ccrc = _crc_out.crci; /* computed CRC */
546 #if !ARCH_LITTLE_ENDIAN
547 ccrc = JOHNSWAP(ccrc);
548 #endif
549 if (ccrc == cur_salt->crc)
550 goto exit_good;
551
552 exit_bad:
553 MEM_FREE(out);
554 return 0;
555
556 exit_good:
557 MEM_FREE(out);
558 return 1;
559 }
560
561 #ifdef SIMD_COEF_32
sevenzip_kdf(int buf_idx,int * indices,unsigned char * master)562 static void sevenzip_kdf(int buf_idx, int *indices, unsigned char *master)
563 {
564 int i, j;
565 long long round, rounds = (long long) 1 << cur_salt->NumCyclesPower;
566 uint32_t (*buf_in)[NBKEYS*16] = vec_in[buf_idx];
567 uint32_t *buf_out = vec_out[buf_idx];
568 int pw_len = saved_len[indices[0]];
569 int tot_len = (pw_len + 8)*rounds;
570 int acc_len = 0;
571 #if !ARCH_LITTLE_ENDIAN
572 unsigned char temp[8] = { 0,0,0,0,0,0,0,0 };
573 #endif
574
575 int cur_buf = 0;
576 int fst_blk = 1;
577
578 // it's assumed rounds is divisible by 64
579 for (round = 0; round < rounds; ++round) {
580 // copy password to vector buffer
581 for (i = 0; i < NBKEYS; ++i) {
582 UTF16 *buf = saved_key[indices[i]];
583 for (j = 0; j < pw_len; ++j) {
584 int len = acc_len + j;
585 char *in = (char*)buf_in[(len & 64)>>6];
586 in[GETPOS(len%64, i)] = ((char*)buf)[j];
587 }
588
589 for (j = 0; j < 8; ++j) {
590 int len = acc_len + pw_len + j;
591 char *in = (char*)buf_in[(len & 64)>>6];
592 #if ARCH_LITTLE_ENDIAN
593 in[GETPOS(len%64, i)] = ((char*)&round)[j];
594 #else
595 in[GETPOS(len%64, i)] = temp[j];
596 #endif
597 }
598 }
599 #if !ARCH_LITTLE_ENDIAN
600 for (j = 0; j < 8; j++)
601 if (++(temp[j]) != 0)
602 break;
603 #endif
604 acc_len += (pw_len + 8);
605
606 // swap out and compute digest on the filled buffer
607 if ((acc_len & 64) != (cur_buf << 6)) {
608 if (fst_blk)
609 SIMDSHA256body(buf_in[cur_buf], buf_out, NULL, SSEi_MIXED_IN);
610 else
611 SIMDSHA256body(buf_in[cur_buf], buf_out, buf_out, SSEi_MIXED_IN | SSEi_RELOAD);
612 fst_blk = 0;
613 cur_buf = 1 - cur_buf;
614 }
615 }
616
617 // padding
618 memset(buf_in[0], 0, sizeof(buf_in[0]));
619 for (i = 0; i < NBKEYS; ++i) {
620 buf_in[0][HASH_IDX_IN(i)] = (0x80U << 24);
621 buf_in[0][HASH_IDX_IN(i) + 15*SIMD_COEF_32] = tot_len*8;
622 }
623 SIMDSHA256body(buf_in[0], buf_out, buf_out, SSEi_MIXED_IN | SSEi_RELOAD);
624
625 // copy out result
626 for (i = 0; i < NBKEYS; ++i) {
627 uint32_t *m = (uint32_t*)&master[i*32];
628 for (j = 0; j < 32/4; ++j)
629 m[j] = JOHNSWAP(buf_out[HASH_IDX_OUT(i) + j*SIMD_COEF_32]);
630 }
631 }
632 #else
sevenzip_kdf(int index,unsigned char * master)633 static void sevenzip_kdf(int index, unsigned char *master)
634 {
635 long long rounds = (long long) 1 << cur_salt->NumCyclesPower;
636 long long round;
637 #if !ARCH_LITTLE_ENDIAN
638 int i;
639 unsigned char temp[8] = { 0,0,0,0,0,0,0,0 };
640 #endif
641 SHA256_CTX sha;
642
643 /* kdf */
644 SHA256_Init(&sha);
645 for (round = 0; round < rounds; round++) {
646 if (cur_salt->SaltSize)
647 SHA256_Update(&sha, cur_salt->salt, cur_salt->SaltSize);
648 SHA256_Update(&sha, (char*)saved_key[index], saved_len[index]);
649 #if ARCH_LITTLE_ENDIAN
650 SHA256_Update(&sha, (char*)&round, 8);
651 #else
652 SHA256_Update(&sha, temp, 8);
653 for (i = 0; i < 8; i++)
654 if (++(temp[i]) != 0)
655 break;
656 #endif
657 }
658 SHA256_Final(master, &sha);
659 }
660 #endif
661
crypt_all(int * pcount,struct db_salt * salt)662 static int crypt_all(int *pcount, struct db_salt *salt)
663 {
664 const int count = *pcount;
665 int index = 0;
666 #ifdef SIMD_COEF_32
667 static int tot_todo;
668 int len;
669
670 /* Tricky formula, see GitHub #1692 :-) */
671 if (!indices)
672 indices = mem_alloc((max_kpc + MIN(PLAINTEXT_LENGTH + 1, max_kpc) *
673 (NBKEYS - 1)) * sizeof(int));
674 if (!master)
675 master = mem_alloc((max_kpc + MIN(PLAINTEXT_LENGTH + 1, max_kpc) *
676 (NBKEYS - 1)) * sizeof(*master));
677 #else
678 if (!master)
679 master = mem_alloc(max_kpc * sizeof(*master));
680 #endif
681
682 #ifdef SIMD_COEF_32
683 if (new_keys) {
684 // sort passwords by length
685 tot_todo = 0;
686 for (len = 0; len <= PLAINTEXT_LENGTH*2; len += 2) {
687 for (index = 0; index < count; ++index) {
688 if (saved_len[index] == len)
689 indices[tot_todo++] = index;
690 }
691 while (tot_todo % NBKEYS)
692 indices[tot_todo++] = count;
693 }
694 }
695
696 #ifdef _OPENMP
697 #pragma omp parallel for
698 #endif
699 for (index = 0; index < tot_todo; index += NBKEYS) {
700 int j;
701
702 if (new_keys)
703 sevenzip_kdf(index/NBKEYS, indices + index, master[index]);
704
705 /* do decryption and checks */
706 for (j = 0; j < NBKEYS; ++j) {
707 cracked[indices[index + j]] = sevenzip_decrypt(master[index + j]);
708 }
709 }
710 #else
711 #ifdef _OPENMP
712 #pragma omp parallel for
713 #endif
714 for (index = 0; index < count; index++) {
715 /* derive key */
716 if (new_keys)
717 sevenzip_kdf(index, master[index]);
718
719 /* do decryption and checks */
720 cracked[index] = sevenzip_decrypt(master[index]);
721 }
722 #endif // SIMD_COEF_32
723 new_keys = 0;
724
725 return count;
726 }
727
cmp_all(void * binary,int count)728 static int cmp_all(void *binary, int count)
729 {
730 int index;
731 for (index = 0; index < count; index++)
732 if (cracked[index])
733 return 1;
734 return 0;
735 }
736
cmp_one(void * binary,int index)737 static int cmp_one(void *binary, int index)
738 {
739 return cracked[index];
740 }
741
cmp_exact(char * source,int index)742 static int cmp_exact(char *source, int index)
743 {
744 return 1;
745 }
746
sevenzip_set_key(char * key,int index)747 static void sevenzip_set_key(char *key, int index)
748 {
749 /* Convert key to utf-16-le format (--encoding aware) */
750 int len;
751 len = enc_to_utf16(saved_key[index], PLAINTEXT_LENGTH, (UTF8*)key, strlen(key));
752
753 if (len <= 0)
754 len = strlen16(saved_key[index]);
755 len *= 2;
756 saved_len[index] = len;
757
758 new_keys = 1;
759 }
760
get_key(int index)761 static char *get_key(int index)
762 {
763 return (char*)utf16_to_enc(saved_key[index]);
764 }
765
iteration_count(void * salt)766 static unsigned int iteration_count(void *salt)
767 {
768 struct custom_salt *my_salt;
769
770 my_salt = *((struct custom_salt **)salt);
771 return (unsigned int)(1 << my_salt->NumCyclesPower);
772 }
773
padding_size(void * salt)774 static unsigned int padding_size(void *salt)
775 {
776 struct custom_salt *my_salt;
777
778 my_salt = *((struct custom_salt **)salt);
779 return my_salt->length - my_salt->unpacksize;
780 }
781
compression_type(void * salt)782 static unsigned int compression_type(void *salt)
783 {
784 struct custom_salt *my_salt;
785
786 my_salt = *((struct custom_salt **)salt);
787 return my_salt->type;
788 }
789
790 struct fmt_main fmt_sevenzip = {
791 {
792 FORMAT_LABEL,
793 FORMAT_NAME,
794 ALGORITHM_NAME,
795 BENCHMARK_COMMENT,
796 BENCHMARK_LENGTH,
797 0,
798 PLAINTEXT_LENGTH,
799 BINARY_SIZE,
800 BINARY_ALIGN,
801 SALT_SIZE,
802 SALT_ALIGN,
803 MIN_KEYS_PER_CRYPT,
804 MAX_KEYS_PER_CRYPT,
805 FMT_CASE | FMT_8_BIT | FMT_OMP | FMT_UNICODE | FMT_ENC | FMT_DYNA_SALT | FMT_HUGE_INPUT,
806 {
807 "iteration count",
808 "padding size",
809 "compression type",
810 },
811 { FORMAT_TAG },
812 sevenzip_tests
813 }, {
814 init,
815 done,
816 fmt_default_reset,
817 fmt_default_prepare,
818 valid,
819 fmt_default_split,
820 fmt_default_binary,
821 get_salt,
822 {
823 iteration_count,
824 padding_size,
825 compression_type,
826 },
827 fmt_default_source,
828 {
829 fmt_default_binary_hash
830 },
831 fmt_default_salt_hash,
832 salt_compare,
833 set_salt,
834 sevenzip_set_key,
835 get_key,
836 fmt_default_clear_keys,
837 crypt_all,
838 {
839 fmt_default_get_hash
840 },
841 cmp_all,
842 cmp_one,
843 cmp_exact
844 }
845 };
846
847 #endif /* plugin stanza */
848