2.4.3.2 Encryption

This encryption accepts two parameters as input:

Data (Variable): An array of bytes to be obfuscated.

Length (4 bytes): An unsigned integer that specifies the length of Data.

The algorithm will yield an array of bytes as defined in Encrypted Data Structure (section 2.4.3.1).

To encrypt Data, an implementation MUST maintain the following states:

UnencryptedByte1 (1 byte): Specifies the last unencrypted byte read or written.

EncryptedByte1 (1 byte): Specifies the last encrypted byte read or written.

EncryptedByte2 (1 byte): Specifies the next-to-last encrypted byte read or written.

Version (1 byte): Specifies the encryption version.

ProjKey (1 byte): Specifies a project-specific encryption key.

IgnoredLength (1 byte): Specifies the length in bytes of IgnoredEnc.

Each field MUST be encrypted in the following order:

VersionEnc is calculated using the following formula:

 VersionEnc = Seed XOR Version

Version MUST be 2.

ProjKey is the checksum of the project identifier as computed by the following pseudocode:

 SET ProjKey TO 0.
  
 FOR each CharacterByte IN the string ProjectId.ProjectCLSID (section 2.3.1.2).
    
    ADD CharacterByte TO ProjKey.
  
 END FOR

ProjKeyEnc is calculated using the following formula:

 ProjKeyEnc = Seed XOR ProjKey

Initialize states for the rest of the encoding:

 SET UnencryptedByte1 TO ProjKey.
  
 SET EncryptedByte1 TO ProjKeyEnc.
  
 SET EncryptedByte2 TO VersionEnc .

IgnoredEnc is computed by the following pseudocode:

 SET IgnoredLength TO (Seed BAND 6) / 2.
  
 FOR Counter FROM 1 TO IgnoredLength INCLUSIVE:
  
    SET TempValue TO any value.
  
    SET ByteEnc TO (TempValue XOR (EncryptedByte2 + UnencryptedByte1)).
  
    APPEND IgnoredEnc WITH ByteEnc.
  
    SET EncryptedByte2 TO EncryptedByte1.
   SET EncryptedByte1 TO ByteEnc.
    SET UnencryptedByte1 TO TempValue.
END FOR

DataLengthEnc is computed by the following pseudocode:

 FOR each Byte IN Length in little endian order:
  
    SET ByteEnc TO (Byte XOR (EncryptedByte2 + UnencryptedByte1)).
  
    APPEND DataLengthEnc WITH ByteEnc.
  
    SET EncryptedByte2 TO EncryptedByte1.
  
    SET EncryptedByte1 TO ByteEnc.
  
    SET UnencryptedByte1 TO Byte.
  
 END FOR

DataEnc is computed by the following pseudocode:

 FOR each DataByte IN Data:
  
    SET ByteEnc TO (DataByte  XOR (EncryptedByte2 + UnencryptedByte1)).
  
    APPEND DataEnc WITH ByteEnc.
  
    SET EncryptedByte2 TO EncryptedByte1.
  
    SET EncryptedByte1 TO ByteEnc.
  
    SET UnencryptedByte1 TO DataByte.
  
 END FOR