Source code for virttest.RFBDes

from virttest import utils_misc


[docs]class Des(object): """ Base Data Encryption Standard class. For details, please refer to: http://en.wikipedia.org/wiki/Data_Encryption_Standard """ # Permutation and translation tables for DES PC1 = [ 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 ] # Number left rotations of pc1 left_rotations = [ 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 ] # get_sub_listd choice key (table 2) PC2 = [ 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 ] # Initial permutation IP IP = [ 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7, 56, 48, 40, 32, 24, 16, 8, 0, 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6 ] # Expansion table for turning 32 bit blocks into 48 bits E = [ 31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 8, 9, 10, 11, 12, 11, 12, 13, 14, 15, 16, 15, 16, 17, 18, 19, 20, 19, 20, 21, 22, 23, 24, 23, 24, 25, 26, 27, 28, 27, 28, 29, 30, 31, 0 ] # The (in)famous S-boxes sbox = [ # S1 [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13], # S2 [15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9], # S3 [10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12], # S4 [7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14], # S5 [2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3], # S6 [12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13], # S7 [4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12], # S8 [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11], ] # 32-bit permutation function P used on the output of the S-boxes P = [ 15, 6, 19, 20, 28, 11, 27, 16, 0, 14, 22, 25, 4, 17, 30, 9, 1, 7, 23, 13, 31, 26, 2, 8, 18, 12, 29, 5, 21, 10, 3, 24 ] # Final permutation IP^-1 FP = [ 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25, 32, 0, 40, 8, 48, 16, 56, 24 ] # Initialisation def __init__(self, key): """ Initialize the instance. :param key: Original used in DES. """ if len(key) != 8: key = (key + '\0' * 8)[:8] self.L = [] self.R = [] self.Kn = [[0] * 48] * 16 # 16 48-bit keys (K1 - K16) self.setKey(key)
[docs] def getKey(self): """ Just get the crypting key. """ return self.key
[docs] def setKey(self, key): """ Will set the crypting key for this object. RFB protocol for authentication requires client to encrypt challenge sent by server with password using DES method. However, bits in each byte of the password are put in reverse order before using it as encryption key. :param key: Original used in DES. """ newkey = [] for ki in range(len(key)): bsrc = ord(key[ki]) btgt = 0 for i in range(8): if bsrc & (1 << i): btgt = btgt | (1 << 7 - i) newkey.append(chr(btgt)) self.key = newkey self.create_Kn()
[docs] def get_sub_list(self, table, block): """ Return sub list of block according to index in table. :param table: Index list. :param block: bit list used to get sub list. """ block_list = [] for x in table: block_list.append(block[x]) return block_list
[docs] def create_Kn(self): """ Create the 16 subkeys,from K[0] to K[15], from the given key """ key = self.get_sub_list( self.PC1, utils_misc.string_to_bitlist(self.getKey())) self.L = key[:28] self.R = key[28:] for i in range(16): # Perform circular left shifts for j in range(self.left_rotations[i]): self.L.append(self.L[0]) del self.L[0] self.R.append(self.R[0]) del self.R[0] # Create one of the 16 subkeys through pc2 permutation self.Kn[i] = self.get_sub_list(self.PC2, self.L + self.R)
[docs] def f(self, K): """ The Feistel function (F-function) of DES, operates on half a block (32 bits) at a time and consists of four stages: 1. Expansion 2. Key mixing 3. Substitution 4. Permutation :param K: One of sixteen 48-bit subkeys are derived from the main key. """ # Expansion: # The 32-bit half-block is expanded to 48 bits using E. self.R = self.get_sub_list(self.E, self.R) # Key mixing: The result is combined with a subkey using an XOR # operation. Sixteen 48-bit subkeys are derived from the main key. self.R = list(map(lambda x, y: x ^ y, self.R, K)) # The block is divided into eight 6-bit pieces B = [self.R[:6], self.R[6:12], self.R[12:18], self.R[18:24], self.R[24:30], self.R[30:36], self.R[36:42], self.R[42:]] # Substitution: Bn = [0] * 32 pos = 0 for j in range(8): # Work out the offsets m = (B[j][0] << 1) + B[j][5] n = (B[j][1] << 3) + (B[j][2] << 2) + (B[j][3] << 1) + B[j][4] # Find the permutation value v = self.sbox[j][(m << 4) + n] # Turn value into bits, add it to result: Bn Bn[pos] = (v & 8) >> 3 Bn[pos + 1] = (v & 4) >> 2 Bn[pos + 2] = (v & 2) >> 1 Bn[pos + 3] = v & 1 pos += 4 # Permutation: # Bn are rearranged according to a fixed permutation, the P-box. self.R = self.get_sub_list(self.P, Bn)
[docs] def des_crypt(self, data, crypt_type=0): """ Crypt the block of data through DES bit-manipulation :param data: data need to crypt. :param crypt_type: crypt type. 0 means encrypt, and 1 means decrypt. """ # Get new block by using Ip. block = self.get_sub_list(self.IP, data) self.L = block[:32] self.R = block[32:] if crypt_type == 0: des_i = 0 des_adj = 1 else: des_i = 15 des_adj = -1 i = 0 while i < 16: tempR = self.R self.f(self.Kn[des_i]) # Xor with L[i - 1] self.R = list(map(lambda x, y: x ^ y, self.R, self.L)) # Optimization: This now replaces the below commented code self.L = tempR i += 1 des_i += des_adj # Final permutation of R[16]L[16] final = self.get_sub_list(self.FP, self.R + self.L) return final
[docs] def crypt(self, data, crypt_type=0): """ Crypt the data in blocks, running it through des_crypt() :param data: Data to be encrypted/decrypted. :param crypt_type: crypt type. 0 means encrypt, and 1 means decrypt. """ # Split the data into list, crypting each one separately i = 0 result = [] while i < len(data): # Test code for caching encryption results block = utils_misc.string_to_bitlist(data[i:i + 8]) pro_block = self.des_crypt(block, crypt_type) # Add the resulting block to our list result.append(utils_misc.bitlist_to_string(pro_block)) i += 8 # Return the full encrypted/decrypted string return ''.join(result)