Message encryption

The message encryption in Nano was determined by 3 factors:
  • The server should be able to store the response a relevant fast-access cache storage

  • Responding to requests from this cache storage must be as secure as responding from the destination Nano instance

  • The server must not respond from cache without consulting the destination Nano instance

End to End protocol

Nano only ever accepts requests in authenticated-encryption, and also responds in a similar manner.

The end-to-end protocol of the Nano is built to help the server to utilize caching of encrypted data chunks. Despite this caching feature, it is still guaranteed that a server won’t be able to serve a request without consulting the responding Nano.

This is because a request is always encrypted in a way that only the Nano’s owner account can decrypt it. Since it is encrypted the server cannot discern what the request is. The encryption means that the server cannot respond to a request from the cache outright.

Response kinds

Nano may separate the response into encrypted chunks depending on whether the server is able to cache the response or not.

The first chunk is responsible for setting up the security and authenticity of the following message parts. The rest of the message parts are also encrypted and can only be decrypted with the key included in the initial response.

After separating the response into chunks, Nano sends an initial response that holds a request-authenticity-hash. This request-authenticity-hash is built up from the request’s metadata. The authenticity-hash provides unfalsifiable proof that the response is for this specific request and the server is not trying to mislead the client.

The initial response also contains the count of the chunks the content will be separated into. With the data received in the initial response, the client can securely request the wanted message. This request will then be served from either the server cache or the Nano client.

Because of this two-step response handling, even if the server can send the response from the cache storage, the initial request is always sent to the Nano client. After authenticating the request, the Nano client then responds with a cache or transfer key that the server can use. These keys are encrypted as well, the server does not know what they represent.

Cacheable response

Cacheable responses are always separated into multiple parts. The initial response will hold cache-key, and a part-key that is the unique encryption key of the whole payload.

The cache key is the best-effort state representation of the data source. In case of a file it includes multiple information from which the file’s recentness can be deducted (the inode, size, mtime and path for example). A change in any of those will indicate that the cache-key is stale and the client needs to restart the request. This automatically invalidates previous cache entries. The cache keys are securely encrypted.

Un-cacheable response

Responses that the server is unable to cache are equipped with a transfer key in place of the cache key.

Cache, Transfer and Part keys

Cache/transfer keys and part keys are always derived from strong cryptographic secret values generated and unique to the Nano instance.

Replay Attacks

Requests that are not idempotent, or in other words requests that would result in a mutation/state change on the Nano client require the requester to set-up a session-id. This session-id is used to prevent replay attacks by a malicious server. This session-id (or mutation-id) consists of a session token which identifies the current command request in the context of the current client-Nano connection. The session-id also has a sequence number which the Nano saves in order to challenge the next command with the same session id.