import binascii import time import pyaes from kmsBase import kmsRequestStruct, kmsResponseStruct, kmsBase from structure import Structure # v4 AES Key key = b'\x05\x3D\x83\x07\xF9\xE5\xF0\x88\xEB\x5E\xA6\x68\x6C\xF0\x37\xC7\xE4\xEF\xD2\xD6' # Xor Buffer def xorBuffer(source, offset, destination, size): for i in range(0, size): destination[i] ^= source[i + offset] def generateHash(message): """ The KMS v4 hash is a variant of CMAC-AES-128. There are two key differences: * The 'AES' used is modified in particular ways: * The basic algorithm is Rjindael with a conceptual 160bit key and 128bit blocks. This isn't part of the AES standard, but it works the way you'd expect. Accordingly, the algorithm uses 11 rounds and a 192 byte expanded key. * The trailing block is not XORed with a generated subkey, as defined in CMAC. This is probably because the subkey generation algorithm is only defined for situations where block and key size are the same. """ aes = pyaes.AES(key, rounds=11) messageSize = len(message) lastBlock = bytearray(16) hashBuffer = bytearray(16) # MessageSize / Blocksize j = messageSize >> 4 # Remainding bytes k = messageSize & 0xf # Hash for i in range(0, j): xorBuffer(message, i << 4, hashBuffer, 16) hashBuffer = bytearray(aes.encrypt(hashBuffer)) # Bit Padding ii = 0 for i in range(j << 4, k + (j << 4)): lastBlock[ii] = message[i] ii += 1 lastBlock[k] = 0x80 xorBuffer(lastBlock, 0, hashBuffer, 16) hashBuffer = bytearray(aes.encrypt(hashBuffer)) return bytes(hashBuffer) class kmsRequestV4(kmsBase): class RequestV4(Structure): commonHdr = () structure = ( ('bodyLength1', '