Software APIs
error.h
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #ifndef OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_ERROR_H_
6 #define OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_ERROR_H_
7 
10 
11 #define USING_INTERNAL_STATUS
12 #include "sw/device/lib/base/internal/status.h"
13 #undef USING_INTERNAL_STATUS
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 /**
20  * List of modules which can produce errors.
21  *
22  * Choose a two-letter identifier for each module and encode the module
23  * identifier the concatenated ASCII representation of those letters.
24  */
25 #define MODULE_CODE(ch0_, ch1_) ((ch0_) << 8 | (ch1_))
26 enum module_ {
27  // clang-format off
28  kModuleUnknown = 0,
29  kModuleAlertHandler = MODULE_CODE('A', 'H'),
30  kModuleSigverify = MODULE_CODE('S', 'V'),
31  kModuleKeymgr = MODULE_CODE('K', 'M'),
32  kModuleManifest = MODULE_CODE('M', 'A'),
33  kModuleRom = MODULE_CODE('M', 'R'),
34  kModuleInterrupt = MODULE_CODE('I', 'R'),
35  kModuleEpmp = MODULE_CODE('E', 'P'),
36  kModuleKmac = MODULE_CODE('K', 'C'),
37  kModuleOtbn = MODULE_CODE('B', 'N'),
38  kModuleFlashCtrl = MODULE_CODE('F', 'C'),
39  kModuleBootPolicy = MODULE_CODE('B', 'P'),
40  kModuleBootstrap = MODULE_CODE('B', 'S'),
41  kModuleLog = MODULE_CODE('L', 'G'),
42  kModuleBootData = MODULE_CODE('B', 'D'),
43  kModuleSpiDevice = MODULE_CODE('S', 'P'),
44  kModuleAst = MODULE_CODE('A', 'S'),
45  kModuleRstmgr = MODULE_CODE('R', 'S'),
46  KModuleRnd = MODULE_CODE('R', 'N'),
47  kModuleBootSvc = MODULE_CODE('B', 'C'),
48  kModuleBootLog = MODULE_CODE('B', 'L'),
49  kModuleRomExt = MODULE_CODE('R', 'E'),
50  kModuleRomExtInterrupt = MODULE_CODE('R', 'I'),
51  kModuleAsn1 = MODULE_CODE('A', '1'),
52  kModuleRetRam = MODULE_CODE('R', 'R'),
53  kModuleXModem = MODULE_CODE('X', 'M'),
54  kModuleRescue = MODULE_CODE('R', 'S'),
55  kModuleCert = MODULE_CODE('C', 'E'),
56  kModuleOwnership = MODULE_CODE('O', 'W'),
57  kModulePersoTlv = MODULE_CODE('P', 'T'),
58  // clang-format on
59 };
60 
61 /**
62  * Field definitions for the different fields of the error word.
63  */
64 #define ROM_ERROR_FIELD_ERROR ((bitfield_field32_t){.mask = 0xFF, .index = 24})
65 #define ROM_ERROR_FIELD_MODULE \
66  ((bitfield_field32_t){.mask = 0xFFFF, .index = 8})
67 #define ROM_ERROR_FIELD_STATUS ((bitfield_field32_t){.mask = 0xFF, .index = 0})
68 
69 /**
70  * Helper macro for building up error codes.
71  * @param status_ An appropriate general status code from absl_staus.h.
72  * @param module_ The module identifier which produces this error.
73  * @param error_ The unique error id in that module. Error ids must not
74  * repeat within a module.
75  */
76 #define ERROR_(error_, module_, status_) \
77  ((error_ << 24) | (module_ << 8) | (status_))
78 
79 // clang-format off
80 // Use an X-macro to facilitate writing unit tests.
81 // Note: This list is extend-only and you may not renumber errors after they
82 // have been created. This is required for error-space stability
83 // after the ROM is frozen.
84 #define DEFINE_ERRORS(X) \
85  X(kErrorOk, 0x739), \
86  X(kErrorWriteBootdataThenReboot, 0x2ea), \
87  X(kErrorUnknown, 0xffffffff), \
88  \
89  X(kErrorSigverifyBadRsaSignature, ERROR_(1, kModuleSigverify, kInvalidArgument)), \
90  X(kErrorSigverifyBadSpxSignature, ERROR_(2, kModuleSigverify, kInvalidArgument)), \
91  X(kErrorSigverifyBadKey, ERROR_(3, kModuleSigverify, kInvalidArgument)), \
92  X(kErrorSigverifyBadRsaKey, ERROR_(4, kModuleSigverify, kInvalidArgument)), \
93  X(kErrorSigverifyBadSpxKey, ERROR_(5, kModuleSigverify, kInvalidArgument)), \
94  X(kErrorSigverifyLargeRsaSignature, ERROR_(6, kModuleSigverify, kInvalidArgument)), \
95  X(kErrorSigverifyBadEcdsaSignature, ERROR_(7, kModuleSigverify, kInvalidArgument)), \
96  X(kErrorSigverifyBadAuthPartition, ERROR_(8, kModuleSigverify, kInvalidArgument)), \
97  X(kErrorSigverifyBadEcdsaKey, ERROR_(9, kModuleSigverify, kInvalidArgument)), \
98  X(kErrorSigverifyBadSpxConfig, ERROR_(10, kModuleSigverify, kInvalidArgument)), \
99  \
100  X(kErrorKeymgrInternal, ERROR_(1, kModuleKeymgr, kInternal)), \
101  \
102  X(kErrorManifestBadEntryPoint, ERROR_(1, kModuleManifest, kInternal)), \
103  X(kErrorManifestBadCodeRegion, ERROR_(2, kModuleManifest, kInternal)), \
104  X(kErrorManifestBadSignedRegion, ERROR_(3, kModuleManifest, kInternal)), \
105  X(kErrorManifestBadExtension, ERROR_(4, kModuleManifest, kInternal)), \
106  X(kErrorManifestBadVersionMajor, ERROR_(5, kModuleManifest, kInternal)), \
107  \
108  X(kErrorAlertBadIndex, ERROR_(1, kModuleAlertHandler, kInvalidArgument)), \
109  X(kErrorAlertBadClass, ERROR_(2, kModuleAlertHandler, kInvalidArgument)), \
110  X(kErrorAlertBadEnable, ERROR_(3, kModuleAlertHandler, kInvalidArgument)), \
111  X(kErrorAlertBadEscalation, ERROR_(4, kModuleAlertHandler, kInvalidArgument)), \
112  X(kErrorAlertBadCrc32, ERROR_(5, kModuleAlertHandler, kInvalidArgument)), \
113  \
114  X(kErrorRomBootFailed, ERROR_(1, kModuleRom, kFailedPrecondition)), \
115  X(kErrorRomResetReasonFault, ERROR_(2, kModuleRom, kUnknown)), \
116  \
117  /* The high-byte of kErrorInterrupt is modified with the interrupt cause */ \
118  X(kErrorInterrupt, ERROR_(0, kModuleInterrupt, kUnknown)), \
119  \
120  X(kErrorEpmpBadCheck, ERROR_(1, kModuleEpmp, kInternal)), \
121  \
122  X(kErrorKmacInvalidStatus, ERROR_(1, kModuleKmac, kInternal)), \
123  X(kErrorKmacInvalidKeySize, ERROR_(2, kModuleKmac, kInvalidArgument)), \
124  \
125  X(kErrorOtbnInvalidArgument, ERROR_(1, kModuleOtbn, kInvalidArgument)), \
126  X(kErrorOtbnBadOffsetLen, ERROR_(2, kModuleOtbn, kInvalidArgument)), \
127  X(kErrorOtbnExecutionFailed, ERROR_(3, kModuleOtbn, kInternal)), \
128  X(kErrorOtbnSecWipeImemFailed, ERROR_(4, kModuleOtbn, kInternal)), \
129  X(kErrorOtbnSecWipeDmemFailed, ERROR_(5, kModuleOtbn, kInternal)), \
130  X(kErrorOtbnBadInsnCount, ERROR_(6, kModuleOtbn, kInternal)), \
131  X(kErrorOtbnUnavailable, ERROR_(7, kModuleOtbn, kInternal)), \
132  \
133  X(kErrorFlashCtrlDataRead, ERROR_(1, kModuleFlashCtrl, kInternal)), \
134  X(kErrorFlashCtrlInfoRead, ERROR_(2, kModuleFlashCtrl, kInternal)), \
135  X(kErrorFlashCtrlDataWrite, ERROR_(3, kModuleFlashCtrl, kInternal)), \
136  X(kErrorFlashCtrlInfoWrite, ERROR_(4, kModuleFlashCtrl, kInternal)), \
137  X(kErrorFlashCtrlDataErase, ERROR_(5, kModuleFlashCtrl, kInternal)), \
138  X(kErrorFlashCtrlInfoErase, ERROR_(6, kModuleFlashCtrl, kInternal)), \
139  X(kErrorFlashCtrlDataEraseVerify, ERROR_(7, kModuleFlashCtrl, kInternal)), \
140  \
141  X(kErrorBootPolicyBadIdentifier, ERROR_(1, kModuleBootPolicy, kInternal)), \
142  X(kErrorBootPolicyBadLength, ERROR_(2, kModuleBootPolicy, kInternal)), \
143  X(kErrorBootPolicyRollback, ERROR_(3, kModuleBootPolicy, kInternal)), \
144  \
145  X(kErrorBootstrapEraseAddress, ERROR_(1, kModuleBootstrap, kInvalidArgument)), \
146  X(kErrorBootstrapProgramAddress, ERROR_(2, kModuleBootstrap, kInvalidArgument)), \
147  X(kErrorBootstrapInvalidState, ERROR_(3, kModuleBootstrap, kInvalidArgument)), \
148  X(kErrorBootstrapNotRequested, ERROR_(4, kModuleBootstrap, kInternal)), \
149  X(kErrorBootstrapDisabledRomExt, ERROR_(5, kModuleBootstrap, kInternal)), \
150  \
151  X(kErrorLogBadFormatSpecifier, ERROR_(1, kModuleLog, kInternal)), \
152  \
153  X(kErrorBootDataNotFound, ERROR_(1, kModuleBootData, kInternal)), \
154  X(kErrorBootDataWriteCheck, ERROR_(2, kModuleBootData, kInternal)), \
155  X(kErrorBootDataInvalid, ERROR_(3, kModuleBootData, kInternal)), \
156  \
157  X(kErrorSpiDevicePayloadOverflow, ERROR_(1, kModuleSpiDevice, kInternal)), \
158  \
159  X(kErrorAstInitNotDone, ERROR_(1, kModuleAst, kInternal)), \
160  \
161  X(kErrorRstmgrBadInit, ERROR_(1, kModuleRstmgr, kInternal)), \
162  \
163  X(kErrorRndBadCrc32, ERROR_(1, KModuleRnd, kInvalidArgument)), \
164  \
165  X(kErrorBootSvcBadHeader, ERROR_(1, kModuleBootSvc, kInternal)), \
166  X(kErrorBootSvcBadSlot, ERROR_(2, kModuleBootSvc, kInvalidArgument)), \
167  X(kErrorBootSvcBadSecVer, ERROR_(3, kModuleBootSvc, kInvalidArgument)), \
168  \
169  X(kErrorRomExtBootFailed, ERROR_(1, kModuleRomExt, kFailedPrecondition)), \
170  \
171  X(kErrorXModemTimeoutStart, ERROR_(1, kModuleXModem, kDeadlineExceeded)), \
172  X(kErrorXModemTimeoutPacket, ERROR_(2, kModuleXModem, kDeadlineExceeded)), \
173  X(kErrorXModemTimeoutData, ERROR_(3, kModuleXModem, kDeadlineExceeded)), \
174  X(kErrorXModemTimeoutCrc, ERROR_(4, kModuleXModem, kDeadlineExceeded)), \
175  X(kErrorXModemTimeoutAck, ERROR_(5, kModuleXModem, kDeadlineExceeded)), \
176  X(kErrorXModemCrc, ERROR_(6, kModuleXModem, kDataLoss)), \
177  X(kErrorXModemEndOfFile, ERROR_(7, kModuleXModem, kOutOfRange)), \
178  X(kErrorXModemCancel, ERROR_(8, kModuleXModem, kCancelled)), \
179  X(kErrorXModemUnknown, ERROR_(9, kModuleXModem, kUnknown)), \
180  X(kErrorXModemProtocol, ERROR_(10, kModuleXModem, kInvalidArgument)), \
181  X(kErrorXModemTooManyErrors, ERROR_(11, kModuleXModem, kFailedPrecondition)), \
182  \
183  /* The high-byte of kErrorInterrupt is modified with the interrupt cause */ \
184  X(kErrorRomExtInterrupt, ERROR_(0, kModuleRomExtInterrupt, kUnknown)), \
185  \
186  X(kErrorBootLogInvalid, ERROR_(1, kModuleBootLog, kInternal)), \
187  \
188  X(kErrorAsn1Internal, ERROR_(1, kModuleAsn1, kInternal)), \
189  X(kErrorAsn1StartInvalidArgument, ERROR_(2, kModuleAsn1, kInvalidArgument)), \
190  X(kErrorAsn1PushBytesInvalidArgument, ERROR_(3, kModuleAsn1, kInvalidArgument)), \
191  X(kErrorAsn1PushIntegerPadInvalidArgument, ERROR_(4, kModuleAsn1, kInvalidArgument)), \
192  X(kErrorAsn1PushIntegerInvalidArgument, ERROR_(5, kModuleAsn1, kInvalidArgument)), \
193  X(kErrorAsn1FinishBitstringInvalidArgument, ERROR_(6, kModuleAsn1, kInvalidArgument)), \
194  X(kErrorAsn1BufferExhausted, ERROR_(7, kModuleAsn1, kResourceExhausted)), \
195  \
196  X(kErrorRetRamBadVersion, ERROR_(1, kModuleRetRam, kUnknown)), \
197  \
198  X(kErrorRescueReboot, ERROR_(0, kModuleRescue, kInternal)), \
199  X(kErrorRescueBadMode, ERROR_(1, kModuleRescue, kInvalidArgument)), \
200  X(kErrorRescueImageTooBig, ERROR_(2, kModuleRescue, kFailedPrecondition)), \
201  \
202  X(kErrorCertInternal, ERROR_(0, kModuleCert, kInternal)), \
203  X(kErrorCertInvalidArgument, ERROR_(1, kModuleCert, kInvalidArgument)), \
204  X(kErrorCertInvalidSize, ERROR_(2, kModuleCert, kDataLoss)), \
205  \
206  X(kErrorOwnershipInvalidNonce, ERROR_(0, kModuleOwnership, kInvalidArgument)), \
207  X(kErrorOwnershipInvalidMode, ERROR_(1, kModuleOwnership, kInvalidArgument)), \
208  X(kErrorOwnershipInvalidSignature, ERROR_(2, kModuleOwnership, kInvalidArgument)), \
209  X(kErrorOwnershipInvalidState, ERROR_(3, kModuleOwnership, kInvalidArgument)), \
210  X(kErrorOwnershipInvalidRequest, ERROR_(4, kModuleOwnership, kInvalidArgument)), \
211  X(kErrorOwnershipInvalidTag, ERROR_(5, kModuleOwnership, kInvalidArgument)), \
212  X(kErrorOwnershipInvalidTagLength, ERROR_(6, kModuleOwnership, kInvalidArgument)), \
213  X(kErrorOwnershipDuplicateItem, ERROR_(7, kModuleOwnership, kAlreadyExists)), \
214  X(kErrorOwnershipFlashConfigLenth, ERROR_(8, kModuleOwnership, kOutOfRange)), \
215  X(kErrorOwnershipInvalidInfoPage, ERROR_(9, kModuleOwnership, kInvalidArgument)), \
216  X(kErrorOwnershipBadInfoPage, ERROR_(10, kModuleOwnership, kInternal)), \
217  X(kErrorOwnershipNoOwner, ERROR_(11, kModuleOwnership, kInternal)), \
218  X(kErrorOwnershipKeyNotFound, ERROR_(12, kModuleOwnership, kNotFound)), \
219  X(kErrorOwnershipInvalidDin, ERROR_(13, kModuleOwnership, kInvalidArgument)), \
220  X(kErrorOwnershipUnlockDenied, ERROR_(14, kModuleOwnership, kPermissionDenied)), \
221  X(kErrorOwnershipFlashConfigRomExt, ERROR_(15, kModuleOwnership, kInvalidArgument)), \
222  /* Group all of the tag version error codes together */ \
223  X(kErrorOwnershipOWNRVersion, ERROR_(0x70, kModuleOwnership, kInvalidArgument)), \
224  X(kErrorOwnershipAPPKVersion, ERROR_(0x71, kModuleOwnership, kInvalidArgument)), \
225  X(kErrorOwnershipFLSHVersion, ERROR_(0x72, kModuleOwnership, kInvalidArgument)), \
226  X(kErrorOwnershipINFOVersion, ERROR_(0x73, kModuleOwnership, kInvalidArgument)), \
227  X(kErrorOwnershipRESQVersion, ERROR_(0x74, kModuleOwnership, kInvalidArgument)), \
228  \
229  X(kErrorPersoTlvInternal, ERROR_(0, kModulePersoTlv, kInternal)), \
230  X(kErrorPersoTlvCertObjNotFound, ERROR_(1, kModulePersoTlv, kNotFound)), \
231  X(kErrorPersoTlvCertNameTooLong, ERROR_(2, kModulePersoTlv, kOutOfRange)), \
232  X(kErrorPersoTlvOutputBufTooSmall, ERROR_(3, kModulePersoTlv, kOutOfRange)), \
233  \
234  /* This comment prevent clang from trying to format the macro. */
235 
236 // clang-format on
237 
238 #define ERROR_ENUM_INIT(name_, value_) name_ = value_
239 
240 /**
241  * Unified set of errors for ROM and ROM_EXT.
242  */
243 typedef enum rom_error { DEFINE_ERRORS(ERROR_ENUM_INIT) } rom_error_t;
244 
245 /**
246  * Evaluate an expression and return if the result is an error.
247  *
248  * @param expr_ An expression which results in a `rom_error_t`.
249  */
250 #define RETURN_IF_ERROR(expr_) \
251  do { \
252  rom_error_t local_error_ = expr_; \
253  if (local_error_ != kErrorOk) { \
254  return local_error_; \
255  } \
256  } while (false)
257 
258 /**
259  * Hardened version of `RETURN_IF_ERROR()`.
260  *
261  * See `launder32()` and `HARDENED_CHECK_EQ()` in
262  * `sw/device/lib/base/hardened.h` for more details.
263  *
264  * @param expr_ An expression which results in a `rom_error_t`.
265  */
266 #define HARDENED_RETURN_IF_ERROR(expr_) \
267  do { \
268  rom_error_t error_ = expr_; \
269  if (launder32(error_) != kErrorOk) { \
270  return error_; \
271  } \
272  HARDENED_CHECK_EQ(error_, kErrorOk); \
273  } while (false)
274 
275 #ifdef __cplusplus
276 }
277 #endif
278 #endif // OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_ERROR_H_