Digital signatures for RP2350 boards

(This is split out from @henrygab’s discussions in OTP whitelabel options for RP2350 boards, and is by no means a priority or important. It’s a thought experiment that I’d like to engage in with the community.)

The RP2350 boards have an OTP area that can be used to store things, uh, once. There have been discussions about what to put there; I’d like to put in a plug for a digital signature in the form of an x509 certificate.

But why is it important or necessary?

The Bus Pirate is open source, so where would be the benefit/value-add of a digital signature?

It would be good for Dangerous Prototypes to be able to authenticate that any individual BP is one that they produced, what the serial number is, and when it was produces from the standpoint of tracking, recall, warranty. @ian has been absolutely amazing when it comes to customer service, but at some point it will become important from a business standpoint to more easily and reliably be able to know these things.

Note that I am not saying that there should be some functionality limited only to “official” BPs; only that “official” BPs be easily identified.

Why an x509 certificate?

This is a pretty industry standard method. The cert is signed by a private key held by Dangerous Prototypes and can be authenticated by anyone using the public key. That public key would be hard-coded into the firmware.

What kind of stuff would be in the cert?

  • Validity: the Not Before date would be the manufacturing date. Set the Not After 10 years later or so; we really only care about the mfg date.
  • Subject:
    • C: probably NL?
    • O: probably Dangerous Prototypes?
    • OU: maybe BusPirate
    • CN: maybe a description including hardware ver, like BP7rev1
  • x509 Extensions:
    • serial number
    • I would say mfg location code if there is ever a plan to make them anywhere besides DirtyPCBs
    • anything else?
How to create the cert?

This would be need to be done at manufacturing:

  • A signing server is on the network, and available to the assembly station where loading takes place.
  • The manufacturing computer gets the next serial number (many, many ways to handle this), and sends it to the signing server along with other needed information like hardware model and rev.
  • The signing server creates a new cert with today’s date and the other stuff in the Subject field
  • The signing server encodes the serial number as an extension (either bit string or integer; whatever makes sense)
  • The server sends the .der-formatted cert to the the mfg computer
How to add the cert?

This would be a manufacturing process. Just like the firmware is loaded at manufacturing, there would need to be an additional process. (Does manufacturing do something like the self test?

There are 2 ways I can think of:

  1. There is a special “manufacturing” version of firmware:
    • This version is not functional
    • This version has some test features used in mfg
    • This version has a method to copy the cert (in .der format) into OTP, and verify it is there correctly.
    • Caveat - Either mfg or the end user has to load the “standard” firmware. When I worked in the ICS supplier world, we would ship it many things with the mfg firmware, forcing the end user to load the latest (or desired) firmware before commissioning the product.
  2. The “standard” firmware has the OTP write functions:
    • Mfg would use this to load the cert
    • The function would just fail with an error like “OTP already programmed”
The cert is in OTP, now what?

The running firmware has the public key hard-coded, so whenever it needs to reference the cert, the firmware would first authenticate the cert with that key. If the cert is “OK”, the firmware could extract the important information (mfg date, serial number, hardware information) and populate a global data structure.

When to do this?

  • On init? (this wouldn’t take a lot of time)
  • When the i info command is issued? Then the info could be added to the info output (or some values indicating it is not a “genuine” BP)

When else?

  • When the format command is issued, the firmware could copy the cert from OTP to the filesystem. That would be kind of cool - a user could look at the cert themselves.
What could go wrong?

CAVEAT - I have not threat-modeled this, so these are just off the top of my head

  • OTP Corruption - this is a valid BP, but somehow the OTP was corrupted (either at write or some other time)
  • Loss of confidentiality of the private signing key. This can be a hard problem to solve when using a manufacturing facility you don’t control. I would guess it’s not a problem now, but something to think about.
  • Errors in the manufacturing process; the cert generation/OTP process is missed due to human error or lack of training.
  • Forgeries:
    • A bad actor could make BPs and copy the contents of the OTP to their product. That data would pass validation and show as a “genuine” BP, but every one the bad actor made would have the same serial number and mfg date
    • A bad actor could create their own private/public keypair and make their own certs and load them into OTP. They would also fork/clone the firmware and change it to use their public key. The BPs they make would have unique serial numbers and mfg dates that would validate until the user (or anyone else) loads firmware from Dangerous Prototypes.

The good thing is that an error or problem with the signature really doesn’t cause a lot of problems. To the user/consumer, their Bus Pirate will function correctly; but there may be an issue with warranty or a missed tracking/recall campaign. I don’t forsee forgeries becoming an issue.

Ok, that was a little long winded, but thoughts? I could argue it adds complexity with minimal value added, but it’s still worth talking about.

(Note - this sounds interesting, so I just ordered a few $5.00 2350 boards to experiment with. Just what I needed - another distraction! :D)

2 Likes

This is the hardest part, imho. Can the cert generation / programming be split from the signing of the cert?

The goal would be to prevent the signing certificate from being exposed. I think at least Azure provides a Hardware Storage Module for securely generating and securing keys, allowing digital signatures to be done without anyone ever seeing the keys.

All the above adds complexity; Key rotation, intermediate key levels, parsing of certificates, certificate revocation, expiration dates, etc.

And … I’d recommend creating multiple signatures, at least two of which use post-quantum algorithms…

2 Likes

Yup, that is the hardest part of any PKI.

The way I’ve handled it was an intermediate server that one would set up the CSR, and would be the only one that could talk to the signing server. The signing server was the only thing that could access the HSM…. That was a high stakes operation; critical infrastructure, etc.

What really needs to happen is a solid, thorough threat model. It comes down to what the actual risks, and more importantly the impacts, are. That threat model then helps guide what would be done.

1 Like

Interesting part in this discussion is threat model.

If what you want is some level of traceability do you need to go over board.

In this case I would generate a self signed key for each production run, or a key signed by BP.

With a date range covering the production run. If the run is going to take 30 days generate a 30 day key, if this key gets in the wild and used elsewhere it will be obvious when used a year later.

The conversation started with simple writing of OTP memory, I like the idea of signing the data but this is not signing a bank transfer.

1 Like

One of the points of threat modeling is that we might come to the conclusion that “the impact is low, we don’t need to go to the level of an HSM to manage our PKI”. :slightly_smiling_face:

1 Like

While there may be cheaper clones some day, buying an “official” model is the best way to show support for the creator.

3 Likes

I bought two. a 5 and 6! :rofl:

1 Like

I bought a 3.5 and 5 for personal use; purchased a few 3.5’s over the years for use with employers :slightly_smiling_face:

Lol, my coworkers would smile every time I described using a Bus Pirate in my test reports.

2 Likes

Just to clarify: what exactly do you mean by “serial number” in this context? A serial number of a Bus Pirate, that is counted up sequentially?
Or the randomly created serial number that is written into the OTP of the RP2350 by RasPi during their manufacturing?

I suggest to make the random serial of the RP2350 part of the certificate, regardless if there is a sequential serial of BusPirates created during manufacturing or not: a forger could otherwise just duplicate several serials and their certificates. Since the OTP serial of the RP2350 is preprogrammed and designed to be unique for practical purposes, the forger wouldn’t be able to create a RP2350 with the same serial. The actual serial of the RP2350 and the one in the cert could then be compared by firmware.

One solution would be to use an intermediate certificate, like it is done by commecial certification authorities: The actual root certificate is kept by ian and never handed out. He then uses this to create an intermediate cert. This intermediate cert has a very limited validity time, just enough for one production batch. This is then given to the manufacturing company to do one production run.

If someone at the factory were to do a “night shift operation” to manufacture their own BPs and claim they are genuine parts, you could at least pinpoint this to a manufacturing date. A true protection would require a hardware security module though.

But I’m not sure how much this part is an issue at all, in previous posts it sounded to me like the final testing was done by Dangerous Prototypes staff and not some external manufacturing company.

2 Likes

Good question - in my mind I was just thinking about a unique identifier per BP unit. I didn’t give it more thought than that; just that an identifier is created by some process per BP, and is stored as an x509 extension in the birth certificate.

Yup, that works. It just becomes a matter of the firmware needing not only the public key of the signing certificate, but also the public keys all the way up the signing chain to validate the full chain. These are normal things and solved problems.

Again, I was throwing this out as a thought experiment/wild ideas just to get the conversations started. Thanks for the feedback and suggestions :slight_smile:

Ultimately, it comes down to whatever @ian and Dangerous Prototypes wants to do - I’ve got no agenda or skin in this.

2 Likes

Yeah, but just as I mentioned - a forger could just forge such a serial number too.

If the certificate is bound to an externally given number that is hard to forge, like the serial of the RP2350 as programmed by RasPi during their manufacturing, the forger would also have to somehow reset the OTP antifuse memory in the RP2350.

2 Likes

I see what you mean. The good thing about x509 extensions is that you can have many of them! How about one extension with the Dangerous Prototypes-assigned “serial number” and another with the RP2350 serial from RasPi.

After validating the birth certificate and the signing chain, the BP firmware could read the RasPi serial from OTP and compare to what’s in the cert as an additional check.

From my original post:

It all comes down to evaluating risks in terms of impact and likelihood, and what to do about them.

I know I said “threat modeling” earlier and that seems to have struck some nerves, but that’s what I spent years doing as a security engineer before moving into hardware red teaming (all of that after years of embedded firmware engineering). It’s where my mind goes when this kind of discussion comes up :person_shrugging:

4 Likes

This is all very fascinating! I’m of course open to it.

I have no idea how any of this works, so my interest is in figuring out how it is applied in practice and documenting it using the Bus Pirate itself. Outputs could include a tool chain checked into github, a tutorial on how to use it in the docs and a command in the firmware to interacting with it.

Roughly, the components seem to be:

  • A specific key data format (x509?)
  • Signing Authority/cert issuer
    –A private key
    –Some software that issues certs with the private key
    –Some kind of server exposed that communicates certs to the manufacturing process, perhaps in response to data like the individual rpi serial numbers
  • A script for manufacturing that reads the serial, fetches the cert, burns it and locks it
  • Some firmware that is able to check the cert using the public key and compare to e.g. the rpi serial number, display the data, etc

An intermediate key might fit in there somewhere.

The server infrastructure could be simple, but imagine some thought needs to go into how to log the issued keys and verify the requestor. I’m sure there’s bog standard methods, but once we start pushing it through the great firewall stuff gets slow and unreliable.

It sounds really cool though, and I would be interested in documenting the setup in a way that might help/inspire other open hardware people.

3 Likes

Give me a few days to catch up and put something a little more formal together :slightly_smiling_face:

2 Likes

Nice!

BTW: in the other thread we seem to have discovered there’s a handful of chips with blank OTP, which could in theory be used to makes clones with a valid cert/“unique” ID :slight_smile:

That might make a nice demo of a “vulnerability”.

2 Likes

I’ve been trying to follow the other thread, too. How much space is there in OTP that we can use?

2 Likes

Usable, probably 6-7K, but it is not continuous.

Row 0x000: B4B8 === B4B8 === B8 B4 [33] (..)
Row 0x001: F87E === F87E === 7E F8 [3D] (~.)
Row 0x002: 6290 === 6290 === 90 62 [2C] (.b)
Row 0x003: 4E1A === 4E1A === 1A 4E [2F] (.N)
Row 0x004: 28D9 === 28D9 === D9 28 [08] (.()
Row 0x005: E76F === E76F === 6F E7 [18] (o.)
Row 0x006: 0C85 === 0C85 === 85 0C [37] (..)
Row 0x007: 7892 === 7892 === 92 78 [04] (.x)
Row 0x008: 0E9E === 0E9E === 9E 0E [11] (..)
Row 0x009: B861 === B861 === 61 B8 [07] (a.)
Row 0x00A: 39EA === 39EA === EA 39 [32] (.9)
Row 0x00B: EE5F === EE5F === 5F EE [27] (_.)
Row 0x010: 2D39 === 2D39 === 39 2D [27] (9-)
Row 0x011: 731B === 731B === 1B 73 [3E] (.s)
Row 0x018: 0030 === 0030 === 30 00 [03] (0.)
Row 0x036: 6036 === 6036 === 36 60 [27] (6`)
Row 0x037: 7B83 === 7B83 === 83 7B [0D] (.{)
Row 0xF80: 3F37 === 3F37 =?= 3F 3F [3F] (7?)
Row 0xF81: 1505 === 1505 =?= 15 15 [15] (..)
Row 0xF83: 0504 === 0504 =?= 04 04 [04] (..)
Row 0xF85: 0504 === 0504 =?= 04 04 [04] (..)
Row 0xFFD: 0504 === 0504 =?= 04 04 [04] (..)

These are the in-use rows, plus ~60bytes for white label stuff. Realistically (without getting too in the weeds) I think we get about 6K continuous.

Oh good, we would probably need up to 1k for a der encoded certificate

2 Likes

Is there a go to package for this? Looking around it seems people get OpenSSL going on embedded. There is also wolfSSL (gpl2) with specific rp2350 optimizations.

1 Like

I’ve used both. OpenSSL is kind of bloated and can be a pain. Wolf works if you want to deal with the license.

There’s also mbedtls GitHub - Mbed-TLS/mbedtls: An open source, portable, easy to use, readable and flexible TLS library, and reference implementation of the PSA Cryptography API. Releases are on a varying cadence, typically around 3 - 6 months between releases.

2 Likes