int LoadDecryptCopySpecializeFile()

in lsvmload/specialize.c [133:272]


int LoadDecryptCopySpecializeFile(
    EFI_HANDLE imageHandle,
    Blkdev* bootdev,
    EXT2* bootfs,
    const CHAR16* path)
{
    const char* func = __FUNCTION__;
    int rc = -1;
    void* data = NULL;
    UINTN size;
    const UINT8* mkData = NULL;
    UINTN mkSize;
    UINT8* specializeData = NULL;
    UINTN specializeSize = 0;
    SPECIALIZATION_FILE* specFiles = NULL;
    UINTN numSpecFiles;

    /* Check for null parameters */
    if (!imageHandle || !bootdev || !path)
    {
        LOGE(L"%a(): null parameter", Str(func));
        goto done;
    }

    /* If specialize file exists, then load and decrypt it */
    if (FileExists(imageHandle, path) == EFI_SUCCESS)
    {
        SECURE_SPECIALIZATION* spec;
        UINTN i;

        /* Load the file into memory */
        if (EFILoadFile(imageHandle, path, &data, &size) != EFI_SUCCESS)
        {
            LOGE(L"%a: failed to load %s", Str(func), Wcs(path));
            goto done;
        }

        /* Check for valid header in spec file. */
        if (!_IsValidHeader(data, size))
        {
            LOGE(L"%a: failed to validate", Str(func));
            goto done;
        }

        /* Get the masterkey from the boot device */
        if (LUKSBlkdevGetMasterKey(bootdev, &mkData, &mkSize) != 0)
        {
            LOGE(L"%a: failed to retrieve masterkey", Str(func));
            goto done;
        }

        /* Decrypt the specialization file */
        spec = (SECURE_SPECIALIZATION*) data;
        if (SpecFuncs[spec->Mode-1](
            spec,
            mkData, 
            mkSize * 8, /* key size in bits */
            &specializeData, 
            &specializeSize) != 0)
        {
            LOGE(L"%a: failed to decrypt specialize file", Str(func));
            goto done;
        }

        LOGI(L"Loaded %s", Wcs(path));

        if (ExtractSpecFiles(
            specializeData,
            specializeSize,
            &specFiles,
            &numSpecFiles) != 0)
        {
            LOGE(L"%a: failed to deserialize spec data", Str(func));
            goto done;         
        }


        PutProgress(L"Creating /lsvmload/specialize");

        if (EXT2MkDir(
            bootfs,
            LSVMLOAD_SPEC_DIR,
            EXT2_DIR_MODE_RWX_R0X_R0X) != EXT2_ERR_NONE)
        {
            LOGE(L"%a: failed to create boot:/lsvmload/specialize", Str(func));
            goto done;
        }
            
        for (i = 0; i< numSpecFiles; i++)
        {
            UINT32 filePathLen = Strlen(specFiles[i].FileName);
            char* path = (char*) Malloc(sizeof(LSVMLOAD_SPEC_DIR) + 1 + filePathLen);
            if (path == NULL)
            {
                LOGE(L"%a: failed allocate memory for path: %a", Str(func), specFiles[i].FileName);
                goto done;
            }

            Memcpy(path, LSVMLOAD_SPEC_DIR, sizeof(LSVMLOAD_SPEC_DIR) - 1);
            path[sizeof(LSVMLOAD_SPEC_DIR) - 1] = '/';
            Memcpy(path + sizeof(LSVMLOAD_SPEC_DIR), specFiles[i].FileName, filePathLen);
            path[sizeof(LSVMLOAD_SPEC_DIR) + filePathLen] = 0;

            /* Copy file to boot partition */
            if (EXT2Put(
                bootfs, 
                specFiles[i].PayloadData, 
                specFiles[i].PayloadSize, 
                path,
                EXT2_FILE_MODE_RW0_000_000) != EXT2_ERR_NONE)
            {
                LOGE(L"%a: failed to create boot:/lsvmload/specialize/%a", Str(func), specFiles[i].FileName);
                goto done; 
            }

        }

        if (DeleteFile(imageHandle, path) != EFI_SUCCESS)
        {
            LOGE(L"%a: failed to delete spec file: %s", Str(func), Wcs(path));
            goto done;
        }

        LOGI(L"Created boot:/lsvmload/specialize");
    }

    rc = 0;

done:
    if (data)
        Free(data);

    if (specializeData)
        Free(specializeData);

    if (specFiles)
        FreeSpecFiles(specFiles, numSpecFiles);

    return rc;
}