// The input encrypted as though 128bit counter mode is being used. The extra // state information to record how much of the 128bit block we have used is // contained in *num, and the encrypted counter is kept in ecount_buf. Both // *num and ecount_buf must be initialised with zeros before the first call to // CRYPTO_ctr128_encrypt(). // // This algorithm assumes that the counter is in the x lower bits of the IV // (ivec), and that the application has full control over overflow and the rest // of the IV. This implementation takes NO responsibility for checking that // the counter doesn't overflow into the rest of the IV when incremented. void CRYPTO_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len, const void *key, uint8_t ivec[16], uint8_t ecount_buf[16], unsigned int *num, block128_f block) { unsigned int n; assert(key && ecount_buf && num); assert(len == 0 || (in && out)); assert(*num < 16); n = *num; while (n && len) { *(out++) = *(in++) ^ ecount_buf[n]; --len; n = (n + 1) % 16; } #if STRICT_ALIGNMENT if (((uintptr_t)in | (uintptr_t)out | (uintptr_t)ecount_buf) % sizeof(size_t) != 0) { size_t l = 0; while (l < len) { if (n == 0) { (*block)(ivec, ecount_buf, key); ctr128_inc(ivec); } out[l] = in[l] ^ ecount_buf[n]; ++l; n = (n + 1) % 16; } *num = n; return; } #endif while (len >= 16) { (*block)(ivec, ecount_buf, key); ctr128_inc(ivec); for (n = 0; n < 16; n += sizeof(size_t)) { store_word_le(out + n, load_word_le(in + n) ^ load_word_le(ecount_buf + n)); } len -= 16; out += 16; in += 16; n = 0; } if (len) { (*block)(ivec, ecount_buf, key); ctr128_inc(ivec); while (len--) { out[n] = in[n] ^ ecount_buf[n]; ++n; } } *num = n; }
/* The input encrypted as though 128bit counter mode is being used. The extra * state information to record how much of the 128bit block we have used is * contained in *num, and the encrypted counter is kept in ecount_buf. Both * *num and ecount_buf must be initialised with zeros before the first call to * CRYPTO_ctr128_encrypt(). * * This algorithm assumes that the counter is in the x lower bits of the IV * (ivec), and that the application has full control over overflow and the rest * of the IV. This implementation takes NO responsibility for checking that * the counter doesn't overflow into the rest of the IV when incremented. */ void CRYPTO_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len, const void *key, uint8_t ivec[16], uint8_t ecount_buf[16], unsigned int *num, block128_f block) { unsigned int n; size_t l=0; assert(in && out && key && ecount_buf && num); assert(*num < 16); assert((16 % sizeof(size_t)) == 0); n = *num; while (n && len) { *(out++) = *(in++) ^ ecount_buf[n]; --len; n = (n + 1) % 16; } if (STRICT_ALIGNMENT && ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) { while (l < len) { if (n == 0) { (*block)(ivec, ecount_buf, key); ctr128_inc(ivec); } out[l] = in[l] ^ ecount_buf[n]; ++l; n = (n + 1) % 16; } *num = n; return; } while (len >= 16) { (*block)(ivec, ecount_buf, key); ctr128_inc(ivec); for (; n < 16; n += sizeof(size_t)) *(size_t *)(out + n) = *(size_t *)(in + n) ^ *(size_t *)(ecount_buf + n); len -= 16; out += 16; in += 16; n = 0; } if (len) { (*block)(ivec, ecount_buf, key); ctr128_inc(ivec); while (len--) { out[n] = in[n] ^ ecount_buf[n]; ++n; } } *num = n; }
static void ctr128_inc_aligned(unsigned char *counter) { size_t *data, c, d, n; const union { long one; char little; } is_endian = { 1 }; if (is_endian.little || ((size_t)counter % sizeof(size_t)) != 0) { ctr128_inc(counter); return; } data = (size_t *)counter; c = 1; n = 16 / sizeof(size_t); do { --n; d = data[n] += c; /* did addition carry? */ c = ((d - c) & ~d) >> (sizeof(size_t) * 8 - 1); } while (n); }
static void ctr128_inc_aligned(unsigned char *counter) { size_t *data, c, n; const union { long one; char little; } is_endian = { 1 }; if (is_endian.little) { ctr128_inc(counter); return; } data = (size_t *)counter; n = 16 / sizeof(size_t); do { --n; c = data[n]; ++c; data[n] = c; if (c) return; } while (n); }
static void ctr128_inc_aligned(unsigned char *counter) { size_t *data,c,n; if (_BYTE_ORDER == _LITTLE_ENDIAN) { ctr128_inc(counter); return; } data = (size_t *)counter; n = 16/sizeof(size_t); do { --n; c = data[n]; ++c; data[n] = c; if (c) return; } while (n); }
/* * The input encrypted as though 128bit counter mode is being used. The * extra state information to record how much of the 128bit block we have * used is contained in *num, and the encrypted counter is kept in * ecount_buf. Both *num and ecount_buf must be initialised with zeros * before the first call to CRYPTO_ctr128_encrypt(). This algorithm assumes * that the counter is in the x lower bits of the IV (ivec), and that the * application has full control over overflow and the rest of the IV. This * implementation takes NO responsability for checking that the counter * doesn't overflow into the rest of the IV when incremented. */ void CRYPTO_ctr128_encrypt(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, block128_f block) { unsigned int n; size_t l = 0; assert(in && out && key && ecount_buf && num); assert(*num < 16); n = *num; #if !defined(OPENSSL_SMALL_FOOTPRINT) if (16 % sizeof(size_t) == 0) { /* always true actually */ do { while (n && len) { *(out++) = *(in++) ^ ecount_buf[n]; --len; n = (n + 1) % 16; } # if defined(STRICT_ALIGNMENT) if (((size_t)in | (size_t)out | (size_t)ecount_buf) % sizeof(size_t) != 0) break; # endif while (len >= 16) { (*block) (ivec, ecount_buf, key); ctr128_inc_aligned(ivec); for (n = 0; n < 16; n += sizeof(size_t)) *(size_t *)(out + n) = *(size_t *)(in + n) ^ *(size_t *)(ecount_buf + n); len -= 16; out += 16; in += 16; n = 0; } if (len) { (*block) (ivec, ecount_buf, key); ctr128_inc_aligned(ivec); while (len--) { out[n] = in[n] ^ ecount_buf[n]; ++n; } } *num = n; return; } while (0); } /* the rest would be commonly eliminated by x86* compiler */ #endif while (l < len) { if (n == 0) { (*block) (ivec, ecount_buf, key); ctr128_inc(ivec); } out[l] = in[l] ^ ecount_buf[n]; ++l; n = (n + 1) % 16; } *num = n; }