I redownloaded /usr/src.
I made sample code using libcrypto. I won't even compile now.
Is this some way to prevent user programs from digging into the internal
structures?
I want to reuse the working “iv” for further transactions. Is that not
going to be possible?
If you finish a transmission and start again, will you be able to reuse the
working iv, or will it default to the original?
-Luke
--
-Luke
/*
struct evp_cipher_ctx_st {
const EVP_CIPHER *cipher;
ENGINE *engine;
int encrypt;
int buf_len;
unsigned char oiv[EVP_MAX_IV_LENGTH]; // original iv
unsigned char iv[EVP_MAX_IV_LENGTH]; // working iv
unsigned char buf[EVP_MAX_BLOCK_LENGTH];
int num;
void *app_data;
int key_len;
unsigned long flags;
void *cipher_data;
int final_used;
int block_mask;
unsigned char final[EVP_MAX_BLOCK_LENGTH];
}; // EVP_CIPHER_CTX
*/
#include
#include
#include
/* KEYSIZE# can be 16(128 bits), 24(192 bits), or 32(256 bits) */
#define KEYSIZE 32
#define IVSIZE 12
#define AADSIZE 32
#define AESGCMTAGLEN 16
int main()
{
u_char key[KEYSIZE];
u_char ivec[IVSIZE];
int inlen = 20;
u_char inbuf[20];
u_char aad[AADSIZE];
u_char outbuf[100];
arc4random_buf(key, KEYSIZE);
arc4random_buf(ivec, IVSIZE);
arc4random_buf(inbuf, 20);
arc4random_buf(aad, AADSIZE);
EVP_CIPHER_CTX *CTX = NULL;
int tmplen = 0, outlen = 0;
CTX = EVP_CIPHER_CTX_new();
if (CTX == NULL)
errx(1, "cannot make new cipher context");
if (!EVP_EncryptInit_ex(CTX, EVP_aes_256_gcm(), NULL, NULL, NULL))
err(1, "encrypt set EVP_aes_256_gcm failed");
if (!EVP_CIPHER_CTX_ctrl(CTX, EVP_CTRL_GCM_SET_IVLEN, IVSIZE, NULL))
err(1, "encrypt set ivsize failed");
if (!EVP_EncryptInit_ex(CTX, NULL, NULL, key, ivec))
err(1, "encrypt set key and ivec");
if (EVP_EncryptUpdate(CTX, NULL, &tmplen, aad, AADSIZE) != 1)
err(1, "encrypt set aad");
if (!EVP_EncryptUpdate(CTX, outbuf, &outlen, inbuf, inlen))
{
EVP_CIPHER_CTX_free(CTX);
err(1, "EncryptUpdate1 failed.");
}
if (!EVP_EncryptFinal_ex(CTX, outbuf + outlen, &tmplen))
{
EVP_CIPHER_CTX_free(CTX);
err(1, "EncryptFinal failed.");
}
outlen += tmplen;
if (!EVP_CIPHER_CTX_ctrl(CTX, EVP_CTRL_GCM_GET_TAG, AESGCMTAGLEN, outbuf + outlen))
{
EVP_CIPHER_CTX_free(CTX);
err(1, "EVP_CTRL_GCM_GET_TAG failed.");
}
memcpy(ivec, CTX->iv, IVSIZE);
EVP_CIPHER_CTX_free(CTX);
return outlen + AESGCMTAGLEN;
}