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 <err.h>
#include <openssl/evp.h>
#include <string.h>


/* 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;
}

Reply via email to