How to access efi executable present in another partition using gnu-efi? - uefi

I have to create 2 fat16 partitions in a disk and place one of the efi binary in another fat16 partition.
To begin with, wrote a basic HelloWorld.efi application (second stage) and for the first stage, used below-mentioned 2 apis to execute the HelloWorld.efi (both binaries are present in the same partition)
Currently I am trying to figure out a way to access the HelloWorld.efi present in another partition. Using these apis, I can access any file present in the same partition but don't know what api(s) to use to access another partition? Any suggestions? Thanks.
efi_status = BS->HandleProtocol(image_handle, &EFI_LOADED_IMAGE_GUID,
(void **)&shim_li);
efi_status = BS->HandleProtocol(device, &EFI_SIMPLE_FILE_SYSTEM_GUID,
(void **) &drive);

The simplest way would be to check if the file exists inside any filesystem.
The code below uses EDK2 but should work with gnu-efi with minimal modifications.
EFI_STATUS Status;
EFI_HANDLE* Handles;
UINTN HandleCount;
UINTN HandleIndex;
EFI_DEVICE_PATH_PROTOCOL* FilePath;
EFI_HANDLE ImageHandle;
CHAR16* ExitData;
UINTN ExitDataLength;
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &HandleCount, &Handles);
// error handling
for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
FilePath = FileDevicePath(Handles[HandleIndex], L"MyFolder\\HelloWorld.efi");
if (FilePath == NULL) {
continue;
}
Status = gBS->LoadImage(TRUE, gImageHandle, FilePath, NULL, 0, &ImageHandle);
gBS->FreePool(FilePath);
if (Status != EFI_SUCCESS) {
continue;
}
// Set LoadOptions and Watchdog if needed
Status = gBS->StartImage(ImageHandle, &ExitDataLength, &ExitData);
// error handling
}
gBS->FreePool(Handles);
If you know the partition id you can parse the device path of the filesystem and search for the correct partition.

Related

HAL_UARTEx_RxEventCallback() circular DMA: What address is the data?

I'm using the HAL with an STM32F3xx, implementing UART receive with circular DMA. The data should continually be received into the huart->pRxBuffPtr buffer, overwriting old data as new data arrives, and the HAL_UARTEx_RxEventCallback() function gets called regularly to copy out the data before it gets overwritten. The HAL_UARTEx_RxEventCallback() function receives a size parameter and of course a pointer huart, but no direct indication of where in the huart->pRxBuffPtr the freshly arrived data was DMA'd to.
How do I know whereabouts in huart->pRxBuffPtr the freshly arrived data starts?
Thank you to Tom V for the hint. For future generations, here is the solution code - a function which returns true and gets the next available byte, otherwise returns false:
bool uart_receiveByte(uint8_t *pData) {
static size_t dmaTail = 0u;
bool isByteReceived = false;
// dmaHead is the next position in the buffer the DMA will write to.
// dmaTail is the next position in the buffer to be read from.
const size_t dmaHead = huart->RxXferSize - huart->hdmarx->Instance->CNDTR;
if (dmaTail != dmaHead) {
isByteReceived = true;
*pData = pRxDmaBuffer[dmaTail];
if (++dmaTail >= huart->RxXferSize) {
dmaTail = 0u;
}
}
return isByteReceived;
}

Linux Kernel Module dev_get_drvdata Function Always Returns NULL

I have the following kernel module probe function (simplified to show the relevant parts):
static int qnap_ec_probe(struct platform_device* platform_dev)
{
// Allocate memory for the custom data and associate with the device
struct qnap_ec_platform_drv_data* platform_drv_data;
platform_drv_data = devm_kzalloc(&platform_dev->dev, sizeof(struct qnap_ec_platform_drv_data),
GFP_KERNEL);
// Add the custom data to the platform device
platform_set_drvdata(platform_dev, platform_drv_data);
// Register the platform device
devm_hwmon_device_register_with_info(&platform_dev->dev, "qnap_ec", NULL,
&qnap_ec_hwmon_chip_info, NULL);
return 0;
}
and the following hwmon read callback function:
static int qnap_ec_hwmon_read(struct device* dev, enum hwmon_sensor_types type, u32 attribute,
int channel, long* value)
{
struct qnap_ec_platform_drv_data* platform_drv_data;
platform_drv_data = dev_get_drvdata(dev);
if (platform_drv_data == NULL)
{
return -1;
}
return 0;
}
Unfortunately the second function always returns -1 because the dev_get_drvdata function always returns NULL. For some reason the data that's associated with the device in the probe function using platform_set_drvdata doesn't make it into the hwmon read callback function. Am I missing a step in associating this data with the device? What could be causing this issue?

Encrypt message using RSA on ESP32

What I try to achieve here is to encrypt a message inside ESP32 app built using PlatformIO + Arduino framework.
After some searchings, I found this repo: https://github.com/espressif/arduino-esp32
There is a tool inside it seems able to help me achieve what I want https://github.com/espressif/arduino-esp32/blob/master/tools/sdk/include/mbedtls/mbedtls/rsa.h
I imported the library "mbedtls" at https://platformio.org/lib/show/10874/mbedtls to the PlatformIO project and start work from there.
Question: How to load private key file in the app and encrypt the message using the RSA tool?
What I have currently is:
int ret = 1;
char buf[1024];
mbedtls_pk_init(&pk);
memset(buf, 0, sizeof(buf));
mbedtls_mpi_init(&N);
mbedtls_mpi_init(&P);
mbedtls_mpi_init(&Q);
mbedtls_mpi_init(&D);
mbedtls_mpi_init(&E);
mbedtls_mpi_init(&DP);
mbedtls_mpi_init(&DQ);
mbedtls_mpi_init(&QP);
ret = mbedtls_pk_parse_key(&pk, vendorPrivateKey, sizeof(vendorPrivateKey), NULL, NULL);
if (ret != 0) {
Serial.print(" failed! mbedtls_pk_parse_key returned: ");
Serial.print(-ret);
Serial.println();
}
if (mbedtls_pk_get_type(&pk) == MBEDTLS_PK_RSA) {
mbedtls_rsa_context *rsa = mbedtls_pk_rsa(pk);
if ((ret = mbedtls_rsa_export(rsa, &N, &P, &Q, &D, &E)) != 0
|| (ret = mbedtls_rsa_export_crt(rsa, &DP, &DQ, &QP)) != 0) {
Serial.println(" failed! could not export RSA parameters.");
}
}
For now I import the private key content directly in char* form (I'm not sure how to import a pem key file into app.) through the header file:
const unsigned char *vendorPrivateKey = reinterpret_cast<const unsigned char *>(VENDOR_PRIVATE_KEY);
where the value is stored inside secrets.h
Then when I ran the program, it yields the following error message for me:
failed! mbedtls_pk_parse_key returned: 15616
According to the pk.h file description, this error code 15616 in hexa is 3D00 which indicates /**< Invalid key tag or value. */
Is there any website that provides format checking and see if my private key file fits the requirements of the mbedtls?

Analyzer creating multiple diagnostics for compilation unit

I am writing a Roslyn Diagnostic to turn on/off option strict. Since there can only be one per file, I am using the compilation for the node to be examined:
context.RegisterSyntaxNodeAction(CompilationUnitCheck, SyntaxKind.CompilationUnit);
I am seeing multiple diagnostics displayed in the error list pane when running the development hive, at times as many as 3, but always at least 2 per file. They show the same location. What could be causing this, and what can I do to fix it?
private void CompilationUnitCheck(SyntaxNodeAnalysisContext context)
{
var orgRoot = (CompilationUnitSyntax) context.Node;
var fileName = System.IO.Path.GetFileNameWithoutExtension(orgRoot.SyntaxTree.FilePath) ;
if ((fileName?.EndsWith("designer", StringComparison.CurrentCultureIgnoreCase)).GetValueOrDefault() ||
"Reference".Equals(fileName, StringComparison.CurrentCultureIgnoreCase))
{
return;
}
if (fileName != "TestFile") return;
var newErrors = fileName == "TestFile";
var location = orgRoot.GetLocation();
string strictMsg = null ?? "Off";
var diagnostic = Diagnostic.Create(Rule, location, strictMsg);
context.ReportDiagnostic(diagnostic);
}
My current workaround is to get the hashcode of the root, and store that in a static list, if it's in the list, I don't check again.

PKCS#11 C_Encrypt fails with Bad Arguments for 128 bit AES key

I generate a 128-bit AES object using "C_CreateObject".
I then do the following to encrypt a piece of data and get a "Bad Argumnents" error on the call to "C_Encrypt" to get the encrypted data length.
char clear[] = "My name is Eric!";
buf_len = sizeof(clear) -1;
rv = pfunc11->C_EncryptInit(session, pMechanism, hObject);
if (rv != CKR_OK)
{
printf("ERROR: rv=0x%08X: initializing encryption:\n", (unsigned int)rv);
return false;
}
rv = pfunc11->C_Encrypt(session, (CK_BYTE_PTR)clear, (CK_ULONG)buf_len, NULL, pulEncryptedDataLen);
if (rv != CKR_OK)
{
printf("ERROR: rv=0x%08X: derror getting encryption data buffer length:\n", (unsigned int)rv);
return false;
}
What am I doing wrong here ?
Here is my mechanism definition -
CK_MECHANISM myMechanism = {CKM_AES_CBC_PAD, (CK_VOID_PTR)"01020304050607081122334455667788", (CK_ULONG)16};
CK_MECHANISM_PTR pMechanism = &myMechanism;
Your pulEncryptedDataLen is probably NULL which causes CKR_ARGUMENTS_BAD.
It is better to use e.g.:
CK_ULONG ulEncryptedDataLen;
...
rv = pfunc11->C_Encrypt(session, (CK_BYTE_PTR)clear, (CK_ULONG)buf_len, NULL, &ulEncryptedDataLen);
The number of bytes sufficient to store encryption result of a single-part encryption gets stored into ulEncryptedDataLen.
Also please note that your way of passing IV value is not correct as "01020304050607081122334455667788" results in an ASCII string (giving IV as 30313032303330343035303630373038 -- which is probably not what you want).
To get correct IV use "\x01\x02\x03\x04\x05\x06\x07\x08\x11\x22\x33\x44\x55\x66\x77\x88" instead.
Good luck!