Chain of trust and tpm? - boot

Lets take the 1st step when the CRTM measures the Bios it extends the hash value to the PCR located in the TPM. Before passing control to the bios it must be a verification of hash values. My question is there an agent (third party) to commit this verification? or PCRs has a default set, so each time extending hash values these values must correspond to the PCR default hash before passing the control to bios?

It depends. In some implementations, the CRTM is a part of BIOS, so you have to implicitly trust the first boot block of BIOS to be loaded, which then verifies the rest of the BIOS. In other implementations, such as with Intel's AMT, the CPU measures the BIOS independently.

What you asked is the PCR values from so-called "golden measurement" or "baseline measurement", which can be conducted by the platform manufacturer such as DELL or platform administrator like your department IT. Those values are saved and used for verification by TPM. This is part of the "provisioning process".
Please check the book "TCG TPM v2.0 Provisioning Guidance" for section 10 and section 11.

Related

GetSystemIdForPublisher doesn't return unique ID

I use GetSystemIdForPublisher() to identify machine IDs. According to the documentation they are unique, but I have a handful of machines which return the same ID. These machines are completely unrelated and have no common history. They are located in different countries and belong to different users. The Windows version of these machines is the latest Windows 1909 10.0.18363 update.
The documentation clearly states:
The method will first attempt to use the Trusted Platform Module
(TPM), if present, to get an ID. If a TPM is not present, the method
will try to get an ID from the Unified Extensible Firmware Interface
(UEFI). If neither of these sources is available, this method will
return an ID that is backed by the Windows registry. In the case of
the Windows registry, the ID will not satisfy all the above
guarantees. For example, if a system does not have a TPM or UEFI
support, and thus an ID was obtained from the registry, a clean
install of Windows will result in a new, different ID being returned.
Callers of this method should refer to the Source property of the
returned SystemIdentificationInfo to determine where the ID was
obtained from in order to understand the guarantees provided.
As far as I can see, none of these statements explain to me what is happening here. Does anyone else have an idea whats going on? Any help is highly appreciated!
Addendum:
we got feedback in form of a cpu-z report from 2 persons on 2 different continents with the same machine id:
user A:
Mainboard Model Z87M Extreme4 (0x00000444 - 0xECE9B6D4)
UEFI Yes
BIOS Vendor American Megatrends Inc.
BIOS MSG 63-0100-000001-00101111-1xxxx5-Chipset
BIOS Date 12/10/15
Mainboard Vendor 000001
user B:
Mainboard Model 151-BE-E097 (0x0000025D - 0x0A74C7F0)
UEFI Yes
BIOS Vendor American Megatrends Inc.
BIOS MSG 63-0100-000001-00101111-0XXXX5-Chipset
BIOS Date 09/10/15
Mainboard Vendor 000001
both got the same identifier when calling GetSystemIdForPublisher():
XlPRXXXlAPXk-yFXXXJUv3-XXXXXXXXXXXXX = [source is UEFI, ]
==> X included for obfuscation
We have around 60 customers worldwide whose computers return this exact ID.

Using SetupDiSetDeviceRegistryProperty with SPDRP_HARDWAREID

The docs for the SetupDiSetDeviceRegistryProperty function say,
The following values are reserved for use by the operating system and
cannot be used in the Property parameter ...
SPDRP_HARDWAREID
However, there are lots of examples of code out there, including MS DevCon utility which uses this function with the SPDRP_HARDWAREID parameter, ie:
SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
&DeviceInfoData,
SPDRP_HARDWAREID,
(LPBYTE)hwIdList,
(lstrlen(hwIdList)+1+1)*sizeof(TCHAR)))
They also have an article which suggests doing so:
If an installer detects a non-PnP device, the installer should select a driver for the device as follows: create a device information element (SetupDiCreateDeviceInfo), set the SPDRP_HARDWAREID property by calling SetupDiSetDeviceRegistryProperty
I'd like to (and do) use this function to set Hardware ID for my virtual device. The question is - is it a typo in the manual, or it's some sort of unsupported behavior and therefore it can stop working any time?
TL;DR: If you're creating a root-enumerated device node, you're free to set SPDRP_HARDWAREID/SPDRP_COMPATIBLEIDS yourself by calling SetupDiSetDeviceRegistryProperty. Otherwise you're not allowed to do so.
This was an error in the docs that was fixed at some point.
Today the docs of SetupDiSetDeviceRegistryProperty read:
SPDRP_HARDWAREID or SPDRP_COMPATIBLEIDS can only be used when DeviceInfoData represents a root-enumerated device. For other devices, the bus driver reports hardware and compatible IDs when enumerating a child device after receiving IRP_MN_QUERY_ID. [Emphasis mine]
... which is exactly what DevCon does.

Jump to App from custom bootloader in TMS320 digital media processor

I am working on a boot loader for TMS320DM6437. The idea is to create 2 independent firmware that one will update another. In firmware1 I will download firmware2 file and write it to NOR flash in a specified address. Both firmware are stored in NOR flash in ais format. Now I have two applications in flash. One is my custom boot loader and the second one is my main project. I want to know how I can jump from the first program to the second program located at a specified address. I also expect information about documents which may help me to create custom bootloader
Any recommendations?
You can jump to the entry point. I'm using this approach on TMS320 2802x and 2803x, but it should be the same.
The symbol of the entry point is c_int00.
To get to know the address of c_int00 in the second application, you have to fix the Run-Time Support (RTS) library at a specific address, by modifying the linker command file.
Otherwise you can leave the RTS unconstrained, and create a C variable (at a fixed address) that is initialized with the value of cint_00. Using this method your memory map is more flexible and you can add, togheter with the C variable, a comprehensive data structure with other information for your bootloader, e.g. CRC, version number, etc.
Be carefull with the (re)initialization of the peripherals in the second application, since you are not starting from a hardware reset, and you may need to explicity reset some more registers, or clear interrupt requests.

Unique computer id based on CPU flags

I need to use unique computer id for the purpose of software licensing. I decided to use CPU Flags. On MSVC they are retrived with function __cpuid, and on gcc version 4.3 and up with the function __get_cpuid. I get an integer out of these functions which is sort of a bit array with the purpose to be used as unique ID.
What I'm not sure whether the CPU flags retrieved with the above functions can ever change? Can those flags be programmatically changed by the user? If not by regular application maybe through BIOS?
Thank you.
No, an end user cannot change them because each of the commands you listed is essentially a wrapper for an actual processor opcode cpuid that is provided in Intel (and Intel-clone) chips.
So this information is 'burned' into the silicon. No user can change it.
The following resources might be helpful:
1) Wikipedia's article on CPUID
2) Code guru article (2 pages) on accessing processor info using a call to CPUID
3) Table listing many processors by stepping, family, and model numbers
OK after some testing I can confirm that the flags from the 2nd byte of Info Type 1 are changing. So I will stick with Stepping ID,Model,Family and Processor Type values only.

Is CryptEncrypt() thread-safe?

Microsoft says:
The CryptEncrypt function is not guaranteed to be thread safe and may return incorrect results if invoked simultaneously by multiple callers.
Does this mean that the function modifies global data?
Or does it simply mean that you can't use the same hash/key simultaneously?
(In other words, is the comment below correct?)
It means what it means: the function is not guaranteed to be thread-safe. It probably has an internal static (or global) state, but that's an implementation detail.
Whether you use or not the same hash or key is irrelevant.
Edit after comment: according to this MSDN page, CryptoApi key handles are not thread safe because of the internal key state:
Most algorithms and modes require that data be decrypted in the same order that it was encrypted. This is a difficult task in a multithreaded environment because use of a critical section will not address the ordering issue. If you are using a block cipher (that is, RC2, DES, or 3DES) in ECB cipher mode, then this issue is not a factor because the internal key state does not change. However, ECB is not the default cipher mode. CBC is the default cipher mode. With CBC cipher mode, the internal key state does change.
So after all, it would seem reasonable to think that you can indeed use CryptEncrypt on several threads if they don't share the same key. This is merely a guess, though.
I believe it means that you cannot fork several processes at the same time to use it because the function uses shared address space. It has access to the memory of all the threads and therefore will give you unexpected results. This should only be a problem with multi-threading if your application is doing that.

Resources