Skip to content

Commit

Permalink
i386/slaunch: Add support for AMD SKINIT
Browse files Browse the repository at this point in the history
Signed-off-by: Krystian Hebel <[email protected]>
Signed-off-by: Sergii Dmytruk <[email protected]>
  • Loading branch information
krystian-hebel authored and SergiiDmytruk committed Feb 26, 2024
1 parent b4faf70 commit c90cc21
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 2 deletions.
6 changes: 6 additions & 0 deletions grub-core/lib/i386/relocator32.S
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ VARIABLE(grub_relocator32_edx)
cmpl $SLP_INTEL_TXT, %edi
je LOCAL(intel_txt)

cmpl $SLP_AMD_SKINIT, %edi
je LOCAL(amd_skinit)

.byte 0xea
VARIABLE(grub_relocator32_eip)
.long 0
Expand All @@ -123,6 +126,9 @@ VARIABLE(grub_relocator32_eip)
LOCAL(intel_txt):
getsec

LOCAL(amd_skinit):
skinit

/* GDT. Copied from loader/i386/linux.c. */
.p2align 4
LOCAL(gdt):
Expand Down
57 changes: 57 additions & 0 deletions grub-core/loader/i386/skinit.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,63 @@
/* Offset to area for passing data to SKL. */
#define SLB_PARAM(slb) ((const grub_uint16_t *) (slb))[3]

int
grub_skinit_is_slb (const void *slb_base, grub_uint32_t slb_size)
{
const grub_uint8_t skl_uuid[16] = {
0x78, 0xf1, 0x26, 0x8e, 0x04, 0x92, 0x11, 0xe9,
0x83, 0x2a, 0xc8, 0x5b, 0x76, 0xc4, 0xcc, 0x02,
};
/* We need space after SLB to pass SLRT to it. */
const grub_ssize_t max_size = GRUB_SKINIT_SLB_SIZE - SLRT_SIZE;

const grub_uint8_t *uuid;

if (slb_size > max_size)
{
grub_dprintf ("slaunch", "SLB is too large: %d > %d\n",
slb_size, max_size);
return 0;
}

if (SLB_MEASURED (slb_base) > slb_size)
{
grub_dprintf ("slaunch", "SLB measured size is too large: %d > %d\n",
SLB_MEASURED (slb_base), slb_size);
return 0;
}

if (SLB_ENTRY (slb_base) >= SLB_MEASURED (slb_base))
{
grub_dprintf ("slaunch", "SLB entry is not measured: %d >= %d\n",
SLB_ENTRY (slb_base), SLB_MEASURED (slb_base));
return 0;
}

if (SLB_INFO (slb_base) > slb_size - sizeof(skl_uuid))
{
grub_dprintf ("slaunch", "SLB info offset is too large: %d > %d\n",
SLB_INFO (slb_base), slb_size - sizeof(skl_uuid));
return 0;
}

if (SLB_PARAM (slb_base) > max_size)
{
grub_dprintf ("slaunch", "SLB bootloader data offset is too large: %d > %d\n",
SLB_PARAM (slb_base), max_size);
return 0;
}

uuid = (const grub_uint8_t *) slb_base + SLB_INFO (slb_base);
if (grub_memcmp (uuid, skl_uuid, sizeof(skl_uuid)) != 0)
{
grub_dprintf ("slaunch", "SLB has unexpected UUID\n");
return 0;
}

return 1;
}

grub_err_t
grub_skinit_boot_prepare (struct grub_relocator *rel,
struct grub_slaunch_params *slparams)
Expand Down
35 changes: 33 additions & 2 deletions grub-core/loader/i386/slaunch.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <grub/i386/cpuid.h>
#include <grub/i386/msr.h>
#include <grub/i386/mmio.h>
#include <grub/i386/skinit.h>
#include <grub/i386/slaunch.h>
#include <grub/i386/tpm.h>
#include <grub/i386/txt.h>
Expand Down Expand Up @@ -77,8 +78,12 @@ grub_slaunch_init_slrt_storage (int arch)
/* Setup DCE and DLME information. */
slr_dl_info_staging.hdr.tag = GRUB_SLR_ENTRY_DL_INFO;
slr_dl_info_staging.hdr.size = sizeof(struct grub_slr_entry_dl_info);
slr_dl_info_staging.bl_context.bootloader = GRUB_SLR_BOOTLOADER_GRUB;
slr_dl_info_staging.bl_context.context = slparams.boot_params_addr;
slr_dl_info_staging.dce_base = slparams.dce_base;
slr_dl_info_staging.dce_size = slparams.dce_size;
slr_dl_info_staging.dlme_base = slparams.mle_start;
slr_dl_info_staging.dlme_size = slparams.mle_size;
slr_dl_info_staging.dlme_entry = mle_header->entry_point;

slr_log_info_staging.hdr.tag = GRUB_SLR_ENTRY_LOG_INFO;
Expand Down Expand Up @@ -152,7 +157,8 @@ grub_cmd_slaunch (grub_command_t cmd __attribute__ ((unused)),
char *argv[] __attribute__ ((unused)))
{
grub_uint32_t manufacturer[3];
grub_uint32_t eax;
grub_uint32_t eax, ebx, ecx, edx;
grub_uint64_t msr_value;
grub_err_t err;

if (!grub_cpu_is_cpuid_supported ())
Expand All @@ -174,6 +180,19 @@ grub_cmd_slaunch (grub_command_t cmd __attribute__ ((unused)),

slp = SLP_INTEL_TXT;
}
else if (!grub_memcmp (manufacturer, "AuthenticAMD", 12))
{
grub_cpuid (GRUB_AMD_CPUID_FEATURES, eax, ebx, ecx, edx);
if (! (ecx & GRUB_AMD_CPUID_FEATURES_ECX_SVM) )
return grub_error (GRUB_ERR_BAD_DEVICE, N_("CPU does not support AMD SVM"));

/* Check whether SVM feature is disabled in BIOS */
msr_value = grub_rdmsr (GRUB_MSR_AMD64_VM_CR);
if (msr_value & GRUB_MSR_SVM_VM_CR_SVM_DISABLE)
return grub_error (GRUB_ERR_BAD_DEVICE, N_("BIOS has AMD SVM disabled"));

slp = SLP_AMD_SKINIT;
}
else
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("CPU is unsupported"));

Expand All @@ -193,7 +212,7 @@ grub_cmd_slaunch_module (grub_command_t cmd __attribute__ ((unused)),
if (slp == SLP_NONE)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("secure launch not enabled"));

if (slp > SLP_INTEL_TXT)
if (slp > SLP_AMD_SKINIT)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
N_("unknown secure launch platform type: %d"), slp);

Expand Down Expand Up @@ -239,6 +258,14 @@ grub_cmd_slaunch_module (grub_command_t cmd __attribute__ ((unused)),
goto fail;
}
}
else if (slp == SLP_AMD_SKINIT)
{
if (!grub_skinit_is_slb (slaunch_module, size))
{
grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("it does not look like SLB"));
goto fail;
}
}

grub_file_close (file);

Expand Down Expand Up @@ -269,6 +296,10 @@ grub_cmd_slaunch_state (grub_command_t cmd __attribute__ ((unused)),
grub_printf ("Secure launcher: Intel TXT\n");
grub_txt_state_show ();
}
else if (slp == SLP_AMD_SKINIT)
{
grub_printf ("Secure launcher: AMD SKINIT\n");
}
else
return grub_error (GRUB_ERR_BAD_ARGUMENT,
N_("Unknown secure launcher platform type: %d\n"), slp);
Expand Down
2 changes: 2 additions & 0 deletions include/grub/i386/skinit.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#include <grub/cpu/relocator.h>
#include <grub/i386/slaunch.h>

int grub_skinit_is_slb (const void *slb_base, grub_uint32_t slb_size);

grub_err_t grub_skinit_boot_prepare (struct grub_relocator *rel,
struct grub_slaunch_params *slparams);

Expand Down
1 change: 1 addition & 0 deletions include/grub/i386/slaunch.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
/* Secure launch platform types. */
#define SLP_NONE 0
#define SLP_INTEL_TXT 1
#define SLP_AMD_SKINIT 2

#define GRUB_SLAUNCH_TPM_EVT_LOG_SIZE (8 * GRUB_PAGE_SIZE)

Expand Down
2 changes: 2 additions & 0 deletions include/grub/slr_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ struct grub_slr_entry_dl_info
grub_uint64_t dl_handler;
grub_uint64_t dce_base;
grub_uint32_t dce_size;
grub_uint64_t dlme_base;
grub_uint32_t dlme_size;
grub_uint64_t dlme_entry;
} GRUB_PACKED;

Expand Down

0 comments on commit c90cc21

Please sign in to comment.