summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2008-09-06 12:15:42 +0000
committerDamien Miller <djm@cvs.openbsd.org>2008-09-06 12:15:42 +0000
commitff01a08e168005630ffd154331b06d4b987aa4b8 (patch)
tree9a006f666ae02117ff1bbc3f31a8b3d91769f3ce
parent60331c274490f3a9b12ade044a4b3ccb770adcc2 (diff)
import of OpenSSL 0.9.8h
-rw-r--r--lib/libssl/src/crypto/camellia/cmll_cbc.c227
-rw-r--r--lib/libssl/src/crypto/camellia/cmll_cfb.c110
-rw-r--r--lib/libssl/src/crypto/camellia/cmll_ctr.c85
-rw-r--r--lib/libssl/src/crypto/camellia/cmll_locl.h105
-rw-r--r--lib/libssl/src/crypto/camellia/cmll_misc.c50
-rw-r--r--lib/libssl/src/crypto/camellia/cmll_ofb.c28
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;
}