diff options
author | Damien Miller <djm@cvs.openbsd.org> | 2008-09-06 12:15:42 +0000 |
---|---|---|
committer | Damien Miller <djm@cvs.openbsd.org> | 2008-09-06 12:15:42 +0000 |
commit | ff01a08e168005630ffd154331b06d4b987aa4b8 (patch) | |
tree | 9a006f666ae02117ff1bbc3f31a8b3d91769f3ce | |
parent | 60331c274490f3a9b12ade044a4b3ccb770adcc2 (diff) |
import of OpenSSL 0.9.8h
-rw-r--r-- | lib/libssl/src/crypto/camellia/cmll_cbc.c | 227 | ||||
-rw-r--r-- | lib/libssl/src/crypto/camellia/cmll_cfb.c | 110 | ||||
-rw-r--r-- | lib/libssl/src/crypto/camellia/cmll_ctr.c | 85 | ||||
-rw-r--r-- | lib/libssl/src/crypto/camellia/cmll_locl.h | 105 | ||||
-rw-r--r-- | lib/libssl/src/crypto/camellia/cmll_misc.c | 50 | ||||
-rw-r--r-- | lib/libssl/src/crypto/camellia/cmll_ofb.c | 28 |
6 files changed, 563 insertions, 42 deletions
diff --git a/lib/libssl/src/crypto/camellia/cmll_cbc.c b/lib/libssl/src/crypto/camellia/cmll_cbc.c index 4c8d455adef..4141a7b59bb 100644 --- a/lib/libssl/src/crypto/camellia/cmll_cbc.c +++ b/lib/libssl/src/crypto/camellia/cmll_cbc.c @@ -49,16 +49,225 @@ * */ +#ifndef CAMELLIA_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include <assert.h> +#include <stdio.h> +#include <string.h> + #include <openssl/camellia.h> -#include <openssl/modes.h> +#include "cmll_locl.h" void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const CAMELLIA_KEY *key, - unsigned char *ivec, const int enc) - { + const unsigned long length, const CAMELLIA_KEY *key, + unsigned char *ivec, const int enc) { + + unsigned long n; + unsigned long len = length; + const unsigned char *iv = ivec; + union { u32 t32[CAMELLIA_BLOCK_SIZE/sizeof(u32)]; + u8 t8 [CAMELLIA_BLOCK_SIZE]; } tmp; + const union { long one; char little; } camellia_endian = {1}; + + + assert(in && out && key && ivec); + assert((CAMELLIA_ENCRYPT == enc)||(CAMELLIA_DECRYPT == enc)); - if (enc) - CRYPTO_cbc128_encrypt(in,out,len,key,ivec,(block128_f)Camellia_encrypt); - else - CRYPTO_cbc128_decrypt(in,out,len,key,ivec,(block128_f)Camellia_decrypt); - } + if(((size_t)in|(size_t)out|(size_t)ivec) % sizeof(u32) == 0) + { + if (CAMELLIA_ENCRYPT == enc) + { + while (len >= CAMELLIA_BLOCK_SIZE) + { + XOR4WORD2((u32 *)out, + (u32 *)in, (u32 *)iv); + if (camellia_endian.little) + SWAP4WORD((u32 *)out); + key->enc(key->rd_key, (u32 *)out); + if (camellia_endian.little) + SWAP4WORD((u32 *)out); + iv = out; + len -= CAMELLIA_BLOCK_SIZE; + in += CAMELLIA_BLOCK_SIZE; + out += CAMELLIA_BLOCK_SIZE; + } + if (len) + { + for(n=0; n < len; ++n) + out[n] = in[n] ^ iv[n]; + for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n) + out[n] = iv[n]; + if (camellia_endian.little) + SWAP4WORD((u32 *)out); + key->enc(key->rd_key, (u32 *)out); + if (camellia_endian.little) + SWAP4WORD((u32 *)out); + iv = out; + } + memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE); + } + else if (in != out) + { + while (len >= CAMELLIA_BLOCK_SIZE) + { + memcpy(out,in,CAMELLIA_BLOCK_SIZE); + if (camellia_endian.little) + SWAP4WORD((u32 *)out); + key->dec(key->rd_key,(u32 *)out); + if (camellia_endian.little) + SWAP4WORD((u32 *)out); + XOR4WORD((u32 *)out, (u32 *)iv); + iv = in; + len -= CAMELLIA_BLOCK_SIZE; + in += CAMELLIA_BLOCK_SIZE; + out += CAMELLIA_BLOCK_SIZE; + } + if (len) + { + memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE); + if (camellia_endian.little) + SWAP4WORD(tmp.t32); + key->dec(key->rd_key, tmp.t32); + if (camellia_endian.little) + SWAP4WORD(tmp.t32); + for(n=0; n < len; ++n) + out[n] = tmp.t8[n] ^ iv[n]; + iv = in; + } + memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE); + } + else /* in == out */ + { + while (len >= CAMELLIA_BLOCK_SIZE) + { + memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE); + if (camellia_endian.little) + SWAP4WORD((u32 *)out); + key->dec(key->rd_key, (u32 *)out); + if (camellia_endian.little) + SWAP4WORD((u32 *)out); + XOR4WORD((u32 *)out, (u32 *)ivec); + memcpy(ivec, tmp.t8, CAMELLIA_BLOCK_SIZE); + len -= CAMELLIA_BLOCK_SIZE; + in += CAMELLIA_BLOCK_SIZE; + out += CAMELLIA_BLOCK_SIZE; + } + if (len) + { + memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE); + if (camellia_endian.little) + SWAP4WORD((u32 *)out); + key->dec(key->rd_key,(u32 *)out); + if (camellia_endian.little) + SWAP4WORD((u32 *)out); + for(n=0; n < len; ++n) + out[n] ^= ivec[n]; + for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n) + out[n] = tmp.t8[n]; + memcpy(ivec, tmp.t8, CAMELLIA_BLOCK_SIZE); + } + } + } + else /* no aligned */ + { + if (CAMELLIA_ENCRYPT == enc) + { + while (len >= CAMELLIA_BLOCK_SIZE) + { + for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n) + tmp.t8[n] = in[n] ^ iv[n]; + if (camellia_endian.little) + SWAP4WORD(tmp.t32); + key->enc(key->rd_key, tmp.t32); + if (camellia_endian.little) + SWAP4WORD(tmp.t32); + memcpy(out, tmp.t8, CAMELLIA_BLOCK_SIZE); + iv = out; + len -= CAMELLIA_BLOCK_SIZE; + in += CAMELLIA_BLOCK_SIZE; + out += CAMELLIA_BLOCK_SIZE; + } + if (len) + { + for(n=0; n < len; ++n) + tmp.t8[n] = in[n] ^ iv[n]; + for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n) + tmp.t8[n] = iv[n]; + if (camellia_endian.little) + SWAP4WORD(tmp.t32); + key->enc(key->rd_key, tmp.t32); + if (camellia_endian.little) + SWAP4WORD(tmp.t32); + memcpy(out, tmp.t8, CAMELLIA_BLOCK_SIZE); + iv = out; + } + memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE); + } + else if (in != out) + { + while (len >= CAMELLIA_BLOCK_SIZE) + { + memcpy(tmp.t8,in,CAMELLIA_BLOCK_SIZE); + if (camellia_endian.little) + SWAP4WORD(tmp.t32); + key->dec(key->rd_key,tmp.t32); + if (camellia_endian.little) + SWAP4WORD(tmp.t32); + for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n) + out[n] = tmp.t8[n] ^ iv[n]; + iv = in; + len -= CAMELLIA_BLOCK_SIZE; + in += CAMELLIA_BLOCK_SIZE; + out += CAMELLIA_BLOCK_SIZE; + } + if (len) + { + memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE); + if (camellia_endian.little) + SWAP4WORD(tmp.t32); + key->dec(key->rd_key, tmp.t32); + if (camellia_endian.little) + SWAP4WORD(tmp.t32); + for(n=0; n < len; ++n) + out[n] = tmp.t8[n] ^ iv[n]; + iv = in; + } + memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE); + } + else + { + while (len >= CAMELLIA_BLOCK_SIZE) + { + memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE); + if (camellia_endian.little) + SWAP4WORD(tmp.t32); + key->dec(key->rd_key, tmp.t32); + if (camellia_endian.little) + SWAP4WORD(tmp.t32); + for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n) + tmp.t8[n] ^= ivec[n]; + memcpy(ivec, in, CAMELLIA_BLOCK_SIZE); + memcpy(out, tmp.t8, CAMELLIA_BLOCK_SIZE); + len -= CAMELLIA_BLOCK_SIZE; + in += CAMELLIA_BLOCK_SIZE; + out += CAMELLIA_BLOCK_SIZE; + } + if (len) + { + memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE); + if (camellia_endian.little) + SWAP4WORD(tmp.t32); + key->dec(key->rd_key,tmp.t32); + if (camellia_endian.little) + SWAP4WORD(tmp.t32); + for(n=0; n < len; ++n) + tmp.t8[n] ^= ivec[n]; + memcpy(ivec, in, CAMELLIA_BLOCK_SIZE); + memcpy(out,tmp.t8,len); + } + } + } +} diff --git a/lib/libssl/src/crypto/camellia/cmll_cfb.c b/lib/libssl/src/crypto/camellia/cmll_cfb.c index 3d81b51d3f4..af0f9f49ad9 100644 --- a/lib/libssl/src/crypto/camellia/cmll_cfb.c +++ b/lib/libssl/src/crypto/camellia/cmll_cfb.c @@ -105,8 +105,17 @@ * [including the GNU Public Licence.] */ +#ifndef CAMELLIA_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include <assert.h> +#include <string.h> + #include <openssl/camellia.h> -#include <openssl/modes.h> +#include "cmll_locl.h" +#include "e_os.h" /* The input and output encrypted as though 128bit cfb mode is being @@ -115,25 +124,112 @@ */ void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const CAMELLIA_KEY *key, + const unsigned long length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num, const int enc) { - CRYPTO_cfb128_encrypt(in,out,length,key,ivec,num,enc,(block128_f)Camellia_encrypt); + unsigned int n; + unsigned long l = length; + unsigned char c; + + assert(in && out && key && ivec && num); + + n = *num; + + if (enc) + { + while (l--) + { + if (n == 0) + { + Camellia_encrypt(ivec, ivec, key); + } + ivec[n] = *(out++) = *(in++) ^ ivec[n]; + n = (n+1) % CAMELLIA_BLOCK_SIZE; + } + } + else + { + while (l--) + { + if (n == 0) + { + Camellia_encrypt(ivec, ivec, key); + } + c = *(in); + *(out++) = *(in++) ^ ivec[n]; + ivec[n] = c; + n = (n+1) % CAMELLIA_BLOCK_SIZE; + } + } + + *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 */ +void Camellia_cfbr_encrypt_block(const unsigned char *in,unsigned char *out, + const int nbits,const CAMELLIA_KEY *key, + unsigned char *ivec,const int enc) + { + int n,rem,num; + unsigned char ovec[CAMELLIA_BLOCK_SIZE*2]; + + if (nbits<=0 || nbits>128) return; + + /* fill in the first half of the new IV with the current IV */ + memcpy(ovec,ivec,CAMELLIA_BLOCK_SIZE); + /* construct the new IV */ + Camellia_encrypt(ivec,ivec,key); + num = (nbits+7)/8; + if (enc) /* encrypt the input */ + for(n=0 ; n < num ; ++n) + out[n] = (ovec[CAMELLIA_BLOCK_SIZE+n] = in[n] ^ ivec[n]); + else /* decrypt the input */ + for(n=0 ; n < num ; ++n) + out[n] = (ovec[CAMELLIA_BLOCK_SIZE+n] = in[n]) ^ ivec[n]; + /* shift ovec left... */ + rem = nbits%8; + num = nbits/8; + if(rem==0) + memcpy(ivec,ovec+num,CAMELLIA_BLOCK_SIZE); + else + for(n=0 ; n < CAMELLIA_BLOCK_SIZE ; ++n) + ivec[n] = ovec[n+num]<<rem | ovec[n+num+1]>>(8-rem); + + /* 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 Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const CAMELLIA_KEY *key, + const unsigned long length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num, const int enc) { - CRYPTO_cfb128_1_encrypt(in,out,length,key,ivec,num,enc,(block128_f)Camellia_encrypt); + 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; + Camellia_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 Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const CAMELLIA_KEY *key, + const unsigned long length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num, const int enc) { - CRYPTO_cfb128_8_encrypt(in,out,length,key,ivec,num,enc,(block128_f)Camellia_encrypt); + unsigned int n; + + assert(in && out && key && ivec && num); + assert(*num == 0); + + for(n=0 ; n < length ; ++n) + Camellia_cfbr_encrypt_block(&in[n],&out[n],8,key,ivec,enc); } diff --git a/lib/libssl/src/crypto/camellia/cmll_ctr.c b/lib/libssl/src/crypto/camellia/cmll_ctr.c index 014e621a34b..cc21b70890d 100644 --- a/lib/libssl/src/crypto/camellia/cmll_ctr.c +++ b/lib/libssl/src/crypto/camellia/cmll_ctr.c @@ -49,16 +49,95 @@ * */ +#ifndef CAMELLIA_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include <assert.h> + #include <openssl/camellia.h> -#include <openssl/modes.h> +#include "cmll_locl.h" + +/* NOTE: the IV/counter CTR mode is big-endian. The rest of the Camellia code + * is endian-neutral. */ +/* increment counter (128-bit int) by 1 */ +static void Camellia_ctr128_inc(unsigned char *counter) + { + unsigned long c; + + /* Grab bottom dword of counter and increment */ + c = GETU32(counter + 12); + c++; c &= 0xFFFFFFFF; + PUTU32(counter + 12, c); + + /* if no overflow, we're done */ + if (c) + return; + + /* Grab 1st dword of counter and increment */ + c = GETU32(counter + 8); + c++; c &= 0xFFFFFFFF; + PUTU32(counter + 8, c); + + /* if no overflow, we're done */ + if (c) + return; + + /* Grab 2nd dword of counter and increment */ + c = GETU32(counter + 4); + c++; c &= 0xFFFFFFFF; + PUTU32(counter + 4, c); + + /* if no overflow, we're done */ + if (c) + return; + /* Grab top dword of counter and increment */ + c = GETU32(counter + 0); + c++; c &= 0xFFFFFFFF; + PUTU32(counter + 0, c); + } + +/* The input encrypted as though 128bit counter mode is being + * used. The extra state information to record how much of the + * 128bit block we have used is contained in *num, and the + * encrypted counter is kept in ecount_buf. Both *num and + * ecount_buf must be initialised with zeros before the first + * call to Camellia_ctr128_encrypt(). + * + * This algorithm assumes that the counter is in the x lower bits + * of the IV (ivec), and that the application has full control over + * overflow and the rest of the IV. This implementation takes NO + * responsability for checking that the counter doesn't overflow + * into the rest of the IV when incremented. + */ void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const CAMELLIA_KEY *key, + const unsigned long length, const CAMELLIA_KEY *key, unsigned char ivec[CAMELLIA_BLOCK_SIZE], unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE], unsigned int *num) { - CRYPTO_ctr128_encrypt(in,out,length,key,ivec,ecount_buf,num,(block128_f)Camellia_encrypt); + unsigned int n; + unsigned long l=length; + + assert(in && out && key && counter && num); + assert(*num < CAMELLIA_BLOCK_SIZE); + + n = *num; + + while (l--) + { + if (n == 0) + { + Camellia_encrypt(ivec, ecount_buf, key); + Camellia_ctr128_inc(ivec); + } + *(out++) = *(in++) ^ ecount_buf[n]; + n = (n+1) % CAMELLIA_BLOCK_SIZE; + } + + *num=n; } diff --git a/lib/libssl/src/crypto/camellia/cmll_locl.h b/lib/libssl/src/crypto/camellia/cmll_locl.h index 246b6ce1d8c..2ac2e954357 100644 --- a/lib/libssl/src/crypto/camellia/cmll_locl.h +++ b/lib/libssl/src/crypto/camellia/cmll_locl.h @@ -68,19 +68,98 @@ #ifndef HEADER_CAMELLIA_LOCL_H #define HEADER_CAMELLIA_LOCL_H -typedef unsigned int u32; +#include "openssl/e_os2.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + typedef unsigned char u8; +typedef unsigned int u32; + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) +# define SWAP(x) ( _lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00 ) +# define GETU32(p) SWAP(*((u32 *)(p))) +# define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); } +# define CAMELLIA_SWAP4(x) (x = ( _lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) ) + +#else /* not windows */ +# define GETU32(pt) (((u32)(pt)[0] << 24) \ + ^ ((u32)(pt)[1] << 16) \ + ^ ((u32)(pt)[2] << 8) \ + ^ ((u32)(pt)[3])) + +# define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); \ + (ct)[1] = (u8)((st) >> 16); \ + (ct)[2] = (u8)((st) >> 8); \ + (ct)[3] = (u8)(st); } + +#if (defined (__GNUC__) && (defined(__x86_64__) || defined(__x86_64))) +#define CAMELLIA_SWAP4(x) \ + do{\ + asm("bswap %1" : "+r" (x));\ + }while(0) +#else +#define CAMELLIA_SWAP4(x) \ + do{\ + x = ((u32)x << 16) + ((u32)x >> 16);\ + x = (((u32)x & 0xff00ff) << 8) + (((u32)x >> 8) & 0xff00ff);\ + } while(0) +#endif +#endif + +#define COPY4WORD(dst, src) \ + do \ + { \ + (dst)[0]=(src)[0]; \ + (dst)[1]=(src)[1]; \ + (dst)[2]=(src)[2]; \ + (dst)[3]=(src)[3]; \ + }while(0) + +#define SWAP4WORD(word) \ + do \ + { \ + CAMELLIA_SWAP4((word)[0]); \ + CAMELLIA_SWAP4((word)[1]); \ + CAMELLIA_SWAP4((word)[2]); \ + CAMELLIA_SWAP4((word)[3]); \ + }while(0) + +#define XOR4WORD(a, b)/* a = a ^ b */ \ + do \ + { \ + (a)[0]^=(b)[0]; \ + (a)[1]^=(b)[1]; \ + (a)[2]^=(b)[2]; \ + (a)[3]^=(b)[3]; \ + }while(0) + +#define XOR4WORD2(a, b, c)/* a = b ^ c */ \ + do \ + { \ + (a)[0]=(b)[0]^(c)[0]; \ + (a)[1]=(b)[1]^(c)[1]; \ + (a)[2]=(b)[2]^(c)[2]; \ + (a)[3]=(b)[3]^(c)[3]; \ + }while(0) + + +void camellia_setup128(const u8 *key, u32 *subkey); +void camellia_setup192(const u8 *key, u32 *subkey); +void camellia_setup256(const u8 *key, u32 *subkey); + +void camellia_encrypt128(const u32 *subkey, u32 *io); +void camellia_decrypt128(const u32 *subkey, u32 *io); +void camellia_encrypt256(const u32 *subkey, u32 *io); +void camellia_decrypt256(const u32 *subkey, u32 *io); + +#ifdef __cplusplus +} +#endif -int Camellia_Ekeygen(int keyBitLength, const u8 *rawKey, - KEY_TABLE_TYPE keyTable); -void Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[], - const KEY_TABLE_TYPE keyTable, u8 ciphertext[]); -void Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[], - const KEY_TABLE_TYPE keyTable, u8 plaintext[]); -void Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[], - const KEY_TABLE_TYPE keyTable, u8 ciphertext[]); -void Camellia_DecryptBlock(int keyBitLength, const u8 ciphertext[], - const KEY_TABLE_TYPE keyTable, u8 plaintext[]); -int private_Camellia_set_key(const unsigned char *userKey, const int bits, - CAMELLIA_KEY *key); #endif /* #ifndef HEADER_CAMELLIA_LOCL_H */ + diff --git a/lib/libssl/src/crypto/camellia/cmll_misc.c b/lib/libssl/src/crypto/camellia/cmll_misc.c index f44d48564c2..f1047b54e03 100644 --- a/lib/libssl/src/crypto/camellia/cmll_misc.c +++ b/lib/libssl/src/crypto/camellia/cmll_misc.c @@ -50,31 +50,67 @@ */ #include <openssl/opensslv.h> -#include <openssl/crypto.h> #include <openssl/camellia.h> #include "cmll_locl.h" const char CAMELLIA_version[]="CAMELLIA" OPENSSL_VERSION_PTEXT; -int private_Camellia_set_key(const unsigned char *userKey, const int bits, +int Camellia_set_key(const unsigned char *userKey, const int bits, CAMELLIA_KEY *key) { - if(!userKey || !key) + if (!userKey || !key) + { return -1; - if(bits != 128 && bits != 192 && bits != 256) + } + + switch(bits) + { + case 128: + camellia_setup128(userKey, (unsigned int *)key->rd_key); + key->enc = camellia_encrypt128; + key->dec = camellia_decrypt128; + break; + case 192: + camellia_setup192(userKey, (unsigned int *)key->rd_key); + key->enc = camellia_encrypt256; + key->dec = camellia_decrypt256; + break; + case 256: + camellia_setup256(userKey, (unsigned int *)key->rd_key); + key->enc = camellia_encrypt256; + key->dec = camellia_decrypt256; + break; + default: return -2; - key->grand_rounds = Camellia_Ekeygen(bits , userKey, key->u.rd_key); + } + + key->bitLength = bits; return 0; } void Camellia_encrypt(const unsigned char *in, unsigned char *out, const CAMELLIA_KEY *key) { - Camellia_EncryptBlock_Rounds(key->grand_rounds, in , key->u.rd_key , out); + u32 tmp[CAMELLIA_BLOCK_SIZE/sizeof(u32)]; + const union { long one; char little; } camellia_endian = {1}; + + memcpy(tmp, in, CAMELLIA_BLOCK_SIZE); + if (camellia_endian.little) SWAP4WORD(tmp); + key->enc(key->rd_key, tmp); + if (camellia_endian.little) SWAP4WORD(tmp); + memcpy(out, tmp, CAMELLIA_BLOCK_SIZE); } void Camellia_decrypt(const unsigned char *in, unsigned char *out, const CAMELLIA_KEY *key) { - Camellia_DecryptBlock_Rounds(key->grand_rounds, in , key->u.rd_key , out); + u32 tmp[CAMELLIA_BLOCK_SIZE/sizeof(u32)]; + const union { long one; char little; } camellia_endian = {1}; + + memcpy(tmp, in, CAMELLIA_BLOCK_SIZE); + if (camellia_endian.little) SWAP4WORD(tmp); + key->dec(key->rd_key, tmp); + if (camellia_endian.little) SWAP4WORD(tmp); + memcpy(out, tmp, CAMELLIA_BLOCK_SIZE); } + diff --git a/lib/libssl/src/crypto/camellia/cmll_ofb.c b/lib/libssl/src/crypto/camellia/cmll_ofb.c index a482befc747..d89cf9f3b32 100644 --- a/lib/libssl/src/crypto/camellia/cmll_ofb.c +++ b/lib/libssl/src/crypto/camellia/cmll_ofb.c @@ -105,15 +105,37 @@ * [including the GNU Public Licence.] */ +#ifndef CAMELLIA_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include <assert.h> #include <openssl/camellia.h> -#include <openssl/modes.h> +#include "cmll_locl.h" /* The input and output encrypted as though 128bit ofb mode is being * used. The extra state information to record how much of the * 128bit block we have used is contained in *num; */ void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const CAMELLIA_KEY *key, + const unsigned long length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num) { - CRYPTO_ofb128_encrypt(in,out,length,key,ivec,num,(block128_f)Camellia_encrypt); + + unsigned int n; + unsigned long l=length; + + assert(in && out && key && ivec && num); + + n = *num; + + while (l--) { + if (n == 0) { + Camellia_encrypt(ivec, ivec, key); + } + *(out++) = *(in++) ^ ivec[n]; + n = (n+1) % CAMELLIA_BLOCK_SIZE; + } + + *num=n; } |