Пример #1
0
void print_key(key_header_t* key_hdr)
{
	char* cipher = cipherstr(key_hdr->algorithm);
	char* type_str = datumtypestr(key_hdr->datum_type);
	
	xprintf(L_INFO, "====[ Private Key Header information ]====\n");
	xprintf(L_INFO, "Size: %hu bytes\n", key_hdr->size);
	xprintf(L_INFO, "Unknown: %hu\n", key_hdr->zeros);
	xprintf(L_INFO, "Datum type: %s (%#hx)\n", type_str, key_hdr->datum_type);
	xprintf(L_INFO, "Encryption Type: %s (%#hx)\n", cipher, key_hdr->algorithm);
	xprintf(L_INFO, "Unknown1: \n"); 
	hexdump(L_INFO, key_hdr->unknown1, sizeof(key_hdr->unknown1));
	xprintf(L_INFO, "Decryption Key:\n");
	hexdump(L_INFO, key_hdr->decryption_key, sizeof(key_hdr->decryption_key));
	
	xfree(cipher);
	xfree(type_str);
}
Пример #2
0
void print_ext_info_header(external_info_header_t* header) 
{
	char rec_id[37] = {0,};
	time_t ts;
	char* type_str = NULL;
	
	ntfs2utc(header->timestamp, &ts);
	format_guid(header->guid, rec_id);
	type_str = datumtypestr(header->datum_type);
	
	xprintf(L_INFO, "===[ Header information ]===\n");
	xprintf(L_INFO, "Size: %hu bytes\n", header->size);
	xprintf(L_INFO, "Unknown1: %#.4x\n", header->unknown1);
	xprintf(L_INFO, "Datum type: %s (%#.4x)\n", type_str, header->datum_type);
	xprintf(L_INFO, "Error status: %hu\n", header->error_status);
	xprintf(L_INFO, "Recovery Key Id: %s\n", rec_id);
	xprintf(L_INFO, "Epoch Timestamp: %ud sec, or %s\n", (unsigned int)ts, asctime(gmtime(&ts)));
	
	xfree(type_str);
}
Пример #3
0
/**
 * Get the VMK datum using a recovery password
 * 
 * @param dataset The dataset where a clear key is assumed to be
 * @param cfg The configuration structure
 * @param vmk_datum The datum_key_t found, containing the unencrypted VMK
 * @return TRUE if result can be trusted, FALSE otherwise
 */
int get_vmk_from_rp(bitlocker_dataset_t* dataset, dis_config_t* cfg, void** vmk_datum)
{
	// Check parameters
	if(!dataset || !cfg)
		return FALSE;
	
	uint8_t* recovery_key = NULL;
	uint8_t salt[16] = {0,};
	
	int result = FALSE;
	
	/* If the recovery password wasn't provide, ask for it */
	if(!cfg->recovery_password)
		if(!prompt_rp(&cfg->recovery_password))
		{
			xprintf(L_ERROR, "Cannot get valid recovery password. Abort.\n");
			return FALSE;
		}
	
	
	xprintf(L_DEBUG, "Using the recovery password: '******'.\n",
	                (char *)cfg->recovery_password);
	
	
	/*
	 * We need a salt contained in the VMK datum associated to the recovery
	 * password, so go get this salt and the VMK datum first
	 * We use here the range which should be upper (or equal) than 0x800
	 */
	if(!get_vmk_datum_from_range((void*)dataset, 0x800, 0xfff, (void**)vmk_datum))
	{
		xprintf(L_ERROR, "Error, can't find a valid and matching VMK datum. Abort.\n");
		*vmk_datum = NULL;
		return FALSE;
	}
	
	
	/*
	 * We have the datum containing other data, so get in there and take the
	 * nested one with type 3 (stretch key)
	 */
	void* stretch_datum = NULL;
	if(!get_nested_datumtype(*vmk_datum, DATUM_STRETCH_KEY, &stretch_datum) || !stretch_datum)
	{
		char* type_str = datumtypestr(DATUM_STRETCH_KEY);
		xprintf(L_ERROR, "Error looking for the nested datum of type %hd (%s) in the VMK one. "
		                 "Internal failure, abort.\n", DATUM_STRETCH_KEY, type_str);
		xfree(type_str);
		*vmk_datum = NULL;
		return FALSE;
	}
	
	
	/* The salt is in here, don't forget to keep it somewhere! */
	memcpy(salt, ((datum_stretch_key_t*)stretch_datum)->salt, 16);
	
	
	/* Get data which can be decrypted with this password */
	void* aesccm_datum = NULL;
	if(!get_nested_datumtype(*vmk_datum, DATUM_AES_CCM, &aesccm_datum) || !aesccm_datum)
	{
		xprintf(L_ERROR, "Error finding the AES_CCM datum including the VMK. Internal failure, abort.\n");
		*vmk_datum = NULL;
		return FALSE;
	}
	
	
	/*
	 * We have all the things we need to compute the intermediate key from
	 * the recovery password, so do it!
	 */
	recovery_key = xmalloc(32 * sizeof(uint8_t));

	if(!intermediate_key(cfg->recovery_password, salt, recovery_key))
	{
		xprintf(L_ERROR, "Error computing the recovery password to the recovery key. Abort.\n");
		*vmk_datum = NULL;
		xfree(recovery_key);
		return FALSE;
	}
	
	/* We don't need the recovery_password anymore */
	memclean((char*)cfg->recovery_password, strlen((char*)cfg->recovery_password));
	cfg->recovery_password = NULL;
	
	/* As the computed key length is always the same, use a direct value */
	result = get_vmk((datum_aes_ccm_t*)aesccm_datum, recovery_key, 32, (datum_key_t**)vmk_datum);
	
	xfree(recovery_key);
	
	return result;
}