Post Go back to editing

Problem Accessing OTP memory using ADI OTP service

Category: Software
Product Number: ADSP-SC598
Software Version: CCES 2.11.1

Hello!

We are trying to create a separate boot-time utility that will handle the programming of the OTP memory (programming the secure key, and handle the locking part).

We already have an early loader with the purpose to launch linux (not using u-boot), it's a sort of a shim loader that mainly unpacks the kernel, places the device tree at the right location and then launch linux in EL3.

This part has been working fine for us.

Now we want to add some additional functionality in it that enables it to program the OTP memory in a separate boot flow.
In a first attempt, we try to just simply read something out from the OTP memory in order to see that we at least can access it.

We are using the OTP service api in the cces libraries (adi_otp_v1).

We call adi_otp_Open() providing a sufficient memory for it and a status callback.

Then call adi_otp_SecurityEnable() with the returned handle with false as parameter (to enable the access to the memory).

Then we try to just read out any part of the otp memory. As an example we try to read out using adi_otp_Read() with the ADI_OTPCMD_PVTKEY0 as a command.

Here is where we fail, with some uart-logging we can see that we end up in the internal do_read() function where it gets stuck (it seems like it's only derefencing the otp memory pointer to read out the requested data).

We do not get any calls back from the SMPU in our provided status handler.

This leads us to think that may need to initialize or set something else up before we start using the service.

We cannot find any usage examples of this api anywhere and are out of ideas what is missing or what goes wrong here.

Is there anything else that must be prepared before using this api? Some specific clocks set up (CGU/CDU), or some other stuff in the SPU or the SMPU, or maybe even something specific in the MMU?

We can see that there are slight changes in the code for this otp service in the latest CCES 3.0.1, but haven't tried it yet. This makes us wonder if this api was working in CCES 2.11.1 at all.

The 3.0.1 version appears to omit the SMPU setup, if the target is SC598.

Grateful for some ideas or directions for accessing the OTP memory (any code examples would be great).

Best Regards,

Lars

Parents
  • Hi Lars,

    While looking into your query, it seems that the adi_otp_Read() is working as expected in CCES 2.11.1 and not working in CCES 3.0.1. Please confirm whether our understanding is correct.

    If yes, some OTP sources are missing in the CCES 3.0.1 installation path, and it has been already logged in the bug report. We are checking on this and will get back to you as soon as possible.

    Regards,
    Ranjitha R

  • Hi Ranji!
    Thanks for the answer!

    Actually, suddenly it started working! And to be honest I am not sure in my memory what made it work, after a lot of different testing.

    It just might have been that I provided the destination buffer in RAM with the wrong size (or something like that).

    I should have updated my question earlier to inform about things looking much better, sorry for that.

    I have also been successful in writing to the OTP as well (I used the GP1 area offset since it's not important to us if I overwrite and destroy cells there on my unit).

    There was however one strange observation:
    If I have understood things properly about the OTP, regardless of where in the OTP memory I write something it should work to write at one specific location only once (One-Time-Programmable memory in that exact sense).

    So I wrote the first GP1 as an uint32. Just put in a hexvalue of "0xABBACAFE".

    During that run, I observed that I could read back the very same value (into a different RAM buffer to be sure). I got the same value back as expected.

    The next time I tried writing to that very same location in GP1, it failed (probably completely expected if my understanding is correct).
    However, the value DID change to 0xCAFE0000 (so it seemed to have succeded with writing 16 lower bits of that uint32, but writing zeroes).
    After this no changes are accepted to the OTP on that GP1 uint32 offset (also probably expected), but I am surprised that that uint32's lower 16 bits DID change the second time I wrote it to zeroes.

    Can this happen? Is it even some sort of feature, like say to invalidate something?

    Regards,

    Lars

  • Hi Lars,

    Glad to know that the API issue got resolved and thanks for the update.

    Regarding "no changes are accepted to the OTP on that GP1 uint32 offset (also probably expected)"
    >> Yes, your understanding is correct. But the data available in the OTP may corrupt if the same space is tried to rewrite with same/different data.

    Basically, we can program OTP with different offset if the incorrect data is program. In order to use the another offset, we need to invalidate the current offset and then we can program and use the another offset in the OTP.

    But it seems that one GP1 space is available in ADSP-SC598 and unfortunately it cannot be modified since it is corrupted.

    Regards,
    Ranjitha.R

  • Hi again Ranji,

    Thanks for the good clarifications!

    I am now at the point to start testing my tool for writing the OTP keys (it is intended to be started as a tool in a third boot stage in a production sequence). My tool will have the responsibility to both program the keys and flash the secure loader(s) in the NOR.

    Despite me having thorougly tested the generated images with the keys with the ADI "securebootsim" tool to decrypt/authenticate boot images (and some x86 based simulated testing for my code) it is still a bit nerve-wrecking to actually program the keys the first time.

    So I have one question of what I should expect..

    The first time we won't lock the OTP (yet), only program the private/public/jag emu keys in the OTP (in their respective first key "slot").

    * When this is done, will then the system only boot encrypted + signed images (despite the OTP not being locked), or will it at this point accept both encrypted / signed images and non-signed / non-encrypted images?

    I haven't found any clarification on that detail in the documentation (or perhaps I've missed it).

    Grateful for answer on this.

    Regards,

    Lars

  • Hi Lars,

    Yes, your understanding is correct. If the OTP is not locked but the keys are programmed, the system will accept both encrypted/signed images and non-signed/non-encrypted images.

    Regards,
    Ranjitha.R

  • Thanks Ranjitha,

    That answer made me much more comfortable to start actual testing of my own OTP programmer tool on a real device!

    Regards,

    Lars W.

  • Hello again Ranji!

    Before vacation I finally did run a sharp programming of the OTP keys AND at the same time, my tool programmed secure BLx images into the flash (both a first stage loader at offset 0 in the flash and a second stage loader, also secure at 0x10000). The first one boots the other using the adi_rom_Boot() function, e.g.:

    adi_rom_Boot((void*)0x60010000, 0, 0, 0, 0x10207);

    I did NOT lock the OTP memory.

    To my surprise, the system did not boot at all.

    After vacations I programmed back the non-secure variants of these loaders at the same locations into flash using JLink SPI flasher.

    To my relief the system boots again with non-secure images.

    My tool reports that the keys were properly programmed to OTP according to the keys it carries internally.

    This tells me that the OTP ROM will NOT boot any secure images when the keys are programmed but the OTP memory is not yet locked.

    Even though I have tested these images with the adi_securebootsim tool with success (it produces the original images back as result), I am however now not yet confident enough to lock the memory (I have a second lock-tool image ready, dedicated only for that purpose).

    I have read in the document EE66v02.pdf (which I believe applies to the SC589 SOM's) that using a JTAG emulator I can simulate with a separate loader using the hook function that enables the secure boot by modifying flags in the boot config.

    It looks like this SecureBoot_OpenPart example project that boots from an emulator does this specially adapted kind of boot, enforcing encrypted mode on the open part. I am not sure if this confirms that when a part is open, it will not try to boot encrypted/signed BLx images?

    Are there are any updates of documents to the secure booting process for the SC598 SOM's (later than EE66v02.pdf document that seems to be for the SC589)?

    Regards

    Lars

  • Hi Lars,
    For further assistance, please contact us in private support via processor.support@analog.com email address.
    Kindly include the link to this Ezone thread in your message.
    Regards,
    Nandini C
  • Hi Nandini,
    Many thanks, I will do so!

  • I finally managed to get the system booting with out secure loaders!

    I just want to close this by finally stating the reason for the troubles I had.

    For newer ADI parts (like the SC59x family), the signing tool to use is "adi_signtool", NOT the "signtool".

    It is a simple detail that is pretty easy to miss.

    As an example for signing (linux, SC598, ecdsa224 based key), it could look like this:

    "<cces_path>/adi_signtool" -proc ADSP-SC598 -add-sbh-hash-224 sign -type BLx -attribute 0x80000003=224 -prikey ./Keys/224_ECDSA/keypair.bin -enckey ./Keys/224_ECDSA/encrypt_key.bin -infile <path_to_unsigned_loader.ldr> -outfile <path_to_signed_loader.ldr>

    And of course similarly for ecdsa256 based key:

    "<cces_path>/adi_signtool" -proc ADSP-SC598 -add-sbh-hash-256 sign -type BLx -attribute 0x80000003=256 -prikey ./Keys/256_ECDSA/keypair.bin -enckey ./Keys/256_ECDSA/encrypt_key.bin -infile <path_to_unsigned_loader.ldr> -outfile <path_to_signed_loader.ldr>

    And finally, many thanks to ADI support staff for your help, sincerely appreciated.

    Regards,

    Lars

Reply
  • I finally managed to get the system booting with out secure loaders!

    I just want to close this by finally stating the reason for the troubles I had.

    For newer ADI parts (like the SC59x family), the signing tool to use is "adi_signtool", NOT the "signtool".

    It is a simple detail that is pretty easy to miss.

    As an example for signing (linux, SC598, ecdsa224 based key), it could look like this:

    "<cces_path>/adi_signtool" -proc ADSP-SC598 -add-sbh-hash-224 sign -type BLx -attribute 0x80000003=224 -prikey ./Keys/224_ECDSA/keypair.bin -enckey ./Keys/224_ECDSA/encrypt_key.bin -infile <path_to_unsigned_loader.ldr> -outfile <path_to_signed_loader.ldr>

    And of course similarly for ecdsa256 based key:

    "<cces_path>/adi_signtool" -proc ADSP-SC598 -add-sbh-hash-256 sign -type BLx -attribute 0x80000003=256 -prikey ./Keys/256_ECDSA/keypair.bin -enckey ./Keys/256_ECDSA/encrypt_key.bin -infile <path_to_unsigned_loader.ldr> -outfile <path_to_signed_loader.ldr>

    And finally, many thanks to ADI support staff for your help, sincerely appreciated.

    Regards,

    Lars

Children
No Data