Creates an input block suitably padded for encryption by a block cipher in ECB or CBC mode.
Public Declare Function PAD_BytesBlock Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutputLen As Long, ByRef lpInput As Byte, ByVal nInputLen As Long, ByVal nBlockLen As Long, ByVal nOptions As Long) As Long
nRet = PAD_BytesBlock(lpOutput(0), nOutputLen, lpInput(0), nInputLen, nBlockLen, nOptions) ' Note the "(0)" after the byte array parameters
long __stdcall PAD_BytesBlock(unsigned char *lpOutput, long nOutBytes, const unsigned char *lpInput, long nInputLen, long nBlkLen, long nOptions);
If successful, the return value is the number of bytes in the output; otherwise it returns a negative error code.
Public Function padBytesBlock
(lpInput() As Byte, nBlkLen As Long, Optional nOptions As Long = 0) As Byte()
static bvec_t dipki::Cipher::Pad (const bvec_t &input, Alg alg, Padding pad=Padding::Pkcs5)
static Cipher.pad(data, alg, pad=Pad.PKCS5)
The output will be padded according to the convention specified.
If nOutBytes is set to zero or lpOutput set to 0 (or NULL
in C or ByVal 0&
in VBA)
then the required number of bytes will be returned. The output is always longer than the input.
Only block lengths of 8 or 16 bytes are supported.
Note the test when unpadding to cope with a zero-length byte array.
Dim abInput() As Byte Dim abOutput() As Byte Dim nOutputLen As Long Dim nInputLen As Long Dim nBlockLen As Long Dim i As Long ' Prepare test input 5 bytes long nInputLen = 5 ReDim abInput(nInputLen - 1) For i = 0 To nInputLen - 1 abInput(i) = &HFF Next Debug.Print "Input data=0x" & cnvHexStrFromBytes(abInput) ' Find out the required length nBlockLen = 8 nOutputLen = PAD_BytesBlock(vbNull, 0, abInput(0), nInputLen, nBlockLen, 0) Debug.Print "Required length is " & nOutputLen & " bytes" ' Check for error If (nOutputLen <= 0) Then Exit Function ' Pre-dimension output ReDim abOutput(nOutputLen - 1) nOutputLen = PAD_BytesBlock(abOutput(0), nOutputLen, abInput(0), nInputLen, nBlockLen, 0) Debug.Print "Padded data=0x" & cnvHexStrFromBytes(abOutput) ' Now set input as padded output and remove padding abInput = abOutput nInputLen = nOutputLen ' Remove padding... ' No need to query for length because we know the output will be shorter than input ' so make sure output is as long as the input nOutputLen = nInputLen ReDim abOutput(nOutputLen - 1) nOutputLen = PAD_UnpadBytes(abOutput(0), nOutputLen, abInput(0), nInputLen, nBlockLen, 0) Debug.Print "Unpadded length is " & nOutputLen & " bytes" ' Check for error If (nOutputLen < 0) Then Exit Function ' Truncate the output to the correct length If nOutputLen > 0 Then ReDim Preserve abOutput(nOutputLen - 1) Else ' Catch zero-length output abOutput = vbNullString End If Debug.Print "Unpadded data=0x" & cnvHexStrFromBytes(abOutput)
This should result in output as follows:
Input data=0xFFFFFFFFFF Required length is 8 bytes Padded data=0xFFFFFFFFFF030303 Unpadded length is 5 bytes Unpadded data=0xFFFFFFFFFF
Dim lpInput() As Byte Dim lpBlock() As Byte Dim lpUnpadded() As Byte lpInput = cnvBytesFromHexStr("FDFDFDFDFD") 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)
PAD_UnpadBytes
PAD_HexBlock
PAD_UnpadHex