UEFI TGC2's sendCommand always returns error 21 - uefi

I'm developing an UEFI app using the TPM2. getCapabilities works, but everything else is shoved onto this submitCommand() function. everything I try there returns EFI_ABORTED as status.
I tried several commands, like read_PCR and get_random_number, but it appears to occur for all commands (TPM2 spec part 3). I chose the random number command because it's a simple command without authorization or encryption that should always return when executed correctly.
struct TPM2_ {
EFI_HANDLE image;
EFI_BOOT_SERVICES *BS;
EFI_TCG2_PROTOCOL *prot;
UINT32 activePCRbanks;
};
struct TPM2_Rand_Read_Command {
TPMI_ST_COMMAND_TAG tag;
UINT32 commandSize;
TPM_CC commandCode;
UINT16 bytesRequested;
};
struct TPM2_Rand_Read_Response {
TPM_ST tag;
UINT32 responseSize;
TPM_RC responseCode;
TPM2B_DIGEST randomBytes;
};
UINTN tpm_get_random(TPM2 * tpm) {
struct TPM2_Rand_Read_Command cmd;
struct TPM2_Rand_Read_Response resp;
cmd.tag = __builtin_bswap16(TPM_ST_NO_SESSIONS); //x86 is little endian, TPM2 is big-endian, use bswap to convert!)
cmd.commandCode = __builtin_bswap32(TPM_CC_GetRandom);
cmd.commandSize = __builtin_bswap32(sizeof(struct TPM2_Rand_Read_Command));
cmd.bytesRequested = __builtin_bswap16(4);
EFI_STATUS stat = tpm->prot->SubmitCommand(tpm->prot,sizeof(struct TPM2_Rand_Read_Command), (UINT8*)&cmd,sizeof(struct TPM2_Rand_Read_Response),(UINT8*)&resp); //responds 0x15 || 21
Print(L"statreadrand: %x \t %d \r\n", stat, *((UINT32*)resp.randomBytes.buffer));
CHECK_STATUS(stat, L"SubmitReadCommand");
return 0;
}
TPM2* tpm_create(EFI_BOOT_SERVICES *BS, EFI_HANDLE image) {
TPM2* tpm = calloc(1, sizeof(TPM2));
EFI_GUID prot_guid = (EFI_GUID)EFI_TCG2_PROTOCOL_GUID;
tpm->BS = BS;
tpm->image = image;
EFI_STATUS stat = tpm->BS->LocateProtocol(&prot_guid, NULL, (void **)&tpm->prot);
CHECK_STATUS(stat, L"LocateTPMProtocol");
return tpm;
}
I expect the SubmitCommand function to return EFI_SUCCESS (0) and fill the response struct with 4 random bytes. But the function returns EFI_ABORTED (21)
Does anyone know how to solve this?
EDIT: tried different toolchains (GNU-EFI/ plain GCC / EDK2) all give the same behaviour.

The particular PC had this exact problem. probably the TPM was locked.
When using a different PC With a TPM2 the problem didn' t occur and instead, I just got a random number back.

Related

Can't write Double word on STM32F429 using HAL driver

I am trying to write uint64_t(double word) variable into the flash memory, without success though. Here is the code.
#define APPLICATION_START_ADDRESS 0x8008000
void flashErase(uint8_t startSector, uint8_t numberOfSectors)
{
HAL_FLASH_Unlock();
Flash_eraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
Flash_eraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
Flash_eraseInitStruct.Sector = startSector;
Flash_eraseInitStruct.NbSectors = numberOfSectors;
if(HAL_FLASHEx_Erase(&Flash_eraseInitStruct, &Flash_halOperationSectorError) != HAL_OK)
{
Flash_raiseError(errHAL_FLASHEx_Erase);
}
HAL_FLASH_Lock();
}
int main(void)
{
HAL_Init();
main_clockSystemInit();
__IO uint64_t word = 0x1234567890;
flashErase(2, 1);
// flashProgramWord(aTxBuffer, APPLICATION_START_ADDRESS, 2 );
HAL_FLASH_Unlock();
HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, APPLICATION_START_ADDRESS, word);
}
I get error flag raised PGSERR and PGAERR. The erase operation goes without problems. But programming returns ERROR.
Some Ideas?
There is no STM32F249, did you mean STM32F429?
In order to use 64 bit programming, VPP (BOOT0) has to be powered by 8 - 9 Volts. Is it?
See the Reference Manual Section 3.6.2
By the way,
__IO uint64_t word = 0x1234567890;
would not work as (presumably) expected. It is a 32 bit architecture, integer constants will be truncated to 32 bits, unless there is an L suffix. U wouldn't hurt either, because the variable is unsigned. __IO is unnecessary.
uint64_t word = 0x1234567890UL;

Simblee/Rfduino Gzll communcation failing

I am attempting to send data from device to host using the Gazelle protocol, however, when reading a time varying signal in on MATLAB the values continuously change elements in the array.
Here is the Simblee/Rfduino host code:
#include <SimbleeGZLL.h>
device_t role = HOST;
char array[5];
void setup() {
Serial.begin(9600);
SimbleeGZLL.begin(role);
timer_one(1); // 1 ms timer
}
void loop() {
Serial.flush();
printf(EMG);
}
void SimbleeGZLL_onReceive(device_t device, int rssi, char *data, int len)
{
if (len > 0) {
digitalWrite(2,HIGH);
array[0] = data[0];
array[1] = data[1];
array[2] = data[2];
array[3] = data[3];
array[4] = '\0';
} else SimbleeGZLL.sendToDevice(device, 'A');
}
And the device code:
include
device_t role = DEVICE1;
volatile int state;
char array[4];
void setup() {
SimbleeGZLL.begin(role);
Serial.begin(9600);
timer_one(1);
}
void loop() {
array[0] = analogRead(2);
array[1] = analogRead(3);
array[2] = analogRead(4);
array[3] = analogRead(5);
SimbleeGZLL.sendToHost(EMG,4);
}
Could someone please provide some assistance to identify where the issue may lie?
Thank you!
Matlab is not super reliable with serial communication. I actually had a similar issue with a serial device where the input values would be out of order. Are you signaling when to start and stop printing? What does your matlab code look like?
I would set up a ring buffer on the host and the device to deal with the asycn time issues.
You are going to get timing issues with the current method. What kind of frequency are you going for? The analogRead is super slow, and double multiple in a row seems to make things even slower. Could you try to set up an ADC interrupt?
Where is your timer code?

Simple OS kernel -- screen output long string array issue

I am following the steps in: "Writing a Simple Operating System from Scratch". I got the basic kernel up and running, but got a strange error when I try to output a very long string.
The following code output all "0"s. But when I use a shorter "msg" string, then the screen prints "x".
I wonder if anybody can help me, thanks much! (I am testing it in Bochs in windows 8).
Here is the kernel.c
void start ()
{
// Create a pointer to a char , and point it to the first text cell of
// video memory (i.e. the top - left of the screen )
unsigned char *video_memory = ( unsigned char*) 0xb8000;
// At the address pointed to by video_memory , store the character 'X'
// (i.e. display 'X' in the top - left of the screen ).
// this string: the outputs are "0"s.
const char msg[] = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzAbcdefghijkAbcdefghijklmnopqrstuvwxyzA";
// this string: output are "x"s.
//const char msg[] = "abcdefghijklmnopqrstuvwxyzabcdefghijk";
int i = 0;
int offset = 0;
while(i<85)
{
// Test if msg points to the right memory
if(msg[i]==0)
{
video_memory[offset] = '0';
}
else
{
video_memory[offset] = 'x';
}
video_memory[offset+1] = 0x02; // Green color
i = i + 1;
offset = offset + 2;
//set_cursor(offset);
}
}

GPS output being incorrectly written to file on SD card- Arduino

I have a sketch to take information (Lat, Long) from an EM-406a GPS receiver and write the information to an SD card on an Arduino shield.
The program is as follows:
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <SD.h>
TinyGPSPlus gps;
SoftwareSerial ss(4, 3); //pins for the GPS
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;
void setup()
{
Serial.begin(115200); //for the serial output
ss.begin(4800); //start ss at 4800 baud
Serial.println("gpsLogger by Aaron McRuer");
Serial.println("based on code by Mikal Hart");
Serial.println();
//initialize the SD card
if(!card.init(SPI_FULL_SPEED, 9))
{
Serial.println("card.init failed");
}
//initialize a FAT volume
if(!volume.init(&card)){
Serial.println("volume.init failed");
}
//open the root directory
if(!root.openRoot(&volume)){
Serial.println("openRoot failed");
}
//create new file
char name[] = "WRITE00.TXT";
for (uint8_t i = 0; i < 100; i++){
name[5] = i/10 + '0';
name[6] = i%10 + '0';
if(file.open(&root, name, O_CREAT | O_EXCL | O_WRITE)){
break;
}
}
if(!file.isOpen())
{
Serial.println("file.create");
}
file.print("Ready...\n");
}
void loop()
{
bool newData = false;
//For one second we parse GPS data and report some key values
for (unsigned long start = millis(); millis() - start < 1000;)
{
while (ss.available())
{
char c = ss.read();
//Serial.write(c); //uncomment this line if you want to see the GPS data flowing
if(gps.encode(c)) //did a new valid sentence come in?
newData = true;
}
}
if(newData)
{
file.write(gps.location.lat());
file.write("\n");
file.write(gps.location.lng());
file.write("\n");
}
file.close();
}
When I open up the file on the SD card when the program is finished executing, I get a message that it has an encoding error.
I'm currently inside (and unable to get a GPS signal, thus the 0), but the encoding problem needs to be tackled, and there should be as many lines as there are seconds that the device has been on. There's only that one. What do I need to do to make things work correctly here?
Closing the file in the loop, and never reopening it, is the reason there's only one set of data in your file.
Are you sure gps.location.lat() and gps.location.lng() return strings, not an integer or float? That would explain the binary data and the "encoding error" you see.

AudioQueueGetProperty returns out-of-range value for kAudioQueueProperty_CurrentLevelMeter property

I'm writing an application that requires the user be in a quiet environment. To do this, I periodically check the power reading off the microphone. (I'm aware of the returned value being in dBFS or, in this case, a float in the interval [0, 1]. )
My problem is that the below code works just fine... except when it returns 18466064732283753157623808.00000. I see no NSLog output indicating AudioQueueGetProperty returning a failure. The weird value is always the mentioned value.
-(float)instantaneousPeakPower {
UInt32 dataSize = sizeof(AudioQueueLevelMeterState) * recordFormat.mChannelsPerFrame;
AudioQueueLevelMeterState *levels = (AudioQueueLevelMeterState*)malloc(dataSize);
OSStatus rc = AudioQueueGetProperty(audioQueue, kAudioQueueProperty_CurrentLevelMeter, levels, &dataSize);
if (rc) {
NSLog(#"NoiseLeveMeter>>takeSample - AudioQueueGetProperty(CurrentLevelMeter) returned %#", rc);
}
float channelAvg = 0;
for (int i = 0; i < recordFormat.mChannelsPerFrame; i++) {
channelAvg += levels[i].mPeakPower;
}
free(levels);
// This works because in this particular case one channel always has an mAveragePower of 0.
return channelAvg;
}
What gives? Does the bit pattern of the value perhaps give a clue?
Did you enabled audio level metering?
UInt32 trueValue = true;
AudioQueueSetProperty(audioQueue,kAudioQueueProperty_EnableLevelMetering,&trueValue,sizeof (UInt32));