[crypto] Consolidate the OTBN driver and make it stateless.
Previously, the functional OTBN driver for cryptolib was split between
drivers/otbn.c and impl/otbn_util.c, with the latter providing a few
basic utility functions in terms of the former. The otbn_util.c version
also included a state struct which simply stated which app was loaded
into OTBN (if any).
This commit completely removes impl/otbn_util.c. It removes the state
struct and moves some functions to drivers/otbn.c while eliminating
others (for instance, `otbn_copy_data_to_otbn()` is replaced with
`otbn_dmem_write()`, since they have a very similar interface).
Accordingly, some of existing functions (including `otbn_dmem_write`)
are adjusted to be more intuitive to use (e.g. by using an `otbn_addr_t`
instead of a raw byte offset).
Overall, the purpose of this change is to make the driver easier to
understand, use, and test, with all the source code in one place. It
also fits better with the (stateless) cryptolib to remove the OTBN state
struct.
Signed-off-by: Jade Philipoom <jadep@google.com>
diff --git a/sw/device/lib/crypto/drivers/otbn.c b/sw/device/lib/crypto/drivers/otbn.c
index 0ac7920..131e58b 100644
--- a/sw/device/lib/crypto/drivers/otbn.c
+++ b/sw/device/lib/crypto/drivers/otbn.c
@@ -35,10 +35,41 @@
ASSERT_ERR_BIT_MATCH(kOtbnErrBitsFatalSoftware,
OTBN_ERR_BITS_FATAL_SOFTWARE_BIT);
-const size_t kOtbnDMemSizeBytes = OTBN_DMEM_SIZE_BYTES;
-const size_t kOtbnIMemSizeBytes = OTBN_IMEM_SIZE_BYTES;
+enum {
+ /**
+ * Base address for OTBN.
+ */
+ kBase = TOP_EARLGREY_OTBN_BASE_ADDR,
+ /**
+ * DMEM size in bytes.
+ */
+ kOtbnDMemSizeBytes = OTBN_DMEM_SIZE_BYTES,
+ /**
+ * IMEM size in bytes.
+ */
+ kOtbnIMemSizeBytes = OTBN_IMEM_SIZE_BYTES,
+};
-enum { kBase = TOP_EARLGREY_OTBN_BASE_ADDR };
+/**
+ * OTBN commands
+ */
+typedef enum otbn_cmd {
+ kOtbnCmdExecute = 0xd8,
+ kOtbnCmdSecWipeDmem = 0xc3,
+ kOtbnCmdSecWipeImem = 0x1e,
+} otbn_cmd_t;
+
+/**
+ * OTBN status
+ */
+typedef enum otbn_status {
+ kOtbnStatusIdle = 0x00,
+ kOtbnStatusBusyExecute = 0x01,
+ kOtbnStatusBusySecWipeDmem = 0x02,
+ kOtbnStatusBusySecWipeImem = 0x03,
+ kOtbnStatusBusySecWipeInt = 0x04,
+ kOtbnStatusLocked = 0xFF,
+} otbn_status_t;
/**
* Ensures that `offset_bytes` and `len` are valid for a given `mem_size`.
@@ -53,7 +84,15 @@
return kOtbnErrorOk;
}
-otbn_error_t otbn_assert_idle(void) {
+/**
+ * Ensures OTBN is idle.
+ *
+ * If OTBN is busy or locked, this function will return
+ * `kOtbnErrorUnavailable`; otherwise it will return `kOtbnErrorOk`.
+ *
+ * @return Result of the operation.
+ */
+static otbn_error_t otbn_assert_idle(void) {
uint32_t status = launder32(~kOtbnStatusIdle);
otbn_error_t res = launder32(kOtbnErrorOk ^ status);
status = abs_mmio_read32(kBase + OTBN_STATUS_REG_OFFSET);
@@ -67,30 +106,6 @@
return kOtbnErrorUnavailable;
}
-otbn_error_t otbn_busy_wait_for_done(void) {
- uint32_t status = launder32(UINT32_MAX);
- otbn_error_t res = launder32(kOtbnErrorOk ^ status);
- do {
- status = abs_mmio_read32(kBase + OTBN_STATUS_REG_OFFSET);
- } while (launder32(status) != kOtbnStatusIdle &&
- launder32(status) != kOtbnStatusLocked);
- res ^= ~status;
-
- otbn_err_bits_t err_bits;
- otbn_err_bits_get(&err_bits);
-
- if (launder32(res) == kOtbnErrorOk &&
- launder32(err_bits) == kOtbnErrBitsNoError) {
- HARDENED_CHECK_EQ(res, kOtbnErrorOk);
- otbn_err_bits_get(&err_bits);
- HARDENED_CHECK_EQ(err_bits, kOtbnErrBitsNoError);
- HARDENED_CHECK_EQ(abs_mmio_read32(kBase + OTBN_STATUS_REG_OFFSET),
- kOtbnStatusIdle);
- return res;
- }
- return kOtbnErrorExecutionFailed;
-}
-
/**
* Helper function for writing to OTBN's DMEM or IMEM.
*
@@ -116,6 +131,33 @@
HARDENED_CHECK_EQ(iter_cnt, num_words);
}
+static otbn_error_t otbn_imem_write(size_t num_words, const uint32_t *src,
+ otbn_addr_t dest) {
+ OTBN_RETURN_IF_ERROR(check_offset_len(dest, num_words, kOtbnIMemSizeBytes));
+ otbn_write(kBase + OTBN_IMEM_REG_OFFSET + dest, src, num_words);
+ return kOtbnErrorOk;
+}
+
+otbn_error_t otbn_dmem_write(size_t num_words, const uint32_t *src,
+ otbn_addr_t dest) {
+ OTBN_RETURN_IF_ERROR(check_offset_len(dest, num_words, kOtbnDMemSizeBytes));
+ otbn_write(kBase + OTBN_DMEM_REG_OFFSET + dest, src, num_words);
+ return kOtbnErrorOk;
+}
+
+otbn_error_t otbn_dmem_read(size_t num_words, otbn_addr_t src, uint32_t *dest) {
+ OTBN_RETURN_IF_ERROR(check_offset_len(src, num_words, kOtbnDMemSizeBytes));
+
+ size_t i = 0;
+ for (; launder32(i) < num_words; ++i) {
+ dest[i] = abs_mmio_read32(kBase + OTBN_DMEM_REG_OFFSET + src +
+ i * sizeof(uint32_t));
+ }
+ HARDENED_CHECK_EQ(i, num_words);
+
+ return kOtbnErrorOk;
+}
+
otbn_error_t otbn_execute(void) {
// Ensure OTBN is idle before attempting to run a command.
OTBN_RETURN_IF_ERROR(otbn_assert_idle());
@@ -124,6 +166,30 @@
return kOtbnErrorOk;
}
+otbn_error_t otbn_busy_wait_for_done(void) {
+ uint32_t status = launder32(UINT32_MAX);
+ otbn_error_t res = launder32(kOtbnErrorOk ^ status);
+ do {
+ status = abs_mmio_read32(kBase + OTBN_STATUS_REG_OFFSET);
+ } while (launder32(status) != kOtbnStatusIdle &&
+ launder32(status) != kOtbnStatusLocked);
+ res ^= ~status;
+
+ otbn_err_bits_t err_bits;
+ otbn_err_bits_get(&err_bits);
+
+ if (launder32(res) == kOtbnErrorOk &&
+ launder32(err_bits) == kOtbnErrBitsNoError) {
+ HARDENED_CHECK_EQ(res, kOtbnErrorOk);
+ otbn_err_bits_get(&err_bits);
+ HARDENED_CHECK_EQ(err_bits, kOtbnErrBitsNoError);
+ HARDENED_CHECK_EQ(abs_mmio_read32(kBase + OTBN_STATUS_REG_OFFSET),
+ kOtbnStatusIdle);
+ return res;
+ }
+ return kOtbnErrorExecutionFailed;
+}
+
void otbn_err_bits_get(otbn_err_bits_t *err_bits) {
*err_bits = abs_mmio_read32(kBase + OTBN_ERR_BITS_REG_OFFSET);
}
@@ -139,14 +205,6 @@
return kOtbnErrorOk;
}
-otbn_error_t otbn_imem_write(uint32_t offset_bytes, const uint32_t *src,
- size_t num_words) {
- OTBN_RETURN_IF_ERROR(
- check_offset_len(offset_bytes, num_words, kOtbnIMemSizeBytes));
- otbn_write(kBase + OTBN_IMEM_REG_OFFSET + offset_bytes, src, num_words);
- return kOtbnErrorOk;
-}
-
otbn_error_t otbn_dmem_sec_wipe(void) {
OTBN_RETURN_IF_ERROR(otbn_assert_idle());
abs_mmio_write32(kBase + OTBN_CMD_REG_OFFSET, kOtbnCmdSecWipeDmem);
@@ -154,29 +212,6 @@
return kOtbnErrorOk;
}
-otbn_error_t otbn_dmem_write(uint32_t offset_bytes, const uint32_t *src,
- size_t num_words) {
- OTBN_RETURN_IF_ERROR(
- check_offset_len(offset_bytes, num_words, kOtbnDMemSizeBytes));
- otbn_write(kBase + OTBN_DMEM_REG_OFFSET + offset_bytes, src, num_words);
- return kOtbnErrorOk;
-}
-
-otbn_error_t otbn_dmem_read(uint32_t offset_bytes, uint32_t *dest,
- size_t num_words) {
- OTBN_RETURN_IF_ERROR(
- check_offset_len(offset_bytes, num_words, kOtbnDMemSizeBytes));
-
- size_t i = 0;
- for (; launder32(i) < num_words; ++i) {
- dest[i] = abs_mmio_read32(kBase + OTBN_DMEM_REG_OFFSET + offset_bytes +
- i * sizeof(uint32_t));
- }
- HARDENED_CHECK_EQ(i, num_words);
-
- return kOtbnErrorOk;
-}
-
otbn_error_t otbn_set_ctrl_software_errs_fatal(bool enable) {
// Ensure OTBN is idle (otherwise CTRL writes will be ignored).
OTBN_RETURN_IF_ERROR(otbn_assert_idle());
@@ -194,3 +229,57 @@
return kOtbnErrorOk;
}
+
+/**
+ * Checks if the OTBN application's IMEM and DMEM address parameters are valid.
+ *
+ * This function checks the following properties:
+ * - IMEM and DMEM ranges must not be "backwards" in memory, with the end
+ * address coming before the start address.
+ * - The IMEM range must be non-empty.
+ *
+ * @param app the OTBN application to check
+ * @return `kHardenedBoolTrue` if checks pass, otherwise `kHardenedBoolFalse`.
+ */
+static hardened_bool_t check_app_address_ranges(const otbn_app_t *app) {
+ // IMEM must not be backwards or empty.
+ if (app->imem_end <= app->imem_start) {
+ return kHardenedBoolFalse;
+ }
+ HARDENED_CHECK_LT(app->imem_start, app->imem_end);
+
+ // DMEM data section must not be backwards.
+ if (app->dmem_data_end < app->dmem_data_start) {
+ return kHardenedBoolFalse;
+ }
+ HARDENED_CHECK_LE(app->dmem_data_start, app->dmem_data_end);
+
+ return kHardenedBoolTrue;
+}
+
+otbn_error_t otbn_load_app(const otbn_app_t app) {
+ if (!check_app_address_ranges(&app)) {
+ return kOtbnErrorInvalidArgument;
+ }
+
+ // Ensure OTBN is idle.
+ OTBN_RETURN_IF_ERROR(otbn_assert_idle());
+
+ const size_t imem_num_words = app.imem_end - app.imem_start;
+ const size_t data_num_words = app.dmem_data_end - app.dmem_data_start;
+
+ OTBN_RETURN_IF_ERROR(otbn_imem_sec_wipe());
+ OTBN_RETURN_IF_ERROR(otbn_dmem_sec_wipe());
+
+ // IMEM always starts at zero.
+ otbn_addr_t imem_start_addr = 0;
+ OTBN_RETURN_IF_ERROR(
+ otbn_imem_write(imem_num_words, app.imem_start, imem_start_addr));
+
+ if (data_num_words > 0) {
+ OTBN_RETURN_IF_ERROR(otbn_dmem_write(data_num_words, app.dmem_data_start,
+ app.dmem_data_start_addr));
+ }
+
+ return kOtbnErrorOk;
+}
diff --git a/sw/device/lib/crypto/drivers/otbn.h b/sw/device/lib/crypto/drivers/otbn.h
index 4711354..eb61603 100644
--- a/sw/device/lib/crypto/drivers/otbn.h
+++ b/sw/device/lib/crypto/drivers/otbn.h
@@ -14,35 +14,14 @@
#endif
/**
- * The size of OTBN's data memory in bytes.
+ * Constants related to OTBN wide words
*/
-extern const size_t kOtbnDMemSizeBytes;
-
-/**
- * The size of OTBN's instruction memory in bytes.
- */
-extern const size_t kOtbnIMemSizeBytes;
-
-/**
- * OTBN commands
- */
-typedef enum otbn_cmd {
- kOtbnCmdExecute = 0xd8,
- kOtbnCmdSecWipeDmem = 0xc3,
- kOtbnCmdSecWipeImem = 0x1e,
-} otbn_cmd_t;
-
-/**
- * OTBN status
- */
-typedef enum otbn_status {
- kOtbnStatusIdle = 0x00,
- kOtbnStatusBusyExecute = 0x01,
- kOtbnStatusBusySecWipeDmem = 0x02,
- kOtbnStatusBusySecWipeImem = 0x03,
- kOtbnStatusBusySecWipeInt = 0x04,
- kOtbnStatusLocked = 0xFF,
-} otbn_status_t;
+enum {
+ /* Length of an OTBN wide word in bits */
+ kOtbnWideWordNumBits = 256,
+ /* Length of an OTBN wide word in words */
+ kOtbnWideWordNumWords = kOtbnWideWordNumBits / (sizeof(uint32_t) * 8),
+};
/**
* Error codes for the OTBN driver.
@@ -60,54 +39,6 @@
kOtbnErrorUnavailable = 4,
} otbn_error_t;
-/**
- * Evaluate an expression and return if the result is an error.
- *
- * @param expr_ An expression which results in an otbn_error_t.
- */
-#define OTBN_RETURN_IF_ERROR(expr_) \
- do { \
- otbn_error_t local_error_ = expr_; \
- if (local_error_ != kOtbnErrorOk) { \
- return local_error_; \
- } \
- } while (0)
-
-/**
- * Start the execution of the application loaded into OTBN.
- *
- * This function returns an error if called when OTBN is not idle.
- *
- * @return Result of the operation.
- */
-otbn_error_t otbn_execute(void);
-
-/**
- * Ensures OTBN is idle.
- *
- * If OTBN is busy or locked, this function will return
- * `kOtbnErrorUnavailable`; otherwise it will return `kOtbnErrorOk`.
- *
- * @return Result of the operation.
- */
-otbn_error_t otbn_assert_idle(void);
-
-/**
- * Blocks until OTBN is idle.
- *
- * If OTBN is or becomes locked, an error will occur.
- *
- * @return Result of the operation.
- */
-otbn_error_t otbn_busy_wait_for_done(void);
-
-/**
- * OTBN Internal Errors
- *
- * OTBN uses a bitfield to indicate which errors have been seen. Multiple errors
- * can be seen at the same time. This enum gives the individual bits that may be
- * set for different errors.
- */
typedef enum otbn_err_bits {
kOtbnErrBitsNoError = 0,
/** A BAD_DATA_ADDR error was observed. */
@@ -139,6 +70,221 @@
} otbn_err_bits_t;
/**
+ * Evaluate an expression and return if the result is an error.
+ *
+ * @param expr_ An expression which results in an otbn_error_t.
+ */
+#define OTBN_RETURN_IF_ERROR(expr_) \
+ do { \
+ otbn_error_t local_error_ = expr_; \
+ if (local_error_ != kOtbnErrorOk) { \
+ return local_error_; \
+ } \
+ } while (false)
+
+/**
+ * The address of an OTBN symbol as seen by OTBN.
+ *
+ * Use `OTBN_DECLARE_SYMBOL_ADDR()` together with `OTBN_ADDR_T_INIT()` to
+ * initialize this type.
+ */
+typedef uint32_t otbn_addr_t;
+
+/**
+ * Information about an embedded OTBN application image.
+ *
+ * All pointers reference data in the normal CPU address space.
+ * uint32_t values are addresses in the OTBN address space.
+ *
+ * Use `OTBN_DECLARE_APP_SYMBOLS()` together with `OTBN_APP_T_INIT()` to
+ * initialize this structure.
+ */
+typedef struct otbn_app {
+ /**
+ * Start of OTBN instruction memory in the embedded program.
+ *
+ * This pointer references Ibex's memory.
+ */
+ const uint32_t *imem_start;
+ /**
+ * The first word after OTBN instruction memory in the embedded program.
+ *
+ * This pointer references Ibex's memory.
+ *
+ * This address satifies `imem_start < imem_end`.
+ */
+ const uint32_t *imem_end;
+ /**
+ * Start of initialized OTBN data in the embedded program.
+ *
+ * This pointer references Ibex's memory.
+ *
+ * Data in between `dmem_data_start` and `dmem_data_end` will be copied to
+ * OTBN at app load time.
+ */
+ const uint32_t *dmem_data_start;
+ /**
+ * The first word after initialized OTBN data in the embedded program.
+ *
+ * This pointer references Ibex's memory.
+ *
+ * Should satisfy `dmem_data_start <= dmem_data_end`.
+ */
+ const uint32_t *dmem_data_end;
+ /**
+ * Start of initialized data section in OTBN's DMEM.
+ *
+ * This pointer references OTBN's memory and is used to copy data at app load
+ * time.
+ */
+ const otbn_addr_t dmem_data_start_addr;
+} otbn_app_t;
+
+/**
+ * Generate the prefix to add to an OTBN symbol name used on the Ibex side
+ *
+ * The result is a pointer to Ibex's rodata that should be used to initialise
+ * memory for that symbol.
+ *
+ * This is needed by the OTBN driver to support DMEM/IMEM ranges but
+ * application code shouldn't need to use this. Use the `otbn_addr_t` type and
+ * supporting macros instead.
+ */
+#define OTBN_SYMBOL_PTR(app_name, sym) _otbn_local_app_##app_name##_##sym
+
+/**
+ * Generate the prefix to add to an OTBN symbol name used on the OTBN side
+ *
+ * The result is a pointer whose integer value is the address by which the
+ * symbol should be accessed in OTBN memory.
+ *
+ * This is an internal macro used in `OTBN_DECLARE_SYMBOL_ADDR` and
+ * `OTBN_ADDR_T_INIT` but application code shouldn't need to use it directly.
+ */
+#define OTBN_SYMBOL_ADDR(app_name, sym) _otbn_remote_app_##app_name##_##sym
+
+/**
+ * Makes a symbol in the OTBN application image available.
+ *
+ * This is needed by the OTBN driver to support DMEM/IMEM ranges but
+ * application code shouldn't need to use this. To get access to OTBN
+ * addresses, use `OTBN_DECLARE_SYMBOL_ADDR` instead.
+ */
+#define OTBN_DECLARE_SYMBOL_PTR(app_name, symbol_name) \
+ extern const uint32_t OTBN_SYMBOL_PTR(app_name, symbol_name)[]
+
+/**
+ * Makes the OTBN address of a symbol in the OTBN application available.
+ *
+ * Symbols are typically function or data pointers, i.e. labels in assembly
+ * code. Unlike OTBN_DECLARE_SYMBOL_PTR, this will work for symbols in the .bss
+ * section (which exist on the OTBN side, even though they don't have backing
+ * data on Ibex).
+ *
+ * Use this macro instead of manually declaring the symbols as symbol names
+ * might change.
+ *
+ * @param app_name Name of the application the function is contained in.
+ * @param symbol_name Name of the symbol (function, label).
+ */
+#define OTBN_DECLARE_SYMBOL_ADDR(app_name, symbol_name) \
+ extern const uint32_t OTBN_SYMBOL_ADDR(app_name, symbol_name)[]
+
+/**
+ * Makes an embedded OTBN application image available for use.
+ *
+ * Make symbols available that indicate the start and the end of instruction
+ * and data memory regions, as they are stored in the device memory.
+ *
+ * Use this macro instead of manually declaring the symbols as symbol names
+ * might change.
+ *
+ * @param app_name Name of the application to load, which is typically the
+ * name of the main (assembly) source file.
+ */
+#define OTBN_DECLARE_APP_SYMBOLS(app_name) \
+ OTBN_DECLARE_SYMBOL_PTR(app_name, _imem_start); \
+ OTBN_DECLARE_SYMBOL_PTR(app_name, _imem_end); \
+ OTBN_DECLARE_SYMBOL_PTR(app_name, _dmem_data_start); \
+ OTBN_DECLARE_SYMBOL_PTR(app_name, _dmem_data_end); \
+ OTBN_DECLARE_SYMBOL_ADDR(app_name, _dmem_data_start);
+
+/**
+ * Initializes the OTBN application information structure.
+ *
+ * After making all required symbols from the application image available
+ * through `OTBN_DECLARE_APP_SYMBOLS()`, use this macro to initialize an
+ * `otbn_app_t` struct with those symbols.
+ *
+ * @param app_name Name of the application to load.
+ * @see OTBN_DECLARE_APP_SYMBOLS()
+ */
+#define OTBN_APP_T_INIT(app_name) \
+ ((otbn_app_t){ \
+ .imem_start = OTBN_SYMBOL_PTR(app_name, _imem_start), \
+ .imem_end = OTBN_SYMBOL_PTR(app_name, _imem_end), \
+ .dmem_data_start = OTBN_SYMBOL_PTR(app_name, _dmem_data_start), \
+ .dmem_data_end = OTBN_SYMBOL_PTR(app_name, _dmem_data_end), \
+ .dmem_data_start_addr = OTBN_ADDR_T_INIT(app_name, _dmem_data_start), \
+ })
+
+/**
+ * Initializes an `otbn_addr_t`.
+ */
+#define OTBN_ADDR_T_INIT(app_name, symbol_name) \
+ ((uint32_t)OTBN_SYMBOL_ADDR(app_name, symbol_name))
+
+/**
+ * Write to OTBN's data memory (DMEM)
+ *
+ * Only 32b-aligned 32b word accesses are allowed. If `dest` is not
+ * word-aligned or if the length and offset exceed the DMEM size, this function
+ * will return an error.
+ *
+ * The caller must ensure OTBN is idle before calling this function.
+ *
+ * @param num_words Length of the data in 32-bit words.
+ * @param src The main memory location to copy from.
+ * @param dest The DMEM location to copy to.
+ * @return Result of the operation.
+ */
+otbn_error_t otbn_dmem_write(size_t num_words, const uint32_t *src,
+ otbn_addr_t dest);
+
+/**
+ * Read from OTBN's data memory (DMEM)
+ *
+ * Only 32b-aligned 32b word accesses are allowed. If `src` is not word-aligned
+ * or if the length and offset exceed the DMEM size, this function will return
+ * an error.
+ *
+ * The caller must ensure OTBN is idle before calling this function.
+ *
+ * @param num_words Length of the data in 32-bit words.
+ * @param src The DMEM location to copy from.
+ * @param[out] dest The main memory location to copy to.
+ */
+otbn_error_t otbn_dmem_read(size_t num_words, otbn_addr_t src, uint32_t *dest);
+
+/**
+ * Start the execution of the application loaded into OTBN.
+ *
+ * This function returns an error if called when OTBN is not idle.
+ *
+ * @return Result of the operation.
+ */
+otbn_error_t otbn_execute(void);
+
+/**
+ * Blocks until OTBN is idle.
+ *
+ * If OTBN is or becomes locked, an error will occur.
+ *
+ * @return Result of the operation.
+ */
+otbn_error_t otbn_busy_wait_for_done(void);
+
+/**
* Get the error bits set by the device if the operation failed.
*
* @param[out] err_bits The error bits returned by the hardware.
@@ -172,23 +318,6 @@
otbn_error_t otbn_imem_sec_wipe(void);
/**
- * Write an OTBN application into its instruction memory (IMEM)
- *
- * Only 32b-aligned 32b word accesses are allowed. If `offset_bytes` is not
- * word-aligned or if the length and offset exceed the IMEM size, this function
- * will return an error.
- *
- * The caller must ensure OTBN is idle before calling this function.
- *
- * @param offset_bytes the byte offset in IMEM the first word is written to
- * @param src the main memory location to start reading from.
- * @param len number of words to copy.
- * @return Result of the operation.
- */
-otbn_error_t otbn_imem_write(uint32_t offset_bytes, const uint32_t *src,
- size_t len);
-
-/**
* Wipe DMEM securely.
*
* This function returns an error if called when OTBN is not idle, and blocks
@@ -199,39 +328,6 @@
otbn_error_t otbn_dmem_sec_wipe(void);
/**
- * Write to OTBN's data memory (DMEM)
- *
- * Only 32b-aligned 32b word accesses are allowed. If `offset_bytes` is not
- * word-aligned or if the length and offset exceed the DMEM size, this function
- * will return an error.
- *
- * The caller must ensure OTBN is idle before calling this function.
- *
- * @param offset_bytes the byte offset in DMEM the first word is written to
- * @param src the main memory location to start reading from.
- * @param len number of words to copy.
- * @return Result of the operation.
- */
-otbn_error_t otbn_dmem_write(uint32_t offset_bytes, const uint32_t *src,
- size_t len);
-
-/**
- * Read from OTBN's data memory (DMEM)
- *
- * Only 32b-aligned 32b word accesses are allowed. If `offset_bytes` is not
- * word-aligned or if the length and offset exceed the DMEM size, this function
- * will return an error.
- *
- * The caller must ensure OTBN is idle before calling this function.
- *
- * @param offset_bytes the byte offset in DMEM the first word is read from
- * @param[out] dest the main memory location to copy the data to (preallocated)
- * @param len number of words to copy.
- * @return Result of the operation.
- */
-otbn_error_t otbn_dmem_read(uint32_t offset_bytes, uint32_t *dest, size_t len);
-
-/**
* Sets the software errors are fatal bit in the control register.
*
* When set any software error becomes a fatal error. The bit can only be
@@ -244,6 +340,20 @@
*/
otbn_error_t otbn_set_ctrl_software_errs_fatal(bool enable);
+/**
+ * (Re-)loads the provided application into OTBN.
+ *
+ * Load the application image with both instruction and data segments into
+ * OTBN.
+ *
+ * This function will return an error if called when OTBN is not idle.
+ *
+ * @param ctx The context object.
+ * @param app The application to load into OTBN.
+ * @return The result of the operation.
+ */
+otbn_error_t otbn_load_app(const otbn_app_t app);
+
#ifdef __cplusplus
}
#endif
diff --git a/sw/device/lib/crypto/impl/BUILD b/sw/device/lib/crypto/impl/BUILD
index c0154bc..0cc2960 100644
--- a/sw/device/lib/crypto/impl/BUILD
+++ b/sw/device/lib/crypto/impl/BUILD
@@ -5,16 +5,6 @@
package(default_visibility = ["//visibility:public"])
cc_library(
- name = "otbn_util",
- srcs = ["otbn_util.c"],
- hdrs = ["otbn_util.h"],
- deps = [
- "//sw/device/lib/base:hardened",
- "//sw/device/lib/crypto/drivers:otbn",
- ],
-)
-
-cc_library(
name = "integrity_check",
srcs = ["integrity_check.c"],
hdrs = [
diff --git a/sw/device/lib/crypto/impl/ecdsa_p256/BUILD b/sw/device/lib/crypto/impl/ecdsa_p256/BUILD
index 14a08b2..971f079 100644
--- a/sw/device/lib/crypto/impl/ecdsa_p256/BUILD
+++ b/sw/device/lib/crypto/impl/ecdsa_p256/BUILD
@@ -14,7 +14,6 @@
deps = [
"//sw/device/lib/base:hardened",
"//sw/device/lib/crypto/drivers:otbn",
- "//sw/device/lib/crypto/impl:otbn_util",
"//sw/otbn/crypto:p256_ecdsa",
],
)
diff --git a/sw/device/lib/crypto/impl/ecdsa_p256/ecdsa_p256.c b/sw/device/lib/crypto/impl/ecdsa_p256/ecdsa_p256.c
index 140165c..6ab78f5 100644
--- a/sw/device/lib/crypto/impl/ecdsa_p256/ecdsa_p256.c
+++ b/sw/device/lib/crypto/impl/ecdsa_p256/ecdsa_p256.c
@@ -6,7 +6,6 @@
#include "sw/device/lib/base/hardened.h"
#include "sw/device/lib/crypto/drivers/otbn.h"
-#include "sw/device/lib/crypto/impl/otbn_util.h"
#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
@@ -44,42 +43,36 @@
otbn_error_t ecdsa_p256_sign(const ecdsa_p256_message_digest_t *digest,
const ecdsa_p256_private_key_t *private_key,
ecdsa_p256_signature_t *result) {
- // If OTBN is non-idle, return an error.
- OTBN_RETURN_IF_ERROR(otbn_assert_idle());
-
- otbn_t otbn;
- otbn_init(&otbn);
-
- // Load the ECDSA/P-256 app and set up data pointers
- OTBN_RETURN_IF_ERROR(otbn_load_app(&otbn, kOtbnAppEcdsa));
+ // Load the ECDSA/P-256 app. Fails if OTBN is non-idle.
+ OTBN_RETURN_IF_ERROR(otbn_load_app(kOtbnAppEcdsa));
// Set mode so start() will jump into p256_ecdsa_sign.
- OTBN_RETURN_IF_ERROR(otbn_copy_data_to_otbn(
- &otbn, kOtbnEcdsaModeNumWords, &kOtbnEcdsaModeSign, kOtbnVarEcdsaMode));
+ OTBN_RETURN_IF_ERROR(otbn_dmem_write(kOtbnEcdsaModeNumWords,
+ &kOtbnEcdsaModeSign, kOtbnVarEcdsaMode));
// Set the message digest.
- OTBN_RETURN_IF_ERROR(otbn_copy_data_to_otbn(&otbn, kP256ScalarNumWords,
- digest->h, kOtbnVarEcdsaMsg));
+ OTBN_RETURN_IF_ERROR(
+ otbn_dmem_write(kP256ScalarNumWords, digest->h, kOtbnVarEcdsaMsg));
// Set the private key shares.
- OTBN_RETURN_IF_ERROR(otbn_copy_data_to_otbn(
- &otbn, kP256ScalarNumWords, private_key->d0, kOtbnVarEcdsaD0));
- OTBN_RETURN_IF_ERROR(otbn_copy_data_to_otbn(
- &otbn, kP256ScalarNumWords, private_key->d1, kOtbnVarEcdsaD1));
+ OTBN_RETURN_IF_ERROR(
+ otbn_dmem_write(kP256ScalarNumWords, private_key->d0, kOtbnVarEcdsaD0));
+ OTBN_RETURN_IF_ERROR(
+ otbn_dmem_write(kP256ScalarNumWords, private_key->d1, kOtbnVarEcdsaD1));
// Start the OTBN routine.
- OTBN_RETURN_IF_ERROR(otbn_execute_app(&otbn));
+ OTBN_RETURN_IF_ERROR(otbn_execute());
// Spin here waiting for OTBN to complete.
OTBN_RETURN_IF_ERROR(otbn_busy_wait_for_done());
// Read signature R out of OTBN dmem.
- OTBN_RETURN_IF_ERROR(otbn_copy_data_from_otbn(&otbn, kP256ScalarNumWords,
- kOtbnVarEcdsaR, result->r));
+ OTBN_RETURN_IF_ERROR(
+ otbn_dmem_read(kP256ScalarNumWords, kOtbnVarEcdsaR, result->r));
// Read signature S out of OTBN dmem.
- OTBN_RETURN_IF_ERROR(otbn_copy_data_from_otbn(&otbn, kP256ScalarNumWords,
- kOtbnVarEcdsaS, result->s));
+ OTBN_RETURN_IF_ERROR(
+ otbn_dmem_read(kP256ScalarNumWords, kOtbnVarEcdsaS, result->s));
// TODO: try to verify the signature, and return an error if verification
// fails.
@@ -93,49 +86,43 @@
const ecdsa_p256_message_digest_t *digest,
const ecdsa_p256_public_key_t *public_key,
hardened_bool_t *result) {
- // If OTBN is non-idle, return an error.
- OTBN_RETURN_IF_ERROR(otbn_assert_idle());
-
- otbn_t otbn;
- otbn_init(&otbn);
-
// Load the ECDSA/P-256 app and set up data pointers
- OTBN_RETURN_IF_ERROR(otbn_load_app(&otbn, kOtbnAppEcdsa));
+ OTBN_RETURN_IF_ERROR(otbn_load_app(kOtbnAppEcdsa));
// Set mode so start() will jump into p256_ecdsa_verify.
- OTBN_RETURN_IF_ERROR(otbn_copy_data_to_otbn(
- &otbn, kOtbnEcdsaModeNumWords, &kOtbnEcdsaModeVerify, kOtbnVarEcdsaMode));
+ OTBN_RETURN_IF_ERROR(otbn_dmem_write(
+ kOtbnEcdsaModeNumWords, &kOtbnEcdsaModeVerify, kOtbnVarEcdsaMode));
// Set the message digest.
- OTBN_RETURN_IF_ERROR(otbn_copy_data_to_otbn(&otbn, kP256ScalarNumWords,
- digest->h, kOtbnVarEcdsaMsg));
+ OTBN_RETURN_IF_ERROR(
+ otbn_dmem_write(kP256ScalarNumWords, digest->h, kOtbnVarEcdsaMsg));
// Set the signature R.
- OTBN_RETURN_IF_ERROR(otbn_copy_data_to_otbn(&otbn, kP256ScalarNumWords,
- signature->r, kOtbnVarEcdsaR));
+ OTBN_RETURN_IF_ERROR(
+ otbn_dmem_write(kP256ScalarNumWords, signature->r, kOtbnVarEcdsaR));
// Set the signature S.
- OTBN_RETURN_IF_ERROR(otbn_copy_data_to_otbn(&otbn, kP256ScalarNumWords,
- signature->s, kOtbnVarEcdsaS));
+ OTBN_RETURN_IF_ERROR(
+ otbn_dmem_write(kP256ScalarNumWords, signature->s, kOtbnVarEcdsaS));
// Set the public key x coordinate.
- OTBN_RETURN_IF_ERROR(otbn_copy_data_to_otbn(&otbn, kP256CoordNumWords,
- public_key->x, kOtbnVarEcdsaX));
+ OTBN_RETURN_IF_ERROR(
+ otbn_dmem_write(kP256CoordNumWords, public_key->x, kOtbnVarEcdsaX));
// Set the public key y coordinate.
- OTBN_RETURN_IF_ERROR(otbn_copy_data_to_otbn(&otbn, kP256CoordNumWords,
- public_key->y, kOtbnVarEcdsaY));
+ OTBN_RETURN_IF_ERROR(
+ otbn_dmem_write(kP256CoordNumWords, public_key->y, kOtbnVarEcdsaY));
// Start the OTBN routine.
- OTBN_RETURN_IF_ERROR(otbn_execute_app(&otbn));
+ OTBN_RETURN_IF_ERROR(otbn_execute());
// Spin here waiting for OTBN to complete.
OTBN_RETURN_IF_ERROR(otbn_busy_wait_for_done());
// Read x_r (recovered R) out of OTBN dmem.
uint32_t x_r[kP256ScalarNumWords];
- OTBN_RETURN_IF_ERROR(otbn_copy_data_from_otbn(&otbn, kP256ScalarNumWords,
- kOtbnVarEcdsaXr, x_r));
+ OTBN_RETURN_IF_ERROR(
+ otbn_dmem_read(kP256ScalarNumWords, kOtbnVarEcdsaXr, x_r));
// TODO: Harden this memory comparison or do it in OTBN.
// Check that x_r == R.
diff --git a/sw/device/lib/crypto/impl/otbn_util.c b/sw/device/lib/crypto/impl/otbn_util.c
deleted file mode 100644
index a438b01..0000000
--- a/sw/device/lib/crypto/impl/otbn_util.c
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-
-#include "sw/device/lib/crypto/impl/otbn_util.h"
-
-#include "sw/device/lib/crypto/drivers/otbn.h"
-
-#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
-
-void otbn_init(otbn_t *ctx) {
- *ctx = (otbn_t){
- .app = {0},
- .app_is_loaded = kHardenedBoolFalse,
- .error_bits = kOtbnErrBitsNoError,
- };
-}
-
-/**
- * Checks if the OTBN application's IMEM and DMEM address parameters are valid.
- *
- * IMEM and DMEM ranges must not be "backwards" in memory, with the end address
- * coming before the start address, and the IMEM range must additionally be
- * non-empty. Finally, separate sections in DMEM must not overlap each other
- * when converted to DMEM address space.
- *
- * @param app the OTBN application to check
- * @return true if the addresses are valid, otherwise false.
- */
-static bool check_app_address_ranges(const otbn_app_t *app) {
- // IMEM must have a strictly positive range (cannot be backwards or empty)
- if (app->imem_end <= app->imem_start) {
- return false;
- }
- // DMEM data section must not be backwards
- if (app->dmem_data_end < app->dmem_data_start) {
- return false;
- }
- return true;
-}
-
-otbn_error_t otbn_load_app(otbn_t *ctx, const otbn_app_t app) {
- if (!check_app_address_ranges(&app)) {
- return kOtbnErrorInvalidArgument;
- }
-
- // Ensure OTBN is idle.
- OTBN_RETURN_IF_ERROR(otbn_assert_idle());
-
- const size_t imem_num_words = app.imem_end - app.imem_start;
- const size_t data_num_words = app.dmem_data_end - app.dmem_data_start;
-
- ctx->app_is_loaded = kHardenedBoolFalse;
-
- OTBN_RETURN_IF_ERROR(otbn_imem_sec_wipe());
- OTBN_RETURN_IF_ERROR(otbn_imem_write(0, app.imem_start, imem_num_words));
-
- OTBN_RETURN_IF_ERROR(otbn_dmem_sec_wipe());
- if (data_num_words > 0) {
- OTBN_RETURN_IF_ERROR(
- otbn_dmem_write(0, app.dmem_data_start, data_num_words));
- }
-
- ctx->app = app;
- ctx->app_is_loaded = kHardenedBoolTrue;
- return kOtbnErrorOk;
-}
-
-otbn_error_t otbn_execute_app(otbn_t *ctx) {
- if (launder32(ctx->app_is_loaded) != kHardenedBoolTrue) {
- return kOtbnErrorInvalidArgument;
- }
- HARDENED_CHECK_EQ(ctx->app_is_loaded, kHardenedBoolTrue);
-
- return otbn_execute();
-}
-
-otbn_error_t otbn_copy_data_to_otbn(otbn_t *ctx, size_t len,
- const uint32_t *src, otbn_addr_t dest) {
- return otbn_dmem_write(dest, src, len);
-}
-
-otbn_error_t otbn_copy_data_from_otbn(otbn_t *ctx, size_t len_bytes,
- otbn_addr_t src, uint32_t *dest) {
- return otbn_dmem_read(src, dest, len_bytes);
-}
diff --git a/sw/device/lib/crypto/impl/otbn_util.h b/sw/device/lib/crypto/impl/otbn_util.h
deleted file mode 100644
index 887e1c8..0000000
--- a/sw/device/lib/crypto/impl/otbn_util.h
+++ /dev/null
@@ -1,239 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-
-#ifndef OPENTITAN_SW_DEVICE_LIB_CRYPTO_IMPL_OTBN_UTIL_H_
-#define OPENTITAN_SW_DEVICE_LIB_CRYPTO_IMPL_OTBN_UTIL_H_
-
-#include "sw/device/lib/base/hardened.h"
-#include "sw/device/lib/crypto/drivers/otbn.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Constants related to OTBN wide words
- */
-enum {
- /* Length of an OTBN wide word in bits */
- kOtbnWideWordNumBits = 256,
- /* Length of an OTBN wide word in words */
- kOtbnWideWordNumWords = kOtbnWideWordNumBits / (sizeof(uint32_t) * 8),
-};
-
-/**
- * Information about an embedded OTBN application image.
- *
- * All pointers reference data in the normal CPU address space.
- * uint32_t values are addresses in the OTBN address space.
- *
- * Use `OTBN_DECLARE_APP_SYMBOLS()` together with `OTBN_APP_T_INIT()` to
- * initialize this structure.
- */
-typedef struct otbn_app {
- /**
- * Start of OTBN instruction memory.
- */
- const uint32_t *imem_start;
- /**
- * The first word after OTBN instruction memory.
- *
- * This address satifies `imem_len = imem_end - imem_start`.
- */
- const uint32_t *imem_end;
- /**
- * Start of initialized OTBN data.
- *
- * Data in between dmem_data_start and dmem_data_end will be copied to OTBN
- * at app load time.
- */
- const uint32_t *dmem_data_start;
- /**
- * The first word after initialized OTBN data.
- *
- * Should satisfy `dmem_data_start <= dmem_data_end`.
- */
- const uint32_t *dmem_data_end;
-} otbn_app_t;
-
-/**
- * The address of an OTBN symbol as seen by OTBN
- *
- * Use `OTBN_DECLARE_SYMBOL_ADDR()` together with `OTBN_ADDR_T_INIT()` to
- * initialize this type.
- */
-typedef uint32_t otbn_addr_t;
-
-/**
- * OTBN context structure.
- *
- * Use `otbn_init()` to initialize.
- */
-typedef struct otbn {
- /**
- * The application loaded or to be loaded into OTBN.
- *
- * Only valid if @p app_is_loaded is kHardenedBoolTrue.
- */
- otbn_app_t app;
-
- /**
- * Is the application loaded into OTBN?
- */
- hardened_bool_t app_is_loaded;
-
- /**
- * The error bits from the last execution of OTBN.
- */
- uint32_t error_bits;
-} otbn_t;
-
-/**
- * Generate the prefix to add to an OTBN symbol name used on the Ibex side
- *
- * The result is a pointer to Ibex's rodata that should be used to initialise
- * memory for that symbol.
- *
- * This is needed by the OTBN driver to support DMEM/IMEM ranges but
- * application code shouldn't need to use this. Use the `otbn_addr_t` type and
- * supporting macros instead.
- */
-#define OTBN_SYMBOL_PTR(app_name, sym) _otbn_local_app_##app_name##_##sym
-
-/**
- * Generate the prefix to add to an OTBN symbol name used on the OTBN side
- *
- * The result is a pointer whose integer value is the address by which the
- * symbol should be accessed in OTBN memory.
- *
- * This is an internal macro used in `OTBN_DECLARE_SYMBOL_ADDR` and
- * `OTBN_ADDR_T_INIT` but application code shouldn't need to use it directly.
- */
-#define OTBN_SYMBOL_ADDR(app_name, sym) _otbn_remote_app_##app_name##_##sym
-
-/**
- * Makes a symbol in the OTBN application image available.
- *
- * This is needed by the OTBN driver to support DMEM/IMEM ranges but
- * application code shouldn't need to use this. To get access to OTBN
- * addresses, use `OTBN_DECLARE_SYMBOL_ADDR` instead.
- */
-#define OTBN_DECLARE_SYMBOL_PTR(app_name, symbol_name) \
- extern const uint32_t OTBN_SYMBOL_PTR(app_name, symbol_name)[]
-
-/**
- * Makes the OTBN address of a symbol in the OTBN application available.
- *
- * Symbols are typically function or data pointers, i.e. labels in assembly
- * code. Unlike OTBN_DECLARE_SYMBOL_PTR, this will work for symbols in the .bss
- * section (which exist on the OTBN side, even though they don't have backing
- * data on Ibex).
- *
- * Use this macro instead of manually declaring the symbols as symbol names
- * might change.
- *
- * @param app_name Name of the application the function is contained in.
- * @param symbol_name Name of the symbol (function, label).
- */
-#define OTBN_DECLARE_SYMBOL_ADDR(app_name, symbol_name) \
- extern const uint32_t OTBN_SYMBOL_ADDR(app_name, symbol_name)[]
-
-/**
- * Makes an embedded OTBN application image available for use.
- *
- * Make symbols available that indicate the start and the end of instruction
- * and data memory regions, as they are stored in the device memory.
- *
- * Use this macro instead of manually declaring the symbols as symbol names
- * might change.
- *
- * @param app_name Name of the application to load, which is typically the
- * name of the main (assembly) source file.
- */
-#define OTBN_DECLARE_APP_SYMBOLS(app_name) \
- OTBN_DECLARE_SYMBOL_PTR(app_name, _imem_start); \
- OTBN_DECLARE_SYMBOL_PTR(app_name, _imem_end); \
- OTBN_DECLARE_SYMBOL_PTR(app_name, _dmem_data_start); \
- OTBN_DECLARE_SYMBOL_PTR(app_name, _dmem_data_end)
-
-/**
- * Initializes the OTBN application information structure.
- *
- * After making all required symbols from the application image available
- * through `OTBN_DECLARE_APP_SYMBOLS()`, use this macro to initialize an
- * `otbn_app_t` struct with those symbols.
- *
- * @param app_name Name of the application to load.
- * @see OTBN_DECLARE_APP_SYMBOLS()
- */
-#define OTBN_APP_T_INIT(app_name) \
- ((otbn_app_t){ \
- .imem_start = OTBN_SYMBOL_PTR(app_name, _imem_start), \
- .imem_end = OTBN_SYMBOL_PTR(app_name, _imem_end), \
- .dmem_data_start = OTBN_SYMBOL_PTR(app_name, _dmem_data_start), \
- .dmem_data_end = OTBN_SYMBOL_PTR(app_name, _dmem_data_end), \
- })
-
-/**
- * Initializes an `otbn_addr_t`.
- */
-#define OTBN_ADDR_T_INIT(app_name, symbol_name) \
- ((uint32_t)OTBN_SYMBOL_ADDR(app_name, symbol_name))
-
-void otbn_init(otbn_t *ctx);
-
-/**
- * (Re-)loads the provided application into OTBN.
- *
- * Load the application image with both instruction and data segments into
- * OTBN.
- *
- * This function will return an error if called when OTBN is not idle.
- *
- * @param ctx The context object.
- * @param app The application to load into OTBN.
- * @return The result of the operation.
- */
-otbn_error_t otbn_load_app(otbn_t *ctx, const otbn_app_t app);
-
-/**
- * Start the OTBN application.
- *
- * This function will return an error if called when OTBN is not idle.
- *
- * @param ctx The context object.
- * @return The result of the operation.
- */
-otbn_error_t otbn_execute_app(otbn_t *ctx);
-
-/**
- * Copies data from the CPU memory to OTBN data memory.
- *
- * @param ctx The context object.
- * @param len Number of 32b words to copy.
- * @param dest Address of the destination in OTBN's data memory.
- * @param src Source of the data to copy.
- * @return The result of the operation.
- */
-otbn_error_t otbn_copy_data_to_otbn(otbn_t *ctx, size_t len,
- const uint32_t *src, otbn_addr_t dest);
-
-/**
- * Copies data from OTBN's data memory to CPU memory.
- *
- * @param ctx The context object.
- * @param len The number of 32b words to copy.
- * @param src The address in OTBN data memory to copy from.
- * @param[out] dest The destination of the copied data in main memory
- * (preallocated).
- * @return The result of the operation.
- */
-otbn_error_t otbn_copy_data_from_otbn(otbn_t *ctx, size_t len,
- const otbn_addr_t src, uint32_t *dest);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // OPENTITAN_SW_DEVICE_LIB_CRYPTO_IMPL_OTBN_UTIL_H_
diff --git a/sw/device/lib/crypto/impl/rsa_3072/BUILD b/sw/device/lib/crypto/impl/rsa_3072/BUILD
index 64f73eb..7ddb3f3 100644
--- a/sw/device/lib/crypto/impl/rsa_3072/BUILD
+++ b/sw/device/lib/crypto/impl/rsa_3072/BUILD
@@ -17,7 +17,6 @@
"//sw/device/lib/base:memory",
"//sw/device/lib/crypto/drivers:hmac",
"//sw/device/lib/crypto/drivers:otbn",
- "//sw/device/lib/crypto/impl:otbn_util",
"//sw/otbn/crypto:run_rsa_verify_3072",
],
)
diff --git a/sw/device/lib/crypto/impl/rsa_3072/rsa_3072_verify.c b/sw/device/lib/crypto/impl/rsa_3072/rsa_3072_verify.c
index 4f9291c..ebefabb 100644
--- a/sw/device/lib/crypto/impl/rsa_3072/rsa_3072_verify.c
+++ b/sw/device/lib/crypto/impl/rsa_3072/rsa_3072_verify.c
@@ -9,7 +9,6 @@
#include "sw/device/lib/base/memory.h"
#include "sw/device/lib/crypto/drivers/hmac.h"
#include "sw/device/lib/crypto/drivers/otbn.h"
-#include "sw/device/lib/crypto/impl/otbn_util.h"
#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
@@ -108,9 +107,9 @@
* @param dst Address of the destination in OTBN's data memory.
* @return The result of the operation.
*/
-otbn_error_t write_rsa_3072_int_to_otbn(otbn_t *otbn, const rsa_3072_int_t *src,
+otbn_error_t write_rsa_3072_int_to_otbn(const rsa_3072_int_t *src,
otbn_addr_t dst) {
- return otbn_copy_data_to_otbn(otbn, kRsa3072NumWords, src->data, dst);
+ return otbn_dmem_write(kRsa3072NumWords, src->data, dst);
}
/**
@@ -121,42 +120,37 @@
* @param dst The destination of the copied data in main memory (preallocated).
* @return The result of the operation.
*/
-otbn_error_t read_rsa_3072_int_from_otbn(otbn_t *otbn, otbn_addr_t src,
- rsa_3072_int_t *dst) {
- return otbn_copy_data_from_otbn(otbn, kRsa3072NumWords, src, dst->data);
+otbn_error_t read_rsa_3072_int_from_otbn(otbn_addr_t src, rsa_3072_int_t *dst) {
+ return otbn_dmem_read(kRsa3072NumWords, src, dst->data);
}
// TODO: This implementation waits while OTBN is processing; it should be
// modified to be non-blocking.
otbn_error_t rsa_3072_compute_constants(const rsa_3072_public_key_t *public_key,
rsa_3072_constants_t *result) {
- otbn_t otbn;
-
- // Initialize OTBN and load the RSA app.
- otbn_init(&otbn);
- OTBN_RETURN_IF_ERROR(otbn_load_app(&otbn, kOtbnAppRsa));
+ // Load the RSA app. Fails if OTBN is non-idle.
+ OTBN_RETURN_IF_ERROR(otbn_load_app(kOtbnAppRsa));
// Set mode to compute constants.
- OTBN_RETURN_IF_ERROR(otbn_copy_data_to_otbn(
- &otbn, kOtbnRsaModeNumWords, &kOtbnRsaModeConstants, kOtbnVarRsaMode));
+ OTBN_RETURN_IF_ERROR(otbn_dmem_write(
+ kOtbnRsaModeNumWords, &kOtbnRsaModeConstants, kOtbnVarRsaMode));
// Set the modulus (n).
OTBN_RETURN_IF_ERROR(
- write_rsa_3072_int_to_otbn(&otbn, &public_key->n, kOtbnVarRsaInMod));
+ write_rsa_3072_int_to_otbn(&public_key->n, kOtbnVarRsaInMod));
// Start the OTBN routine.
- OTBN_RETURN_IF_ERROR(otbn_execute_app(&otbn));
+ OTBN_RETURN_IF_ERROR(otbn_execute());
// Spin here waiting for OTBN to complete.
OTBN_RETURN_IF_ERROR(otbn_busy_wait_for_done());
// Read constant rr out of DMEM.
- OTBN_RETURN_IF_ERROR(
- read_rsa_3072_int_from_otbn(&otbn, kOtbnVarRsaRR, &result->rr));
+ OTBN_RETURN_IF_ERROR(read_rsa_3072_int_from_otbn(kOtbnVarRsaRR, &result->rr));
// Read constant m0_inv out of DMEM.
- OTBN_RETURN_IF_ERROR(otbn_copy_data_from_otbn(
- &otbn, kOtbnWideWordNumWords, kOtbnVarRsaM0Inv, result->m0_inv));
+ OTBN_RETURN_IF_ERROR(
+ otbn_dmem_read(kOtbnWideWordNumWords, kOtbnVarRsaM0Inv, result->m0_inv));
return kOtbnErrorOk;
}
@@ -183,33 +177,30 @@
return kOtbnErrorInvalidArgument;
}
- // Initialize OTBN and load the RSA app.
- otbn_t otbn;
- otbn_init(&otbn);
- OTBN_RETURN_IF_ERROR(otbn_load_app(&otbn, kOtbnAppRsa));
+ // Load the RSA app. Fails if OTBN is non-idle.
+ OTBN_RETURN_IF_ERROR(otbn_load_app(kOtbnAppRsa));
// Set mode to perform modular exponentiation.
- OTBN_RETURN_IF_ERROR(otbn_copy_data_to_otbn(
- &otbn, kOtbnRsaModeNumWords, &kOtbnRsaModeModexp, kOtbnVarRsaMode));
+ OTBN_RETURN_IF_ERROR(otbn_dmem_write(kOtbnRsaModeNumWords,
+ &kOtbnRsaModeModexp, kOtbnVarRsaMode));
// Set the modulus (n).
OTBN_RETURN_IF_ERROR(
- write_rsa_3072_int_to_otbn(&otbn, &public_key->n, kOtbnVarRsaInMod));
+ write_rsa_3072_int_to_otbn(&public_key->n, kOtbnVarRsaInMod));
// Set the signature.
- OTBN_RETURN_IF_ERROR(
- write_rsa_3072_int_to_otbn(&otbn, signature, kOtbnVarRsaInBuf));
+ OTBN_RETURN_IF_ERROR(write_rsa_3072_int_to_otbn(signature, kOtbnVarRsaInBuf));
// Set the precomputed constant R^2.
OTBN_RETURN_IF_ERROR(
- write_rsa_3072_int_to_otbn(&otbn, &constants->rr, kOtbnVarRsaRR));
+ write_rsa_3072_int_to_otbn(&constants->rr, kOtbnVarRsaRR));
// Set the precomputed constant m0_inv.
- OTBN_RETURN_IF_ERROR(otbn_copy_data_to_otbn(
- &otbn, kOtbnWideWordNumWords, constants->m0_inv, kOtbnVarRsaM0Inv));
+ OTBN_RETURN_IF_ERROR(otbn_dmem_write(kOtbnWideWordNumWords, constants->m0_inv,
+ kOtbnVarRsaM0Inv));
// Start the OTBN routine.
- OTBN_RETURN_IF_ERROR(otbn_execute_app(&otbn));
+ OTBN_RETURN_IF_ERROR(otbn_execute());
// Spin here waiting for OTBN to complete.
OTBN_RETURN_IF_ERROR(otbn_busy_wait_for_done());
@@ -217,7 +208,7 @@
// Read recovered message out of OTBN dmem.
rsa_3072_int_t recoveredMessage;
OTBN_RETURN_IF_ERROR(
- read_rsa_3072_int_from_otbn(&otbn, kOtbnVarRsaOutBuf, &recoveredMessage));
+ read_rsa_3072_int_from_otbn(kOtbnVarRsaOutBuf, &recoveredMessage));
// TODO: harden this memory comparison
// Check if recovered message matches expectation
diff --git a/sw/device/lib/crypto/impl/rsa_3072/rsa_3072_verify.h b/sw/device/lib/crypto/impl/rsa_3072/rsa_3072_verify.h
index e2775a0..3216756 100644
--- a/sw/device/lib/crypto/impl/rsa_3072/rsa_3072_verify.h
+++ b/sw/device/lib/crypto/impl/rsa_3072/rsa_3072_verify.h
@@ -10,7 +10,7 @@
#include "sw/device/lib/base/hardened.h"
#include "sw/device/lib/crypto/drivers/hmac.h"
-#include "sw/device/lib/crypto/impl/otbn_util.h"
+#include "sw/device/lib/crypto/drivers/otbn.h"
#ifdef __cplusplus
extern "C" {
diff --git a/sw/device/tests/crypto/BUILD b/sw/device/tests/crypto/BUILD
index 5a20416..23eeae6 100644
--- a/sw/device/tests/crypto/BUILD
+++ b/sw/device/tests/crypto/BUILD
@@ -73,7 +73,6 @@
deps = [
"//sw/device/lib/crypto/drivers:hmac",
"//sw/device/lib/crypto/drivers:otbn",
- "//sw/device/lib/crypto/impl:otbn_util",
"//sw/device/lib/crypto/impl/ecdsa_p256",
"//sw/device/lib/runtime:log",
"//sw/device/lib/testing:entropy_testutils",
@@ -98,7 +97,6 @@
":ecdsa_p256_verify_testvectors_hardcoded_header",
"//sw/device/lib/crypto/drivers:hmac",
"//sw/device/lib/crypto/drivers:otbn",
- "//sw/device/lib/crypto/impl:otbn_util",
"//sw/device/lib/crypto/impl/ecdsa_p256",
"//sw/device/lib/runtime:log",
"//sw/device/lib/testing/test_framework:ottf_main",
@@ -130,7 +128,6 @@
":rsa_3072_verify_testvectors_wycheproof_header",
"//sw/device/lib/crypto/drivers:hmac",
"//sw/device/lib/crypto/drivers:otbn",
- "//sw/device/lib/crypto/impl:otbn_util",
"//sw/device/lib/crypto/impl/rsa_3072:rsa_3072_verify",
"//sw/device/lib/runtime:log",
"//sw/device/lib/testing/test_framework:ottf_main",
@@ -154,7 +151,6 @@
":rsa_3072_verify_testvectors_hardcoded_header",
"//sw/device/lib/crypto/drivers:hmac",
"//sw/device/lib/crypto/drivers:otbn",
- "//sw/device/lib/crypto/impl:otbn_util",
"//sw/device/lib/crypto/impl/rsa_3072:rsa_3072_verify",
"//sw/device/lib/runtime:log",
"//sw/device/lib/testing/test_framework:ottf_main",
diff --git a/sw/device/tests/crypto/ecdsa_p256_functest.c b/sw/device/tests/crypto/ecdsa_p256_functest.c
index 88bbe1a..bfa7d17 100644
--- a/sw/device/tests/crypto/ecdsa_p256_functest.c
+++ b/sw/device/tests/crypto/ecdsa_p256_functest.c
@@ -5,7 +5,6 @@
#include "sw/device/lib/crypto/drivers/hmac.h"
#include "sw/device/lib/crypto/drivers/otbn.h"
#include "sw/device/lib/crypto/impl/ecdsa_p256/ecdsa_p256.h"
-#include "sw/device/lib/crypto/impl/otbn_util.h"
#include "sw/device/lib/runtime/log.h"
#include "sw/device/lib/testing/entropy_testutils.h"
#include "sw/device/lib/testing/test_framework/check.h"