4.1.10.5.11 EncryptValuesIfNecessary

 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 [SCHNEIER] section 17.1). 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
 pPayload: ADDRESS OF ENCRYPTED_PAYLOAD
  
  
 if not IsSecretAttribute(attr.attrTyp) then
   /* No additional encryption necessary. */
   return 0
 endif
  
 if not DRS_EXT_STRONG_ENCRYPTION in ClientExtensions(hDrs).dwFlags then
   return SEC_E_ALGORITHM_MISMATCH
 endif
  
  
  
 /* Get session key associated with the RPC connection. */
 sessionKey := session key associated with security context of hDrs,
   as specified by [MS-RPCE] section 3.3.1.5.2, "Building and Using a
   Security Context", and [MS-KILE] section 3.1.1.2, "Cryptographic
   Material"
  
  
 /* 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. */
   MD5Init(md5Context)
   MD5Update(md5context, sessionKey, sessionKey.length)
   MD5Update(md5context, salt, 16)
   MD5Final(md5Context)
  
  
   /* 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 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
 endfor
  
 return 0