Introduction of the cryptosystem

Let's say we have a system with a central server SRV that is considered secure (communication with this server is secured too with TLS).

Then let's say we have many clients CLIENT which are supposed to be secure too (their firmware is encrypted with a per-client unique, non readable key)

Finally, we have some tag TAG that can store some data unencrypted and only one secret item with a key of our choice. The TAG contains a unique identifier but this can be spoofed.

The communication between CLIENT and TAG is unsecure (can be eavesdropped). Yet, the TAG contains a authentication scheme that can be used to certify CLIENT knows the same secret key that's stored in the TAG and prevent reading the secret item if the authentication failed.

Authentication does not reveal the secret key.

So for a simple diagram, it looks like this:

         //   \\
     CLIENT1  CLIENT2  --- TAG1
                      \__ TAG2

// double line means secure communication, simple line means insecure communication

I want to perform the following features:

  1. A TAG could be enrolled on any CLIENT
  2. The CLIENT learn the TAG and store some identifying information in its own memory and also on the SRV. It can store information in the TAG too.
  3. The CLIENT should recognize an already enrolled TAG securely without connecting to the SRV
  4. Another CLIENT should recognize a TAG that its has not enrolled by connecting to the SRV
  5. The CLIENT should allow to forget an enrolled TAG (with or without connection the SRV) and when this happens, such TAG should not be accepted anymore on another CLIENT

Please notice that I can't use the TAG's unique identifier because it's not unique (one can spoof such identifier either by reading the TAG or by emulating a TAG), so storing the TAG UID in the CLIENT and/or SRV is not safe.

Also, using a common shared secret between CLIENT and SRV to store on the TAG secret's area is not safe either since any tag emulator will capture such secret when it's programmed on the TAG's secret key (this is done in clear).

Proposed solution

I'm thinking of using Shamir's secret sharing SSS here with the number of share set to 2 and the number of part set to 3.

Typically, the enrolling process is:

  1. Read the TAG UID as TagUID
  2. Read some data in the unsecure area as KeyTag
  3. If KeyTag is not empty, exit enrolling
  4. Pick a random Key
  5. Use SSS with Key to make 3 parts: KeyTag, KeyClient, KeySrv
  6. Write KeyClient in CLIENT memory for the TagUID
  7. Write KeyTag in the unsecure area of the TAG
  8. Send (TagUID => KeySrv) to SRV for remote storage
  9. Write Key to the Tag secure vault (so next authentications will require such key)
  10. Store some ID/signature/HMAC/Whatever in the TAG's secret area

The TAG recognition process is like this:

  1. Read the TagUID from the TAG
  2. Read KeyTag from the TAG unsecure area
  3. If there is a KeyClient for such TagUID in CLIENT memory,

    2.1 Compute Key from SSS(KeyClient, KeyTag)

  4. Else

    3.1 Query SRV for KeySrv for such TagUID 3.2 Compute Key from SSS(KeySrv, KeyTag)

  5. Authenticate with Key
  6. Read ID/signature/HMAC from the secure area, and check it's valid.

The TAG forget process is:

  1. Read TagUID
  2. If connected, remove such TagUID from SRV
  3. Erase KeyTag from the TAG
  4. Authenticate with the TAG (following the previous process)
  5. Erase secure area from the TAG
  6. Erase authentication from the TAG
  7. Remove KeyClient for this TagUID in CLIENT memory

This scheme seems secure from the many scenario I've thought about, yet I need some expert checking here for what I might have overlooked.

Here are the cases I've thought about:

  1. When used with a tag emulator, one could intercept the random Key for a given TAG but that should not compromise the security of the other tags or other clients. That is, such emulator when used on other CLIENT will be detected as a valid TAG, yet it can't read any other TAG nor inpersonate them.
  2. If the CLIENT is disconnected from the SRV while forgetting a TAG, it'll still wipe the TAG thus there will be no more a KeyTag on it and as such it can't be decoded anymore. Here the SRV could contain stale TagUID, KeySrv combination, but that should not hurt.
  3. An emulator providing wrong KeyTag does not gain anything since computed Key will not pass authentication and it's not possible to read a TAG's Key once programmed. Thus, the ID/signature/HMAC reading will not pass.
  4. A attacker opening a CLIENT would not get any information since there is no common secure key in the CLIENT for all tags. At best, she could get the vault of KeyClient for each TAG but in order to gain advantage, it would also need the KeyTag for each TAG.
  5. Any eavesdropping on the CLIENT/SRV communication should not reveal anything, since it's protected by TLS.

Did I miss anything ?

  • their firmware is encrypted with a per-client unique, non readable key - This seems like a false assumption. Something needs to be able to read the key in order to decrypt the data, regardless if it's unique to the client or not. Oct 17 '19 at 20:22
  • Yes, the client ROM can read the key but no peripheral can (it's burnt in the efuse of such client's CPU), I'd say that reading it requires some desoldering of the chip and an X ray machine. I don't think what's protected by this system would worth such investment. I know that updating the firmware for the client is also at risk but that's not part of this question.
    – xryl669
    Oct 17 '19 at 20:34
  • Let's take a step back here. Is this discussion for a theoretical crypto system, or one that is actually intended for real world use? Oct 17 '19 at 21:17
  • It's both. I know of at least one system where the client's encrypted firmware is already considered secure enough. I thought entering in details for all parts of the system would be too much here, so I made the hypothesis the client's firmware can not be read nor can the server's software and the communication between client and server.
    – xryl669
    Oct 17 '19 at 21:25
  • If this is for an actual system, I would recommend going with an approach more in line with best practices, rather than rolling your own. Assuming that the client is secure and trusting that it will never need to be updated is dangerous. The Shell shock bug was discovered 25 years after it was introduced. Regarding vulnerabilities for your specific crypto system, the first thing that comes to mind is I don't see anything which would prevent an attacker from submitting bad data to SRV and creating a DoS condition. Oct 17 '19 at 21:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.