def test_invalid_decrypt_or_update_after_verify(self):
        cipher = ChaCha20_Poly1305.new(key=self.key_256, nonce=self.nonce_96)
        ct = cipher.encrypt(self.data_128)
        mac = cipher.digest()

        for method_name in "decrypt", "update":
            cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                           nonce=self.nonce_96)
            cipher.decrypt(ct)
            cipher.verify(mac)
            self.assertRaises(TypeError, getattr(cipher, method_name),
                              self.data_128)

            cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                           nonce=self.nonce_96)
            cipher.decrypt(ct)
            cipher.verify(mac)
            self.assertRaises(TypeError, getattr(cipher, method_name),
                              self.data_128)

            cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                           nonce=self.nonce_96)
            cipher.decrypt_and_verify(ct, mac)
            self.assertRaises(TypeError, getattr(cipher, method_name),
                              self.data_128)
    def test_invalid_decrypt_or_update_after_verify(self):
        cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                       nonce=self.nonce_96)
        ct = cipher.encrypt(self.data_128)
        mac = cipher.digest()

        for method_name in "decrypt", "update":
            cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                           nonce=self.nonce_96)
            cipher.decrypt(ct)
            cipher.verify(mac)
            self.assertRaises(TypeError, getattr(cipher, method_name),
                              self.data_128)

            cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                           nonce=self.nonce_96)
            cipher.decrypt(ct)
            cipher.verify(mac)
            self.assertRaises(TypeError, getattr(cipher, method_name),
                              self.data_128)

            cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                           nonce=self.nonce_96)
            cipher.decrypt_and_verify(ct, mac)
            self.assertRaises(TypeError, getattr(cipher, method_name),
                              self.data_128)
    def test_valid_init_verify(self):
        # Verify path INIT->VERIFY
        cipher = ChaCha20_Poly1305.new(key=self.key_256, nonce=self.nonce_96)
        mac = cipher.digest()

        cipher = ChaCha20_Poly1305.new(key=self.key_256, nonce=self.nonce_96)
        cipher.verify(mac)
    def test_hex_mac(self):
        cipher = ChaCha20_Poly1305.new(key=self.key_256, nonce=self.nonce_96)
        mac_hex = cipher.hexdigest()
        self.assertEqual(cipher.digest(), unhexlify(mac_hex))

        cipher = ChaCha20_Poly1305.new(key=self.key_256, nonce=self.nonce_96)
        cipher.hexverify(mac_hex)
    def test_loopback(self):
        cipher = ChaCha20_Poly1305.new(key=self.key_256, nonce=self.nonce_96)
        pt = get_tag_random("plaintext", 16 * 100)
        ct = cipher.encrypt(pt)

        cipher = ChaCha20_Poly1305.new(key=self.key_256, nonce=self.nonce_96)
        pt2 = cipher.decrypt(ct)
        self.assertEqual(pt, pt2)
    def test_either_encrypt_or_decrypt(self):
        cipher = ChaCha20_Poly1305.new(key=self.key_256, nonce=self.nonce_96)
        cipher.encrypt(b"")
        self.assertRaises(TypeError, cipher.decrypt, b"")

        cipher = ChaCha20_Poly1305.new(key=self.key_256, nonce=self.nonce_96)
        cipher.decrypt(b"")
        self.assertRaises(TypeError, cipher.encrypt, b"")
    def test_data_must_be_bytes(self):
        cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                       nonce=self.nonce_96)
        self.assertRaises(TypeError, cipher.encrypt, u'test1234567890-*')

        cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                       nonce=self.nonce_96)
        self.assertRaises(TypeError, cipher.decrypt, u'test1234567890-*')
    def test_nonce_attribute(self):
        cipher = ChaCha20_Poly1305.new(key=self.key_256, nonce=self.nonce_96)
        self.assertEqual(cipher.nonce, self.nonce_96)

        # By default, a 12 bytes long nonce is randomly generated
        nonce1 = ChaCha20_Poly1305.new(key=self.key_256).nonce
        nonce2 = ChaCha20_Poly1305.new(key=self.key_256).nonce
        self.assertEqual(len(nonce1), 12)
        self.assertNotEqual(nonce1, nonce2)
    def test_hex_mac(self):
        cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                       nonce=self.nonce_96)
        mac_hex = cipher.hexdigest()
        self.assertEqual(cipher.digest(), unhexlify(mac_hex))

        cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                       nonce=self.nonce_96)
        cipher.hexverify(mac_hex)
    def test_valid_init_verify(self):
        # Verify path INIT->VERIFY
        cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                       nonce=self.nonce_96)
        mac = cipher.digest()

        cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                       nonce=self.nonce_96)
        cipher.verify(mac)
    def test_invalid_mac(self):
        from Cryptodome.Util.strxor import strxor_c
        cipher = ChaCha20_Poly1305.new(key=self.key_256, nonce=self.nonce_96)
        ct, mac = cipher.encrypt_and_digest(self.data_128)

        invalid_mac = strxor_c(mac, 0x01)

        cipher = ChaCha20_Poly1305.new(key=self.key_256, nonce=self.nonce_96)
        self.assertRaises(ValueError, cipher.decrypt_and_verify, ct,
                          invalid_mac)
    def test_loopback(self):
        cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                       nonce=self.nonce_96)
        pt = get_tag_random("plaintext", 16 * 100)
        ct = cipher.encrypt(pt)

        cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                       nonce=self.nonce_96)
        pt2 = cipher.decrypt(ct)
        self.assertEqual(pt, pt2)
    def test_either_encrypt_or_decrypt(self):
        cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                       nonce=self.nonce_96)
        cipher.encrypt(b"")
        self.assertRaises(TypeError, cipher.decrypt, b"")

        cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                       nonce=self.nonce_96)
        cipher.decrypt(b"")
        self.assertRaises(TypeError, cipher.encrypt, b"")
    def test_nonce_attribute(self):
        cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                       nonce=self.nonce_96)
        self.assertEqual(cipher.nonce, self.nonce_96)

        # By default, a 12 bytes long nonce is randomly generated
        nonce1 = ChaCha20_Poly1305.new(key=self.key_256).nonce
        nonce2 = ChaCha20_Poly1305.new(key=self.key_256).nonce
        self.assertEqual(len(nonce1), 12)
        self.assertNotEqual(nonce1, nonce2)
    def test_valid_init_encrypt_decrypt_digest_verify(self):
        # No authenticated data, fixed plaintext
        # Verify path INIT->ENCRYPT->DIGEST
        cipher = ChaCha20_Poly1305.new(key=self.key_256, nonce=self.nonce_96)
        ct = cipher.encrypt(self.data_128)
        mac = cipher.digest()

        # Verify path INIT->DECRYPT->VERIFY
        cipher = ChaCha20_Poly1305.new(key=self.key_256, nonce=self.nonce_96)
        cipher.decrypt(ct)
        cipher.verify(mac)
    def test_valid_encrypt_and_digest_decrypt_and_verify(self):
        # encrypt_and_digest
        cipher = ChaCha20_Poly1305.new(key=self.key_256, nonce=self.nonce_96)
        cipher.update(self.data_128)
        ct, mac = cipher.encrypt_and_digest(self.data_128)

        # decrypt_and_verify
        cipher = ChaCha20_Poly1305.new(key=self.key_256, nonce=self.nonce_96)
        cipher.update(self.data_128)
        pt = cipher.decrypt_and_verify(ct, mac)
        self.assertEqual(self.data_128, pt)
    def test_valid_init_update_digest_verify(self):
        # No plaintext, fixed authenticated data
        # Verify path INIT->UPDATE->DIGEST
        cipher = ChaCha20_Poly1305.new(key=self.key_256, nonce=self.nonce_96)
        cipher.update(self.data_128)
        mac = cipher.digest()

        # Verify path INIT->UPDATE->VERIFY
        cipher = ChaCha20_Poly1305.new(key=self.key_256, nonce=self.nonce_96)
        cipher.update(self.data_128)
        cipher.verify(mac)
    def test_invalid_mac(self):
        from Cryptodome.Util.strxor import strxor_c
        cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                       nonce=self.nonce_96)
        ct, mac = cipher.encrypt_and_digest(self.data_128)

        invalid_mac = strxor_c(mac, 0x01)

        cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                       nonce=self.nonce_96)
        self.assertRaises(ValueError, cipher.decrypt_and_verify, ct,
                          invalid_mac)
    def test_invalid_encrypt_or_update_after_digest(self):
        for method_name in "encrypt", "update":
            cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                           nonce=self.nonce_96)
            cipher.encrypt(self.data_128)
            cipher.digest()
            self.assertRaises(TypeError, getattr(cipher, method_name),
                              self.data_128)

            cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                           nonce=self.nonce_96)
            cipher.encrypt_and_digest(self.data_128)
    def test_invalid_encrypt_or_update_after_digest(self):
        for method_name in "encrypt", "update":
            cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                           nonce=self.nonce_96)
            cipher.encrypt(self.data_128)
            cipher.digest()
            self.assertRaises(TypeError, getattr(cipher, method_name),
                              self.data_128)

            cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                           nonce=self.nonce_96)
            cipher.encrypt_and_digest(self.data_128)
    def test_valid_multiple_digest_or_verify(self):
        # Multiple calls to digest
        cipher = ChaCha20_Poly1305.new(key=self.key_256, nonce=self.nonce_96)
        cipher.update(self.data_128)
        first_mac = cipher.digest()
        for x in range(4):
            self.assertEqual(first_mac, cipher.digest())

        # Multiple calls to verify
        cipher = ChaCha20_Poly1305.new(key=self.key_256, nonce=self.nonce_96)
        cipher.update(self.data_128)
        for x in range(5):
            cipher.verify(first_mac)
    def test_valid_init_encrypt_decrypt_digest_verify(self):
        # No authenticated data, fixed plaintext
        # Verify path INIT->ENCRYPT->DIGEST
        cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                       nonce=self.nonce_96)
        ct = cipher.encrypt(self.data_128)
        mac = cipher.digest()

        # Verify path INIT->DECRYPT->VERIFY
        cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                       nonce=self.nonce_96)
        cipher.decrypt(ct)
        cipher.verify(mac)
    def test_valid_encrypt_and_digest_decrypt_and_verify(self):
        # encrypt_and_digest
        cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                       nonce=self.nonce_96)
        cipher.update(self.data_128)
        ct, mac = cipher.encrypt_and_digest(self.data_128)

        # decrypt_and_verify
        cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                       nonce=self.nonce_96)
        cipher.update(self.data_128)
        pt = cipher.decrypt_and_verify(ct, mac)
        self.assertEqual(self.data_128, pt)
    def test_valid_init_update_digest_verify(self):
        # No plaintext, fixed authenticated data
        # Verify path INIT->UPDATE->DIGEST
        cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                       nonce=self.nonce_96)
        cipher.update(self.data_128)
        mac = cipher.digest()

        # Verify path INIT->UPDATE->VERIFY
        cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                       nonce=self.nonce_96)
        cipher.update(self.data_128)
        cipher.verify(mac)
    def runTest(self):
        for assoc_data, pt, ct, mac, key, nonce in self.test_vectors:
            # Encrypt
            cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
            cipher.update(assoc_data)
            ct2, mac2 = cipher.encrypt_and_digest(pt)
            self.assertEqual(ct, ct2)
            self.assertEqual(mac, mac2)

            # Decrypt
            cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
            cipher.update(assoc_data)
            pt2 = cipher.decrypt_and_verify(ct, mac)
            self.assertEqual(pt, pt2)
    def runTest(self):
        for assoc_data, pt, ct, mac, key, nonce in self.test_vectors:
            # Encrypt
            cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
            cipher.update(assoc_data)
            ct2, mac2 = cipher.encrypt_and_digest(pt)
            self.assertEqual(ct, ct2)
            self.assertEqual(mac, mac2)

            # Decrypt
            cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
            cipher.update(assoc_data)
            pt2 = cipher.decrypt_and_verify(ct, mac)
            self.assertEqual(pt, pt2)
    def test_valid_multiple_digest_or_verify(self):
        # Multiple calls to digest
        cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                       nonce=self.nonce_96)
        cipher.update(self.data_128)
        first_mac = cipher.digest()
        for x in range(4):
            self.assertEqual(first_mac, cipher.digest())

        # Multiple calls to verify
        cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                       nonce=self.nonce_96)
        cipher.update(self.data_128)
        for x in range(5):
            cipher.verify(first_mac)
Beispiel #28
0
def chacha20_poly1305_decrypt(*,
                              key: bytes,
                              nonce: bytes,
                              associated_data: bytes = None,
                              data: bytes) -> bytes:
    assert isinstance(key, (bytes, bytearray))
    assert isinstance(nonce, (bytes, bytearray))
    assert isinstance(associated_data, (bytes, bytearray, type(None)))
    assert isinstance(data, (bytes, bytearray))
    assert len(key) == 32, f"unexpected key size: {len(key)} (expected: 32)"
    assert len(
        nonce) == 12, f"unexpected nonce size: {len(nonce)} (expected: 12)"
    if HAS_CRYPTODOME:
        cipher = CD_ChaCha20_Poly1305.new(key=key, nonce=nonce)
        if associated_data is not None:
            cipher.update(associated_data)
        # raises ValueError if not valid (e.g. incorrect MAC)
        return cipher.decrypt_and_verify(ciphertext=data[:-16],
                                         received_mac_tag=data[-16:])
    if HAS_CRYPTOGRAPHY:
        a = CG_aead.ChaCha20Poly1305(key)
        try:
            return a.decrypt(nonce, data, associated_data)
        except cryptography.exceptions.InvalidTag as e:
            raise ValueError("invalid tag") from e
    raise Exception("no chacha20 backend found")
def aead_encrypt(key: bytes, nonce: int, associated_data: bytes,
                 data: bytes) -> bytes:
    nonce_bytes = get_nonce_bytes(nonce)
    cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce_bytes)
    cipher.update(associated_data)
    ciphertext, mac = cipher.encrypt_and_digest(plaintext=data)
    return ciphertext + mac
Beispiel #30
0
    def receiveM2(self, data):
        logger.info("Receive M2")

        pvDict = OPACK.decode(data)
        tlv = TLV8Box.decodeFromData(pvDict["pd"]).toDict()
        searching_device_pub_key = x25519.X25519PublicKey.from_public_bytes(
            bytes(tlv[0x03]))
        self.shared_secret = self.session_keys.private.exchange(
            searching_device_pub_key)

        hkdf_inst = hkdf.Hkdf("Pair-Verify-Encrypt-Salt".encode(),
                              self.shared_secret,
                              hash=hashlib.sha512)
        key = hkdf_inst.expand("Pair-Verify-Encrypt-Info".encode(), 32)

        encryptedData = bytes(tlv[0x05])[:-16]
        authKey = bytes(tlv[0x05])[-16:]
        nonce = "PV-Msg02".encode()

        cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
        plainData = cipher.decrypt_and_verify(encryptedData, authKey)
        plainTLV = TLV8Box.decodeFromData(plainData).toDict()

        # plainTLV contains authentication data:
        # {
        #    9: Signature over public keys of grantor and requestor
        #   10: Apple ID certificate (NSDataCompressed)
        #   20: Apple ID validation record (NSDataCompressed)
        # }
        logger.debug(f"Identity TLV: {plainTLV}")

        self.sendM3()
Beispiel #31
0
    def test_bytearray(self):

        # Encrypt
        key_ba = bytearray(self.key_256)
        nonce_ba = bytearray(self.nonce_96)
        header_ba = bytearray(self.data_128)
        data_ba = bytearray(self.data_128)

        cipher1 = ChaCha20_Poly1305.new(key=self.key_256,
                                        nonce=self.nonce_96)
        cipher1.update(self.data_128)
        ct = cipher1.encrypt(self.data_128)
        tag = cipher1.digest()

        cipher2 = ChaCha20_Poly1305.new(key=self.key_256,
                                        nonce=self.nonce_96)
        key_ba[:3] = b'\xFF\xFF\xFF'
        nonce_ba[:3] = b'\xFF\xFF\xFF'
        cipher2.update(header_ba)
        header_ba[:3] = b'\xFF\xFF\xFF'
        ct_test = cipher2.encrypt(data_ba)
        data_ba[:3] = b'\x99\x99\x99'
        tag_test = cipher2.digest()

        self.assertEqual(ct, ct_test)
        self.assertEqual(tag, tag_test)
        self.assertEqual(cipher1.nonce, cipher2.nonce)

        # Decrypt
        key_ba = bytearray(self.key_256)
        nonce_ba = bytearray(self.nonce_96)
        header_ba = bytearray(self.data_128)
        ct_ba = bytearray(ct)
        tag_ba = bytearray(tag)
        del data_ba

        cipher3 = ChaCha20_Poly1305.new(key=self.key_256,
                                        nonce=self.nonce_96)
        key_ba[:3] = b'\xFF\xFF\xFF'
        nonce_ba[:3] = b'\xFF\xFF\xFF'
        cipher3.update(header_ba)
        header_ba[:3] = b'\xFF\xFF\xFF'
        pt_test = cipher3.decrypt(ct_ba)
        ct_ba[:3] = b'\xFF\xFF\xFF'
        cipher3.verify(tag_ba)

        self.assertEqual(pt_test, self.data_128)
Beispiel #32
0
    def test_memoryview(self):

        # Encrypt
        key_mv = memoryview(bytearray(self.key_256))
        nonce_mv = memoryview(bytearray(self.nonce_96))
        header_mv = memoryview(bytearray(self.data_128))
        data_mv = memoryview(bytearray(self.data_128))

        cipher1 = ChaCha20_Poly1305.new(key=self.key_256,
                                        nonce=self.nonce_96)
        cipher1.update(self.data_128)
        ct = cipher1.encrypt(self.data_128)
        tag = cipher1.digest()

        cipher2 = ChaCha20_Poly1305.new(key=self.key_256,
                                        nonce=self.nonce_96)
        key_mv[:3] = b'\xFF\xFF\xFF'
        nonce_mv[:3] = b'\xFF\xFF\xFF'
        cipher2.update(header_mv)
        header_mv[:3] = b'\xFF\xFF\xFF'
        ct_test = cipher2.encrypt(data_mv)
        data_mv[:3] = b'\x99\x99\x99'
        tag_test = cipher2.digest()

        self.assertEqual(ct, ct_test)
        self.assertEqual(tag, tag_test)
        self.assertEqual(cipher1.nonce, cipher2.nonce)

        # Decrypt
        key_mv = memoryview(bytearray(self.key_256))
        nonce_mv = memoryview(bytearray(self.nonce_96))
        header_mv = memoryview(bytearray(self.data_128))
        ct_mv = memoryview(bytearray(ct))
        tag_mv = memoryview(bytearray(tag))
        del data_mv

        cipher3 = ChaCha20_Poly1305.new(key=self.key_256,
                                        nonce=self.nonce_96)
        key_mv[:3] = b'\xFF\xFF\xFF'
        nonce_mv[:3] = b'\xFF\xFF\xFF'
        cipher3.update(header_mv)
        header_mv[:3] = b'\xFF\xFF\xFF'
        pt_test = cipher3.decrypt(ct_mv)
        ct_mv[:3] = b'\x99\x99\x99'
        cipher3.verify(tag_mv)

        self.assertEqual(pt_test, self.data_128)
Beispiel #33
0
 def test_corrupt_decrypt(self, tv):
     self._id = "Wycheproof Corrupt Decrypt ChaCha20-Poly1305 Test #" + str(tv.id)
     if len(tv.iv) == 0 or len(tv.ct) < 1:
         return
     cipher = ChaCha20_Poly1305.new(key=tv.key, nonce=tv.iv)
     cipher.update(tv.aad)
     ct_corrupt = strxor(tv.ct, b"\x00" * (len(tv.ct) - 1) + b"\x01")
     self.assertRaises(ValueError, cipher.decrypt_and_verify, ct_corrupt, tv.tag)
    def runTest(self):
        # Encrypt/Decrypt data and test output parameter

        key = b'4' * 32
        nonce = b'5' * 12
        cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)

        pt = b'5' * 16
        ct = cipher.encrypt(pt)

        output = bytearray(16)
        cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
        res = cipher.encrypt(pt, output=output)
        self.assertEqual(ct, output)
        self.assertEqual(res, None)

        cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
        res = cipher.decrypt(ct, output=output)
        self.assertEqual(pt, output)
        self.assertEqual(res, None)

        import sys
        if sys.version[:3] != '2.6':
            output = memoryview(bytearray(16))
            cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
            cipher.encrypt(pt, output=output)
            self.assertEqual(ct, output)

            cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
            cipher.decrypt(ct, output=output)
            self.assertEqual(pt, output)

        cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
        self.assertRaises(TypeError, cipher.encrypt, pt, output=b'0' * 16)

        cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
        self.assertRaises(TypeError, cipher.decrypt, ct, output=b'0' * 16)

        shorter_output = bytearray(7)

        cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
        self.assertRaises(ValueError,
                          cipher.encrypt,
                          pt,
                          output=shorter_output)

        cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
        self.assertRaises(ValueError,
                          cipher.decrypt,
                          ct,
                          output=shorter_output)
def aead_decrypt(key: bytes, nonce: int, associated_data: bytes,
                 data: bytes) -> bytes:
    nonce_bytes = get_nonce_bytes(nonce)
    cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce_bytes)
    cipher.update(associated_data)
    # raises ValueError if not valid (e.g. incorrect MAC)
    return cipher.decrypt_and_verify(ciphertext=data[:-16],
                                     received_mac_tag=data[-16:])
    def test_message_chunks(self):
        # Validate that both associated data and plaintext/ciphertext
        # can be broken up in chunks of arbitrary length

        auth_data = get_tag_random("authenticated data", 127)
        plaintext = get_tag_random("plaintext", 127)

        cipher = ChaCha20_Poly1305.new(key=self.key_256, nonce=self.nonce_96)
        cipher.update(auth_data)
        ciphertext, ref_mac = cipher.encrypt_and_digest(plaintext)

        def break_up(data, chunk_length):
            return [
                data[i:i + chunk_length]
                for i in range(0, len(data), chunk_length)
            ]

        # Encryption
        for chunk_length in 1, 2, 3, 7, 10, 13, 16, 40, 80, 128:

            cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                           nonce=self.nonce_96)

            for chunk in break_up(auth_data, chunk_length):
                cipher.update(chunk)
            pt2 = b""
            for chunk in break_up(ciphertext, chunk_length):
                pt2 += cipher.decrypt(chunk)
            self.assertEqual(plaintext, pt2)
            cipher.verify(ref_mac)

        # Decryption
        for chunk_length in 1, 2, 3, 7, 10, 13, 16, 40, 80, 128:

            cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                           nonce=self.nonce_96)

            for chunk in break_up(auth_data, chunk_length):
                cipher.update(chunk)
            ct2 = b""
            for chunk in break_up(plaintext, chunk_length):
                ct2 += cipher.encrypt(chunk)
            self.assertEqual(ciphertext, ct2)
            self.assertEquals(cipher.digest(), ref_mac)
    def test_message_chunks(self):
        # Validate that both associated data and plaintext/ciphertext
        # can be broken up in chunks of arbitrary length

        auth_data = get_tag_random("authenticated data", 127)
        plaintext = get_tag_random("plaintext", 127)

        cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                       nonce=self.nonce_96)
        cipher.update(auth_data)
        ciphertext, ref_mac = cipher.encrypt_and_digest(plaintext)

        def break_up(data, chunk_length):
            return [data[i:i+chunk_length] for i in range(0, len(data),
                    chunk_length)]

        # Encryption
        for chunk_length in 1, 2, 3, 7, 10, 13, 16, 40, 80, 128:

            cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                           nonce=self.nonce_96)

            for chunk in break_up(auth_data, chunk_length):
                cipher.update(chunk)
            pt2 = b""
            for chunk in break_up(ciphertext, chunk_length):
                pt2 += cipher.decrypt(chunk)
            self.assertEqual(plaintext, pt2)
            cipher.verify(ref_mac)

        # Decryption
        for chunk_length in 1, 2, 3, 7, 10, 13, 16, 40, 80, 128:

            cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                           nonce=self.nonce_96)

            for chunk in break_up(auth_data, chunk_length):
                cipher.update(chunk)
            ct2 = b""
            for chunk in break_up(plaintext, chunk_length):
                ct2 += cipher.encrypt(chunk)
            self.assertEqual(ciphertext, ct2)
            self.assertEquals(cipher.digest(), ref_mac)
 def test_invalid_mixing_encrypt_decrypt(self):
     # Once per method, with or without assoc. data
     for method1_name, method2_name in (("encrypt", "decrypt"),
                                        ("decrypt", "encrypt")):
         for assoc_data_present in (True, False):
             cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                            nonce=self.nonce_96)
             if assoc_data_present:
                 cipher.update(self.data_128)
             getattr(cipher, method1_name)(self.data_128)
             self.assertRaises(TypeError, getattr(cipher, method2_name),
                               self.data_128)
Beispiel #39
0
def can_decrypt(key, package):
    try:        
        jv = decode_package(package)

        cipher = ChaCha20_Poly1305.new(key=key, nonce=jv['nonce'])
        cipher.update(jv['header'])
        plaintext = cipher.decrypt_and_verify(jv['ciphertext'], jv['tag'])
        #print("The message was: " + str(plaintext))
        return True, plaintext
    except ValueError:
        #print("Incorrect decryption")
        return False, None
 def test_invalid_mixing_encrypt_decrypt(self):
     # Once per method, with or without assoc. data
     for method1_name, method2_name in (("encrypt", "decrypt"),
                                        ("decrypt", "encrypt")):
         for assoc_data_present in (True, False):
             cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                            nonce=self.nonce_96)
             if assoc_data_present:
                 cipher.update(self.data_128)
             getattr(cipher, method1_name)(self.data_128)
             self.assertRaises(TypeError, getattr(cipher, method2_name),
                               self.data_128)
Beispiel #41
0
def pyCrypto():
    import Cryptodome
    from Cryptodome.Cipher import AES, ChaCha20, DES, DES3, ARC2, ARC4, Blowfish, CAST, PKCS1_v1_5, PKCS1_OAEP, ChaCha20_Poly1305, Salsa20
    from Cryptodome.PublicKey import ElGamal

    Cryptodome.Cipher.AES.new()  # Noncompliant
    Cryptodome.Other.AES.new()  # OK
    AES.new(key=key)  # Noncompliant
    ChaCha20.new(key=key)  # Noncompliant
    DES.new(key=key)  # Noncompliant
    DES3.new(key=key)  # Noncompliant
    ARC2.new(key=key)  # Noncompliant
    ARC4.new(key=key)  # Noncompliant
    Blowfish.new(key=key)  # Noncompliant
    CAST.new(key=key)  # Noncompliant
    PKCS1_v1_5.new(key=key)  # Noncompliant
    PKCS1_OAEP.new(key=key)  # Noncompliant
    ChaCha20_Poly1305.new(key=key)  # Noncompliant
    Salsa20.new(key=key)  # Noncompliant

    ElGamal.generate(key_size)  # Noncompliant
    def runTest(self):
        # Encrypt/Decrypt data and test output parameter

        key = b'4' * 32
        nonce = b'5' * 12
        cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)

        pt = b'5' * 16
        ct = cipher.encrypt(pt)

        output = bytearray(16)
        cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
        res = cipher.encrypt(pt, output=output)
        self.assertEqual(ct, output)
        self.assertEqual(res, None)
        
        cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
        res = cipher.decrypt(ct, output=output)
        self.assertEqual(pt, output)
        self.assertEqual(res, None)

        import sys
        if sys.version[:3] != '2.6':
            output = memoryview(bytearray(16))
            cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
            cipher.encrypt(pt, output=output)
            self.assertEqual(ct, output)
        
            cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
            cipher.decrypt(ct, output=output)
            self.assertEqual(pt, output)

        cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
        self.assertRaises(TypeError, cipher.encrypt, pt, output=b'0'*16)
        
        cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
        self.assertRaises(TypeError, cipher.decrypt, ct, output=b'0'*16)

        shorter_output = bytearray(7)
        
        cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
        self.assertRaises(ValueError, cipher.encrypt, pt, output=shorter_output)
        
        cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
        self.assertRaises(ValueError, cipher.decrypt, ct, output=shorter_output)
 def test_valid_multiple_encrypt_or_decrypt(self):
     for method_name in "encrypt", "decrypt":
         for auth_data in (None, b"333", self.data_128,
                           self.data_128 + b"3"):
             cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                            nonce=self.nonce_96)
             if auth_data is not None:
                 cipher.update(auth_data)
             method = getattr(cipher, method_name)
             method(self.data_128)
             method(self.data_128)
             method(self.data_128)
             method(self.data_128)
 def test_valid_multiple_encrypt_or_decrypt(self):
     for method_name in "encrypt", "decrypt":
         for auth_data in (None, b"333", self.data_128,
                           self.data_128 + b"3"):
             cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                            nonce=self.nonce_96)
             if auth_data is not None:
                 cipher.update(auth_data)
             method = getattr(cipher, method_name)
             method(self.data_128)
             method(self.data_128)
             method(self.data_128)
             method(self.data_128)
Beispiel #45
0
    def encrypt(self, msg, aad, iv, key):
        """Content Encryption with AEAD_XCHACHA20_POLY1305

        :param msg: text to be encrypt in bytes
        :param aad: additional authenticated data in bytes
        :param iv: initialization vector in bytes
        :param key: encrypted key in bytes
        :return: (ciphertext, tag)
        """
        self.check_iv(iv)
        chacha = Cryptodome_ChaCha20_Poly1305.new(key=key, nonce=iv)
        chacha.update(aad)
        ciphertext, tag = chacha.encrypt_and_digest(msg)
        return ciphertext, tag
Beispiel #46
0
    def decrypt(self, ciphertext, aad, iv, tag, key):
        """Content Decryption with AEAD_XCHACHA20_POLY1305

        :param ciphertext: ciphertext in bytes
        :param aad: additional authenticated data in bytes
        :param iv: initialization vector in bytes
        :param tag: authentication tag in bytes
        :param key: encrypted key in bytes
        :return: message
        """
        self.check_iv(iv)
        chacha = Cryptodome_ChaCha20_Poly1305.new(key=key, nonce=iv)
        chacha.update(aad)
        return chacha.decrypt_and_verify(ciphertext, tag)
Beispiel #47
0
def chacha20_poly1305_encrypt(*, key: bytes, nonce: bytes, associated_data: bytes, data: bytes) -> bytes:
    assert isinstance(key, (bytes, bytearray))
    assert isinstance(nonce, (bytes, bytearray))
    assert isinstance(associated_data, (bytes, bytearray))
    assert isinstance(data, (bytes, bytearray))
    if HAS_CRYPTODOME:
        cipher = CD_ChaCha20_Poly1305.new(key=key, nonce=nonce)
        cipher.update(associated_data)
        ciphertext, mac = cipher.encrypt_and_digest(plaintext=data)
        return ciphertext + mac
    if HAS_CRYPTOGRAPHY:
        a = CG_aead.ChaCha20Poly1305(key)
        return a.encrypt(nonce, data, associated_data)
    raise Exception("no chacha20 backend found")
    def test_encrypt(self, tv):
        self._id = "Wycheproof Encrypt ChaCha20-Poly1305 Test #" + str(tv.id)
        
        try:
            cipher = ChaCha20_Poly1305.new(key=tv.key, nonce=tv.iv)
        except ValueError as e:
            assert len(tv.iv) not in (8, 12) and "Nonce must be" in str(e)
            return

        cipher.update(tv.aad)
        ct, tag = cipher.encrypt_and_digest(tv.msg)
        if tv.valid:
            self.assertEqual(ct, tv.ct)
            self.assertEqual(tag, tv.tag)
            self.warn(tv)
    def test_decrypt(self, tv):
        self._id = "Wycheproof Decrypt ChaCha20-Poly1305 Test #" + str(tv.id)
        
        try:
            cipher = ChaCha20_Poly1305.new(key=tv.key, nonce=tv.iv)
        except ValueError as e:
            assert len(tv.iv) not in (8, 12) and "Nonce must be" in str(e)
            return

        cipher.update(tv.aad)
        try:
            pt = cipher.decrypt_and_verify(tv.ct, tv.tag)
        except ValueError:
            assert not tv.valid
        else:
            assert tv.valid
            self.assertEqual(pt, tv.msg)
            self.warn(tv)
    def test_nonce(self):
        # Nonce can only be 8 or 12 bytes
        cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                       nonce=b'H' * 8)
        self.assertEqual(len(cipher.nonce), 8)
        cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                       nonce=b'H' * 12)
        self.assertEqual(len(cipher.nonce), 12)

        # If not passed, the nonce is created randomly
        cipher = ChaCha20_Poly1305.new(key=self.key_256)
        nonce1 = cipher.nonce
        cipher = ChaCha20_Poly1305.new(key=self.key_256)
        nonce2 = cipher.nonce
        self.assertEqual(len(nonce1), 12)
        self.assertNotEqual(nonce1, nonce2)

        cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                       nonce=self.nonce_96)
        ct = cipher.encrypt(self.data_128)

        cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                       nonce=self.nonce_96)
        self.assertEquals(ct, cipher.encrypt(self.data_128))
 def test_block_size(self):
     # Not based on block ciphers
     cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                    nonce=self.nonce_96)
     self.failIf(hasattr(cipher, 'block_size'))
 def test_null_encryption_decryption(self):
     for func in "encrypt", "decrypt":
         cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                        nonce=self.nonce_96)
         result = getattr(cipher, func)(b"")
         self.assertEqual(result, b"")
 def test_mac_len(self):
     cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                    nonce=self.nonce_96)
     _, mac = cipher.encrypt_and_digest(self.data_128)
     self.assertEqual(len(mac), 16)
 def test_valid_init_digest(self):
     # Verify path INIT->DIGEST
     cipher = ChaCha20_Poly1305.new(key=self.key_256,
                                    nonce=self.nonce_96)
     cipher.digest()