[EXTERNAL] Re: Proposal for a New Command to U-Boot Fuse Programming
Harsha Vardhan V M
h-vm at ti.com
Mon Jan 27 11:52:36 CET 2025
On 25/01/25 00:59, Tom Rini wrote:
> On Fri, Jan 24, 2025 at 02:31:15PM +0530, Harsha Vardhan V M wrote:
>>
>>
>> On 22/01/25 22:52, Tom Rini wrote:
>>> On Fri, Jan 10, 2025 at 11:12:47AM +0530, Harsha Vardhan V M wrote:
>>>>
>>>>
>>>> On 07/01/25 03:53, Tom Rini wrote:
>>>>> On Mon, Jan 06, 2025 at 12:06:25PM +0530, Harsha Vardhan V M wrote:
>>>>>
>>>>>> I would like to propose a new command for U-Boot's fuse programming
>>>>>> functionality to address the challenges posed by the current implementation.
>>>>>> While the existing fuse prog command works well for programming individual
>>>>>> fuse values, it becomes cumbersome especially when dealing with large-scale
>>>>>> programming requirements.
>>>>>>
>>>>>> Current Command: fuse prog [-y] <bank> <word> <hexval> [<hexval>...]
>>>>>>
>>>>>> This command programs one or more fuse words starting from a specific <bank>
>>>>>> and <word> with the hex values given as input.
>>>>>>
>>>>>> While functional, it lacks the efficiency and robustness needed for
>>>>>> programming a significant number of fuses or handling structured fuse
>>>>>> configuration data. Repeatedly specifying values for each fuse bank and word
>>>>>> is not only time-consuming but also prone to errors during manual input or
>>>>>> scripting. This approach does not leverage the ability to process
>>>>>> pre-structured data in memory. For users with complex programming needs, the
>>>>>> current method becomes an obstacle rather than a tool.
>>>>>>
>>>>>> Proposed Command: fuse writebuff
>>>>>
>>>>> It would be good to provide some documentation links to the fuses that
>>>>> you're wanting to deal with. What we have now works on a number of
>>>>> diverse SoCs, even if for some cases it might be best to write a
>>>>> script that's run rather than copy/paste things live. Any sort of new
>>>>> mechanism needs to get feedback from users at other semiconductor
>>>>> vendors to make sure it's generic enough for everyones needs. Thanks.
>>>>>
>>>>
>>>> Hi Tom and Simon,
>>>>
>>>> The buffer is not a text file. It is a structure in memory. The buffer is
>>>> structured to contain all necessary information for the fuse programming
>>>> process. This can include metadata, fuse programming data etc. The exact
>>>> structure of the buffer can determined by the command_id, which provides
>>>> flexibility for supporting different use cases. The memory buffer is
>>>> typically prepared in user-space code or a script and loaded in memory
>>>> before invoking the fuse writebuff command. It is not stored as a text file
>>>> or any other file format, as the command operates directly on memory
>>>> addresses.
>>>>
>>>> Example of a buffer:
>>>>
>>>> struct fuse_buffer {
>>>> struct fuse_mpkh smpkh;
>>>> struct fuse_msv msv;
>>>> struct fuse_key_cnt key_cnt;
>>>> u8 buffer_hash[64];
>>>> };
>>>>
>>>> This fuse_buffer struct will be loaded in memory containing all the
>>>> necessary information for fuse programming.
>>>>
>>>> struct fuse_mpkh {
>>>> u8 mpkh[64]; // public key hash
>>>> u8 bch[8];
>>>> u32 attributes; // read-protect, write-protect, override, active flag
>>>> u32 reserved[2];
>>>> };
>>>> struct fuse_msv {
>>>> u32 msv_with_bch; //model specific value
>>>> u32 attributes;
>>>> u32 reserved[2];
>>>> };
>>>> struct fuse_key_cnt {
>>>> u32 key_cnt; //key count
>>>> u32 attributes;
>>>> u32 reserved[2];
>>>> };
>>>>
>>>> -> eFUSE layout is abstract and isn't public as its programming and layout
>>>> itself is security sensitive (it has authentication and decryption keys
>>>> etc). So, fuse prog doesn't work as there is no "banks/offset" here.
>>>> -> Platform Security Core running Secure SW exposes APIs through which these
>>>> Keys and its attributes can be programmed. Whole content maybe encrypted for
>>>> enhanced security on unsecure factory floor.
>>>> -> There is a definite order in which these fields needs to be programmed.
>>>>
>>>> Its possible to break the struct into 32bit values and send them across but
>>>> we would end up with ~30 odd fuse prog cmds which is inefficient and error
>>>> prone.
>>>> It would be hard on secure core to also ensure correctness of operations
>>>> against all sorts of silly errors (such of accidentally skipping a word or
>>>> mess up ordering) which can render Silicon unusable.
>>>>
>>>> So passing a opaque pointer with a command_id to Secure core is all that
>>>> fuse cmd needs to do which is what writebuff supports.
>>>>
>>>> This can be extended to any vendor; It's just an opaque pointer handoff. I
>>>> see at least one other vendor do it in custom way:
>>>> arch/arm/mach-imx/cmd_dek.c which could benefit from this new cmd fuse
>>>> writebuff.
>>>>
>>>> Here’s how the fuse writebuff command works in a typical flow:
>>>> 1. Buffer Preparation: Vendors or developers create a complete buffer (e.g.,
>>>> key.bin) containing all fuse programming data using vendor-specific scripts
>>>> or tools and copied to SD card.
>>>> 2. The buffer is loaded into memory using commands like:
>>>> fatload mmc 1 0x80000000 key.bin
>>>> 3. The fuse writebuff command passes the memory address (0x80000000) and
>>>> command_id to the secure core:
>>>> fuse writebuff <command_id> 0x80000000
>>>> 4. The secure core receives the memory address as a pointer and validates,
>>>> interprets it based on the command_id and then programs the fuses.
>>>
>>> To summarize what we talked about on a call, I would like to see either:
>>> 1) Work with arch/arm/mach-imx/cmd_dek.c and use that as the base of
>>> some new generic command that deals with SoC-specific fuse
>>> configurations that are handled via security processor.
>> Hi Tom,
>>
>> 1) I have looked at arch/arm/mach-imx/cmd_dek.c. The underlying
>> implementation data structure is very specific to the vendor and how iMX
>> devices are configured. The other vendors would also differ in their
>> structures and SoC-specific fuse configurations, so I don't see a way to use
>> this cmd_dek.c as the base and then abstract, create a new command out of
>> it.
>>
>>> OR
>>> 2) Create a new command (that should be in cmd/ti/) for handling the K3
>>> fuses, if we cannot make something abstract enough to handle this
>>> concept on multiple vendors while having any sort of useful code re-use.
>>
>> 2) In this case, I would like to add the fuse writebuff command for TI’s K3
>> architecture in cmd/ti/k3_fuse.c. And the command will look like
>>
>> fuse writebuff <command_id> <addr>
>>
>> However, I would still like to place the fuse writebuff command in
>> cmd/fuse.c as a generic interface because the parameters command_id and an
>> opaque pointer handoff provides a mechanism for the secure core to interpret
>> buffers differently based on vendor or use case.
>
> This I guess is my confusion. If we can't abstract cmd_dek.c and the
> underlying i.MX specific parts to be supported in "fuse writebuff ..."
> what is the non-K3 (or better still, non-TI) abstraction for what you're
> proposing?
>
Hi Tom,
There are two types of fuse programming flows;
a) Where the fuse layout is known to U-Boot -> fuse cmd options support
this flow today
b) Where fuse cmd is abstracted from U-Boot -> needs a co-processor to
proxy the programming
For b) the fuse layout is virtualized via a "vendor-specific" structure
which is generated offline (typically with GUI tools) and then loaded to
memory from a file on SD card . This pointer would then be relayed to Co
processor as a IPC call...
So, whats common b/w cmd_dek.c and TI's fuse cmd -> loading opaque
struct to memory and then passing it to Secure co-processor along with
one or more command identifiers which will serve as hint for such secure
co-processor.
"fuse writebuff" tries to abstract essentially this: take a cmd_id and
file pointer from fuse cmd and pass to it Vendor specific backend. I
know its not a lot but frontend tools used to flash the devices can
still make the most of it with simple vendor neutral abstractions than
needing to know custom command for each vendor.
What cannot be abstracted is:
a) struct of the file,
b) common definition of command Id
c) IPC mechanisms
Unfortunately all the above 3 are tightly coupled to co-processor on the
other end which most likely is immutable for most SoCs...
Thanks,
Harsha
More information about the U-Boot
mailing list