void alter_endianity_w(void * _x, unsigned int count) { int i = -1; ARCH_WORD_32 * x = (ARCH_WORD_32 *) _x; #if ARCH_ALLOWS_UNALIGNED while (++i < (int) count) { x[i] = JOHNSWAP(x[i]); } #else unsigned char *cpX, c; if (is_aligned(x, sizeof(ARCH_WORD_32))) { // we are in alignment. while (++i < (int) count) { x[i] = JOHNSWAP(x[i]); } return; } // non-aligned data :( cpX = (unsigned char *) x; while (++i < (int) count) { c = *cpX; *cpX = cpX[3]; cpX[3] = c; c = cpX[1]; cpX[1] = cpX[2]; cpX[2] = c; cpX += 4; } #endif }
static void set_key(char *key, int index) { int len; #ifdef SIMD_COEF_32 ARCH_WORD_32 *ipadp = (ARCH_WORD_32*)&ipad[GETPOS(3, index)]; ARCH_WORD_32 *opadp = (ARCH_WORD_32*)&opad[GETPOS(3, index)]; const ARCH_WORD_32 *keyp = (ARCH_WORD_32*)key; unsigned int temp; len = strlen(key); memcpy(saved_plain[index], key, len); saved_plain[index][len] = 0; if (len > PAD_SIZE) { unsigned char k0[BINARY_SIZE]; SHA256_CTX ctx; int i; SHA256_Init(&ctx); SHA256_Update(&ctx, key, len); SHA256_Final(k0, &ctx); keyp = (unsigned int*)k0; for(i = 0; i < BINARY_SIZE / 4; i++, ipadp += SIMD_COEF_32, opadp += SIMD_COEF_32) { temp = JOHNSWAP(*keyp++); *ipadp ^= temp; *opadp ^= temp; } } else while(((temp = JOHNSWAP(*keyp++)) & 0xff000000)) { if (!(temp & 0x00ff0000) || !(temp & 0x0000ff00)) { ((unsigned short*)ipadp)[1] ^= (unsigned short)(temp >> 16); ((unsigned short*)opadp)[1] ^= (unsigned short)(temp >> 16); break; } *ipadp ^= temp; *opadp ^= temp; if (!(temp & 0x000000ff)) break; ipadp += SIMD_COEF_32; opadp += SIMD_COEF_32; }
static void *get_binary(char *ciphertext) { static union { unsigned char c[MAX_BINARY_SIZE]; uint32_t dummy; } buf; unsigned char *out = buf.c; char *p; int i, len; char delim; delim = strchr(ciphertext, '.') ? '.' : '$'; p = strrchr(ciphertext, delim) + 1; len = strlen(p) / 2; for (i = 0; i < len && *p; i++) { out[i] = (atoi16[ARCH_INDEX(*p)] << 4) | atoi16[ARCH_INDEX(p[1])]; p += 2; } #if !ARCH_LITTLE_ENDIAN for (i = 0; i < len/sizeof(uint32_t); ++i) { ((uint32_t*)out)[i] = JOHNSWAP(((uint32_t*)out)[i]); } #endif #if 0 dump_stuff_msg(__FUNCTION__, out, BINARY_SIZE); #endif return out; }
static int crypt_all(int *pcount, struct db_salt *salt) { const int count = *pcount; int index = 0; #ifdef _OPENMP #pragma omp parallel for for (index = 0; index < count; index++) #endif { uint32_t block[16] = { 0 }; int len = saved_len[index]; MD5_CTX ctx; MD5_Init(&ctx); // key + keyfill memcpy(block, saved_key[index], len); PUTCHAR(block, len, 0x80); block[14] = len << 3; #if (ARCH_LITTLE_ENDIAN==0) block[14] = JOHNSWAP(block[14]); #endif MD5_Update(&ctx, (unsigned char*)block, 64); // data MD5_Update(&ctx, cur_salt->salt, cur_salt->length); // key (again) MD5_Update(&ctx, saved_key[index], len); MD5_Final((unsigned char*)crypt_out[index], &ctx); } return count; }
static void hmac_sha256(uint8_t * pass, uint8_t passlen, uint8_t * salt, uint32_t saltlen, uint32_t add, uint64_t * ret) { uint8_t i, ipad[64], opad[64]; SHA256_CTX ctx; memset(ipad, 0x36, 64); memset(opad, 0x5c, 64); for (i = 0; i < passlen; i++) { ipad[i] ^= pass[i]; opad[i] ^= pass[i]; } SHA256_Init(&ctx); SHA256_Update(&ctx, ipad, 64); SHA256_Update(&ctx, salt, saltlen); if (add > 0) { #if ARCH_LITTLE_ENDIAN add = JOHNSWAP(add); #endif SHA256_Update(&ctx, &add, 4); } SHA256_Final((uint8_t *) ret, &ctx); SHA256_Init(&ctx); SHA256_Update(&ctx, opad, 64); SHA256_Update(&ctx, (uint8_t *) ret, 32); SHA256_Final((uint8_t *) ret, &ctx); }
static void set_key(char *key, int index) { #ifdef SIMD_COEF_32 const ARCH_WORD_32 *wkey = (ARCH_WORD_32*)key; ARCH_WORD_32 *keybuffer = &((ARCH_WORD_32*)saved_key)[(index&(SIMD_COEF_32-1)) + (unsigned int)index/SIMD_COEF_32*SHA_BUF_SIZ*SIMD_COEF_32]; ARCH_WORD_32 *keybuf_word = keybuffer; unsigned int len; ARCH_WORD_32 temp; len = 0; while((unsigned char)(temp = *wkey++)) { if (!(temp & 0xff00)) { *keybuf_word = JOHNSWAP((temp & 0xff) | (0x80 << 8)); len++; goto key_cleaning; } if (!(temp & 0xff0000)) { *keybuf_word = JOHNSWAP((temp & 0xffff) | (0x80 << 16)); len+=2; goto key_cleaning; } if (!(temp & 0xff000000)) { *keybuf_word = JOHNSWAP(temp | (0x80 << 24)); len+=3; goto key_cleaning; } *keybuf_word = JOHNSWAP(temp); len += 4; keybuf_word += SIMD_COEF_32; } *keybuf_word = 0x80000000; key_cleaning: keybuf_word += SIMD_COEF_32; while(*keybuf_word) { *keybuf_word = 0; keybuf_word += SIMD_COEF_32; } saved_len[index] = len; #else strnzcpy(saved_key[index], key, PLAINTEXT_LENGTH + 1); #endif }
static int crypt_all(int *pcount, struct db_salt *salt) { const int count = *pcount; int index = 0; #ifdef _OPENMP #pragma omp parallel for for (index = 0; index < count; index += MAX_KEYS_PER_CRYPT) #endif { unsigned char master[MAX_KEYS_PER_CRYPT][32]; unsigned char output[1024]; unsigned char *iv_in; unsigned char iv_out[16]; int size,i; int page_sz = 1008; /* 1024 - strlen(SQLITE_FILE_HEADER) */ int reserve_sz = 16; /* for HMAC off case */ AES_KEY akey; #ifdef SIMD_COEF_32 int len[MAX_KEYS_PER_CRYPT]; unsigned char *pin[MAX_KEYS_PER_CRYPT], *pout[MAX_KEYS_PER_CRYPT]; for (i = 0; i < MAX_KEYS_PER_CRYPT; ++i) { len[i] = strlen(saved_key[i+index]); pin[i] = (unsigned char*)saved_key[i+index]; pout[i] = master[i]; } pbkdf2_sha1_sse((const unsigned char **)pin, len, cur_salt->salt, 16, ITERATIONS, pout, 32, 0); #else pbkdf2_sha1((unsigned char *)saved_key[index], strlen(saved_key[index]), cur_salt->salt, 16, ITERATIONS, master[0], 32, 0); #if !ARCH_LITTLE_ENDIAN for (i = 0; i < 32/sizeof(ARCH_WORD_32); ++i) { ((ARCH_WORD_32*)master[0])[i] = JOHNSWAP(((ARCH_WORD_32*)master[0])[i]); } #endif #endif for (i = 0; i < MAX_KEYS_PER_CRYPT; ++i) { memcpy(output, SQLITE_FILE_HEADER, FILE_HEADER_SZ); size = page_sz - reserve_sz; iv_in = cur_salt->data + size + 16; memcpy(iv_out, iv_in, 16); if (AES_set_decrypt_key(master[i], 256, &akey) < 0) { fprintf(stderr, "AES_set_decrypt_key failed!\n"); } /* decrypting 24 bytes is enough */ AES_cbc_encrypt(cur_salt->data + 16, output + 16, 24, &akey, iv_out, AES_DECRYPT); if (verify_page(output) == 0) { cracked[index+i] = 1; } else cracked[index+i] = 0; } } return count; }
static void set_key(char *key, int index) { const ARCH_WORD_32 *wkey = (ARCH_WORD_32*)key; ARCH_WORD_32 *keybuffer = &((ARCH_WORD_32*)saved_key)[(index&(SIMD_COEF_32-1)) + (unsigned int)index/SIMD_COEF_32*SHA_BUF_SIZ*SIMD_COEF_32]; ARCH_WORD_32 *keybuf_word = keybuffer; unsigned int len; ARCH_WORD_32 temp; len = 0; while((unsigned char)(temp = *wkey++)) { if (!(temp & 0xff00)) { *keybuf_word = JOHNSWAP((temp & 0xff) | (0x80 << 8)); len++; goto key_cleaning; } if (!(temp & 0xff0000)) { *keybuf_word = JOHNSWAP((temp & 0xffff) | (0x80 << 16)); len+=2; goto key_cleaning; } if (!(temp & 0xff000000)) { *keybuf_word = JOHNSWAP(temp | (0x80 << 24)); len+=3; goto key_cleaning; } *keybuf_word = JOHNSWAP(temp); len += 4; keybuf_word += SIMD_COEF_32; } *keybuf_word = 0x80000000; key_cleaning: keybuf_word += SIMD_COEF_32; while(*keybuf_word) { *keybuf_word = 0; keybuf_word += SIMD_COEF_32; } keybuffer[15*SIMD_COEF_32] = len << 3; }
__inline__ #endif #endif /* * This function is loosely based on JimF's check_inflate_CODE2() from * pkzip_fmt. Together with the other bit-checks, we are rejecting over 96% * of the candidates without resorting to a slow full check (which in turn * may reject semi-early, especially if it's a PPM block) * * Input is first 16 bytes of RAR buffer decrypted, as-is. It also contain the * first 2 bits, which have already been decoded, and have told us we had an * LZ block (RAR always use dynamic Huffman table) and keepOldTable was not set. * * RAR use 20 x (4 bits length, optionally 4 bits zerocount), and reversed * byte order. */ static int check_huffman(unsigned char *next) { unsigned int bits, hold, i; int left; unsigned int ncount[4]; unsigned char *count = (unsigned char*)ncount; unsigned char bit_length[20]; unsigned char *was = next; hold = JOHNSWAP(*(unsigned int*)next); next += 4; // we already have the first 32 bits hold <<= 2; // we already processed 2 bits, PPM and keepOldTable bits = 32 - 2; /* First, read 20 pairs of (bitlength[, zerocount]) */ for (i=0 ; i < 20 ; i++) { int length, zero_count; length = hold >> 28; ADD_BITS(4); if (length == 15) { zero_count = hold >> 28; ADD_BITS(4); if (zero_count == 0) { bit_length[i] = 15; } else { zero_count += 2; while (zero_count-- > 0 && i < sizeof(bit_length) / sizeof(bit_length[0])) bit_length[i++] = 0; i--; } } else {
static int crypt_all(int *pcount, struct db_salt *salt) { const int count = *pcount; int index = 0; #ifdef _OPENMP #pragma omp parallel for for (index = 0; index < count; index += MAX_KEYS_PER_CRYPT) #endif { #ifdef SIMD_COEF_32 unsigned char master[MAX_KEYS_PER_CRYPT][32]; int lens[MAX_KEYS_PER_CRYPT], i; unsigned char *pin[MAX_KEYS_PER_CRYPT], *pout[MAX_KEYS_PER_CRYPT]; for (i = 0; i < MAX_KEYS_PER_CRYPT; ++i) { lens[i] = strlen(saved_key[i+index]); pin[i] = (unsigned char*)saved_key[i+index]; pout[i] = master[i]; } pbkdf2_sha1_sse((const unsigned char **)pin, lens, cur_salt->data, 16, cur_salt->iter, pout, 32, 0); for (i = 0; i < MAX_KEYS_PER_CRYPT; ++i) { if(blockchain_decrypt(master[i], cur_salt->data) == 0) cracked[i+index] = 1; else cracked[i+index] = 0; } #else unsigned char master[32]; pbkdf2_sha1((unsigned char *)saved_key[index], strlen(saved_key[index]), cur_salt->data, 16, cur_salt->iter, master, 32, 0); #if !ARCH_LITTLE_ENDIAN { int i; for (i = 0; i < 32/sizeof(ARCH_WORD_32); ++i) { ((ARCH_WORD_32*)master)[i] = JOHNSWAP(((ARCH_WORD_32*)master)[i]); } } #endif if(blockchain_decrypt(master, cur_salt->data) == 0) cracked[index] = 1; else cracked[index] = 0; #endif } return count; }
/* Check the FULL binary, just for good measure. There is not a chance we'll have a false positive here but this function is not performance critical. */ static int cmp_exact(char *source, int index) { int i = 0, len, result; char *p, *key = get_key(index); char delim; unsigned char *binary, *crypt; delim = strchr(source, '.') ? '.' : '$'; p = strrchr(source, delim) + 1; len = strlen(p) / 2; if (len == BINARY_SIZE) return 1; binary = mem_alloc(len); crypt = mem_alloc(len); while (*p) { binary[i++] = (atoi16[ARCH_INDEX(*p)] << 4) | atoi16[ARCH_INDEX(p[1])]; p += 2; } #if !ARCH_LITTLE_ENDIAN for (i = 0; i < len/sizeof(uint32_t); ++i) { ((uint32_t*)binary)[i] = JOHNSWAP(((uint32_t*)binary)[i]); } #endif pbkdf2_sha1((const unsigned char*)key, strlen(key), cur_salt->salt, cur_salt->length, cur_salt->iterations, crypt, len, 0); result = !memcmp(binary, crypt, len); #if 0 dump_stuff_msg("hash binary", binary, len); dump_stuff_msg("calc binary", crypt, len); #endif MEM_FREE(binary); MEM_FREE(crypt); if (!result) fprintf(stderr, "\n%s: Warning: Partial match for '%s'.\n" "This is a bug or a malformed input line of:\n%s\n", FORMAT_LABEL, key, source); return result; }
static int crypt_all(int *pcount, struct db_salt *salt) { const int count = *pcount; int index = 0; #ifdef _OPENMP #pragma omp parallel for for (index = 0; index < count; index += MAX_KEYS_PER_CRYPT) #endif { unsigned char master[MAX_KEYS_PER_CRYPT][32]; int i; #ifdef SIMD_COEF_32 int lens[MAX_KEYS_PER_CRYPT]; unsigned char *pin[MAX_KEYS_PER_CRYPT], *pout[MAX_KEYS_PER_CRYPT]; for (i = 0; i < MAX_KEYS_PER_CRYPT; ++i) { lens[i] = strlen(saved_key[index+i]); pin[i] = (unsigned char*)saved_key[index+i]; pout[i] = master[i]; } pbkdf2_sha1_sse((const unsigned char**)pin, lens, salt_struct->salt, SALTLEN, 1000, pout, 24, 0); #else pbkdf2_sha1((unsigned char *)saved_key[index], strlen(saved_key[index]), salt_struct->salt, SALTLEN, 1000, master[0], 24, 0); #if !ARCH_LITTLE_ENDIAN { int i; for (i = 0; i < 24/sizeof(ARCH_WORD_32); ++i) { ((ARCH_WORD_32*)master[0])[i] = JOHNSWAP(((ARCH_WORD_32*)master[0])[i]); } } #endif #endif for (i = 0; i < MAX_KEYS_PER_CRYPT; ++i) { if(kcdecrypt(master[i], salt_struct->iv, salt_struct->ct) == 0) cracked[index+i] = 1; else cracked[index+i] = 0; } } return count; }
void alter_endianity(void * _x, unsigned int size) { ARCH_WORD_32 * x = (ARCH_WORD_32 *) _x; // size is in octets size >>= 2; #if !ARCH_ALLOWS_UNALIGNED if (is_aligned(x, sizeof(ARCH_WORD_32))) { #endif while (size--) { *x = JOHNSWAP(*x); x++; } #if !ARCH_ALLOWS_UNALIGNED } else { unsigned char *cpX, c; cpX = (unsigned char *) x; while (size--) { c = *cpX; *cpX = cpX[3]; cpX[3] = c; c = cpX[1]; cpX[1] = cpX[2]; cpX[2] = c; cpX += 4; } } #endif }
static int crypt_all(int *pcount, struct db_salt *salt) { int count = *pcount; int index = 0; #ifdef _OPENMP #pragma omp parallel for for (index = 0; index < count; index += MAX_KEYS_PER_CRYPT) #endif { unsigned char key[MAX_KEYS_PER_CRYPT][32]; unsigned char hash[MAX_KEYS_PER_CRYPT][32]; BF_KEY bf_key; int bf_ivec_pos, i; unsigned char ivec[8]; unsigned char output[1024]; SHA_CTX ctx; #ifdef MMX_COEF int lens[MAX_KEYS_PER_CRYPT]; unsigned char *pin[MAX_KEYS_PER_CRYPT], *pout[MAX_KEYS_PER_CRYPT]; #endif if(cur_salt->checksum_type == 0 && cur_salt->cipher_type == 0) { for (i = 0; i < MAX_KEYS_PER_CRYPT; ++i) { SHA1_Init(&ctx); SHA1_Update(&ctx, (unsigned char *)saved_key[index+i], strlen(saved_key[index+i])); SHA1_Final((unsigned char *)(hash[i]), &ctx); } #ifdef MMX_COEF for (i = 0; i < MAX_KEYS_PER_CRYPT; ++i) { lens[i] = 20; pin[i] = hash[i]; pout[i] = key[i]; } pbkdf2_sha1_sse((const unsigned char**)pin, lens, cur_salt->salt, cur_salt->salt_length, cur_salt->iterations, pout, cur_salt->key_size, 0); #else pbkdf2_sha1(hash[0], 20, cur_salt->salt, cur_salt->salt_length, cur_salt->iterations, key[0], cur_salt->key_size, 0); #if !ARCH_LITTLE_ENDIAN for (i = 0; i < cur_salt->key_size/sizeof(ARCH_WORD_32); ++i) { ((ARCH_WORD_32*)key[0])[i] = JOHNSWAP(((ARCH_WORD_32*)key[0])[i]); } #endif #endif for (i = 0; i < MAX_KEYS_PER_CRYPT; ++i) { bf_ivec_pos = 0; memcpy(ivec, cur_salt->iv, 8); BF_set_key(&bf_key, cur_salt->key_size, key[i]); BF_cfb64_encrypt(cur_salt->content, output, cur_salt->content_length, &bf_key, ivec, &bf_ivec_pos, 0); SHA1_Init(&ctx); SHA1_Update(&ctx, output, cur_salt->content_length); SHA1_Final((unsigned char*)crypt_out[index+i], &ctx); } } else { SHA256_CTX ctx; AES_KEY akey; unsigned char iv[16]; for (i = 0; i < MAX_KEYS_PER_CRYPT; ++i) { SHA256_Init(&ctx); SHA256_Update(&ctx, (unsigned char *)saved_key[index+i], strlen(saved_key[index+i])); SHA256_Final((unsigned char *)hash[i], &ctx); } #ifdef MMX_COEF for (i = 0; i < MAX_KEYS_PER_CRYPT; ++i) { lens[i] = 32; pin[i] = hash[i]; pout[i] = key[i]; } pbkdf2_sha1_sse((const unsigned char**)pin, lens, cur_salt->salt, cur_salt->salt_length, cur_salt->iterations, pout, cur_salt->key_size, 0); #else pbkdf2_sha1(hash[0], 32, cur_salt->salt, cur_salt->salt_length, cur_salt->iterations, key[0], cur_salt->key_size, 0); #if !ARCH_LITTLE_ENDIAN for (i = 0; i < cur_salt->key_size/sizeof(ARCH_WORD_32); ++i) { ((ARCH_WORD_32*)key[0])[i] = JOHNSWAP(((ARCH_WORD_32*)key[0])[i]); } #endif #endif for (i = 0; i < MAX_KEYS_PER_CRYPT; ++i) { memcpy(iv, cur_salt->iv, 16); memset(&akey, 0, sizeof(AES_KEY)); if(AES_set_decrypt_key(key[i], 256, &akey) < 0) { fprintf(stderr, "AES_set_decrypt_key failed!\n"); } AES_cbc_encrypt(cur_salt->content, output, cur_salt->content_length, &akey, iv, AES_DECRYPT); SHA256_Init(&ctx); SHA256_Update(&ctx, output, cur_salt->content_length); SHA256_Final((unsigned char*)crypt_out[index+i], &ctx); } } } return count; }
void sha256_hash_block(sha256_ctx *ctx, const unsigned char data[64], int perform_endian_swap) { ARCH_WORD_32 A, B, C, D, E, F, G, H, tmp, W[16]; #if ARCH_LITTLE_ENDIAN int i; if (perform_endian_swap) { for (i = 0; i < 16; ++i) W[i] = JOHNSWAP(*((ARCH_WORD_32*)&(data[i<<2]))); } else #endif memcpy(W, data, 16*sizeof(ARCH_WORD_32)); // Load state from all prior blocks (or init state) A = ctx->h[0]; B = ctx->h[1]; C = ctx->h[2]; D = ctx->h[3]; E = ctx->h[4]; F = ctx->h[5]; G = ctx->h[6]; H = ctx->h[7]; R(A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98); R(H, A, B, C, D, E, F, G, W[ 1], 0x71374491); R(G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF); R(F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5); R(E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B); R(D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1); R(C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4); R(B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5); R(A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98); R(H, A, B, C, D, E, F, G, W[ 9], 0x12835B01); R(G, H, A, B, C, D, E, F, W[10], 0x243185BE); R(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3); R(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74); R(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE); R(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7); R(B, C, D, E, F, G, H, A, W[15], 0xC19BF174); R(A, B, C, D, E, F, G, H, M(16), 0xE49B69C1); R(H, A, B, C, D, E, F, G, M(17), 0xEFBE4786); R(G, H, A, B, C, D, E, F, M(18), 0x0FC19DC6); R(F, G, H, A, B, C, D, E, M(19), 0x240CA1CC); R(E, F, G, H, A, B, C, D, M(20), 0x2DE92C6F); R(D, E, F, G, H, A, B, C, M(21), 0x4A7484AA); R(C, D, E, F, G, H, A, B, M(22), 0x5CB0A9DC); R(B, C, D, E, F, G, H, A, M(23), 0x76F988DA); R(A, B, C, D, E, F, G, H, M(24), 0x983E5152); R(H, A, B, C, D, E, F, G, M(25), 0xA831C66D); R(G, H, A, B, C, D, E, F, M(26), 0xB00327C8); R(F, G, H, A, B, C, D, E, M(27), 0xBF597FC7); R(E, F, G, H, A, B, C, D, M(28), 0xC6E00BF3); R(D, E, F, G, H, A, B, C, M(29), 0xD5A79147); R(C, D, E, F, G, H, A, B, M(30), 0x06CA6351); R(B, C, D, E, F, G, H, A, M(31), 0x14292967); R(A, B, C, D, E, F, G, H, M(32), 0x27B70A85); R(H, A, B, C, D, E, F, G, M(33), 0x2E1B2138); R(G, H, A, B, C, D, E, F, M(34), 0x4D2C6DFC); R(F, G, H, A, B, C, D, E, M(35), 0x53380D13); R(E, F, G, H, A, B, C, D, M(36), 0x650A7354); R(D, E, F, G, H, A, B, C, M(37), 0x766A0ABB); R(C, D, E, F, G, H, A, B, M(38), 0x81C2C92E); R(B, C, D, E, F, G, H, A, M(39), 0x92722C85); R(A, B, C, D, E, F, G, H, M(40), 0xA2BFE8A1); R(H, A, B, C, D, E, F, G, M(41), 0xA81A664B); R(G, H, A, B, C, D, E, F, M(42), 0xC24B8B70); R(F, G, H, A, B, C, D, E, M(43), 0xC76C51A3); R(E, F, G, H, A, B, C, D, M(44), 0xD192E819); R(D, E, F, G, H, A, B, C, M(45), 0xD6990624); R(C, D, E, F, G, H, A, B, M(46), 0xF40E3585); R(B, C, D, E, F, G, H, A, M(47), 0x106AA070); R(A, B, C, D, E, F, G, H, M(48), 0x19A4C116); R(H, A, B, C, D, E, F, G, M(49), 0x1E376C08); R(G, H, A, B, C, D, E, F, M(50), 0x2748774C); R(F, G, H, A, B, C, D, E, M(51), 0x34B0BCB5); R(E, F, G, H, A, B, C, D, M(52), 0x391C0CB3); R(D, E, F, G, H, A, B, C, M(53), 0x4ED8AA4A); R(C, D, E, F, G, H, A, B, M(54), 0x5B9CCA4F); R(B, C, D, E, F, G, H, A, M(55), 0x682E6FF3); R(A, B, C, D, E, F, G, H, M(56), 0x748F82EE); R(H, A, B, C, D, E, F, G, M(57), 0x78A5636F); R(G, H, A, B, C, D, E, F, M(58), 0x84C87814); R(F, G, H, A, B, C, D, E, M(59), 0x8CC70208); R(E, F, G, H, A, B, C, D, M(60), 0x90BEFFFA); R(D, E, F, G, H, A, B, C, M(61), 0xA4506CEB); R(C, D, E, F, G, H, A, B, M(62), 0xBEF9A3F7); R(B, C, D, E, F, G, H, A, M(63), 0xC67178F2); // save state for usage in next block (or result if this was last block) ctx->h[0] += A; ctx->h[1] += B; ctx->h[2] += C; ctx->h[3] += D; ctx->h[4] += E; ctx->h[5] += F; ctx->h[6] += G; ctx->h[7] += H; }
static int sevenzip_decrypt(unsigned char *derived_key, unsigned char *data) { #ifdef _MSC_VER unsigned char *out; #else unsigned char out[cur_salt->length]; #endif AES_KEY akey; unsigned char iv[16]; union { unsigned char crcc[4]; unsigned int crci; } _crc_out; unsigned char *crc_out = _crc_out.crcc; unsigned int ccrc; CRC32_t crc; int i; int nbytes, margin; #ifdef _MSC_VER out = malloc(cur_salt->length); #endif memcpy(iv, cur_salt->iv, 16); if(AES_set_decrypt_key(derived_key, 256, &akey) < 0) { fprintf(stderr, "AES_set_decrypt_key failed in crypt!\n"); } AES_cbc_encrypt(cur_salt->data, out, cur_salt->length, &akey, iv, AES_DECRYPT); /* various verifications tests */ // test 0, padding check, bad hack :-( margin = nbytes = cur_salt->length - cur_salt->unpacksize; i = cur_salt->length - 1; while (nbytes > 0) { if (out[i] != 0) { #ifdef _MSC_VER free(out); #endif return -1; } nbytes--; i--; } if (margin > 7) { // printf("valid padding test ;-)\n"); // print_hex(out, cur_salt->length); #ifdef _MSC_VER free(out); #endif return 0; } // test 1, CRC test CRC32_Init(&crc); CRC32_Update(&crc, out, cur_salt->unpacksize); CRC32_Final(crc_out, crc); ccrc = _crc_out.crci; // computed CRC #if !ARCH_LITTLE_ENDIAN ccrc = JOHNSWAP(ccrc); #endif if (ccrc == cur_salt->crc) { #ifdef _MSC_VER free(out); #endif return 0; // XXX don't be too eager! } // XXX test 2, "well-formed folder" test if (validFolder(out)) { printf("validFolder check ;-)\n"); #ifdef _MSC_VER free(out); #endif return 0; } #ifdef _MSC_VER free(out); #endif return -1; }