NTSTATUS CipherInit() { const UINT hw_crypt = TRUE; xts_init(hw_crypt); ExInitializeFastMutex(&g_pCipherOptsMutex); return STATUS_SUCCESS; }
int try_decrypt(char *passphrase) { struct xts_ctx *xts_ctx; struct pbkdf_prf *prf; int dklen = 64; uint8_t *dk; uint32_t sector = 0; uint32_t crc; int ret = -1; dk = malloc(dklen); xts_ctx = malloc(sizeof(struct xts_ctx)); for (prf = &prfs[0]; prf->hmac_fn != NULL; ++prf) { /* We decrypt in place, so we have to re-read every time */ bios_read_sectors(biosdev, &hdr, 63, 1); pbkdf2(dk, dklen, passphrase, strlen(passphrase), hdr.enc.salt, SALT_LEN, prf->iterations, prf->hmac_fn, prf->digest_sz); #ifdef DEBUG bios_print_hex(dk, dklen); bios_print("\r\n"); #endif xts_init(xts_ctx, aes256_init, aes256_encrypt_ecb, aes256_decrypt_ecb, 16, dk, dklen); xts_decrypt(xts_ctx, hdr.enc.enc, sizeof(hdr.enc.enc), §or, sizeof(sector)); xts_uninit(xts_ctx); if (memcmp(hdr.dec.tc_str, TC_SIG, sizeof(hdr.dec.tc_str)) != 0) { bios_print("Signature mismatch\r\n"); continue; } bswap_inplace(&hdr.dec.tc_ver, sizeof(hdr.dec.tc_ver)); bswap_inplace(&hdr.dec.crc_keys, sizeof(hdr.dec.crc_keys)); bswap_inplace(&hdr.dec.off_mk_scope, sizeof(hdr.dec.off_mk_scope)); bswap_inplace(&hdr.dec.sz_mk_scope, sizeof(hdr.dec.sz_mk_scope)); bswap_inplace(&hdr.dec.flags, sizeof(hdr.dec.flags)); crc = crc32((void *)hdr.dec.keys, sizeof(hdr.dec.keys)); if (crc != hdr.dec.crc_keys) { bios_print("Keys CRC mismatch\r\n"); continue; } ret = 0; break; } free (dk, dklen); free (xts_ctx, sizeof(struct xts_ctx)); return ret; }
void dc_init_encryption() { DbgMsg("dc_init_encryption\n"); if (aes256_padlock_available() != 0) { SetFlag(dc_load_flags, DST_VIA_PADLOCK); DbgMsg("CpuFlags_VIA_PadLock: Yes\n"); } else { ClearFlag(dc_load_flags, DST_VIA_PADLOCK); DbgMsg("CpuFlags_VIA_PadLock: No\n"); } if (xts_aes_ni_available() != 0) { SetFlag(dc_load_flags, DST_INTEL_NI); DbgMsg("CpuFlags_AES_NI: Yes\n"); } else { ClearFlag(dc_load_flags, DST_INTEL_NI); DbgMsg("CpuFlags_AES_NI: No\n"); } #ifdef _M_IX86 if (xts_serpent_sse2_available() != 0) { SetFlag(dc_load_flags, DST_INSTR_SSE2); DbgMsg("CpuFlags_SSE2: Yes\n"); } else { ClearFlag(dc_load_flags, DST_INSTR_SSE2); DbgMsg("CpuFlags_SSE2: No\n"); } #else DbgMsg("CpuFlags_SSE2: Yes\n"); SetFlag(dc_load_flags, DST_INSTR_SSE2); #endif if (xts_serpent_avx_available() != 0) { SetFlag(dc_load_flags, DST_INSTR_AVX); DbgMsg("CpuFlags_AVX: Yes\n"); } else { ClearFlag(dc_load_flags, DST_INSTR_AVX); DbgMsg("CpuFlags_AVX: No\n"); } // initialize XTS mode engine and run small encryption test xts_init(dc_conf_flags & CONF_HW_CRYPTO); dc_simple_encryption_test(); }
int dc_encrypt_cd( wchar_t *src_path, wchar_t *dst_path, dc_pass *pass, int cipher, cd_callback callback, void *param ) { dc_conf_data conf; HANDLE h_src = NULL; HANDLE h_dst = NULL; xts_key *v_key = NULL; xts_key *h_key = NULL; dc_header head; int resl; u64 iso_sz; u32 bytes; u8 salt[PKCS5_SALT_SIZE]; u8 dk[DISKKEY_SIZE]; if (alg_ok == 0) { if (dc_load_conf(&conf) == ST_OK) { xts_init(conf.conf_flags & CONF_HW_CRYPTO); } else { xts_init(0); } alg_ok = 1; } do { if ( (resl = dc_lock_memory(dk, sizeof(dk))) != ST_OK ) { break; } if ( (resl = dc_lock_memory(&head, sizeof(head))) != ST_OK ) { break; } h_src = CreateFile( src_path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0); if (h_src == INVALID_HANDLE_VALUE) { h_src = NULL; resl = ST_NO_OPEN_FILE; break; } h_dst = CreateFile( dst_path, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, 0); if (h_dst == INVALID_HANDLE_VALUE) { h_dst = NULL; resl = ST_NO_CREATE_FILE; break; } if (GetFileSizeEx(h_src, pv(&iso_sz)) == 0) { resl = ST_IO_ERROR; break; } v_key = VirtualAlloc(NULL, sizeof(xts_key), MEM_COMMIT+MEM_RESERVE, PAGE_EXECUTE_READWRITE); h_key = VirtualAlloc(NULL, sizeof(xts_key), MEM_COMMIT+MEM_RESERVE, PAGE_EXECUTE_READWRITE); if ( (v_key == NULL) || (h_key == NULL) ) { resl = ST_NOMEM; break; } /* lock keys in memory */ if ( (resl = dc_lock_memory(v_key, sizeof(xts_key))) != ST_OK ) { break; } if ( (resl = dc_lock_memory(h_key, sizeof(xts_key))) != ST_OK ) { break; } /* create volume header */ zeroauto(&head, sizeof(dc_header)); dc_get_random(pv(salt), PKCS5_SALT_SIZE); dc_get_random(pv(&head.disk_id), sizeof(u32)); dc_get_random(pv(head.key_1), DISKKEY_SIZE); head.sign = DC_VOLM_SIGN; head.version = DC_HDR_VERSION; head.flags = VF_NO_REDIR; head.alg_1 = cipher; head.use_size = iso_sz; head.data_off = sizeof(dc_header); head.hdr_crc = crc32(pv(&head.version), DC_CRC_AREA_SIZE); /* initialize volume key */ xts_set_key(head.key_1, cipher, v_key); /* initialize header key */ sha512_pkcs5_2( 1000, pass->pass, pass->size, salt, PKCS5_SALT_SIZE, dk, PKCS_DERIVE_MAX); xts_set_key(dk, cipher, h_key); /* encrypt volume header */ xts_encrypt(pv(&head), pv(&head), sizeof(dc_header), 0, h_key); /* save salt */ autocpy(head.salt, salt, PKCS5_SALT_SIZE); /* write volume header to file */ if (WriteFile(h_dst, &head, sizeof(head), &bytes, NULL) == 0) { resl = ST_IO_ERROR; break; } resl = do_cd_encrypt(h_src, h_dst, iso_sz, v_key, callback, param); } while (0); /* prevent leaks */ zeroauto(dk, sizeof(dk)); zeroauto(&head, sizeof(head)); dc_unlock_memory(dk); dc_unlock_memory(&head); if (v_key != NULL) { zeroauto(v_key, sizeof(xts_key)); dc_unlock_memory(v_key); VirtualFree(v_key, 0, MEM_RELEASE); } if (h_key != NULL) { zeroauto(h_key, sizeof(xts_key)); dc_unlock_memory(h_key); VirtualFree(h_key, 0, MEM_RELEASE); } if (h_src != NULL) { CloseHandle(h_src); } if (h_dst != NULL) { CloseHandle(h_dst); if (resl != ST_OK) { DeleteFile(dst_path); } } return resl; }