Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 1 | --- |
| 2 | title: OpenTitan Big Number Accelerator (OTBN) Technical Specification |
| 3 | --- |
| 4 | |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 5 | # Overview |
| 6 | |
| 7 | This document specifies functionality of the OpenTitan Big Number Accelerator, or OTBN. |
| 8 | OTBN is a coprocessor for asymmetric cryptographic operations like RSA or Elliptic Curve Cryptography (ECC). |
| 9 | |
| 10 | This module conforms to the [Comportable guideline for peripheral functionality]({{< relref "doc/rm/comportability_specification" >}}). |
| 11 | See that document for integration overview within the broader top level system. |
| 12 | |
| 13 | ## Features |
| 14 | |
| 15 | * Processor optimized for wide integer arithmetic |
| 16 | * 32b wide control path with 32 32b wide registers |
| 17 | * 256b wide data path with 32 256b wide registers |
| 18 | * Full control-flow support with conditional branch and unconditional jump instructions, hardware loops, and hardware-managed call/return stacks. |
| 19 | * Reduced, security-focused instruction set architecture for easier verification and the prevention of data leaks. |
| 20 | * Built-in access to random numbers. |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 21 | |
| 22 | ## Description |
| 23 | |
| 24 | OTBN is a processor, specialized for the execution of security-sensitive asymmetric (public-key) cryptography code, such as RSA or ECC. |
| 25 | Such algorithms are dominated by wide integer arithmetic, which are supported by OTBN's 256b wide data path, registers, and instructions which operate these wide data words. |
| 26 | On the other hand, the control flow is clearly separated from the data, and reduced to a minimum to avoid data leakage. |
| 27 | |
| 28 | The data OTBN processes is security-sensitive, and the processor design centers around that. |
| 29 | The design is kept as simple as possible to reduce the attack surface and aid verification and testing. |
| 30 | For example, no interrupts or exceptions are included in the design, and all instructions are designed to be executable within a single cycle. |
| 31 | |
| 32 | OTBN is designed as a self-contained co-processor with its own instruction and data memory, which is accessible as a bus device. |
| 33 | |
| 34 | ## Compatibility |
| 35 | |
| 36 | OTBN is not designed to be compatible with other cryptographic accelerators. |
Felix Miller | 75b30e2 | 2020-09-04 14:23:07 +0200 | [diff] [blame] | 37 | It received some inspiration from assembly code available from the [Chromium EC project](https://chromium.googlesource.com/chromiumos/platform/ec/), |
| 38 | which has been formally verified within the [Fiat Crypto project](http://adam.chlipala.net/papers/FiatCryptoSP19/FiatCryptoSP19.pdf). |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 39 | |
| 40 | # Instruction Set |
| 41 | |
Rupert Swarbrick | 83c6aef | 2020-11-19 13:02:58 +0000 | [diff] [blame] | 42 | OTBN is a processor with a custom instruction set. |
Philipp Wagner | 07494a3 | 2021-03-18 15:59:57 +0000 | [diff] [blame] | 43 | The full ISA description can be found in our [ISA manual]({{< relref "isa" >}}). |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 44 | The instruction set is split into two groups: |
| 45 | |
| 46 | * The **base instruction subset** operates on the 32b General Purpose Registers (GPRs). |
| 47 | Its instructions are used for the control flow of a OTBN application. |
Philipp Wagner | e938c88 | 2021-07-20 14:32:44 +0100 | [diff] [blame] | 48 | The base instructions are inspired by RISC-V's RV32I instruction set, but not compatible with it. |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 49 | * The **big number instruction subset** operates on 256b Wide Data Registers (WDRs). |
| 50 | Its instructions are used for data processing. |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 51 | |
| 52 | ## Processor State |
| 53 | |
| 54 | ### General Purpose Registers (GPRs) |
| 55 | |
Rupert Swarbrick | 0673ae1 | 2020-11-19 14:07:00 +0000 | [diff] [blame] | 56 | OTBN has 32 General Purpose Registers (GPRs), each of which is 32b wide. |
| 57 | The GPRs are defined in line with RV32I and are mainly used for control flow. |
| 58 | They are accessed through the base instruction subset. |
Philipp Wagner | ba56cd3 | 2021-05-10 15:56:34 +0100 | [diff] [blame] | 59 | GPRs aren't used by the main data path; this operates on the [Wide Data Registers](#wide-data-registers-wdrs), a separate register file, controlled by the big number instructions. |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 60 | |
| 61 | <table> |
| 62 | <tr> |
| 63 | <td><code>x0</code></td> |
Rupert Swarbrick | 0673ae1 | 2020-11-19 14:07:00 +0000 | [diff] [blame] | 64 | <td>Zero register. Reads as 0; writes are ignored.</td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 65 | </tr> |
| 66 | <tr> |
| 67 | <td><code>x1</code></td> |
Rupert Swarbrick | 0673ae1 | 2020-11-19 14:07:00 +0000 | [diff] [blame] | 68 | <td> |
| 69 | |
| 70 | Access to the [call stack](#call-stack) |
| 71 | |
| 72 | </td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 73 | </tr> |
| 74 | <tr> |
Rupert Swarbrick | 0673ae1 | 2020-11-19 14:07:00 +0000 | [diff] [blame] | 75 | <td><code>x2</code> ... <code>x31</code></td> |
| 76 | <td>General purpose registers</td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 77 | </tr> |
| 78 | </table> |
| 79 | |
Rupert Swarbrick | 0673ae1 | 2020-11-19 14:07:00 +0000 | [diff] [blame] | 80 | Note: Currently, OTBN has no "standard calling convention," and GPRs other than `x0` and `x1` can be used for any purpose. |
| 81 | If a calling convention is needed at some point, it is expected to be aligned with the RISC-V standard calling conventions, and the roles assigned to registers in that convention. |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 82 | Even without a agreed-on calling convention, software authors are encouraged to follow the RISC-V calling convention where it makes sense. |
| 83 | For example, good choices for temporary registers are `x6`, `x7`, `x28`, `x29`, `x30`, and `x31`. |
| 84 | |
Rupert Swarbrick | 0673ae1 | 2020-11-19 14:07:00 +0000 | [diff] [blame] | 85 | ### Call Stack |
| 86 | |
| 87 | OTBN has an in-built call stack which is accessed through the `x1` GPR. |
| 88 | This is intended to be used as a return address stack, containing return addresses for the current stack of function calls. |
Philipp Wagner | 00fccb1 | 2021-07-20 14:37:58 +0100 | [diff] [blame] | 89 | See the documentation for {{< otbnInsnRef "JAL" >}} and {{< otbnInsnRef "JALR" >}} for a description of how to use it for this purpose. |
Rupert Swarbrick | 0673ae1 | 2020-11-19 14:07:00 +0000 | [diff] [blame] | 90 | |
| 91 | The call stack has a maximum depth of 8 elements. |
| 92 | Each instruction that reads from `x1` pops a single element from the stack. |
| 93 | Each instruction that writes to `x1` pushes a single element onto the stack. |
Greg Chadwick | 5ce1cb7 | 2021-01-13 14:20:48 +0000 | [diff] [blame] | 94 | An instruction that reads from an empty stack or writes to a full stack causes OTBN to stop, raising an alert and setting the `ErrBitCallStack` bit in the {{< regref "ERR_BITS" >}} register. |
Rupert Swarbrick | 0673ae1 | 2020-11-19 14:07:00 +0000 | [diff] [blame] | 95 | |
| 96 | A single instruction can both read and write to the stack. |
| 97 | In this case, the read is ordered before the write. |
| 98 | Providing the stack has at least one element, this is allowed, even if the stack is full. |
| 99 | |
Philipp Wagner | 44bd4ca | 2021-07-20 14:39:54 +0100 | [diff] [blame] | 100 | ### Control and Status Registers (CSRs) {#csrs} |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 101 | |
| 102 | Control and Status Registers (CSRs) are 32b wide registers used for "special" purposes, as detailed in their description; |
| 103 | they are not related to the GPRs. |
Philipp Wagner | 00fccb1 | 2021-07-20 14:37:58 +0100 | [diff] [blame] | 104 | CSRs can be accessed through dedicated instructions, {{< otbnInsnRef "CSRRS" >}} and {{< otbnInsnRef "CSRRW" >}}. |
Philipp Wagner | 44bd4ca | 2021-07-20 14:39:54 +0100 | [diff] [blame] | 105 | Writes to read-only (RO) registers are ignored; they do not signal an error. |
| 106 | All read-write (RW) CSRs are set to 0 when OTBN starts an operation (when 1 is written to {{< regref "CMD.start" >}}). |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 107 | |
Rupert Swarbrick | 14b3e5e | 2021-07-21 13:44:49 +0100 | [diff] [blame] | 108 | <!-- This list of CSRs is replicated in otbn_env_cov.sv, wsr.py, the |
| 109 | RTL and in rig/model.py. If editing one, edit the other four as well. --> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 110 | <table> |
| 111 | <thead> |
| 112 | <tr> |
| 113 | <th>Number</th> |
Philipp Wagner | 44bd4ca | 2021-07-20 14:39:54 +0100 | [diff] [blame] | 114 | <th>Access</th> |
| 115 | <th>Name</th> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 116 | <th>Description</th> |
| 117 | </tr> |
| 118 | </thead> |
| 119 | <tbody> |
| 120 | <tr> |
| 121 | <td>0x7C0</td> |
| 122 | <td>RW</td> |
Philipp Wagner | 44bd4ca | 2021-07-20 14:39:54 +0100 | [diff] [blame] | 123 | <td>FG0</td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 124 | <td> |
Greg Chadwick | dbd655a | 2020-11-24 16:42:06 +0000 | [diff] [blame] | 125 | Wide arithmetic flag group 0. |
| 126 | This CSR provides access to flag group 0 used by wide integer arithmetic. |
| 127 | <strong>FLAGS</strong>, <strong>FG0</strong> and <strong>FG1</strong> provide different views on the same underlying bits. |
| 128 | <table> |
| 129 | <thead> |
| 130 | <tr><th>Bit</th><th>Description</th></tr> |
| 131 | </thead> |
| 132 | <tbody> |
| 133 | <tr><td>0</td><td>Carry of Flag Group 0</td></tr> |
| 134 | <tr><td>1</td><td>MSb of Flag Group 0</td></tr> |
| 135 | <tr><td>2</td><td>LSb of Flag Group 0</td></tr> |
| 136 | <tr><td>3</td><td>Zero of Flag Group 0</td></tr> |
| 137 | </tbody> |
| 138 | </table> |
| 139 | </td> |
| 140 | </tr> |
| 141 | <tr> |
| 142 | <td>0x7C1</td> |
| 143 | <td>RW</td> |
Philipp Wagner | 44bd4ca | 2021-07-20 14:39:54 +0100 | [diff] [blame] | 144 | <td>FG1</td> |
Greg Chadwick | dbd655a | 2020-11-24 16:42:06 +0000 | [diff] [blame] | 145 | <td> |
Greg Chadwick | dbd655a | 2020-11-24 16:42:06 +0000 | [diff] [blame] | 146 | Wide arithmetic flag group 1. |
| 147 | This CSR provides access to flag group 1 used by wide integer arithmetic. |
| 148 | <strong>FLAGS</strong>, <strong>FG0</strong> and <strong>FG1</strong> provide different views on the same underlying bits. |
| 149 | <table> |
| 150 | <thead> |
| 151 | <tr><th>Bit</th><th>Description</th></tr> |
| 152 | </thead> |
| 153 | <tbody> |
| 154 | <tr><td>0</td><td>Carry of Flag Group 1</td></tr> |
| 155 | <tr><td>1</td><td>MSb of Flag Group 1</td></tr> |
| 156 | <tr><td>2</td><td>LSb of Flag Group 1</td></tr> |
| 157 | <tr><td>3</td><td>Zero of Flag Group 1</td></tr> |
| 158 | </tbody> |
| 159 | </table> |
| 160 | </td> |
| 161 | </tr> |
| 162 | <tr> |
| 163 | <td>0x7C8</td> |
| 164 | <td>RW</td> |
Philipp Wagner | 44bd4ca | 2021-07-20 14:39:54 +0100 | [diff] [blame] | 165 | <td>FLAGS</td> |
Greg Chadwick | dbd655a | 2020-11-24 16:42:06 +0000 | [diff] [blame] | 166 | <td> |
Greg Chadwick | dbd655a | 2020-11-24 16:42:06 +0000 | [diff] [blame] | 167 | Wide arithmetic flag groups. |
| 168 | This CSR provides access to both flags groups used by wide integer arithmetic. |
| 169 | <strong>FLAGS</strong>, <strong>FG0</strong> and <strong>FG1</strong> provide different views on the same underlying bits. |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 170 | <table> |
| 171 | <thead> |
| 172 | <tr><th>Bit</th><th>Description</th></tr> |
| 173 | </thead> |
| 174 | <tbody> |
| 175 | <tr><td>0</td><td>Carry of Flag Group 0</td></tr> |
Greg Chadwick | 6c63272 | 2020-10-08 17:59:18 +0100 | [diff] [blame] | 176 | <tr><td>1</td><td>MSb of Flag Group 0</td></tr> |
| 177 | <tr><td>2</td><td>LSb of Flag Group 0</td></tr> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 178 | <tr><td>3</td><td>Zero of Flag Group 0</td></tr> |
| 179 | <tr><td>4</td><td>Carry of Flag Group 1</td></tr> |
Greg Chadwick | 6c63272 | 2020-10-08 17:59:18 +0100 | [diff] [blame] | 180 | <tr><td>5</td><td>MSb of Flag Group 1</td></tr> |
| 181 | <tr><td>6</td><td>LSb of Flag Group 1</td></tr> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 182 | <tr><td>7</td><td>Zero of Flag Group 1</td></tr> |
| 183 | </tbody> |
| 184 | </table> |
| 185 | </td> |
| 186 | </tr> |
| 187 | <tr> |
| 188 | <td>0x7D0</td> |
| 189 | <td>RW</td> |
Philipp Wagner | 44bd4ca | 2021-07-20 14:39:54 +0100 | [diff] [blame] | 190 | <td>MOD0</td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 191 | <td> |
Philipp Wagner | 00fccb1 | 2021-07-20 14:37:58 +0100 | [diff] [blame] | 192 | Bits [31:0] of the modulus operand, used in the {{< otbnInsnRef "BN.ADDM" >}}/{{< otbnInsnRef "BN.SUBM" >}} instructions. |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 193 | This CSR is mapped to the MOD WSR. |
| 194 | </td> |
| 195 | </tr> |
| 196 | <tr> |
| 197 | <td>0x7D1</td> |
| 198 | <td>RW</td> |
Philipp Wagner | 44bd4ca | 2021-07-20 14:39:54 +0100 | [diff] [blame] | 199 | <td>MOD1</td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 200 | <td> |
Philipp Wagner | 00fccb1 | 2021-07-20 14:37:58 +0100 | [diff] [blame] | 201 | Bits [63:32] of the modulus operand, used in the {{< otbnInsnRef "BN.ADDM" >}}/{{< otbnInsnRef "BN.SUBM" >}} instructions. |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 202 | This CSR is mapped to the MOD WSR. |
| 203 | </td> |
| 204 | </tr> |
| 205 | <tr> |
| 206 | <td>0x7D2</td> |
| 207 | <td>RW</td> |
Philipp Wagner | 44bd4ca | 2021-07-20 14:39:54 +0100 | [diff] [blame] | 208 | <td>MOD2</td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 209 | <td> |
Philipp Wagner | 00fccb1 | 2021-07-20 14:37:58 +0100 | [diff] [blame] | 210 | Bits [95:64] of the modulus operand, used in the {{< otbnInsnRef "BN.ADDM" >}}/{{< otbnInsnRef "BN.SUBM" >}} instructions. |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 211 | This CSR is mapped to the MOD WSR. |
| 212 | </td> |
| 213 | </tr> |
| 214 | <tr> |
| 215 | <td>0x7D3</td> |
| 216 | <td>RW</td> |
Philipp Wagner | 44bd4ca | 2021-07-20 14:39:54 +0100 | [diff] [blame] | 217 | <td>MOD3</td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 218 | <td> |
Philipp Wagner | 00fccb1 | 2021-07-20 14:37:58 +0100 | [diff] [blame] | 219 | Bits [127:96] of the modulus operand, used in the {{< otbnInsnRef "BN.ADDM" >}}/{{< otbnInsnRef "BN.SUBM" >}} instructions. |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 220 | This CSR is mapped to the MOD WSR. |
| 221 | </td> |
| 222 | </tr> |
| 223 | <tr> |
| 224 | <td>0x7D4</td> |
| 225 | <td>RW</td> |
Philipp Wagner | 44bd4ca | 2021-07-20 14:39:54 +0100 | [diff] [blame] | 226 | <td>MOD4</td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 227 | <td> |
Philipp Wagner | 00fccb1 | 2021-07-20 14:37:58 +0100 | [diff] [blame] | 228 | Bits [159:128] of the modulus operand, used in the {{< otbnInsnRef "BN.ADDM" >}}/{{< otbnInsnRef "BN.SUBM" >}} instructions. |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 229 | This CSR is mapped to the MOD WSR. |
| 230 | </td> |
| 231 | </tr> |
| 232 | <tr> |
| 233 | <td>0x7D5</td> |
| 234 | <td>RW</td> |
Philipp Wagner | 44bd4ca | 2021-07-20 14:39:54 +0100 | [diff] [blame] | 235 | <td>MOD5</td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 236 | <td> |
Philipp Wagner | 00fccb1 | 2021-07-20 14:37:58 +0100 | [diff] [blame] | 237 | Bits [191:160] of the modulus operand, used in the {{< otbnInsnRef "BN.ADDM" >}}/{{< otbnInsnRef "BN.SUBM" >}} instructions. |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 238 | This CSR is mapped to the MOD WSR. |
| 239 | </td> |
| 240 | </tr> |
| 241 | <tr> |
| 242 | <td>0x7D6</td> |
| 243 | <td>RW</td> |
Philipp Wagner | 44bd4ca | 2021-07-20 14:39:54 +0100 | [diff] [blame] | 244 | <td>MOD6</td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 245 | <td> |
Philipp Wagner | 00fccb1 | 2021-07-20 14:37:58 +0100 | [diff] [blame] | 246 | Bits [223:192] of the modulus operand, used in the {{< otbnInsnRef "BN.ADDM" >}}/{{< otbnInsnRef "BN.SUBM" >}} instructions. |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 247 | This CSR is mapped to the MOD WSR. |
| 248 | </td> |
| 249 | </tr> |
| 250 | <tr> |
| 251 | <td>0x7D7</td> |
| 252 | <td>RW</td> |
Philipp Wagner | 44bd4ca | 2021-07-20 14:39:54 +0100 | [diff] [blame] | 253 | <td>MOD7</td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 254 | <td> |
Philipp Wagner | 00fccb1 | 2021-07-20 14:37:58 +0100 | [diff] [blame] | 255 | Bits [255:224] of the modulus operand, used in the {{< otbnInsnRef "BN.ADDM" >}}/{{< otbnInsnRef "BN.SUBM" >}} instructions. |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 256 | This CSR is mapped to the MOD WSR. |
| 257 | </td> |
| 258 | </tr> |
| 259 | <tr> |
Philipp Wagner | 9387752 | 2021-07-16 10:49:25 +0100 | [diff] [blame] | 260 | <td>0x7D8</td> |
| 261 | <td>RW</td> |
Philipp Wagner | 44bd4ca | 2021-07-20 14:39:54 +0100 | [diff] [blame] | 262 | <td>RND_PREFETCH</td> |
Philipp Wagner | 9387752 | 2021-07-16 10:49:25 +0100 | [diff] [blame] | 263 | <td> |
Philipp Wagner | 9387752 | 2021-07-16 10:49:25 +0100 | [diff] [blame] | 264 | Write to this CSR to begin a request to fill the RND cache. |
| 265 | Always reads as 0. |
| 266 | </td> |
| 267 | </tr> |
| 268 | <tr> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 269 | <td>0xFC0</td> |
Rupert Swarbrick | 2f9cbd7 | 2021-07-21 13:43:47 +0100 | [diff] [blame] | 270 | <td>RO</td> |
Philipp Wagner | 44bd4ca | 2021-07-20 14:39:54 +0100 | [diff] [blame] | 271 | <td>RND</td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 272 | <td> |
Philipp Wagner | 8a19191 | 2021-07-15 18:08:07 +0100 | [diff] [blame] | 273 | An AIS31-compliant class PTG.3 random number with guaranteed entropy and forward and backward secrecy. |
| 274 | Primarily intended to be used for key generation. |
| 275 | |
| 276 | The number is sourced from the EDN via a single-entry cache. |
| 277 | Reads when the cache is empty will cause OTBN to be stalled until a new random number is fetched from the EDN. |
Greg Chadwick | bd9c77e | 2021-03-05 16:15:16 +0000 | [diff] [blame] | 278 | </td> |
| 279 | </tr> |
| 280 | <tr> |
| 281 | <td>0xFC1</td> |
Rupert Swarbrick | 2f9cbd7 | 2021-07-21 13:43:47 +0100 | [diff] [blame] | 282 | <td>RO</td> |
Philipp Wagner | 44bd4ca | 2021-07-20 14:39:54 +0100 | [diff] [blame] | 283 | <td>URND</td> |
Greg Chadwick | bd9c77e | 2021-03-05 16:15:16 +0000 | [diff] [blame] | 284 | <td> |
Philipp Wagner | 8a19191 | 2021-07-15 18:08:07 +0100 | [diff] [blame] | 285 | A random number without guaranteed secrecy properties or specific statistical properties. |
| 286 | Intended for use in masking and blinding schemes. |
| 287 | Use RND for high-quality randomness. |
| 288 | |
| 289 | The number is sourced from an LFSR. |
| 290 | Reads never stall. |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 291 | </td> |
| 292 | </tr> |
| 293 | </tbody> |
| 294 | </table> |
| 295 | |
| 296 | ### Wide Data Registers (WDRs) |
| 297 | |
| 298 | In addition to the 32b wide GPRs, OTBN has a second "wide" register file, which is used by the big number instruction subset. |
| 299 | This register file consists of NWDR = 32 Wide Data Registers (WDRs). |
| 300 | Each WDR is WLEN = 256b wide. |
| 301 | |
| 302 | Wide Data Registers (WDRs) and the 32b General Purpose Registers (GPRs) are separate register files. |
| 303 | They are only accessible through their respective instruction subset: |
| 304 | GPRs are accessible from the base instruction subset, and WDRs are accessible from the big number instruction subset (`BN` instructions). |
| 305 | |
| 306 | | Register | |
| 307 | |----------| |
| 308 | | w0 | |
| 309 | | w1 | |
| 310 | | ... | |
| 311 | | w31 | |
| 312 | |
Philipp Wagner | 44bd4ca | 2021-07-20 14:39:54 +0100 | [diff] [blame] | 313 | ### Wide Special Purpose Registers (WSRs) {#wsrs} |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 314 | |
Rupert Swarbrick | 9b61faa | 2020-11-23 16:41:13 +0000 | [diff] [blame] | 315 | OTBN has 256b Wide Special purpose Registers (WSRs). |
| 316 | These are analogous to the 32b CSRs, but are used by big number instructions. |
Philipp Wagner | 44bd4ca | 2021-07-20 14:39:54 +0100 | [diff] [blame] | 317 | They can be accessed with the {{< otbnInsnRef "BN.WSRR" >}} and {{< otbnInsnRef "BN.WSRW" >}} instructions. |
| 318 | Writes to read-only (RO) registers are ignored; they do not signal an error. |
| 319 | All read-write (RW) WSRs are set to 0 when OTBN starts an operation (when 1 is written to {{< regref "CMD.start" >}}). |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 320 | |
Rupert Swarbrick | ab5baa4 | 2021-07-21 11:00:04 +0100 | [diff] [blame] | 321 | <!-- This list of WSRs is replicated in otbn_env_cov.sv, wsr.py, the |
| 322 | RTL and in rig/model.py. If editing one, edit the other four as well. --> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 323 | <table> |
| 324 | <thead> |
| 325 | <tr> |
| 326 | <th>Number</th> |
Philipp Wagner | 44bd4ca | 2021-07-20 14:39:54 +0100 | [diff] [blame] | 327 | <th>Access</th> |
Rupert Swarbrick | 9b61faa | 2020-11-23 16:41:13 +0000 | [diff] [blame] | 328 | <th>Name</th> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 329 | <th>Description</th> |
| 330 | </tr> |
| 331 | </thead> |
| 332 | <tbody> |
| 333 | <tr> |
Philipp Wagner | 31399ae | 2020-07-16 16:48:31 +0100 | [diff] [blame] | 334 | <td>0x0</td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 335 | <td>RW</td> |
Philipp Wagner | 44bd4ca | 2021-07-20 14:39:54 +0100 | [diff] [blame] | 336 | <td>MOD</td> |
Rupert Swarbrick | 9b61faa | 2020-11-23 16:41:13 +0000 | [diff] [blame] | 337 | <td> |
| 338 | |
Philipp Wagner | 00fccb1 | 2021-07-20 14:37:58 +0100 | [diff] [blame] | 339 | The modulus used by the {{< otbnInsnRef "BN.ADDM" >}} and {{< otbnInsnRef "BN.SUBM" >}} instructions. |
Rupert Swarbrick | 9b61faa | 2020-11-23 16:41:13 +0000 | [diff] [blame] | 340 | This WSR is also visible as CSRs `MOD0` through to `MOD7`. |
| 341 | |
| 342 | </td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 343 | </tr> |
| 344 | <tr> |
Philipp Wagner | 31399ae | 2020-07-16 16:48:31 +0100 | [diff] [blame] | 345 | <td>0x1</td> |
Rupert Swarbrick | 2f9cbd7 | 2021-07-21 13:43:47 +0100 | [diff] [blame] | 346 | <td>RO</td> |
Philipp Wagner | 44bd4ca | 2021-07-20 14:39:54 +0100 | [diff] [blame] | 347 | <td>RND</td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 348 | <td> |
Philipp Wagner | 8a19191 | 2021-07-15 18:08:07 +0100 | [diff] [blame] | 349 | An AIS31-compliant class PTG.3 random number with guaranteed entropy and forward and backward secrecy. |
| 350 | Primarily intended to be used for key generation. |
| 351 | |
| 352 | The number is sourced from the EDN via a single-entry cache. |
| 353 | Reads when the cache is empty will cause OTBN to be stalled until a new random number is fetched from the EDN. |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 354 | </td> |
| 355 | </tr> |
Greg Chadwick | 935a910 | 2020-07-15 17:49:17 +0100 | [diff] [blame] | 356 | <tr> |
Philipp Wagner | 31399ae | 2020-07-16 16:48:31 +0100 | [diff] [blame] | 357 | <td>0x2</td> |
Rupert Swarbrick | 2f9cbd7 | 2021-07-21 13:43:47 +0100 | [diff] [blame] | 358 | <td>RO</td> |
Rupert Swarbrick | b55cb88 | 2021-07-21 13:21:38 +0100 | [diff] [blame] | 359 | <td>URND</td> |
Greg Chadwick | bd9c77e | 2021-03-05 16:15:16 +0000 | [diff] [blame] | 360 | <td> |
Philipp Wagner | 8a19191 | 2021-07-15 18:08:07 +0100 | [diff] [blame] | 361 | A random number without guaranteed secrecy properties or specific statistical properties. |
| 362 | Intended for use in masking and blinding schemes. |
| 363 | Use RND for high-quality randomness. |
| 364 | |
| 365 | The number is sourced from an LFSR. |
| 366 | Reads never stall. |
Greg Chadwick | bd9c77e | 2021-03-05 16:15:16 +0000 | [diff] [blame] | 367 | </td> |
| 368 | </tr> |
Philipp Wagner | 0f1a9f2 | 2021-07-20 15:15:20 +0100 | [diff] [blame] | 369 | <tr> |
| 370 | <td>0x3</td> |
| 371 | <td>RW</td> |
| 372 | <td>ACC</td> |
| 373 | <td> |
| 374 | The accumulator register used by the {{< otbnInsnRef "BN.MULQACC" >}} instruction. |
| 375 | </td> |
| 376 | </tr> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 377 | </tbody> |
| 378 | </table> |
| 379 | |
| 380 | ### Flags |
| 381 | |
| 382 | In addition to the wide register file, OTBN maintains global state in two groups of flags for the use by wide integer operations. |
| 383 | Flag groups are named Flag Group 0 (`FG0`), and Flag Group 1 (`FG1`). |
| 384 | Each group consists of four flags. |
| 385 | Each flag is a single bit. |
| 386 | |
| 387 | - `C` (Carry flag). |
| 388 | Set to 1 an overflow occurred in the last arithmetic instruction. |
| 389 | |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 390 | - `M` (MSb flag) |
| 391 | The most significant bit of the result of the last arithmetic or shift instruction. |
| 392 | |
Rupert Swarbrick | f18c169 | 2020-12-16 13:55:00 +0000 | [diff] [blame] | 393 | - `L` (LSb flag). |
| 394 | The least significant bit of the result of the last arithmetic or shift instruction. |
| 395 | |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 396 | - `Z` (Zero Flag) |
| 397 | Set to 1 if the result of the last operation was zero; otherwise 0. |
| 398 | |
Rupert Swarbrick | f18c169 | 2020-12-16 13:55:00 +0000 | [diff] [blame] | 399 | The `M`, `L`, and `Z` flags are determined based on the result of the operation as it is written back into the result register, without considering the overflow bit. |
Philipp Wagner | 73f4ec6 | 2020-09-03 14:05:14 +0100 | [diff] [blame] | 400 | |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 401 | ### Loop Stack |
| 402 | |
Philipp Wagner | 00fccb1 | 2021-07-20 14:37:58 +0100 | [diff] [blame] | 403 | OTBN has two instructions for hardware-assisted loops: {{< otbnInsnRef "LOOP" >}} and {{< otbnInsnRef "LOOPI" >}}. |
Rupert Swarbrick | f7e92cf | 2020-12-07 11:15:27 +0000 | [diff] [blame] | 404 | Both use the same state for tracking control flow. |
| 405 | This is a stack of tuples containing a loop count, start address and end address. |
| 406 | The stack has a maximum depth of eight and the top of the stack is the current loop. |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 407 | |
Philipp Wagner | dc5b9a9 | 2021-05-07 15:03:47 +0100 | [diff] [blame] | 408 | # Security Features |
| 409 | |
| 410 | <div class="bd-callout bd-callout-warning"> |
| 411 | <h5>Work in progress</h5> |
| 412 | |
| 413 | Work on OTBN is ongoing, including work on the specification and implementation of its security features. |
| 414 | Do not treat the following description (or anything in this documentation) as final, fully implemented, or verified. |
| 415 | </div> |
| 416 | |
| 417 | OTBN is a security co-processor. |
| 418 | It contains various security features and is hardened against side-channel analysis and fault injection attacks. |
| 419 | The following sections describe the high-level security features of OTBN. |
| 420 | Refer to the [Design Details]({{< relref "#design-details" >}}) section for a more in-depth description. |
| 421 | |
| 422 | ## Data Integrity Protection |
| 423 | |
| 424 | OTBN's data integrity protection is designed to protect the data stored and processed within OTBN from modifications through physical attacks. |
| 425 | |
| 426 | Data in OTBN travels along a data path which includes the data memory (DMEM), the load-store-unit (LSU), the register files (GPR and WDR), and the execution units. |
| 427 | Whenever possible, data transmitted or stored within OTBN is protected with an integrity protection code which guarantees the detection of at least three modified bits per 32 bit word. |
| 428 | Additionally, instructions and data stored in the instruction and data memory, respectively, are scrambled with a lightweight, non-cryptographically-secure cipher. |
| 429 | |
| 430 | Refer to the [Data Integrity Protection]({{<relref "#design-details-data-integrity-protection">}}) section for details of how the data integrity protections are implemented. |
| 431 | |
Vladimir Rozic | e76ca1f | 2021-07-12 14:06:00 +0100 | [diff] [blame] | 432 | ## Secure Wipe |
| 433 | |
| 434 | OTBN provides a mechanism to securely wipe all state it stores, including the instruction memory. |
| 435 | |
| 436 | The full secure wipe mechanism is split into three parts: |
| 437 | - [Data memory secure wipe]({{<relref "#design-details-secure-wipe-dmem">}}) |
| 438 | - [Instruction memory secure wipe]({{<relref "#design-details-secure-wipe-imem">}}) |
| 439 | - [Internal state secure wipe]({{<relref "#design-details-secure-wipe-internal">}}) |
| 440 | |
| 441 | A secure wipe is performed automatically in certain situations, or can be requested manually by the host software. |
| 442 | The full secure wipe is automatically initiated as a local reaction to a fatal error. |
Vladimir Rozic | e76ca1f | 2021-07-12 14:06:00 +0100 | [diff] [blame] | 443 | A secure wipe of only the internal state is performed whenever an OTBN operation is completed and after a recoverable error. |
Vladimir Rozic | 630526c | 2021-07-27 14:42:18 +0100 | [diff] [blame] | 444 | Finally, host software can manually trigger the data memory and instruction memory secure wipe operations by writing to the {{< regref "SEC_WIPE">}} register. |
Vladimir Rozic | e76ca1f | 2021-07-12 14:06:00 +0100 | [diff] [blame] | 445 | |
| 446 | Refer to the [Secure Wipe]({{<relref "#design-details-secure-wipe">}}) section for implementation details. |
| 447 | |
Vladimir Rozic | 30ac29f | 2021-07-07 15:13:58 +0100 | [diff] [blame] | 448 | ## Instruction Counter |
Philipp Wagner | 8a19191 | 2021-07-15 18:08:07 +0100 | [diff] [blame] | 449 | |
Vladimir Rozic | 30ac29f | 2021-07-07 15:13:58 +0100 | [diff] [blame] | 450 | In order to detect and mitigate fault injection attacks on the OTBN, the host CPU can read the number of executed instructions from {{< regref "INSN_CNT">}} and verify whether it matches the expectation. |
| 451 | |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 452 | # Theory of Operations |
| 453 | |
| 454 | ## Block Diagram |
| 455 | |
| 456 |  |
| 457 | |
| 458 | ## Hardware Interfaces |
| 459 | |
Philipp Wagner | e520362 | 2021-03-15 19:59:09 +0000 | [diff] [blame] | 460 | {{< incGenFromIpDesc "../data/otbn.hjson" "hwcfg" >}} |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 461 | |
Philipp Wagner | 8a19191 | 2021-07-15 18:08:07 +0100 | [diff] [blame] | 462 | ### Hardware Interface Requirements |
| 463 | |
| 464 | OTBN connects to other components in an OpenTitan system. |
| 465 | This section lists requirements on those interfaces that go beyond the physical connectivity. |
| 466 | |
| 467 | #### Entropy Distribution Network (EDN) |
| 468 | |
| 469 | OTBN has two EDN connections: `edn_urnd` and `edn_rnd`. |
| 470 | What kind of randomness is provided on the EDN connections is configurable at runtime, but unknown to OTBN. |
| 471 | To maintain its security properties, OTBN requires the following configuration for the two EDN connections: |
| 472 | |
| 473 | * OTBN has no specific requirements on the randomness drawn from `edn_urnd`. |
| 474 | For performance reasons, requests on this EDN connection should be answered quickly. |
| 475 | * `edn_rnd` must provide AIS31-compliant class PTG.3 random numbers. |
| 476 | The randomness from this interface is made available through the `RND` WSR and intended to be used for key generation. |
| 477 | |
Philipp Wagner | dc5b9a9 | 2021-05-07 15:03:47 +0100 | [diff] [blame] | 478 | ## Design Details {#design-details} |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 479 | |
Philipp Wagner | 58a124d | 2021-01-14 16:34:25 +0000 | [diff] [blame] | 480 | ### Memories |
| 481 | |
| 482 | The OTBN processor core has access to two dedicated memories: an instruction memory (IMEM), and a data memory (DMEM). |
| 483 | Each memory is 4 kiB in size. |
| 484 | |
| 485 | The memory layout follows the Harvard architecture. |
| 486 | Both memories are byte-addressed, with addresses starting at 0. |
| 487 | |
| 488 | The instruction memory (IMEM) is 32b wide and provides the instruction stream to the OTBN processor. |
| 489 | It cannot be read from or written to by user code through load or store instructions. |
| 490 | |
| 491 | The data memory (DMEM) is 256b wide and read-write accessible from the base and big number instruction subsets of the OTBN processor core. |
| 492 | There are four instructions that can access data memory. |
Philipp Wagner | 00fccb1 | 2021-07-20 14:37:58 +0100 | [diff] [blame] | 493 | In the base instruction subset, there are {{< otbnInsnRef "LW" >}} (load word) and {{< otbnInsnRef "SW" >}} (store word). |
Philipp Wagner | 58a124d | 2021-01-14 16:34:25 +0000 | [diff] [blame] | 494 | These access 32b-aligned 32b words. |
Philipp Wagner | 00fccb1 | 2021-07-20 14:37:58 +0100 | [diff] [blame] | 495 | In the big number instruction subset, there are {{< otbnInsnRef "BN.LID" >}} (load indirect) and {{< otbnInsnRef "BN.SID" >}} (store indirect). |
Philipp Wagner | 58a124d | 2021-01-14 16:34:25 +0000 | [diff] [blame] | 496 | These access 256b-aligned 256b words. |
| 497 | |
| 498 | Both memories can be accessed through OTBN's register interface ({{< regref "DMEM" >}} and {{< regref "IMEM" >}}). |
| 499 | These accesses are ignored if OTBN is busy. |
| 500 | A host processor can check whether OTBN is busy by reading the {{< regref "STATUS.busy">}} flag. |
| 501 | All memory accesses through the register interface must be word-aligned 32b word accesses. |
| 502 | |
Greg Chadwick | bd9c77e | 2021-03-05 16:15:16 +0000 | [diff] [blame] | 503 | ### Random Numbers |
| 504 | |
| 505 | OTBN is connected to the [Entropy Distribution Network (EDN)]({{< relref "hw/ip/edn/doc" >}}) which can provide random numbers via the `RND` and `URND` CSRs and WSRs. |
| 506 | |
Philipp Wagner | 8a19191 | 2021-07-15 18:08:07 +0100 | [diff] [blame] | 507 | `RND` provides bits taken directly from the EDN connected via `edn_rnd`. |
Greg Chadwick | bd9c77e | 2021-03-05 16:15:16 +0000 | [diff] [blame] | 508 | As an EDN request can take time, `RND` is backed by a single-entry cache containing the result of the most recent EDN request. |
| 509 | A read from `RND` empties this cache. |
| 510 | A prefetch into the cache, which can be used to hide the EDN latency, is triggered on any write to the `RND_PREFETCH` CSR. |
| 511 | Writes to `RND_PREFETCH` will be ignored whilst a prefetch is in progress or when the cache is already full. |
| 512 | OTBN will stall until the request provides bits. |
| 513 | Both the `RND` CSR and WSR take their bits from the same cache. |
| 514 | `RND` CSR reads simply discard the other 192 bits on a read. |
Philipp Wagner | 8a19191 | 2021-07-15 18:08:07 +0100 | [diff] [blame] | 515 | When stalling on an `RND` read, OTBN will unstall on the cycle after it receives WLEN RND data from the EDN. |
Greg Chadwick | bd9c77e | 2021-03-05 16:15:16 +0000 | [diff] [blame] | 516 | |
Philipp Wagner | 8a19191 | 2021-07-15 18:08:07 +0100 | [diff] [blame] | 517 | `URND` provides bits from an LFSR within OTBN; reads from it never stall. |
| 518 | The `URND` LFSR is seeded once from the EDN connected via `edn_urnd` when OTBN starts execution. |
Greg Chadwick | bd9c77e | 2021-03-05 16:15:16 +0000 | [diff] [blame] | 519 | Each new execution of OTBN will reseed the `URND` LFSR. |
| 520 | The LFSR state is advanced every cycle when OTBN is running. |
| 521 | |
Philipp Wagner | dc5b9a9 | 2021-05-07 15:03:47 +0100 | [diff] [blame] | 522 | ### Error Handling and Reporting {#design-details-error-handling-and-reporting} |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 523 | |
Philipp Wagner | 1d6ca47 | 2021-07-22 16:41:11 +0100 | [diff] [blame] | 524 | OTBN is able to detect a range of errors. |
| 525 | Whenever an error is detected, OTBN reacts locally, and informs the OpenTitan system about it by raising an alert. |
| 526 | OTBN generally does not try to recover from errors, and provides no error handling support to code that runs on it. |
Rupert Swarbrick | b184865 | 2020-11-23 17:03:33 +0000 | [diff] [blame] | 527 | |
Philipp Wagner | 1d6ca47 | 2021-07-22 16:41:11 +0100 | [diff] [blame] | 528 | OTBN classifies errors as either *recoverable* or *fatal*. |
| 529 | Errors which could be caused by a programmer's mistake are typically considered recoverable, while errors which are unlikely or impossible to result from a programmer's mistake are considered fatal. |
| 530 | The description of the {{< regref "ERR_BITS" >}} register lists all possible error causes; those prefixed with `fatal_` are fatal errors. |
Rupert Swarbrick | b184865 | 2020-11-23 17:03:33 +0000 | [diff] [blame] | 531 | |
Philipp Wagner | 1d6ca47 | 2021-07-22 16:41:11 +0100 | [diff] [blame] | 532 | Recoverable errors terminate the currently active OTBN operation and return control to the host CPU. |
| 533 | Fatal errors render OTBN unusable until it is reset. |
| 534 | |
| 535 | ### Recoverable Errors {#design-details-recoverable-errors} |
| 536 | |
| 537 | Recoverable errors can be the result of a programming error in OTBN software. |
| 538 | Recoverable errors can only occur during the execution of software on OTBN, and not in other situations in which OTBN might be busy. |
| 539 | |
| 540 | The following actions are taken when OTBN detects a recoverable error: |
| 541 | |
| 542 | 1. The currently running operation is terminated, similar to the way an {{< otbnInsnRef "ECALL" >}} instruction [is executed](#writing-otbn-applications-ecall): |
| 543 | - No more instructions are fetched or executed. |
| 544 | - A [secure wipe of internal state](#design-details-secure-wipe-internal) is performed. |
| 545 | - The {{< regref "ERR_BITS" >}} register is set to a non-zero value that describes the error. |
| 546 | - The current operation is marked as complete by setting {{< regref "INTR_STATE.done" >}} and clearing {{< regref "STATUS.busy" >}}. |
| 547 | 2. A [recoverable alert]({{< relref "#alerts" >}}) is raised. |
| 548 | |
| 549 | The host software can start another operation on OTBN after a recoverable error was detected. |
| 550 | |
| 551 | ### Fatal Errors {#design-details-fatal-errors} |
| 552 | |
| 553 | Fatal errors are generally seen as a sign of an intrusion, resulting in more drastic measures to protect the secrets stored within OTBN. |
| 554 | Fatal errors can occur at any time, even when an OTBN operation isn't in progress. |
| 555 | |
| 556 | The following actions are taken when OTBN detects a fatal error: |
| 557 | |
| 558 | 1. A [secure wipe of the data memory](#design-details-secure-wipe-dmem) and a [secure wipe of the instruction memory](#design-details-secure-wipe-imem) is initiated. |
| 559 | 2. If OTBN is busy, as indicated by {{< regref "STATUS.busy" >}}, then the currently running operation is terminated, similarly to how an operation ends after an {{< otbnInsnRef "ECALL" >}} instruction [is executed](#writing-otbn-applications-ecall): |
| 560 | - No more instructions are fetched or executed. |
| 561 | - A [secure wipe of internal state](#design-details-secure-wipe-internal) is performed. |
| 562 | - The {{< regref "ERR_BITS" >}} register is set to a non-zero value that describes the error. |
| 563 | - The current operation is marked as completed by setting {{< regref "INTR_STATE.done" >}} and clearing {{< regref "STATUS.busy" >}}. |
| 564 | 3. A [fatal alert]({{< relref "#alerts" >}}) is raised. |
Rupert Swarbrick | b184865 | 2020-11-23 17:03:33 +0000 | [diff] [blame] | 565 | |
| 566 | Note that OTBN can detect some errors even when it isn't running. |
Philipp Wagner | 37b4126 | 2021-07-20 12:11:43 +0100 | [diff] [blame] | 567 | One example of this is an error caused by an integrity error when reading or writing OTBN's memories over the bus. |
Greg Chadwick | 5ce1cb7 | 2021-01-13 14:20:48 +0000 | [diff] [blame] | 568 | In this case, the {{< regref "ERR_BITS" >}} register will not change. |
Rupert Swarbrick | b184865 | 2020-11-23 17:03:33 +0000 | [diff] [blame] | 569 | This avoids race conditions with the host processor's error handling software. |
Philipp Wagner | 1d6ca47 | 2021-07-22 16:41:11 +0100 | [diff] [blame] | 570 | However, every error that OTBN detects when it isn't running is fatal. |
Philipp Wagner | 07494a3 | 2021-03-18 15:59:57 +0000 | [diff] [blame] | 571 | This means that the cause will be reflected in {{< regref "FATAL_ALERT_CAUSE" >}}, as described below in [Alerts]({{< relref "#alerts" >}}). |
Rupert Swarbrick | b184865 | 2020-11-23 17:03:33 +0000 | [diff] [blame] | 572 | This way, no alert is generated without setting an error code somewhere. |
| 573 | |
Rupert Swarbrick | b184865 | 2020-11-23 17:03:33 +0000 | [diff] [blame] | 574 | ### Alerts |
| 575 | |
| 576 | OTBN has two alerts, one recoverable and one fatal. |
Greg Chadwick | 5ce1cb7 | 2021-01-13 14:20:48 +0000 | [diff] [blame] | 577 | The {{< regref "ERR_BITS" >}} register documentation has a detailed list of error conditions, those with 'fatal' in the name raise a **fatal alert**, otherwise they raise a **recoverable alert**. |
Rupert Swarbrick | b184865 | 2020-11-23 17:03:33 +0000 | [diff] [blame] | 578 | |
Philipp Wagner | 1d6ca47 | 2021-07-22 16:41:11 +0100 | [diff] [blame] | 579 | A **recoverable alert** is a one-time triggered alert caused by [recoverable errors](#design-details-recoverable-errors). |
Greg Chadwick | 5ce1cb7 | 2021-01-13 14:20:48 +0000 | [diff] [blame] | 580 | The error that caused the alert can be determined by reading the {{< regref "ERR_BITS" >}} register. |
Rupert Swarbrick | b184865 | 2020-11-23 17:03:33 +0000 | [diff] [blame] | 581 | |
Philipp Wagner | 1d6ca47 | 2021-07-22 16:41:11 +0100 | [diff] [blame] | 582 | A **fatal alert** is a continuously triggered alert caused by [fatal errors](#design-details-fatal-errors). |
Rupert Swarbrick | b184865 | 2020-11-23 17:03:33 +0000 | [diff] [blame] | 583 | The error that caused the alert can be determined by reading the {{< regref "FATAL_ALERT_CAUSE" >}} register. |
Greg Chadwick | 5ce1cb7 | 2021-01-13 14:20:48 +0000 | [diff] [blame] | 584 | If OTBN was running, this value will also be reflected in the {{< regref "ERR_BITS" >}} register. |
Rupert Swarbrick | b184865 | 2020-11-23 17:03:33 +0000 | [diff] [blame] | 585 | A fatal alert can only be cleared by resetting OTBN through the `rst_ni` line. |
Rupert Swarbrick | 234b434 | 2020-08-10 11:24:53 +0100 | [diff] [blame] | 586 | |
Philipp Wagner | 0d6e82b | 2021-07-22 16:44:48 +0100 | [diff] [blame] | 587 | ### Reaction to Life Cycle Escalation Requests |
| 588 | |
| 589 | OTBN receives and reacts to escalation signals from the [life cycle controller]({{< relref "/hw/ip/lc_ctrl/doc#security-escalation" >}}). |
Philipp Wagner | c74ba0a | 2021-08-23 12:56:11 +0200 | [diff] [blame] | 590 | An incoming life cycle escalation is a fatal error of type `lifecycle_escalation` and treated as described in the section [Fatal Errors](#design-details-fatal-errors). |
Philipp Wagner | 0d6e82b | 2021-07-22 16:44:48 +0100 | [diff] [blame] | 591 | |
Rupert Swarbrick | da490e7 | 2021-03-25 08:29:42 +0000 | [diff] [blame] | 592 | ### Idle |
| 593 | |
| 594 | OTBN exposes a single-bit `idle_o` signal, intended to be used by the clock manager to clock-gate the block when it is not in use. |
Rupert Swarbrick | 710e3c9 | 2021-07-13 15:28:59 +0100 | [diff] [blame] | 595 | This signal is in the same clock domain as `clk_i`. |
| 596 | It is high when OTBN is not running. |
Rupert Swarbrick | da490e7 | 2021-03-25 08:29:42 +0000 | [diff] [blame] | 597 | The cycle after a write to {{< regref "CMD.start" >}}, the signal goes low. |
Philipp Wagner | 00fccb1 | 2021-07-20 14:37:58 +0100 | [diff] [blame] | 598 | This remains low until the end of the operation (either from an {{< otbnInsnRef "ECALL" >}}) or an error, at which point it goes high again. |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 599 | |
Rupert Swarbrick | 710e3c9 | 2021-07-13 15:28:59 +0100 | [diff] [blame] | 600 | OTBN also exposes another version of the idle signal as `idle_otp_o`. |
| 601 | This works analogously, but is in the same clock domain as `clk_otp_i`. |
| 602 | |
| 603 | TODO: Specify interactions between `idle_o`, `idle_otp_o` and the clock manager fully. |
| 604 | |
Philipp Wagner | dc5b9a9 | 2021-05-07 15:03:47 +0100 | [diff] [blame] | 605 | ### Data Integrity Protection {#design-details-data-integrity-protection} |
| 606 | |
| 607 | OTBN stores and operates on data (state) in its dedicated memories, register files, and internal registers. |
Philipp Wagner | aaf132f | 2021-05-11 22:54:41 +0100 | [diff] [blame] | 608 | OTBN's data integrity protection is designed to protect all data stored and transmitted within OTBN from modifications through physical attacks. |
Philipp Wagner | dc5b9a9 | 2021-05-07 15:03:47 +0100 | [diff] [blame] | 609 | |
| 610 | During transmission, the integrity of data is protected with an integrity protection code. |
| 611 | Data at rest in the instruction and data memories is additionally scrambled. |
| 612 | |
| 613 | In the following, the Integrity Protection Code and the scrambling algorithm are discussed, followed by their application to individual storage elements. |
| 614 | |
| 615 | #### Integrity Protection Code {#design-details-integrity-protection-code} |
| 616 | |
| 617 | OTBN uses the same integrity protection code everywhere to provide overarching data protection without regular re-encoding. |
| 618 | The code is applied to 32b data words, and produces 39b of encoded data. |
| 619 | |
| 620 | The code used is an (39,32) Hsiao "single error correction, double error detection" (SECDED) error correction code (ECC) [[CHEN08]({{< relref "#ref-chen08">}})]. |
| 621 | It has a minimum Hamming distance of four, resulting in the ability to detect at least three errors in a 32 bit word. |
| 622 | The code is used for error detection only; no error correction is performed. |
| 623 | |
| 624 | #### Memory Scrambling {#design-details-memory-scrambling} |
| 625 | |
| 626 | Contents of OTBN's instruction and data memories are scrambled while at rest. |
Philipp Wagner | aaf132f | 2021-05-11 22:54:41 +0100 | [diff] [blame] | 627 | The data is bound to the address and scrambled before being stored in memory. |
| 628 | The addresses are randomly remapped. |
Philipp Wagner | dc5b9a9 | 2021-05-07 15:03:47 +0100 | [diff] [blame] | 629 | |
| 630 | Note that data stored in other temporary memories within OTBN, including the register files, is not scrambled. |
| 631 | |
| 632 | Scrambling is used to obfuscate the memory contents and to diffuse the data. |
| 633 | Obfuscation makes passive probing more difficult, while diffusion makes active fault injection attacks more difficult. |
| 634 | |
| 635 | The scrambling mechanism is described in detail in the [section "Scrambling Primitive" of the SRAM Controller Technical Specification](/hw/ip/sram_ctrl/doc/#scrambling-primitive). |
| 636 | |
Philipp Wagner | aaf132f | 2021-05-11 22:54:41 +0100 | [diff] [blame] | 637 | The scrambling keys are rotated regularly, refer to the sections below for more details. |
| 638 | |
Philipp Wagner | dc5b9a9 | 2021-05-07 15:03:47 +0100 | [diff] [blame] | 639 | #### Actions on Integrity Errors |
| 640 | |
| 641 | A fatal error is raised whenever a data integrity violation is detected, which results in an immediate stop of all processing and the issuing of a fatal alert. |
| 642 | The section [Error Handling and Reporting]({{< relref "#design-details-error-handling-and-reporting" >}}) describes the error handling in more detail. |
| 643 | |
| 644 | #### Register File Integrity Protection |
| 645 | |
| 646 | OTBN contains two register files: the 32b GPRs and the 256b WDRs. |
| 647 | The data stored in both register files is protected with the [Integrity Protection Code]({{< relref "#design-details-integrity-protection-code">}}). |
| 648 | Neither the register file contents nor register addresses are scrambled. |
| 649 | |
| 650 | The GPRs `x2` to `x31` store a 32b data word together with the Integrity Protection Code, resulting in 39b of stored data. |
| 651 | (`x0`, the zero register, and `x1`, the call stack, require special treatment.) |
| 652 | |
| 653 | Each 256b Wide Data Register (WDR) stores a 256b data word together with the Integrity Protection Code, resulting in 312b of stored data. |
| 654 | The integrity protection is done separately for each of the eight 32b sub-words within a 256b word. |
| 655 | |
| 656 | The register files can consume data protected with the Integrity Protection Code, or add it on demand. |
| 657 | Whenever possible the Integrity Protection Code is preserved from its source and written directly to the register files without recalculation, in particular in the following cases: |
| 658 | |
| 659 | * Data coming from the data memory (DMEM) through the load-store unit to a GPR or WDR. |
Philipp Wagner | 00fccb1 | 2021-07-20 14:37:58 +0100 | [diff] [blame] | 660 | * Data copied between WDRs using the {{< otbnInsnRef "BN.MOV" >}} or {{< otbnInsnRef "BN.MOVR" >}} instructions. |
| 661 | * Data conditionally copied between WDRs using the {{< otbnInsnRef "BN.SEL" >}} instruction. |
Philipp Wagner | dc5b9a9 | 2021-05-07 15:03:47 +0100 | [diff] [blame] | 662 | * Data copied between the `ACC` and `MOD` WSRs and a WDR. |
| 663 | (TODO: Not yet implemented.) |
| 664 | * Data copied between any of the `MOD0` to `MOD7` CSRs and a GPR. |
| 665 | (TODO: Not yet implemented.) |
| 666 | |
| 667 | In all other cases the register files add the Integrity Protection Code to the incoming data before storing the data word. |
| 668 | |
| 669 | The integrity protection bits are checked on every read from the register files, even if the integrity protection is not removed from the data. |
| 670 | |
| 671 | Detected integrity violations in a register file raise a fatal `reg_error`. |
| 672 | |
Philipp Wagner | aaf132f | 2021-05-11 22:54:41 +0100 | [diff] [blame] | 673 | #### Data Memory (DMEM) Integrity Protection |
| 674 | |
| 675 | OTBN's data memory is 256b wide, but allows for 32b word accesses. |
| 676 | To facilitate such accesses, all integrity protection in the data memory is done on a 32b word granularity. |
| 677 | |
| 678 | All data entering or leaving the data memory block is protected with the [Integrity Protection Code]({{< relref "#design-details-integrity-protection-code">}}); |
| 679 | this code is not re-computed within the memory block. |
| 680 | |
| 681 | Before being stored in SRAM, the data word with the attached Integrity Protection Code, as well as the address are scrambled according to the [memory scrambling algorithm]({{< relref "#design-details-memory-scrambling">}}). |
| 682 | The scrambling is reversed on a read. |
| 683 | |
| 684 | The ephemeral memory scrambling key and the nonce are provided by the [OTP block]({{<relref "/hw/ip/otp_ctrl/doc" >}}). |
Vladimir Rozic | e76ca1f | 2021-07-12 14:06:00 +0100 | [diff] [blame] | 685 | They are set once when OTBN block is reset, and changed whenever a [secure wipe]({{<relref "#design-details-secure-wipe-dmem">}}) of the data memory is performed. |
| 686 | |
Philipp Wagner | aaf132f | 2021-05-11 22:54:41 +0100 | [diff] [blame] | 687 | |
| 688 | The Integrity Protection Code is checked on every memory read, even though the code remains attached to the data. |
| 689 | A further check must be performed when the data is consumed. |
| 690 | Detected integrity violations in the data memory raise a fatal `dmem_error`. |
| 691 | |
| 692 | #### Instruction Memory (IMEM) Integrity Protection |
| 693 | |
| 694 | All data entering or leaving the instruction memory block is protected with the [Integrity Protection Code]({{< relref "#design-details-integrity-protection-code">}}); |
| 695 | this code is not re-computed within the memory block. |
| 696 | |
| 697 | Before being stored in SRAM, the instruction word with the attached Integrity Protection Code, as well as the address are scrambled according to the [memory scrambling algorithm]({{< relref "#design-details-memory-scrambling">}}). |
| 698 | The scrambling is reversed on a read. |
| 699 | |
| 700 | The ephemeral memory scrambling key and the nonce are provided by the [OTP block]({{<relref "/hw/ip/otp_ctrl/doc" >}}). |
Vladimir Rozic | e76ca1f | 2021-07-12 14:06:00 +0100 | [diff] [blame] | 701 | They are set once when OTBN block is reset, and changed whenever a [secure wipe]({{<relref "#design-details-secure-wipe-imem">}}) of the instruction memory is performed. |
Philipp Wagner | aaf132f | 2021-05-11 22:54:41 +0100 | [diff] [blame] | 702 | |
| 703 | The Integrity Protection Code is checked on every memory read, even though the code remains attached to the data. |
| 704 | A further check must be performed when the data is consumed. |
| 705 | Detected integrity violations in the data memory raise a fatal `imem_error`. |
| 706 | |
Vladimir Rozic | e76ca1f | 2021-07-12 14:06:00 +0100 | [diff] [blame] | 707 | ### Secure Wipe {#design-details-secure-wipe} |
| 708 | |
Vladimir Rozic | 630526c | 2021-07-27 14:42:18 +0100 | [diff] [blame] | 709 | Applications running on OTBN may store sensitive data in the internal registers or the memory. |
| 710 | In order to prevent an untrusted application from reading any leftover data, OTBN provides the secure wipe operation. |
| 711 | This operation can be applied to: |
| 712 | - [Data memory]({{<relref "#design-details-secure-wipe-dmem">}}) |
| 713 | - [Instruction memory]({{<relref "#design-details-secure-wipe-imem">}}) |
| 714 | - [Internal state]({{<relref "#design-details-secure-wipe-internal">}}) |
| 715 | |
| 716 | Secure wipe of data and instruction memories can be triggered on demand from a host software. |
Vladimir Rozic | e76ca1f | 2021-07-12 14:06:00 +0100 | [diff] [blame] | 717 | In addition, full or partial secure wipe is triggered automatically by the OTBN in certain situations. |
| 718 | |
Philipp Wagner | 1d6ca47 | 2021-07-22 16:41:11 +0100 | [diff] [blame] | 719 | OTBN does not signal any error while a secure wipe operation is in progress. |
| 720 | |
Vladimir Rozic | e76ca1f | 2021-07-12 14:06:00 +0100 | [diff] [blame] | 721 | #### Triggering Secure Wipe |
| 722 | |
| 723 | In the following situations OTBN itself initiates a full secure wipe: |
| 724 | * The lifecycle controller asks for it through its escalation signal. |
| 725 | * A fatal alert is issued. |
| 726 | In this case, a full secure wipe is performed as a local action. |
| 727 | |
| 728 | The internal state secure wipe is automatically triggered when an OTBN operation completes, either successfully, or unsuccessfully due to a recoverable error. |
| 729 | |
Vladimir Rozic | 630526c | 2021-07-27 14:42:18 +0100 | [diff] [blame] | 730 | Host software can trigger a data and instruction memory secure wipe by writing `2'b11` to {{< regref "SEC_WIPE">}} (i.e. by setting both individual state wipe bits to 1). |
Vladimir Rozic | e76ca1f | 2021-07-12 14:06:00 +0100 | [diff] [blame] | 731 | |
| 732 | #### Completion of Secure Wipe {#design-details-secure-wipe-completion} |
| 733 | |
| 734 | During the secure wipe operation the {{< regref "STATUS.busy">}} flag is set to 1, indicating that the OTBN is busy. |
Vladimir Rozic | 630526c | 2021-07-27 14:42:18 +0100 | [diff] [blame] | 735 | Once the operation is completed, an {{< regref "INTR_STATE.done" >}} interrupt is raised and {{< regref "STATUS.busy">}} is cleared. |
Vladimir Rozic | e76ca1f | 2021-07-12 14:06:00 +0100 | [diff] [blame] | 736 | This effectively means that the host software will get a single done interrupt for a secure wipe operation, independent of how many SEC_WIPE bits the software wrote. |
| 737 | |
| 738 | #### Data Memory (DMEM) Secure Wipe {#design-details-secure-wipe-dmem} |
| 739 | |
| 740 | The wiping is performed by securely replacing the memory scrambling key, making all data stored in the memory unusable. |
| 741 | The key replacement is a two-step process: |
| 742 | |
| 743 | * Overwrite the 128b key of the memory scrambling primitive with randomness from URND. |
| 744 | This action takes a single cycle. |
| 745 | * Request new scrambling parameters from OTP. |
| 746 | The request takes multiple cycles to complete. |
| 747 | |
| 748 | Host software can initiate a data memory secure wipe by writing 1 to the {{< regref "SEC_WIPE.dmem">}} register field. |
Philipp Wagner | 1d6ca47 | 2021-07-22 16:41:11 +0100 | [diff] [blame] | 749 | If a secure wipe was triggered in this way, [completion]({{<relref "#design-details-secure-wipe-completion">}}) is signaled by raising an {{< regref "INTR_STATE.done" >}} interrupt. |
Vladimir Rozic | e76ca1f | 2021-07-12 14:06:00 +0100 | [diff] [blame] | 750 | |
| 751 | #### Instruction Memory (IMEM) Secure Wipe {#design-details-secure-wipe-imem} |
| 752 | |
| 753 | The wiping is performed by securely replacing the memory scrambling key, making all instructions stored in the memory unusable. |
| 754 | The key replacement is a two-step process: |
| 755 | |
| 756 | * Overwrite the 128b key of the memory scrambling primitive with randomness from URND. |
| 757 | This action takes a single cycle. |
| 758 | * Request new scrambling parameters from OTP. |
| 759 | The request takes multiple cycles to complete. |
| 760 | |
| 761 | Host software can initiate an instruction memory secure wipe by writing 1 to the {{< regref "SEC_WIPE.imem">}} register field. |
Philipp Wagner | 1d6ca47 | 2021-07-22 16:41:11 +0100 | [diff] [blame] | 762 | If a secure wipe was triggered in this way, [completion]({{<relref "#design-details-secure-wipe-completion">}}) is signaled by raising an {{< regref "INTR_STATE.done" >}} interrupt. |
Vladimir Rozic | e76ca1f | 2021-07-12 14:06:00 +0100 | [diff] [blame] | 763 | |
| 764 | #### Internal State Secure Wipe {#design-details-secure-wipe-internal} |
| 765 | |
| 766 | OTBN provides a mechanism to securely wipe all internal state, excluding the instruction and data memories. |
| 767 | |
| 768 | The following state is wiped: |
| 769 | * Register files: GPRs and WDRs |
| 770 | * The accumulator register (also accessible through the ACC WSR) |
| 771 | * Flags (accessible through the FG0, FG1, and FLAGS CSRs) |
| 772 | * The modulus (accessible through the MOD0 to MOD7 CSRs and the MOD WSR) |
| 773 | |
| 774 | The wiping procedure is a two-step process: |
| 775 | * Overwrite the state with randomness from URND. |
| 776 | * Overwrite the state with zeros. |
| 777 | |
| 778 | Loop and call stack pointers are reset. |
| 779 | |
| 780 | Host software can initiate an internal state secure wipe by writing 1 to the {{< regref "SEC_WIPE.internal">}} register field. |
Philipp Wagner | 1d6ca47 | 2021-07-22 16:41:11 +0100 | [diff] [blame] | 781 | If a secure wipe was triggered in this way, [completion]({{<relref "#design-details-secure-wipe-completion">}}) is signaled by raising an {{< regref "INTR_STATE.done" >}} interrupt. |
Vladimir Rozic | e76ca1f | 2021-07-12 14:06:00 +0100 | [diff] [blame] | 782 | |
Philipp Wagner | 58a124d | 2021-01-14 16:34:25 +0000 | [diff] [blame] | 783 | # Running applications on OTBN |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 784 | |
Philipp Wagner | 58a124d | 2021-01-14 16:34:25 +0000 | [diff] [blame] | 785 | OTBN is a specialized coprocessor which is used from the host CPU. |
| 786 | This section describes how to interact with OTBN from the host CPU to execute an existing OTBN application. |
| 787 | The section [Writing OTBN applications]({{< ref "#writing-otbn-applications" >}}) describes how to write such applications. |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 788 | |
Philipp Wagner | 58a124d | 2021-01-14 16:34:25 +0000 | [diff] [blame] | 789 | ## High-level operation sequence |
Philipp Wagner | e2bf04d | 2020-07-27 11:07:41 +0100 | [diff] [blame] | 790 | |
Philipp Wagner | 58a124d | 2021-01-14 16:34:25 +0000 | [diff] [blame] | 791 | The high-level sequence by which the host processor should use OTBN is as follows. |
Philipp Wagner | e2bf04d | 2020-07-27 11:07:41 +0100 | [diff] [blame] | 792 | |
Philipp Wagner | 58a124d | 2021-01-14 16:34:25 +0000 | [diff] [blame] | 793 | 1. Write the OTBN application binary to {{< regref "IMEM" >}}, starting at address 0. |
| 794 | 2. Optional: Write constants and input arguments, as mandated by the calling convention of the loaded application, to {{< regref "DMEM" >}}. |
| 795 | 3. Start the operation on OTBN by writing `1` to {{< regref "CMD.start" >}}. |
| 796 | Now neither data nor instruction memory may be accessed from the host CPU. |
| 797 | After it has been started the OTBN application runs to completion without further interaction with the host. |
| 798 | 4. Wait for the operation to complete (see below). |
| 799 | As soon as the OTBN operation has completed the data and instruction memories can be accessed again from the host CPU. |
Greg Chadwick | 5ce1cb7 | 2021-01-13 14:20:48 +0000 | [diff] [blame] | 800 | 5. Check if the operation was successful by reading the {{< regref "ERR_BITS" >}} register. |
Philipp Wagner | 58a124d | 2021-01-14 16:34:25 +0000 | [diff] [blame] | 801 | 6. Optional: Retrieve results by reading {{< regref "DMEM" >}}, as mandated by the calling convention of the loaded application. |
Philipp Wagner | e2bf04d | 2020-07-27 11:07:41 +0100 | [diff] [blame] | 802 | |
Philipp Wagner | 58a124d | 2021-01-14 16:34:25 +0000 | [diff] [blame] | 803 | OTBN applications are run to completion. |
| 804 | The host CPU can determine if an application has completed by either polling {{< regref "STATUS.busy">}} or listening for an interrupt. |
Philipp Wagner | e2bf04d | 2020-07-27 11:07:41 +0100 | [diff] [blame] | 805 | |
Philipp Wagner | 58a124d | 2021-01-14 16:34:25 +0000 | [diff] [blame] | 806 | * To poll for a completed operation, software should repeatedly read the {{< regref "STATUS.busy" >}} register. |
| 807 | While the operation is in progress, {{< regref "STATUS.busy" >}} reads as `1`. |
| 808 | The operation is completed if {{< regref "STATUS.busy" >}} is `0`. |
| 809 | * Alternatively, software can listen for the `done` interrupt to determine if the operation has completed. |
| 810 | The standard sequence of working with interrupts has to be followed, i.e. the interrupt has to be enabled, an interrupt service routine has to be registered, etc. |
| 811 | The [DIF]({{<relref "#dif" >}}) contains helpers to do so conveniently. |
Philipp Wagner | e2bf04d | 2020-07-27 11:07:41 +0100 | [diff] [blame] | 812 | |
Philipp Wagner | 58a124d | 2021-01-14 16:34:25 +0000 | [diff] [blame] | 813 | Note: This operation sequence only covers functional aspects. |
| 814 | Depending on the application additional steps might be necessary, such as deleting secrets from the memories. |
Philipp Wagner | 70e0642 | 2020-10-14 14:36:09 +0200 | [diff] [blame] | 815 | |
Philipp Wagner | 58a124d | 2021-01-14 16:34:25 +0000 | [diff] [blame] | 816 | ## Device Interface Functions (DIFs) {#dif} |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 817 | |
Philipp Wagner | 58a124d | 2021-01-14 16:34:25 +0000 | [diff] [blame] | 818 | {{< dif_listing "sw/device/lib/dif/dif_otbn.h" >}} |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 819 | |
Philipp Wagner | 58a124d | 2021-01-14 16:34:25 +0000 | [diff] [blame] | 820 | ## Driver {#driver} |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 821 | |
Philipp Wagner | 58a124d | 2021-01-14 16:34:25 +0000 | [diff] [blame] | 822 | A higher-level driver for the OTBN block is available at `sw/device/lib/runtime/otbn.h` ([API documentation](/sw/apis/otbn_8h.html)). |
| 823 | |
| 824 | ## Register Table |
| 825 | |
Philipp Wagner | e520362 | 2021-03-15 19:59:09 +0000 | [diff] [blame] | 826 | {{< incGenFromIpDesc "../data/otbn.hjson" "registers" >}} |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 827 | |
Philipp Wagner | 58a124d | 2021-01-14 16:34:25 +0000 | [diff] [blame] | 828 | # Writing OTBN applications {#writing-otbn-applications} |
Philipp Wagner | 6562f98 | 2020-12-02 09:45:14 +0000 | [diff] [blame] | 829 | |
Philipp Wagner | 58a124d | 2021-01-14 16:34:25 +0000 | [diff] [blame] | 830 | OTBN applications are (small) pieces of software written in OTBN assembly. |
Philipp Wagner | 07494a3 | 2021-03-18 15:59:57 +0000 | [diff] [blame] | 831 | The full instruction set is described in the [ISA manual]({{< relref "isa" >}}), and example software is available in the `sw/otbn` directory of the OpenTitan source tree. |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 832 | |
Philipp Wagner | 58a124d | 2021-01-14 16:34:25 +0000 | [diff] [blame] | 833 | A hands-on user guide to develop OTBN software can be found in the section [Writing and building software for OTBN]({{<relref "doc/ug/otbn_sw.md" >}}). |
| 834 | |
| 835 | ## Toolchain support |
| 836 | |
| 837 | OTBN comes with a toolchain consisting of an assembler, a linker, and helper tools such as objdump. |
| 838 | The toolchain wraps a RV32 GCC toolchain and supports many of its features. |
| 839 | |
| 840 | The following tools are available: |
| 841 | * `otbn-as`: The OTBN assembler. |
| 842 | * `otbn-ld`: The OTBN linker. |
| 843 | * `otbn-objdump`: objdump for OTBN. |
| 844 | |
| 845 | Other tools from the RV32 toolchain can be used directly, such as objcopy. |
| 846 | |
| 847 | ## Passing of data between the host CPU and OTBN {#writing-otbn-applications-datapassing} |
| 848 | |
| 849 | Passing data between the host CPU and OTBN is done through the data memory (DMEM). |
| 850 | No standard or required calling convention exists, every application is free to pass data in and out of OTBN in whatever format it finds convenient. |
| 851 | All data passing must be done when OTBN is not running, as indicated by the {{< regref "STATUS.busy" >}} bit; during the OTBN operation both the instruction and the data memory are inaccessible from the host CPU. |
| 852 | |
Philipp Wagner | 19aa501 | 2021-07-22 17:54:15 +0100 | [diff] [blame] | 853 | ## Returning from an application {#writing-otbn-applications-ecall} |
Philipp Wagner | 58a124d | 2021-01-14 16:34:25 +0000 | [diff] [blame] | 854 | |
Philipp Wagner | 00fccb1 | 2021-07-20 14:37:58 +0100 | [diff] [blame] | 855 | The software running on OTBN signals completion by executing the {{< otbnInsnRef "ECALL" >}} instruction. |
Philipp Wagner | 58a124d | 2021-01-14 16:34:25 +0000 | [diff] [blame] | 856 | |
Philipp Wagner | 19aa501 | 2021-07-22 17:54:15 +0100 | [diff] [blame] | 857 | Once OTBN has executed the {{< otbnInsnRef "ECALL" >}} instruction, the following things happen: |
| 858 | |
| 859 | - No more instructions are fetched or executed. |
| 860 | - A [secure wipe of internal state](#design-details-secure-wipe-internal) is performed. |
| 861 | - The {{< regref "ERR_BITS" >}} register is set to 0, indicating a successful operation. |
| 862 | - The current operation is marked as completed by setting {{< regref "INTR_STATE.done" >}} and clearing {{< regref "STATUS.busy" >}}. |
Philipp Wagner | 58a124d | 2021-01-14 16:34:25 +0000 | [diff] [blame] | 863 | |
| 864 | The DMEM can be used to pass data back to the host processor, e.g. a "return value" or an "exit code". |
| 865 | Refer to the section [Passing of data between the host CPU and OTBN]({{<relref "#writing-otbn-applications-datapassing" >}}) for more information. |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 866 | |
Philipp Wagner | d011185 | 2021-03-29 14:02:26 +0100 | [diff] [blame] | 867 | ## Using hardware loops |
| 868 | |
Philipp Wagner | 00fccb1 | 2021-07-20 14:37:58 +0100 | [diff] [blame] | 869 | OTBN provides two hardware loop instructions: {{< otbnInsnRef "LOOP" >}} and {{< otbnInsnRef "LOOPI" >}}. |
Philipp Wagner | d011185 | 2021-03-29 14:02:26 +0100 | [diff] [blame] | 870 | |
| 871 | ### Loop nesting |
| 872 | |
| 873 | OTBN permits loop nesting and branches and jumps inside loops. |
| 874 | However, it doesn't have support for early termination of loops: there's no way to pop an entry from the loop stack without executing the last instruction of the loop the correct number of times. |
| 875 | It can also only pop one level of the loop stack per instruction. |
| 876 | |
| 877 | To avoid polluting the loop stack and avoid surprising behaviour, the programmer must ensure that: |
| 878 | * Even if there are branches and jumps within a loop body, the final instruction of the loop body gets executed exactly once per iteration. |
| 879 | * Nested loops have distinct end addresses. |
| 880 | * The end instruction of an outer loop is not executed before an inner loop finishes. |
| 881 | |
Philipp Wagner | 1d6ca47 | 2021-07-22 16:41:11 +0100 | [diff] [blame] | 882 | OTBN does not detect these conditions being violated, so no error will be signaled should they occur. |
Philipp Wagner | d011185 | 2021-03-29 14:02:26 +0100 | [diff] [blame] | 883 | |
| 884 | (Note indentation in the code examples is for clarity and has no functional impact.) |
| 885 | |
| 886 | The following loops are *well nested*: |
| 887 | |
| 888 | ``` |
| 889 | LOOP x2, 3 |
| 890 | LOOP x3, 1 |
| 891 | ADDI x4, x4, 1 |
| 892 | # The NOP ensures that the outer and inner loops end on different instructions |
| 893 | NOP |
| 894 | |
| 895 | # Both inner and outer loops call some_fn, which returns to |
| 896 | # the body of the loop |
| 897 | LOOP x2, 5 |
| 898 | JAL x1, some_fn |
| 899 | LOOP x3, 2 |
| 900 | JAL x1, some_fn |
| 901 | ADDI x4, x4, 1 |
| 902 | NOP |
| 903 | |
| 904 | # Control flow leaves the immediate body of the outer loop but eventually |
| 905 | # returns to it |
| 906 | LOOP x2, 4 |
| 907 | BEQ x4, x5, some_label |
| 908 | branch_back: |
| 909 | LOOP x3, 1 |
| 910 | ADDI x6, x6, 1 |
| 911 | NOP |
| 912 | |
| 913 | some_label: |
| 914 | ... |
| 915 | JAL x0, branch_back |
| 916 | ``` |
| 917 | |
| 918 | The following loops are not well nested: |
| 919 | |
| 920 | ``` |
| 921 | # Both loops end on the same instruction |
| 922 | LOOP x2, 2 |
| 923 | LOOP x3, 1 |
| 924 | ADDI x4, x4, 1 |
| 925 | |
| 926 | # Inner loop jumps into outer loop body (executing the outer loop end |
| 927 | # instruction before the inner loop has finished) |
| 928 | LOOP x2, 5 |
| 929 | LOOP x3, 3 |
| 930 | ADDI x4, x4 ,1 |
| 931 | BEQ x4, x5, outer_body |
| 932 | ADD x6, x7, x8 |
| 933 | outer_body: |
| 934 | SUBI x9, x9, 1 |
| 935 | ``` |
| 936 | |
Greg Chadwick | 5f3e97b | 2020-12-01 14:49:01 +0000 | [diff] [blame] | 937 | ## Algorithic Examples: Multiplication with BN.MULQACC |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 938 | |
Greg Chadwick | 5f3e97b | 2020-12-01 14:49:01 +0000 | [diff] [blame] | 939 | The big number instruction subset of OTBN generally operates on WLEN bit numbers. |
Philipp Wagner | 00fccb1 | 2021-07-20 14:37:58 +0100 | [diff] [blame] | 940 | {{< otbnInsnRef "BN.MULQACC" >}} operates with WLEN/4 bit operands (with a full WLEN accumulator). |
| 941 | This section outlines two techniques to perform larger multiplies by composing multiple {{< otbnInsnRef "BN.MULQACC" >}} instructions. |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 942 | |
Greg Chadwick | 5f3e97b | 2020-12-01 14:49:01 +0000 | [diff] [blame] | 943 | ### Multiplying two WLEN/2 numbers with BN.MULQACC |
| 944 | |
| 945 | This instruction sequence multiplies the lower half of `w0` by the upper half of |
| 946 | `w0` placing the result in `w1`. |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 947 | |
| 948 | ``` |
Greg Chadwick | 60138bd | 2020-08-26 13:59:49 +0100 | [diff] [blame] | 949 | BN.MULQACC.Z w0.0, w0.2, 0 |
| 950 | BN.MULQACC w0.0, w0.3, 64 |
| 951 | BN.MULQACC w0.1, w0.2, 64 |
Greg Chadwick | 5f3e97b | 2020-12-01 14:49:01 +0000 | [diff] [blame] | 952 | BN.MULQACC.WO w1, w0.1, w0.3, 128 |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 953 | ``` |
| 954 | |
Greg Chadwick | 5f3e97b | 2020-12-01 14:49:01 +0000 | [diff] [blame] | 955 | ### Multiplying two WLEN numbers with BN.MULQACC |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 956 | |
| 957 | The shift out functionality can be used to perform larger multiplications without extra adds. |
Greg Chadwick | 60138bd | 2020-08-26 13:59:49 +0100 | [diff] [blame] | 958 | The table below shows how two registers `w0` and `w1` can be multiplied together to give a result in `w2` and `w3`. |
| 959 | The cells on the right show how the result is built up `a0:a3 = w0.0:w0.3` and `b0:b3 = w1.0:w1.3`. |
| 960 | The sum of a column represents WLEN/4 bits of a destination register, where `c0:c3 = w2.0:w2.3` and `d0:d3 = w3.0:w3.3`. |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 961 | Each cell with a multiply in takes up two WLEN/4-bit columns to represent the WLEN/2-bit multiply result. |
| 962 | The current accumulator in each instruction is represented by highlighted cells where the accumulator value will be the sum of the highlighted cell and all cells above it. |
| 963 | |
| 964 | The outlined technique can be extended to arbitrary bit widths but requires unrolled code with all operands in registers. |
| 965 | |
| 966 | <table> |
| 967 | <thead> |
| 968 | <tr> |
| 969 | <th></th> |
| 970 | <th>d3</th> |
| 971 | <th>d2</th> |
| 972 | <th>d1</th> |
| 973 | <th>d0</th> |
| 974 | <th>c3</th> |
| 975 | <th>c2</th> |
| 976 | <th>c1</th> |
| 977 | <th>c0</th> |
| 978 | </tr> |
| 979 | </thead> |
| 980 | <tbody> |
| 981 | <tr> |
Greg Chadwick | 60138bd | 2020-08-26 13:59:49 +0100 | [diff] [blame] | 982 | <td><code>BN.MULQACC.Z w0.0, w1.0, 0</code></td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 983 | <td></td> |
| 984 | <td></td> |
| 985 | <td></td> |
| 986 | <td></td> |
| 987 | <td style="background-color: orange"></td> |
| 988 | <td style="background-color: orange"></td> |
| 989 | <td style="background-color: orange" colspan="2" rowspan="1"><code>a0 * b0</code></td> |
| 990 | </tr> |
| 991 | <tr> |
Greg Chadwick | 60138bd | 2020-08-26 13:59:49 +0100 | [diff] [blame] | 992 | <td><code>BN.MULQACC w0.1, w1.0, 64</code></td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 993 | <td></td> |
| 994 | <td></td> |
| 995 | <td></td> |
| 996 | <td></td> |
| 997 | <td style="background-color: orange"></td> |
| 998 | <td style="background-color: orange" colspan="2" rowspan="1"><code>a1 * b0</code></td> |
| 999 | <td style="background-color: orange"></td> |
| 1000 | </tr> |
| 1001 | <tr> |
Greg Chadwick | 60138bd | 2020-08-26 13:59:49 +0100 | [diff] [blame] | 1002 | <td><code>BN.MULQACC.SO w2.l, w0.0, w1.1, 64</code></td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 1003 | <td></td> |
| 1004 | <td></td> |
| 1005 | <td></td> |
| 1006 | <td></td> |
| 1007 | <td style="background-color: orange"></td> |
| 1008 | <td style="background-color: orange" colspan="2" rowspan="1"><code>a0 * b1</code></td> |
| 1009 | <td style="background-color: orange"></td> |
| 1010 | </tr> |
| 1011 | <tr> |
Greg Chadwick | 60138bd | 2020-08-26 13:59:49 +0100 | [diff] [blame] | 1012 | <td><code>BN.MULQACC w0.2, w1.0, 0</code></td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 1013 | <td></td> |
| 1014 | <td></td> |
| 1015 | <td style="background-color: yellow"></td> |
| 1016 | <td style="background-color: yellow"></td> |
| 1017 | <td style="background-color: yellow" colspan="2" rowspan="1"><code>a2 * b0</code></td> |
| 1018 | <td></td> |
| 1019 | <td></td> |
| 1020 | </tr> |
| 1021 | <tr> |
Greg Chadwick | 60138bd | 2020-08-26 13:59:49 +0100 | [diff] [blame] | 1022 | <td><code>BN.MULQACC w0.1, w1.1, 0</code></td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 1023 | <td></td> |
| 1024 | <td></td> |
| 1025 | <td style="background-color: yellow"></td> |
| 1026 | <td style="background-color: yellow"></td> |
| 1027 | <td style="background-color: yellow" colspan="2" rowspan="1"><code>a1 * b1</code></td> |
| 1028 | <td></td> |
| 1029 | <td></td> |
| 1030 | </tr> |
| 1031 | <tr> |
Greg Chadwick | 60138bd | 2020-08-26 13:59:49 +0100 | [diff] [blame] | 1032 | <td><code>BN.MULQACC w0.0, w1.2, 0</code></td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 1033 | <td></td> |
| 1034 | <td></td> |
| 1035 | <td style="background-color: yellow"></td> |
| 1036 | <td style="background-color: yellow"></td> |
| 1037 | <td style="background-color: yellow" colspan="2" rowspan="1"><code>a0 * b2</code></td> |
| 1038 | <td></td> |
| 1039 | <td></td> |
| 1040 | </tr> |
| 1041 | <tr> |
Greg Chadwick | 60138bd | 2020-08-26 13:59:49 +0100 | [diff] [blame] | 1042 | <td><code>BN.MULQACC w0.3, w1.0, 64</code></td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 1043 | <td></td> |
| 1044 | <td></td> |
| 1045 | <td style="background-color: yellow"></td> |
| 1046 | <td style="background-color: yellow" colspan="2" rowspan="1"><code>a3 * b0</code></td> |
| 1047 | <td style="background-color: yellow"></td> |
| 1048 | <td></td> |
| 1049 | <td></td> |
| 1050 | </tr> |
| 1051 | <tr> |
Greg Chadwick | 60138bd | 2020-08-26 13:59:49 +0100 | [diff] [blame] | 1052 | <td><code>BN.MULQACC w0.2, w1.1, 64</code></td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 1053 | <td></td> |
| 1054 | <td></td> |
| 1055 | <td style="background-color: yellow"></td> |
| 1056 | <td style="background-color: yellow" colspan="2" rowspan="1"><code>a2 * b1</code></td> |
| 1057 | <td style="background-color: yellow"></td> |
| 1058 | <td></td> |
| 1059 | <td></td> |
| 1060 | </tr> |
| 1061 | <tr> |
Greg Chadwick | 60138bd | 2020-08-26 13:59:49 +0100 | [diff] [blame] | 1062 | <td><code>BN.MULQACC w0.1, w1.2, 64</code></td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 1063 | <td></td> |
| 1064 | <td></td> |
| 1065 | <td style="background-color: yellow"></td> |
| 1066 | <td style="background-color: yellow" colspan="2" rowspan="1"><code>a1 * b2</code></td> |
| 1067 | <td style="background-color: yellow"></td> |
| 1068 | <td></td> |
| 1069 | <td></td> |
| 1070 | </tr> |
| 1071 | <tr> |
Greg Chadwick | 60138bd | 2020-08-26 13:59:49 +0100 | [diff] [blame] | 1072 | <td><code>BN.MULQACC.SO w2.u, w0.0, w1.3, 64</code></td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 1073 | <td></td> |
| 1074 | <td></td> |
| 1075 | <td style="background-color: yellow"></td> |
| 1076 | <td style="background-color: yellow" colspan="2" rowspan="1"><code>a0 * b3</code></td> |
| 1077 | <td style="background-color: yellow"></td> |
| 1078 | <td></td> |
| 1079 | <td></td> |
| 1080 | </tr> |
| 1081 | <tr> |
Greg Chadwick | 60138bd | 2020-08-26 13:59:49 +0100 | [diff] [blame] | 1082 | <td><code>BN.MULQACC w0.3, w1.1, 0</code></td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 1083 | <td style="background-color: olive"></td> |
| 1084 | <td style="background-color: olive"></td> |
| 1085 | <td style="background-color: olive" colspan="2" rowspan="1"><code>a3 * b1</code></td> |
| 1086 | <td></td> |
| 1087 | <td></td> |
| 1088 | <td></td> |
| 1089 | <td></td> |
| 1090 | </tr> |
| 1091 | <tr> |
Greg Chadwick | 60138bd | 2020-08-26 13:59:49 +0100 | [diff] [blame] | 1092 | <td><code>BN.MULQACC w0.2, w1.2, 0</code></td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 1093 | <td style="background-color: olive"></td> |
| 1094 | <td style="background-color: olive"></td> |
| 1095 | <td style="background-color: olive" colspan="2" rowspan="1"><code>a2 * b2</code></td> |
| 1096 | <td></td> |
| 1097 | <td></td> |
| 1098 | <td></td> |
| 1099 | <td></td> |
| 1100 | </tr> |
| 1101 | <tr> |
Greg Chadwick | 60138bd | 2020-08-26 13:59:49 +0100 | [diff] [blame] | 1102 | <td><code>BN.MULQACC w0.1, w1.3, 0</code></td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 1103 | <td style="background-color: olive"></td> |
| 1104 | <td style="background-color: olive"></td> |
| 1105 | <td style="background-color: olive" colspan="2" rowspan="1"><code>a1 * b3</code></td> |
| 1106 | <td></td> |
| 1107 | <td></td> |
| 1108 | <td></td> |
| 1109 | <td></td> |
| 1110 | </tr> |
| 1111 | <tr> |
Greg Chadwick | 60138bd | 2020-08-26 13:59:49 +0100 | [diff] [blame] | 1112 | <td><code>BN.MULQACC w0.3, w1.2, 64</code></td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 1113 | <td style="background-color: olive"></td> |
| 1114 | <td style="background-color: olive" colspan="2" rowspan="1"><code>a3 * b2</code></td> |
| 1115 | <td style="background-color: olive"></td> |
| 1116 | <td></td> |
| 1117 | <td></td> |
| 1118 | <td></td> |
| 1119 | <td></td> |
| 1120 | </tr> |
| 1121 | <tr> |
Greg Chadwick | 60138bd | 2020-08-26 13:59:49 +0100 | [diff] [blame] | 1122 | <td><code>BN.MULQACC.SO w3.l, w0.2, w1.3, 64</code></td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 1123 | <td style="background-color: olive"></td> |
| 1124 | <td style="background-color: olive" colspan="2" rowspan="1"><code>a2 * b3</code></td> |
| 1125 | <td style="background-color: olive"></td> |
| 1126 | <td></td> |
| 1127 | <td></td> |
| 1128 | <td></td> |
| 1129 | <td></td> |
| 1130 | </tr> |
| 1131 | <tr> |
Greg Chadwick | 60138bd | 2020-08-26 13:59:49 +0100 | [diff] [blame] | 1132 | <td><code>BN.MULQACC.SO w3.u, w0.3, w1.3, 0</code></td> |
Philipp Wagner | 05a5f14 | 2020-06-03 23:42:20 +0100 | [diff] [blame] | 1133 | <td style="background-color: lightblue" colspan="2" rowspan="1"><code>a3 * b3</code></td> |
| 1134 | <td></td> |
| 1135 | <td></td> |
| 1136 | <td></td> |
| 1137 | <td></td> |
| 1138 | <td></td> |
| 1139 | <td></td> |
| 1140 | </tr> |
| 1141 | </tbody> |
| 1142 | </table> |
Greg Chadwick | 822a7e0 | 2020-08-26 13:45:56 +0100 | [diff] [blame] | 1143 | |
Philipp Wagner | b5b8c7f | 2020-10-27 10:44:27 +0000 | [diff] [blame] | 1144 | Code snippets giving examples of 256x256 and 384x384 multiplies can be found in `sw/otbn/code-snippets/mul256.s` and `sw/otbn/code-snippets/mul384.s`. |
Philipp Wagner | dc5b9a9 | 2021-05-07 15:03:47 +0100 | [diff] [blame] | 1145 | |
| 1146 | # References |
| 1147 | |
| 1148 | <a name="ref-chen08">[CHEN08]</a> L. Chen, "Hsiao-Code Check Matrices and Recursively Balanced Matrices," arXiv:0803.1217 [cs], Mar. 2008 [Online]. Available: http://arxiv.org/abs/0803.1217 |