Decrypt data using an authenticated encryption algorithm.
Public Declare Function CIPHER_DecryptAEAD Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutBytes As Long, ByRef lpInput As Byte, ByVal nInputLen As Long, ByRef lpKey As Byte, ByVal nKeyLen As Long, ByRef lpIV As Byte, ByVal nIvLen As Long, ByRef lpAAD As Byte, ByVal nAadLen As Long, ByVal nOptions As Long) As Long
nRet = CIPHER_DecryptAEAD(lpOutput(0), nOutBytes, lpInput(0), nInputLen, lpKey(0), nKeylen, lpIV(0), nIvLen, lpAAD(0), nAadLen, nOptions)
long __stdcall CIPHER_DecryptAEAD(unsigned char *lpOutput, long nOutBytes, const unsigned char *lpInput, long nInputLen, const unsigned char *lpKey, long nKeyLen, const unsigned char *lpIV, long nIvLen, const unsigned char *lpAAD, long nAadLen, long nOptions);
AEAD_AES_128_GCM
authenticated encryption algorithm from RFC 5116AEAD_AES_256_GCM
authenticated encryption algorithm from RFC 5116AES-192-GCM
authenticated encryption algorithm in the same mannerIf successful, the return value is the number of bytes required in the output; otherwise it returns a negative error code.
Public Function cipherDecryptAEAD
(lpInput() As Byte, lpKey() As Byte, lpIV() As Byte, lpAAD() As Byte, nOptions As Long) As Byte()
Cipher.DecryptAEAD Method (Byte[], Byte[], Byte[], AeadAlgorithm)
Cipher.DecryptAEAD Method (Byte[], Byte[], Byte[], Byte[], AeadAlgorithm, Cipher.Opts)
static bvec_t dipki::Cipher::DecryptAEAD (const bvec_t &input, const bvec_t &key, const bvec_t &iv, AeadAlg aeadAlg, Opts opts=Opts::None, const bvec_t &aad=bvec_t())
static Cipher.decrypt_aead(data, key, iv, aeadalg, aad=None, opts=Opts.DEFAULT)
The input is expected to be the ciphertext with a 16-byte tag appended ciphertext||Tag
, or, if the PKI_IV_PREFIX option is set,
then the same but with the 12-byte IV prepended IV||ciphertext||Tag
, where ||
denotes concatenation.
If the IV is not prepended to the input, then it must be provided in the lpIV argument.
Note that the term "IV" is used here to mean exactly the same as "nonce".
The length of key lpKey must be exactly the required key size in bytes: 16 for PKI_AEAD_AES_128_GCM, 24 for PKI_AEAD_AES_192_GCM, or 32 for PKI_AEAD_AES_256_GCM. It is an error if a PKI_AEAD_ option is not provided in the nOptions argument. In all cases the IV must be exactly 12 bytes (96 bits) and the tag must be exactly 16 bytes (128 bits). If additional authentication data (AAD) was provided during encryption then the exact same AAD data must be provided here.
If nOutBytes is set to zero or lpOutput set to 0 (or NULL
in C or ByVal 0&
in VBA),
the required number of bytes will be returned.
This will be either exactly 16 bytes shorter than the length of the input, or exactly 28 bytes shorter if the PKI_IV_PREFIX option is used.
The output buffer lpOutput must not be the same as or overlap with the input lpInput.
Dim key() As Byte Dim iv() As Byte Dim pt() As Byte Dim ct() As Byte Dim strOK As String Dim ptlen As Long Dim ctlen As Long Dim keylen As Long Dim ivlen As Long ' GCM Test Case #03 (AES-128) key = cnvBytesFromHexStr("feffe9928665731c6d6a8f9467308308") iv = cnvBytesFromHexStr("cafebabefacedbaddecaf888") ct = cnvBytesFromHexStr("42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f59854d5c2af327cd64a62cf35abd2ba6fab4") strOK = "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255" keylen = UBound(key) + 1 ivlen = UBound(iv) + 1 ctlen = UBound(ct) + 1 Debug.Print "KY=" & cnvHexStrFromBytes(key) Debug.Print "IV=" & cnvHexStrFromBytes(iv) Debug.Print "CT=" & cnvHexStrFromBytes(ct) ' 1. Find out required output length ptlen = CIPHER_DecryptAEAD(ByVal 0&, 0, ct(0), ctlen, key(0), keylen, iv(0), ivlen, ByVal 0&, 0, PKI_AEAD_AES_128_GCM) Debug.Print "CIPHER_DecryptAEAD returns " & ptlen ' 1a. Cope with error If (ptlen < 0) Then Debug.Print pkiErrorLookup(ptlen) Exit Sub End If ' 2. Allocate the output buffer, coping with possible zero-length output, then decrypt pt = vbNullString ' Default empty array If ptlen > 0 Then ReDim pt(ptlen - 1) ptlen = CIPHER_DecryptAEAD(pt(0), ptlen, ct(0), ctlen, key(0), keylen, iv(0), ivlen, ByVal 0&, 0, PKI_AEAD_AES_128_GCM) End If Debug.Print "PT=" & cnvHexStrFromBytes(pt) Debug.Print "OK=" & strOK
This should result in output as follows:
KY=FEFFE9928665731C6D6A8F9467308308 IV=CAFEBABEFACEDBADDECAF888 CT=42831EC2217774244B7221B784D0D49CE3AA212F2C02A4E035C17E2329ACA12E21D514B25466931C7D8F6A5AAC84AA051BA30B396A0AAC973D58E091473F59854D5C2AF327CD64A62CF35ABD2BA6FAB4 CIPHER_DecryptAEAD returns 64 PT=D9313225F88406E5A55909C5AFF5269A86A7A9531534F7DA2E4C303D8A318A721C3C0C95956809532FCF0E2449A6B525B16AEDF5AA0DE657BA637B391AAFD255 OK=d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255
Dim key() As Byte Dim iv() As Byte Dim pt() As Byte Dim ct() As Byte Dim strOK As String Dim ptlen As Long Dim ctlen As Long Dim keylen As Long Dim ivlen As Long ' GCM Test Case #03 (AES-128) key = cnvBytesFromHexStr("feffe9928665731c6d6a8f9467308308") iv = cnvBytesFromHexStr("cafebabefacedbaddecaf888") ct = cnvBytesFromHexStr("42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f59854d5c2af327cd64a62cf35abd2ba6fab4") strOK = "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255" keylen = UBound(key) + 1 ivlen = UBound(iv) + 1 ctlen = UBound(ct) + 1 Debug.Print "KY=" & cnvHexStrFromBytes(key) Debug.Print "IV=" & cnvHexStrFromBytes(iv) Debug.Print "CT=" & cnvHexStrFromBytes(ct) ' 1. Find out required output length ptlen = CIPHER_DecryptAEAD(ByVal 0&, 0, ct(0), ctlen, key(0), keylen, iv(0), ivlen, ByVal 0&, 0, PKI_AEAD_AES_128_GCM) Debug.Print "CIPHER_DecryptAEAD returns " & ptlen ' 1a. Cope with error If (ptlen < 0) Then Debug.Print pkiErrorLookup(ptlen) Exit Sub End If ' 2. Allocate the output buffer, coping with possible zero-length output, then decrypt pt = vbNullString ' Default empty array If ptlen > 0 Then ReDim pt(ptlen - 1) ptlen = CIPHER_DecryptAEAD(pt(0), ptlen, ct(0), ctlen, key(0), keylen, iv(0), ivlen, ByVal 0&, 0, PKI_AEAD_AES_128_GCM) End If Debug.Print "PT=" & cnvHexStrFromBytes(pt) Debug.Print "OK=" & strOK ' II.Using New wrapper ' Must dimension any optional empty byte array Dim lpAAD() As Byte pt = cipherDecryptAEAD(ct, key, iv, lpAAD, PKI_AEAD_AES_128_GCM) Debug.Print "PT=" & cnvHexStrFromBytes(pt)
Dim key() As Byte Dim iv() As Byte Dim pt() As Byte Dim ct() As Byte Dim strOK As String ' GCM Test Case #03 (AES-128) key = cnvBytesFromHexStr("feffe9928665731c6d6a8f9467308308") iv = cnvBytesFromHexStr("cafebabefacedbaddecaf888") ct = cnvBytesFromHexStr("42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f59854d5c2af327cd64a62cf35abd2ba6fab4") strOK = "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255" Dim lpAAD() As Byte ' Declare empty array for NULL input pt = cipherDecryptAEAD(ct, key, iv, lpAAD, PKI_AEAD_AES_128_GCM) Debug.Print "PT=" & cnvHexStrFromBytes(pt) Debug.Print "OK=" & strOK