diff options
author | Damien Miller <djm@cvs.openbsd.org> | 2010-10-01 22:54:09 +0000 |
---|---|---|
committer | Damien Miller <djm@cvs.openbsd.org> | 2010-10-01 22:54:09 +0000 |
commit | 1ff1cadcea15907209887ed0d1bba42ea516c3c9 (patch) | |
tree | 00d79c3545c83367a0d86b4aff358834f490c94a | |
parent | 0670cce672f9447e2be1b428f151dfec90f99b1d (diff) |
import OpenSSL-1.0.0a
-rw-r--r-- | lib/libssl/src/crypto/modes/ctr128.c | 92 |
1 files changed, 12 insertions, 80 deletions
diff --git a/lib/libssl/src/crypto/modes/ctr128.c b/lib/libssl/src/crypto/modes/ctr128.c index ee642c5863c..932037f5514 100644 --- a/lib/libssl/src/crypto/modes/ctr128.c +++ b/lib/libssl/src/crypto/modes/ctr128.c @@ -48,8 +48,7 @@ * */ -#include <openssl/crypto.h> -#include "modes_lcl.h" +#include "modes.h" #include <string.h> #ifndef MODES_DEBUG @@ -59,6 +58,17 @@ #endif #include <assert.h> +typedef unsigned int u32; +typedef unsigned char u8; + +#define STRICT_ALIGNMENT +#if defined(__i386) || defined(__i386__) || \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \ + defined(__s390__) || defined(__s390x__) +# undef STRICT_ALIGNMENT +#endif + /* NOTE: the IV/counter CTR mode is big-endian. The code itself * is endian-neutral. */ @@ -172,81 +182,3 @@ void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out, *num=n; } - -/* increment upper 96 bits of 128-bit counter by 1 */ -static void ctr96_inc(unsigned char *counter) { - u32 n=12; - u8 c; - - do { - --n; - c = counter[n]; - ++c; - counter[n] = c; - if (c) return; - } while (n); -} - -void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out, - size_t len, const void *key, - unsigned char ivec[16], unsigned char ecount_buf[16], - unsigned int *num, ctr128_f func) -{ - unsigned int n,ctr32; - - assert(in && out && key && ecount_buf && num); - assert(*num < 16); - - n = *num; - - while (n && len) { - *(out++) = *(in++) ^ ecount_buf[n]; - --len; - n = (n+1) % 16; - } - - ctr32 = GETU32(ivec+12); - while (len>=16) { - size_t blocks = len/16; - /* - * 1<<28 is just a not-so-small yet not-so-large number... - * Below condition is practically never met, but it has to - * be checked for code correctness. - */ - if (sizeof(size_t)>sizeof(unsigned int) && blocks>(1U<<28)) - blocks = (1U<<28); - /* - * As (*func) operates on 32-bit counter, caller - * has to handle overflow. 'if' below detects the - * overflow, which is then handled by limiting the - * amount of blocks to the exact overflow point... - */ - ctr32 += (u32)blocks; - if (ctr32 < blocks) { - blocks -= ctr32; - ctr32 = 0; - } - (*func)(in,out,blocks,key,ivec); - /* (*ctr) does not update ivec, caller does: */ - PUTU32(ivec+12,ctr32); - /* ... overflow was detected, propogate carry. */ - if (ctr32 == 0) ctr96_inc(ivec); - blocks *= 16; - len -= blocks; - out += blocks; - in += blocks; - } - if (len) { - memset(ecount_buf,0,16); - (*func)(ecount_buf,ecount_buf,1,key,ivec); - ++ctr32; - PUTU32(ivec+12,ctr32); - if (ctr32 == 0) ctr96_inc(ivec); - while (len--) { - out[n] = in[n] ^ ecount_buf[n]; - ++n; - } - } - - *num=n; -} |