Пример #1
0
    def runTest(self):

        key = b"0" * 16
        data = b"\x00\x01\x02"

        def get_mv_ro(data):
            return memoryview(data)

        def get_mv_rw(data):
            return memoryview(bytearray(data))

        for get_mv in (get_mv_ro, get_mv_rw):

            # Data and key can be a memoryview (during initialization)
            key_mv = get_mv(key)
            data_mv = get_mv(data)

            h1 = CMAC.new(key, data, ciphermod=AES)
            h2 = CMAC.new(key_mv, data_mv, ciphermod=AES)
            if not data_mv.readonly:
                key_mv[:1] = b'\xFF'
                data_mv[:1] = b'\xFF'
            self.assertEqual(h1.digest(), h2.digest())

            # Data can be a memoryview (during operation)
            data_mv = get_mv(data)

            h1 = CMAC.new(key, ciphermod=AES)
            h2 = CMAC.new(key, ciphermod=AES)
            h1.update(data)
            h2.update(data_mv)
            if not data_mv.readonly:
                data_mv[:1] = b'\xFF'
            self.assertEqual(h1.digest(), h2.digest())
Пример #2
0
    def runTest(self):

        key = b"0" * 16
        data = b"\x00\x01\x02"

        # Data and key can be a bytearray (during initialization)
        key_ba = bytearray(key)
        data_ba = bytearray(data)

        h1 = CMAC.new(key, data, ciphermod=AES)
        h2 = CMAC.new(key_ba, data_ba, ciphermod=AES)
        key_ba[:1] = b'\xFF'
        data_ba[:1] = b'\xFF'
        self.assertEqual(h1.digest(), h2.digest())

        # Data can be a bytearray (during operation)
        key_ba = bytearray(key)
        data_ba = bytearray(data)

        h1 = CMAC.new(key, ciphermod=AES)
        h2 = CMAC.new(key, ciphermod=AES)
        h1.update(data)
        h2.update(data_ba)
        data_ba[:1] = b'\xFF'
        self.assertEqual(h1.digest(), h2.digest())
Пример #3
0
def get_content_block(buff):
	global cmac_keyx
	hash=hashlib.sha256(buff).digest()
	key = int16bytes(normalkey(cmac_keyx, keyy))
	cipher = CMAC.new(key, ciphermod=AES)
	result = cipher.update(hash)
	return result.digest() + b''.join(bytechr(random.randint(0,255)) for _ in range(16))
Пример #4
0
def q2_siv_mode_dec(enc_key, mac_key, ciphertext, associated_data):
    """Question 2 (part 2): Synthetic Initialization Vector (SIV) Authenticated Encryption

    Your Task:
        Similar to the first part of this question, your function should decrypt
        the output produced by the function in the first part and return the 
        plaintext if the tag is valid, and return ERROR otherwise.
    Args:
        enc_key         (str):  16-bytes hex-encoded key to be used for AES
        mac_key         (str):  16-bytes hex-encoded key to be used for CMAC
        ciphertext      (str):  arbitrary-length hec-encoded ciphertext (same format
                                as the output of q2_siv_mode_enc)
        associated_data (str):  arbitrary-length hex-encoded data to be 
                                authenticated, but not encrypted
    Output:
        ret             (str):  ASCII-encoded, plaintext (or 'ERROR')
    Test vectors:
        Use the same test case provided in part 1 of this question.
    """
    backend = default_backend()
    tag = ciphertext[:32]
    cipherMessage = ciphertext[32:]
    cipher = Cipher(algorithms.AES(bytes.fromhex(enc_key)),
                    modes.CTR(bytes.fromhex(tag)), backend)
    decryptor = cipher.decryptor()
    message = decryptor.update(bytes.fromhex(cipherMessage))
    cmac_input = bytes.fromhex(associated_data) + message
    cobj = CMAC.new(bytes.fromhex(mac_key), ciphermod=AES)
    cobj.update(cmac_input)
    ComputedTag = cobj.hexdigest()
    if (tag != ComputedTag):
        return 'ERROR'
    else:
        return message.decode('ascii')
Пример #5
0
    def getContentKey(self, license_request_data: bytes,
                      license_response_data: bytes):
        licenseMessage = license_protocol_pb2.License()
        requestMessage = license_protocol_pb2.SignedMessage()
        responseMessage = license_protocol_pb2.SignedMessage()
        requestMessage.ParseFromString(license_request_data)
        responseMessage.ParseFromString(license_response_data)

        oaep_key = RSA.importKey(self.private_key)
        cipher = PKCS1_OAEP.new(oaep_key)
        cmac_key = cipher.decrypt(responseMessage.session_key)

        _cipher = CMAC.new(cmac_key, ciphermod=AES)
        _auth_key = b'\x01ENCRYPTION\x00' + requestMessage.msg + b"\x00\x00\x00\x80"
        enc_cmac_key = _cipher.update(_auth_key).digest()

        licenseMessage.ParseFromString(responseMessage.msg)
        global KEY_ARRAY
        KEY_ARRAY = []
        for key in licenseMessage.key:
            cryptos = AES.new(enc_cmac_key, AES.MODE_CBC, iv=key.iv[0:16])
            dkey = cryptos.decrypt(key.key[0:16])
            #			print("KID:", binascii.b2a_hex(key.id).decode('utf-8'), "KEY:",binascii.b2a_hex(dkey).decode('utf-8'))
            KEY_ARRAY.append("%s:%s" %
                             (binascii.b2a_hex(key.id).decode('utf-8'),
                              binascii.b2a_hex(dkey).decode('utf-8')))
        KEY_ARRAY.remove(KEY_ARRAY[0])
        for item in KEY_ARRAY:
            print("[info][Found KEY] %s" % item)
Пример #6
0
    def update(self, item):
        """Pass the next component of the vector.

        The maximum number of components you can pass is equal to the block
        length of the cipher (in bits) minus 1.

        :Parameters:
          item : byte string
            The next component of the vector.
        :Raise TypeError: when the limit on the number of components has been reached.
        :Raise ValueError: when the component is empty
        """

        if not item:
            raise ValueError("A component cannot be empty")

        if self._n_updates==0:
            raise TypeError("Too many components passed to S2V")
        self._n_updates -= 1

        mac = CMAC.new(self._key,
                       msg=self._last_string,
                       ciphermod=self._ciphermod,
                       cipher_params=self._cipher_params)
        self._cache = strxor(self._double(self._cache), mac.digest())
        self._last_string = item
Пример #7
0
    def update(self, item):
        """Pass the next component of the vector.

        The maximum number of components you can pass is equal to the block
        length of the cipher (in bits) minus 1.

        :Parameters:
          item : byte string
            The next component of the vector.
        :Raise TypeError: when the limit on the number of components has been reached.
        :Raise ValueError: when the component is empty
        """

        if not item:
            raise ValueError("A component cannot be empty")

        if self._n_updates == 0:
            raise TypeError("Too many components passed to S2V")
        self._n_updates -= 1

        mac = CMAC.new(self._key,
                       msg=self._last_string,
                       ciphermod=self._ciphermod,
                       cipher_params=self._cipher_params)
        self._cache = strxor(self._double(self._cache), mac.digest())
        self._last_string = item
Пример #8
0
def get_content_block(buff):
    global cmac_keyx
    hash = hashlib.sha256(buff).digest()
    key = int16bytes(normalkey(cmac_keyx, keyy))
    cipher = CMAC.new(key, ciphermod=AES)
    result = cipher.update(hash)
    return result.digest() + b'\x00' * 16
Пример #9
0
    def runTest(self):

        data_to_mac = get_tag_random("data_to_mac", 128)
        key = get_tag_random("key", 16)
        ref_mac = CMAC.new(key, msg=data_to_mac, ciphermod=AES).digest()

        # Break up in chunks of different length
        # The result must always be the same
        for chunk_length in 1, 2, 3, 7, 10, 13, 16, 40, 80, 128:

            chunks = [data_to_mac[i:i+chunk_length] for i in
                      range(0, len(data_to_mac), chunk_length)]

            mac = CMAC.new(key, ciphermod=AES)
            for chunk in chunks:
                mac.update(chunk)
            self.assertEqual(ref_mac, mac.digest())
Пример #10
0
    def test_update_after_digest(self):
        msg = b"rrrrttt"
        key = b"4" * 16

        # Normally, update() cannot be done after digest()
        h = CMAC.new(key, msg[:4], ciphermod=AES)
        dig1 = h.digest()
        self.assertRaises(TypeError, h.update, msg[4:])
        dig2 = CMAC.new(key, msg, ciphermod=AES).digest()

        # With the proper flag, it is allowed
        h2 = CMAC.new(key, msg[:4], ciphermod=AES, update_after_digest=True)
        self.assertEquals(h2.digest(), dig1)
        # ... and the subsequent digest applies to the entire message
        # up to that point
        h2.update(msg[4:])
        self.assertEquals(h2.digest(), dig2)
Пример #11
0
def aes_cmac(key, n):
    if have_crypto:
        cobj = CMAC.new(key, ciphermod=AES)
        cobj.update(n)
        return cobj.digest()
    else:
        # return random value
        return os.urandom(16)
Пример #12
0
    def test_update_after_digest(self):
        msg = b"rrrrttt"
        key = b"4" * 16

        # Normally, update() cannot be done after digest()
        h = CMAC.new(key, msg[:4], ciphermod=AES)
        dig1 = h.digest()
        self.assertRaises(TypeError, h.update, msg[4:])
        dig2 = CMAC.new(key, msg, ciphermod=AES).digest()

        # With the proper flag, it is allowed
        h2 = CMAC.new(key, msg[:4], ciphermod=AES, update_after_digest=True)
        self.assertEquals(h2.digest(), dig1)
        # ... and the subsequent digest applies to the entire message
        # up to that point
        h2.update(msg[4:])
        self.assertEquals(h2.digest(), dig2)
Пример #13
0
def aes_cmac(key, n):
    if have_crypto:
        cobj = CMAC.new(key, ciphermod=AES)
        cobj.update(n)
        return cobj.digest()
    else:
        # return dummy value
        return b'\x00' * 16
Пример #14
0
    def runTest(self):

        data_to_mac = get_tag_random("data_to_mac", 128)
        key = get_tag_random("key", 16)
        ref_mac = CMAC.new(key, msg=data_to_mac, ciphermod=AES).digest()

        # Break up in chunks of different length
        # The result must always be the same
        for chunk_length in 1, 2, 3, 7, 10, 13, 16, 40, 80, 128:

            chunks = [data_to_mac[i:i+chunk_length] for i in
                      range(0, len(data_to_mac), chunk_length)]

            mac = CMAC.new(key, ciphermod=AES)
            for chunk in chunks:
                mac.update(chunk)
            self.assertEqual(ref_mac, mac.digest())
Пример #15
0
    def create_cmac_object(self, keyslot: int) -> 'CMACObject':
        """Create a CMAC object with the given keyslot."""
        try:
            key = self.key_normal[keyslot]
        except KeyError:
            raise KeyslotMissingError(
                f'normal key for keyslot 0x{keyslot:02x} is not set up')

        return CMAC.new(key, ciphermod=AES)
Пример #16
0
    def test_internal_caching(self):
        """Verify that internal caching is implemented correctly"""

        data_to_mac = get_tag_random("data_to_mac", 128)
        key = get_tag_random("key", 16)
        ref_mac = CMAC.new(key, msg=data_to_mac, ciphermod=AES).digest()

        # Break up in chunks of different length
        # The result must always be the same
        for chunk_length in 1, 2, 3, 7, 10, 13, 16, 40, 80, 128:

            chunks = [data_to_mac[i:i+chunk_length] for i in
                      range(0, len(data_to_mac), chunk_length)]

            mac = CMAC.new(key, ciphermod=AES)
            for chunk in chunks:
                mac.update(chunk)
            self.assertEqual(ref_mac, mac.digest())
Пример #17
0
 def test_create_mac(self, tv):
     self._id = "Wycheproof MAC creation Test #" + str(tv.id)
     
     try:
         tag = CMAC.new(tv.key, tv.msg, ciphermod=AES, mac_len=tv.tag_size).digest()
     except ValueError as e:
         if len(tv.key) not in (16, 24, 32) and "key length" in str(e):
             return
         raise e
     if tv.valid:
         self.assertEqual(tag, tv.tag)
         self.warn(tv)
def aes128_cmac(key, message):
    """
    (bytes, bytes) -> (bytes)

    Calculates the AES128 CMAC of a message.
    :param key: 128 bit long key. (16 bytes sequence).
    :param message: byte sequence of the message.
    :return: CMAC of the message (16 bytes sequence).
    """
    assert len(key) == 16, "The key must be 128 bits long."
    cobj = CMAC.new(key, ciphermod=AES)
    cobj.update(message)
    return cobj.digest()
Пример #19
0
def q2_siv_mode_enc(enc_key, mac_key, plaintext, associated_data):
    """Question 2 (part 1): Synthetic Initialization Vector (SIV) Authenticated Encryption

    Your Task:
        Your function should implement the SIV mode for authenticated encryption
        as illustrated in lecture 13. For this implementation, you would have to
        use the AES block cipher in CTR mode, along with CMAC as a MAC.
    Args:
        enc_key         (str):  16-bytes hex-encoded key to be used for AES
        mac_key         (str):  16-bytes hex-encoded key to be used for CMAC
        plaintext       (str):  arbitrary-length ASCII encoded plaintext
        associated_data (str):  arbitrary-length hex-encoded data to be 
                                authenticated, but not encrypted
    Output:
        ret             (str):  hex-encoded, ciphertext formatted as
                                    tag + ciphertext (as shown in Lecture slides)
    Test vectors:
        assert(q2_siv_mode_enc( enc_key="7f7e7d7c7b7a79787776757473727170", 
                        mac_key="404142434445464748494a4b4c4d4e4f",
                        plaintext="this is some plaintext to encrypt using SIV-AES",
                        associated_data = "00112233445566778899aabbccddeeffdeaddadadeaddadaffeeddccbbaa99887766554433221100"
                ) == "2550eb1783787e5f2d4e56fba6dff0a7df554c297854c8c4e4833435e66989314b6b2791862c7d11498c2ef034bfbb63808c73bc5ea23e64cb58a8e1a5775a")
    Note:

        Also Feel free to use componenets from the Cryptodome/cryptography libraries 
        to build this function (ex. `from Crypto.Hash import CMAC`). That being 
        said, you should not use the SIV mode provided by any library, you should 
        combine the building blocks to implement the SIV mode on your own.

        When using the tag as a nonce for the CTR mode, some CTR implementations
        would not allow the nonce to be equal to the block_size (for example, 
        the `Cryptodome.Cipher` class with throw an error when using a nonce
        of size > block_size - 1), so I recommend using the CTR mode provided by
        the library `cryptography` instead 
        (e.g `from cryptography.hazmat.primitives.ciphers import Cipher`).

        Also note that for this implementation, there's no need to clear any bits
        of the tag before using it as a nonce. You can assume that the number of
        blocks we would test against would not overflow the counter bits.
    """
    backend = default_backend()
    cmac_input = bytes.fromhex(associated_data) + plaintext.encode('ascii')
    cobj = CMAC.new(bytes.fromhex(mac_key), ciphermod=AES)
    cobj.update(cmac_input)
    tag = cobj.digest()
    cipher = Cipher(algorithms.AES(bytes.fromhex(enc_key)), modes.CTR(tag),
                    backend)
    encryptor = cipher.encryptor()
    cipherText = encryptor.update(plaintext.encode('ascii'))
    return tag.hex() + cipherText.hex()
Пример #20
0
    def ComputMic( self, frame, address, dir, sequence ):
        key = bytes.fromhex( self.nwkSKey )

        b0Block = bytearray( [0x49, 0x00, 0x00, 0x00, 0x00]);

        b0Block.append( dir )

        b0Block.extend( [( address ) & 0xFF, ( address >> 8 ) & 0xFF, ( address >> 16 ) & 0xFF, ( address >> 24 ) & 0xFF] )
        b0Block.extend( [( sequence ) & 0xFF, ( sequence >> 8 ) & 0xFF, ( sequence >> 16 ) & 0xFF, ( sequence >> 24 ) & 0xFF] )
        b0Block.extend( [0, len( frame ) & 0xFF] )
        cmac = CMAC.new( key,ciphermod=AES )
        cmac.update( bytes( b0Block + frame ) )
        mic = ( cmac.digest()[3] << 24 ) | ( cmac.digest()[2] << 16 ) | ( cmac.digest()[1] << 8 ) | ( cmac.digest()[0] << 0 )
        return mic
Пример #21
0
def q2_siv_mode_enc(enc_key, mac_key, plaintext, associated_data):
    """Question 2 (part 1): Synthetic Initialization Vector (SIV) Authenticated Encryption"""

    tag = CMAC.new(binascii.unhexlify(mac_key),
                   (binascii.unhexlify(associated_data) + plaintext.encode()),
                   ciphermod=AES).digest()

    ciphert = Cipher(algorithms.AES(binascii.unhexlify(enc_key)),
                     mode=modes.CTR(tag),
                     backend=default_backend())
    encryptor = ciphert.encryptor()
    ct = encryptor.update(plaintext.encode())

    return binascii.hexlify(tag).decode() + binascii.hexlify(ct).decode()
Пример #22
0
    def create_cmac_object(self, keyslot: Keyslot) -> 'CMAC_CLASS':
        """
        Create a CMAC object with the given keyslot.

        :param keyslot: :class:`Keyslot` to use.
        :return: A CMAC object from PyCryptodome.
        :rtype: CMAC
        """
        try:
            key = self.key_normal[keyslot]
        except KeyError:
            raise KeyslotMissingError(f'normal key for keyslot 0x{keyslot:02x} is not set up')

        return CMAC.new(key, ciphermod=AES)
Пример #23
0
def get_challenge(appeui, appkey, appnonce):
    secret = binascii.a2b_hex(appkey)
    cobj = CMAC.new(secret, ciphermod=AES)
    msg = binascii.a2b_hex(appeui) + \
          binascii.a2b_hex(str('%08x' % appnonce)) + \
          binascii.a2b_hex(str('%08x' % 0))
    cobj.update(msg)
    btr = cobj.digest()
    challenge = ''
    for x in range(0, 16):
        challenge += ('%02X' % btr[16 - x - 1])
    # print(challenge)
    # challenge = cobj.hexdigest()
    #print(challenge)
    return challenge
Пример #24
0
    def derive(self):
        """"Derive a secret from the vector of components.

        :Return: a byte string, as long as the block length of the cipher.
        """

        if len(self._last_string)>=16:
            final = self._last_string[:-16] + strxor(self._last_string[-16:], self._cache)
        else:
            padded = (self._last_string + bchr(0x80)+ bchr(0)*15)[:16]
            final = strxor(padded, self._double(self._cache))
        mac = CMAC.new(self._key,
                       msg=final,
                       ciphermod=self._ciphermod,
                       cipher_params=self._cipher_params)
        return mac.digest()
Пример #25
0
    def derive(self):
        """"Derive a secret from the vector of components.

        :Return: a byte string, as long as the block length of the cipher.
        """

        if len(self._last_string)>=16:
            final = self._last_string[:-16] + strxor(self._last_string[-16:], self._cache)
        else:
            padded = (self._last_string + bchr(0x80)+ bchr(0)*15)[:16]
            final = strxor(padded, self._double(self._cache))
        mac = CMAC.new(self._key,
                       msg=final,
                       ciphermod=self._ciphermod,
                       cipher_params=self._cipher_params)
        return mac.digest()
Пример #26
0
 def test_verify_mac(self, tv):
     self._id = "Wycheproof MAC verification Test #" + str(tv.id)
    
     try:
         mac = CMAC.new(tv.key, tv.msg, ciphermod=AES, mac_len=tv.tag_size)
     except ValueError as e:
         if len(tv.key) not in (16, 24, 32) and "key length" in str(e):
             return
         raise e
     try:
         mac.verify(tv.tag)
     except ValueError:
         assert not tv.valid
     else:
         assert tv.valid
         self.warn(tv)
Пример #27
0
    def __init__(self, factory, key, nonce, mac_len, cipher_params):
        """EAX cipher mode"""

        self.block_size = factory.block_size
        """The block size of the underlying cipher, in bytes."""

        self.nonce = _copy_bytes(None, None, nonce)
        """The nonce originally used to create the object."""

        self._mac_len = mac_len
        self._mac_tag = None  # Cache for MAC tag

        # Allowed transitions after initialization
        self._next = [self.update, self.encrypt, self.decrypt,
                      self.digest, self.verify]

        # MAC tag length
        if not (4 <= self._mac_len <= self.block_size):
            raise ValueError("Parameter 'mac_len' must not be larger than %d"
                             % self.block_size)

        # Nonce cannot be empty and must be a byte string
        if len(self.nonce) == 0:
            raise ValueError("Nonce cannot be empty in EAX mode")
        if isinstance(nonce, unicode):
            raise TypeError("nonce must be a byte string")

        self._omac = [
                CMAC.new(key,
                         b'\x00' * (self.block_size - 1) + struct.pack('B', i),
                         ciphermod=factory,
                         cipher_params=cipher_params)
                for i in xrange(0, 3)
                ]

        # Compute MAC of nonce
        self._omac[0].update(self.nonce)
        self._signer = self._omac[1]

        # MAC of the nonce is also the initial counter for CTR encryption
        counter_int = bytes_to_long(self._omac[0].digest())
        self._cipher = factory.new(key,
                                   factory.MODE_CTR,
                                   initial_value=counter_int,
                                   nonce=b"",
                                   **cipher_params)
Пример #28
0
    def ComputMic(self, frame, address, dir, sequence):
        key = bytes.fromhex(self.nwkSKey)

        b0Block = bytearray([0x49, 0x00, 0x00, 0x00, 0x00])

        b0Block.append(dir)

        b0Block.extend([(address) & 0xFF, (address >> 8) & 0xFF,
                        (address >> 16) & 0xFF, (address >> 24) & 0xFF])
        b0Block.extend([(sequence) & 0xFF, (sequence >> 8) & 0xFF,
                        (sequence >> 16) & 0xFF, (sequence >> 24) & 0xFF])
        b0Block.extend([0, len(frame) & 0xFF])
        cmac = CMAC.new(key, ciphermod=AES)
        cmac.update(bytes(b0Block + frame))
        mic = (cmac.digest()[3] << 24) | (cmac.digest()[2] << 16) | (
            cmac.digest()[1] << 8) | (cmac.digest()[0] << 0)
        return mic
Пример #29
0
    def __init__(self, factory, key, nonce, mac_len, cipher_params):
        """EAX cipher mode"""

        self.block_size = factory.block_size
        """The block size of the underlying cipher, in bytes."""

        self.nonce = bstr(nonce)
        """The nonce originally used to create the object."""

        self._mac_len = mac_len
        self._mac_tag = None  # Cache for MAC tag

        # Allowed transitions after initialization
        self._next = [
            self.update, self.encrypt, self.decrypt, self.digest, self.verify
        ]

        # MAC tag length
        if not (4 <= self._mac_len <= self.block_size):
            raise ValueError("Parameter 'mac_len' must not be larger than %d" %
                             self.block_size)

        # Nonce cannot be empty and must be a byte string
        if len(self.nonce) == 0:
            raise ValueError("Nonce cannot be empty in EAX mode")
        if isinstance(nonce, unicode):
            raise TypeError("nonce must be a byte string")

        self._omac = [
            CMAC.new(key,
                     bchr(0) * (self.block_size - 1) + bchr(i),
                     ciphermod=factory,
                     cipher_params=cipher_params) for i in xrange(0, 3)
        ]

        # Compute MAC of nonce
        self._omac[0].update(self.nonce)
        self._signer = self._omac[1]

        # MAC of the nonce is also the initial counter for CTR encryption
        counter_int = bytes_to_long(self._omac[0].digest())
        self._cipher = factory.new(key,
                                   factory.MODE_CTR,
                                   initial_value=counter_int,
                                   nonce=b(""),
                                   **cipher_params)
Пример #30
0
def q2_siv_mode_dec(enc_key, mac_key, ciphertext, associated_data):
    """Question 2 (part 2): Synthetic Initialization Vector (SIV) Authenticated Encryption"""

    tag = binascii.unhexlify(ciphertext[:32].encode())
    ct = binascii.unhexlify(ciphertext[32:].encode())
    ciphert = Cipher(algorithms.AES(binascii.unhexlify(enc_key)),
                     mode=modes.CTR(tag),
                     backend=default_backend())
    decryptor = ciphert.decryptor()
    pt = decryptor.update(ct)

    tagPoss = CMAC.new(binascii.unhexlify(mac_key),
                       (binascii.unhexlify(associated_data) + pt),
                       ciphermod=AES).digest()
    if tag != tagPoss:
        return "ERROR"
    else:
        return pt.decode()
Пример #31
0
def aes128_cmac(key: Sequence[int], data: Sequence[int]) -> List[int]:
  """
  AES function as it's used in the LoRaWAN specification. Takes a block of 16 bytes as key,
  and an arbitrary length of bytes as data and creates a 16 byte CMAC from it.

  :param key: Key as sequence of bytes
  :param data: Data as sequence of bytes
  """
  if not isinstance(key, Sequence):
    raise TypeError("key must be a sequence of 16 bytes")
  if not isinstance(data, Sequence):
    raise TypeError("data must be a sequence of bytes")
  if len(key)!=16 or next((True for k in key if k < 0 or k > 255),False):
    raise ValueError("key must be a sequence of 16 bytes")
  if next((True for k in key if k < 0 or k > 255), False):
    raise ValueError("data must be a sequence of 16 bytes")

  cmac = CMAC.new(bytes(key), ciphermod=AES)
  cmac.update(bytes(data))
  return [c for c in cmac.digest()]
Пример #32
0
def aes_cmac(key, n):
    cobj = CMAC.new(key, ciphermod=AES)
    cobj.update(n)
    return cobj.digest()
Пример #33
0
    def _real_extract(self, url):
        video_id = self._match_id(url)

        data = json.dumps({
            'method':
            'da.content.get',
            'params': [
                video_id, {
                    'site': 's%d',
                    'referrer': 'http://www.ivi.ru/watch/%s' % video_id,
                    'contentid': video_id
                }
            ]
        })

        bundled = hasattr(sys, 'frozen')

        for site in (353, 183):
            content_data = (data % site).encode()
            if site == 353:
                if bundled:
                    continue
                try:
                    from Cryptodome.Cipher import Blowfish
                    from Cryptodome.Hash import CMAC
                    pycryptodomex_found = True
                except ImportError:
                    pycryptodomex_found = False
                    continue

                timestamp = (self._download_json(
                    self._LIGHT_URL,
                    video_id,
                    'Downloading timestamp JSON',
                    data=json.dumps({
                        'method': 'da.timestamp.get',
                        'params': []
                    }).encode(),
                    fatal=False) or {}).get('result')
                if not timestamp:
                    continue

                query = {
                    'ts':
                    timestamp,
                    'sign':
                    CMAC.new(self._LIGHT_KEY,
                             timestamp.encode() + content_data,
                             Blowfish).hexdigest(),
                }
            else:
                query = {}

            video_json = self._download_json(self._LIGHT_URL,
                                             video_id,
                                             'Downloading video JSON',
                                             data=content_data,
                                             query=query)

            error = video_json.get('error')
            if error:
                origin = error.get('origin')
                message = error.get('message') or error.get('user_message')
                extractor_msg = 'Unable to download video %s'
                if origin == 'NotAllowedForLocation':
                    self.raise_geo_restricted(message, self._GEO_COUNTRIES)
                elif origin == 'NoRedisValidData':
                    extractor_msg = 'Video %s does not exist'
                elif site == 353:
                    continue
                elif bundled:
                    raise ExtractorError(
                        'This feature does not work from bundled exe. Run youtube-dl from sources.',
                        expected=True)
                elif not pycryptodomex_found:
                    raise ExtractorError(
                        'pycryptodomex not found. Please install it.',
                        expected=True)
                elif message:
                    extractor_msg += ': ' + message
                raise ExtractorError(extractor_msg % video_id, expected=True)
            else:
                break

        result = video_json['result']
        title = result['title']

        quality = qualities(self._KNOWN_FORMATS)

        formats = []
        for f in result.get('files', []):
            f_url = f.get('url')
            content_format = f.get('content_format')
            if not f_url or '-MDRM-' in content_format or '-FPS-' in content_format:
                continue
            formats.append({
                'url': f_url,
                'format_id': content_format,
                'quality': quality(content_format),
                'filesize': int_or_none(f.get('size_in_bytes')),
            })
        self._sort_formats(formats)

        compilation = result.get('compilation')
        episode = title if compilation else None

        title = '%s - %s' % (compilation,
                             title) if compilation is not None else title

        thumbnails = [{
            'url': preview['url'],
            'id': preview.get('content_format'),
        } for preview in result.get('preview', []) if preview.get('url')]

        webpage = self._download_webpage(url, video_id)

        season = self._search_regex(
            r'<li[^>]+class="season active"[^>]*><a[^>]+>([^<]+)',
            webpage,
            'season',
            default=None)
        season_number = int_or_none(
            self._search_regex(
                r'<li[^>]+class="season active"[^>]*><a[^>]+data-season(?:-index)?="(\d+)"',
                webpage,
                'season number',
                default=None))

        episode_number = int_or_none(
            self._search_regex(
                r'[^>]+itemprop="episode"[^>]*>\s*<meta[^>]+itemprop="episodeNumber"[^>]+content="(\d+)',
                webpage,
                'episode number',
                default=None))

        description = self._og_search_description(
            webpage, default=None) or self._html_search_meta(
                'description', webpage, 'description', default=None)

        return {
            'id': video_id,
            'title': title,
            'series': compilation,
            'season': season,
            'season_number': season_number,
            'episode': episode,
            'episode_number': episode_number,
            'thumbnails': thumbnails,
            'description': description,
            'duration': int_or_none(result.get('duration')),
            'formats': formats,
        }
Пример #34
0
def _aes_cmac(key: bytes, msg: bytes) -> bytes:
    return CMAC.new(key, msg, ciphermod=AES).digest()
Пример #35
0
def getCMAC(msed):
    hash = hashlib.sha256(msed[:0x110]).digest()
    key = int16bytes(nkey_0x35mac)
    cipher = CMAC.new(key, ciphermod=AES)
    result = cipher.update(hash)
    return result.digest()
Пример #36
0
    def recv_msg3_verify(self, msg3: bytes) -> Tuple[dict, str]:
        pre_quote_len = 16 + 32 + 32 + 256

        io = BytesIO(msg3)

        mac = io.read(16)
        g_a = io.read(32 + 32)

        ps_sec_prop = io.read(256)
        version = io.read(2)
        sign_type = io.read(2)
        epid_group_id = io.read(4)
        qe_svn = io.read(2)
        pce_svn = io.read(2)
        xeid = io.read(4)
        basename = io.read(32)

        cpu_svn = io.read(16)  # Security Version of the CPU
        misc_select = io.read(4)  # Which fields defined in SSA.MISC
        _ = io.read(12)  #
        isv_ext_prod_id = io.read(16)  # ISV assigned Extended Product ID
        attributes = io.read(
            16)  # Any special Capabilities the Enclave possess
        mr_enclave = io.read(
            32)  # The value of the enclave's ENCLAVE measurement
        _ = io.read(32)  #
        mr_signer = io.read(
            32)  # The value of the enclave's SIGNER measurement
        _ = io.read(32)  #
        config_id = io.read(64)  # CONFIGID
        isv_prod_id = io.read(2)  # Product ID of the Enclave
        isv_svn = io.read(2)  # Security Version of the Enclave
        config_svn = io.read(2)  # CONFIGSVN
        reserved4 = io.read(42)  #
        isv_family_id = io.read(16)  # ISV assigned Family ID
        report_data = io.read(64)  # Data provided by the user

        signature_len = _load_int(io.read(4))
        signature = io.read(signature_len)

        # Verify that Ga in msg3 matches Ga in msg1.

        Ga_ser = _serialize_ec_point(self.Ga.pointQ)
        Gb_ser = _serialize_ec_point(self.Gb.pointQ)

        if Ga_ser != g_a:
            return None, "Step1: Peer PK doesn't match to the previous one"

        # Verify CMAC_SMK(M).

        m = msg3[16:pre_quote_len + 436 + signature_len]
        try:
            CMAC.new(self.smk, msg=m, ciphermod=AES).verify(mac)
        except ValueError:
            return None, "Step2: Invalid MAC"

        # Verify that the first 32-bytes of the report data match the SHA-256
        # digest of (Ga || Gb || VK), where || denotes concatenation.
        # VK is derived by performing an AES-128 CMAC over the following byte
        # sequence, using the KDK as the key:
        # 0x01 || "VK" || 0x00 || 0x80 || 0x00

        vk = _aes_cmac(key=self.kdk, msg=self.SEED_VK)
        keyhash = _sha256(Ga_ser, Gb_ser, vk).digest()

        if report_data[:32] != keyhash:
            if VERBOSE:
                print('>>> First 32-bytes of the report data')
                hexdump(report_data[:32])
                print('>>> SHA256(Ga||Gb||VK)')
                hexdump(keyhash)

            return None, "Step3: Key Hash doesn't match"

        if self.sim:
            attestation_report = {}
            advisory_url = ''
        else:

            # Verify the attestation evidence provided by the client.
            # 1. Extract the quote from msg3.
            quote = msg3[pre_quote_len:pre_quote_len + 436 + signature_len]

            if VERBOSE:
                print('>>> quote')
                hexdump(quote)

            # 2. Submit the quote to IAS, calling the API function to verify attestation evidence.
            request_id, report_signature, cert_chain, advisory_url, _, response = self.ias.verify_attestation_evidence(
                quote)
            # TODO: 3. Validate the signing certificate received in the report response.
            # TODO: 4. Validate the report signature using the signing certificate.

            # If the quote is successfully validated in Step 3, perform the following:
            # 1. Extract the attestation status for the enclave and, if provided, the PSE.
            attestation_report = json.loads(response)
            # TODO: 2. Examine the enclave identity (MRSIGNER), security version and product ID.
            # TODO: 3. Examine the debug attribute and ensure it is not set (in a production environment).
            # TODO: 4. Decide whether or not to trust the enclave and, if provided, the PSE.

            # Derive the session keys, SK and MK, that should be used to transmit
            # future messages between the client and server during the session.
            # The client can simply call sgx_ra_get_keys(), but the server must
            # derive them manually by performing an AES-128 CMAC over the following
            # byte sequences, using the KDK as the key:
            # MK: 0x01 || "MK" || 0x00 || 0x80 || 0x00
            # SK: 0x01 || "SK" || 0x00 || 0x80 || 0x00

        self.mk = _aes_cmac(key=self.kdk, msg=self.SEED_MK)
        self.sk = _aes_cmac(key=self.kdk, msg=self.SEED_SK)

        # Generate msg4 and send it to the client.

        return attestation_report, advisory_url