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; }
static INT_PTR CALLBACK _keyfiles_dlg_proc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ) { static int key_list; static list_entry *head; switch ( message ) { case WM_CLOSE : { EndDialog( hwnd, 0 ); return 0L; } break; case WM_NOTIFY : { if( wparam == IDC_LIST_KEYFILES ) { if ( ((NMHDR *)lparam)->code == LVN_ITEMCHANGED && (((NMLISTVIEW *)lparam)->uNewState & LVIS_FOCUSED ) ) { HWND h_list = GetDlgItem( hwnd, IDC_LIST_KEYFILES ); EnableWindow(GetDlgItem( hwnd, IDB_REMOVE_ITEM), ListView_GetSelectedCount( h_list ) ); return 1L; } if ( ((NM_LISTVIEW *)lparam)->hdr.code == NM_CLICK ) { HWND h_list = GetDlgItem( hwnd, IDC_LIST_KEYFILES ); EnableWindow( GetDlgItem( hwnd, IDB_REMOVE_ITEM), ListView_GetSelectedCount( h_list ) ); } } } case WM_COMMAND : { HWND h_list = GetDlgItem( hwnd, IDC_LIST_KEYFILES ); int code = HIWORD(wparam); int id = LOWORD(wparam); switch ( id ) { case IDB_GENERATE_KEYFILE : { wchar_t s_file[MAX_PATH] = { L"keyfile" }; byte keyfile[64]; int rlt; if ( _save_file_dialog( hwnd, s_file, countof(s_file), L"Save 64 bytes random keyfile as.." ) ) { if ( (rlt = dc_get_random(keyfile, sizeof(keyfile))) == ST_OK ) { rlt = save_file(s_file, keyfile, sizeof(keyfile)); burn(keyfile, sizeof(keyfile)); } if ( rlt == ST_OK ) { if ( __msg_q(hwnd, L"Keyfile \"%s\" successfully created\n\n" L"Add this file to the keyfiles list?", s_file ) ) { _ui_keys_list_refresh(hwnd); if ( key_list == KEYLIST_EMBEDDED ) { ListView_DeleteAllItems( h_list ); } _add_item( h_list, s_file ); _ui_embedded( hwnd, key_list ); } } else { __error_s( hwnd, L"Error creating Keyfile", rlt ); } } } break; case IDB_REMOVE_ITEM : { ListView_DeleteItem( h_list, ListView_GetSelectionMark(h_list) ); _ui_keys_list_refresh( hwnd ); _ui_embedded( hwnd, key_list ); } break; case IDB_REMOVE_ITEMS : { ListView_DeleteAllItems( h_list ); _ui_keys_list_refresh( hwnd ); _ui_embedded( hwnd, key_list ); } break; case IDB_ADD_FOLDER : { wchar_t path[MAX_PATH]; if ( _folder_choice(hwnd, path, L"Choice folder..") ) { _ui_keys_list_refresh( hwnd ); _set_trailing_slash( path ); _add_item( h_list, path ); } } break; case IDB_ADD_FILE : { wchar_t s_path[MAX_PATH] = { 0 }; if ( _open_file_dialog(hwnd, s_path, countof(s_path), L"Select File..") ) { if ( key_list == KEYLIST_EMBEDDED ) { HWND h_file = CreateFile( s_path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if ( h_file != INVALID_HANDLE_VALUE ) { if ( GetFileSize( h_file, NULL ) != 64 ) { __error_s( hwnd, L"Embedded keyfile must be 64 byte size", ST_ERROR ); } else { _ui_keys_list_refresh( hwnd ); _add_item( h_list, s_path ); } CloseHandle( h_file ); } _ui_embedded( hwnd, key_list ); } else { _ui_keys_list_refresh( hwnd ); _add_item( h_list, s_path ); } } } break; } if ( id == IDCANCEL ) { EndDialog(hwnd, 0); } if ( id == IDOK ) { int k = 0; _keyfiles_wipe(key_list); for ( ; k < ListView_GetItemCount( h_list ); k ++ ) { wchar_t item[MAX_PATH]; _get_item_text( h_list, k, 0, item, countof(item) ); if ( wcscmp(item, IDS_EMPTY_LIST) != 0 ) { _list_key_files *new_node; if ( (new_node = secure_alloc(sizeof(_list_key_files))) == NULL ) { __error_s( hwnd, L"Can't allocate memory", ST_NOMEM ); _keyfiles_wipe(key_list); break; } wcsncpy(new_node->path, item, countof(new_node->path)); _insert_tail_list(head, &new_node->next); } } EndDialog(hwnd, 0); } } break; case WM_INITDIALOG : { HWND h_list = GetDlgItem(hwnd, IDC_LIST_KEYFILES); _list_key_files *key_file; key_list = (int)lparam; head = _KEYFILES_HEAD_( key_list ); _init_list_headers( h_list, _keyfiles_headers ); if ( key_file = _first_keyfile( key_list ) ) { EnableWindow( GetDlgItem(hwnd, IDB_REMOVE_ITEMS), TRUE ); do { _list_insert_item( h_list, ListView_GetItemCount(h_list), 0, key_file->path, 0 ); key_file = _next_keyfile( key_file, key_list ); } while ( key_file != NULL ); } _ui_keys_list_refresh( hwnd ); _ui_embedded( hwnd, key_list ); ListView_SetBkColor( h_list, GetSysColor(COLOR_BTNFACE) ); ListView_SetTextBkColor( h_list, GetSysColor(COLOR_BTNFACE) ); ListView_SetExtendedListViewStyle( h_list, LVS_EX_FLATSB | LVS_EX_FULLROWSELECT ); SetForegroundWindow(hwnd); return 1L; } break; case WM_CTLCOLOREDIT : { return _ctl_color(wparam, _cl(COLOR_BTNFACE, LGHT_CLR)); } break; default: { int rlt = _draw_proc(message, lparam); if (rlt != -1) return rlt; } } return 0L; }