Skip to content
19 changes: 13 additions & 6 deletions core/arch/arm/plat-qcom/hoya/lemans/target.mk
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,6 @@ ifneq ($(CFG_INSECURE),y)
CFG_QCOM_QFPROM_FUSEPROV ?= y
endif

ifeq ($(CFG_QCOM_QFPROM_FUSEPROV),y)
$(call force,CFG_QCOM_CMD_DB,y)
$(call force,CFG_QCOM_RPMH_CLIENT,y)
$(call force,CFG_QCOM_QFPROM,y)
endif

CFG_QCOM_PAS_PTA ?= y

ifeq ($(CFG_QCOM_PAS_PTA),y)
Expand All @@ -24,3 +18,16 @@ CFG_QCOM_PAS_AUTH ?= y
CFG_PAS_MD_SLOTS ?= 8
endif
CFG_QCOM_HWKM ?= y

ifeq ($(CFG_QCOM_PAS_AUTH),y)
$(call force,CFG_QCOM_FUSE_PTA,y)
endif

ifneq ($(filter y,$(CFG_QCOM_QFPROM_FUSEPROV) $(CFG_QCOM_FUSE_PTA)),)
$(call force,CFG_QCOM_QFPROM,y)
endif

ifeq ($(CFG_QCOM_QFPROM),y)
$(call force,CFG_QCOM_CMD_DB,y)
$(call force,CFG_QCOM_RPMH_CLIENT,y)
endif
30 changes: 30 additions & 0 deletions core/drivers/qcom/qfprom/lemans/qfprom_target.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,36 @@
#define QFPROM_CORR_BASE 0x00784000
#define QFPROM_SIZE 0x4000

#define SECURE_BOOT_APPS_ADDR (SECURITY_CONTROL_BASE + 0x606c)
#define SECURE_BOOT_AUTH_EN_BMSK 0x20
#define SECURE_BOOT_USE_SERIAL_NUM_BMSK 0x40

#define QFPROM_ROOT_OF_TRUST_BYTE_SIZE 48

#define PK_HASH0_SENSE_ADDR (SECURITY_CONTROL_BASE + 0x6190)

#define OEM_ID_SENSE_ADDR (SECURITY_CONTROL_BASE + 0x6138)
#define OEM_ID_BMSK 0xffff0000
#define OEM_ID_SHFT 16
#define MODEL_ID_BMSK 0x0000ffff
#define MODEL_ID_SHFT 0
#define JTAG_ID_SENSE_ADDR (SECURITY_CONTROL_BASE + 0x6130)
#define JTAG_ID_AUTH_BMSK 0x0fffffff
#define SERIAL_NUM_SENSE_ADDR (SECURITY_CONTROL_BASE + 0x6134)

#define TCSR_SOC_HW_VERSION_ADDR 0x01FC8000
#define SOC_HW_VERSION_FAM_DEV_BMSK 0xffff0000
#define SOC_HW_VERSION_FAM_DEV_SHFT 16

#define OEM_CONFIG2_ADDR (SECURITY_CONTROL_BASE + 0x6054)
#define EKU_ENFORCEMENT_EN_SHFT 30

#define SEGMENT_HASH_SELECT_SUPPORTED 1
#define SEGMENT_HASH_FUNCTION_SELECT0_SHFT 16

#define OEM_CONFIG0_ADDR (SECURITY_CONTROL_BASE + 0x604c)
#define IMAGE_ENCRYPTION_ENABLE_SHFT 19

#define QFPROM_BLOW_TIMER_OFFSET 0x2030
#define QFPROM_ACCEL_OFFSET 0x2038

Expand Down
202 changes: 202 additions & 0 deletions core/drivers/qcom/qfprom/qfprom_secboot.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
// SPDX-License-Identifier: BSD-2-Clause
Comment thread
zelvam95 marked this conversation as resolved.
/*
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/

#include <inttypes.h>
#include <io.h>
#include <mm/core_memprot.h>
#include <mm/core_mmu.h>
#include <string.h>
#include <trace.h>
#include <utee_defines.h>
#include <util.h>

#include "qfprom_priv.h"
#include "qfprom_target.h"

register_phys_mem_pgdir(MEM_AREA_IO_SEC, TCSR_SOC_HW_VERSION_ADDR,
CORE_MMU_PGDIR_SIZE);

TEE_Result qcom_secboot_is_enabled(bool *enabled)
{
struct qfprom_context *drv = qfprom_get_context();
uint32_t val = 0;

if (!enabled)
return TEE_ERROR_BAD_PARAMETERS;

if (!drv->raw_base_va)
return TEE_ERROR_BAD_STATE;

val = io_read32(drv->raw_base_va +
(SECURE_BOOT_APPS_ADDR - SECURITY_CONTROL_BASE));
*enabled = (val & SECURE_BOOT_AUTH_EN_BMSK) != 0;

return TEE_SUCCESS;
}

TEE_Result qcom_secboot_get_use_serial_num(bool *enabled)
{
struct qfprom_context *drv = qfprom_get_context();
uint32_t val = 0;

if (!enabled)
return TEE_ERROR_BAD_PARAMETERS;

if (!drv->raw_base_va)
return TEE_ERROR_BAD_STATE;

val = io_read32(drv->raw_base_va +
(SECURE_BOOT_APPS_ADDR - SECURITY_CONTROL_BASE));
*enabled = (val & SECURE_BOOT_USE_SERIAL_NUM_BMSK) != 0;

return TEE_SUCCESS;
}

static TEE_Result read_sense_reg(paddr_t pa, uint32_t *out)
{
struct qfprom_context *drv = qfprom_get_context();

if (!drv->raw_base_va)
return TEE_ERROR_BAD_STATE;

*out = io_read32(drv->raw_base_va + (pa - SECURITY_CONTROL_BASE));

return TEE_SUCCESS;
}

TEE_Result qcom_secboot_get_root_of_trust(uint8_t *hash, size_t len)
{
Comment thread
zelvam95 marked this conversation as resolved.
size_t off = 0;

if (!hash)
return TEE_ERROR_BAD_PARAMETERS;

if (len != QFPROM_ROOT_OF_TRUST_BYTE_SIZE)
return TEE_ERROR_BAD_PARAMETERS;

for (off = 0; off < len; off += sizeof(uint32_t)) {
TEE_Result res = TEE_ERROR_GENERIC;
uint32_t word = 0;

res = read_sense_reg(PK_HASH0_SENSE_ADDR + off, &word);
if (res)
return res;

memcpy(hash + off, &word, MIN(sizeof(word), len - off));
}

return TEE_SUCCESS;
}

TEE_Result qcom_secboot_get_device_ids(struct qcom_secboot_device_ids *ids)
{
TEE_Result res = TEE_ERROR_GENERIC;
uint32_t val = 0;

if (!ids)
return TEE_ERROR_BAD_PARAMETERS;

res = read_sense_reg(OEM_ID_SENSE_ADDR, &val);
if (res)
return res;
ids->oem_id = (val & OEM_ID_BMSK) >> OEM_ID_SHFT;
ids->model_id = (val & MODEL_ID_BMSK) >> MODEL_ID_SHFT;

res = read_sense_reg(JTAG_ID_SENSE_ADDR, &val);
if (res)
return res;
ids->jtag_id = val & JTAG_ID_AUTH_BMSK;

res = read_sense_reg(SERIAL_NUM_SENSE_ADDR, &ids->serial_num);
if (res)
return res;

return TEE_SUCCESS;
}

#define SEGMENT_HASH_ROOT_CERT_SEL_MAX 3U

TEE_Result qcom_secboot_get_segment_hash_len(uint32_t root_cert_sel,
uint32_t *hash_len)
{
if (!hash_len)
return TEE_ERROR_BAD_PARAMETERS;

if (root_cert_sel > SEGMENT_HASH_ROOT_CERT_SEL_MAX)
return TEE_ERROR_BAD_PARAMETERS;

#if SEGMENT_HASH_SELECT_SUPPORTED
{
TEE_Result res = TEE_ERROR_GENERIC;
uint32_t val = 0;

res = read_sense_reg(OEM_CONFIG2_ADDR, &val);
if (res)
return res;

if (val & BIT32(SEGMENT_HASH_FUNCTION_SELECT0_SHFT +
root_cert_sel))
*hash_len = TEE_SHA256_HASH_SIZE;
else
*hash_len = TEE_SHA384_HASH_SIZE;
}
#else
*hash_len = TEE_SHA384_HASH_SIZE;
#endif

return TEE_SUCCESS;
}

TEE_Result qcom_secboot_get_eku_enforcement_en(bool *enabled)
{
TEE_Result res = TEE_ERROR_GENERIC;
uint32_t val = 0;

if (!enabled)
return TEE_ERROR_BAD_PARAMETERS;

res = read_sense_reg(OEM_CONFIG2_ADDR, &val);
if (res)
return res;

*enabled = val & BIT32(EKU_ENFORCEMENT_EN_SHFT);

return TEE_SUCCESS;
}

TEE_Result qcom_secboot_get_image_encryption_en(bool *enabled)
{
TEE_Result res = TEE_ERROR_GENERIC;
uint32_t val = 0;

if (!enabled)
return TEE_ERROR_BAD_PARAMETERS;

res = read_sense_reg(OEM_CONFIG0_ADDR, &val);
if (res)
return res;

*enabled = val & BIT32(IMAGE_ENCRYPTION_ENABLE_SHFT);

return TEE_SUCCESS;
}

TEE_Result qcom_secboot_get_soc_hw_version(uint32_t *fam_dev)
{
vaddr_t va = 0;

if (!fam_dev)
return TEE_ERROR_BAD_PARAMETERS;

va = (vaddr_t)phys_to_virt(TCSR_SOC_HW_VERSION_ADDR, MEM_AREA_IO_SEC,
sizeof(uint32_t));
if (!va)
return TEE_ERROR_GENERIC;

*fam_dev = (io_read32(va) & SOC_HW_VERSION_FAM_DEV_BMSK) >>
SOC_HW_VERSION_FAM_DEV_SHFT;

return TEE_SUCCESS;
}
1 change: 1 addition & 0 deletions core/drivers/qcom/qfprom/sub.mk
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ srcs-y += qfprom_core.c
srcs-y += qfprom_hal.c
srcs-y += qfprom_target.c
srcs-y += $(PLATFORM_FLAVOR)/qfprom_fuse_region.c
srcs-$(CFG_QCOM_FUSE_PTA) += qfprom_secboot.c

global-incdirs-y += .
global-incdirs-y += $(PLATFORM_FLAVOR)
24 changes: 24 additions & 0 deletions core/include/drivers/qcom/qfprom/qfprom.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,30 @@ TEE_Result qfprom_read_row(uint32_t addr,
enum qfprom_addr_space type,
uint32_t *data);

TEE_Result qcom_secboot_is_enabled(bool *enabled);

TEE_Result qcom_secboot_get_use_serial_num(bool *enabled);

TEE_Result qcom_secboot_get_root_of_trust(uint8_t *hash, size_t len);

struct qcom_secboot_device_ids {
uint32_t oem_id;
uint32_t model_id;
uint32_t jtag_id;
uint32_t serial_num;
};

TEE_Result qcom_secboot_get_device_ids(struct qcom_secboot_device_ids *ids);

TEE_Result qcom_secboot_get_soc_hw_version(uint32_t *fam_dev);

TEE_Result qcom_secboot_get_segment_hash_len(uint32_t root_cert_sel,
uint32_t *hash_len);

TEE_Result qcom_secboot_get_eku_enforcement_en(bool *enabled);

TEE_Result qcom_secboot_get_image_encryption_en(bool *enabled);

/* Write QFPROM row data */
TEE_Result qfprom_write_row(uint32_t addr, uint32_t *data);

Expand Down
Loading