AES_SIV_Init, AES_SIV_AssociateData, AES_SIV_EncryptFinal, AES_SIV_DecryptFinal - AES-SIV low-level interface
#include <aes_siv.h>
int AES_SIV_Init(AES_SIV_CTX *ctx, unsigned char const* key, size_t key_len);
int AES_SIV_AssociateData(AES_SIV_CTX *ctx, unsigned char const* data, size_t len);
int AES_SIV_EncryptFinal(AES_SIV_CTX *ctx,
unsigned char *v_out, unsigned char *c_out,
unsigned char const* plaintext, size_t len);
int AES_SIV_DecryptFinal(AES_SIV_CTX *ctx, unsigned char *out,
unsigned char const* v, unsigned char const* c,
size_t len);
These functions provide a low-level interface for AES-SIV encryption and decryption, complying with RFC 5297.
AES_SIV_Init() prepares ctx for encrypting or decrypting data under the given key.
AES_SIV_AssociateData() adds a block of associated data to ctx. This function is also used for adding a nonce; see NOTES for details.
AES_SIV_EncryptFinal() encrypts the provided plaintext, writing a 16-byte authentication tag to v_out and ciphertext to c_out. The ciphertext written to c_out will be equal in length to the plaintext, with both lengths given by len.
AES_SIV_DecryptFinal() decrypts and verifies the provided ciphertext c and 16-byte authentication tag v, writing plaintext to out. The plaintext will be equal in length to c, with both lengths given by len.
When encrypting or decrypting/authenticating multiple messages under
the same key, these functions may be used to achieve better
performance than is possible using the high-level API by caching the
result of of key setup. After calling AES_SIV_Init
(), retain the
resulting ctx structure and use AES_SIV_CTX_copy
() to make a copy
of it for each message being encrypted or decrypted.
The arguments to a typical AEAD encryption function consist of a key,
a nonce, associated data, and plaintext. However, RFC 5297 defines
AES-SIV as accepting an arbitrary number of associated data arguments,
and specifies that the nonce should be given as the final such
argument. This low-level API is structured accordingly. The
high-level functions AES_SIV_Encrypt
() and AES_SIV_Decrypt
() are
implemented on top of it approximately as follows; error-handling is
omitted for brevity.
int AES_SIV_Encrypt(AES_SIV_CTX *ctx,
unsigned char *out, size_t *out_len,
unsigned char const* key, size_t key_len,
unsigned char const* nonce, size_t nonce_len,
unsigned char const* plaintext, size_t plaintext_len,
unsigned char const *ad, size_t ad_len) {
*out_len = plaintext_len + 16;
/* Do not copy-paste this code; it is missing return-value
checking.*/
AES_SIV_Init(ctx, key, key_len);
AES_SIV_AssociateData(ctx, ad, ad_len;
if(nonce) AES_SIV_AssociateData(ctx, nonce, nonce_len);
AES_SIV_EncryptFinal(ctx, out, out+16, plaintext, plaintext_len);
return 1;
}
int AES_SIV_Decrypt(AES_SIV_CTX *ctx,
unsigned char *out, size_t *out_len,
unsigned char const* key, size_t key_len,
unsigned char const* nonce, size_t nonce_len,
unsigned char const* ciphertext, size_t ciphertext_len,
unsigned char const *ad, size_t ad_len) {
*out_len = ciphertext_len - 16;
/* Do not copy-paste this code; it is missing return-value
checking.*/
AES_SIV_Init(ctx, key, key_len);
AES_SIV_AssociateData(ctx, ad, ad_len);
if(nonce) AES_SIV_AssociateData(ctx, nonce, nonce_len);
AES_SIV_DecryptFinal(ctx, out, ciphertext, ciphertext + 16,
ciphertext_len - 16);
return 1;
}