Open TrueBrain opened 10 months ago
Hi,
Your understanding of the streaming API is mostly correct. One thing you might have overlooked is the crypto_aead_init_*()
functions of which we have 3 variants: djb
, x
, and ietf
. You need to chose one of those to initialise the context… and chose your nonce. More on that at the end.
First of all, can we use
crypto_aead_write
for streaming encryption? As in, we have a small packet between 10 and 1200 bytes, which we send every once in a while.
Yes you can, and I explicitly thought of your use case when I designed this API.
Run it through
crypto_aead_write
, send themac
andcipher_text
to the other side, and repeat?
Yep.
Second, as I read it, the
key
is rotated on everycrypto_aead_write
action, and as such, we do not need to add anything to prevent replay-attacks, like rotating thenonce
every packet or something?
Correct. Once you've initialised the context, crypto_aead_write()
will take care of everything, you don't need to call anything else, and you don't need to rotate the nonce. Just encrypt, send the cyphertext and mac, done.
Ideally, if it is not all that much to ask, what would really help us is an example of a streaming implementation.
I'll work on this. In the mean time:
// Handshake takes care of key,
// You may need to chose a nonce.
uint8_t key [32];
uint8_t nonce [24];
arc4random_buf(key, 32);
arc4random_buf(nonce, 24);
// Init streaming context.
// Note the use of `crypto_aead_init_x()` to support random nonces.
crypto_aead_ctx ctx;
crypto_aead_init_x(&ctx, key, nonce);
// Streaming loop (one message at a time)
while (plaintext_available()) {
// Get buffers
uint8_t *text = plaintext_text();
size_t size = plaintext_size();
uint8_t mac[16];
// Encrypt
// Note how I overwrite the plaintext
crypto_aead_write(&ctx, text, mac, NULL, 0, text, size);
// Send
send(socket, cipher_text, text_size, flags);
send(socket, mac, 16, flags);
}
// Wipe sensitive info
crypto_wipe(key, 32);
crypto_wipe(&ctx, sizeof(ctx));
The
nonce
is already sent in the handshake, and from how I read it, we only need to send that once?
That would depend on your handshake:
crypto_aead_init_x()
to handle it. (You could use a counter, but then you must make sure never to reset it before the key itself changes, that's more error prone).crypto_aead_init_*()
function that has a long enough nonce, and pad the rest of the nonce with zeroes if you need to.Hope this clears things up. I'll keep this issue open until I clarify the documentation.
Thank you so much! Exactly the answers we were looking for :)
And thank you for the example, this is lovely!
For OpenTTD we are trying to figure out how we want to do encryption between server and client, and monocypher came out on top because of its small footprint and easy to use API. However, internally we have a small debate how to do things, as that goes with encryption.
In the documentation you make use of "incremental encryption" with some suggestion here and there about "stream", and this makes things a bit unclear to us. And this is mostly because we don't really understand any of this, so I thought it would be easier to just ask, instead of us trying something that might be insecure :D
First of all, can we use
crypto_aead_write
for streaming encryption? As in, we have a small packet between 10 and 1200 bytes, which we send every once in a while. Run it throughcrypto_aead_write
, send themac
andcipher_text
to the other side, and repeat? Thenonce
is already sent in the handshake, and from how I read it, we only need to send that once?Second, as I read it, the
key
is rotated on everycrypto_aead_write
action, and as such, we do not need to add anything to prevent replay-attacks, like rotating thenonce
every packet or something?Ideally, if it is not all that much to ask, what would really help us is an example of a streaming implementation. Much like the
Encrypt one message with the incremental interface
example, but with more than one packet. With two packets alone would be of great help, just to understand what we do need to send, and what we don't.Any help would be greatly appreciated :) Tnx!