Werner Almesberger
2016-05-20 15:15:20 UTC
The records in the account database have the following format:
http://downloads.qi-hardware.com/people/werner/anelok/tmp/crypto-format-20160518.pdf
https://gitlab.com/anelok/anelok/blob/master/doc/crypto/format.fig
I also have a description in text form, along with the algorithm:
https://gitlab.com/anelok/anelok/blob/master/crypter/README
The main steps of encryption are:
1) We generate a nonce (N) and the random key (RK) used to encrypt the
record content.
N has to be unique per record encryption but doesn't have to be
difficult to guess, while RK must be unguessable (for an outside
party) and it must be unique at least per group of records with
the same readership. In practice, this means that RK should be
unique per record, but an existing RK could be reused if changing
a record, as long as the readership remains the same.
2) For each reader, we perform the key agreement using Curve25519,
obtaining a secret (ShK) shared between reader and write.
This is the "beforenm" part of https://nacl.cr.yp.to/box.html
3) We encrypt RK with key ShK using crypto_stream_xsalsa20, yielding
the encrypted key EKr. While there is only one RK per record,
there is a different EKr for each reader allowed to decrypt the
record.
https://nacl.cr.yp.to/stream.html
Since we perform message integrity checking on the payload, we
don't add any here - if something goes wrong, the reader will
simply get garbage for RK and decrypting of the record content
will fail.
4) Last but not least, we encrypt the record content with key RK,
using crypto_secretbox_xsalsa20poly1305 (i.e., as before
crypto_stream_xsalsa20 for encryption, but adding Poly1305 for
message integrity checking.)
https://nacl.cr.yp.to/secretbox.html
Next: what all this looks like.
- Werner
http://downloads.qi-hardware.com/people/werner/anelok/tmp/crypto-format-20160518.pdf
https://gitlab.com/anelok/anelok/blob/master/doc/crypto/format.fig
I also have a description in text form, along with the algorithm:
https://gitlab.com/anelok/anelok/blob/master/crypter/README
The main steps of encryption are:
1) We generate a nonce (N) and the random key (RK) used to encrypt the
record content.
N has to be unique per record encryption but doesn't have to be
difficult to guess, while RK must be unguessable (for an outside
party) and it must be unique at least per group of records with
the same readership. In practice, this means that RK should be
unique per record, but an existing RK could be reused if changing
a record, as long as the readership remains the same.
2) For each reader, we perform the key agreement using Curve25519,
obtaining a secret (ShK) shared between reader and write.
This is the "beforenm" part of https://nacl.cr.yp.to/box.html
3) We encrypt RK with key ShK using crypto_stream_xsalsa20, yielding
the encrypted key EKr. While there is only one RK per record,
there is a different EKr for each reader allowed to decrypt the
record.
https://nacl.cr.yp.to/stream.html
Since we perform message integrity checking on the payload, we
don't add any here - if something goes wrong, the reader will
simply get garbage for RK and decrypting of the record content
will fail.
4) Last but not least, we encrypt the record content with key RK,
using crypto_secretbox_xsalsa20poly1305 (i.e., as before
crypto_stream_xsalsa20 for encryption, but adding Poly1305 for
message integrity checking.)
https://nacl.cr.yp.to/secretbox.html
Next: what all this looks like.
- Werner