Sodium provides a software bitsliced implementation of AES-128 in counter mode written by Peter Schwabe and Emilia Käsper, which resists all cache timing attacks.
int crypto_stream_aes128ctr(unsigned char *out, unsigned long long outlen,
const unsigned char *n, const unsigned char *k);
The crypto_stream_aes128ctr()
function stores outlen
pseudo random bytes into out
using the secret key k
(crypto_stream_aes128ctr_KEYBYTES
bytes) and the nonce n
(crypto_stream_aes128ctr_NONCEBYTES
bytes).
The output is generated by computing AES128(n,k), AES128(n+1,k), AES128(n+2,k), ...
until enough 16-bytes blocks have been generated to match outlen
.
int crypto_stream_aes128ctr_xor(unsigned char *out, const unsigned char *in,
unsigned long long inlen, const unsigned char *n,
const unsigned char *k);
The crypto_stream_aes128ctr_xor()
function encrypts a message in
whose length is inlen
bytes using a secret key k
(crypto_stream_aes128ctr_KEYBYTES
bytes) and a nonce n
(crypto_stream_aes128ctr_NONCEBYTES
bytes).
The output is stored into out
.
In this mode, the same operation can be used both for encryption and decryption.
in
and out
can point to the same address (in-place encryption/decryption). If they don't, the regions should not overlap.
crypto_stream_aes128ctr_KEYBYTES
crypto_stream_aes128ctr_NONCEBYTES
crypto_stream_aes128ctr()
doesn't have an internal counter: the nonce itself is incremented after each 16-bytes block. As a result, extreme care should be taken to avoid reusing a nonce with the same key.
Unless using AES is a requirement, you should consider crypto_stream
(XSalsa20) or crypto_stream_chacha20
(ChaCha20) instead.
crypto_stream_aes128ctr_xor()
simply combines the message with the output of the stream cipher with the XOR operation, and does not add any authentication tag.
Unless this is exactly what you need, you should use crypto_secretbox()
or crypto_box()
instead.