X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fcamellia%2Fcmll_cbc.c;h=2e96b007265eb51882dd185335200576e305b22f;hp=545e6c1f41375c6d65dbc3275e3dcb146a5e54ff;hb=c163b5f7a00eca3a7fd776456a0ff92bbc93f225;hpb=67912e0032f5131f9959533c82dac997cb7e2e43 diff --git a/crypto/camellia/cmll_cbc.c b/crypto/camellia/cmll_cbc.c index 545e6c1f41..2e96b00726 100644 --- a/crypto/camellia/cmll_cbc.c +++ b/crypto/camellia/cmll_cbc.c @@ -55,89 +55,230 @@ # endif #endif #include +#include #include #include #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; + u32 t32[UNITSIZE]; + const union { long one; char little; } camellia_endian = {1}; + 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((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); } - 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); + 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, in, CAMELLIA_BLOCK_SIZE); + if (camellia_endian.little) + SWAP4WORD((u32 *)tmp); + key->dec(key->rd_key, (u32 *)tmp); + if (camellia_endian.little) + SWAP4WORD((u32 *)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; + while (len >= CAMELLIA_BLOCK_SIZE) + { + memcpy(tmp, 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, CAMELLIA_BLOCK_SIZE); + len -= CAMELLIA_BLOCK_SIZE; + in += CAMELLIA_BLOCK_SIZE; + out += CAMELLIA_BLOCK_SIZE; + } + if (len) + { + memcpy(tmp, 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[n]; + memcpy(ivec, tmp, CAMELLIA_BLOCK_SIZE); + } } - if (len) + } + else /* no aligned */ + { + if (CAMELLIA_ENCRYPT == enc) { - Camellia_decrypt(in,tmp,key); - for(n=0; n < len; ++n) - out[n] = tmp[n] ^ iv[n]; - iv = in; + 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); + if (camellia_endian.little) + SWAP4WORD(t32); + key->enc(key->rd_key, t32); + if (camellia_endian.little) + SWAP4WORD(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]; + memcpy(t32, out, CAMELLIA_BLOCK_SIZE); + if (camellia_endian.little) + SWAP4WORD(t32); + key->enc(key->rd_key, t32); + if (camellia_endian.little) + SWAP4WORD(t32); + memcpy(out, t32, CAMELLIA_BLOCK_SIZE); + iv = out; + } + memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE); } - memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE); - } - else - { - while (len >= CAMELLIA_BLOCK_SIZE) + else if (in != out) { - 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; + while (len >= CAMELLIA_BLOCK_SIZE) + { + memcpy(t32,in,CAMELLIA_BLOCK_SIZE); + if (camellia_endian.little) + SWAP4WORD(t32); + key->dec(key->rd_key,t32); + if (camellia_endian.little) + SWAP4WORD(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(t32, in, CAMELLIA_BLOCK_SIZE); + if (camellia_endian.little) + SWAP4WORD(t32); + key->dec(key->rd_key, t32); + if (camellia_endian.little) + SWAP4WORD(t32); + memcpy(out, t32, CAMELLIA_BLOCK_SIZE); + for(n=0; n < len; ++n) + out[n] ^= iv[n]; + iv = in; + } + memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE); } - if (len) + else { - 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); + memcpy(t32, in, CAMELLIA_BLOCK_SIZE); + if (camellia_endian.little) + SWAP4WORD(t32); + key->dec(key->rd_key, t32); + if (camellia_endian.little) + SWAP4WORD(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); + if (camellia_endian.little) + SWAP4WORD(t32); + key->dec(key->rd_key,t32); + if (camellia_endian.little) + SWAP4WORD(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); + } } } - } +} +