1

I'm trying to use BCryptEncrypt to authenticate some AAD but the function is failing with STATUS_INVALID_PARAMETER. BCryptEncrypt takes 10 parameters. One of the parameters is BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO. BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO takes another 13 parameters.

Running my test program results in:

>.\bcrypt-gmac.exe
BCryptEncrypt error, 0xc000000d (STATUS_INVALID_PARAMETER)

STATUS_INVALID_PARAMETER is not very helpful in this case.

My question is, how do I determine which of the 23 parameters is causing the error when using Bcrypt?

Is there a way to get extended error information, like through BcryptPropertyGet (maybe a LAST_ERROR_PARAMETER or something similar)?

Or does Microsoft expect us to guess at the problem? In this case, I guess the answer is, "you can't".


The Microsoft docs don't provide examples of using Bcrypt. I also cannot find helpful examples on Stack Overflow or MSDN. Even Writing Secure Code for Windows Vista fails to provide examples.

Here is the treatment in Writing Secure Code for Windows Vista. It amounts to pseudo-code, which is very disappointing:

enter image description here

enter image description here

jww
  • 97,681
  • 90
  • 411
  • 885
  • Close voter: I'm not interested in having someone inspect my code. I want to learn which parameter is causing `STATUS_INVALID_PARAMETER`. 23 potential parameters (with combinations) is too many to eliminate through guessing. – jww Aug 14 '19 at 06:10
  • 1
    Example code for `BCryptEncrypt` does exist ([here for example](https://learn.microsoft.com/en-us/windows/win32/seccng/encrypting-data-with-cng)) though doesn't seem to handle authenticated cipher mode. The fields for [`BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO`](https://learn.microsoft.com/en-us/windows/win32/api/bcrypt/ns-bcrypt-bcrypt_authenticated_cipher_mode_info) do seem decently documented though. I could also find an example of authenticated encryption on SO [here](https://stackoverflow.com/a/30958068/20270). – Hasturkun Aug 14 '19 at 08:22
  • @Hasturkun - Nice find on the CNG examples. Microsoft docs don't provide sample code or link to them. Confer, [BCryptOpenAlgorithmProvider](https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptopenalgorithmprovider) (and friends). Be careful of the Microsoft docs for [BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO](https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/ns-bcrypt-bcrypt_authenticated_cipher_mode_info). There are at least 2 errors and omissions. Getting back to the question, do you know how to get more information when a call fails with `STATUS_INVALID_PARAMETER`? – jww Aug 14 '19 at 08:34
  • Debug it? It might validate all the parameters at the start of the function if you are lucky. – Anders Aug 14 '19 at 10:41

1 Answers1

0

I spent the better part of the day today struggling with this very issue. While I don't have a good way to answer your question as to how to determine, in a generic way, which parameter exactly is bad, I'll leave these few tidbits here for posterity:

  1. The cbTag field of the BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO needs to be set from the beginning. The pbTag isn't necessary until the final call that produces or verifies the tag, but cbTag must always be present.
  2. The pbNonce field of the BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO structure must remain set for all calls when chaining calls together (by using BCRYPT_AUTH_MODE_CHAIN_CALLS_FLAG).
  3. All calls during a chain (again using BCRYPT_AUTH_MODE_CHAIN_CALLS_FLAG) of encryptions or decryptions, except for the last, must provide an input whose size is a multiple of the algorithm's block size. I think the documentation actually says this, but it's not abundantly clear when they explicitly tell you not to set the BCRYPT_BLOCK_PADDING flag (with authenticated ciphers).

The code I'm working on will eventually be part of the library here, which will hopefully provide a working example to the next person.

John Tyner
  • 1,181
  • 1
  • 12
  • 15