示例#1
0
void cp_set_header_key(xts_key *hdr_key, u8 salt[PKCS5_SALT_SIZE], int cipher, dc_pass *password)
{
	u8 dkey[DISKKEY_SIZE];
	
	sha512_pkcs5_2(
		1000, password->pass, password->size, salt, PKCS5_SALT_SIZE, dkey, PKCS_DERIVE_MAX);

	xts_set_key(dkey, cipher, hdr_key);

	/* prevent leaks */
	burn(dkey, sizeof(dkey));
}
示例#2
0
static void dc_simple_encryption_test()
{
	PXTS_TEST_CONTEXT ctx;
	unsigned char     dk[256];
	unsigned long     e_crc, d_crc, i;

	// test PKDBF2
	for (i = 0; i < (sizeof(pkcs5_vectors) / sizeof(pkcs5_vectors[0])); i++)
	{
		sha512_pkcs5_2(pkcs5_vectors[i].i_count,
			           pkcs5_vectors[i].password, strlen(pkcs5_vectors[i].password),
					   pkcs5_vectors[i].salt, strlen(pkcs5_vectors[i].salt),
					   dk, pkcs5_vectors[i].dklen);

		if (memcmp(dk, pkcs5_vectors[i].key, pkcs5_vectors[i].dklen) != 0)
		{
			KeBugCheckEx(STATUS_ENCRYPTION_FAILED, 'DCRP', i, 0, 0);
		}
	}
	DbgMsg("PKDBF2 test passed\n");

	// test XTS engine if memory may be allocated
	if ( (KeGetCurrentIrql() <= DISPATCH_LEVEL) &&
		 (ctx = (PXTS_TEST_CONTEXT)mm_secure_alloc(sizeof(XTS_TEST_CONTEXT))) != NULL )
	{
		// fill key and test buffer
		for (i = 0; i < (sizeof(ctx->key) / sizeof(ctx->key[0])); i++) ctx->key[i] = (unsigned char)i;
		for (i = 0; i < (sizeof(ctx->test) / sizeof(ctx->test[0])); i++) ctx->test[i] = (unsigned short)i;

		// run test cases
		for (i = 0; i < (sizeof(xts_crc_vectors) / sizeof(xts_crc_vectors[0])); i++)
		{
			xts_set_key(ctx->key, xts_crc_vectors[i].alg, &ctx->xkey);

			xts_encrypt((const unsigned char*)ctx->test, (unsigned char*)ctx->buff, sizeof(ctx->test), 0x3FFFFFFFC00, &ctx->xkey);
			e_crc = crc32((const unsigned char*)ctx->buff, sizeof(ctx->buff));

			xts_decrypt((const unsigned char*)ctx->test, (unsigned char*)ctx->buff, sizeof(ctx->test), 0x3FFFFFFFC00, &ctx->xkey);
			d_crc = crc32((const unsigned char*)ctx->buff, sizeof(ctx->buff));

			if ( e_crc != xts_crc_vectors[i].e_crc || d_crc != xts_crc_vectors[i].d_crc )
			{
				KeBugCheckEx(STATUS_ENCRYPTION_FAILED, 'DCRP', 0xFF00 | i, e_crc, d_crc);
			}
		}

		DbgMsg("XTS test passed\n");
		mm_secure_free(ctx);
	}
}
示例#3
0
int cp_decrypt_header(xts_key *hdr_key, dc_header *header, dc_pass *password)
{
	u8        dk[DISKKEY_SIZE];
	int       i, succs = 0;
	dc_header *hcopy;

	if ( (hcopy = mm_alloc(sizeof(dc_header), MEM_SECURE)) == NULL ) {
		return 0;
	}
	sha512_pkcs5_2(
		1000, password->pass, password->size, 
		header->salt, PKCS5_SALT_SIZE, dk, PKCS_DERIVE_MAX);

	for (i = 0; i < CF_CIPHERS_NUM; i++)
	{
		xts_set_key(dk, i, hdr_key);

		xts_decrypt(
			pv(header), pv(hcopy), sizeof(dc_header), 0, hdr_key);

		/* Magic 'DCRP' */
		if (hcopy->sign != DC_VOLM_SIGN) {
			continue;
		}
		/* Check CRC of header */
		if (hcopy->hdr_crc != crc32(pv(&hcopy->version), DC_CRC_AREA_SIZE)) {
			continue;
		}			
		/* copy decrypted part to output */
		memcpy(&header->sign, &hcopy->sign, DC_ENCRYPTEDDATASIZE);
		succs = 1; break;
	}
	/* prevent leaks */
	burn(dk, sizeof(dk));
	mm_free(hcopy);

	return succs;
}
示例#4
0
int test_pkcs5()
{
	const char *p_key, *data;
	u8          hmac[SHA512_DIGEST_SIZE];
	const char *pass, *salt;
	int         i, dklen;	
	u8          dk[144];

	/* test HMAC-SHA-512 */
	for (i = 0; i < array_num(sha512_hmac_vectors); i++) 
	{
		p_key = sha512_hmac_vectors[i].key;
		data  = sha512_hmac_vectors[i].data;

		sha512_hmac(p_key, strlen(p_key), data, strlen(data), hmac);

		if (memcmp(hmac, sha512_hmac_vectors[i].hmac, sizeof(hmac)) != 0) {
			return 0;
		}
	}
	/* test PKDBF2 */
	for (i = 0; i < array_num(pkcs5_vectors); i++)
	{
		pass  = pkcs5_vectors[i].password;
		salt  = pkcs5_vectors[i].salt;
		dklen = pkcs5_vectors[i].dklen;

		sha512_pkcs5_2(
			pkcs5_vectors[i].i_count, pass, strlen(pass), salt, strlen(salt), dk, dklen);

		if (memcmp(dk, pkcs5_vectors[i].key, dklen) != 0) {
			return 0;
		}
	}	
	return 1;
}
示例#5
0
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;
}