示例#1
0
void print_bek_header(dataset_t* bek) 
{
	time_t ts;
	char rec_id[37];
	
	ntfs2utc(bek->timestamp, &ts); 
	format_guid(bek->hash, rec_id); 
	
	xprintf(L_INFO, "==[ Generic BEK file information ]==\n");
	xprintf(L_INFO, "Total Size: %hu bytes\n", bek->size);
	xprintf(L_INFO, "Unknown: %hu\n", bek->unknown1);
	xprintf(L_INFO, "Header Size: %d bytes\n", bek->header_size);
	xprintf(L_INFO, "Recovery Key Id: %16s \n", rec_id);
	xprintf(L_INFO, "Next counter: %d\n", bek->next_counter);
	xprintf(L_INFO, "Reserved field: 0x%x\n", bek->algo_zeroed);  
	xprintf(L_INFO, "Epoch Timestamp: %ud sec, or %s\n", (unsigned int)ts, asctime(gmtime(&ts)));
}
示例#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
_format_message_dn(char *buf, size_t size, const_efidp dp)
{
	ssize_t off = 0;
	ssize_t sz;
	switch (dp->subtype) {
	case EFIDP_MSG_ATAPI:
		off += format(buf, size, off, "Ata(%d,%d,%d)",
			      dp->atapi.primary, dp->atapi.slave,
			      dp->atapi.lun);
		break;
	case EFIDP_MSG_SCSI:
		off += format(buf, size, off, "SCSI(%d,%d)",
			      dp->scsi.target, dp->scsi.lun);
		break;
	case EFIDP_MSG_FIBRECHANNEL:
		off += format(buf, size, off, "Fibre(%"PRIx64",%"PRIx64")",
			      le64_to_cpu(dp->fc.wwn),
			      le64_to_cpu(dp->fc.lun));
		break;
	case EFIDP_MSG_FIBRECHANNELEX:
		off += format(buf, size, off, "Fibre(%"PRIx64",%"PRIx64")",
			      be64_to_cpu(dp->fc.wwn),
			      be64_to_cpu(dp->fc.lun));
		break;
	case EFIDP_MSG_1394:
		off += format(buf, size, off, "I1394(0x%"PRIx64")",
			      dp->firewire.guid);
		break;
	case EFIDP_MSG_USB:
		off += format(buf, size, off, "USB(%d,%d)",
			      dp->usb.parent_port, dp->usb.interface);
		break;
	case EFIDP_MSG_I2O:
		off += format(buf, size, off, "I2O(%d)", dp->i2o.target);
		break;
	case EFIDP_MSG_INFINIBAND:
		if (dp->infiniband.resource_flags &
				EFIDP_INFINIBAND_RESOURCE_IOC_SERVICE) {
			off += format(buf, size, off,
				      "Infiniband(%08x,%"PRIx64"%"PRIx64",%"PRIx64",%"PRIu64",%"PRIu64")",
				      dp->infiniband.resource_flags,
				      dp->infiniband.port_gid[1],
				      dp->infiniband.port_gid[0],
				      dp->infiniband.service_id,
				      dp->infiniband.target_port_id,
				      dp->infiniband.device_id);
		} else {
			off += format(buf, size, off,
				      "Infiniband(%08x,%"PRIx64"%"PRIx64",",
				      dp->infiniband.resource_flags,
				      dp->infiniband.port_gid[1],
				      dp->infiniband.port_gid[0]);
			off += format_guid(buf, size, off, (efi_guid_t *)
					   &dp->infiniband.ioc_guid);
			off += format(buf, size, off, ",%"PRIu64",%"PRIu64")",
				      dp->infiniband.target_port_id,
				      dp->infiniband.device_id);
		}
		break;
	case EFIDP_MSG_MAC_ADDR:
		off += format(buf, size, off, "MAC(");
		off += format_hex(buf, size, off, dp->mac_addr.mac_addr,
				  dp->mac_addr.if_type < 2 ? 6
					: sizeof(dp->mac_addr.mac_addr));
		off += format(buf, size, off, ",%d)", dp->mac_addr.if_type);
		break;
	case EFIDP_MSG_IPv4: {
		efidp_ipv4_addr const *a = &dp->ipv4_addr;
		off += format(buf, size, off,
			      "IPv4(%hhu.%hhu.%hhu.%hhu:%hu<->%hhu.%hhu.%hhu.%hhu:%hu,%hx,%hhx)",
			      a->local_ipv4_addr[0], a->local_ipv4_addr[1],
			      a->local_ipv4_addr[2], a->local_ipv4_addr[3],
			      a->local_port, a->remote_ipv4_addr[0],
			      a->remote_ipv4_addr[1], a->remote_ipv4_addr[2],
			      a->remote_ipv4_addr[3], a->remote_port,
			      a->protocol, a->static_ip_addr);
		break;
			     }
	case EFIDP_MSG_VENDOR: {
		struct {
			efi_guid_t guid;
			char label[40];
			ssize_t (*formatter)(char *buf, size_t size,
					     const_efidp dp);
		} subtypes[] = {
			{ EFIDP_PC_ANSI_GUID, "VenPcAnsi" },
			{ EFIDP_VT_100_GUID, "VenVt100" },
			{ EFIDP_VT_100_PLUS_GUID, "VenVt100Plus" },
			{ EFIDP_VT_UTF8_GUID, "VenUtf8" },
			{ EFIDP_MSG_DEBUGPORT_GUID, "DebugPort" },
			{ EFIDP_MSG_UART_GUID, "", format_uart },
			{ EFIDP_MSG_SAS_GUID, "", format_sas },
			{ efi_guid_empty, "" }
		};
		char *label = NULL;
		ssize_t (*formatter)(char *buf, size_t size,
				     const_efidp dp) = NULL;

		for (int i = 0; !efi_guid_is_zero(&subtypes[i].guid); i++) {
			if (efi_guid_cmp(&subtypes[i].guid,
					  &dp->msg_vendor.vendor_guid))
				continue;

			label = subtypes[i].label;
			formatter = subtypes[i].formatter;
			break;
		}

		if (!label && !formatter) {
			off += format_vendor(buf, size, off, "VenMsg", dp);
			break;
		} else if (formatter) {
			off += format_helper(formatter, buf, size, off, dp);
			break;
		}

		off += format(buf, size, off, "%s(", label);
		if (efidp_node_size(dp) >
				(ssize_t)(sizeof (efidp_header)
					  + sizeof (efi_guid_t))) {
			off += format_hex(buf, size, off,
					  dp->msg_vendor.vendor_data,
					  efidp_node_size(dp)
						- sizeof (efidp_header)
						- sizeof (efi_guid_t));
		}
		break;
			       }
	case EFIDP_MSG_IPv6: {
		efidp_ipv6_addr const *a = &dp->ipv6_addr;
		char *addr0 = NULL;
		char *addr1 = NULL;

		sz = format_ipv6_port(addr0, 0, 0, a->local_ipv6_addr,
				      a->local_port);
		if (sz < 0)
			return sz;

		addr0 = alloca(sz+1);
		sz = format_ipv6_port(addr0, sz, 0, a->local_ipv6_addr,
				      a->local_port);
		if (sz < 0)
			return sz;

		sz = format_ipv6_port(addr1, 0, 0, a->remote_ipv6_addr,
				      a->remote_port);
		if (sz < 0)
			return sz;
		addr1 = alloca(sz+1);
		sz = format_ipv6_port(addr1, sz, 0, a->remote_ipv6_addr,
				      a->remote_port);
		if (sz < 0)
			return sz;

		off += format(buf, size, off, "IPv6(%s<->%s,%hx,%hhx)",
			     addr0, addr1, a->protocol, a->ip_addr_origin);
		break;
			     }
	case EFIDP_MSG_UART: {
		int parity = dp->uart.parity;
		char parity_label[] = "DNEOMS";
		int stop_bits = dp->uart.stop_bits;
		char *sb_label[] = {"D", "1", "1.5", "2"};

		off += format(buf, size, off, "Uart(%"PRIu64",%d,",
			     dp->uart.baud_rate ? dp->uart.baud_rate : 115200,
			     dp->uart.data_bits ? dp->uart.data_bits : 8);
		off += format(buf, size, off,
			     parity > 5 ? "%d," : "%c,",
			     parity > 5 ? parity : parity_label[parity]);
		if (stop_bits > 3)
			off += format(buf, size, off, "%d)", stop_bits);
		else
			off += format(buf, size, off, "%s)",
				     sb_label[stop_bits]);
		break;
			     }
	case EFIDP_MSG_USB_CLASS:
		off += format_helper(format_usb_class, buf, size, off, dp);
		break;
	case EFIDP_MSG_USB_WWID:
		off += format(buf, size, off,
			      "UsbWwid(%"PRIx16",%"PRIx16",%d,",
			      dp->usb_wwid.vendor_id, dp->usb_wwid.product_id,
			      dp->usb_wwid.interface);
		off += format_ucs2(buf, size, off, dp->usb_wwid.serial_number,
				   (efidp_node_size(dp)
				    - offsetof(efidp_usb_wwid, serial_number))
				   / 2 + 1);
		off += format(buf, size, off, ")");
		break;
	case EFIDP_MSG_LUN:
		off += format(buf, size, off, "Unit(%d)", dp->lun.lun);
		break;
	case EFIDP_MSG_SATA:
		off += format(buf, size, off, "Sata(%d,%d,%d)",
			     dp->sata.hba_port, dp->sata.port_multiplier_port,
			     dp->sata.lun);
		break;
	case EFIDP_MSG_ISCSI: {
		size_t sz = efidp_node_size(dp)
			    - offsetof(efidp_iscsi, target_name);
		if (sz > EFIDP_ISCSI_MAX_TARGET_NAME_LEN)
			sz = EFIDP_ISCSI_MAX_TARGET_NAME_LEN;
		char target_name[sz + 1];
		memcpy(target_name, dp->iscsi.target_name, sz);
		target_name[sz] = '\0';
		uint64_t lun;

		memcpy(&lun, dp->iscsi.lun, sizeof (lun));

		off += format(buf, size, off,
			      "iSCSI(%s,%d,0x%"PRIx64",%s,%s,%s,%s)",
			      target_name, dp->iscsi.tpgt,
			      be64_to_cpu(lun),
			      (dp->iscsi.options >> EFIDP_ISCSI_HEADER_DIGEST_SHIFT) & EFIDP_ISCSI_HEADER_CRC32 ? "CRC32" : "None",
			      (dp->iscsi.options >> EFIDP_ISCSI_DATA_DIGEST_SHIFT) & EFIDP_ISCSI_DATA_CRC32 ? "CRC32" : "None",
			      (dp->iscsi.options >> EFIDP_ISCSI_AUTH_SHIFT) & EFIDP_ISCSI_AUTH_NONE ? "None" : \
				      (dp->iscsi.options >> EFIDP_ISCSI_CHAP_SHIFT) & EFIDP_ISCSI_CHAP_UNI ? "CHAP_UNI" : "CHAP_BI",
			      dp->iscsi.protocol == 0 ? "TCP" : "Unknown");
		break;
			      }
	case EFIDP_MSG_VLAN:
		off += format(buf, size, off, "Vlan(%d)", dp->vlan.vlan_id);
		break;
	case EFIDP_MSG_SAS_EX:
		off += format_sas(buf, size, dp);
		break;
	case EFIDP_MSG_NVME:
		off += format(buf, size, off, "NVMe(0x%"PRIx32","
			      "%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X)",
			      dp->nvme.namespace_id, dp->nvme.ieee_eui_64[0],
			      dp->nvme.ieee_eui_64[1], dp->nvme.ieee_eui_64[2],
			      dp->nvme.ieee_eui_64[3], dp->nvme.ieee_eui_64[4],
			      dp->nvme.ieee_eui_64[5], dp->nvme.ieee_eui_64[6],
			      dp->nvme.ieee_eui_64[7]);
		break;
	case EFIDP_MSG_URI: {
		size_t sz = efidp_node_size(dp) - offsetof(efidp_uri, uri);
		char uri[sz + 1];
		memcpy(uri, dp->uri.uri, sz);
		uri[sz] = '\0';
		off += format(buf, size, off, "Uri(%s)", uri);
		break;
			    }
	case EFIDP_MSG_UFS:
		off += format(buf, size, off, "UFS(%d,0x%02x)",
			      dp->ufs.target_id, dp->ufs.lun);
		break;
	case EFIDP_MSG_SD:
		off += format(buf, size, off, "SD(%d)", dp->sd.slot_number);
		break;
	default:
		off += format(buf, size, off, "Msg(%d,", dp->subtype);
		off += format_hex(buf, size, off, (uint8_t *)dp+4,
				  efidp_node_size(dp)-4);
		off += format(buf,size,off,")");
		break;
	}
	return off;
}
示例#4
0
/**
 * Get the VMK datum using a bek file (external key)
 *
 * @param dataset The dataset of BitLocker's metadata on the volume
 * @param bek_file The path to the .BEK file to use
 * @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_bekfile2(dis_metadata_t dis_meta,
                          char* bek_file,
                          void** vmk_datum)
{
	// Check parameters
	if(!dis_meta || !vmk_datum)
		return FALSE;

	guid_t key_guid = {0,};
	char rec_id[37] = {0,};

	bitlocker_dataset_t* bek_dataset = NULL;
	uint8_t* recovery_key = NULL;
	size_t rk_size = 0;

	int result = FALSE;
	int fd_bek = 0;


	if(bek_file)
	{
		/* Check if the bek file exists */
		fd_bek = dis_open(bek_file, O_RDONLY);
		if(fd_bek < 0)
		{
			dis_printf(L_ERROR, "Cannot open FVEK file (%s)\n", bek_file);
			return FALSE;
		}
	}
	else
	{
		dis_printf(
			L_ERROR,
			"Using bekfile method (USB) but missing the bekfile name. Abort.\n"
		);
		return FALSE;
	}

	dis_printf(
		L_INFO,
		"Using the bekfile '%s' to decrypt the VMK.\n",
		bek_file
	);

	/*
	 * We need the recovery key id which can be found in the bek file
	 * to find its match in a datum of the volume's metadata
	 */
	if(!get_bek_dataset(fd_bek, (void**) &bek_dataset))
	{
		dis_printf(L_ERROR, "Unable to retrieve the dataset. Abort.\n");
		dis_close(fd_bek);
		return FALSE;
	}

	/* We have what we wanted, so close the file */
	dis_close(fd_bek);


	/* Get the external datum */
	void* dataset = dis_metadata_set_dataset(dis_meta, bek_dataset);
	get_next_datum(
		dis_meta,
		UINT16_MAX,
		DATUMS_VALUE_EXTERNAL_KEY,
		NULL,
		vmk_datum
	);
	dis_metadata_set_dataset(dis_meta, dataset);

	/* Check the result datum */
	if(!*vmk_datum ||
	   !datum_value_type_must_be(*vmk_datum, DATUMS_VALUE_EXTERNAL_KEY))
	{
		dis_printf(
			L_ERROR,
			"Error processing the bekfile: datum of type %hd not found. "
			"Internal failure, abort.\n",
			DATUMS_VALUE_EXTERNAL_KEY
		);
		*vmk_datum = NULL;
		memclean(bek_dataset, bek_dataset->size);
		return FALSE;
	}

	/* Now that we are sure of the type, take care of copying the recovery key id */
	datum_external_t* datum_exte = (datum_external_t*) *vmk_datum;
	memcpy(key_guid, datum_exte->guid, 16);

	format_guid(key_guid, rec_id);
	dis_printf(
		L_INFO,
		"Bekfile GUID found: '%s', looking for the same in metadata...\n",
		rec_id
	);

	/* Grab the datum nested in the last, we will need it to decrypt the VMK */
	if(!get_nested_datumvaluetype(*vmk_datum, DATUMS_VALUE_KEY, vmk_datum) ||
	   !*vmk_datum)
	{
		dis_printf(
			L_ERROR,
			"Error processing the bekfile: no nested datum found. "
			"Internal failure, abort.\n"
		);
		*vmk_datum = NULL;
		memclean(bek_dataset, bek_dataset->size);
		return FALSE;
	}

	if(!get_payload_safe(*vmk_datum, (void**) &recovery_key, &rk_size))
	{
		dis_printf(
			L_ERROR,
			"Error getting the key to decrypt VMK from the bekfile. "
			"Internal failure, abort.\n"
		);
		*vmk_datum = NULL;
		memclean(bek_dataset, bek_dataset->size);
		return FALSE;
	}

	memclean(bek_dataset, bek_dataset->size);


	/*
	 * Now that we have the key to decrypt the VMK, we need to
	 * find the VMK datum in the BitLocker metadata in order to
	 * decrypt the VMK using this already found key in the bekfile
	 */
	if(!get_vmk_datum_from_guid(dis_meta, key_guid, vmk_datum))
	{
		format_guid(key_guid, rec_id);

		dis_printf(
			L_ERROR,
			"\n\tError, can't find a valid and matching VMK datum.\n"
			"\tThe GUID researched was '%s', check if you have the right "
			"bek file for the right volume.\n"
			"\tAbort.\n",
			rec_id
		);
		*vmk_datum = NULL;
		dis_free(recovery_key);
		return FALSE;
	}

	dis_printf(
		L_INFO,
		"VMK datum of id '%s' found. Trying to reach the Key datum...\n",
		rec_id
	);


	/*
	 * We have the datum containing other data, so get in there and take the
	 * nested one with type 5 (aes-ccm)
	 */
	if(!get_nested_datumvaluetype(*vmk_datum, DATUMS_VALUE_AES_CCM, vmk_datum))
	{
		dis_printf(
			L_ERROR,
			"Error looking for the nested datum in the VMK one. "
			"Internal failure, abort.\n"
		);
		*vmk_datum = NULL;
		dis_free(recovery_key);
		return FALSE;
	}


	dis_printf(L_INFO, "Key datum found and payload extracted!\n");

	result = get_vmk(
		(datum_aes_ccm_t*) *vmk_datum,
		recovery_key,
		rk_size,
		(datum_key_t**) vmk_datum
	);

	dis_free(recovery_key);

	return result;
}
示例#5
0
文件: dp-media.c 项目: 10ne1/efivar
ssize_t
_format_media_dn(char *buf, size_t size, const_efidp dp)
{
	ssize_t off = 0;
	switch (dp->subtype) {
	case EFIDP_MEDIA_HD:
		off += format(buf, size, off, "HD(%d,",
			      dp->hd.partition_number);
		switch (dp->hd.signature_type) {
		case EFIDP_HD_SIGNATURE_MBR:
			off += format(buf, size, off,
				      "MBR,0x%"PRIu32",0x%"PRIx64",0x%"PRIx64")",
				      *(char *)dp->hd.signature,
				      dp->hd.start, dp->hd.size);
			break;
		case EFIDP_HD_SIGNATURE_GUID:
			off += format(buf, size, off, "GPT,");
			off += format_guid(buf, size, off,
					   (efi_guid_t *)dp->hd.signature);
			off += format(buf, size, off,
				      ",0x%"PRIx64",0x%"PRIx64")",
				      dp->hd.start, dp->hd.size);
			break;
		default:
			off += format(buf, size, off, "%d,",
				      dp->hd.signature_type);
			off += format_hex(buf, size, off,
					  dp->hd.signature,
					  sizeof(dp->hd.signature));
			off += format(buf, size, off,
				      ",0x%"PRIx64",0x%"PRIx64")",
				      dp->hd.start, dp->hd.size);
			break;
		}
		break;
	case EFIDP_MEDIA_CDROM:
		off += format(buf, size, off,
			      "CDROM(%d,0x%"PRIx64",0x%"PRIx64")",
			      dp->cdrom.boot_catalog_entry,
			      dp->cdrom.partition_rba, dp->cdrom.sectors);
		break;
	case EFIDP_MEDIA_VENDOR:
		off += format_vendor(buf, size, off, "VenMedia", dp);
		break;
	case EFIDP_MEDIA_FILE:
		off += format(buf, size, off, "File(");
		off += format_ucs2(buf, size, off, dp->file.name,
				   (efidp_node_size(dp)
				   - offsetof(efidp_file, name)) / 2);
		off += format(buf, size, off, ")");
		break;
	case EFIDP_MEDIA_PROTOCOL:
		off += format(buf, size, off, "Media(");
		off += format_guid(buf, size, off, &dp->protocol.protocol_guid);
		off += format(buf, size, off, ")");
		break;
	case EFIDP_MEDIA_FIRMWARE_FILE:
		off += format(buf, size, off, "FvFile(");
		off += format_guid(buf, size, off, &dp->protocol.protocol_guid);
		off += format(buf, size, off, ")");
		break;
	case EFIDP_MEDIA_FIRMWARE_VOLUME:
		off += format(buf, size, off, "FvVol(");
		off += format_guid(buf, size, off, &dp->protocol.protocol_guid);
		off += format(buf, size, off, ")");
		break;
	case EFIDP_MEDIA_RELATIVE_OFFSET:
		off = format(buf, size, off, "Offset(0x%"PRIx64",0x%"PRIx64")",
			     dp->relative_offset.first_byte,
			     dp->relative_offset.last_byte);
		break;
	case EFIDP_MEDIA_RAMDISK: {
		struct {
			efi_guid_t guid;
			char label[40];
		} subtypes[] = {
			{ EFIDP_VIRTUAL_DISK_GUID, "VirtualDisk" },
			{ EFIDP_VIRTUAL_CD_GUID, "VirtualCD" },
			{ EFIDP_PERSISTENT_VIRTUAL_DISK_GUID, "PersistentVirtualDisk" },
			{ EFIDP_PERSISTENT_VIRTUAL_CD_GUID, "PersistentVirtualCD" },
			{ efi_guid_empty, "" }
		};
		char *label = NULL;

		for (int i = 0; !efi_guid_is_zero(&subtypes[i].guid); i++) {
			if (efi_guid_cmp(&subtypes[i].guid,
					  &dp->ramdisk.disk_type_guid))
				continue;

			label = subtypes[i].label;
			break;
		}

		if (label) {
			off += format(buf, size, off,
				     "%s(0x%"PRIx64",0x%"PRIx64",%d)", label,
				     dp->ramdisk.start_addr,
				     dp->ramdisk.end_addr,
				     dp->ramdisk.instance_number);
			break;
		}
		off += format(buf, size, off,
			     "Ramdisk(0x%"PRIx64",0x%"PRIx64",%d,",
			     dp->ramdisk.start_addr, dp->ramdisk.end_addr,
			     dp->ramdisk.instance_number);
		off += format_guid(buf, size, off, &dp->ramdisk.disk_type_guid);
		off += format(buf, size, off, ")");
		break;
					   }
	default:
		off += format(buf, size, off, "MediaPath(%d,", dp->subtype);
		off += format_hex(buf, size, off,
				  (uint8_t *)dp+4,
				  (efidp_node_size(dp)-4) / 2);
		off += format(buf,size,off,")");
		break;
	}
	return off;
}