Merge pull request #843 from nsacyber/v3_issue_836-spdm

fix pciids calls from windows machines
This commit is contained in:
D2B8CA1B27286366A8607B6858C0565962613D18D0546480078B520CD7AD705A 2024-10-24 16:11:44 +00:00 committed by GitHub
commit b163691d49
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 38637 additions and 97 deletions

View File

@ -160,8 +160,9 @@ ospackage {
requires('mariadb-server' , '10.3' , GREATER | EQUAL) requires('mariadb-server' , '10.3' , GREATER | EQUAL)
requires('procps-ng', '3.3.15', GREATER | EQUAL) requires('procps-ng', '3.3.15', GREATER | EQUAL)
requires('alternatives', '1.19', GREATER | EQUAL) requires('alternatives', '1.19', GREATER | EQUAL)
requires('hwdata', '0.314', GREATER | EQUAL)
// Post Trans stage (Occurs after required app and postInstall stage) // Post Trans stage (Occurs after required app and postInstall stage)
// Note postInstall wont wait forrequired apps // Note postInstall wont wait for required apps
postTrans 'update-alternatives --set java java-17-openjdk.x86_64' postTrans 'update-alternatives --set java java-17-openjdk.x86_64'
postTrans 'firewall-cmd --add-port=8443/tcp --permanent' postTrans 'firewall-cmd --add-port=8443/tcp --permanent'
postTrans 'firewall-cmd --reload' postTrans 'firewall-cmd --reload'
@ -181,6 +182,7 @@ ospackage {
requires('openjdk-17-jdk', '17.0', GREATER | EQUAL) requires('openjdk-17-jdk', '17.0', GREATER | EQUAL)
requires('mariadb-server' , '10.3' , GREATER | EQUAL) requires('mariadb-server' , '10.3' , GREATER | EQUAL)
requires('curl') requires('curl')
requires('hwdata', '0.314', GREATER | EQUAL)
// Install after required packages // Install after required packages
postInstall 'bash /opt/hirs/aca/scripts/aca/aca_setup.sh -u' postInstall 'bash /opt/hirs/aca/scripts/aca/aca_setup.sh -u'
postInstall 'bash /opt/hirs/aca/scripts/systemd/aca_enable_service.sh' postInstall 'bash /opt/hirs/aca/scripts/systemd/aca_enable_service.sh'

View File

@ -7,6 +7,8 @@ import com.github.marandus.pciid.model.ProgramInterface;
import com.github.marandus.pciid.model.Vendor; import com.github.marandus.pciid.model.Vendor;
import com.github.marandus.pciid.service.PciIdsDatabase; import com.github.marandus.pciid.service.PciIdsDatabase;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import hirs.utils.tpm.eventlog.uefi.UefiConstants;
import lombok.Getter;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import org.bouncycastle.asn1.ASN1UTF8String; import org.bouncycastle.asn1.ASN1UTF8String;
import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.DERUTF8String;
@ -25,30 +27,46 @@ import java.util.List;
@Log4j2 @Log4j2
public final class PciIds { public final class PciIds {
/**
* Track status of pciids file.
*/
@Getter
private static String pciidsFileStatus = UefiConstants.FILESTATUS_NOT_ACCESSIBLE;
/**
* Name of pciids file in code.
*/
private static final String PCIIDS_FILENAME = "/pci.ids";
/** /**
* This pci ids file can be in different places on different distributions. * This pci ids file can be in different places on different distributions.
* Fedora/RHEL/Rocky/CentOS: /usr/share/hwdata/pci.ids
* Debian/Ubuntu: /usr/share/misc/pci.ids
* If the file is not found on the system (such as with Windows systems),
* the file will have to be accessed from code.
*/ */
public static final List<String> PCI_IDS_PATH = public static final List<String> PCI_IDS_PATH =
Collections.unmodifiableList(new ArrayList<>() { Collections.unmodifiableList(new ArrayList<>() {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
{ {
add("/usr/share/hwdata/pci.ids"); add("/usr/share/hwdata/pci.ids");
add("/usr/share/misc/pci.ids"); add("/usr/share/misc/pci.ids");
add("/tmp/pci.ids"); add("/tmp/pci.ids");
} }
}); });
/** /**
* The PCI IDs Database object. * The PCI IDs Database object.
* <p>
* This only needs to be loaded one time. * This only needs to be loaded one time.
* <p>
* The pci ids library protects the data inside the object by making it immutable. * The pci ids library protects the data inside the object by making it immutable.
*/ */
public static final PciIdsDatabase DB = new PciIdsDatabase(); public static final PciIdsDatabase DB = new PciIdsDatabase();
//Configure the PCI IDs Database object.
static { static {
if (!DB.isReady()) { if (!DB.isReady()) {
// if pciids file is found on the system, then process using this file
String dbFile = null; String dbFile = null;
for (final String path : PCI_IDS_PATH) { for (final String path : PCI_IDS_PATH) {
if ((new File(path)).exists()) { if ((new File(path)).exists()) {
@ -57,11 +75,13 @@ public final class PciIds {
break; break;
} }
} }
if (dbFile != null) {
if(dbFile != null) {
InputStream is = null; InputStream is = null;
try { try {
is = new FileInputStream(dbFile); is = new FileInputStream(dbFile);
DB.loadStream(is); DB.loadStream(is);
pciidsFileStatus = UefiConstants.FILESTATUS_FROM_FILESYSTEM;
} catch (IOException e) { } catch (IOException e) {
// DB will not be ready, hardware IDs will not be translated // DB will not be ready, hardware IDs will not be translated
dbFile = null; dbFile = null;
@ -75,25 +95,48 @@ public final class PciIds {
} }
} }
} }
// if pciids file is not found on the system or not accessible, then attempt to grab it from code
if(pciidsFileStatus == UefiConstants.FILESTATUS_NOT_ACCESSIBLE) {
InputStream isFromCode = PciIds.class.getResourceAsStream(PCIIDS_FILENAME);
if(isFromCode != null) {
try {
DB.loadStream(isFromCode);
pciidsFileStatus = UefiConstants.FILESTATUS_FROM_CODE;
} catch (IOException e) {
// DB will not be ready, hardware IDs will not be translated
} finally {
try {
isFromCode.close();
} catch (IOException e) {
}
}
}
}
// if pciids file is not accessible on system or from within code, then log error
if(pciidsFileStatus == UefiConstants.FILESTATUS_NOT_ACCESSIBLE) {
log.info("PCI IDs file was NOT accessible from within the system or within the code");
}
} }
} }
/** /**
* Default private constructor so checkstyles doesn't complain. * Default private constructor so checkstyles doesn't complain
*/ */
private PciIds() { private PciIds() { }
}
/** /**
* Look up the vendor name from the PCI IDs list, if the input string contains an ID. * Look up the vendor name from the PCI IDs list, if the input string contains an ID.
* If any part of this fails, return the original manufacturer value. * If any part of this fails, return the original manufacturer value.
*
* @param refManufacturer DERUTF8String, likely from a ComponentIdentifier * @param refManufacturer DERUTF8String, likely from a ComponentIdentifier
* @return DERUTF8String with the discovered vendor name, or the original manufacturer value. * @return DERUTF8String with the discovered vendor name, or the original manufacturer value.
*/ */
public static ASN1UTF8String translateVendor(final ASN1UTF8String refManufacturer) { public static ASN1UTF8String translateVendor(final ASN1UTF8String refManufacturer) {
ASN1UTF8String manufacturer = refManufacturer; ASN1UTF8String manufacturer = refManufacturer;
if (manufacturer != null && manufacturer.getString().trim().matches("^[0-9A-Fa-f]{4}$")) { if (!pciidsFileStatus.equals(UefiConstants.FILESTATUS_NOT_ACCESSIBLE)
&& manufacturer != null
&& manufacturer.getString().trim().matches("^[0-9A-Fa-f]{4}$")) {
Vendor ven = DB.findVendor(manufacturer.getString().toLowerCase()); Vendor ven = DB.findVendor(manufacturer.getString().toLowerCase());
if (ven != null && !Strings.isNullOrEmpty(ven.getName())) { if (ven != null && !Strings.isNullOrEmpty(ven.getName())) {
manufacturer = new DERUTF8String(ven.getName()); manufacturer = new DERUTF8String(ven.getName());
@ -105,13 +148,14 @@ public final class PciIds {
/** /**
* Look up the vendor name from the PCI IDs list, if the input string contains an ID. * Look up the vendor name from the PCI IDs list, if the input string contains an ID.
* If any part of this fails, return the original manufacturer value. * If any part of this fails, return the original manufacturer value.
*
* @param refManufacturer String, likely from a ComponentResult * @param refManufacturer String, likely from a ComponentResult
* @return String with the discovered vendor name, or the original manufacturer value. * @return String with the discovered vendor name, or the original manufacturer value.
*/ */
public static String translateVendor(final String refManufacturer) { public static String translateVendor(final String refManufacturer) {
String manufacturer = refManufacturer; String manufacturer = refManufacturer;
if (manufacturer != null && manufacturer.trim().matches("^[0-9A-Fa-f]{4}$")) { if (!pciidsFileStatus.equals(UefiConstants.FILESTATUS_NOT_ACCESSIBLE)
&& manufacturer != null
&& manufacturer.trim().matches("^[0-9A-Fa-f]{4}$")) {
Vendor ven = DB.findVendor(manufacturer.toLowerCase()); Vendor ven = DB.findVendor(manufacturer.toLowerCase());
if (ven != null && !Strings.isNullOrEmpty(ven.getName())) { if (ven != null && !Strings.isNullOrEmpty(ven.getName())) {
manufacturer = ven.getName(); manufacturer = ven.getName();
@ -124,16 +168,16 @@ public final class PciIds {
* Look up the device name from the PCI IDs list, if the input strings contain IDs. * Look up the device name from the PCI IDs list, if the input strings contain IDs.
* The Device lookup requires the Vendor ID AND the Device ID to be valid values. * The Device lookup requires the Vendor ID AND the Device ID to be valid values.
* If any part of this fails, return the original model value. * If any part of this fails, return the original model value.
*
* @param refManufacturer ASN1UTF8String, likely from a ComponentIdentifier * @param refManufacturer ASN1UTF8String, likely from a ComponentIdentifier
* @param refModel ASN1UTF8String, likely from a ComponentIdentifier * @param refModel ASN1UTF8String, likely from a ComponentIdentifier
* @return ASN1UTF8String with the discovered device name, or the original model value. * @return ASN1UTF8String with the discovered device name, or the original model value.
*/ */
public static ASN1UTF8String translateDevice(final ASN1UTF8String refManufacturer, public static ASN1UTF8String translateDevice(final ASN1UTF8String refManufacturer,
final ASN1UTF8String refModel) { final ASN1UTF8String refModel) {
ASN1UTF8String manufacturer = refManufacturer; ASN1UTF8String manufacturer = refManufacturer;
ASN1UTF8String model = refModel; ASN1UTF8String model = refModel;
if (manufacturer != null if (!pciidsFileStatus.equals(UefiConstants.FILESTATUS_NOT_ACCESSIBLE)
&& manufacturer != null
&& model != null && model != null
&& manufacturer.getString().trim().matches("^[0-9A-Fa-f]{4}$") && manufacturer.getString().trim().matches("^[0-9A-Fa-f]{4}$")
&& model.getString().trim().matches("^[0-9A-Fa-f]{4}$")) { && model.getString().trim().matches("^[0-9A-Fa-f]{4}$")) {
@ -150,15 +194,15 @@ public final class PciIds {
* Look up the device name from the PCI IDs list, if the input strings contain IDs. * Look up the device name from the PCI IDs list, if the input strings contain IDs.
* The Device lookup requires the Vendor ID AND the Device ID to be valid values. * The Device lookup requires the Vendor ID AND the Device ID to be valid values.
* If any part of this fails, return the original model value. * If any part of this fails, return the original model value.
*
* @param refManufacturer String, likely from a ComponentResult * @param refManufacturer String, likely from a ComponentResult
* @param refModel String, likely from a ComponentResult * @param refModel String, likely from a ComponentResult
* @return String with the discovered device name, or the original model value. * @return String with the discovered device name, or the original model value.
*/ */
public static String translateDevice(final String refManufacturer, public static String translateDevice(final String refManufacturer,
final String refModel) { final String refModel) {
String model = refModel; String model = refModel;
if (refManufacturer != null if (!pciidsFileStatus.equals(UefiConstants.FILESTATUS_NOT_ACCESSIBLE)
&& refManufacturer != null
&& model != null && model != null
&& refManufacturer.trim().matches("^[0-9A-Fa-f]{4}$") && refManufacturer.trim().matches("^[0-9A-Fa-f]{4}$")
&& model.trim().matches("^[0-9A-Fa-f]{4}$")) { && model.trim().matches("^[0-9A-Fa-f]{4}$")) {
@ -174,39 +218,26 @@ public final class PciIds {
/** /**
* Look up the device class name from the PCI IDs list, if the input string contains an ID. * Look up the device class name from the PCI IDs list, if the input string contains an ID.
* If any part of this fails, return the original manufacturer value. * If any part of this fails, return the original manufacturer value.
*
* @param refClassCode String, formatted as 2 characters (1 byte) for each of the 3 categories * @param refClassCode String, formatted as 2 characters (1 byte) for each of the 3 categories
* Example "010802": * Example "010802":
* Class: "01" * Class: "01"
* Subclass: "08" * Subclass: "08"
* Programming Interface: "02" * Programming Interface: "02"
* @return List<String> 3-element list with the class code * @return List<String> 3-element list with the class code
* 1st element: human-readable description of Class * 1st element: human-readable description of Class
* 2nd element: human-readable description of Subclass * 2nd element: human-readable description of Subclass
* 3rd element: human-readable description of Programming Interface * 3rd element: human-readable description of Programming Interface
*/ */
public static List<String> translateDeviceClass(final String refClassCode) { public static List<String> translateDeviceClass(final String refClassCode) {
List<String> translatedClassCode = new ArrayList<>(); List<String> translatedClassCode = new ArrayList<>();
String classCode = refClassCode; String classCode = refClassCode;
if (classCode != null && classCode.trim().matches("^[0-9A-Fa-f]{6}$")) { if (!pciidsFileStatus.equals(UefiConstants.FILESTATUS_NOT_ACCESSIBLE)
final int startIndexOfDeviceClass = 0; && classCode != null
final int endIndexOfDeviceClass = 2; && classCode.trim().matches("^[0-9A-Fa-f]{6}$")) {
String deviceClass = String deviceClass = classCode.substring(0, 2).toLowerCase();
classCode.substring(startIndexOfDeviceClass, endIndexOfDeviceClass).toLowerCase(); String deviceSubclass = classCode.substring(2, 4).toLowerCase();
String programInterface = classCode.substring(4, 6).toLowerCase();
final int startIndexOfDeviceSubclass = 2;
final int endIndexOfDeviceSubclass = 4;
String deviceSubclass =
classCode.substring(startIndexOfDeviceSubclass, endIndexOfDeviceSubclass)
.toLowerCase();
final int startIndexOfProgramInterface = 4;
final int endIndexOfProgramInterface = 6;
final String programInterface =
classCode.substring(startIndexOfProgramInterface, endIndexOfProgramInterface)
.toLowerCase();
translatedClassCode.add(deviceClass); translatedClassCode.add(deviceClass);
translatedClassCode.add(deviceSubclass); translatedClassCode.add(deviceSubclass);
translatedClassCode.add(programInterface); translatedClassCode.add(programInterface);
@ -225,4 +256,4 @@ public final class PciIds {
} }
return translatedClassCode; return translatedClassCode;
} }
} }

View File

@ -20,9 +20,6 @@ import java.security.cert.CertificateException;
import java.util.Collection; import java.util.Collection;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILESTATUS_FROM_FILESYSTEM;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILESTATUS_NOT_ACCESSIBLE;
/** /**
* Class for handling different formats of TCG Event logs. * Class for handling different formats of TCG Event logs.
*/ */
@ -88,7 +85,16 @@ public final class TCGEventLog {
* and if that event causes a different status. * and if that event causes a different status.
*/ */
@Getter @Getter
private String vendorTableFileStatus = FILESTATUS_FROM_FILESYSTEM; private String vendorTableFileStatus = UefiConstants.FILESTATUS_FROM_FILESYSTEM;
/**
* Track status of pci.ids
* This is only used if there is an event that uses functions from the pciids class.
* Default is normal status (normal status is from-filesystem).
* Status will only change IF there is an event that uses pciids file, and the file
* causes a different status.
*/
@Getter
private String pciidsFileStatus = UefiConstants.FILESTATUS_FROM_FILESYSTEM;
/** /**
* Default blank object constructor. * Default blank object constructor.
@ -169,11 +175,17 @@ public final class TCGEventLog {
// the if statement is executed // the if statement is executed
// [new event file status = eventList.get(eventNumber-1).getVendorTableFileStatus()] // [new event file status = eventList.get(eventNumber-1).getVendorTableFileStatus()]
// (ie. if the new file status is not-accessible or from-code, then want to update) // (ie. if the new file status is not-accessible or from-code, then want to update)
if ((vendorTableFileStatus != FILESTATUS_NOT_ACCESSIBLE) if ((vendorTableFileStatus != UefiConstants.FILESTATUS_NOT_ACCESSIBLE)
&& (eventList.get(eventNumber - 1).getVendorTableFileStatus() && (eventList.get(eventNumber - 1).getVendorTableFileStatus()
!= FILESTATUS_FROM_FILESYSTEM)) { != UefiConstants.FILESTATUS_FROM_FILESYSTEM)) {
vendorTableFileStatus = eventList.get(eventNumber - 1).getVendorTableFileStatus(); vendorTableFileStatus = eventList.get(eventNumber - 1).getVendorTableFileStatus();
} }
//similar to above with vendor-table.json file, but here with pci.ids file
if ((pciidsFileStatus != UefiConstants.FILESTATUS_NOT_ACCESSIBLE)
&& (eventList.get(eventNumber - 1).getPciidsFileStatus()
!= UefiConstants.FILESTATUS_FROM_FILESYSTEM)) {
pciidsFileStatus = eventList.get(eventNumber - 1).getPciidsFileStatus();
}
} }
calculatePcrValues(); calculatePcrValues();
} }

View File

@ -127,6 +127,16 @@ public class TpmPcrEvent {
@Getter @Getter
private String vendorTableFileStatus = FILESTATUS_FROM_FILESYSTEM; private String vendorTableFileStatus = FILESTATUS_FROM_FILESYSTEM;
/**
* Track status of pci.ids
* This is only used for events that access the pci.ids file.
* Default is normal status (normal status is from-filesystem).
* Status will only change IF this is an event that uses this file,
* and if that event causes a different status.
*/
@Getter
private String pciidsFileStatus = FILESTATUS_FROM_FILESYSTEM;
/** /**
* Constructor. * Constructor.
* *
@ -438,6 +448,7 @@ public class TpmPcrEvent {
specVersion = noAction.getSpecVersion(); specVersion = noAction.getSpecVersion();
specErrataVersion = noAction.getSpecErrataVersion(); specErrataVersion = noAction.getSpecErrataVersion();
} }
pciidsFileStatus = noAction.getPciidsFileStatus();
break; break;
case EvConstants.EV_SEPARATOR: case EvConstants.EV_SEPARATOR:
if (EvPostCode.isAscii(content)) { if (EvPostCode.isAscii(content)) {
@ -523,7 +534,9 @@ public class TpmPcrEvent {
break; break;
case EvConstants.EV_EFI_SPDM_FIRMWARE_BLOB: case EvConstants.EV_EFI_SPDM_FIRMWARE_BLOB:
case EvConstants.EV_EFI_SPDM_FIRMWARE_CONFIG: case EvConstants.EV_EFI_SPDM_FIRMWARE_CONFIG:
description += "Event Content:\n" + new EvEfiSpdmDeviceSecurityEvent(content).toString(); EvEfiSpdmDeviceSecurityEvent efiSpdmDse = new EvEfiSpdmDeviceSecurityEvent(content);
description += "Event Content:\n" + efiSpdmDse.toString();
pciidsFileStatus = efiSpdmDse.getPciidsFileStatus();
break; break;
default: default:
description += " Unknown Event found" + "\n"; description += " Unknown Event found" + "\n";

View File

@ -1,5 +1,6 @@
package hirs.utils.tpm.eventlog.events; package hirs.utils.tpm.eventlog.events;
import hirs.utils.tpm.eventlog.uefi.UefiConstants;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@ -44,7 +45,7 @@ public abstract class DeviceSecurityEvent {
* DeviceSecurityEventDataContext Object. * DeviceSecurityEventDataContext Object.
*/ */
@Getter @Getter
private DeviceSecurityEventDataDeviceContext dsedDevContext = null; private DeviceSecurityEventDataPciContext dsedPciContext = null;
/** /**
* Device type. * Device type.
@ -60,6 +61,17 @@ public abstract class DeviceSecurityEvent {
@Getter @Getter
private String deviceContextInfo = ""; private String deviceContextInfo = "";
/**
* Track status of pci.ids
* This is only used for events that access the pci.ids file.
* (In this class, this is only needed if DeviceSecurityEvent includes a DeviceSecurityEventDataPciContext)
* Default is normal status (normal status is from-filesystem).
* Status will only change IF this is an event that uses this file,
* and if that event causes a different status.
*/
@Getter
private String pciidsFileStatus = UefiConstants.FILESTATUS_FROM_FILESYSTEM;
/** /**
* DeviceSecurityEventData Default Constructor. * DeviceSecurityEventData Default Constructor.
* *
@ -82,8 +94,11 @@ public abstract class DeviceSecurityEvent {
if (deviceType == DeviceSecurityEventDataDeviceContext.DEVICE_TYPE_NONE) { if (deviceType == DeviceSecurityEventDataDeviceContext.DEVICE_TYPE_NONE) {
deviceContextInfo = "\n No Device Context (indicated by device type value of 0)"; deviceContextInfo = "\n No Device Context (indicated by device type value of 0)";
} else if (deviceType == DeviceSecurityEventDataDeviceContext.DEVICE_TYPE_PCI) { } else if (deviceType == DeviceSecurityEventDataDeviceContext.DEVICE_TYPE_PCI) {
dsedDevContext = new DeviceSecurityEventDataPciContext(dsedDeviceContextBytes); dsedPciContext = new DeviceSecurityEventDataPciContext(dsedDeviceContextBytes);
deviceContextInfo = dsedDevContext.toString(); deviceContextInfo = dsedPciContext.toString();
// getPciidsFileStatus() must be called after DeviceSecurityEventDataPciContext.toString(),
// because the toString function is where the pciids db gets set up and used
pciidsFileStatus = dsedPciContext.getPciidsFileStatus();
} else if (deviceType == DeviceSecurityEventDataDeviceContext.DEVICE_TYPE_USB) { } else if (deviceType == DeviceSecurityEventDataDeviceContext.DEVICE_TYPE_USB) {
deviceContextInfo = " Device Type: USB - To be implemented"; deviceContextInfo = " Device Type: USB - To be implemented";
} else { } else {

View File

@ -1,6 +1,8 @@
package hirs.utils.tpm.eventlog.events; package hirs.utils.tpm.eventlog.events;
import hirs.utils.HexUtils; import hirs.utils.HexUtils;
import hirs.utils.PciIds;
import hirs.utils.tpm.eventlog.uefi.UefiConstants;
import lombok.Getter; import lombok.Getter;
import java.util.List; import java.util.List;
@ -69,6 +71,12 @@ public class DeviceSecurityEventDataPciContext extends DeviceSecurityEventDataDe
@Getter @Getter
private String subsystemId = ""; private String subsystemId = "";
/**
* Track status of pci.ids file.
*/
@Getter
private String pciidsFileStatus = UefiConstants.FILESTATUS_NOT_ACCESSIBLE;
/** /**
* DeviceSecurityEventDataPciContext Constructor. * DeviceSecurityEventDataPciContext Constructor.
* *
@ -122,6 +130,13 @@ public class DeviceSecurityEventDataPciContext extends DeviceSecurityEventDataDe
dSEDpciContextInfo += super.toString(); dSEDpciContextInfo += super.toString();
dSEDpciContextInfo += " Device Type = PCI\n"; dSEDpciContextInfo += " Device Type = PCI\n";
dSEDpciContextInfo += " Vendor = " + translateVendor(vendorId) + "\n"; dSEDpciContextInfo += " Vendor = " + translateVendor(vendorId) + "\n";
// the above call to translateVendor() is the first location in this class where
// a function in pciids class is called
// thus, if pciids db has not previously been set up, this call will trigger that setup
// the setup will look for the pciids file; need to check and store the status of that file
pciidsFileStatus = PciIds.getPciidsFileStatus();
dSEDpciContextInfo += " Device = " + translateDevice(vendorId, deviceId) + "\n"; dSEDpciContextInfo += " Device = " + translateDevice(vendorId, deviceId) + "\n";
dSEDpciContextInfo += " RevisionID = " + revisionId + "\n"; dSEDpciContextInfo += " RevisionID = " + revisionId + "\n";
@ -133,7 +148,7 @@ public class DeviceSecurityEventDataPciContext extends DeviceSecurityEventDataDe
dSEDpciContextInfo += " Subclass = " + classCodeList.get(1) + "\n"; dSEDpciContextInfo += " Subclass = " + classCodeList.get(1) + "\n";
dSEDpciContextInfo += " Programming Interface = " + classCodeList.get(2) + "\n"; dSEDpciContextInfo += " Programming Interface = " + classCodeList.get(2) + "\n";
} else { } else {
dSEDpciContextInfo += " ** Class code could not be determined **"; dSEDpciContextInfo += " (Class code could not be determined)\n";
} }
dSEDpciContextInfo += " SubsystemVendor = " + translateVendor(subsystemVendorId) + "\n"; dSEDpciContextInfo += " SubsystemVendor = " + translateVendor(subsystemVendorId) + "\n";
dSEDpciContextInfo += " Subsystem = " + translateDevice(subsystemVendorId, subsystemId) + "\n"; dSEDpciContextInfo += " Subsystem = " + translateDevice(subsystemVendorId, subsystemId) + "\n";

View File

@ -2,6 +2,7 @@ package hirs.utils.tpm.eventlog.events;
import hirs.utils.HexUtils; import hirs.utils.HexUtils;
import hirs.utils.tpm.eventlog.uefi.UefiConstants; import hirs.utils.tpm.eventlog.uefi.UefiConstants;
import lombok.Getter;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@ -45,6 +46,16 @@ public class EvEfiSpdmDeviceSecurityEvent {
*/ */
private String spdmInfo = ""; private String spdmInfo = "";
/**
* Track status of pci.ids
* This is only used for events that access the pci.ids file.
* Default is normal status (normal status is from-filesystem).
* Status will only change IF this is an event that uses this file,
* and if that event causes a different status.
*/
@Getter
private String pciidsFileStatus = UefiConstants.FILESTATUS_FROM_FILESYSTEM;
/** /**
* EvEfiSpdmFirmwareBlob constructor. * EvEfiSpdmFirmwareBlob constructor.
* *
@ -72,6 +83,7 @@ public class EvEfiSpdmDeviceSecurityEvent {
if (dsedVersion.equals("0200")) { if (dsedVersion.equals("0200")) {
dsed = new DeviceSecurityEventData2(eventData); dsed = new DeviceSecurityEventData2(eventData);
spdmInfo += dsed.toString(); spdmInfo += dsed.toString();
pciidsFileStatus = dsed.getPciidsFileStatus();
} else { } else {
spdmInfo += " Incompatible version for DeviceSecurityEventData2: " + dsedVersion + "\n"; spdmInfo += " Incompatible version for DeviceSecurityEventData2: " + dsedVersion + "\n";
} }
@ -82,6 +94,7 @@ public class EvEfiSpdmDeviceSecurityEvent {
if (dsedVersion.equals("0100")) { if (dsedVersion.equals("0100")) {
dsed = new DeviceSecurityEventData(eventData); dsed = new DeviceSecurityEventData(eventData);
spdmInfo += dsed.toString(); spdmInfo += dsed.toString();
pciidsFileStatus = dsed.getPciidsFileStatus();
} else { } else {
spdmInfo += " Incompatible version for DeviceSecurityEventData: " + dsedVersion + "\n"; spdmInfo += " Incompatible version for DeviceSecurityEventData: " + dsedVersion + "\n";
} }

View File

@ -53,6 +53,16 @@ public class EvNoAction {
@Getter @Getter
private String noActionInfo = ""; private String noActionInfo = "";
/**
* Track status of pci.ids
* This is only used for events that access the pci.ids file.
* Default is normal status (normal status is from-filesystem).
* Status will only change IF this is an event that uses this file,
* and if that event causes a different status.
*/
@Getter
private String pciidsFileStatus = UefiConstants.FILESTATUS_FROM_FILESYSTEM;
/** /**
* EvNoAction constructor. * EvNoAction constructor.
* *
@ -78,6 +88,7 @@ public class EvNoAction {
} else if (signature.contains("NvIndexInstance")) { } else if (signature.contains("NvIndexInstance")) {
NvIndexInstanceEventLogData nvIndexInstanceEvent = new NvIndexInstanceEventLogData(eventData); NvIndexInstanceEventLogData nvIndexInstanceEvent = new NvIndexInstanceEventLogData(eventData);
noActionInfo += nvIndexInstanceEvent.toString(); noActionInfo += nvIndexInstanceEvent.toString();
pciidsFileStatus = nvIndexInstanceEvent.getPciidsFileStatus();
} else if (signature.contains("NvIndexDynamic")) { } else if (signature.contains("NvIndexDynamic")) {
NvIndexDynamicEventLogData nvIndexDynamicEvent = new NvIndexDynamicEventLogData(eventData); NvIndexDynamicEventLogData nvIndexDynamicEvent = new NvIndexDynamicEventLogData(eventData);
noActionInfo += nvIndexDynamicEvent.toString(); noActionInfo += nvIndexDynamicEvent.toString();

View File

@ -1,6 +1,8 @@
package hirs.utils.tpm.eventlog.events; package hirs.utils.tpm.eventlog.events;
import hirs.utils.HexUtils; import hirs.utils.HexUtils;
import hirs.utils.tpm.eventlog.uefi.UefiConstants;
import lombok.Getter;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@ -8,19 +10,19 @@ import java.nio.charset.StandardCharsets;
* Class to process the NV_INDEX_DYNAMIC_EVENT_LOG_DATA per PFP. * Class to process the NV_INDEX_DYNAMIC_EVENT_LOG_DATA per PFP.
* Per PFP, the first 16 bytes of the structure are a String based identifier (Signature), * Per PFP, the first 16 bytes of the structure are a String based identifier (Signature),
* which are a NULL-terminated ASCII string "NvIndexDynamic". * which are a NULL-terminated ASCII string "NvIndexDynamic".
* <p> *
* HEADERS defined by PFP v1.06 Rev 52. * HEADERS defined by PFP v1.06 Rev 52.
* Certain fields are common to both ..HEADER and ..HEADER2, and are noted below the structures. * Certain fields are common to both ..HEADER and ..HEADER2, and are noted below the structures.
* <p> * <p>
* typedef struct tdNV_INDEX_DYNAMIC_EVENT_LOG_DATA { * typedef struct tdNV_INDEX_DYNAMIC_EVENT_LOG_DATA {
* BYTE Signature[16]; * BYTE Signature[16];
* UINT16 Version; * UINT16 Version;
* UINT8[6] Reserved; * UINT8[6] Reserved;
* UINT64 UID; * UINT64 UID;
* UINT16 DescriptionSize; * UINT16 DescriptionSize;
* UINT8 Description[DescriptionSize]; * UINT8 Description[DescriptionSize];
* UINT16 DataSize; * UINT16 DataSize;
* DEVICE_SECURITY_EVENT_DATA2 Data[DataSize]; * UINT8 Data[DataSize];
* } NV_INDEX_DYNAMIC_EVENT_LOG_DATA; * } NV_INDEX_DYNAMIC_EVENT_LOG_DATA;
* <p> * <p>
*/ */
@ -43,16 +45,13 @@ public class NvIndexDynamicEventLogData {
*/ */
public NvIndexDynamicEventLogData(final byte[] eventData) { public NvIndexDynamicEventLogData(final byte[] eventData) {
final int signatureBytesSize = 16; byte[] signatureBytes = new byte[16];
byte[] signatureBytes = new byte[signatureBytesSize]; System.arraycopy(eventData, 0, signatureBytes, 0, 16);
System.arraycopy(eventData, 0, signatureBytes, 0, signatureBytesSize);
signature = new String(signatureBytes, StandardCharsets.UTF_8); signature = new String(signatureBytes, StandardCharsets.UTF_8);
signature = signature.replaceAll("[^\\P{C}\t\r\n]", ""); // remove null characters signature = signature.replaceAll("[^\\P{C}\t\r\n]", ""); // remove null characters
final int versionBytesSize = 2; byte[] versionBytes = new byte[2];
final int eventDataSrcIndex1 = 16; System.arraycopy(eventData, 16, versionBytes, 0, 2);
byte[] versionBytes = new byte[versionBytesSize];
System.arraycopy(eventData, eventDataSrcIndex1, versionBytes, 0, versionBytesSize);
String nvIndexVersion = HexUtils.byteArrayToHexString(versionBytes); String nvIndexVersion = HexUtils.byteArrayToHexString(versionBytes);
if (nvIndexVersion.isEmpty()) { if (nvIndexVersion.isEmpty()) {
nvIndexVersion = "version not readable"; nvIndexVersion = "version not readable";
@ -61,28 +60,23 @@ public class NvIndexDynamicEventLogData {
nvIndexDynamicInfo += " Nv Index Dynamic Version = " + nvIndexVersion + "\n"; nvIndexDynamicInfo += " Nv Index Dynamic Version = " + nvIndexVersion + "\n";
// 6 bytes of Reserved data // 6 bytes of Reserved data
final int uidBytesSize = 8;
final int eventDataSrcIndex2 = 24; byte[] uidBytes = new byte[8];
byte[] uidBytes = new byte[uidBytesSize]; System.arraycopy(eventData, 24, uidBytes, 0, 8);
System.arraycopy(eventData, eventDataSrcIndex2, uidBytes, 0, uidBytesSize);
String uid = HexUtils.byteArrayToHexString(uidBytes); String uid = HexUtils.byteArrayToHexString(uidBytes);
nvIndexDynamicInfo += " UID = " + uid + "\n"; nvIndexDynamicInfo += " UID = " + uid + "\n";
final int descriptionSizeBytesLength = 2; byte[] descriptionSizeBytes = new byte[2];
final int eventDataSrcIndex3 = 32; System.arraycopy(eventData, 32, descriptionSizeBytes, 0, 2);
byte[] descriptionSizeBytes = new byte[descriptionSizeBytesLength];
System.arraycopy(eventData, eventDataSrcIndex3, descriptionSizeBytes, 0, descriptionSizeBytesLength);
int descriptionSize = HexUtils.leReverseInt(descriptionSizeBytes); int descriptionSize = HexUtils.leReverseInt(descriptionSizeBytes);
final int eventDataSrcIndex4 = 34;
byte[] descriptionBytes = new byte[descriptionSize]; byte[] descriptionBytes = new byte[descriptionSize];
System.arraycopy(eventData, eventDataSrcIndex4, descriptionBytes, 0, descriptionSize); System.arraycopy(eventData, 34, descriptionBytes, 0, descriptionSize);
String description = new String(descriptionBytes, StandardCharsets.UTF_8); String description = new String(descriptionBytes, StandardCharsets.UTF_8);
description = description.replaceAll("[^\\P{C}\t\r\n]", ""); // remove null characters description = description.replaceAll("[^\\P{C}\t\r\n]", ""); // remove null characters
nvIndexDynamicInfo += " Description = " + description + "\n"; nvIndexDynamicInfo += " Description = " + description + "\n";
final int dataSizeOffset = 34; int dataSizeStartByte = 34 + descriptionSize;
int dataSizeStartByte = dataSizeOffset + descriptionSize;
byte[] dataSizeBytes = new byte[2]; byte[] dataSizeBytes = new byte[2];
System.arraycopy(eventData, dataSizeStartByte, dataSizeBytes, 0, 2); System.arraycopy(eventData, dataSizeStartByte, dataSizeBytes, 0, 2);
int dataSize = HexUtils.leReverseInt(dataSizeBytes); int dataSize = HexUtils.leReverseInt(dataSizeBytes);
@ -102,4 +96,4 @@ public class NvIndexDynamicEventLogData {
public String toString() { public String toString() {
return nvIndexDynamicInfo; return nvIndexDynamicInfo;
} }
} }

View File

@ -1,6 +1,8 @@
package hirs.utils.tpm.eventlog.events; package hirs.utils.tpm.eventlog.events;
import hirs.utils.HexUtils; import hirs.utils.HexUtils;
import hirs.utils.tpm.eventlog.uefi.UefiConstants;
import lombok.Getter;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@ -38,6 +40,16 @@ public class NvIndexInstanceEventLogData {
*/ */
private String nvIndexInstanceInfo = ""; private String nvIndexInstanceInfo = "";
/**
* Track status of pci.ids
* This is only used for events that access the pci.ids file.
* Default is normal status (normal status is from-filesystem).
* Status will only change IF this is an event that uses this file,
* and if that event causes a different status.
*/
@Getter
private String pciidsFileStatus = UefiConstants.FILESTATUS_FROM_FILESYSTEM;
/** /**
* NvIndexInstanceEventLogData constructor. * NvIndexInstanceEventLogData constructor.
* *
@ -89,6 +101,7 @@ public class NvIndexInstanceEventLogData {
if (dsedVersion.equals("0200")) { if (dsedVersion.equals("0200")) {
dsed = new DeviceSecurityEventData2(dsedEventData); dsed = new DeviceSecurityEventData2(dsedEventData);
nvIndexInstanceInfo += dsed.toString(); nvIndexInstanceInfo += dsed.toString();
pciidsFileStatus = dsed.getPciidsFileStatus();
} else { } else {
nvIndexInstanceInfo += " Incompatible version for DeviceSecurityEventData2: " nvIndexInstanceInfo += " Incompatible version for DeviceSecurityEventData2: "
+ dsedVersion + "\n"; + dsedVersion + "\n";

View File

@ -10,10 +10,6 @@ import java.nio.file.FileSystems;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.UUID; import java.util.UUID;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILESTATUS_FROM_CODE;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILESTATUS_FROM_FILESYSTEM;
import static hirs.utils.tpm.eventlog.uefi.UefiConstants.FILESTATUS_NOT_ACCESSIBLE;
/** /**
* Class to process GUID per the UEFI specification * Class to process GUID per the UEFI specification
* GUIDs are essentially UUID as defined by RFC-1422, however Microsoft refers to GUIDS. * GUIDs are essentially UUID as defined by RFC-1422, however Microsoft refers to GUIDS.
@ -44,7 +40,7 @@ public class UefiGuid {
* Track status of vendor-table.json. * Track status of vendor-table.json.
*/ */
@Getter @Getter
private String vendorTableFileStatus = FILESTATUS_NOT_ACCESSIBLE; private String vendorTableFileStatus = UefiConstants.FILESTATUS_NOT_ACCESSIBLE;
/** /**
* guid byte array. * guid byte array.
@ -78,12 +74,12 @@ public class UefiGuid {
"VendorTable"); "VendorTable");
if (!isVendorTableReferenceHandleEmpty()) { if (!isVendorTableReferenceHandleEmpty()) {
vendorTableFileStatus = FILESTATUS_FROM_FILESYSTEM; vendorTableFileStatus = UefiConstants.FILESTATUS_FROM_FILESYSTEM;
} else { } else {
// could not access vendor-table.json from filesystem, so attempt to access from code // could not access vendor-table.json from filesystem, so attempt to access from code
uefiVendorRef = JsonUtils.getSpecificJsonObject(JSON_FILENAME, "VendorTable"); uefiVendorRef = JsonUtils.getSpecificJsonObject(JSON_FILENAME, "VendorTable");
if (!isVendorTableReferenceHandleEmpty()) { if (!isVendorTableReferenceHandleEmpty()) {
vendorTableFileStatus = FILESTATUS_FROM_CODE; vendorTableFileStatus = UefiConstants.FILESTATUS_FROM_CODE;
} }
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -119,9 +119,11 @@ ospackage {
buildRpm { buildRpm {
arch = X86_64 arch = X86_64
requires('hwdata', '0.314', GREATER | EQUAL)
} }
buildDeb { buildDeb {
arch = 'amd64' arch = 'amd64'
requires('hwdata', '0.314', GREATER | EQUAL)
} }
} }

View File

@ -136,13 +136,24 @@ final class Main {
+ evLog.getEventList().size() + " events:\n\n"); + evLog.getEventList().size() + " events:\n\n");
} }
if (evLog.getVendorTableFileStatus() == FILESTATUS_NOT_ACCESSIBLE) { if (evLog.getVendorTableFileStatus() == FILESTATUS_NOT_ACCESSIBLE) {
writeOut("*** WARNING: The file vendor-table.json was not accessible from the " writeOut("*** WARNING: "
+ "filesystem or the code, so some event data shown in the output of this " + "The file vendor-table.json was not accessible from the filesystem or the code,\n"
+ "tool may be outdated or omitted.\n\n"); + " so some event data shown in the output of this tool may be outdated\n"
+ " or omitted.\n\n");
} else if (evLog.getVendorTableFileStatus() == FILESTATUS_FROM_CODE) { } else if (evLog.getVendorTableFileStatus() == FILESTATUS_FROM_CODE) {
writeOut("*** NOTE: " writeOut("*** NOTE: "
+ "The file vendor-table.json file was not accessible from the filesystem,\n" + "The file vendor-table.json file was not accessible from the filesystem,\n"
+ " so the vendor-table.json from code was used.\n\n"); + " so the vendor-table.json from code was used.\n\n");
}
if (evLog.getPciidsFileStatus() == FILESTATUS_NOT_ACCESSIBLE) {
writeOut("*** WARNING: "
+ "The file pci.ids was not accessible from the filesystem or the code,\n"
+ " so some pci device info lookups in the output of this tool\n"
+ " may be omitted or the hex code may be used instead.\n\n");
} else if (evLog.getPciidsFileStatus() == FILESTATUS_FROM_CODE) {
writeOut("*** NOTE: "
+ "The file pci.ids file was not accessible from the filesystem,\n"
+ " so the pci.ids from code was used.\n\n");
} }
} }
int eventCount = 0; int eventCount = 0;