Commit 413e0853 authored by Bodo Möller's avatar Bodo Möller
Browse files

New Camellia implementation (replacing previous version)

Submitted by: NTT
parent 8e4560c4
Loading
Loading
Loading
Loading
+1584 −513

File changed.

Preview size limit exceeded, changes collapsed.

+6 −1
Original line number Diff line number Diff line
@@ -74,13 +74,17 @@ extern "C" {
#define CAMELLIA_TABLE_BYTE_LEN 272
#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4)

typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; /* to match with WORD */
 /* to match with WORD */
typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN];

struct camellia_key_st 
	{
	KEY_TABLE_TYPE rd_key;
	int bitLength;
	void (*enc)(const unsigned int *subkey, unsigned int *io);
	void (*dec)(const unsigned int *subkey, unsigned int *io);
	};

typedef struct camellia_key_st CAMELLIA_KEY;

int Camellia_set_key(const unsigned char *userKey, const int bits,
@@ -122,3 +126,4 @@ void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out,
#endif

#endif /* !HEADER_Camellia_H */
+149 −58
Original line number Diff line number Diff line
@@ -55,30 +55,110 @@
# endif
#endif
#include <assert.h>
#include <stdio.h>
#include <string.h>

#include <openssl/camellia.h>
#include "cmll_locl.h"

void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
		     const unsigned long length, const CAMELLIA_KEY *key,
	unsigned char *ivec, const int enc) 
	{
		     unsigned char *ivec, const int enc) {

	unsigned long n;
	unsigned long len = length;
	unsigned char tmp[CAMELLIA_BLOCK_SIZE];
	const unsigned char *iv = ivec;
	uint32_t t32[UNITSIZE];


	assert(in && out && key && ivec);
	assert((CAMELLIA_ENCRYPT == enc)||(CAMELLIA_DECRYPT == enc));

	if(((size_t)in) % ALIGN == 0
		&& ((size_t)out) % ALIGN == 0
		&& ((size_t)ivec) % ALIGN == 0)
		{
		if (CAMELLIA_ENCRYPT == enc)
			{
			while (len >= CAMELLIA_BLOCK_SIZE)
				{
				XOR4WORD2((uint32_t *)out,
					(uint32_t *)in, (uint32_t *)iv);
				key->enc(key->rd_key, (uint32_t *)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];
				key->enc(key->rd_key, (uint32_t *)out);
				iv = out;
				}
			memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE);
			}
		else if (in != out)
			{
			while (len >= CAMELLIA_BLOCK_SIZE)
				{
				memcpy(out,in,CAMELLIA_BLOCK_SIZE);
				key->dec(key->rd_key,(uint32_t *)out);
				XOR4WORD((uint32_t *)out, (uint32_t *)iv);
				iv = in;
				len -= CAMELLIA_BLOCK_SIZE;
				in  += CAMELLIA_BLOCK_SIZE;
				out += CAMELLIA_BLOCK_SIZE;
				}
			if (len)
				{
				memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
				key->dec(key->rd_key, (uint32_t *)tmp);
				for(n=0; n < len; ++n)
					out[n] = tmp[n] ^ iv[n];
				iv = in;
				}
			memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE);
			}
		else /* in == out */
			{
			while (len >= CAMELLIA_BLOCK_SIZE)
				{
				memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
				key->dec(key->rd_key, (uint32_t *)out);
				XOR4WORD((uint32_t *)out, (uint32_t *)ivec);
				memcpy(ivec, tmp, CAMELLIA_BLOCK_SIZE);
				len -= CAMELLIA_BLOCK_SIZE;
				in += CAMELLIA_BLOCK_SIZE;
				out += CAMELLIA_BLOCK_SIZE;
				}
			if (len)
				{
				memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
				key->dec(key->rd_key,(uint32_t *)out);
				for(n=0; n < len; ++n)
					out[n] ^= ivec[n];
				for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n)
					out[n] = tmp[n];
				memcpy(ivec, tmp, CAMELLIA_BLOCK_SIZE);
				}
			}
		}
	else /* no aligned */
		{
		if (CAMELLIA_ENCRYPT == enc)
			{
			while (len >= CAMELLIA_BLOCK_SIZE)
				{
				for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n)
					out[n] = in[n] ^ iv[n];
			Camellia_encrypt(out, out, key);
				memcpy(t32, out, CAMELLIA_BLOCK_SIZE);
				key->enc(key->rd_key, t32);
				memcpy(out, t32, CAMELLIA_BLOCK_SIZE);
				iv = out;
				len -= CAMELLIA_BLOCK_SIZE;
				in += CAMELLIA_BLOCK_SIZE;
@@ -90,7 +170,7 @@ void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
					out[n] = in[n] ^ iv[n];
				for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n)
					out[n] = iv[n];
			Camellia_encrypt(out, out, key);
				key->enc(key->rd_key, (uint32_t *)out);
				iv = out;
				}
			memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE);
@@ -99,7 +179,9 @@ void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
			{
			while (len >= CAMELLIA_BLOCK_SIZE)
				{
			Camellia_decrypt(in, out, key);
				memcpy(t32,in,CAMELLIA_BLOCK_SIZE);
				key->dec(key->rd_key,t32);
				memcpy(out,t32,CAMELLIA_BLOCK_SIZE);
				for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n)
					out[n] ^= iv[n];
				iv = in;
@@ -109,7 +191,10 @@ void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
				}
			if (len)
				{
			Camellia_decrypt(in,tmp,key);
				memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
				memcpy(t32, in, CAMELLIA_BLOCK_SIZE);
				key->dec(key->rd_key, t32);
				memcpy(out, t32, CAMELLIA_BLOCK_SIZE);
				for(n=0; n < len; ++n)
					out[n] = tmp[n] ^ iv[n];
				iv = in;
@@ -121,7 +206,9 @@ void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
			while (len >= CAMELLIA_BLOCK_SIZE)
				{
				memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
			Camellia_decrypt(in, out, key);
				memcpy(t32, in, CAMELLIA_BLOCK_SIZE);
				key->dec(key->rd_key, t32);
				memcpy(out, t32, CAMELLIA_BLOCK_SIZE);
				for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n)
					out[n] ^= ivec[n];
				memcpy(ivec, tmp, CAMELLIA_BLOCK_SIZE);
@@ -132,7 +219,9 @@ void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
			if (len)
				{
				memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
			Camellia_decrypt(tmp, out, key);
				memcpy(t32, in, CAMELLIA_BLOCK_SIZE);
				key->dec(key->rd_key,t32);
				memcpy(out, t32, CAMELLIA_BLOCK_SIZE);
				for(n=0; n < len; ++n)
					out[n] ^= ivec[n];
				for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n)
@@ -141,3 +230,5 @@ void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
				}
			}
		}
}
+102 −21
Original line number Diff line number Diff line
@@ -68,30 +68,111 @@
#ifndef HEADER_CAMELLIA_LOCL_H
#define HEADER_CAMELLIA_LOCL_H

#include "openssl/e_os2.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#if defined(_MSC_VER)
typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
typedef unsigned __int64 uint64_t;
#else
#include <inttypes.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif

#define ALIGN 4
#define UNITSIZE 4

#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)); }
#else
# 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); }
# define GETU32(p) SWAP(*((uint32_t *)(p)))
# define PUTU32(ct, st) { *((uint32_t *)(ct)) = SWAP((st)); }
# define CAMELLIA_SWAP4(x) (x = ( _lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) )


#else /* not windows */
# define GETU32(pt) (((uint32_t)(pt)[0] << 24) \
	^ ((uint32_t)(pt)[1] << 16) \
	^ ((uint32_t)(pt)[2] <<  8) \
	^ ((uint32_t)(pt)[3]))

# define PUTU32(ct, st) { (ct)[0] = (uint8_t)((st) >> 24); \
	(ct)[1] = (uint8_t)((st) >> 16); \
	(ct)[2] = (uint8_t)((st) >>  8); \
	(ct)[3] = (uint8_t)(st); }

#ifdef L_ENDIAN
#if (defined (__GNUC__) && !defined(i386))
#define CAMELLIA_SWAP4(x) \
  do{\
    asm("bswap %1" : "+r" (x));\
  }while(0)
#else /* not gcc */
#define CAMELLIA_SWAP4(x) \
   do{\
     x = ((uint32_t)x << 16) + ((uint32_t)x >> 16);\
     x = (((uint32_t)x & 0xff00ff) << 8) + (((uint32_t)x >> 8) & 0xff00ff);\
   } while(0)
#endif /* not gcc */
#else /* big endian */
#define CAMELLIA_SWAP4(x)
#endif /* L_ENDIAN */
#endif

/* Internal types */
typedef unsigned char Byte;
typedef unsigned int Word;
#define COPY4WORD(dst, src)	 \
	     do			 \
		     {		 \
		     (dst)[0]=(src)[0];		\
		     (dst)[1]=(src)[1];		\
		     (dst)[2]=(src)[2];		\
		     (dst)[3]=(src)[3];		\
		     }while(0)

#ifdef CAMELLIA_LONG
typedef unsigned long u32;
#else
typedef unsigned int u32;
#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 unsigned char *key, uint32_t *subkey);
void camellia_setup192(const unsigned char *key, uint32_t *subkey);
void camellia_setup256(const unsigned char *key, uint32_t *subkey);

void camellia_encrypt128(const uint32_t *subkey, uint32_t *io);
void camellia_decrypt128(const uint32_t *subkey, uint32_t *io);
void camellia_encrypt256(const uint32_t *subkey, uint32_t *io);
void camellia_decrypt256(const uint32_t *subkey, uint32_t *io);

#ifdef __cplusplus
}
#endif
typedef unsigned short u16;
typedef unsigned char u8;

void Camellia_Ekeygen(const int keyBitLength, const Byte *rawKey, KEY_TABLE_TYPE keyTable);
void Camellia_EncryptBlock(const int keyBitLength, const Byte plaintext[], 
		const KEY_TABLE_TYPE keyTable, Byte ciphertext[]);
void Camellia_DecryptBlock(const int keyBitLength, const Byte ciphertext[], 
		const KEY_TABLE_TYPE keyTable, Byte plaintext[]);

#endif /* #ifndef HEADER_CAMELLIA_LOCL_H */
+35 −6
Original line number Diff line number Diff line
@@ -59,10 +59,31 @@ int Camellia_set_key(const unsigned char *userKey, const int bits,
	CAMELLIA_KEY *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;
	Camellia_Ekeygen(bits , userKey, key->rd_key);
		}
	
	key->bitLength = bits;
	return 0;
	}
@@ -70,12 +91,20 @@ int Camellia_set_key(const unsigned char *userKey, const int bits,
void Camellia_encrypt(const unsigned char *in, unsigned char *out,
	const CAMELLIA_KEY *key)
	{
	Camellia_EncryptBlock(key->bitLength, in , key->rd_key , out);
	uint32_t tmp[UNITSIZE];

	memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
	key->enc(key->rd_key, tmp);
	memcpy(out, tmp, CAMELLIA_BLOCK_SIZE);
	}

void Camellia_decrypt(const unsigned char *in, unsigned char *out,
	const CAMELLIA_KEY *key)
	{
	Camellia_DecryptBlock(key->bitLength, in , key->rd_key , out);
	uint32_t tmp[UNITSIZE];

	memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
	key->dec(key->rd_key, tmp);
	memcpy(out, tmp, CAMELLIA_BLOCK_SIZE);
	}