Skip to content

Commit

Permalink
[pentest] OTBN FI key sideloading & load integrity
Browse files Browse the repository at this point in the history
This commits adds the following two FI penetration tests for OTBN:
- otbn.fi.load_integrity
- otbn.fi.key_sideload

The first test aims to check whether the CRC checksum over the
DMEM can be manipulated.
The second test aims to test whether a fault can manipulate a key
that gets sideloaded from the key manager.

Signed-off-by: Pascal Nasahl <[email protected]>
  • Loading branch information
nasahlpa committed Mar 8, 2024
1 parent 2a4cf85 commit b200083
Show file tree
Hide file tree
Showing 11 changed files with 372 additions and 12 deletions.
21 changes: 21 additions & 0 deletions sw/device/lib/dif/dif_otbn.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,27 @@ dif_result_t dif_otbn_get_insn_cnt(const dif_otbn_t *otbn, uint32_t *insn_cnt) {
return kDifOk;
}

dif_result_t dif_otbn_get_load_checksum(const dif_otbn_t *otbn,
uint32_t *checksum) {
if (otbn == NULL || checksum == NULL) {
return kDifBadArg;
}

*checksum =
mmio_region_read32(otbn->base_addr, OTBN_LOAD_CHECKSUM_REG_OFFSET);
return kDifOk;
}

dif_result_t dif_otbn_clear_load_checksum(const dif_otbn_t *otbn) {
if (otbn == NULL) {
return kDifBadArg;
}

mmio_region_write32(otbn->base_addr, OTBN_LOAD_CHECKSUM_REG_OFFSET, 0);

return kDifOk;
}

dif_result_t dif_otbn_imem_write(const dif_otbn_t *otbn, uint32_t offset_bytes,
const void *src, size_t len_bytes) {
if (otbn == NULL || src == NULL ||
Expand Down
24 changes: 24 additions & 0 deletions sw/device/lib/dif/dif_otbn.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,30 @@ dif_result_t dif_otbn_get_err_bits(const dif_otbn_t *otbn,
OT_WARN_UNUSED_RESULT
dif_result_t dif_otbn_get_insn_cnt(const dif_otbn_t *otbn, uint32_t *insn_cnt);

/**
* Gets the content of the load checksum register.
*
* Gets the 32-bit CRC checksum of data written to memory.
*
* @param otbn OTBN instance.
* @param[out] insn_cnt The number of instructions executed by OTBN.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_otbn_get_load_checksum(const dif_otbn_t *otbn,
uint32_t *insn_cnt);

/**
* Clears the load checksum register.
*
* Writes 0 to the load checksum register to clear it.
*
* @param otbn OTBN instance.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_otbn_clear_load_checksum(const dif_otbn_t *otbn);

/**
* Write an OTBN application into its instruction memory (IMEM).
*
Expand Down
5 changes: 5 additions & 0 deletions sw/device/tests/crypto/cryptotest/firmware/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -125,16 +125,21 @@ cc_library(
"//sw/device/lib/base:memory",
"//sw/device/lib/base:status",
"//sw/device/lib/crypto/drivers:otbn",
"//sw/device/lib/dif:keymgr",
"//sw/device/lib/dif:otbn",
"//sw/device/lib/runtime:log",
"//sw/device/lib/testing:entropy_testutils",
"//sw/device/lib/testing:keymgr_testutils",
"//sw/device/lib/testing/test_framework:ujson_ottf",
"//sw/device/lib/ujson",
"//sw/device/sca/lib:sca",
"//sw/device/tests/crypto/cryptotest/firmware:sca_lib",
"//sw/device/tests/crypto/cryptotest/firmware/otbn:otbn_char_hardware_dmem_op_loop",
"//sw/device/tests/crypto/cryptotest/firmware/otbn:otbn_char_hardware_reg_op_loop",
"//sw/device/tests/crypto/cryptotest/firmware/otbn:otbn_char_unrolled_dmem_op_loop",
"//sw/device/tests/crypto/cryptotest/firmware/otbn:otbn_char_unrolled_reg_op_loop",
"//sw/device/tests/crypto/cryptotest/firmware/otbn:otbn_key_sideload",
"//sw/device/tests/crypto/cryptotest/firmware/otbn:otbn_load_integrity",
"//sw/device/tests/crypto/cryptotest/json:otbn_fi_commands",
],
)
Expand Down
14 changes: 14 additions & 0 deletions sw/device/tests/crypto/cryptotest/firmware/otbn/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,17 @@ otbn_binary(
"otbn_char_unrolled_reg_op_loop.s",
],
)

otbn_binary(
name = "otbn_key_sideload",
srcs = [
"otbn_key_sideload.s",
],
)

otbn_binary(
name = "otbn_load_integrity",
srcs = [
"otbn_load_integrity.s",
],
)
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,8 @@
*/
.section .text.start

/* Load loop counter from dmem and set num it. of outer loop to 100. */
li x1, 100
la x3, lc
/* Increment loop counter in nested hardware loops. */
loop x1, 5
loopi 100, 3
lw x2, 0(x3)
addi x2, x2, 1
sw x2, 0(x3)
nop
/* Execute a single nop and return. */
nop

ecall

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/* Copyright lowRISC contributors. */
/* Licensed under the Apache License, Version 2.0, see LICENSE for details. */
/* SPDX-License-Identifier: Apache-2.0 */
/*
OBTN.KEY_SIDELOAD FI Penetration Test
*/
.section .text.start

/* Load all key shares into w20...w23. */
bn.wsrr w20, KEY_S0_L
bn.wsrr w21, KEY_S1_L
bn.wsrr w22, KEY_S0_H
bn.wsrr w23, KEY_S1_H

/* Write key shared into accessible DMEM. */
li x2, 20
la x3, k_s0_l
bn.sid x2, 0(x3)

li x2, 21
la x3, k_s0_h
bn.sid x2, 0(x3)

li x2, 22
la x3, k_s1_l
bn.sid x2, 0(x3)

li x2, 23
la x3, k_s1_h
bn.sid x2, 0(x3)

ecall

.data
.globl k_s0_l
.balign 32
k_s0_l:
.zero 32

.globl k_s0_h
.balign 32
k_s0_h:
.zero 32

.globl k_s1_l
.balign 32
k_s1_l:
.zero 32

.globl k_s1_h
.balign 32
k_s1_h:
.zero 32
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* Copyright lowRISC contributors. */
/* Licensed under the Apache License, Version 2.0, see LICENSE for details. */
/* SPDX-License-Identifier: Apache-2.0 */
/*
OBTN.LOAD_INTEGRITY FI Penetration Test
*/
.section .text.start

/* Execute 10 NOPs. */
li x1, 10
loop x1, 1
nop

ecall

.data
/* Reference values. */
.balign 32
.globl refval1
refval1:
.word 0x1BADB002

.balign 32
.globl refval2
refval2:
.word 0x8BADF00D

.balign 32
.globl refval3
refval3:
.word 0xA5A5A5A5

Loading

0 comments on commit b200083

Please sign in to comment.