Attribute VB_Name = "TestAPI" ' $Id: TestAPI.bas $ '****************************** LICENSE *********************************** ' * Copyright (C) 2001-21 David Ireland, DI Management Services Pty Limited. ' * All rights reserved. <www.di-mgt.com.au> <www.cryptosys.net> ' * The code in this module is licensed under the terms of the MIT license. ' * For a copy, see <http://opensource.org/licenses/MIT> ' * Last updated: ' * $Date: 2021-09-25 10:01 $ ' * $Version: 6.20.0 $ '**************************************************************************** ' ' Some tests using the CryptoSys API VB6/VBA wrapper interface. Option Explicit Option Base 0 Public Const MIN_VERSION As Long = 62000 Public Sub DoAllTests() Dim n As Long Dim isok As Boolean Debug.Print ("INTERROGATE THE CORE DICRYPTOSYS DLL...") n = apiVersion() Debug.Print "Version=" & n If n < MIN_VERSION Then MsgBox "Require diCryptoSys v" & MIN_VERSION & " or higher", vbCritical Exit Sub End If Debug.Print "ModuleName=" & apiModuleName() Call test_cnvBytesLen Call test_rngKeyBytes Call test_rngKeyHex Call test_pbeKdf2 Call test_pbeKdf2Hex Call test_pbeScrypt Call test_pbeScryptHex Call test_xofBytes Call test_cipherStreamHex Call test_cipherStreamBytes Call test_CipherStreamInit Call test_prfBytes Call test_hashHexFromBits Call test_hashHexFromString Call test_padBytesBlock Call Test_padHexBlock Call test_unpadHex Call test_apiErrorLookup Call test_ErrorMessages Call test_rngNonceHex Call test_cipherEncryptBytes Call test_cipherEncryptHex Call test_cipherFile Call test_cipherKeyWrap Call test_aeadEncryptWithTag Call test_zlibDeflate Call test_hashHexFromBytes Call test_macHexFromBytes Call test_hashHexFromBytes Call test_macHexFromBytes Call test_Hash_Objects Call test_Hash_1Mxa Call test_MAC_Init Call test_MAC_AddBytes Call test_cipherInit_error Call test_cipherInit_objects Call test_cipherInitHex_objects Call test_comprCompress Call test_crc Call test_cipherStreamFile Call test_blfBytesBlock Call test_aeadInit Call test_wipeBytes Call test_apiModuleName Call test_apiCompileTime Debug.Print Debug.Print "ALL DONE." End Sub Public Sub test_cnvBytesLen() Debug.Print "test_cnvBytesLen..." Dim ab() As Byte Debug.Print cnvBytesLen(ab) ' Expecting 0 ReDim ab(10) ' NB actually 11 elements (0..10) Debug.Print cnvBytesLen(ab) ' 11 ab = vbNullString ' Set to empty array Debug.Print cnvBytesLen(ab) ' 0 End Sub Public Sub test_rngKeyBytes() Debug.Print "test_rngKeyBytes..." Dim i As Integer For i = 1 To 5 Debug.Print cnvHexStrFromBytes(rngKeyBytes(32)) Next End Sub Public Sub test_rngKeyHex() Dim i As Integer For i = 1 To 10 Debug.Print rngKeyHex(16) Next End Sub Public Sub test_pbeKdf2() Dim lpPwd() As Byte Dim lpSalt() As Byte Dim lpDK() As Byte lpPwd = StrConv("password", vbFromUnicode) lpSalt = cnvBytesFromHexStr("78 57 8E 5A 5D 63 CB 06") lpDK = pbeKdf2(24, lpPwd, lpSalt, 2048, API_HASH_SHA256) Debug.Print "DK=" & cnvHexStrFromBytes(lpDK) Debug.Print "OK=97B5A91D35AF542324881315C4F849E327C4707D1BC9D322" End Sub Public Sub test_pbeKdf2Hex() Dim strDerivedKey As String strDerivedKey = pbeKdf2Hex(24, "password", "78578E5A5D63CB06", 2048, 0) Debug.Print "Derived key = " & strDerivedKey Debug.Print "OK = " & "BFDE6BE94DF7E11DD409BCE20A0255EC327CB936FFE93643" End Sub Public Sub test_pbeScrypt() Dim lpPwd() As Byte Dim lpSalt() As Byte Dim lpDK() As Byte lpPwd = StrConv("password", vbFromUnicode) lpSalt = StrConv("NaCl", vbFromUnicode) lpDK = pbeScrypt(64, lpPwd, lpSalt, 1024, 8, 16, 0) Debug.Print "DK=" & cnvHexStrFromBytes(lpDK) Debug.Print "OK=FDBABE1C9D3472007856E7190D01E9FE7C6AD7CBC8237830E77376634B3731622EAF30D92E22A3886FF109279D9830DAC727AFB94A83EE6D8360CBDFA2CC0640" ' INPUT: (N=16, r=1, p=1) ' P="", S="" => empty strings => byte arrays of length zero ' Set lpPwd and lpSalt to be empty arrays lpPwd = vbNullString lpSalt = vbNullString lpDK = pbeScrypt(64, lpPwd, lpSalt, 16, 1, 1, 0) Debug.Print "DK=" & cnvHexStrFromBytes(lpDK) Debug.Print "OK=77D6576238657B203B19CA42C18A0497F16B4844E3074AE8DFDFFA3FEDE21442FCD0069DED0948F8326A753A0FC81F17E8D3E0FB2E0D3628CF35E20C38D18906" End Sub Public Sub test_pbeScryptHex() Dim strDerivedKey As String strDerivedKey = pbeScryptHex(64, "pleaseletmein", cnvHexStrFromString("SodiumChloride"), 16384, 8, 1, 0) Debug.Print "Derived key = " & strDerivedKey Debug.Print "OK = " & "7023BDCB3AFD7348461C06CD81FD38EBFDA8FBBA904F8E3EA9B543F6545DA1F2D5432955613F0FCF62D49705242A9AF9E61E85DC0D651E40DFCF017B45575887" End Sub Public Sub test_xofBytes() Dim lpMessage() As Byte Dim lpOut() As Byte lpMessage = cnvBytesFromHexStr("6ae23f058f0f2264a18cd609acc26dd4dbc00f5c3ee9e13ecaea2bb5a2f0bb6b") ' Output 2000 bits lpOut = xofBytes(2000 \ 8, lpMessage, API_XOF_SHAKE256) Debug.Print "OUT=" & cnvHexStrFromBytes(lpOut) Debug.Print "OK =" & "b9b92544fb25cf...f1d35bdff79a" End Sub Public Sub test_cipherStreamHex() Dim strCipher As String Dim strPlain As String strCipher = cipherStreamHex("0000000000000000000000000000000000000000000000000000000000000000", _ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F", _ "0000000000000000", API_SC_SALSA20) Debug.Print "CT=" & strCipher Debug.Print "OK=B580F7671C76E5F7441AF87C146D6B513910DC8B4146EF1B3211CF12AF4A4B49" ' Decrypt by calling again... strPlain = cipherStreamHex(strCipher, _ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F", _ "0000000000000000", API_SC_SALSA20) Debug.Print "PT=" & strPlain strCipher = cipherStreamHex("00000000000000000000", "ef012345", "", API_SC_ARCFOUR) Debug.Print "CT=" & strCipher Debug.Print "OK=d6a141a7ec3c38dfbd61" ' Decrypt by calling again... strPlain = cipherStreamHex(strCipher, "ef012345", "", API_SC_ARCFOUR) Debug.Print "PT=" & strPlain End Sub Public Sub test_cipherStreamBytes() Dim lpCipher() As Byte Dim lpPlain() As Byte Dim lpKey() As Byte Dim lpIV() As Byte Dim strData As String lpKey = cnvBytesFromHexStr("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f") lpIV = cnvBytesFromHexStr("000000000000004a00000000") strData = _ "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it." lpPlain = StrConv(strData, vbFromUnicode) ' Encode as bytes ' Encipher using ChaCha20 with counter=1 lpCipher = cipherStreamBytes(lpPlain, lpKey, lpIV, API_SC_CHACHA20, 1) Debug.Print "CT=" & cnvHexStrFromBytes(lpCipher) Debug.Print "OK=6E2E359A2568F98041BA0728DD0D6981E97E7AEC1D4360C20A27AFCCFD9FAE0BF91B65C5524733AB8F593DABCD62B3571639D624E65152AB8F" _ & "530C359F0861D807CA0DBF500D6A6156A38E088A22B65E52BC514D16CCF806818CE91AB77937365AF90BBF74A35BE6B40B8EEDF2785E42874D" ' Now decipher just by calling again. ... lpPlain = cipherStreamBytes(lpCipher, lpKey, lpIV, API_SC_CHACHA20, 1) Debug.Print "PT=" & StrConv(lpPlain, vbUnicode) ' Decode bytes to string ' Arcfour test vector lpKey = cnvBytesFromHexStr("0123456789abcdef") lpPlain = cnvBytesFromHexStr("0123456789abcdef") lpIV = vbNullString ' Empty (null) array ' Encipher using Arcfour lpCipher = cipherStreamBytes(lpPlain, lpKey, lpIV, API_SC_ARCFOUR) Debug.Print "CT=" & cnvHexStrFromBytes(lpCipher) Debug.Print "OK=75b7878099e0c596" End Sub Public Sub test_cipherStreamFile() Dim strFileIn As String Dim strFileOut As String Dim lpKey() As Byte Dim lpIV() As Byte Dim nRet As Long lpKey = cnvBytesFromHexStr("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f") lpIV = cnvBytesFromHexStr("000000000000004a00000000") ' Encipher plaintext file strFileIn = "sunscreen.txt" strFileOut = "sunscreen-chacha.dat" nRet = cipherStreamFile(strFileOut, strFileIn, lpKey, lpIV, API_SC_CHACHA20, 1) Debug.Print "cipherStreamFile returns " & nRet & " (expecting 0)" End Sub Public Sub test_CipherStreamInit() ' Ref: `draft-strombergson-chacha-test-vectors-02.txt` TC7: Sequence patterns in key and IV. Rounds: 20 Dim lpKey() As Byte Dim lpIV() As Byte Dim lpInput() As Byte Dim lpOutput() As Byte Dim hContext As Long Dim nRet As Long Dim nDataLen As Long Dim strCorrect As String ' Use incremental functions to encrypt a 65-byte input of *zeros* in chunks of 1, 62 and 2 bytes Debug.Print "CHACHA20 (INCREMENTAL):" strCorrect = "9fadf409c00811d00431d67efbd88fba59218d5d6708b1d685863fabbb0e961eea480fd6fb532bfd494b2151015057423ab60a63fe4f55f7a212e2167ccab931fb" lpKey = cnvFromHex("00112233445566778899aabbccddeeffffeeddccbbaa99887766554433221100") lpIV = cnvFromHex("0f1e2d3c4b5a6978") ' Initialize CIPHERSTREAM context hContext = cipherStreamInit(lpKey, lpIV, API_SC_CHACHA20) Debug.Assert hContext <> 0 ' Part 1: block of 1 byte nDataLen = 1 ReDim lpInput(nDataLen - 1) ' Set to zero by default lpOutput = cipherStreamUpdate(hContext, lpInput) Debug.Print cnvHexStrFromBytes(lpOutput) ' Part 2: block of 62 bytes nDataLen = 62 ReDim lpInput(nDataLen - 1) ' Set to zero by default lpOutput = cipherStreamUpdate(hContext, lpInput) Debug.Print cnvHexStrFromBytes(lpOutput) ' Part 3: block of 2 bytes nDataLen = 2 ReDim lpInput(nDataLen - 1) ' Set to zero by default lpOutput = cipherStreamUpdate(hContext, lpInput) Debug.Print cnvHexStrFromBytes(lpOutput) Debug.Print "CORRECT=" Debug.Print strCorrect ' We are done with context nRet = cipherStreamFinal(hContext) Debug.Print "cipherStreamFinal returns " & nRet & " (expecting 0)" End Sub Public Sub test_prfBytes() Dim lpPrf() As Byte Dim lpMsg() As Byte Dim lpKey() As Byte lpKey = cnvBytesFromHexStr("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F") lpMsg = cnvBytesFromHexStr("00010203") ' NB order of parameters (szCustom <=> nOptions). lpPrf = prfBytes(256 \ 8, lpMsg, lpKey, API_KMAC_128, "My Tagged Application") Debug.Print "KMAC=" & cnvHexStrFromBytes(lpPrf) Debug.Print "OK =3B1FBA963CD8B0B59E8C1A6D71888B7143651AF8BA0A7070C0979E2811324AA5" End Sub Public Sub test_hashHexFromBits() Dim strDigest As String Dim lpData() As Byte ' NIST SHAVS CAVS 11.0 "SHA-1 ShortMsg" information lpData = cnvBytesFromHexStr("5180") ' 9-bit bitstring = 0101 0001 1 strDigest = hashHexFromBits(lpData, 9, API_HASH_SHA1) Debug.Print "MD = " & strDigest Debug.Print "OK = 0f582fa68b71ecdf1dcfc4946019cf5a18225bd2" ' SHAVS-SHA3 CAVS 19.0 "SHA3-256 ShortMsg" lpData = cnvBytesFromHexStr("2590A0") strDigest = hashHexFromBits(lpData, 22, API_HASH_SHA3_256) Debug.Print "MD = " & strDigest Debug.Print "OK = d5863d4b1ff41551c92a9e08c52177e32376c9bd100c611c607db840096eb22f" ' ERROR: too many bits for data byte array Debug.Print "Expecting error..." strDigest = hashHexFromBits(lpData, 666, API_HASH_SHA3_256) Debug.Print "hashHexFromBits(too many bits) returns '" & strDigest & "'" Debug.Print errFormatErrorMessage End Sub Public Sub test_hashHexFromString() Dim strMessage As String Dim strDigest As String strDigest = hashHexFromString("abc", API_HASH_SHA1) Debug.Print "SHA-1('abc')=" & strDigest Debug.Print "OK = a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d" strMessage = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" '(length 448 bits). strDigest = hashHexFromString(strMessage, API_HASH_SHA3_256) Debug.Print "msg='" & strMessage & "'" Debug.Print "SHA3-256(msg)=" & strDigest Debug.Print "OK = 41c0dba2a9d62408 49100376a8235e2c 82e1b9998a999e21 db32dd97496d3376" End Sub Public Sub test_padBytesBlock() Dim lpInput() As Byte Dim lpBlock() As Byte Dim lpUnpadded() As Byte lpInput = cnvBytesFromHexStr("FFFFFFFFFF") Debug.Print "Input data = 0x" & cnvHexStrFromBytes(lpInput) lpBlock = padBytesBlock(lpInput, 8, 0) Debug.Print "Padded data = 0x" & cnvHexStrFromBytes(lpBlock) ' Unpad lpUnpadded = padUnpadBytes(lpBlock, 8, 0) Debug.Print "Unpadded data = 0x" & cnvHexStrFromBytes(lpUnpadded) ' Special corner case - output is the empty string lpBlock = cnvBytesFromHexStr("0808080808080808") Debug.Print "Padded data = 0x" & cnvHexStrFromBytes(lpBlock) lpUnpadded = padUnpadBytes(lpBlock, 8, 0) Debug.Print "Unpadded data = 0x" & cnvHexStrFromBytes(lpUnpadded) End Sub Public Sub Test_padHexBlock() Dim strInputHex As String Dim strOutputHex As String strInputHex = "FFFFFF" Debug.Print "Hex input =" & strInputHex strOutputHex = padHexBlock(strInputHex, 8, 0) Debug.Print "Padded data=" & strOutputHex Debug.Print "Unpadded =" & padUnpadHex(strOutputHex, 8, 0) strOutputHex = padHexBlock(strInputHex, 8, API_PAD_1ZERO) Debug.Print "Padded data=" & strOutputHex Debug.Print "Unpadded =" & padUnpadHex(strOutputHex, 8, API_PAD_1ZERO) strOutputHex = padHexBlock(strInputHex, 8, API_PAD_AX923) Debug.Print "Padded data=" & strOutputHex Debug.Print "Unpadded =" & padUnpadHex(strOutputHex, 8, API_PAD_AX923) End Sub Public Sub test_unpadHex() Dim strInputHex As String Dim strOutputHex As String strInputHex = "FFFFFFFFFF030303" Debug.Print "Hex input =" & strInputHex strOutputHex = padUnpadHex(strInputHex, API_BLK_TDEA_BYTES, 0) Debug.Print "Unpadded =" & strOutputHex ' Output is empty string strInputHex = "0808080808080808" Debug.Print "Hex input =" & strInputHex strOutputHex = padUnpadHex(strInputHex, API_BLK_TDEA_BYTES, 0) Debug.Print "Unpadded =" & strOutputHex ' Bad input data results in the same data being returned strInputHex = "FFFFFFFFFFFFFFFF" ' Invalid! Debug.Print "Hex input =" & strInputHex strOutputHex = padUnpadHex(strInputHex, API_BLK_TDEA_BYTES, 0) Debug.Print "Unpadded =" & strOutputHex If Len(strOutputHex) = Len(strInputHex) Then Debug.Print "DECRYPTION ERROR (<= expected)" End If End Sub Public Sub test_apiErrorLookup() Dim i As Long For i = 0 To 9 Debug.Print "apiErrorLookup(" & i & ") => "; apiErrorLookup(i) Next End Sub Public Sub test_rngNonceHex() Dim i As Long For i = 1 To 5 Debug.Print rngNonceHex(32) Next End Sub Public Sub test_cipherEncryptBytes() ' [v6.20] Changed "~Bytes2" to "~Bytes" Dim key() As Byte Dim iv() As Byte Dim pt() As Byte Dim ct() As Byte Dim dt() As Byte Dim algstr As String ' PART 1 algstr = "Aes128/CBC/OneAndZeroes" Debug.Print algstr key = cnvBytesFromHexStr("0123456789ABCDEFF0E1D2C3B4A59687") iv = cnvBytesFromHexStr("FEDCBA9876543210FEDCBA9876543210") ' "Now is the time for all good men to" pt = cnvBytesFromHexStr("4E6F77206973207468652074696D6520666F7220616C6C20676F6F64206D656E20746F") ct = cipherEncryptBytes(pt, key, iv, algstr, 0) Debug.Print "CT=" & cnvHexStrFromBytes(ct) Debug.Print "OK=C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B" dt = cipherDecryptBytes(ct, key, iv, algstr, 0) Debug.Print "dt='" & StrConv(dt, vbUnicode) & "'" ' PART 2 - Use CTR mode and prefix the IV in the output algstr = "Aes128/CTR" Debug.Print algstr & " + PREFIX" ct = cipherEncryptBytes(pt, key, iv, algstr, API_IV_PREFIX) Debug.Print "CT=" & cnvHexStrFromBytes(ct) dt = cipherDecryptBytes(ct, key, iv, algstr, API_IV_PREFIX) Debug.Print "dt='" & StrConv(dt, vbUnicode) & "'" ' PART 3 - Use ECB mode and pass an empty byte array for the IV algstr = "Aes128/ECB" Debug.Print algstr iv = vbNullString ' Set IV as empty array ct = cipherEncryptBytes(pt, key, iv, algstr, 0) Debug.Print "CT=" & cnvHexStrFromBytes(ct) dt = cipherDecryptBytes(ct, key, iv, algstr, 0) Debug.Print "dt='" & StrConv(dt, vbUnicode) & "'" End Sub Public Sub test_cipherEncryptHex() Dim strKeyHex As String Dim strIvHex As String Dim strPlainHex As String Dim strCipherHex As String strKeyHex = "0123456789ABCDEFF0E1D2C3B4A59687" strIvHex = "FEDCBA9876543210FEDCBA9876543210" strPlainHex = "4E6F77206973207468652074696D6520666F7220616C6C20676F6F64206D656E20746F" ' Get encrypted output directly in hex strCipherHex = cipherEncryptHex(strPlainHex, strKeyHex, strIvHex, "Aes128/CBC/OneAndZeroes", 0) Debug.Print strCipherHex ' Same again with hex using ECB mode with default PKCS#5 padding ' To pass a "null" IV in hex, just use the empty string strCipherHex = cipherEncryptHex(strPlainHex, strKeyHex, "", "Aes128/ECB", 0) Debug.Print strCipherHex ' Or vbNullString strCipherHex = cipherEncryptHex(strPlainHex, strKeyHex, vbNullString, "Aes128/ECB", 0) Debug.Print strCipherHex End Sub Public Sub test_cipherDecryptHex() Dim strKeyHex As String Dim strIvHex As String Dim strPlainHex As String Dim strCipherHex As String strKeyHex = "0123456789ABCDEFF0E1D2C3B4A59687" strIvHex = "FEDCBA9876543210FEDCBA9876543210" strCipherHex = "C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B" strPlainHex = cipherDecryptHex(strCipherHex, strKeyHex, strIvHex, "Aes128/CBC/OneAndZeroes") Debug.Print "PT=" & strPlainHex Debug.Print "PT='" & cnvStringFromHexStr(strPlainHex) & "'" ' PART 2 - CT includes IV prefix strCipherHex = "FEDCBA9876543210FEDCBA9876543210C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B" Debug.Print "IV||CT=" & strCipherHex strPlainHex = cipherDecryptHex(strCipherHex, strKeyHex, strIvHex, "Aes128/CBC/OneAndZeroes", API_IV_PREFIX) Debug.Print "PT=" & strPlainHex Debug.Print "PT='" & cnvStringFromHexStr(strPlainHex) & "'" End Sub Public Sub test_cipherFile() Dim lpKey() As Byte Dim lpIV() As Byte Dim nRet As Long ' Encrypt using AES-192 in CBC mode with ANSI-X923 padding, prefixing the IV to the output lpKey = cnvFromHex("fedcba9876543210fedcba98765432101122334455667788") ' Generate a random IV of correct length for AES lpIV = rngNonce(API_BLK_AES_BYTES) nRet = cipherFileEncrypt("hello.aes192.enc.dat", "hello.txt", lpKey, lpIV, "aes192/CBC/ANSIX923", API_IV_PREFIX) Debug.Print "cipherFileEncrypt returns " & nRet & " (expecting 0)" Debug.Assert 0 = nRet Debug.Print "Encrypted file has length " & FileLen("hello.aes192.enc.dat") ' Now decrypt nRet = cipherFileDecrypt("hello.aes192.chk.txt", "hello.aes192.enc.dat", lpKey, lpIV, "aes192/CBC/ANSIX923", API_IV_PREFIX) Debug.Print "cipherFileDecrypt returns " & nRet & " (expecting 0)" Debug.Assert 0 = nRet Debug.Print "Encrypted file has length " & FileLen("hello.aes192.chk.txt") ' Repeat using ECB mode and default PKCS#5 padding lpIV = vbNullString ' Set IV to empty array nRet = cipherFileEncrypt("hello.aes192.enc.ecb.dat", "hello.txt", lpKey, lpIV, "aes192/ecb") Debug.Print "cipherFileEncrypt returns " & nRet & " (expecting 0)" Debug.Assert 0 = nRet Debug.Print "Encrypted file has length " & FileLen("hello.aes192.enc.ecb.dat") ' Now decrypt nRet = cipherFileDecrypt("hello.aes192.chk1.txt", "hello.aes192.enc.ecb.dat", lpKey, lpIV, "aes192/ecb") Debug.Print "cipherFileDecrypt returns " & nRet & " (expecting 0)" Debug.Assert 0 = nRet Debug.Print "Encrypted file has length " & FileLen("hello.aes192.chk1.txt") End Sub Public Sub test_cipherKeyWrap() Dim lpKeyData() As Byte Dim lpKek() As Byte Dim lpWK() As Byte Dim lpKD() As Byte ' Input for AES128-Wrap lpKeyData = cnvBytesFromHexStr("8cbedec4 8d063e1b a46be8e3 69a9c398 d8e30ee5 42bc347c 4f30e928 ddd7db49") lpKek = cnvBytesFromHexStr("9e84ee99 e6a84b50 c76cd414 a2d2ec05 8af41bfe 4bf3715b f894c8da 1cd445f6") ' Wrap the content encyption key lpWK = cipherKeyWrap(lpKeyData, lpKek, API_BC_AES256) Debug.Print "WK=" & cnvHexStrFromBytes(lpWK) Debug.Print "OK=EAFB901F82B98D37F17497063DE3E5EC7246AB57200AE73EDDDDF24AA403DAFA0C5AE151D1746FA4" ' Unwrap lpKD = cipherKeyUnwrap(lpWK, lpKek, API_BC_AES256) Debug.Print "KD=" & cnvHexStrFromBytes(lpKD) Debug.Print "OK=" & cnvHexStrFromBytes(lpKeyData) End Sub Public Sub test_aeadEncryptWithTag() Dim lpKey() As Byte Dim lpNonce() As Byte Dim lpAAD() As Byte Dim lpPT() As Byte Dim lpCT() As Byte Dim lpDT() As Byte ' Ref: IEEE P802.1 MACsec 2.4.1 54-byte Packet Encryption Using GCM-AES-128: ' Set byte arrays from hex strings lpKey = cnvBytesFromHexStr("071b113b 0ca743fe cccf3d05 1f737382") lpNonce = cnvBytesFromHexStr("f0761e8d cd3d0001 76d457ed") lpAAD = cnvBytesFromHexStr("e20106d7 cd0df076 1e8dcd3d 88e54c2a 76d457ed") lpPT = cnvBytesFromHexStr("08000f10 11121314 15161718 191a1b1c 1d1e1f20 21222324 25262728 292a2b2c 2d2e2f30 31323334 0004") lpCT = aeadEncryptWithTag(lpPT, lpKey, lpNonce, lpAAD, API_AEAD_AES_128_GCM Or API_IV_PREFIX) Debug.Print "C: " & cnvHexStrFromBytes(lpCT) Debug.Print "OK f0761e8dcd3d000176d457ed13b4c72b389dc5018e72a171dd85a5d3752274d3a019fbcaed09a425cd9b2e1c9b72eee7c9de7d52b3f3d6a5284f4a6d3fe22a5d6c2b960494c3" lpDT = aeadDecryptWithTag(lpCT, lpKey, lpNonce, lpAAD, API_AEAD_AES_128_GCM Or API_IV_PREFIX) Debug.Print "P: " & cnvHexStrFromBytes(lpDT) Debug.Print "OK 08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F30313233340004" End Sub Public Sub test_zlibDeflate() Dim strPlain As String Dim lpToCompress() As Byte Dim lpCompressed() As Byte Dim lpUncompressed() As Byte strPlain = "hello, hello, hello. This is a 'hello world' message " & _ "for the world, repeat, for the world." lpToCompress = StrConv(strPlain, vbFromUnicode) lpCompressed = zlibDeflate(lpToCompress) Debug.Print "OK= " & "789CCB48CDC9C9D751C840A2F4144232328B15802851411D2CA2509E5F9493A2AE909B5A5C9C989EAA90965FA45092910A11D651284A2D484D2CD14115D6030086D11F4E" Debug.Print "COMPRESSED=" & cnvHexStrFromBytes(lpCompressed) lpUncompressed = zlibInflate(lpCompressed) Debug.Print "'" & StrConv(lpUncompressed, vbUnicode); "'" End Sub Public Sub test_hashHexFromBytes() Dim lpMessage() As Byte lpMessage = StrConv("abc", vbFromUnicode) Debug.Print "lpMessage=" & cnvHexStrFromBytes(lpMessage) Debug.Print "OK:" & vbCrLf & "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" Debug.Print hashHexFromBytes(lpMessage, API_HASH_SHA256) Debug.Print hashHexFromHex("616263", API_HASH_SHA256) Debug.Print hashHexFromFile("abc.txt", API_HASH_SHA256) Debug.Print cnvHexStrFromBytes(hashBytes(lpMessage, API_HASH_SHA256)) Debug.Print cnvHexStrFromBytes(hashFile("abc.txt", API_HASH_SHA256)) End Sub Public Sub test_macHexFromBytes() Dim lpMessage() As Byte Dim lpKey() As Byte lpMessage = StrConv("what do ya want for nothing?", vbFromUnicode) lpKey = StrConv("Jefe", vbFromUnicode) Debug.Print "OK:" & vbCrLf & "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843" Debug.Print macHexFromBytes(lpMessage, lpKey, API_HMAC_SHA256) Debug.Print macHexFromHex(cnvHexStrFromBytes(lpMessage), cnvHexStrFromBytes(lpKey), API_HMAC_SHA256) Debug.Print cnvHexStrFromBytes(macBytes(lpMessage, lpKey, API_HMAC_SHA256)) End Sub Public Sub test_Hash_Objects() Dim hContext As Long Dim lpDigest() As Byte ' Initialize context to use SHA-3-256 (NB HASH_ func) hContext = HASH_Init(API_HASH_SHA3_256) Debug.Print "HASH_Init returns 0x" & Hex(hContext) ' Check for an invalid handle If hContext = 0 Then MsgBox "Failed to set context" Exit Sub End If ' Add "abc" in parts Call hashAddBytes(hContext, cnvBytesFromHexStr("61")) ' ASCII "a" Call hashAddString(hContext, "") ' Empty string => No effect Call hashAddBytes(hContext, cnvBytesFromHexStr("")) ' Empty byte array => No effect Call hashAddString(hContext, "bc") ' Add a string directly ' Get final digest value lpDigest = hashFinal(hContext) Debug.Print "DIG=" & cnvHexStrFromBytes(lpDigest) Debug.Print "OK= " & "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532" End Sub Public Sub test_Hash_1Mxa() ' Compute the SHA-3-224 digest of one million repetitions of the character "a" Dim hContext As Long Dim lpDigest() As Byte Dim nRet As Long Dim i As Long Dim sA1000 As String ' Initialize context hContext = HASH_Init(API_HASH_SHA3_224) If hContext = 0 Then MsgBox "Failed to set context" Exit Sub End If ' Create a string of 1000 'a's sA1000 = String(1000, "a") ' Add 1000 times => one million repetitions of "a" For i = 1 To 1000 nRet = hashAddString(hContext, sA1000) Next ' Get final digest value lpDigest = hashFinal(hContext) Debug.Print "DIG=" & cnvHexStrFromBytes(lpDigest) Debug.Print "OK= " & "d69335b93325192e516a912e6d19a15cb51c6ed5c15243e7a7fd653c" End Sub Public Sub test_MAC_Init() Dim hContext As Long Dim r As Long Dim lpKey() As Byte lpKey = cnvBytesFromHexStr("0102030405060708090a0b0c0d0e0f10111213141516171819") hContext = MAC_Init(lpKey(0), cnvBytesLen(lpKey), API_HMAC_SHA256) Debug.Print "MAC_Init returns 0x" & Hex(hContext) & " (expected nonzero)" Debug.Print "MAC_CodeLength = " & MAC_CodeLength(hContext) r = MAC_Reset(hContext) Debug.Print "After reset, MAC_CodeLength returns " & MAC_CodeLength(hContext) Debug.Print "apiErrorCode=" & apiErrorCode() & ": " & apiErrorLookup(apiErrorCode()) hContext = MAC_Init(lpKey(0), cnvBytesLen(lpKey), &HFF) ' Invalid alg code Debug.Print "MAC_Init(INVALID) returns 0x" & Hex(hContext) Debug.Print "apiErrorCode=" & apiErrorCode() & ": " & apiErrorLookup(apiErrorCode()) ' Wrapper fn hContext = macInit(lpKey, API_HMAC_SHA256) Debug.Print "macInit returns 0x" & Hex(hContext) & " (expected nonzero)" r = MAC_Reset(hContext) End Sub Public Sub test_MAC_AddBytes() ' Test case 4 from RFC 2202 and RFC 4231 ' key = 0x0102030405060708090a0b0c0d0e0f10111213141516171819 ' key_len 25 ' data = 0xcd repeated 50 times ' data_len = 50 Dim hContext As Long Dim r As Long Dim lpKey() As Byte Dim lpMsg10() As Byte Dim lpDigest() As Byte Dim i As Long lpKey = cnvBytesFromHexStr("0102030405060708090a0b0c0d0e0f10111213141516171819") lpMsg10 = cnvBytesFromHexStr("cdcdcdcdcdcdcdcdcdcd") ' 0xcd repeated 10 times ' HMAC-SHA-1 hContext = macInit(lpKey, API_HMAC_SHA1) Debug.Print "macInit returns 0x" & Hex(hContext) & " (expected nonzero)" For i = 1 To 5 r = macAddBytes(hContext, lpMsg10) Debug.Print "macAddBytes returns " & r Next lpDigest = macFinal(hContext) Debug.Print "MAC=" & cnvHexStrFromBytes(lpDigest) Debug.Print "OK= " & "4c9007f4026250c6bc8414f9bf50c86c2d7235da" ' HMAC-SHA-256 hContext = macInit(lpKey, API_HMAC_SHA256) Debug.Print "macInit returns 0x" & Hex(hContext) & " (expected nonzero)" For i = 1 To 5 r = macAddBytes(hContext, lpMsg10) 'Debug.Print "macAddBytes returns " & r Next lpDigest = macFinal(hContext) Debug.Print "MAC=" & cnvHexStrFromBytes(lpDigest) Debug.Print "OK= " & "82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b" Dim strData As String Dim strKey As String ' Test case 2 from RFC 2202 and RFC 4231 strData = "what do ya want for nothing?" strKey = "Jefe" lpKey = StrConv(strKey, vbFromUnicode) hContext = macInit(lpKey, API_HMAC_SHA512) ' Split input into parts r = macAddString(hContext, "what do ya") r = macAddString(hContext, " want for ") r = macAddString(hContext, "nothing?") lpDigest = macFinal(hContext) Debug.Print "MAC=" & cnvHexStrFromBytes(lpDigest) Debug.Print "OK =" _ & "164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea250554" _ & "9758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737" _ End Sub Public Sub test_cipherInit_error() ' Using the "raw" functions Dim key() As Byte Dim iv() As Byte Dim hContext As Long key = cnvFromHex("0123456789ABCDEFF0E1D2C3B4A59687") iv = cnvFromHex("FEDCBA9876543210FEDCBA9876543210") ' Test errors for cipherInit hContext = cipherInit(ENCRYPT, "BADALG", key, iv) Debug.Print "cipherInit returns 0x" & Hex(hContext) & " (0 => error)" Debug.Assert hContext = 0 Debug.Print "ErrorCode=" & apiErrorCode() & ": " & apiErrorLookup(apiErrorCode()) hContext = cipherInit(ENCRYPT, "", key, iv, &HFFFF) Debug.Print "cipherInit returns 0x" & Hex(hContext) & " (0 => error)" Debug.Assert hContext = 0 Debug.Print "ErrorCode=" & apiErrorCode() & ": " & apiErrorLookup(apiErrorCode()) hContext = cipherInit(ENCRYPT, "BADALG", cnvBytesFromHexStr("0123456789ABCDEFF0E1D2C3B4A59687"), cnvBytesFromHexStr("")) Debug.Print "cipherInit returns 0x" & Hex(hContext) & " (0 => error)" Debug.Assert hContext = 0 Debug.Print "ErrorCode=" & apiErrorCode() & ": " & apiErrorLookup(apiErrorCode()) End Sub Public Sub test_cipherInit_objects() ' Using the wrapper functions Dim key() As Byte Dim iv() As Byte Dim pt() As Byte Dim ct() As Byte Dim algstr As String Dim hContext As Long Dim nRet As Long key = cnvBytesFromHexStr("0123456789ABCDEFF0E1D2C3B4A59687") iv = cnvBytesFromHexStr("FEDCBA9876543210FEDCBA9876543210") Debug.Print "KY=" & cnvHexStrFromBytes(key) Debug.Print "IV=" & cnvHexStrFromBytes(iv) ' TEST 1 - CBC mode algstr = "Aes128/CBC" Debug.Print algstr ' Initialize context for repeated chunks hContext = cipherInit(ENCRYPT, algstr, key, iv) Debug.Print "cipherInit returns 0x" & Hex(hContext) & " (expected NON-zero)" Debug.Assert hContext <> 0 ' Pass data in chunks of 16 bytes (or multiples of) ' Part 1... pt = StrConv("Now is the time for all good men", vbFromUnicode) Debug.Print "PT=" & cnvHexStrFromBytes(pt) ct = cipherUpdate(hContext, pt) Debug.Print "CT=" & cnvHexStrFromBytes(ct) ' Part 2... pt = StrConv(" to come to the aid of the party", vbFromUnicode) Debug.Print "PT=" & cnvHexStrFromBytes(pt) ct = cipherUpdate(hContext, pt) Debug.Print "CT=" & cnvHexStrFromBytes(ct) ' We are done nRet = CIPHER_Final(hContext) Debug.Print "CIPHER_Final returns " & nRet & " (expected 0)" ' TEST 2 - ECB mode algstr = "Aes128/ecb" Debug.Print algstr Dim dummy() As Byte ' Initialize context for repeated chunks hContext = cipherInit(ENCRYPT, algstr, key, dummy) Debug.Print "cipherInit returns 0x" & Hex(hContext) & " (expected NON-zero)" Debug.Assert hContext <> 0 ' Pass data in chunks of 16 bytes (or multiples of) ' Part 1... pt = StrConv("Now is the time for all good men", vbFromUnicode) Debug.Print "PT=" & cnvHexStrFromBytes(pt) ct = cipherUpdate(hContext, pt) Debug.Print "CT=" & cnvHexStrFromBytes(ct) ' Part 2... pt = StrConv(" to come to the aid of the party", vbFromUnicode) Debug.Print "PT=" & cnvHexStrFromBytes(pt) ct = cipherUpdate(hContext, pt) Debug.Print "CT=" & cnvHexStrFromBytes(ct) ' We are done nRet = CIPHER_Final(hContext) Debug.Assert nRet = 0 ' TEST 3 - CTR mode algstr = "Aes128/ctr" Debug.Print algstr ' Initialize context for repeated chunks hContext = cipherInit(ENCRYPT, algstr, key, iv) Debug.Print "cipherInit returns 0x" & Hex(hContext) & " (expected NON-zero)" Debug.Assert hContext <> 0 ' Pass data in chunks of 16 bytes (or multiples of) ' Part 1... pt = StrConv("Now is the time for all good men", vbFromUnicode) Debug.Print "PT=" & cnvHexStrFromBytes(pt) ct = cipherUpdate(hContext, pt) Debug.Print "CT=" & cnvHexStrFromBytes(ct) ' Part 2... ' In CTR mode (and OFB and CFB) the last block need not be a multiple pt = StrConv(" to come to the aid of", vbFromUnicode) Debug.Print "PT=" & cnvHexStrFromBytes(pt) ct = cipherUpdate(hContext, pt) Debug.Print "CT=" & cnvHexStrFromBytes(ct) ' We are done nRet = CIPHER_Final(hContext) Debug.Assert nRet = 0 End Sub Public Sub test_cipherInitHex_objects() ' Using the wrapper functions Dim keyhex As String Dim ivhex As String Dim pthex As String Dim cthex As String Dim algstr As String Dim hContext As Long Dim nRet As Long keyhex = "0123456789ABCDEFF0E1D2C3B4A59687" ivhex = "FEDCBA9876543210FEDCBA9876543210" Debug.Print "KY=" & keyhex Debug.Print "IV=" & ivhex ' TEST 1 - CBC mode algstr = "Aes128/CBC" Debug.Print algstr ' Initialize context for repeated chunks hContext = cipherInitHex(ENCRYPT, algstr, keyhex, ivhex, 0) Debug.Print "cipherInitHex returns 0x" & Hex(hContext) & " (expected NON-zero)" Debug.Assert hContext <> 0 ' Pass data in chunks of 16 bytes (or multiples of) ' Part 1... pthex = cnvHexStrFromString("Now is the time for all good men") Debug.Print "PT=" & pthex cthex = cipherUpdateHex(hContext, pthex) Debug.Print "CT=" & cthex ' Part 2... pthex = cnvHexStrFromString(" to come to the aid of the party") Debug.Print "PT=" & pthex cthex = cipherUpdateHex(hContext, pthex) Debug.Print "CT=" & cthex ' We are done nRet = cipherFinal(hContext) Debug.Print "cipherFinal returns " & nRet & " (expected 0)" ' TEST 4 - Decrypt in CTR mode algstr = "Aes128/ctr" Debug.Print algstr Debug.Print "DECRYPTING..." ' Initialize context for repeated chunks hContext = cipherInitHex(DECRYPT, algstr, keyhex, ivhex, 0) Debug.Assert hContext <> 0 ' Pass data in chunks of 16 bytes (or multiples of) ' Part 1... cthex = "3FAC68CBAE6D774151306E9DB16CE0191C51E91959DA4F082B7CE3498C2D20D7" Debug.Print "CT=" & cthex ' NB switched pt <=> ct pthex = cipherUpdateHex(hContext, cthex) Debug.Print "PT=" & pthex Debug.Print "'" & cnvStringFromHexStr(pthex) & "'" ' Part 2... cthex = "8437EC92088FE4C19FB49BDF2BADF7C7FD6FB9A7D52A" Debug.Print "CT=" & cthex pthex = cipherUpdateHex(hContext, cthex) Debug.Print "PT=" & pthex Debug.Print "'" & cnvStringFromHexStr(pthex) & "'" ' We are done nRet = cipherFinal(hContext) Debug.Assert nRet = 0 End Sub Public Sub test_comprCompress() Dim strPlain As String Dim lpToCompress() As Byte Dim lpCompressed() As Byte Dim lpUncompressed() As Byte strPlain = "hello, hello, hello. This is a 'hello world' message " & _ "for the world, repeat, for the world." lpToCompress = StrConv(strPlain, vbFromUnicode) ' Using default zlib algorithm lpCompressed = comprCompress(lpToCompress) Debug.Print "COMPRESSED(ZLIB)=" & cnvHexStrFromBytes(lpCompressed) ' 789CCB48CDC9C9D751C840A2F4144232328B15802851411D2CA2509E5F9493A2AE909B5A5C9C989EAA90965FA45092910A11D651284A2D484D2CD14115D6030086D11F4E lpUncompressed = comprUncompress(lpCompressed) Debug.Print "'" & StrConv(lpUncompressed, vbUnicode); "'" ' Using Zstandard algorithm lpCompressed = comprCompress(lpToCompress, API_COMPR_ZSTD) Debug.Print "COMPRESSED(ZSTD)=" & cnvHexStrFromBytes(lpCompressed) ' 28B52FFD205A1D0200540368656C6C6F2C202E20546869732069732061202720776F726C6427206D65737361676520666F72207468652C207265706561742C2E0400409E3AB1E1D97E71C508 lpUncompressed = comprUncompress(lpCompressed, API_COMPR_ZSTD) Debug.Print "'" & StrConv(lpUncompressed, vbUnicode); "'" End Sub Public Sub test_crc() Dim n As Long Dim ab() As Byte n = crcString("123456789") Debug.Print "crcString returns " & Hex(n) ' CBF43926 ab = StrConv("123456789", vbFromUnicode) n = crcBytes(ab) Debug.Print "crcBytes returns " & Hex(n) ' CBF43926 n = crcFile("hello.txt") Debug.Print "crcFile('hello.txt') returns " & Hex(n) ' 38E6C41A End Sub Public Sub test_blfBytesBlock() Dim lpPT() As Byte Dim lpKey() As Byte Dim lpIV() As Byte Dim lpCT() As Byte Dim lpDT() As Byte lpKey = cnvBytesFromHexStr("0123456789ABCDEFF0E1D2C3B4A59687") lpIV = cnvBytesFromHexStr("FEDCBA9876543210") lpPT = cnvBytesFromHexStr("37363534333231204E6F77206973207468652074696D6520666F722000000000") Debug.Print "PT=" & cnvHexStrFromBytes(lpPT) lpCT = blfBytesBlock(ENCRYPT, lpPT, lpKey, lpIV, "CBC") Debug.Print "CT=" & cnvHexStrFromBytes(lpCT) ' 6B77B4D63006DEE605B156E27403979358DEB9E7154616D959F1652BD5FF92CC lpDT = blfBytesBlock(DECRYPT, lpCT, lpKey, lpIV, "CBC") Debug.Print "DT=" & cnvHexStrFromBytes(lpDT) ' 37363534333231204E6F77206973207468652074696D6520666F722000000000 End Sub Public Sub test_aeadInit() ' RFC7539 ChaCha20_Poly1305 Sunscreen test - INCREMENTAL MODE: Dim lpKey() As Byte Dim lpNonce() As Byte Dim lpAAD() As Byte Dim lpPT() As Byte Dim lpCT() As Byte Dim lpTag() As Byte Dim lpChunk() As Byte Dim strPT As String Dim strCtHex As String Dim nRet As Long Dim strCTOK As String Dim strTagOK As String Dim hContext As Long Dim nOffset As Long Dim nLen As Long Dim nLeft As Long Dim strSubStr As String Debug.Print "RFC7539 ChaCha20_Poly1305 Sunscreen test:" ' Set byte arrays from hex strings lpKey = cnvBytesFromHexStr("808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F") lpNonce = cnvBytesFromHexStr("070000004041424344454647") lpAAD = cnvBytesFromHexStr("50515253C0C1C2C3C4C5C6C7") strPT = "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it." strTagOK = "1ae10b594f09e26a7e902ecbd0600691" ' Do authenticated encryption using AEAD_CHACHA20_POLY1305 ' 1.1 Initialize with the key and AEAD algorithm hContext = aeadInitKey(lpKey, API_AEAD_CHACHA20_POLY1305) Debug.Print "aeadInitKey returns 0x" & Hex(hContext) & " (expecting non-zero)" Debug.Assert hContext <> 0 ' 1.2 Set the nonce nRet = aeadSetNonce(hContext, lpNonce) ' 1.3 Add the AAD (simulate adding in two parts) nRet = aeadAddAAD(hContext, cnvFromHex("50515253")) nRet = aeadAddAAD(hContext, cnvFromHex("C0C1C2C3C4C5C6C7")) ' 1.4 Start Encrypting nRet = aeadStartEncrypt(hContext) ' 1.5 Update plaintext -> ciphertext (simulate adding in chunks) Debug.Print "Adding plaintext in chunks" ' We'll store the ciphertext chunks in a hex string because it's simpler strCtHex = "" nLen = 17 nLeft = Len(strPT) nOffset = 0 While nLeft > 0 If nLeft < nLen Then nLen = nLeft strSubStr = Mid(strPT, nOffset + 1, nLen) Debug.Print "P: '" & strSubStr & "'" Debug.Print "P: " & cnvHexStrFromString(strSubStr) ' Update another chunk of plaintext lpChunk = aeadUpdate(hContext, StrConv(strSubStr, vbFromUnicode)) Debug.Print "C: " & cnvToHex(lpChunk) strCtHex = strCtHex & cnvToHex(lpChunk) nOffset = nOffset + nLen nLeft = nLeft - nLen Wend ' 1.6 Finish encrypting and output Tag lpTag = aeadFinishEncrypt(hContext) Debug.Print "T: " & cnvHexStrFromBytes(lpTag) Debug.Print "OK:" & strTagOK ' DECRYPTING... Debug.Print "DECRYPTING..." ' 2.1 Use key we initialized with in step 1.1 ' 2.2 Set Nonce nRet = aeadSetNonce(hContext, lpNonce) ' 2.3 Add AAD (this time in one go) nRet = aeadAddAAD(hContext, lpAAD) ' 2.4 Start decrypting using Tag we just made nRet = aeadStartDecrypt(hContext, lpTag) ' 2.5. Update with ciphertext -> plaintext (simulate adding in chunks) lpCT = cnvFromHex(strCtHex) Debug.Print "Adding ciphertext in chunks" nLen = 13 nLeft = cnvBytesLen(lpCT) nOffset = 0 While nLeft > 0 If nLeft < nLen Then nLen = nLeft End If ' Update chunk of ciphertext in situ Debug.Print "C: " & cnvHexFromBytesMid(lpCT, nOffset, nLen) lpChunk = aeadUpdate(hContext, cnvBytesMid(lpCT, nOffset, nLen)) Debug.Print "P: " & cnvToHex(lpChunk) Debug.Print "P: " & StrConv(lpChunk, vbUnicode) nOffset = nOffset + nLen nLeft = nLeft - nLen Wend ' Note: treat plaintext output as suspect until authenticated by FinishDecrypt ' 2.6 Finish decrypting and check OK|FAIL nRet = aeadFinishDecrypt(hContext) Debug.Print "aeadFinishDecrypt returns " & nRet & " (0 => OK)" ' 3. We are done with the key so destroy it nRet = aeadDestroy(hContext) Debug.Print "aeadDestroy returns " & nRet & " (expecting 0)" End Sub Public Sub test_wipeBytes() Dim lpData() As Byte lpData = cnvFromHex("DEADBEEF") Debug.Print "Before wipeBytes='" & cnvToHex(lpData) & "'" Call wipeBytes(lpData) Debug.Print "After wipeBytes='" & cnvToHex(lpData) & "'" ' Zeroize a byte array Dim strData As String strData = "Secret information" Debug.Print "Before wipeString='" & strData & "'" ' Zeroise a string Call wipeString(strData) ' This just sets each character in the string to a zero value Debug.Print cnvHexStrFromString(strData) ' To clear the string completely, do the following strData = wipeString(strData) Debug.Print "After wipeString='" & strData & "'" End Sub Public Sub test_wipeFile() Dim strFileName As String Dim nRet As Long strFileName = "FileToBeDeleted.txt" WriteFileFromString strFileName, "Secret information" Debug.Print "Before wipeFile='" & ReadFileIntoString(strFileName) & "'" nRet = wipeFile(strFileName) Debug.Print "wipeFile returns " & nRet & " (expecting 0)" Debug.Assert 0 = nRet Debug.Print "After wipeFile='" & ReadFileIntoString(strFileName) & "'" End Sub Public Sub test_ErrorMessages() Dim nRet As Long Dim strDigest As String Debug.Print "EXPECTING ERRORS..." ' Invalid context handle, error code returned nRet = cipherFinal(666) Debug.Print errFormatErrorMessage(nRet) ' Missing file, empty string returned strDigest = hashFile("missing.file", API_HASH_SHA1) Debug.Print errFormatErrorMessage() ' Unsupported algorithm nRet = hashInit(API_HASH_MD2) ' Plus a user message Debug.Print errFormatErrorMessage(nRet, "OMG! user-supplied message") End Sub Public Sub test_apiModuleName() Debug.Print "ModuleName= " & apiModuleName() End Sub Public Sub test_apiCompileTime() Debug.Print "CompileTime=" & apiCompileTime() Debug.Print "Licence=" & apiLicenceType() End Sub ' ----------------- ' FILE UTILITIES ' ----------------- Private Function ReadFileIntoString(sFilePath As String) As String ' Reads file (if it exists) into a string. Dim strIn As String Dim hFile As Integer ' Check if file exists If Len(Dir(sFilePath)) = 0 Then Exit Function End If hFile = FreeFile Open sFilePath For Binary Access Read As #hFile strIn = Input(LOF(hFile), #hFile) Close #hFile ReadFileIntoString = strIn End Function Private Function WriteFileFromString(sFilePath As String, strIn As String) As Boolean ' Creates a file from a string. Clobbers any existing file. On Error GoTo OnError Dim hFile As Integer If Len(Dir(sFilePath)) > 0 Then Kill sFilePath End If hFile = FreeFile Open sFilePath For Binary Access Write As #hFile Put #hFile, , strIn Close #hFile WriteFileFromString = True Done: Exit Function OnError: Resume Done End Function