All pastes #925049 Raw Edit

Untitled

public text v1 · immutable
·published 2008-03-01 22:59 UTC
rendered paste body
#include <string.h>
#include <assert.h>

#if defined(__WIN32)
#include <windows.h>
#else
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#endif

#include "enc.h"

int encrypt_init (Encryptor *enc, uint8_t *key)
{
	memcpy(enc->key, key, ENC_BLOWFISH_KEYLEN);
	int res = gcry_cipher_open(&enc->ctx, GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC, 0);
	assert(res==0);
	res = gcry_cipher_setkey(enc->ctx, key, ENC_BLOWFISH_KEYLEN);
	assert(res==0);
	return 1;
}

int encrypt_free (Encryptor *enc)
{
	gcry_cipher_close(enc->ctx);
	memset(enc, 0, sizeof(Encryptor));
}

int encrypt_encrypt (Encryptor *enc, uint8_t *in, int in_len, uint8_t *out, int *out_len)
{
	// generate an IV
	uint8_t iv[ENC_BLOWFISH_IVLEN];
	gcry_randomize(iv, ENC_BLOWFISH_IVLEN, GCRY_STRONG_RANDOM);

	// copy IV
	memcpy(out, iv, ENC_BLOWFISH_IVLEN);

	// calculate cyphertext size
	int cyphertext_size = (in_len-(in_len%ENC_BLOWFISH_BLOCKLEN))+ENC_BLOWFISH_BLOCKLEN;
	int excess = cyphertext_size - in_len;

	// copy data to output and set data marigin
	memcpy(out+ENC_BLOWFISH_IVLEN, in, in_len);
	out[ENC_BLOWFISH_IVLEN+in_len]=1;
	memset(out+ENC_BLOWFISH_IVLEN+in_len+1, 0, excess-1);

	// encrypt
	if (gcry_cipher_setiv(enc->ctx, iv, ENC_BLOWFISH_IVLEN)) return 0;
	if (gcry_cipher_encrypt(enc->ctx, out+ENC_BLOWFISH_IVLEN, cyphertext_size, NULL, 0)) return 0;

	// set final size
	*out_len = ENC_BLOWFISH_IVLEN+cyphertext_size;
	return 1;
}

int encrypt_decrypt (Encryptor *enc, uint8_t *in, int in_len, uint8_t *out, int *out_len)
{
	// read IV
	if (in_len<ENC_BLOWFISH_IVLEN) return 0;

	// check cyphertext size
	// must be multiple of block length
	// must be at least one block for padding info
	int cyphertext_size = in_len-ENC_BLOWFISH_IVLEN;
	if (cyphertext_size%ENC_BLOWFISH_BLOCKLEN) return 0;
	if (cyphertext_size<ENC_BLOWFISH_BLOCKLEN) return 0;

	// copy cyphertext to output
	memcpy(out, in+ENC_BLOWFISH_IVLEN, cyphertext_size);

	// decrypt cyphertext
	if (gcry_cipher_setiv(enc->ctx, in, ENC_BLOWFISH_IVLEN)) return 0;
	if (gcry_cipher_decrypt(enc->ctx, out, cyphertext_size, NULL, 0)) return 0;

	// read marigin
	int i;
	for (i=cyphertext_size-1; i>=cyphertext_size-ENC_BLOWFISH_BLOCKLEN; i--)
	{
		if (out[i]==1)
		{
			*out_len = i;
			return 1;
		}
		if (out[i]!=0) return 0;
	}
	return 0;
}