Software APIs
dif_otp_ctrl.h
Go to the documentation of this file.
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 #ifndef OPENTITAN_SW_DEVICE_LIB_DIF_DIF_OTP_CTRL_H_
5 #define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_OTP_CTRL_H_
6 
7 /**
8  * @file
9  * @brief <a href="/hw/top_earlgrey/ip_autogen/otp_ctrl/doc/">
10  * OTP Controller</a> Device Interface Functions
11  */
12 
13 #include <stdint.h>
14 
18 
19 #include "sw/device/lib/dif/autogen/dif_otp_ctrl_autogen.h"
20 
21 // Header Extern Guard (so header can be used from C and C++)
22 #ifdef __cplusplus
23 extern "C" {
24 #endif // __cplusplus
25 
26 /**
27  * A partition within OTP memory.
28  */
29 typedef enum dif_otp_ctrl_partition {
30  /**
31  * Vendor test partition.
32  *
33  * This is reserved for manufacturing smoke checks. The OTP wrapper
34  * control logic inside prim_otp is allowed to read/write to this
35  * region. ECC uncorrectable errors seen on the functional prim_otp
36  * interface will not lead to an alert for this partition.
37  * Instead, such errors will be reported as correctable ECC errors.
38  */
40  /**
41  * Software configuration partition.
42  *
43  * This is for device-specific calibration data, e.g, clock, LDO, RNG,
44  * and configuration settings set by the ROM.
45  */
47  /**
48  * Software configuration partition.
49  *
50  * This contains data that changes software behavior in the ROM, for
51  * example enabling defensive features in ROM or selecting failure
52  * modes if verification fails.
53  */
55  /**
56  * This OTP partition is used to store four P-256 keys and four Sphincs+ keys.
57  *
58  * The partition requires 464
59  * bytes of software visible storage. The partition is
60  * locked at manufacturing time to protect against
61  * malicious write attempts.
62  */
64  /**
65  * This OTP partition is used to capture the state of each key slot.
66  *
67  * Each key can be in one of the
68  * following states: BLANK, ENABLED, DISABLED. The
69  * encoded values are such that transitions between
70  * BLANK -> ENABLED -> DISABLED are possible without
71  * causing ECC errors (this is a mechanism similar to
72  * how we manage life cycle state transitions). The
73  * partition is left unlocked to allow STATE updates in
74  * the field. The ROM_EXT is required to lock access to
75  * the OTP Direct Access Interface to prevent DoS
76  * attacks from malicious code executing on Silicon
77  * Owner partitions. DAI write locking is available in
78  * EarlGrey.
79  */
81  /**
82  * Hardware configuration 0 partition.
83  *
84  * This contains a device identifier and manufacturing state.
85  */
87  /**
88  * Hardware configuration 1 partition.
89  *
90  * This contains several hardware feature switches.
91  */
93  /**
94  * Secret partition 0.
95  *
96  * This contains TEST lifecycle unlock tokens.
97  */
99  /**
100  * Secret partition 1.
101  *
102  * This contains SRAM and flash scrambling keys.
103  */
105  /**
106  * Secret partition 2.
107  *
108  * This contains RMA unlock token, creator root key, and creator seed.
109  */
111  /**
112  * Lifecycle partition.
113  *
114  * This contains lifecycle transition count and state. This partition
115  * cannot be locked since the life cycle state needs to advance to RMA
116  * in-field. Note that while this partition is not marked secret, it
117  * is not readable nor writeable via the DAI. Only the LC controller
118  * can access this partition, and even via the LC controller it is not
119  * possible to read the raw manufacturing life cycle state in encoded
120  * form, since that encoding is considered a netlist secret. The LC
121  * controller only exposes a decoded version of this state.
122  */
125 
126 /**
127  * Runtime configuration for OTP.
128  *
129  * This struct describes runtime information for one-time configuration of the
130  * hardware.
131  */
132 typedef struct dif_otp_ctrl_config {
133  /**
134  * The timeout for an integrity or consistency check to succeed, in cycles.
135  *
136  * 100'000 is recommended as a minimum safe value.
137  */
138  uint32_t check_timeout;
139  /**
140  * A mask for the pseudo-random integrity check period.
141  *
142  * The value of this mask limits the period of the integrity check; when the
143  * pseudo-random period is computed, this mask is applied to limit it. For
144  * example, a value of 0x3'ffff would correspond to a maximum period of about
145  * 2.8s at 24MHz.
146  *
147  * A value of zero disables the check.
148  */
150  /**
151  * A mask for the pseudo-random consistency check period.
152  *
153  * The value of this mask limits the period of the consistency check; when the
154  * pseudo-random period is computed, this mask is applied to limit it. For
155  * example, a value of 0x3ff'ffff would correspond to a maximum period of
156  * about 716s at 24MHz.
157  *
158  * A value of zero disables the check.
159  */
162 
163 /**
164  * A hardware-level status code.
165  */
167  // NOTE: This enum's API *requires* that all "error"-like codes (that is,
168  // those which have associated cause registers) be a prefix of the enum
169  // values.
170  //
171  // Note furthermore that these enum variants are intended as bit indices, so
172  // their values should not be randomized.
173  /**
174  * Indicates an error occurred in the `VendorTest` partition.
175  */
177  /**
178  * Indicates an error occurred in the `CreatorSwCfg` partition.
179  */
181  /**
182  * Indicates an error occurred in the `OwnerSwCfg` partition.
183  */
185  /**
186  * Indicates an error occurred in the `RotCreatorAuthCodesign` partition.
187  */
189  /**
190  * Indicates an error occurred in the `RotCreatorAuthState` partition.
191  */
193  /**
194  * Indicates an error occurred in the `HwCfg0` partition.
195  */
197  /**
198  * Indicates an error occurred in the `HwCfg1` partition.
199  */
201  /**
202  * Indicates an error occurred in the `Secret0` partition.
203  */
205  /**
206  * Indicates an error occurred in the `Secret1` partition.
207  */
209  /**
210  * Indicates an error occurred in the `Secret2` partition.
211  */
213  /**
214  * Indicates an error occurred in the `LifeCycle` partition.
215  */
217  /**
218  * Indicates an error occurred in the direct access interface.
219  */
221  /**
222  * Indicates an error occurred in the lifecycle interface.
223  */
225  /**
226  * This is not a status code; rather, it represents the last error code which
227  * has a corresponding "cause" register.
228  *
229  * See `dif_otp_ctrl_status_t` for information on how to use this.
230  */
232  /**
233  * Indicates that an integrity or consistency check has timed out.
234  *
235  * This error is unrecoverable.
236  */
238  /**
239  * Indicates that the LFSR that generates pseudo-random integrity and
240  * consistency checks is in a bad state.
241  *
242  * This error is unrecoverable.
243  */
245  /**
246  * Indicates that the scrambling hardware is in a bad state.
247  *
248  * This error is unrecoverable.
249  */
251  /**
252  * Indicates that the key derivation hardware is in a bad state.
253  *
254  * This error is unrecoverable.
255  */
257  /**
258  * Indicates a bus integrity error.
259  *
260  * This error will raise an alert.
261  */
263  /**
264  * Indicates that the direct access interface is idle.
265  */
267  /**
268  * Indicates that an integrity or consistency check is currently pending.
269  */
272 
273 /**
274  * A hardware-level error code, associated with a particular error defined in
275  * `dif_otp_ctrl_status_t`.
276  */
277 typedef enum dif_otp_ctrl_error {
278  /**
279  * Indicates no error.
280  */
282  /**
283  * Indicates that an OTP macro command was invalid or did not
284  * complete successfully.
285  *
286  * This error indicates non-recoverable hardware malfunction.
287  */
289  /**
290  * Indicates a recoverable error during a read operation.
291  *
292  * A followup read should work as expected.
293  */
295  /**
296  * Indicates an unrecoverable error during a read operation.
297  *
298  * This error indicates non-recoverable hardware malfunction.
299  */
301  /**
302  * Indicates that the blank write check failed during a write operation.
303  */
305  /**
306  * Indicates a locked memory region was accessed.
307  */
309  /**
310  * Indicates a parity, integrity or consistency check failed in the buffer
311  * registers.
312  *
313  * This error indicates non-recoverable hardware malfunction.
314  */
316  /**
317  * Indicates that the FSM of the controller is in a bad state or that the
318  * controller's FSM has been moved into its terminal state due to escalation
319  * via the alert subsystem.
320  *
321  * This error indicates that the device has been glitched by an attacker.
322  */
325 
326 /**
327  * The overall status of the OTP controller.
328  *
329  * See `dif_otp_ctrl_get_status()`.
330  */
331 typedef struct dif_otp_ctrl_status {
332  /**
333  * Currently active statuses, given as a bit vector. To check whether a
334  * particular status code was returned, write
335  *
336  * bool has_code = (status.codes >> kMyStatusCode) & 1;
337  *
338  * Note that it is possible to quickly check that the controller is idle and
339  * error-free by writing
340  *
341  * bool is_ok = status.codes == (1 << kDifOtpStatusCodeDaiIdle);
342  */
343  uint32_t codes;
344  /**
345  * A list of root causes for each error status code.
346  *
347  * If the error status code `error` is present in `codes`, and
348  * `error <= kDifOtpCtrlStatusCodeHasCauseLast`, then `causes[error]`
349  * will contain its root cause.
350  */
353 
354 /**
355  * Configures OTP with runtime information.
356  *
357  * This function should need to be called at most once for the lifetime of
358  * `otp`.
359  *
360  * @param otp An OTP handle.
361  * @param config Runtime configuration parameters.
362  * @return The result of the operation.
363  */
365 dif_result_t dif_otp_ctrl_configure(const dif_otp_ctrl_t *otp,
366  dif_otp_ctrl_config_t config);
367 
368 /**
369  * Runs an integrity check on the OTP hardware.
370  *
371  * This function can be used to trigger an integrity check independent of the
372  * pseudo-random hardware-generated checks.
373  *
374  * @param otp An OTP handle.
375  * @return The result of the operation.
376  */
378 dif_result_t dif_otp_ctrl_check_integrity(const dif_otp_ctrl_t *otp);
379 
380 /**
381  * Runs a consistency check on the OTP hardware.
382  *
383  * This function can be used to trigger a consistency check independent of the
384  * pseudo-random hardware-generated checks.
385  *
386  * @param otp An OTP handle.
387  * @return The result of the operation.
388  */
390 dif_result_t dif_otp_ctrl_check_consistency(const dif_otp_ctrl_t *otp);
391 
392 /**
393  * Locks out access to the direct access interface registers.
394  *
395  * This function is idempotent: calling it while functionality is locked will
396  * have no effect and return `kDifOk`.
397  *
398  * @param otp An OTP handle.
399  * @return The result of the operation.
400  */
402 dif_result_t dif_otp_ctrl_dai_lock(const dif_otp_ctrl_t *otp);
403 
404 /**
405  * Checks whether access to the direct access interface is locked.
406  *
407  * Note that besides locking the DAI out until the next reset using the
408  * dif_otp_ctrl_dai_lock function, the DAI is also temporarily locked by the
409  * HW itself when it is busy processing a DAI command. In such a case, the
410  * kDifOtpCtrlStatusCodeDaiIdle status bit will be set to 0 as well.
411  *
412  * @param otp An OTP handle.
413  * @param[out] is_locked Out-param for the locked state.
414  * @return The result of the operation.
415  */
417 dif_result_t dif_otp_ctrl_dai_is_locked(const dif_otp_ctrl_t *otp,
418  bool *is_locked);
419 
420 /**
421  * Locks out `dif_otp_ctrl_configure()` function.
422  *
423  * This function is idempotent: calling it while functionality is locked will
424  * have no effect and return `kDifOk`.
425  *
426  * @param otp An OTP handle.
427  * @return The result of the operation.
428  */
430 dif_result_t dif_otp_ctrl_lock_config(const dif_otp_ctrl_t *otp);
431 
432 /**
433  * Checks whether `dif_otp_ctrl_configure()` function is locked-out.
434  *
435  * @param otp An OTP handle.
436  * @param[out] is_locked Out-param for the locked state.
437  * @return The result of the operation.
438  */
440 dif_result_t dif_otp_ctrl_config_is_locked(const dif_otp_ctrl_t *otp,
441  bool *is_locked);
442 
443 /**
444  * Locks out `dif_otp_ctrl_check_*()` functions.
445  *
446  * This function is idempotent: calling it while functionality is locked will
447  * have no effect and return `kDifOk`.
448  *
449  * @param otp An OTP handle.
450  * @return The result of the operation.
451  */
453 dif_result_t dif_otp_ctrl_lock_check_trigger(const dif_otp_ctrl_t *otp);
454 
455 /**
456  * Checks whether the `dif_otp_ctrl_check_*()` functions are locked-out.
457  *
458  * @param otp An OTP handle.
459  * @param[out] is_locked Out-param for the locked state.
460  * @return The result of the operation.
461  */
463 dif_result_t dif_otp_ctrl_check_trigger_is_locked(const dif_otp_ctrl_t *otp,
464  bool *is_locked);
465 
466 /**
467  * Locks out reads to a SW partition.
468  *
469  * This function should only be called on SW partitions; doing otherwise will
470  * return an error.
471  *
472  * Note that this is distinct from the write-locking performed by calling
473  * `dif_otp_ctrl_dai_digest()`. In particular, the effects of this function will
474  * not persist past a system reset.
475  *
476  * This function is idempotent: calling it while functionality is locked will
477  * have no effect and return `kDifOk`.
478  *
479  * @param otp An OTP handle.
480  * @param partition The SW partition to lock.
481  * @return The result of the operation.
482  */
484 dif_result_t dif_otp_ctrl_lock_reading(const dif_otp_ctrl_t *otp,
485  dif_otp_ctrl_partition_t partition);
486 
487 /**
488  * Checks whether reads to a SW partition are locked out.
489  *
490  * This function should only be called on SW partitions; doing otherwise will
491  * return an error.
492  *
493  * @param otp An OTP handle.
494  * @param partition the SW partition to check for locking.
495  * @param[out] is_locked Out-param for the locked state.
496  * @return The result of the operation.
497  */
499 dif_result_t dif_otp_ctrl_reading_is_locked(const dif_otp_ctrl_t *otp,
500  dif_otp_ctrl_partition_t partition,
501  bool *is_locked);
502 
503 /**
504  * Gets the current status of the OTP controller.
505  *
506  * @param otp An OTP handle.
507  * @param[out] status Out-param for the controller's status.
508  * @return The result of the operation.
509  */
511 dif_result_t dif_otp_ctrl_get_status(const dif_otp_ctrl_t *otp,
513 
514 /**
515  * Calculates a `relative_address` with respect to a `partition` start
516  * address.
517  *
518  * @param partition The partition to use to calculate the reference start
519  * address.
520  * @param abs_address Input address relative to the OTP memory start address.
521  * @param[out] relative_address The result relative address with respect to the
522  * `partition` start address.
523  * @return The result of the operation.
524  */
527  uint32_t abs_address,
528  uint32_t *relative_address);
529 
530 /**
531  * Schedules a read on the Direct Access Interface.
532  *
533  * Reads are performed relative to a partition; `address` should be given
534  * relative to the start of `partition`. An error is returned for out-of-bounds
535  * access.
536  *
537  * Furthermore, `address` must be well-aligned: it must be four-byte aligned for
538  * normal partitions and eight-byte-aligned for secret partitions. An error is
539  * returned for unaligned access.
540  *
541  * @param otp An OTP handle.
542  * @param partition The partition to read from.
543  * @param address A partition-relative address to read from.
544  * @return The result of the operation.
545  */
547 dif_result_t dif_otp_ctrl_dai_read_start(const dif_otp_ctrl_t *otp,
548  dif_otp_ctrl_partition_t partition,
549  uint32_t address);
550 
551 /**
552  * Gets the result of a completed 32-bit read operation on the Direct Access
553  * Interface.
554  *
555  * Whether this function or its 64-bit variant should be called is dependent on
556  * the most recent partition read from.
557  *
558  * @param otp An OTP handle.
559  * @param[out] value Out-param for the read value.
560  * @return The result of the operation.
561  */
563 dif_result_t dif_otp_ctrl_dai_read32_end(const dif_otp_ctrl_t *otp,
564  uint32_t *value);
565 
566 /**
567  * Gets the result of a completed 64-bit read operation on the Direct Access
568  * Interface.
569  *
570  * Whether this function or its 32-bit variant should be called is dependent on
571  * the most recent partition read from.
572  *
573  * @param otp An OTP handle.
574  * @param[out] value Out-param for the read value.
575  * @return The result of the operation.
576  */
578 dif_result_t dif_otp_ctrl_dai_read64_end(const dif_otp_ctrl_t *otp,
579  uint64_t *value);
580 
581 /**
582  * Schedules a 32-bit write on the Direct Access Interface.
583  *
584  * Writes are performed relative to a partition; `address` should be given
585  * relative to the start of `partition`. An error is returned for out-of-bounds
586  * access.
587  *
588  * Furthermore, `address` must be four-byte-aligned, and `partition` must not be
589  * a secret partition. An error is returned if neither condition is met.
590  *
591  * Note that this function cannot be used to program the digest at the end of a
592  * `SW` partition; `dif_otp_ctrl_dai_digest()` must be used instead.
593  *
594  * @param otp An OTP handle.
595  * @param partition The partition to program.
596  * @param address A partition-relative address to program.
597  * @param value The value to program into the OTP.
598  * @return The result of the operation.
599  */
601 dif_result_t dif_otp_ctrl_dai_program32(const dif_otp_ctrl_t *otp,
602  dif_otp_ctrl_partition_t partition,
603  uint32_t address, uint32_t value);
604 
605 /**
606  * Schedules a 64-bit write on the Direct Access Interface.
607  *
608  * Writes are performed relative to a partition; `address` should be given
609  * relative to the start of `partition`. An error is returned for out-of-bounds
610  * access.
611  *
612  * Furthermore, `address` must be eight-byte-aligned, and `partition` must be
613  * a secret partition. An error is returned if neither condition is met.
614  *
615  * @param otp An OTP handle.
616  * @param partition The partition to program.
617  * @param address A partition-relative address to program.
618  * @param value The value to program into the OTP.
619  * @return The result of the operation.
620  */
622 dif_result_t dif_otp_ctrl_dai_program64(const dif_otp_ctrl_t *otp,
623  dif_otp_ctrl_partition_t partition,
624  uint32_t address, uint64_t value);
625 
626 /**
627  * Schedules a hardware digest operation on the Direct Access Interface.
628  *
629  * **This operation will also lock writes for the given partition.**
630  *
631  * If `partition` is a SW partition, `digest` must be non-zero; if it is a
632  * partition with a hardware-managed digest, `digest` *must* be zero (since the
633  * digest will be generated by the hardware). An error is returned if either
634  * precondition is not met.
635  *
636  * This function does not work with the lifecycle state partition, and will
637  * return an error in that case.
638  *
639  * @param otp An OTP handle.
640  * @param partition The partition to digest and lock.
641  * @param digest The digest to program (for SW partitions).
642  * @return The result of the operation.
643  */
645 dif_result_t dif_otp_ctrl_dai_digest(const dif_otp_ctrl_t *otp,
646  dif_otp_ctrl_partition_t partition,
647  uint64_t digest);
648 
649 /**
650  * Checks if the digest value for the given partition has been computed. Once a
651  * digest has been computed for a partition, the partition is write-locked
652  * (additionally, read-locked if the partition is secret).
653  *
654  * The lifecycle partition does not have a digest, and checking if this region
655  * has a computed digest will return an error.
656  *
657  * @param otp An OTP handle.
658  * @param partition The partition to check the digest of.
659  * @param[out] is_computed Indicates if the digest has been computed.
660  * @return The result of the operation.
661  */
663 dif_result_t dif_otp_ctrl_is_digest_computed(const dif_otp_ctrl_t *otp,
664  dif_otp_ctrl_partition_t partition,
665  bool *is_computed);
666 
667 /**
668  * Gets the buffered digest value for the given partition.
669  *
670  * Note that this value is only updated when the device is reset; if the digest
671  * has not been computed yet, or has been computed but not since device reset,
672  * this function will return an error.
673  *
674  * The lifecycle partition does not have a digest and will result in an error
675  * being returned.
676  *
677  * @param otp An OTP handle.
678  * @param partition The partition to get a digest for.
679  * @param[out] digest Out-param for the digest.
680  * @return The result of the operation.
681  */
683 dif_result_t dif_otp_ctrl_get_digest(const dif_otp_ctrl_t *otp,
684  dif_otp_ctrl_partition_t partition,
685  uint64_t *digest);
686 
687 /**
688  * Performs a memory-mapped read of the given partition, if it supports them.
689  *
690  * In particular, this function will read `len` words, starting at `address`,
691  * relative to the start of `partition`.
692  *
693  * The same caveats for `dif_otp_ctrl_dai_read_start()` apply to `address`; in
694  * addition, `address + len` must also be in-range and must not overflow.
695  *
696  * This function will block until the read completes, unlike Direct Access
697  * Interface functions.
698  *
699  * @param otp An OTP handle.
700  * @param partition The partition to read from.
701  * @param address A partition-relative address to read from.
702  * @param[out] buf A buffer of words to write read values to.
703  * @param len The number of words to read.
704  * @return The result of the operation.
705  */
707 dif_result_t dif_otp_ctrl_read_blocking(const dif_otp_ctrl_t *otp,
708  dif_otp_ctrl_partition_t partition,
709  uint32_t address, uint32_t *buf,
710  size_t len);
711 
712 #ifdef __cplusplus
713 } // extern "C"
714 #endif // __cplusplus
715 
716 #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_OTP_CTRL_H_