Commit 8d1ebe0b authored by Richard Levitte's avatar Richard Levitte
Browse files

Add the missing parts for DES CFB1 and CFB8.

Add the corresponding AES parts while I'm at it.
make update
parent 1fb72444
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -97,6 +97,15 @@ void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
	const unsigned long length, const AES_KEY *key,
	unsigned char *ivec, int *num, const int enc);
void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
	const unsigned long length, const AES_KEY *key,
	unsigned char *ivec, int *num, const int enc);
void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
	const unsigned long length, const AES_KEY *key,
	unsigned char *ivec, int *num, const int enc);
void AES_cfbr_encrypt_block(const unsigned char *in,unsigned char *out,
			    const int nbits,const AES_KEY *key,
			    unsigned char *ivec,const int enc);
void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
	const unsigned long length, const AES_KEY *key,
	unsigned char *ivec, int *num);
+93 −0
Original line number Diff line number Diff line
@@ -155,3 +155,96 @@ void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
	*num=n;
}

/* This expects a single block of size nbits for both in and out. Note that
   it corrupts any extra bits in the last byte of out */
/* Untested, once it is working, it will be optimised */
void AES_cfbr_encrypt_block(const unsigned char *in,unsigned char *out,
			    const int nbits,const AES_KEY *key,
			    unsigned char *ivec,const int enc)
    {
    int n;
    unsigned char ovec[AES_BLOCK_SIZE*2];

    assert(in && out && key && ivec);
    if(enc)
	{
	/* construct the new IV */
	AES_encrypt(ivec,ovec,key);
	/* encrypt the input */
	for(n=0 ; n < (nbits+7)/8 ; ++n)
	    out[n]=in[n]^ovec[n];
	/* fill in the first half of the new IV with the current IV */
	memcpy(ovec,ivec,AES_BLOCK_SIZE);
	/* and put the ciphertext in the second half */
	memcpy(ovec+AES_BLOCK_SIZE,out,(nbits+7)/8);
	/* shift ovec left most of the bits... */
	memmove(ovec,ovec+nbits/8,AES_BLOCK_SIZE+(nbits%8 ? 1 : 0));
	/* now the remaining bits */
	if(nbits%8 != 0)
	    for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
		{
		ovec[n]<<=nbits%8;
		ovec[n]|=ovec[n+1]>>(8-nbits%8);
		}
	/* finally, move it back into place */
	memcpy(ivec,ovec,AES_BLOCK_SIZE);
	}
    else
	{
	/* construct the new IV in the first half of ovec */
	AES_encrypt(ivec,ovec,key);
	/* decrypt the input */
	for(n=0 ; n < (nbits+7)/8 ; ++n)
	    out[n]=in[n]^ovec[n];
	/* fill in the first half of the new IV with the current IV */
	memcpy(ovec,ivec,AES_BLOCK_SIZE);
	/* append the ciphertext */
	memcpy(ovec+AES_BLOCK_SIZE,in,(nbits+7)/8);
	/* shift ovec left most of the bits... */
	memmove(ovec,ovec+nbits/8,AES_BLOCK_SIZE+(nbits%8 ? 1 : 0));
	/* now the remaining bits */
	if(nbits%8 != 0)
	    for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
		{
		ovec[n]<<=nbits%8;
		ovec[n]|=ovec[n+1]>>(8-nbits%8);
		}
	/* finally, move it back into place */
	memcpy(ivec,ovec,AES_BLOCK_SIZE);
	}
    /* it is not necessary to cleanse ovec, since the IV is not secret */
    }

/* N.B. This expects the input to be packed, MS bit first */
void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
		      const unsigned long length, const AES_KEY *key,
		      unsigned char *ivec, int *num, const int enc)
    {
    unsigned int n;
    unsigned char c[1],d[1];

    assert(in && out && key && ivec && num);
    assert(*num == 0);

    memset(out,0,(length+7)/8);
    for(n=0 ; n < length ; ++n)
	{
	c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0;
	AES_cfbr_encrypt_block(c,d,1,key,ivec,enc);
	out[n/8]=(out[n/8]&~(1 << (7-n%8)))|((d[0]&0x80) >> (n%8));
	}
    }

void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
		      const unsigned long length, const AES_KEY *key,
		      unsigned char *ivec, int *num, const int enc)
    {
    unsigned int n;

    assert(in && out && key && ivec && num);
    assert(*num == 0);

    for(n=0 ; n < length ; ++n)
	AES_cfbr_encrypt_block(&in[n],&out[n],8,key,ivec,enc);
    }
+4 −0
Original line number Diff line number Diff line
@@ -187,6 +187,10 @@ void DES_ede3_cfb64_encrypt(const unsigned char *in,unsigned char *out,
			    long length,DES_key_schedule *ks1,
			    DES_key_schedule *ks2,DES_key_schedule *ks3,
			    DES_cblock *ivec,int *num,int enc);
void DES_ede3_cfb_encrypt(const unsigned char *in,unsigned char *out,
			  int numbits,long length,DES_key_schedule *ks1,
			  DES_key_schedule *ks2,DES_key_schedule *ks3,
			  DES_cblock *ivec,int enc);
void DES_ede3_ofb64_encrypt(const unsigned char *in,unsigned char *out,
			    long length,DES_key_schedule *ks1,
			    DES_key_schedule *ks2,DES_key_schedule *ks3,
+8 −0
Original line number Diff line number Diff line
@@ -67,6 +67,8 @@ void OpenSSL_add_all_ciphers(void)

#ifndef OPENSSL_NO_DES
	EVP_add_cipher(EVP_des_cfb());
	EVP_add_cipher(EVP_des_cfb1());
	EVP_add_cipher(EVP_des_cfb8());
	EVP_add_cipher(EVP_des_ede_cfb());
	EVP_add_cipher(EVP_des_ede3_cfb());

@@ -150,6 +152,8 @@ void OpenSSL_add_all_ciphers(void)
	EVP_add_cipher(EVP_aes_128_ecb());
	EVP_add_cipher(EVP_aes_128_cbc());
	EVP_add_cipher(EVP_aes_128_cfb());
	EVP_add_cipher(EVP_aes_128_cfb1());
	EVP_add_cipher(EVP_aes_128_cfb8());
	EVP_add_cipher(EVP_aes_128_ofb());
#if 0
	EVP_add_cipher(EVP_aes_128_ctr());
@@ -159,6 +163,8 @@ void OpenSSL_add_all_ciphers(void)
	EVP_add_cipher(EVP_aes_192_ecb());
	EVP_add_cipher(EVP_aes_192_cbc());
	EVP_add_cipher(EVP_aes_192_cfb());
	EVP_add_cipher(EVP_aes_192_cfb1());
	EVP_add_cipher(EVP_aes_192_cfb8());
	EVP_add_cipher(EVP_aes_192_ofb());
#if 0
	EVP_add_cipher(EVP_aes_192_ctr());
@@ -168,6 +174,8 @@ void OpenSSL_add_all_ciphers(void)
	EVP_add_cipher(EVP_aes_256_ecb());
	EVP_add_cipher(EVP_aes_256_cbc());
	EVP_add_cipher(EVP_aes_256_cfb());
	EVP_add_cipher(EVP_aes_256_cfb1());
	EVP_add_cipher(EVP_aes_256_cfb8());
	EVP_add_cipher(EVP_aes_256_ofb());
#if 0
	EVP_add_cipher(EVP_aes_256_ctr());
+22 −4
Original line number Diff line number Diff line
@@ -86,15 +86,33 @@ IMPLEMENT_BLOCK_CIPHER(aes_256, ks, AES, EVP_AES_KEY,
		       EVP_CIPHER_get_asn1_iv,
		       NULL)

#define IMPLEMENT_AES_CFBR(ksize,cbits)	IMPLEMENT_CFBR(aes,AES,EVP_AES_KEY,ks,ksize,cbits,16)

IMPLEMENT_AES_CFBR(128,1)
IMPLEMENT_AES_CFBR(192,1)
IMPLEMENT_AES_CFBR(256,1)

IMPLEMENT_AES_CFBR(128,8)
IMPLEMENT_AES_CFBR(192,8)
IMPLEMENT_AES_CFBR(256,8)

static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
		   const unsigned char *iv, int enc) {
		   const unsigned char *iv, int enc)
	{
	int ret;

	if ((ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_CFB_MODE
	    || (ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_OFB_MODE
	    || enc) 
		AES_set_encrypt_key(key, ctx->key_len * 8, ctx->cipher_data);
		ret=AES_set_encrypt_key(key, ctx->key_len * 8, ctx->cipher_data);
	else
		AES_set_decrypt_key(key, ctx->key_len * 8, ctx->cipher_data);
		ret=AES_set_decrypt_key(key, ctx->key_len * 8, ctx->cipher_data);

	if(ret < 0)
		{
		EVPerr(EVP_F_AES_INIT_KEY,EVP_R_AES_KEY_SETUP_FAILED);
		return 0;
		}

	return 1;
	}
Loading