int crypt_ctr_decrypt(cipher_context *cctx, uint8 *in, uint8 *out, ulong length, int64 offset) { int64 alignment; unsigned char ivec[MAX_CIPHER_BLOCK_SIZE]; unsigned char ecount_buf[MAX_CIPHER_BLOCK_SIZE]; unsigned int n; unsigned long l=length; if(offset%MAX_CIPHER_BLOCK_SIZE) { alignment = offset/MAX_CIPHER_BLOCK_SIZE; ctr_init_iv(ivec, alignment); crypt_enc_block(cctx, ivec, ecount_buf, MAX_CIPHER_BLOCK_SIZE); AES_ctr128_inc(ivec); n = offset%MAX_CIPHER_BLOCK_SIZE; } else { ctr_init_iv(ivec, offset/MAX_CIPHER_BLOCK_SIZE); n = 0; } while (l) { if (n == 0) { crypt_enc_block(cctx, ivec, ecount_buf, MAX_CIPHER_BLOCK_SIZE); AES_ctr128_inc(ivec); } *(out++) = *(in++) ^ ecount_buf[n]; n = (n+1) % MAX_CIPHER_BLOCK_SIZE; l--; } return 1; }
/* 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 AES_ctr128_encrypt(). */ void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, const unsigned long length, const AES_KEY *key, unsigned char counter[AES_BLOCK_SIZE], unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num) { unsigned int n; unsigned long l=length; assert(in && out && key && counter && num); assert(*num < AES_BLOCK_SIZE); n = *num; while (l--) { if (n == 0) { AES_encrypt(counter, ecount_buf, key); AES_ctr128_inc(counter); } *(out++) = *(in++) ^ ecount_buf[n]; n = (n+1) % AES_BLOCK_SIZE; } *num=n; }