Can I specify nonce counter and counter in AES counter mode?

I am trying to use the Crypto ++ library to create AES Counter based encryption / decryption

I want to split the IV value into nonce and counter.
Is there any API that directly accepts nonce and counter to construct an IV?

I did the following to achieve it

byte counter[AES::BLOCKSIZE/2] = {0x0};     // initialized to zero : 64 bit counter
string counterstr ;
byte nonce[AES::BLOCKSIZE/2];                // 64 bit nonce 
string noncestr ;
prng.GenerateBlock(nonce, sizeof(nonce));
StringSource(nonce, sizeof(nonce), true,
    new HexEncoder(
    new StringSink(noncestr)
    ) // HexEncoder
    );
StringSource(counter, sizeof(counter), true,
    new HexEncoder(
    new StringSink(counterstr)
    ) // HexEncoder
    );
SecByteBlock no = HexDecodeString(noncestr);
SecByteBlock ctr = HexDecodeString(counterstr);
string ivv = noncestr + counterstr;
SecByteBlock ivvb = HexDecodeString(ivv);

      

then i use

e.SetKeyWithIV(key, sizeof(key), iv);

      

Questions:

  • Is this the only way to achieve this or is there some other easier way?

  • Does the counter increment when doing block encryption or decryption?

  • This is trivial, should I specify a different nonce for each block?

+3


source to share


1 answer


Is this the only way to achieve this or is there another easier way?

Not. The increment function runs on a full 128-bit block. See CTR mode and increment counter on the Crypto ++ wiki.

Longer answer: Yes , if , you provide your own function IncrementCounter

. The longer answer may be Yes if the high order bit is used for the nonce and low order bit for the counter (see below).




Does the counter increment when doing block encryption or decryption?

Yes.




This is trivial, should I specify a different nonce for each block?

Not. The counter increases.




Is there any API that directly accepts nonce and counter to construct an IV?

Not. More practically, there is a limit to how much plain text can be encrypted under the key / nonce pair (or security context). I think it is well below 2GB. If my recollection is correct, you will have to re-enter long before your counter goes into high 64-bit.

Essentially, this means that you can use the high 64-bit as the random nonce and use the lower 64-bit as the counter. Thus, your code will look something like this:

byte counter[AES::BLOCKSIZE] = {0};
prng.GenerateBlock(counter, 8);

      

After executing the above code, the high 64-bit values ​​will be random, and the lower 64-bits will start at 0 and serve as a counter.

Since 2GB is the limit, you can use a 12-4 split instead of 8-8:

byte counter[AES::BLOCKSIZE] = {0};
prng.GenerateBlock(counter, 12);

      

After executing the above code, the high 96-bit values ​​will be random and the low 32-bit values ​​will start at 0 and serve as a counter.




Related, never reuse nonce. Each message must have its own unique security context. This usually means a unique nonce (another option is to provide a unique key for each message). Otherwise, you can trivially recover the key with XOR

.

0


source







All Articles