| > I think you're over-describing your use case, to the point that it's unclear what you're really saying. I read your "Introduction" section several times, and I don't understand if you're just saying "the use case is an authenticated key exchange" or something different. That makes it hard to judge the protocol. Okay. I indeed failed to abstract away from the device properly. I'm guessing that the confusion comes from the fact that I had a specific device in mind, but failed to describe it. > These two requirements are contradictory. How do you "authenticate" a server that has a different identity each time you interact with it? Not necessarily. So how TKey works: the hardware contains a preprogrammed device secret. The hardware does not have storage. Upon each power-up it expects a program to be loaded. Upon loading that program, a secret is computed for that specific program: `blake2s(device-secret, program-binary, user-secret)` (user-secret is optional). The secret is generated deterministically, but unpredictable because we don't know the device-secret. > Why not just use Diffie-Hellman? What else is this offering? Given that there exists an "identity", which is the same every time the program loads, this identity can be used for authentication. The identity is different for every program, but after acquiring it once, a client application can perform a key-exchange that finishes with the signature proving the authenticity. If 'device' or 'program-binary' or 'user-secret' changes, the secret changes. So if the secret is the same, you have quite strong guarantees that nobody screwed around with your device or program. |
Ok, I think this is still a fairly standard situation. I understand it that the above quoted text represents the device's long term private key? If so...
You can do this:
- device derives a long-term public device key from the long-term private key
- client generates a fresh public/private session keypair
- client and server perform a Diffie-Hellman exchange, resulting in shared_session_key
- client also verifies device's long-term public key is correct (a simple equality check)
At this point the client and server now have a shared_session_key, and you're in standard territory.
Next problems are replay attack prevention and forward secrecy. The two-birds-with-one-stone for that is for each side to:
- generate fresh a ephemeral keypair
- encrypt using the shared_session_key (with a random nonce)
- perform another Diffie-Hellman exchange
This results in a shared_ephemeral_key. This key can now be used to communicate securely, but you'll need to use incrementing integers as nonces for each message in the ephemeral session to prevent replay attacks. None of this needs storage.