mirror of
https://github.com/torvalds/linux.git
synced 2024-12-29 14:21:47 +00:00
habanalabs/gaudi2: add secured attestation info uapi
User will provide a nonce via the ioctl, and will retrieve secured attestation data of the boot, generated using given nonce. Signed-off-by: Dani Liberman <dliberman@habana.ai> Reviewed-by: Oded Gabbay <ogabbay@kernel.org> Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
This commit is contained in:
parent
43657dadfe
commit
0c88760f8f
@ -2988,3 +2988,49 @@ void hl_fw_set_max_power(struct hl_device *hdev)
|
||||
if (rc)
|
||||
dev_err(hdev->dev, "Failed to set max power, error %d\n", rc);
|
||||
}
|
||||
|
||||
static int hl_fw_get_sec_attest_data(struct hl_device *hdev, u32 packet_id, void *data, u32 size,
|
||||
u32 nonce, u32 timeout)
|
||||
{
|
||||
struct cpucp_packet pkt = {};
|
||||
dma_addr_t req_dma_addr;
|
||||
void *req_cpu_addr;
|
||||
int rc;
|
||||
|
||||
req_cpu_addr = hl_cpu_accessible_dma_pool_alloc(hdev, size, &req_dma_addr);
|
||||
if (!data) {
|
||||
dev_err(hdev->dev,
|
||||
"Failed to allocate DMA memory for CPU-CP packet %u\n", packet_id);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(data, 0, size);
|
||||
|
||||
pkt.ctl = cpu_to_le32(packet_id << CPUCP_PKT_CTL_OPCODE_SHIFT);
|
||||
pkt.addr = cpu_to_le64(req_dma_addr);
|
||||
pkt.data_max_size = cpu_to_le32(size);
|
||||
pkt.nonce = cpu_to_le32(nonce);
|
||||
|
||||
rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
|
||||
timeout, NULL);
|
||||
if (rc) {
|
||||
dev_err(hdev->dev,
|
||||
"Failed to handle CPU-CP pkt %u, error %d\n", packet_id, rc);
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy(data, req_cpu_addr, size);
|
||||
|
||||
out:
|
||||
hl_cpu_accessible_dma_pool_free(hdev, size, req_cpu_addr);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int hl_fw_get_sec_attest_info(struct hl_device *hdev, struct cpucp_sec_attest_info *sec_attest_info,
|
||||
u32 nonce)
|
||||
{
|
||||
return hl_fw_get_sec_attest_data(hdev, CPUCP_PACKET_SEC_ATTEST_GET, sec_attest_info,
|
||||
sizeof(struct cpucp_sec_attest_info), nonce,
|
||||
HL_CPUCP_SEC_ATTEST_INFO_TINEOUT_USEC);
|
||||
}
|
||||
|
@ -66,6 +66,7 @@ struct hl_fpriv;
|
||||
#define HL_CPUCP_INFO_TIMEOUT_USEC 10000000 /* 10s */
|
||||
#define HL_CPUCP_EEPROM_TIMEOUT_USEC 10000000 /* 10s */
|
||||
#define HL_CPUCP_MON_DUMP_TIMEOUT_USEC 10000000 /* 10s */
|
||||
#define HL_CPUCP_SEC_ATTEST_INFO_TINEOUT_USEC 10000000 /* 10s */
|
||||
|
||||
#define HL_FW_STATUS_POLL_INTERVAL_USEC 10000 /* 10ms */
|
||||
#define HL_FW_COMMS_STATUS_PLDM_POLL_INTERVAL_USEC 1000000 /* 1s */
|
||||
@ -3748,6 +3749,8 @@ int hl_get_pwm_info(struct hl_device *hdev, int sensor_index, u32 attr, long *va
|
||||
void hl_set_pwm_info(struct hl_device *hdev, int sensor_index, u32 attr, long value);
|
||||
long hl_fw_get_max_power(struct hl_device *hdev);
|
||||
void hl_fw_set_max_power(struct hl_device *hdev);
|
||||
int hl_fw_get_sec_attest_info(struct hl_device *hdev, struct cpucp_sec_attest_info *sec_attest_info,
|
||||
u32 nonce);
|
||||
int hl_set_voltage(struct hl_device *hdev, int sensor_index, u32 attr, long value);
|
||||
int hl_set_current(struct hl_device *hdev, int sensor_index, u32 attr, long value);
|
||||
int hl_set_power(struct hl_device *hdev, int sensor_index, u32 attr, long value);
|
||||
|
@ -662,6 +662,55 @@ static int dev_mem_alloc_page_sizes_info(struct hl_fpriv *hpriv, struct hl_info_
|
||||
return copy_to_user(out, &info, min_t(size_t, max_size, sizeof(info))) ? -EFAULT : 0;
|
||||
}
|
||||
|
||||
static int sec_attest_info(struct hl_fpriv *hpriv, struct hl_info_args *args)
|
||||
{
|
||||
void __user *out = (void __user *) (uintptr_t) args->return_pointer;
|
||||
struct cpucp_sec_attest_info *sec_attest_info;
|
||||
struct hl_info_sec_attest *info;
|
||||
u32 max_size = args->return_size;
|
||||
int rc;
|
||||
|
||||
if ((!max_size) || (!out))
|
||||
return -EINVAL;
|
||||
|
||||
sec_attest_info = kmalloc(sizeof(*sec_attest_info), GFP_KERNEL);
|
||||
if (!sec_attest_info)
|
||||
return -ENOMEM;
|
||||
|
||||
info = kmalloc(sizeof(*info), GFP_KERNEL);
|
||||
if (!info) {
|
||||
rc = -ENOMEM;
|
||||
goto free_sec_attest_info;
|
||||
}
|
||||
|
||||
rc = hl_fw_get_sec_attest_info(hpriv->hdev, sec_attest_info, args->sec_attest_nonce);
|
||||
if (rc)
|
||||
goto free_info;
|
||||
|
||||
info->nonce = le32_to_cpu(sec_attest_info->nonce);
|
||||
info->pcr_quote_len = le16_to_cpu(sec_attest_info->pcr_quote_len);
|
||||
info->pub_data_len = le16_to_cpu(sec_attest_info->pub_data_len);
|
||||
info->certificate_len = le16_to_cpu(sec_attest_info->certificate_len);
|
||||
info->pcr_num_reg = sec_attest_info->pcr_num_reg;
|
||||
info->pcr_reg_len = sec_attest_info->pcr_reg_len;
|
||||
info->quote_sig_len = sec_attest_info->quote_sig_len;
|
||||
memcpy(&info->pcr_data, &sec_attest_info->pcr_data, sizeof(info->pcr_data));
|
||||
memcpy(&info->pcr_quote, &sec_attest_info->pcr_quote, sizeof(info->pcr_quote));
|
||||
memcpy(&info->public_data, &sec_attest_info->public_data, sizeof(info->public_data));
|
||||
memcpy(&info->certificate, &sec_attest_info->certificate, sizeof(info->certificate));
|
||||
memcpy(&info->quote_sig, &sec_attest_info->quote_sig, sizeof(info->quote_sig));
|
||||
|
||||
rc = copy_to_user(out, info,
|
||||
min_t(size_t, max_size, sizeof(*info))) ? -EFAULT : 0;
|
||||
|
||||
free_info:
|
||||
kfree(info);
|
||||
free_sec_attest_info:
|
||||
kfree(sec_attest_info);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int eventfd_register(struct hl_fpriv *hpriv, struct hl_info_args *args)
|
||||
{
|
||||
int rc;
|
||||
@ -844,6 +893,9 @@ static int _hl_info_ioctl(struct hl_fpriv *hpriv, void *data,
|
||||
case HL_INFO_DRAM_PENDING_ROWS:
|
||||
return dram_pending_rows_info(hpriv, args);
|
||||
|
||||
case HL_INFO_SECURED_ATTESTATION:
|
||||
return sec_attest_info(hpriv, args);
|
||||
|
||||
case HL_INFO_REGISTER_EVENTFD:
|
||||
return eventfd_register(hpriv, args);
|
||||
|
||||
|
@ -629,6 +629,12 @@ enum pq_init_status {
|
||||
* CPUCP_PACKET_ENGINE_CORE_ASID_SET -
|
||||
* Packet to perform engine core ASID configuration
|
||||
*
|
||||
* CPUCP_PACKET_SEC_ATTEST_GET -
|
||||
* Get the attestaion data that is collected during various stages of the
|
||||
* boot sequence. the attestation data is also hashed with some unique
|
||||
* number (nonce) provided by the host to prevent replay attacks.
|
||||
* public key and certificate also provided as part of the FW response.
|
||||
*
|
||||
* CPUCP_PACKET_MONITOR_DUMP_GET -
|
||||
* Get monitors registers dump from the CpuCP kernel.
|
||||
* The CPU will put the registers dump in the a buffer allocated by the driver
|
||||
@ -691,15 +697,15 @@ enum cpucp_packet_id {
|
||||
CPUCP_PACKET_RESERVED, /* not used */
|
||||
CPUCP_PACKET_ENGINE_CORE_ASID_SET, /* internal */
|
||||
CPUCP_PACKET_RESERVED2, /* not used */
|
||||
CPUCP_PACKET_SEC_ATTEST_GET, /* internal */
|
||||
CPUCP_PACKET_RESERVED3, /* not used */
|
||||
CPUCP_PACKET_RESERVED4, /* not used */
|
||||
CPUCP_PACKET_RESERVED5, /* not used */
|
||||
CPUCP_PACKET_MONITOR_DUMP_GET, /* debugfs */
|
||||
CPUCP_PACKET_RESERVED5, /* not used */
|
||||
CPUCP_PACKET_RESERVED6, /* not used */
|
||||
CPUCP_PACKET_RESERVED7, /* not used */
|
||||
CPUCP_PACKET_RESERVED8, /* not used */
|
||||
CPUCP_PACKET_RESERVED9, /* not used */
|
||||
CPUCP_PACKET_RESERVED10, /* not used */
|
||||
CPUCP_PACKET_ACTIVE_STATUS_SET, /* internal */
|
||||
CPUCP_PACKET_ID_MAX /* must be last */
|
||||
};
|
||||
@ -794,6 +800,9 @@ struct cpucp_packet {
|
||||
* result cannot be used to hold general purpose data.
|
||||
*/
|
||||
__le32 status_mask;
|
||||
|
||||
/* random, used once number, for security packets */
|
||||
__le32 nonce;
|
||||
};
|
||||
|
||||
/* For NIC requests */
|
||||
@ -1219,6 +1228,70 @@ enum cpu_reset_status {
|
||||
CPU_RST_STATUS_SOFT_RST_DONE = 1,
|
||||
};
|
||||
|
||||
#define SEC_PCR_DATA_BUF_SZ 256
|
||||
#define SEC_PCR_QUOTE_BUF_SZ 510 /* (512 - 2) 2 bytes used for size */
|
||||
#define SEC_SIGNATURE_BUF_SZ 255 /* (256 - 1) 1 byte used for size */
|
||||
#define SEC_PUB_DATA_BUF_SZ 510 /* (512 - 2) 2 bytes used for size */
|
||||
#define SEC_CERTIFICATE_BUF_SZ 2046 /* (2048 - 2) 2 bytes used for size */
|
||||
|
||||
/*
|
||||
* struct cpucp_sec_attest_info - attestation report of the boot
|
||||
* @pcr_data: raw values of the PCR registers
|
||||
* @pcr_num_reg: number of PCR registers in the pcr_data array
|
||||
* @pcr_reg_len: length of each PCR register in the pcr_data array (bytes)
|
||||
* @nonce: number only used once. random number provided by host. this also
|
||||
* passed to the quote command as a qualifying data.
|
||||
* @pcr_quote_len: length of the attestation quote data (bytes)
|
||||
* @pcr_quote: attestation report data structure
|
||||
* @quote_sig_len: length of the attestation report signature (bytes)
|
||||
* @quote_sig: signature structure of the attestation report
|
||||
* @pub_data_len: length of the public data (bytes)
|
||||
* @public_data: public key for the signed attestation
|
||||
* (outPublic + name + qualifiedName)
|
||||
* @certificate_len: length of the certificate (bytes)
|
||||
* @certificate: certificate for the attestation signing key
|
||||
*/
|
||||
struct cpucp_sec_attest_info {
|
||||
__u8 pcr_data[SEC_PCR_DATA_BUF_SZ];
|
||||
__u8 pcr_num_reg;
|
||||
__u8 pcr_reg_len;
|
||||
__le16 pad0;
|
||||
__le32 nonce;
|
||||
__le16 pcr_quote_len;
|
||||
__u8 pcr_quote[SEC_PCR_QUOTE_BUF_SZ];
|
||||
__u8 quote_sig_len;
|
||||
__u8 quote_sig[SEC_SIGNATURE_BUF_SZ];
|
||||
__le16 pub_data_len;
|
||||
__u8 public_data[SEC_PUB_DATA_BUF_SZ];
|
||||
__le16 certificate_len;
|
||||
__u8 certificate[SEC_CERTIFICATE_BUF_SZ];
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cpucp_dev_info_signed - device information signed by a secured device
|
||||
* @info: device information structure as defined above
|
||||
* @nonce: number only used once. random number provided by host. this number is
|
||||
* hashed and signed along with the device information.
|
||||
* @info_sig_len: length of the attestation signature (bytes)
|
||||
* @info_sig: signature of the info + nonce data.
|
||||
* @pub_data_len: length of the public data (bytes)
|
||||
* @public_data: public key info signed info data
|
||||
* (outPublic + name + qualifiedName)
|
||||
* @certificate_len: length of the certificate (bytes)
|
||||
* @certificate: certificate for the signing key
|
||||
*/
|
||||
struct cpucp_dev_info_signed {
|
||||
struct cpucp_info info; /* assumed to be 64bit aligned */
|
||||
__le32 nonce;
|
||||
__le32 pad0;
|
||||
__u8 info_sig_len;
|
||||
__u8 info_sig[SEC_SIGNATURE_BUF_SZ];
|
||||
__le16 pub_data_len;
|
||||
__u8 public_data[SEC_PUB_DATA_BUF_SZ];
|
||||
__le16 certificate_len;
|
||||
__u8 certificate[SEC_CERTIFICATE_BUF_SZ];
|
||||
};
|
||||
|
||||
/*
|
||||
* struct dcore_monitor_regs_data - DCORE monitor regs data.
|
||||
* the structure follows sync manager block layout. relevant only to Gaudi.
|
||||
|
@ -773,6 +773,7 @@ enum hl_server_type {
|
||||
* Razwi initiator.
|
||||
* Razwi cause, was it a page fault or MMU access error.
|
||||
* HL_INFO_DEV_MEM_ALLOC_PAGE_SIZES - Retrieve valid page sizes for device memory allocation
|
||||
* HL_INFO_SECURED_ATTESTATION - Retrieve attestation report of the boot.
|
||||
* HL_INFO_REGISTER_EVENTFD - Register eventfd for event notifications.
|
||||
* HL_INFO_UNREGISTER_EVENTFD - Unregister eventfd
|
||||
* HL_INFO_GET_EVENTS - Retrieve the last occurred events
|
||||
@ -802,6 +803,7 @@ enum hl_server_type {
|
||||
#define HL_INFO_CS_TIMEOUT_EVENT 24
|
||||
#define HL_INFO_RAZWI_EVENT 25
|
||||
#define HL_INFO_DEV_MEM_ALLOC_PAGE_SIZES 26
|
||||
#define HL_INFO_SECURED_ATTESTATION 27
|
||||
#define HL_INFO_REGISTER_EVENTFD 28
|
||||
#define HL_INFO_UNREGISTER_EVENTFD 29
|
||||
#define HL_INFO_GET_EVENTS 30
|
||||
@ -1133,6 +1135,45 @@ struct hl_info_dev_memalloc_page_sizes {
|
||||
__u64 page_order_bitmask;
|
||||
};
|
||||
|
||||
#define SEC_PCR_DATA_BUF_SZ 256
|
||||
#define SEC_PCR_QUOTE_BUF_SZ 510 /* (512 - 2) 2 bytes used for size */
|
||||
#define SEC_SIGNATURE_BUF_SZ 255 /* (256 - 1) 1 byte used for size */
|
||||
#define SEC_PUB_DATA_BUF_SZ 510 /* (512 - 2) 2 bytes used for size */
|
||||
#define SEC_CERTIFICATE_BUF_SZ 2046 /* (2048 - 2) 2 bytes used for size */
|
||||
|
||||
/*
|
||||
* struct hl_info_sec_attest - attestation report of the boot
|
||||
* @nonce: number only used once. random number provided by host. this also passed to the quote
|
||||
* command as a qualifying data.
|
||||
* @pcr_quote_len: length of the attestation quote data (bytes)
|
||||
* @pub_data_len: length of the public data (bytes)
|
||||
* @certificate_len: length of the certificate (bytes)
|
||||
* @pcr_num_reg: number of PCR registers in the pcr_data array
|
||||
* @pcr_reg_len: length of each PCR register in the pcr_data array (bytes)
|
||||
* @quote_sig_len: length of the attestation report signature (bytes)
|
||||
* @pcr_data: raw values of the PCR registers
|
||||
* @pcr_quote: attestation report data structure
|
||||
* @quote_sig: signature structure of the attestation report
|
||||
* @public_data: public key for the signed attestation
|
||||
* (outPublic + name + qualifiedName)
|
||||
* @certificate: certificate for the attestation signing key
|
||||
*/
|
||||
struct hl_info_sec_attest {
|
||||
__u32 nonce;
|
||||
__u16 pcr_quote_len;
|
||||
__u16 pub_data_len;
|
||||
__u16 certificate_len;
|
||||
__u8 pcr_num_reg;
|
||||
__u8 pcr_reg_len;
|
||||
__u8 quote_sig_len;
|
||||
__u8 pcr_data[SEC_PCR_DATA_BUF_SZ];
|
||||
__u8 pcr_quote[SEC_PCR_QUOTE_BUF_SZ];
|
||||
__u8 quote_sig[SEC_SIGNATURE_BUF_SZ];
|
||||
__u8 public_data[SEC_PUB_DATA_BUF_SZ];
|
||||
__u8 certificate[SEC_CERTIFICATE_BUF_SZ];
|
||||
__u8 pad0[2];
|
||||
};
|
||||
|
||||
enum gaudi_dcores {
|
||||
HL_GAUDI_WS_DCORE,
|
||||
HL_GAUDI_WN_DCORE,
|
||||
@ -1158,6 +1199,7 @@ enum gaudi_dcores {
|
||||
* driver. It is possible for the user to allocate buffer larger than
|
||||
* needed, hence updating this variable so user will know the exact amount
|
||||
* of bytes copied by the kernel to the buffer.
|
||||
* @sec_attest_nonce: Nonce number used for attestation report.
|
||||
* @pad: Padding to 64 bit.
|
||||
*/
|
||||
struct hl_info_args {
|
||||
@ -1172,6 +1214,7 @@ struct hl_info_args {
|
||||
__u32 pll_index;
|
||||
__u32 eventfd;
|
||||
__u32 user_buffer_actual_size;
|
||||
__u32 sec_attest_nonce;
|
||||
};
|
||||
|
||||
__u32 pad;
|
||||
|
Loading…
Reference in New Issue
Block a user