Pavona 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_egret/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
23extern "C" {
24#endif // __cplusplus
25
26/**
27 * A partition within OTP memory.
28 */
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#if defined(OPENTITAN_IS_EGRET)
56 /**
57 * This OTP partition is used to store four P-256 keys and four Sphincs+ keys.
58 *
59 * The partition requires 464
60 * bytes of software visible storage. The partition is
61 * locked at manufacturing time to protect against
62 * malicious write attempts.
63 */
64 kDifOtpCtrlPartitionRotCreatorAuthCodesign,
65 /**
66 * This OTP partition is used to capture the state of each key slot.
67 *
68 * Each key can be in one of the
69 * following states: BLANK, ENABLED, DISABLED. The
70 * encoded values are such that transitions between
71 * BLANK -> ENABLED -> DISABLED are possible without
72 * causing ECC errors (this is a mechanism similar to
73 * how we manage life cycle state transitions). The
74 * partition is left unlocked to allow STATE updates in
75 * the field. The ROM_EXT is required to lock access to
76 * the OTP Direct Access Interface to prevent DoS
77 * attacks from malicious code executing on Silicon
78 * Owner partitions. DAI write locking is available in
79 * Egret.
80 */
81 kDifOtpCtrlPartitionRotCreatorAuthState,
82#elif defined(OPENTITAN_IS_DRAGONFLY)
83 /**
84 * SW managed asset ownership states partition.
85 *
86 * Multibit enable value for the tracking the asset ownership states.
87 * Note that the states can be written multiple times in a device lifetime.
88 * The values to be written are engineered in the same way as the LC_CTRL
89 * state encoding words so that the ECC encoding remains valid even after
90 * updating the values.
91 *
92 * The constants can be found in the lc_ctrl_state_pkg.sv package.
93 *
94 * The programming order has to adhere to:
95 *
96 * OWNERSHIP_ST_RAW (factory all-zero state) ->
97 * OWNERSHIP_ST_LOCKED0 ->
98 * OWNERSHIP_ST_RELEASED0 ->
99 * ...
100 * OWNERSHIP_ST_SCRAPPED
101 *
102 * Note that if there are less than 4 slots available the higher slot states
103 * become logically equivalent to OWNERSHIP_SCRAPPED (firmware has to handle
104 * this correctly).
105 */
106 kDifOtpCtrlPartitionOwnershipSlotState,
107 /**
108 * Software managed creator partition.
109 *
110 */
111 kDifOtpCtrlPartitionRotCreatorIdentity,
112 /**
113 * Software managed owner slot 0 partition.
114 *
115 */
116 kDifOtpCtrlPartitionRotOwnerAuthSlot0,
117 /**
118 * Software managed owner slot 1 partition.
119 *
120 */
121 kDifOtpCtrlPartitionRotOwnerAuthSlot1,
122 /**
123 * Software managed platform integrator slot 0 partition.
124 *
125 */
126 kDifOtpCtrlPartitionPlatIntegAuthSlot0,
127 /**
128 * Software managed platform integrator slot 1 partition.
129 *
130 */
131 kDifOtpCtrlPartitionPlatIntegAuthSlot1,
132 /**
133 * Software managed platform owner slot 0 partition.
134 *
135 */
136 kDifOtpCtrlPartitionPlatOwnerAuthSlot0,
137 /**
138 * Software managed platform owner slot 1 partition.
139 *
140 */
141 kDifOtpCtrlPartitionPlatOwnerAuthSlot1,
142 /**
143 * Software managed platform owner slot 2 partition.
144 *
145 */
146 kDifOtpCtrlPartitionPlatOwnerAuthSlot2,
147 /**
148 * Software managed platform owner slot 3 partition.
149 *
150 */
151 kDifOtpCtrlPartitionPlatOwnerAuthSlot3,
152 /**
153 * Anti-replay protection Strike Counters partition.
154 *
155 */
156 kDifOtpCtrlPartitionExtNvm,
157 /**
158 * ROM Patch Code section.
159 *
160 * May contain multiple signed ROM2 patches.
161 */
162 kDifOtpCtrlPartitionRomPatch,
163 /**
164 * SoC Fuses CP section.
165 *
166 */
167 kDifOtpCtrlPartitionSocFusesCp,
168 /**
169 * SoC Fuses FT section.
170 *
171 */
172 kDifOtpCtrlPartitionSocFusesFt,
173 /**
174 * Scratch Fuses section.
175 *
176 */
177 kDifOtpCtrlPartitionScratchFuses,
178#else
179#error "dif_otp_ctrl does not support this top"
180#endif
181 /**
182 * Hardware configuration 0 partition.
183 *
184 * This contains a device identifier and manufacturing state.
185 */
187 /**
188 * Hardware configuration 1 partition.
189 *
190 * This contains several hardware feature switches.
191 */
193 /**
194 * Secret partition 0.
195 *
196 * This contains TEST lifecycle unlock tokens.
197 */
199 /**
200 * Secret partition 1.
201 *
202 * This contains SRAM and flash scrambling keys.
203 */
205 /**
206 * Secret partition 2.
207 *
208 * This contains RMA unlock token, creator root key, and creator seed.
209 */
211#if defined(OPENTITAN_IS_DRAGONFLY)
212 /**
213 * Secret partition 3.
214 *
215 * This contains the owner seed.
216 */
217 kDifOtpCtrlPartitionSecret3,
218#elif defined(OPENTITAN_IS_EGRET)
219// Egret only has 3 secret partitions.
220#else
221#error "dif_otp_ctrl does not support this top"
222#endif
223 /**
224 * Lifecycle partition.
225 *
226 * This contains lifecycle transition count and state. This partition
227 * cannot be locked since the life cycle state needs to advance to RMA
228 * in-field. Note that while this partition is not marked secret, it
229 * is not readable nor writeable via the DAI. Only the LC controller
230 * can access this partition, and even via the LC controller it is not
231 * possible to read the raw manufacturing life cycle state in encoded
232 * form, since that encoding is considered a netlist secret. The LC
233 * controller only exposes a decoded version of this state.
234 */
236
237 /**
238 * This is not a partition; rather, it represents the total number of
239 * partitions.
240 */
242
243 /**
244 * The following two are not partitions; rather they represent error codes
245 * that have a corresponding entry in dif_otp_ctrl_status_t.causes.
246 */
248 kDifOtpCtrlPartitionLciError,
249
250 /**
251 * This is not a partition; rather, it represents the total number of entries
252 * in dif_otp_ctrl_status_t.causes.
253 */
255
257
258/**
259 * Runtime configuration for OTP.
260 *
261 * This struct describes runtime information for one-time configuration of the
262 * hardware.
263 */
264typedef struct dif_otp_ctrl_config {
265 /**
266 * The timeout for an integrity or consistency check to succeed, in cycles.
267 *
268 * 100'000 is recommended as a minimum safe value.
269 */
271 /**
272 * A mask for the pseudo-random integrity check period.
273 *
274 * The value of this mask limits the period of the integrity check; when the
275 * pseudo-random period is computed, this mask is applied to limit it. For
276 * example, a value of 0x3'ffff would correspond to a maximum period of about
277 * 2.8s at 24MHz.
278 *
279 * A value of zero disables the check.
280 */
282 /**
283 * A mask for the pseudo-random consistency check period.
284 *
285 * The value of this mask limits the period of the consistency check; when the
286 * pseudo-random period is computed, this mask is applied to limit it. For
287 * example, a value of 0x3ff'ffff would correspond to a maximum period of
288 * about 716s at 24MHz.
289 *
290 * A value of zero disables the check.
291 */
294
295/**
296 * A hardware-level status code.
297 */
299 // Note that these enum variants are intended as bit indices, so
300 // their values should not be randomized.
301 /**
302 * Indicates that at least one partition raised an error.
303 */
305 /**
306 * Indicates an error occurred in the direct access interface.
307 */
309 /**
310 * Indicates an error occurred in the lifecycle interface.
311 */
313 /**
314 * Indicates that an integrity or consistency check has timed out.
315 *
316 * This error is unrecoverable.
317 */
319 /**
320 * Indicates that the LFSR that generates pseudo-random integrity and
321 * consistency checks is in a bad state.
322 *
323 * This error is unrecoverable.
324 */
326 /**
327 * Indicates that the scrambling hardware is in a bad state.
328 *
329 * This error is unrecoverable.
330 */
332 /**
333 * Indicates that the key derivation hardware is in a bad state.
334 *
335 * This error is unrecoverable.
336 */
338 /**
339 * Indicates a bus integrity error.
340 *
341 * This error will raise an alert.
342 */
344 /**
345 * Indicates that the direct access interface is idle.
346 */
348 /**
349 * Indicates that an integrity or consistency check is currently pending.
350 */
353
354/**
355 * A hardware-level error code, associated with a particular error defined in
356 * `dif_otp_ctrl_status_t`.
357 */
358typedef enum dif_otp_ctrl_error {
359 /**
360 * Indicates no error.
361 */
363 /**
364 * Indicates that an OTP macro command was invalid or did not
365 * complete successfully.
366 *
367 * This error indicates non-recoverable hardware malfunction.
368 */
370 /**
371 * Indicates a recoverable error during a read operation.
372 *
373 * A followup read should work as expected.
374 */
376 /**
377 * Indicates an unrecoverable error during a read operation.
378 *
379 * This error indicates non-recoverable hardware malfunction.
380 */
382 /**
383 * Indicates that the blank write check failed during a write operation.
384 */
386 /**
387 * Indicates a locked memory region was accessed.
388 */
390 /**
391 * Indicates a parity, integrity or consistency check failed in the buffer
392 * registers.
393 *
394 * This error indicates non-recoverable hardware malfunction.
395 */
397 /**
398 * Indicates that the FSM of the controller is in a bad state or that the
399 * controller's FSM has been moved into its terminal state due to escalation
400 * via the alert subsystem.
401 *
402 * This error indicates that the device has been glitched by an attacker.
403 */
406
407/**
408 * The overall status of the OTP controller.
409 *
410 * See `dif_otp_ctrl_get_status()`.
411 */
412typedef struct dif_otp_ctrl_status {
413 /**
414 * Currently active statuses, given as a bit vector. To check whether a
415 * particular status code was returned, write
416 *
417 * bool has_code = (status.codes >> kMyStatusCode) & 1;
418 *
419 * Note that it is possible to quickly check that the controller is idle and
420 * error-free by writing
421 *
422 * bool is_ok = status.codes == (1 << kDifOtpStatusCodeDaiIdle);
423 *
424 * Note this mapes to the "status" hw register.
425 */
426 uint32_t codes;
427 /**
428 * A list of root causes for each partition as well as for DAI and LCI.
429 * dif_otp_ctrl_partition_t can be used for indexing.
430 */
433
434/**
435 * Configures OTP with runtime information.
436 *
437 * This function should need to be called at most once for the lifetime of
438 * `otp`.
439 *
440 * @param otp An OTP handle.
441 * @param config Runtime configuration parameters.
442 * @return The result of the operation.
443 */
446 dif_otp_ctrl_config_t config);
447
448/**
449 * Runs an integrity check on the OTP hardware.
450 *
451 * This function can be used to trigger an integrity check independent of the
452 * pseudo-random hardware-generated checks.
453 *
454 * @param otp An OTP handle.
455 * @return The result of the operation.
456 */
459
460/**
461 * Runs a consistency check on the OTP hardware.
462 *
463 * This function can be used to trigger a consistency check independent of the
464 * pseudo-random hardware-generated checks.
465 *
466 * @param otp An OTP handle.
467 * @return The result of the operation.
468 */
471
472/**
473 * Locks out access to the direct access interface registers.
474 *
475 * This function is idempotent: calling it while functionality is locked will
476 * have no effect and return `kDifOk`.
477 *
478 * @param otp An OTP handle.
479 * @return The result of the operation.
480 */
483
484/**
485 * Checks whether access to the direct access interface is locked.
486 *
487 * Note that besides locking the DAI out until the next reset using the
488 * dif_otp_ctrl_dai_lock function, the DAI is also temporarily locked by the
489 * HW itself when it is busy processing a DAI command. In such a case, the
490 * kDifOtpCtrlStatusCodeDaiIdle status bit will be set to 0 as well.
491 *
492 * @param otp An OTP handle.
493 * @param[out] is_locked Out-param for the locked state.
494 * @return The result of the operation.
495 */
498 bool *is_locked);
499
500/**
501 * Locks out `dif_otp_ctrl_configure()` function.
502 *
503 * This function is idempotent: calling it while functionality is locked will
504 * have no effect and return `kDifOk`.
505 *
506 * @param otp An OTP handle.
507 * @return The result of the operation.
508 */
511
512/**
513 * Checks whether `dif_otp_ctrl_configure()` function is locked-out.
514 *
515 * @param otp An OTP handle.
516 * @param[out] is_locked Out-param for the locked state.
517 * @return The result of the operation.
518 */
521 bool *is_locked);
522
523/**
524 * Locks out `dif_otp_ctrl_check_*()` functions.
525 *
526 * This function is idempotent: calling it while functionality is locked will
527 * have no effect and return `kDifOk`.
528 *
529 * @param otp An OTP handle.
530 * @return The result of the operation.
531 */
534
535/**
536 * Checks whether the `dif_otp_ctrl_check_*()` functions are locked-out.
537 *
538 * @param otp An OTP handle.
539 * @param[out] is_locked Out-param for the locked state.
540 * @return The result of the operation.
541 */
544 bool *is_locked);
545
546/**
547 * Locks out reads to a SW partition.
548 *
549 * This function should only be called on SW partitions; doing otherwise will
550 * return an error.
551 *
552 * Note that this is distinct from the write-locking performed by calling
553 * `dif_otp_ctrl_dai_digest()`. In particular, the effects of this function will
554 * not persist past a system reset.
555 *
556 * This function is idempotent: calling it while functionality is locked will
557 * have no effect and return `kDifOk`.
558 *
559 * @param otp An OTP handle.
560 * @param partition The SW partition to lock.
561 * @return The result of the operation.
562 */
565 dif_otp_ctrl_partition_t partition);
566
567/**
568 * Checks whether reads to a SW partition are locked out.
569 *
570 * This function should only be called on SW partitions; doing otherwise will
571 * return an error.
572 *
573 * @param otp An OTP handle.
574 * @param partition the SW partition to check for locking.
575 * @param[out] is_locked Out-param for the locked state.
576 * @return The result of the operation.
577 */
580 dif_otp_ctrl_partition_t partition,
581 bool *is_locked);
582
583/**
584 * Gets the current status of the OTP controller.
585 *
586 * @param otp An OTP handle.
587 * @param[out] status Out-param for the controller's status.
588 * @return The result of the operation.
589 */
593
594/**
595 * Calculates a `relative_address` with respect to a `partition` start
596 * address.
597 *
598 * @param partition The partition to use to calculate the reference start
599 * address.
600 * @param abs_address Input address relative to the OTP memory start address.
601 * @param[out] relative_address The result relative address with respect to the
602 * `partition` start address.
603 * @return The result of the operation.
604 */
607 uint32_t abs_address,
608 uint32_t *relative_address);
609
610/**
611 * Schedules a read on the Direct Access Interface.
612 *
613 * Reads are performed relative to a partition; `address` should be given
614 * relative to the start of `partition`. An error is returned for out-of-bounds
615 * access.
616 *
617 * Furthermore, `address` must be well-aligned: it must be four-byte aligned for
618 * normal partitions and eight-byte-aligned for secret partitions. An error is
619 * returned for unaligned access.
620 *
621 * @param otp An OTP handle.
622 * @param partition The partition to read from.
623 * @param address A partition-relative address to read from.
624 * @return The result of the operation.
625 */
628 dif_otp_ctrl_partition_t partition,
629 uint32_t address);
630
631/**
632 * Gets the result of a completed 32-bit read operation on the Direct Access
633 * Interface.
634 *
635 * Whether this function or its 64-bit variant should be called is dependent on
636 * the most recent partition read from.
637 *
638 * @param otp An OTP handle.
639 * @param[out] value Out-param for the read value.
640 * @return The result of the operation.
641 */
644 uint32_t *value);
645
646/**
647 * Gets the result of a completed 64-bit read operation on the Direct Access
648 * Interface.
649 *
650 * Whether this function or its 32-bit variant should be called is dependent on
651 * the most recent partition read from.
652 *
653 * @param otp An OTP handle.
654 * @param[out] value Out-param for the read value.
655 * @return The result of the operation.
656 */
659 uint64_t *value);
660
661/**
662 * Schedules a 32-bit write on the Direct Access Interface.
663 *
664 * Writes are performed relative to a partition; `address` should be given
665 * relative to the start of `partition`. An error is returned for out-of-bounds
666 * access.
667 *
668 * Furthermore, `address` must be four-byte-aligned, and `partition` must not be
669 * a secret partition. An error is returned if neither condition is met.
670 *
671 * Note that this function cannot be used to program the digest at the end of a
672 * `SW` partition; `dif_otp_ctrl_dai_digest()` must be used instead.
673 *
674 * @param otp An OTP handle.
675 * @param partition The partition to program.
676 * @param address A partition-relative address to program.
677 * @param value The value to program into the OTP.
678 * @return The result of the operation.
679 */
682 dif_otp_ctrl_partition_t partition,
683 uint32_t address, uint32_t value);
684
685/**
686 * Schedules a 64-bit write on the Direct Access Interface.
687 *
688 * Writes are performed relative to a partition; `address` should be given
689 * relative to the start of `partition`. An error is returned for out-of-bounds
690 * access.
691 *
692 * Furthermore, `address` must be eight-byte-aligned, and `partition` must be
693 * a secret partition. An error is returned if neither condition is met.
694 *
695 * @param otp An OTP handle.
696 * @param partition The partition to program.
697 * @param address A partition-relative address to program.
698 * @param value The value to program into the OTP.
699 * @return The result of the operation.
700 */
703 dif_otp_ctrl_partition_t partition,
704 uint32_t address, uint64_t value);
705
706/**
707 * Schedules a hardware digest operation on the Direct Access Interface.
708 *
709 * **This operation will also lock writes for the given partition.**
710 *
711 * If `partition` is a SW partition, `digest` must be non-zero; if it is a
712 * partition with a hardware-managed digest, `digest` *must* be zero (since the
713 * digest will be generated by the hardware). An error is returned if either
714 * precondition is not met.
715 *
716 * This function does not work with the lifecycle state partition, and will
717 * return an error in that case.
718 *
719 * @param otp An OTP handle.
720 * @param partition The partition to digest and lock.
721 * @param digest The digest to program (for SW partitions).
722 * @return The result of the operation.
723 */
726 dif_otp_ctrl_partition_t partition,
727 uint64_t digest);
728
729/**
730 * Checks if the digest value for the given partition has been computed. Once a
731 * digest has been computed for a partition, the partition is write-locked
732 * (additionally, read-locked if the partition is secret).
733 *
734 * The lifecycle partition does not have a digest, and checking if this region
735 * has a computed digest will return an error.
736 *
737 * @param otp An OTP handle.
738 * @param partition The partition to check the digest of.
739 * @param[out] is_computed Indicates if the digest has been computed.
740 * @return The result of the operation.
741 */
744 dif_otp_ctrl_partition_t partition,
745 bool *is_computed);
746
747/**
748 * Gets the buffered digest value for the given partition.
749 *
750 * Note that this value is only updated when the device is reset; if the digest
751 * has not been computed yet, or has been computed but not since device reset,
752 * this function will return an error.
753 *
754 * The lifecycle partition does not have a digest and will result in an error
755 * being returned.
756 *
757 * @param otp An OTP handle.
758 * @param partition The partition to get a digest for.
759 * @param[out] digest Out-param for the digest.
760 * @return The result of the operation.
761 */
764 dif_otp_ctrl_partition_t partition,
765 uint64_t *digest);
766
767/**
768 * Performs a memory-mapped read of the given partition, if it supports them.
769 *
770 * In particular, this function will read `len` words, starting at `address`,
771 * relative to the start of `partition`.
772 *
773 * The same caveats for `dif_otp_ctrl_dai_read_start()` apply to `address`; in
774 * addition, `address + len` must also be in-range and must not overflow.
775 *
776 * This function will block until the read completes, unlike Direct Access
777 * Interface functions.
778 *
779 * @param otp An OTP handle.
780 * @param partition The partition to read from.
781 * @param address A partition-relative address to read from.
782 * @param[out] buf A buffer of words to write read values to.
783 * @param len The number of words to read.
784 * @return The result of the operation.
785 */
788 dif_otp_ctrl_partition_t partition,
789 uint32_t address, uint32_t *buf,
790 size_t len);
791
792#ifdef __cplusplus
793} // extern "C"
794#endif // __cplusplus
795
796#endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_OTP_CTRL_H_