procedure EncryptValuesIfNecessary(
   hDrs: DRS_HANDLE,
   var attr: ATTR) : ULONG

Informative summary of behavior: The EncryptValuesIfNecessary procedure encrypts the values of attributes that contain secret data. It performs the encryption by using an MD5 digest (as specified in [RFC1321]), a CRC32 checksum (as specified in [ISO/IEC 13239]), and an RC4 stream cipher (as specified in [RC4]). This encryption is in addition to the encryption that is provided by RPC privacy.

 sessionKey: sequence of BYTE
 i: integer
 salt: sequence of BYTE
 md5Context: MD5_CTX
 crc: ULONG
 if not IsSecretAttribute(attr.attrTyp) then
   /* No additional encryption necessary. */
   return 0
 if not DRS_EXT_STRONG_ENCRYPTION in ClientExtensions(hDrs).dwFlags then
 /* Get session key associated with the RPC connection. */
 sessionKey := session key associated with security context of hDrs,
   as specified by [MS-RPCE] section, "Building and Using a
   Security Context", and [MS-KILE] section, "Cryptographic
 /* Encrypt each value of this attribute. */
 for i := 0 to attr.AttrVal.valCount - 1
   salt := randomly generated 128-bit number
   /* Calculate checksum of the clear value. */
   crc := CRC32 [ISO/IEC 13239] of the attr.AttrVal.pAVal[i].valLen
       bytes starting at attr.AttrVal.pAVal[i].pVal
   /* Compute encryption key. */
   MD5Update(md5context, sessionKey, sessionKey.length)
   MD5Update(md5context, salt, 16)
   /* Construct payload, encrypting its contents with the exception of
    * the Salt field. */
   pPayload := New ENCRYPTED_PAYLOAD, sized to hold
       attr.AttrVal.pAVal[i].valLen bytes in the EncryptedData field
   pPayload^.Salt := salt
   pPayload^.Checksum := crc
   Copy attr.AttrVal.pAVal[i].valLen bytes from
       attr.AttrVal.pAVal[i].pVal to pPayload^.EncryptedData
   Encrypt attr.AttrVal.pAVal[i].valLen + 4 bytes starting at the
       address of pPayload^.Checksum using the RC4 stream cipher
       algorithm [RC4] with encryption key md5Context.digest
   /* Replace the clear value with the encrypted value. */
   attr.AttrVal.pAVal[i].pVal := pPayload
   attr.AttrVal.pAVal[i].valLen := attr.AttrVal.pAVal[i].valLen + 20
 return 0