/* ** Name: encode ** ** Description: ** Applies the Driver semantics to convert the data and key ** into form acceptable to CI and encodes the data using the ** key provided. An optional key mask, CompatCI.CRYPT_SIZE ** in length, will be combined with the key if provided. ** ** Input: ** key Encryption key. ** mask Key mask, may be NULL. ** data Data to be encrypted. ** ** Output: ** None. ** ** Returns: ** byte [] Encrypted data. ** ** History: ** 6-May-99 (gordy) ** Created. ** 22-Sep-99 (gordy) ** Converted parameters to byte arrays for easier processing ** here and to support character set/encoding at a higher level. ** 21-Apr-00 (gordy) ** Extracted from class AdvanObject. ** 6-jul-04 (gordy; ported by thoda04) ** Added key mask. */ public static byte[] encode(byte[] key, byte[] mask, byte[] data) { byte[] buff = null; int i, j, m, n, blocks; lock (KS) { /* ** The key schedule is built from a single CRYPT_SIZE ** byte array. We use the input key to build the byte ** array, truncating or duplicating as necessary. */ for (m = n = 0; m < CI.CRYPT_SIZE; m++) { if (n >= key.Length) { n = 0; } kbuff[m] = (byte)(key[n++] ^ (mask != null ? mask[m] : (byte)0)); } CI.set(kbuff, KS); /* ** The data to be encoded must be padded to a multiple ** of CRYPT_SIZE bytes. Random data is used for the ** pad, so for strings the null terminator is included ** in the data. A random value is added to each block ** so that a given key/data pair does not encode the ** same way twice. ** ** The total number of blocks can be calculated from ** the string length plus the null terminator divided ** into CRYPT_SIZE blocks (with one random byte): ** ((len+1) + (CRYPT_SIZE-2)) / (CRYPT_SIZE-1) ** which can be simplified as: ** (len / (CRYPT_SIZE - 1) + 1 */ blocks = (data.Length / (CI.CRYPT_SIZE - 1)) + 1; buff = new byte[blocks * CI.CRYPT_SIZE]; for (i = m = n = 0; i < blocks; i++) { buff[m++] = (byte)(rand.Next(256)); for (j = 1; j < CI.CRYPT_SIZE; j++) { if (n < data.Length) { buff[m++] = data[n++]; } else if (n > data.Length) { buff[m++] = (byte)(rand.Next(256)); } else { buff[m++] = 0; // null terminator n++; } } } // encode using obfuscated encode name method // CI.encode (buff, 0, buff.Length, KS, buff, 0); CI.toString(buff, 0, buff.Length, KS, buff, 0); } return(buff); } // encode