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:
SRV
// \\
CLIENT1 CLIENT2 --- TAG1
\__ TAG2
// double line means secure communication, simple line means insecure communication
I want to perform the following features:
- A
TAGcould be enrolled on anyCLIENT - The
CLIENTlearn theTAGand store some identifying information in its own memory and also on theSRV. It can store information in theTAGtoo. - The
CLIENTshould recognize an already enrolledTAGsecurely without connecting to theSRV - Another
CLIENTshould recognize aTAGthat its has not enrolled by connecting to theSRV - The
CLIENTshould allow to forget an enrolledTAG(with or without connection theSRV) and when this happens, suchTAGshould not be accepted anymore on anotherCLIENT
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:
- Read the
TAGUID asTagUID - Read some data in the unsecure area as
KeyTag - If
KeyTagis not empty, exit enrolling - Pick a random
Key - Use
SSSwithKeyto make 3 parts:KeyTag,KeyClient,KeySrv - Write
KeyClientinCLIENTmemory for theTagUID - Write
KeyTagin the unsecure area of theTAG - Send (
TagUID => KeySrv) toSRVfor remote storage - Write
Keyto theTagsecure vault (so next authentications will require such key) - Store some ID/signature/HMAC/Whatever in the
TAG's secret area
The TAG recognition process is like this:
- Read the
TagUIDfrom theTAG - Read
KeyTagfrom theTAGunsecure area If there is a
KeyClientfor suchTagUIDinCLIENTmemory,2.1 Compute
KeyfromSSS(KeyClient, KeyTag)Else
3.1 Query
SRVforKeySrvfor suchTagUID3.2 ComputeKeyfromSSS(KeySrv, KeyTag)- Authenticate with
Key - Read ID/signature/HMAC from the secure area, and check it's valid.
The TAG forget process is:
- Read
TagUID - If connected, remove such
TagUIDfromSRV - Erase
KeyTagfrom theTAG - Authenticate with the
TAG(following the previous process) - Erase secure area from the
TAG - Erase authentication from the
TAG - Remove
KeyClientfor thisTagUIDinCLIENTmemory
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:
- When used with a tag emulator, one could intercept the random
Keyfor a givenTAGbut that should not compromise the security of the other tags or other clients. That is, such emulator when used on otherCLIENTwill be detected as a validTAG, yet it can't read any otherTAGnor inpersonate them. - If the
CLIENTis disconnected from theSRVwhile forgetting aTAG, it'll still wipe theTAGthus there will be no more aKeyTagon it and as such it can't be decoded anymore. Here theSRVcould contain staleTagUID, KeySrvcombination, but that should not hurt. - An emulator providing wrong
KeyTagdoes not gain anything since computedKeywill not pass authentication and it's not possible to read aTAG'sKeyonce programmed. Thus, the ID/signature/HMAC reading will not pass. - A attacker opening a
CLIENTwould not get any information since there is no common secure key in theCLIENTfor all tags. At best, she could get the vault ofKeyClientfor eachTAGbut in order to gain advantage, it would also need theKeyTagfor eachTAG. - Any eavesdropping on the
CLIENT/SRVcommunication should not reveal anything, since it's protected by TLS.
Did I miss anything ?