Ejemplo n.º 1
0
static 
int dc_probe_decrypt(dev_hook *hook, dc_header **header, xts_key **res_key, dc_pass *password)
{
	xts_key  *hdr_key;
	dsk_pass *d_pass;	
	int       resl, succs;

	hdr_key = NULL; succs = 0; *header = NULL;
	do
	{
		/* read raw volume header */
		if ( (resl = io_read_header(hook, header, NULL, NULL)) != ST_OK ) {
			break;
		}
		if ( (hdr_key = mm_secure_alloc(sizeof(xts_key))) == NULL ) {
			resl = ST_NOMEM; break;
		}

		/* derive header key and decrypt header */
		do
		{
			if (password != NULL)
			{
				/* probe mount with entered password */
				if (succs = cp_decrypt_header(hdr_key, *header, password)) {
					break;
				}
			}

			KeEnterCriticalRegion();
			ExAcquireResourceSharedLite(&p_resource, TRUE);

			/* probe mount with cached passwords */
			for (d_pass = f_pass; d_pass; d_pass = d_pass->next)
			{
				if (succs = cp_decrypt_header(hdr_key, *header, &d_pass->pass)) {
					break;
				}
			}

			ExReleaseResourceLite(&p_resource);
			KeLeaveCriticalRegion();
		} while (0);

		if (succs != 0) {
			*res_key = hdr_key; hdr_key = NULL; resl = ST_OK; 
		} else {
			resl = ST_PASS_ERR;
		}
	} while (0);

	if (resl != ST_OK && *header != NULL) {
		mm_secure_free(*header); *header = NULL;
	}
	if (hdr_key != NULL) {
		mm_secure_free(hdr_key);
	}
	return resl;
}
Ejemplo n.º 2
0
int dc_backup_header(wchar_t *dev_name, dc_pass *password, void *out)
{
	dc_header *header = NULL;
	xts_key   *hdr_key = NULL;
	dev_hook  *hook    = NULL;
	int        resl;
	s8         salt[PKCS5_SALT_SIZE];

	do
	{
		if ( (hook = dc_find_hook(dev_name)) == NULL ) {
			resl = ST_NF_DEVICE; break;
		}
		wait_object_infinity(&hook->busy_lock);

		if (hook->flags & (F_SYNC | F_UNSUPRT | F_DISABLE | F_CDROM)) {
			resl = ST_ERROR; break;
		}
		if ( (hdr_key = mm_alloc(sizeof(xts_key), MEM_SECURE)) == NULL ) {
			resl = ST_NOMEM; break;
		}
		/* get device params */
		if (hook->dsk_size == 0) {
			if ( (resl = dc_fill_disk_info(hook)) != ST_OK ) break;
		}
		if ( (resl = io_read_header(hook, &header, NULL, password)) != ST_OK ) {
			break;
		}
		/* generate new salt */
		cp_rand_bytes(header->salt, PKCS5_SALT_SIZE);
		/* save original salt */
		memcpy(salt, header->salt, PKCS5_SALT_SIZE);		
		/* init new header key */
		cp_set_header_key(hdr_key, header->salt, header->alg_1, password);		
		/* encrypt header with new key */
		xts_encrypt(pv(header), pv(header), sizeof(dc_header), 0, hdr_key);
		/* restore original salt */
		memcpy(header->salt, salt, PKCS5_SALT_SIZE);

		/* copy header to output */
		memcpy(out, header, sizeof(dc_header));
		resl = ST_OK;
	} while (0);

	if (hook != NULL) {
		KeReleaseMutex(&hook->busy_lock, FALSE);
		dc_deref_hook(hook);
	}
	/* prevent leaks */
	burn(salt, sizeof(salt));
	/* free memory */	
	if (header != NULL) mm_free(header);
	if (hdr_key != NULL) mm_free(hdr_key);
	return resl;
}
Ejemplo n.º 3
0
int dc_change_pass(wchar_t *dev_name, dc_pass *old_pass, dc_pass *new_pass)
{
	dc_header *header = NULL;
	dev_hook  *hook   = NULL;
	int        wp_init = 0;
	int        resl;
	wipe_ctx   wipe;	
	
	do
	{
		if ( (hook = dc_find_hook(dev_name)) == NULL ) {
			resl = ST_NF_DEVICE; break;
		}
		wait_object_infinity(&hook->busy_lock);

		if ( !(hook->flags & F_ENABLED) ) {
			resl = ST_NO_MOUNT; break;
		}
		if (hook->flags & (F_SYNC | F_FORMATTING | F_CDROM)) {
			resl = ST_ERROR; break;
		}
		/* read old volume header */
		if ( (resl = io_read_header(hook, &header, NULL, old_pass)) != ST_OK ) {
			break;
		}
		/* init data wipe */
		if ( (resl = dc_wipe_init(
			&wipe, hook, hook->head_len, WP_GUTMANN, hook->crypt.cipher_id)) == ST_OK )
		{
			wp_init = 1;
		} else break;

		/* wipe volume header */
		dc_wipe_process(&wipe, 0, hook->head_len);		
		/* write new volume header */
		resl = io_write_header(hook, header, NULL, new_pass);
	} while (0);

	if (wp_init != 0) {
		dc_wipe_free(&wipe);
	}
	if (hook != NULL) {
		KeReleaseMutex(&hook->busy_lock, FALSE);
		dc_deref_hook(hook);
	}	
	if (header != NULL) mm_free(header);
	return resl;
}