2

I am exploring the use of Windows CNG to replace some OpenSSL-based code that takes advantage of AES in counter mode. From the outside, everything should look the same after the switch.

The section BCRYPT_CHAINING_MODE in this piece of CNG documentation gives me the impression that the only counter modes supported are BCRYPT_CHAIN_MODE_CCM, which sets the algorithm's chaining mode to counter with CBC-MAC mode (CCM) and BCRYPT_CHAIN_MODE_GCM, which sets the algorithm's chaining mode to Galois/counter mode (GCM)

I have no experience with CCM or GCM and would like to understand whether it is possible to use them in such a way that it can interoperate with CTR, by "disabling" the authentication part or in any other way. I did not find any indication that that is possible indeed, but on the other hand, I would be surprised if CNG does not support AES-CTR.

Maybe my question should have been "does Windows CNG support AES-CTR" to get a more direct answer :-)


Update: On another Microsoft webpage, in the section Cryptographic Algorithms, the table called "Table 12 – Advanced Encryption Standard (AES)" mentions "CTR( int only; 128 , 192 , 256 )", which I suppose means that it is internal functionality only.


I think this question is related: What is wrong with AES-CTR-HMAC-SHA256 - or why is it not in TLS?

2 Answers2

3

A message encrypted with AES-GCM can be decrypted with an AES-CTR library IF the authentication tag is stripped from the message.

If you are encrypting with AES-GCM and then adding an HMAC tag, you need to strip the HMAC and the GTAG off the message in order to decrypt it, assuming the IV section of the message is in the correct location for each library to handle.

edit:

Thanks to Maarten Bodewes for pointing out that the initial counter value is used in GCM to create the Galois hash key, and thus would need to be incremented by 1 in order to read the message data properly.

Richie Frame
  • 13,278
  • 1
  • 26
  • 42
2

That might not be speed-efficient, but for educational purpose it is possible to implement the CTR internals manually, by using the ECB mode of CNG:

Set the Algorithm mode:

BCryptSetProperty(hAesAlg, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_ECB, sizeof(BCRYPT_CHAIN_MODE_ECB), 0)

Encrypt all blocks the IV with counter with the key hKey:

BCryptEncrypt(hKey, 
              pbIV, // Feed the IV here
              cbIV, // block size (IV size)
              NULL, // padding not used
              NULL, // we do not need to pass IV here
              cbBlockLen,
              ptPlaintext,  //Output to plaintext buffer
              cbPlaintext,  //Blocksize here.
              &cbCipherText, 
              0)

and finally, XOR the whole resulting array with Ciphertext.

P.S> I forgot to add - the IV should be incremented after each call to BCryptEncrypt, and it's big-endian, the increment procedure on the 128 (or 192 or 256) bit integer (which IV is) should be implemented manually as well.

Pukeko
  • 36
  • 3