EFI_STATUS WrapBootBIO()

in lsvmload/bootbio.c [142:301]


EFI_STATUS WrapBootBIO(
    EFI_HANDLE imageHandle,
    EFI_TCG2_PROTOCOL* tcg2Protocol,
    const UINT8* masterkeyData,
    UINTN masterkeySize)
{
    EFI_STATUS status = EFI_UNSUPPORTED;
    EFI_STATUS rc;
    EFI_GUID guid;
    EFI_DEVICE_PATH* dp = NULL;
    UINT64 firstLBA = 0;
    UINT64 lastLBA = 0;
    EFI_HANDLE handle = NULL;
    Blkdev* bootdev = NULL;

    /* Check parameters */
    if (!imageHandle || !masterkeyData || !masterkeySize)
        goto done;

    /* Get boot device */
    if (!(bootdev = GetBootDevice(
        imageHandle, 
        tcg2Protocol,
        masterkeyData,
        masterkeySize)))
    {
        LOGE(L"WrapBootBIO(): GetBootDevice() failed");
        goto done;
    }

    /* Copy over media from LUKS parition */
    Memcpy(
        &_block_io.media, 
        globals.bootbio->blockIO->Media, 
        sizeof(EFI_BLOCK_IO_MEDIA));
    _block_io.base.Media = &_block_io.media;

    /* Set EFI_BLOCK_IO_MEDIA.LastBlock */
    {
        union 
        {
            LUKSHeader header;
            UINT8 blocks[LUKS_SECTOR_SIZE*2];
        }
        u;
        static UINT8 _magic[LUKS_MAGIC_SIZE] = LUKS_MAGIC_INITIALIZER;

        /* Read the LUKS header (blkno == 0) */
        if (ReadBIO(globals.bootbio, 0, &u, sizeof(u)) != EFI_SUCCESS)
        {
            LOGE(L"WrapBootBIO(): ReadBIO() failed");
            goto done;
        }

        /* Check the magic number */
        if (Memcmp(u.header.magic, _magic, sizeof(_magic)) != 0)
        {
            LOGE(L"WrapBootBIO(): bad LUK magic"); 
            goto done;
        }

        /* Fix the byte order of the hader */
        LUKSFixByteOrder(&u.header);

        /* Adjust the last block field (omit leading LUKS metadata) */
        _block_io.media.LastBlock -= u.header.payload_offset;
    }

    /* Set the function pointers */
    _block_io.base.Reset = _EFI_BLOCK_IO_Reset;
    _block_io.base.ReadBlocks = _EFI_BLOCK_IO_ReadBlocks;
    _block_io.base.WriteBlocks = _EFI_BLOCK_IO_WriteBlocks;
    _block_io.base.FlushBlocks = _EFI_BLOCK_IO_FlushBlocks;
    _block_io.dev = bootdev;

#if 0
    /* Use the guid from the boot file system */
    if (globals.bootfs)
    {
        LogHexStr(L"EXT2-GUID", globals.bootfs->sb.s_uuid,
            sizeof(globals.bootfs->sb.s_uuid));
        MakeGUIDFromBytes(&guid, globals.bootfs->sb.s_uuid);
    }
#endif

    /* Allocate device path for this new parition */
    if (!(dp = DevPathCreatePseudoPartition(
        _block_io.media.LastBlock,
        &guid,
        &firstLBA,
        &lastLBA)))
    {
        LOGE(L"WrapBootBIO(): DevPathCreatePseudoPartition() failed");
        goto done;
    }

    LOGI(L"Mapped pseudo partition: firstLBA=%d lastLBA=%d",
        (int)firstLBA, (int)lastLBA);

    /* Install new EFI_BLOCK_IO (assigns new handle) */
    {
        static EFI_GUID protocol = BLOCK_IO_PROTOCOL;

        if ((rc = uefi_call_wrapper(
            BS->InstallProtocolInterface, 
            4, 
            &handle,
            &protocol,
            EFI_NATIVE_INTERFACE,
            &_block_io)) != EFI_SUCCESS)
        {
            LOGE(L"WrapBootBIO(): InstallProtocolInterface(1) failed");
            goto done;
        }
    }

    /* Install new DEVICE_PATH protocol interface */
    {
        static EFI_GUID protocol = DEVICE_PATH_PROTOCOL;

        if ((rc = uefi_call_wrapper(
            BS->InstallProtocolInterface, 
            4, 
            &handle,
            &protocol,
            EFI_NATIVE_INTERFACE,
            dp)) != EFI_SUCCESS)
        {
            LOGE(L"WrapBootBIO(): InstallProtocolInterface(2) failed");
            goto done;
        }
    }

    /* Add this new parition to the GPT */
    if (AddPartition(L"BOOTFS", &guid, firstLBA, lastLBA) != 0)
    {
        LOGE(L"WrapBootBIO(): AddPartition() failed");
        goto done;
    }

    /* Add a region so diskbio will find this data */
    if (AddRegion(
        REGION_ID_BOOT,
        firstLBA, 
        lastLBA, 
        lastLBA - firstLBA + 1,
        FALSE, /* readOnly */
        NULL, 
        &_block_io.base) != 0)
    {
        LOGE(L"WrapBootBIO(): AddRegion() failed");
        goto done;
    }

    status = EFI_SUCCESS;

done:

    return status;
}