New Camellia implementation (replacing previous version)
Submitted by: NTT
This commit is contained in:
parent
d045e1d77e
commit
d9c06b56ca
5 changed files with 1874 additions and 597 deletions
File diff suppressed because it is too large
Load diff
|
@ -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 */
|
||||
|
||||
|
|
|
@ -55,89 +55,180 @@
|
|||
# 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)
|
||||
{
|
||||
const unsigned long length, const CAMELLIA_KEY *key,
|
||||
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 (CAMELLIA_ENCRYPT == enc)
|
||||
if(((size_t)in) % ALIGN == 0
|
||||
&& ((size_t)out) % ALIGN == 0
|
||||
&& ((size_t)ivec) % ALIGN == 0)
|
||||
{
|
||||
while (len >= CAMELLIA_BLOCK_SIZE)
|
||||
if (CAMELLIA_ENCRYPT == enc)
|
||||
{
|
||||
for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n)
|
||||
out[n] = in[n] ^ iv[n];
|
||||
Camellia_encrypt(out, out, key);
|
||||
iv = out;
|
||||
len -= CAMELLIA_BLOCK_SIZE;
|
||||
in += CAMELLIA_BLOCK_SIZE;
|
||||
out += CAMELLIA_BLOCK_SIZE;
|
||||
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);
|
||||
}
|
||||
if (len)
|
||||
else if (in != out)
|
||||
{
|
||||
for(n=0; n < len; ++n)
|
||||
out[n] = in[n] ^ iv[n];
|
||||
for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n)
|
||||
out[n] = iv[n];
|
||||
Camellia_encrypt(out, out, key);
|
||||
iv = 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);
|
||||
}
|
||||
memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE);
|
||||
}
|
||||
else if (in != out)
|
||||
{
|
||||
while (len >= CAMELLIA_BLOCK_SIZE)
|
||||
else /* in == out */
|
||||
{
|
||||
Camellia_decrypt(in, out, key);
|
||||
for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n)
|
||||
out[n] ^= iv[n];
|
||||
iv = in;
|
||||
len -= CAMELLIA_BLOCK_SIZE;
|
||||
in += CAMELLIA_BLOCK_SIZE;
|
||||
out += CAMELLIA_BLOCK_SIZE;
|
||||
}
|
||||
if (len)
|
||||
{
|
||||
Camellia_decrypt(in,tmp,key);
|
||||
for(n=0; n < len; ++n)
|
||||
out[n] = tmp[n] ^ iv[n];
|
||||
iv = in;
|
||||
}
|
||||
memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (len >= CAMELLIA_BLOCK_SIZE)
|
||||
{
|
||||
memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
|
||||
Camellia_decrypt(in, out, key);
|
||||
for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n)
|
||||
out[n] ^= ivec[n];
|
||||
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);
|
||||
Camellia_decrypt(tmp, out, key);
|
||||
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);
|
||||
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];
|
||||
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;
|
||||
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(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;
|
||||
len -= CAMELLIA_BLOCK_SIZE;
|
||||
in += CAMELLIA_BLOCK_SIZE;
|
||||
out += CAMELLIA_BLOCK_SIZE;
|
||||
}
|
||||
if (len)
|
||||
{
|
||||
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;
|
||||
}
|
||||
memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (len >= CAMELLIA_BLOCK_SIZE)
|
||||
{
|
||||
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 < CAMELLIA_BLOCK_SIZE; ++n)
|
||||
out[n] ^= ivec[n];
|
||||
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);
|
||||
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)
|
||||
out[n] = tmp[n];
|
||||
memcpy(ivec, tmp, CAMELLIA_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 SWAP(x) ( _lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00 )
|
||||
# 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 */
|
||||
|
||||
|
|
|
@ -53,16 +53,37 @@
|
|||
#include <openssl/camellia.h>
|
||||
#include "cmll_locl.h"
|
||||
|
||||
const char *CAMELLIA_version="CAMELLIA" OPENSSL_VERSION_PTEXT;
|
||||
const char *CAMELLIA_version="CAMELLIA" OPENSSL_VERSION_PTEXT;
|
||||
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue