@@ -490,6 +490,11 @@ REG32(LC_STATE, 16344u)
490490#define DAI_DIGEST_DELAY_NS 50000u /* 50us */
491491#define LCI_PROG_SCHED_NS 1000u /* 1us*/
492492
493+ /* The size of keys used for OTP scrambling */
494+ #define OTP_SCRAMBLING_KEY_WIDTH 128u
495+ #define OTP_SCRAMBLING_KEY_BYTES ((OTP_SCRAMBLING_KEY_WIDTH) / 8u)
496+
497+ /* Sizes of constants used for deriving scrambling keys (e.g. SRAM, OTBN) */
493498#define SRAM_KEY_SEED_WIDTH (SRAM_DATA_KEY_SEED_SIZE * 8u)
494499#define KEY_MGR_KEY_WIDTH 256u
495500#define SRAM_KEY_WIDTH 128u
@@ -749,6 +754,8 @@ struct OtOTPDjState {
749754 uint8_t digest_const [16u ];
750755 uint64_t sram_iv ;
751756 uint8_t sram_const [16u ];
757+ /* OTP scrambling key constants, not constants for deriving other keys */
758+ uint8_t * otp_scramble_keys [ARRAY_SIZE (OtOTPPartDescs )]; /* may be NULL */
752759 uint8_t * inv_default_parts [ARRAY_SIZE (OtOTPPartDescs )]; /* may be NULL */
753760
754761 OtOTPStorage * otp ;
@@ -765,6 +772,7 @@ struct OtOTPDjState {
765772 char * digest_iv_xstr ;
766773 char * sram_const_xstr ;
767774 char * sram_iv_xstr ;
775+ char * otp_scramble_key_xstrs [ARRAY_SIZE (OtOTPPartDescs )]; /* may be NULL */
768776 char * inv_default_part_xstrs [ARRAY_SIZE (OtOTPPartDescs )]; /* may be NULL */
769777 uint8_t edn_ep ;
770778 bool fatal_escalate ;
@@ -3667,6 +3675,65 @@ static void ot_otp_dj_configure_sram(OtOTPDjState *s)
36673675 s -> sram_iv = ldq_le_p (sram_iv );
36683676}
36693677
3678+ static void ot_otp_dj_configure_part_scramble_keys (OtOTPDjState * s )
3679+ {
3680+ for (unsigned ix = 0u ; ix < ARRAY_SIZE (OtOTPPartDescs ); ix ++ ) {
3681+ if (!s -> otp_scramble_key_xstrs [ix ]) {
3682+ continue ;
3683+ }
3684+
3685+ size_t len = strlen (s -> otp_scramble_key_xstrs [ix ]);
3686+ if (len != OTP_SCRAMBLING_KEY_BYTES * 2u ) {
3687+ error_setg (
3688+ & error_fatal ,
3689+ "%s: %s Invalid OTP scrambling key length %zu for partition %u" ,
3690+ __func__ , s -> ot_id , len , ix );
3691+ return ;
3692+ }
3693+
3694+ g_assert (!s -> otp_scramble_keys [ix ]);
3695+
3696+ s -> otp_scramble_keys [ix ] = g_new0 (uint8_t , OTP_SCRAMBLING_KEY_BYTES );
3697+ if (ot_common_parse_hexa_str (s -> otp_scramble_keys [ix ],
3698+ s -> otp_scramble_key_xstrs [ix ],
3699+ OTP_SCRAMBLING_KEY_BYTES , true, true)) {
3700+ error_setg (& error_fatal ,
3701+ "%s: %s unable to parse otp_scramble_keys[%u]" , __func__ ,
3702+ s -> ot_id , ix );
3703+ return ;
3704+ }
3705+
3706+ TRACE_OTP ("otp_scramble_keys[%s] %s" , PART_NAME (ix ),
3707+ ot_otp_hexdump (s , s -> otp_scramble_keys [ix ],
3708+ OTP_SCRAMBLING_KEY_BYTES ));
3709+ }
3710+ }
3711+
3712+ static void ot_otp_dj_class_add_scramble_key_props (OtOTPClass * odc )
3713+ {
3714+ unsigned secret_ix = 0u ;
3715+ for (unsigned ix = 0u ; ix < ARRAY_SIZE (OtOTPPartDescs ); ix ++ ) {
3716+ if (!OtOTPPartDescs [ix ].secret ) {
3717+ continue ;
3718+ }
3719+
3720+ Property * prop = g_new0 (Property , 1u );
3721+
3722+ /*
3723+ * Assumes secret partitions are sequentially ordered and named
3724+ * SECRET0, SECRET1, SECRET2, SECRET3 etc.
3725+ */
3726+ prop -> name = g_strdup_printf ("secret%u_scramble_key" , secret_ix ++ );
3727+ prop -> info = & qdev_prop_string ;
3728+ prop -> offset = offsetof(OtOTPDjState , otp_scramble_key_xstrs ) +
3729+ sizeof (char * ) * ix ;
3730+
3731+ object_class_property_add (OBJECT_CLASS (odc ), prop -> name ,
3732+ prop -> info -> name , prop -> info -> get ,
3733+ prop -> info -> set , prop -> info -> release , prop );
3734+ }
3735+ }
3736+
36703737static void ot_otp_dj_configure_inv_default_parts (OtOTPDjState * s )
36713738{
36723739 for (unsigned ix = 0 ; ix < ARRAY_SIZE (OtOTPPartDescs ); ix ++ ) {
@@ -3891,6 +3958,7 @@ static void ot_otp_dj_realize(DeviceState *dev, Error **errp)
38913958 ot_otp_dj_configure_scrmbl_key (s );
38923959 ot_otp_dj_configure_digest (s );
38933960 ot_otp_dj_configure_sram (s );
3961+ ot_otp_dj_configure_part_scramble_keys (s );
38943962 ot_otp_dj_configure_inv_default_parts (s );
38953963}
38963964
@@ -3998,6 +4066,7 @@ static void ot_otp_dj_class_init(ObjectClass *klass, void *data)
39984066 oc -> get_keymgr_secret = & ot_otp_dj_get_keymgr_secret ;
39994067 oc -> program_req = & ot_otp_dj_program_req ;
40004068
4069+ ot_otp_dj_class_add_scramble_key_props (oc );
40014070 ot_otp_dj_class_add_inv_def_props (oc );
40024071}
40034072
0 commit comments