5.1.2 Secret Encryption and Decryption
This cipher is used to provide confidentiality of wire traffic for operations that reference this section.
The encrypt_secret routine is used to encrypt a cleartext value into ciphertext prior to transmission. The decrypt_secret routine is used to decrypt a ciphertext value into cleartext after receipt. The appropriate mode is selected based on the requirements of the interface.
The definitions of des_ecb_lm_dec and des_ecb_lm_enc are specified in section 5.1.3.
-
encrypt_secret(input : LSA_UNICODE_STRING, sessionkey : byte[16], output : LSA_UNICODE_STRING) { LET blocklen be 8 LET keyindex be 0 // Set version, length // temporary buffer. LET buffer be an array of blocklen bytes DECLEARE Version as ULONG SET Version to 1 SET buffer to input->length SET (buffer + 4) to Version CALL des_ecb_lm_enc(buffer, sessionkey[keyindex], output->buffer) INCREMENT output->buffer by blocklen INCREMENT output->length by blocklen SET keyindex to AdvanceKey(keyindex) LET remaining be input->length WHILE remaining > blocklen CALL des_ecb_lm_enc(input->buffer, sessionkey[keyindex], output->buffer) INCREMENT input->buffer by blocklen INCREMENT output->buffer by blocklen INCREMENT output->length by blocklen SET keyindex to AdvanceKey(keyindex) DECREMENT remaining by blocklen ENDWHILE IF (remaining > 0) THEN // zero pad the last block. SET bytes in buffer to 0 COPY remaining bytes from input->buffer to buffer CALL des_ecb_lm_enc(buffer, sessionkey[keyindex], output->buffer) INCREMENT output->length by blocklen ENDIF } decrypt_secret(input : LSA_UNICODE_STRING, sessionkey : byte[16], output : LSA_UNICODE_STRING) { LET keyindex be 0 LET blocklen be 8 // Check version, get clear length. CALL des_ecb_lm_dec(input->buffer, sessionkey[keyindex], output->buffer) LET outputlength be output[0] LET version be output[1] IF (version ≠ 1) THEN // version check FAIL ENDIF INCREMENT input->buffer by blocklen SET keyindex to AdvanceKey(keyindex) LET remaining be outputlength WHILE remaining > blocklen CALL des_ecb_lm_dec(input->buffer, sessionkey[keyindex], output->buffer) INCREMENT input->buffer by blocklen INCREMENT output->buffer by blocklen SET keyindex to AdvanceKey(keyindex) DECREMENT remaining by blocklen ENDWHILE IF (remaining > 0) THEN CALL des_ecb_lm_dec(input->buffer, sessionkey[keyindex], output->buffer) ENDIF SET output->length to outputlength } ULONG AdvanceKey(pos : ULONG) { LET KeyBlockLen be 7; DECLARE overrun as ULONG DECLARE currpos as ULONG; DECLARE nextpos as ULONG; LET pos = pos + KeyBlockLen; LET currpos = pos; LET nextpos = pos + KeyBlockLen; IF (nextpos > sizeof(sessionKey)) THEN LET overrun = nextpos- sizeof(sessionKey); LET currpos = (KeyBlockLen - overrun); ENDIF RETURN currpos; }