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
TAG
could be enrolled on anyCLIENT
- The
CLIENT
learn theTAG
and store some identifying information in its own memory and also on theSRV
. It can store information in theTAG
too. - The
CLIENT
should recognize an already enrolledTAG
securely without connecting to theSRV
- Another
CLIENT
should recognize aTAG
that its has not enrolled by connecting to theSRV
- The
CLIENT
should allow to forget an enrolledTAG
(with or without connection theSRV
) and when this happens, suchTAG
should 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
TAG
UID asTagUID
- Read some data in the unsecure area as
KeyTag
- If
KeyTag
is not empty, exit enrolling - Pick a random
Key
- Use
SSS
withKey
to make 3 parts:KeyTag
,KeyClient
,KeySrv
- Write
KeyClient
inCLIENT
memory for theTagUID
- Write
KeyTag
in the unsecure area of theTAG
- Send (
TagUID => KeySrv
) toSRV
for remote storage - Write
Key
to theTag
secure 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
TagUID
from theTAG
- Read
KeyTag
from theTAG
unsecure area If there is a
KeyClient
for suchTagUID
inCLIENT
memory,2.1 Compute
Key
fromSSS(KeyClient, KeyTag)
Else
3.1 Query
SRV
forKeySrv
for suchTagUID
3.2 ComputeKey
fromSSS(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
TagUID
fromSRV
- Erase
KeyTag
from theTAG
- Authenticate with the
TAG
(following the previous process) - Erase secure area from the
TAG
- Erase authentication from the
TAG
- Remove
KeyClient
for thisTagUID
inCLIENT
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:
- When used with a tag emulator, one could intercept the random
Key
for a givenTAG
but that should not compromise the security of the other tags or other clients. That is, such emulator when used on otherCLIENT
will be detected as a validTAG
, yet it can't read any otherTAG
nor inpersonate them. - If the
CLIENT
is disconnected from theSRV
while forgetting aTAG
, it'll still wipe theTAG
thus there will be no more aKeyTag
on it and as such it can't be decoded anymore. Here theSRV
could contain staleTagUID, KeySrv
combination, but that should not hurt. - An emulator providing wrong
KeyTag
does not gain anything since computedKey
will not pass authentication and it's not possible to read aTAG
'sKey
once programmed. Thus, the ID/signature/HMAC reading will not pass. - A attacker opening a
CLIENT
would not get any information since there is no common secure key in theCLIENT
for all tags. At best, she could get the vault ofKeyClient
for eachTAG
but in order to gain advantage, it would also need theKeyTag
for eachTAG
. - Any eavesdropping on the
CLIENT
/SRV
communication should not reveal anything, since it's protected by TLS.
Did I miss anything ?