summaryrefslogtreecommitdiffstats
path: root/crypto/camellia/cmll_cbc.c
diff options
context:
space:
mode:
authorAndy Polyakov <appro@openssl.org>2008-10-28 08:47:24 +0000
committerAndy Polyakov <appro@openssl.org>2008-10-28 08:47:24 +0000
commit27f864e8acd4c495f94363af3074861576af303f (patch)
tree9db6efbb80495e2d008cf9148be487a970ef31ca /crypto/camellia/cmll_cbc.c
parent80aa9cc985251463a3ad65b0a4d64bf93c70b175 (diff)
Camellia update. Quoting camellia.c:
/* * This release balances code size and performance. In particular key * schedule setup is fully unrolled, because doing so *significantly* * reduces amount of instructions per setup round and code increase is * justifiable. In block functions on the other hand only inner loops * are unrolled, as full unroll gives only nominal performance boost, * while code size grows 4 or 7 times. Also, unlike previous versions * this one "encourages" compiler to keep intermediate variables in * registers, which should give better "all round" results, in other * words reasonable performance even with not so modern compilers. */
Diffstat (limited to 'crypto/camellia/cmll_cbc.c')
-rw-r--r--crypto/camellia/cmll_cbc.c248
1 files changed, 59 insertions, 189 deletions
diff --git a/crypto/camellia/cmll_cbc.c b/crypto/camellia/cmll_cbc.c
index 4141a7b59b..545e6c1f41 100644
--- a/crypto/camellia/cmll_cbc.c
+++ b/crypto/camellia/cmll_cbc.c
@@ -55,219 +55,89 @@
# 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;
- 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(((size_t)in|(size_t)out|(size_t)ivec) % sizeof(u32) == 0)
+ if (CAMELLIA_ENCRYPT == enc)
{
- if (CAMELLIA_ENCRYPT == enc)
+ while (len >= CAMELLIA_BLOCK_SIZE)
{
- 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);
+ 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;
}
- else if (in != out)
+ if (len)
{
- 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);
+ 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;
}
- else /* in == out */
+ memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE);
+ }
+ else if (in != out)
+ {
+ while (len >= CAMELLIA_BLOCK_SIZE)
{
- 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);
- }
+ 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;
}
- }
- else /* no aligned */
- {
- if (CAMELLIA_ENCRYPT == enc)
+ if (len)
{
- 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);
+ Camellia_decrypt(in,tmp,key);
+ for(n=0; n < len; ++n)
+ out[n] = tmp[n] ^ iv[n];
+ iv = in;
}
- else if (in != out)
+ memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE);
+ }
+ else
+ {
+ while (len >= CAMELLIA_BLOCK_SIZE)
{
- 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);
+ 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;
}
- else
+ if (len)
{
- 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);
- }
+ 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);
}
}
-}
+ }