Wrap a content-encryption key with a key-encryption key.
Public Declare Function CIPHER_KeyWrap Lib "diCrPKI.dll"
(ByRef lpOutput As Byte, ByVal nOutBytes As Long,
ByRef lpData As Byte, ByVal nDataLen As Long,
ByRef lpKek As Byte, ByVal nKekLen As Long, ByVal nOptions As Long) As Long
nRet = CIPHER_KeyWrap(lpOutput(0), nOutBytes, lpData(0), nDataLen,
lpKek(0), nKekLen, nOptions)
long __stdcall CIPHER_KeyWrap(unsigned char *lpOutput, long nOutBytes, const unsigned char *lpData, long nDataLen, const unsigned char *lpKek, long nKekLen, long nOptions);
AES128-Wrap
AES128-Wrap
AES128-Wrap
cms3DESWrap
If successful, the return value is the number of bytes in the output; otherwise it returns a negative error code.
Public Function cipherKeyWrap
(lpData() As Byte, lpKEK() As Byte, nOptions As Long) As Byte()
static bvec_t dipki::Cipher::KeyWrap (const bvec_t &data, const bvec_t &kek, Alg alg)
static Cipher.key_wrap(data, kek, alg)
This wraps (encrypts) key material using a key encryption key (KEK) and uses either the AES Key Wrap Algorithm from [RFC3394] or the Triple-DES Key Wrap algorithm from [RFC3217]. There is no default algorithm. The algorithm must be specified in the nOptions parameter. The input data to be wrapped must be a valid length for the underlying data encapsulation mechanism; specifically, at least 16 bytes and a multiple of 8 bytes for AES, or exactly 24 bytes for Triple DES. To find the required length for the output wrapped key, pass zero as the nOutBytes parameter (Hint: an AES-wrapped key is exactly 8 bytes longer than the input; a triple-DES-wrapped key is 16 bytes longer). No parity bit checks or changes are made for a Triple-DES key.
Changed in [v20.5]: Added the explicit key wrap options PKI_KWRAP_* which are different from the old PKI_BC_* options. The old PKI_BC_* options are still accepted for backwards compatibility.
Dim abWK() As Byte Dim abKeyData() As Byte Dim abKek() As Byte Dim nWkLen As Long Dim nKdLen As Long Dim nKekLen As Long abKeyData = cnvBytesFromHexStr("00112233 44556677 8899aabb ccddeeff") abKek = cnvBytesFromHexStr("c17a44e8 e28d7d64 81d1ddd5 0a3b8914") nKdLen = UBound(abKeyData) + 1 nKekLen = UBound(abKek) + 1 nWkLen = CIPHER_KeyWrap(0, 0, abKeyData(0), nKdLen, abKek(0), nKekLen, PKI_BC_AES128) If nWkLen <= 0 Then Debug.Print " returns " & nWkLen & ": " & pkiErrorLookup(nWkLen) Exit Sub End If ReDim abWK(nWkLen - 1) nWkLen = CIPHER_KeyWrap(abWK(0), nWkLen, abKeyData(0), nKdLen, abKek(0), nKekLen, PKI_BC_AES128) Debug.Print "WK=" & cnvHexStrFromBytes(abWK) abKeyData = cnvBytesFromHexStr("8cbedec4 8d063e1b a46be8e3 69a9c398 d8e30ee5 42bc347c 4f30e928 ddd7db49") abKek = cnvBytesFromHexStr("9e84ee99 e6a84b50 c76cd414 a2d2ec05 8af41bfe 4bf3715b f894c8da 1cd445f6") nKdLen = UBound(abKeyData) + 1 nKekLen = UBound(abKek) + 1 nWkLen = CIPHER_KeyWrap(0, 0, abKeyData(0), nKdLen, abKek(0), nKekLen, PKI_BC_AES256) If nWkLen <= 0 Then Debug.Print " returns " & nWkLen & ": " & pkiErrorLookup(nWkLen) Exit Sub End If ReDim abWK(nWkLen - 1) nWkLen = CIPHER_KeyWrap(abWK(0), nWkLen, abKeyData(0), nKdLen, abKek(0), nKekLen, PKI_BC_AES256) Debug.Print "WK=" & cnvHexStrFromBytes(abWK) abKeyData = cnvBytesFromHexStr("84e7f2d8 78f89fcc cd2d5eba fc56daf7 3300f27e f771cd68") abKek = cnvBytesFromHexStr("8ad8274e 56f46773 8edd83d4 394e5e29 af7c4089 e4f8d9f4") nKdLen = UBound(abKeyData) + 1 nKekLen = UBound(abKek) + 1 nWkLen = CIPHER_KeyWrap(0, 0, abKeyData(0), nKdLen, abKek(0), nKekLen, PKI_BC_3DES) If nWkLen <= 0 Then Debug.Print " returns " & nWkLen & ": " & pkiErrorLookup(nWkLen) Exit Sub End If ReDim abWK(nWkLen - 1) nWkLen = CIPHER_KeyWrap(abWK(0), nWkLen, abKeyData(0), nKdLen, abKek(0), nKekLen, PKI_BC_3DES) Debug.Print "WK=" & cnvHexStrFromBytes(abWK)
This should result in output as follows:
WK=503D75C73630A7B02ECF51B9B29B907749310B77B0B2E054 WK=EAFB901F82B98D37F17497063DE3E5EC7246AB57200AE73EDDDDF24AA403DAFA0C5AE151D1746FA4 WK=E6517B14A383D48AD71D2D80C98894A10C59901D69ABDF77E27A11B50370FAA21AF5231552D2C1F0
The AES key wrap will always give the same result for the same input data, but the triple DES result will be different each time.
Dim lpWK() As Byte Dim lpKeyData() As Byte Dim lpKek() As Byte lpKeyData = cnvBytesFromHexStr("00112233 44556677 8899aabb ccddeeff") lpKek = cnvBytesFromHexStr("c17a44e8 e28d7d64 81d1ddd5 0a3b8914") ' NB Specific nonzero option required in nOptions lpWK = cipherKeyWrap(lpKeyData, lpKek, PKI_BC_AES128) Debug.Print "WK=" & cnvHexStrFromBytes(lpWK) Debug.Print "OK=503D75C73630A7B02ECF51B9B29B907749310B77B0B2E054" ' Now unwrap the KEK Dim lpKeyUnwrapped() As Byte lpKeyUnwrapped = cipherKeyUnwrap(lpWK, lpKek, PKI_BC_AES128) Debug.Print "KY=" & cnvHexStrFromBytes(lpKeyUnwrapped) Debug.Print "OK=00112233445566778899AABBCCDDEEFF"