diff options
Diffstat (limited to 'src/modes/ctr')
-rw-r--r-- | src/modes/ctr/ctr.cpp | 41 |
1 files changed, 21 insertions, 20 deletions
diff --git a/src/modes/ctr/ctr.cpp b/src/modes/ctr/ctr.cpp index a3476c474..d458d7848 100644 --- a/src/modes/ctr/ctr.cpp +++ b/src/modes/ctr/ctr.cpp @@ -65,21 +65,24 @@ std::string CTR_BE::name() const */ void CTR_BE::set_iv(const InitializationVector& iv) { - if(iv.length() != cipher->BLOCK_SIZE) + const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE; + + if(iv.length() != BLOCK_SIZE) throw Invalid_IV_Length(name(), iv.length()); enc_buffer.clear(); position = 0; - for(u32bit i = 0; i != PARALLEL_BLOCKS; ++i) + counter.copy(0, iv.begin(), iv.length()); + + for(u32bit i = 1; i != PARALLEL_BLOCKS; ++i) { - counter.copy(i*cipher->BLOCK_SIZE, iv.begin(), iv.length()); + counter.copy(i*BLOCK_SIZE, + counter.begin() + (i-1)*BLOCK_SIZE, BLOCK_SIZE); - // FIXME: this is stupid - for(u32bit j = 0; j != i; ++j) - for(s32bit k = cipher->BLOCK_SIZE - 1; k >= 0; --k) - if(++counter[i*cipher->BLOCK_SIZE+k]) - break; + for(s32bit j = BLOCK_SIZE - 1; j >= 0; --j) + if(++counter[i*BLOCK_SIZE+j]) + break; } cipher->encrypt_n(counter, enc_buffer, PARALLEL_BLOCKS); @@ -122,19 +125,17 @@ void CTR_BE::increment_counter() { for(u32bit i = 0; i != PARALLEL_BLOCKS; ++i) { - // FIXME: Can do it in a single loop - /* - for(u32bit j = 1; j != cipher->BLOCK_SIZE; ++j) - { - byte carry = 0; - byte z = counter[(i+1)*cipher->BLOCK_SIZE-1] + PARALLEL_BLOCKS; - - if( - */ - for(u32bit j = 0; j != PARALLEL_BLOCKS; ++j) - for(s32bit k = cipher->BLOCK_SIZE - 1; k >= 0; --k) - if(++counter[i*cipher->BLOCK_SIZE+k]) + byte* this_ctr = counter + i*cipher->BLOCK_SIZE; + + byte last_byte = this_ctr[cipher->BLOCK_SIZE-1]; + last_byte += PARALLEL_BLOCKS; + + if(this_ctr[cipher->BLOCK_SIZE-1] > last_byte) + for(s32bit j = cipher->BLOCK_SIZE - 2; j >= 0; --j) + if(++this_ctr[j]) break; + + this_ctr[cipher->BLOCK_SIZE-1] = last_byte; } cipher->encrypt_n(counter, enc_buffer, PARALLEL_BLOCKS); |