diff --git a/libcaliptra/src/caliptra_api.c b/libcaliptra/src/caliptra_api.c index 5bac11a39e..6c9827ee9c 100644 --- a/libcaliptra/src/caliptra_api.c +++ b/libcaliptra/src/caliptra_api.c @@ -11,6 +11,7 @@ #include "caliptra_types.h" #include "caliptra_fuses.h" #include "caliptra_mbox.h" +#include "caliptra_sha.h" #define CALIPTRA_STATUS_NOT_READY (0) #define CALIPTRA_REG_BASE (CALIPTRA_TOP_REG_MBOX_CSR_BASE_ADDR) @@ -1251,7 +1252,6 @@ void caliptra_req_idev_csr_complete() caliptra_write_u32(CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_CPTRA_DBG_MANUF_SERVICE_REG, dbg_manuf_serv_req & ~0x01); } - // Check if IDEV CSR is ready. bool caliptra_is_idevid_csr_ready() { uint32_t status; @@ -1264,3 +1264,81 @@ bool caliptra_is_idevid_csr_ready() { return false; } + +int caliptra_compute_sha(int mode, int endian, uint32_t* data, uint32_t data_len, uint32_t* hash, uint32_t mbox_start_addr) { + if (mode == CALIPTRA_SHA_ACCELERATOR_MODE_MBOX_384 || mode == CALIPTRA_SHA_ACCELERATOR_MODE_MBOX_512) { + // Writing 1 will clear the lock + caliptra_write_u32(CALIPTRA_SHA_ACCELERATOR_LOCK_ADDR, 0x1); + // Zeroize engine registers to start fresh + caliptra_write_u32(CALIPTRA_SHA_ACCELERATOR_CONTROL_ADDR, 0x1); + // Set mode and endianess accordingly + uint32_t control_value = (mode & 0xFFFF) | ((endian & 0xFF) << 16); + caliptra_write_u32(CALIPTRA_SHA_ACCELERATOR_CONTROL_ADDR, control_value); + // Write data to the SHA accelerator + caliptra_write_u32(CALIPTRA_SHA_ACCELERATOR_START_ADDR, mbox_start_addr); + caliptra_write_u32(CALIPTRA_SHA_ACCELERATOR_DLEN_ADDR, data_len); + // Let engine read out mbox addr + caliptra_write_u32(CALIPTRA_SHA_ACCELERATOR_EXECUTE_ADDR, 0x1); + // Wait for the SHA accelerator to complete + uint32_t status; + do { + caliptra_read_u32(CALIPTRA_SHA_ACCELERATOR_STATUS_ADDR, &status); + } while ((status & 0x1) == 0); + // Read out the DIGEST registers and place into hash struct + for (int i = 0; i < 16; i++) { + caliptra_read_u32(CALIPTRA_SHA_ACCELERATOR_DIGEST_ADDR + (i * 4), &hash[i]); + } + + return 0; + } else { + return INVALID_PARAMS; + } +} + +int caliptra_start_sha_stream(int mode, int endian, uint32_t* data, uint32_t data_len) { + if (mode == CALIPTRA_SHA_ACCELERATOR_MODE_STREAM_384 || mode == CALIPTRA_SHA_ACCELERATOR_MODE_STREAM_512) { + // Writing 1 will clear the lock + caliptra_write_u32(CALIPTRA_SHA_ACCELERATOR_LOCK_ADDR, 0x1); + // Zeroize engine registers to start fresh + caliptra_write_u32(CALIPTRA_SHA_ACCELERATOR_CONTROL_ADDR, 0x1); + // Set mode and endianess accordingly + uint32_t control_value = (mode & 0xFFFF) | ((endian & 0xFF) << 16); + caliptra_write_u32(CALIPTRA_SHA_ACCELERATOR_CONTROL_ADDR, control_value); + + // Write initial data to the SHA accelerator + for (uint32_t i = 0; i < data_len; i++) { + caliptra_write_u32(CALIPTRA_SHA_ACCELERATOR_DATAIN_ADDR, data[i]); + } + + return 0; + } else { + return INVALID_PARAMS; + } +} + +int caliptra_update_sha_stream(uint32_t* data, uint32_t data_len) { + // Write data to the SHA accelerator + for (uint32_t i = 0; i < data_len; i++) { + caliptra_write_u32(CALIPTRA_SHA_ACCELERATOR_DATAIN_ADDR, data[i]); + } + + return 0; +} + +int caliptra_finish_sha_stream(uint32_t* hash) { + // Signal the SHA accelerator to finish the stream + caliptra_write_u32(CALIPTRA_SHA_ACCELERATOR_EXECUTE_ADDR, 0x1); + + // Wait for the SHA accelerator to complete + uint32_t status; + do { + caliptra_read_u32(CALIPTRA_SHA_ACCELERATOR_STATUS_ADDR, &status); + } while ((status & 0x1) == 0); + + // Read out the DIGEST registers and place into hash struct + for (int i = 0; i < 16; i++) { + caliptra_read_u32(CALIPTRA_SHA_ACCELERATOR_DIGEST_ADDR + (i * 4), &hash[i]); + } + + return 0; +} diff --git a/libcaliptra/src/caliptra_fuses.h b/libcaliptra/src/caliptra_fuses.h index 184d987864..d6e424173a 100644 --- a/libcaliptra/src/caliptra_fuses.h +++ b/libcaliptra/src/caliptra_fuses.h @@ -48,9 +48,9 @@ static inline uint32_t caliptra_read_fw_error_fatal(void) return caliptra_generic_and_fuse_read(GENERIC_AND_FUSE_REG_CPTRA_FW_ERROR_FATAL); } -static inline uint32_t caliptra_read_dbg_manuf_serv() +static inline uint32_t caliptra_read_dbg_manuf_serv() { - return caliptra_generic_and_fuse_read(GENERIC_AND_FUSE_REG_CPTRA_DBG_MANUF_SERVICE_REG); + return caliptra_generic_and_fuse_read(GENERIC_AND_FUSE_REG_CPTRA_DBG_MANUF_SERVICE_REG); } @@ -119,10 +119,10 @@ static inline void caliptra_write_fuse_valid_pauser(uint32_t data) caliptra_generic_and_fuse_write(GENERIC_AND_FUSE_REG_CPTRA_FUSE_VALID_PAUSER, data); } -static inline void caliptra_write_dbg_manuf_serv(uint32_t data) +static inline void caliptra_write_dbg_manuf_serv(uint32_t data) { // Set Manuf service reg - caliptra_generic_and_fuse_write(GENERIC_AND_FUSE_REG_CPTRA_DBG_MANUF_SERVICE_REG, data); + caliptra_generic_and_fuse_write(GENERIC_AND_FUSE_REG_CPTRA_DBG_MANUF_SERVICE_REG, data); } diff --git a/libcaliptra/src/caliptra_sha.h b/libcaliptra/src/caliptra_sha.h new file mode 100644 index 0000000000..d508d30931 --- /dev/null +++ b/libcaliptra/src/caliptra_sha.h @@ -0,0 +1,26 @@ +// Licensed under the Apache-2.0 license +#pragma once + +#define CALIPTRA_SHA_ACCELERATOR_BASE_ADDR 0x30021000 +#define CALIPTRA_SHA_ACCELERATOR_LOCK_ADDR (CALIPTRA_SHA_ACCELERATOR_BASE_ADDR + 0x00) +#define CALIPTRA_SHA_ACCELERATOR_USER_ADDR (CALIPTRA_SHA_ACCELERATOR_BASE_ADDR + 0x04) +#define CALIPTRA_SHA_ACCELERATOR_MODE_ADDR (CALIPTRA_SHA_ACCELERATOR_BASE_ADDR + 0x08) +#define CALIPTRA_SHA_ACCELERATOR_START_ADDR (CALIPTRA_SHA_ACCELERATOR_BASE_ADDR + 0x0c) +#define CALIPTRA_SHA_ACCELERATOR_DLEN_ADDR (CALIPTRA_SHA_ACCELERATOR_BASE_ADDR + 0x10) +#define CALIPTRA_SHA_ACCELERATOR_DATAIN_ADDR (CALIPTRA_SHA_ACCELERATOR_BASE_ADDR + 0x14) +#define CALIPTRA_SHA_ACCELERATOR_EXECUTE_ADDR (CALIPTRA_SHA_ACCELERATOR_BASE_ADDR + 0x18) +#define CALIPTRA_SHA_ACCELERATOR_STATUS_ADDR (CALIPTRA_SHA_ACCELERATOR_BASE_ADDR + 0x1c) +#define CALIPTRA_SHA_ACCELERATOR_DIGEST_ADDR (CALIPTRA_SHA_ACCELERATOR_BASE_ADDR + 0x20) +#define CALIPTRA_SHA_ACCELERATOR_CONTROL_ADDR (CALIPTRA_SHA_ACCELERATOR_BASE_ADDR + 0x60) + +enum caliptra_sha_accelerator_endianess { + CALIPTRA_SHA_ACCELERATOR_ENDIANESS_BIG = 0, + CALIPTRA_SHA_ACCELERATOR_ENDIANESS_LITTLE = 1, +}; + +enum caliptra_sha_accelerator_mode { + CALIPTRA_SHA_ACCELERATOR_MODE_STREAM_384 = 0, + CALIPTRA_SHA_ACCELERATOR_MODE_STREAM_512 = 1, + CALIPTRA_SHA_ACCELERATOR_MODE_MBOX_384 = 2, + CALIPTRA_SHA_ACCELERATOR_MODE_MBOX_512 = 3, +};