Exemplo n.º 1
0
def test_challenge18():
    key = b'YELLOW SUBMARINE'
    nonce = urandom(16)

    be_cipher = challenge18.AESCTR(key, nonce, byteorder='big')
    reference = Cipher(AES(key), CTR(nonce), default_backend())
    check_cipher_interoperability(
        be_cipher,
        reference,
        b'welcome to the wonderful world of cryptography',
    )

    # The ciphertext provided by the exercise prompt was produced using the
    # increment function in little endian mode (which seems to not be the
    # default)
    le_cipher = challenge18.AESCTR(
        key,
        bytes(16),
        byteorder='little',
    )
    ciphertext = b64decode(
        b'L77na/nrFsKvynd6HzOoG7GHTLXsTVu9qvY/2syLXzhPweyyMTJULu/6/kXX0KSvoOLSFQ=='
    )
    plaintext = le_cipher.crypt(ciphertext)
    assert plaintext == b"Yo, VIP Let's kick it Ice, Ice, baby Ice, Ice, baby "
Exemplo n.º 2
0
    def tape_gen(self, data):
        """Return a bit string, generated from the given data string"""

        # FIXME
        data = str(data).encode()

        # Derive a key from data
        hmac_obj = hmac.HMAC(self.key, digestmod=hashlib.sha256)
        hmac_obj.update(data)
        assert hmac_obj.digest_size == 32
        digest = hmac_obj.digest()

        # Use AES in the CTR mode to generate a pseudo-random bit string
        aes_algo = algorithms.AES(digest)
        aes_cipher = Cipher(aes_algo,
                            mode=CTR(b'\x00' * 16),
                            backend=default_backend())
        encryptor = aes_cipher.encryptor()

        while True:
            encrypted_bytes = encryptor.update(b'\x00' * 16)
            # Convert the data to a list of bits
            bits = util.str_to_bitstring(encrypted_bytes)
            for bit in bits:
                yield bit
Exemplo n.º 3
0
def decrypt_ctr(key, iv, aad, data):
    """
    verify HMAC and decrypt using CTR mode

    key: 16 byte key
    iv: 12 bytes nonce. 4 zero bytes are appended to create the 16 byte
        nonce used for CTR mode
    aad: bytes. additional unencrypted data to include in the signature
    data: bytes. plaint text to encrypt

    """
    nonce = iv + b'\x00\x00\x00\x00'
    ct = data[:-16]
    tag = data[-16:]

    h = HMAC(key, SHA256(), backend=default_backend())
    h.update(aad)
    h.update(ct)
    act = h.finalize()[:16]

    if not bytes_eq(tag, act):
        raise ValueError()

    decryptor = Cipher(AES(key), CTR(nonce),
                       backend=default_backend()).decryptor()

    return decryptor.update(ct) + decryptor.finalize()
Exemplo n.º 4
0
    def decrypt(self):
        pad = self.enc_pad(self.enckey, self.pad_iv)

        aes = Cipher(AES(self.enckey), CTR(self.iv),
                     default_backend()).decryptor()
        self.fwd = pad + aes.update(self.onion[:self.fwd_end])
        self.msg = aes.update(self.onion[self.fwd_end:self.msg_end])
Exemplo n.º 5
0
def encrypt_ctr(key, iv, aad, data):
    """
    encrypt using CTR then sign with an HMAC

    Note: this implementation is similar to AES-CCM, but is slower.
    The implementation is left in only for benchmarking purposes.

    Note: in theory this should parallize well, however in practice
    it is about 2x slower than GCM mode. The HMAC is not the bottleneck

    key: 16 byte key
    iv: 12 bytes nonce. 4 zero bytes are appended to create the 16 byte
        nonce used for CTR mode
    aad: bytes. additional unencrypted data to include in the signature
    data: bytes. plaint text to encrypt

    future work: require key to be 32 bytes, and then use
        16 bytes for the HMAC and the other 16 bytes for CTR mode
    """
    nonce = iv + b'\x00\x00\x00\x00'

    encryptor = Cipher(AES(key), CTR(nonce),
                       backend=default_backend()).encryptor()

    ct = encryptor.update(data) + encryptor.finalize()

    h = HMAC(key, SHA256(), backend=default_backend())
    h.update(aad)
    h.update(ct)
    tag = h.finalize()[:16]

    return ct + tag
Exemplo n.º 6
0
 def initialize_cipher(self) -> None:
     """Creates the cipher-related objects needed for AES-CTR
     encryption and decryption.
     """
     self.cipher = Cipher(AES(self.key), CTR(self.iv), default_backend())
     self.encryptor = self.cipher.encryptor()
     self.decryptor = self.cipher.decryptor()
Exemplo n.º 7
0
def cryptography_aes_ctr(key, index):
    from cryptography.hazmat.backends import default_backend
    from cryptography.hazmat.primitives.ciphers import Cipher
    from cryptography.hazmat.primitives.ciphers.algorithms import AES
    from cryptography.hazmat.primitives.ciphers.modes import CTR
    from struct import pack
    ctr = b'\0' * 8 + pack('>Q', index)
    cipher = Cipher(AES(key), CTR(ctr), default_backend())
    e = cipher.encryptor()
    e.encrypt = e.update
    return e
Exemplo n.º 8
0
def decrypt_and_unpack(
    input_file: IOIter,
    output_file: IOIter,
    key_pair: Optional[bytes],
    options: OptionsDict,
) -> None:
    """ Read encrypted, GZIPed data from an open file descriptor, and write the decoded data to
    another file descriptor; verify the HMAC of the encrypted data to ensure integrity

    :param input_file: an IOIter object to read compressed ciphertext from
    :param output_file: an IOIter object to write plaintext data to
    """
    key, nonce, signature = (
        key_pair[:AES_KEY_SIZE],
        key_pair[AES_KEY_SIZE:AES_KEY_SIZE + AES_BLOCK_SIZE],
        key_pair[AES_KEY_SIZE + AES_BLOCK_SIZE:]
    ) if key_pair else (b'', b'', b'')
    decrypted_data = b''
    decrypt_fn: Callable[[bytes], bytes] = (
        Cipher(AES(key), CTR(nonce), backend=default_backend()).decryptor().update
        if options['use_encryption'] else identity
    )
    decompress_obj = zlib.decompressobj()
    unzip_fn: Callable[[bytes], bytes] = (
        decompress_obj.decompress  # type: ignore
        if options['use_compression'] else identity
    )
    hmac = HMAC(key, SHA256(), default_backend())
    writer = output_file.writer(); next(writer)
    for encrypted_data in input_file.reader():
        if options['use_encryption']:
            hmac.update(encrypted_data)
        decrypted_data += decrypt_fn(encrypted_data)
        logger.debug2(f'decrypt_fn returned {len(decrypted_data)} bytes')

        block = unzip_fn(decrypted_data)
        logger.debug2(f'unzip_fn returned {len(block)} bytes')
        writer.send(block)
        decrypted_data = decompress_obj.unused_data

    # Decompress and write out the last block
    if decrypted_data:
        block = unzip_fn(decrypted_data)
        logger.debug2(f'unzip_fn returned {len(block)} bytes')
        writer.send(block)

    try:
        if options['use_encryption']:
            hmac.verify(signature)
    except InvalidSignature as e:
        raise BackupCorruptedError("The file's signature did not match the data") from e
Exemplo n.º 9
0
    def set_shared_secret(self, data):
        """
        When used in the NTOR handshake, the first HASH_LEN bytes form the
        forward digest Df; the next HASH_LEN form the backward digest Db; the
        next KEY_LEN form Kf, the next KEY_LEN form Kb, and the final
        DIGEST_LEN bytes are taken as a nonce to use in the place of KH in the
        hidden service protocol. Excess bytes from K are discarded.

        :type data: bytes
        """
        forward_digest, backward_digest, encryption_key, decryption_key = struct.unpack(
            "!20s20s16s16s", data)

        self._forward_digest = self.set_digest(forward_digest)
        self._backward_digest = self.set_digest(backward_digest)
        self.encryption_key = encryption_key
        self.decryption_key = decryption_key
        self._forward_cipher = Cipher(AES(self.encryption_key),
                                      CTR(b'\0' * 16),
                                      backend=default_backend()).encryptor()
        self._backward_cipher = Cipher(AES(self.decryption_key),
                                       CTR(b'\0' * 16),
                                       backend=default_backend()).decryptor()
Exemplo n.º 10
0
def mdp_crypt(main_password: str, password_to_crypt: str):
    """
    @param main_password: str -> the userpassword
    @param password_to_crypt: str -> to crypt
    @return: byte string
    """
    nonce = os.urandom(32)
    key = bcrypt.kdf(password=bytes(main_password, "utf8"),
                     salt=nonce,
                     desired_key_bytes=32,
                     rounds=100)
    ciph = Cipher(AES(key), CTR(nonce), default_backend())
    encryptor = ciph.encryptor()

    return encryptor.update(bytes(password_to_crypt,
                                  "utf8")).hex(), nonce.hex()
Exemplo n.º 11
0
    def seek(self, n, whence=0):
        if whence == 0:
            goal = n
        elif whence == 1:
            goal = self._pos + n
        else:
            raise ValueError("SEEK_END not supported; keystreams are infinite.")

        closest_block, beyond = divmod(goal, self._octets_per_block)
        self._remaining = b""
        self._pos = closest_block * self._octets_per_block
        self._encryptor = Cipher(
            self._algorithm,
            CTR(int_to_bytes(closest_block, self._octets_per_block)),
            backend=default_backend(),
        ).encryptor()
        self.read(beyond)
Exemplo n.º 12
0
def test_decrypt_and_unpack_bad_signature(caplog, mock_open_streams):
    orig, new, _ = mock_open_streams
    orig_contents = orig._fd.getvalue()
    cipher = Cipher(AES(TMP_KEY), CTR(TMP_NONCE),
                    backend=default_backend()).encryptor()
    ct = cipher.update(zlib.compress(orig_contents))
    hmac = HMAC(TMP_KEY, SHA256(), default_backend())
    hmac.update(ct)
    signature = hmac.finalize()
    orig._fd.write(ct)
    with pytest.raises(BackupCorruptedError):
        decrypt_and_unpack(
            orig,
            new,
            TMP_KEYPAIR + signature[:-2] + b'f',
            dict(use_compression=True, use_encryption=True),
        )
Exemplo n.º 13
0
def aesctr_decrypt_stream(key: AES128Key, iv: bytes,
                          cipher_text: bytes) -> Iterator[int]:
    aes_key = AES(key)
    ctr = CTR(iv)

    try:
        cipher = Cipher(aes_key, ctr, backend=default_backend())
    except ValueError as err:
        raise DecryptionError(str(err)) from err

    decryptor = cipher.decryptor()
    num_blocks = int(math.ceil(len(cipher_text) / 16))
    for i in range(num_blocks):
        cipher_text_block = cipher_text[i * 16:(i + 1) * 16]
        plain_text_block = decryptor.update(cipher_text_block)
        yield from plain_text_block
    yield from decryptor.finalize()
Exemplo n.º 14
0
def test_compress_and_encrypt_no_compression(caplog, mock_open_streams):
    orig, new, _ = mock_open_streams
    signature = compress_and_encrypt(
        orig,
        new,
        TMP_KEYPAIR,
        dict(use_compression=False, use_encryption=True),
    )

    cipher = Cipher(AES(TMP_KEY), CTR(TMP_NONCE),
                    backend=default_backend()).decryptor()
    hmac = HMAC(TMP_KEY, SHA256(), default_backend())
    decrypted = cipher.update(new._fd.getvalue())
    hmac.update(new._fd.getvalue())
    assert decrypted == orig._fd.getvalue()
    assert count_matching_log_lines('read 2 bytes from /orig', caplog) == 4
    assert count_matching_log_lines('wrote 2 bytes to /new', caplog) == 4
    hmac.verify(signature)
Exemplo n.º 15
0
def mdp_decrypt(main_password: str, pasword_to_decrypt: str,
                nonce: str) -> str:
    """
    @summary décrypte un mot de passe a partir du maitre et du nonce
    @param main_password: str
    @param pasword_to_decrypt: str
    @param nonce: str
    @return: bytes .decode("utf8") pour utf8
    """
    nonce = bytes.fromhex(nonce)
    main_password = bytes(main_password, 'utf8')
    key = bcrypt.kdf(password=main_password,
                     salt=nonce,
                     desired_key_bytes=32,
                     rounds=100)
    ciph = Cipher(AES(key), CTR(nonce), default_backend())
    decryptor = ciph.decryptor()

    return decryptor.update(bytes.fromhex(pasword_to_decrypt))
Exemplo n.º 16
0
def compress_and_encrypt(
    input_file: IOIter,
    output_file: IOIter,
    key_pair: Optional[bytes],
    options: OptionsDict,
) -> bytes:
    """ Read data from an open file descriptor, and write the compressed, encrypted data to another
    file descriptor; compute the HMAC of the encrypted data to ensure integrity

    :param input_file: an IOIter object to read plaintext data from
    :param output_file: an IOIter object to write compressed ciphertext to
    """
    key, nonce = (key_pair[:AES_KEY_SIZE], key_pair[AES_KEY_SIZE:]) if key_pair else (b'', b'')
    compressobj = zlib.compressobj()
    zip_fn: Callable[[bytes], bytes] = (  # type: ignore
        compressobj.compress if options['use_compression'] else identity
    )
    encrypt_fn: Callable[[bytes], bytes] = (
        Cipher(AES(key), CTR(nonce), backend=default_backend()).encryptor().update
        if options['use_encryption'] else identity
    )
    hmac = HMAC(key, SHA256(), default_backend())

    def last_block() -> Generator[Tuple[bytes, bool], None, None]:
        yield (compressobj.flush(), False) if options['use_compression'] else (b'', False)

    writer = output_file.writer(); next(writer)
    logger.debug2('starting to compress')
    for block, needs_compression in chain(zip(input_file.reader(), repeat(True)), last_block()):
        if needs_compression:
            block = zip_fn(block)
        logger.debug2(f'zip_fn returned {len(block)} bytes')
        block = encrypt_fn(block)
        logger.debug2(f'encrypt_fn returned {len(block)} bytes')
        if options['use_encryption']:
            hmac.update(block)
        writer.send(block)

    if options['use_encryption']:
        return hmac.finalize()
    else:
        return b''
Exemplo n.º 17
0
def test_decrypt_and_unpack_no_compression(caplog, mock_open_streams):
    orig, new, _ = mock_open_streams
    orig_contents = orig._fd.getvalue()
    cipher = Cipher(AES(TMP_KEY), CTR(TMP_NONCE),
                    backend=default_backend()).encryptor()
    ct = cipher.update(orig_contents)
    hmac = HMAC(TMP_KEY, SHA256(), default_backend())
    hmac.update(ct)
    signature = hmac.finalize()
    orig._fd.write(ct)
    decrypt_and_unpack(
        orig,
        new,
        TMP_KEYPAIR + signature,
        dict(use_compression=False, use_encryption=True),
    )

    assert new._fd.getvalue() == orig_contents
    assert count_matching_log_lines('read 2 bytes from /orig', caplog) == 4
    assert count_matching_log_lines('wrote 2 bytes to /new', caplog) == 4
Exemplo n.º 18
0
def aesctr_encrypt(key: AES128Key, iv: bytes, plain_text: bytes) -> bytes:
    cipher = Cipher(AES(key), CTR(iv), backend=default_backend())
    encryptor = cipher.encryptor()
    return encryptor.update(plain_text) + encryptor.finalize()
Exemplo n.º 19
0
 def test_aes_ctr_always_available(self):
     # AES CTR should always be available, even in 1.0.0.
     assert backend.cipher_supported(AES(b"\x00" * 16), CTR(
         b"\x00" * 16)) is True
Exemplo n.º 20
0
def aes_ctr_decryptor(key, iv=b'\0' * 16):
    return Cipher(AES(key), CTR(iv), backend=bend).decryptor()
Exemplo n.º 21
0
    def __init__(self, msgs, pubkeys):
        assert len(msgs) == len(pubkeys)
        assert 0 < len(msgs) <= 20
        assert all( len(m) <= self.MSG_LEN for m in msgs )

        msgs = [m + "\0"*(self.MSG_LEN - len(m)) for m in msgs]
        pubkeys = [ecc.ECC(pubkey=pk, curve='secp256k1') for pk in pubkeys]
        n = len(msgs)

        tmpkeys = []
        tmppubkeys = []
        for i in range(n):
            while True:
                t = ecc.ECC(curve='secp256k1')
                if ord(t.pubkey_y[-1]) % 2 == 0:
                    break
                # or do the math to "flip" the secret key and pub key
            tmpkeys.append(t)
            tmppubkeys.append(t.pubkey_x)

        enckeys, hmacs, ivs, pad_ivs = zip(*[self.get_ecdh_secrets(tmpkey, pkey.pubkey_x, pkey.pubkey_y)
            for tmpkey, pkey in zip(tmpkeys, pubkeys)])

        # padding takes the form:
        #  E_(n-1)(0000s)
        #  D_(n-1)(
        #      E(n-2)(0000s)
        #      D(n-2)(
        #          ...
        #      )
        #  )

        padding = ""
        for i in range(n-1):
             pad = self.enc_pad(enckeys[i], pad_ivs[i])
             aes = Cipher(AES(enckeys[i]), CTR(ivs[i]),
                     default_backend()).decryptor()
             padding = pad + aes.update(padding)

        if n < 20:
            padding += str(bytearray(random.getrandbits(8)
                             for _ in range(len(self.ZEROES) * (20-n))))

        # to encrypt the message we need to bump the counter past all
        # the padding, then just encrypt the final message
        aes = Cipher(AES(enckeys[-1]), CTR(ivs[-1]),
            default_backend()).encryptor()
        aes.update(padding) # don't care about cyphertext
        msgenc = aes.update(msgs[-1])

        msgenc = padding + msgenc + tmppubkeys[-1]
        del padding
        msgenc += hmac_sha256(hmacs[-1], msgenc)

        # *PHEW*
        # now iterate

        for i in reversed(range(n-1)):
            # drop the padding this node will add
            msgenc = msgenc[len(self.ZEROES):]
            # adding the msg
            msgenc += msgs[i]
            # encrypt it
            aes = Cipher(AES(enckeys[i]), CTR(ivs[i]),
                default_backend()).encryptor()
            msgenc = aes.update(msgenc)
            # add the tmp key
            msgenc += tmppubkeys[i]
            # add the hmac
            msgenc += hmac_sha256(hmacs[i], msgenc)
        self.onion = msgenc
Exemplo n.º 22
0
 def enc_pad(self, enckey, pad_iv):
     aes = Cipher(AES(enckey), CTR(pad_iv),
                  default_backend()).encryptor()
     return aes.update(self.ZEROES)
Exemplo n.º 23
0
    async def _decrypt_v2(self,
                          file_data: bytes,
                          metadata: Dict[str, str],
                          entire_file_length: int,
                          range_start: Optional[int] = None,
                          desired_start: Optional[int] = None,
                          desired_end: Optional[int] = None) -> bytes:

        decryption_key = base64.b64decode(metadata['x-amz-key-v2'])
        material_description = json.loads(metadata['x-amz-matdesc'])

        aes_key = await self._crypto_context.get_decryption_aes_key(
            decryption_key, material_description)

        # x-amz-key-v2 - Contains base64 encrypted key
        # x-amz-iv - AES IVs
        # x-amz-matdesc - JSON Description of client-side master key (used as encryption context as is)
        # x-amz-unencrypted-content-length - Unencrypted content length
        # x-amz-wrap-alg - Key wrapping algo, either AESWrap, RSA/ECB/OAEPWithSHA-256AndMGF1Padding or KMS
        # x-amz-cek-alg - AES/GCM/NoPadding or AES/CBC/PKCS5Padding
        # x-amz-tag-len - AEAD Tag length in bits

        iv = base64.b64decode(metadata['x-amz-iv'])

        # TODO look at doing AES as stream
        if metadata.get('x-amz-cek-alg',
                        'AES/CBC/PKCS5Padding') == 'AES/GCM/NoPadding':
            # AES/GCM/NoPadding

            # So begin the nastyness
            if range_start is not None:
                # Generate IV's as if you were doing so for each block until we get to the one we need
                iv = _adjust_iv_for_range(iv, range_start)
                # IV is now 16 bytes not 12

                aesctr = Cipher(AES(aes_key), CTR(iv),
                                backend=self._backend).decryptor()

                result = await self._loop.run_in_executor(
                    None, lambda:
                    (aesctr.update(file_data) + aesctr.finalize()))

                # Possible remove AEAD tag if our range covers the end
                aead_tag_len = int(metadata['x-amz-tag-len']) // 8
                max_offset = entire_file_length - aead_tag_len - 1
                desired_end = max_offset if desired_end > max_offset else desired_end

                # Chop file
                result = result[desired_start:desired_end]

            else:
                aesgcm = AESGCM(aes_key)

                try:
                    result = await self._loop.run_in_executor(
                        None, lambda: aesgcm.decrypt(iv, file_data, None))
                except InvalidTag:
                    raise DecryptError(
                        'Failed to decrypt, AEAD tag is incorrect. Possible key or IV are incorrect'
                    )

        else:
            if range_start:
                raise DecryptError('Cannot decrypt AES-CBC file with range')

            # AES/CBC/PKCS5Padding
            aescbc = Cipher(AES(aes_key), CBC(iv),
                            backend=self._backend).decryptor()
            padded_result = await self._loop.run_in_executor(
                None, lambda: (aescbc.update(file_data) + aescbc.finalize()))

            unpadder = PKCS7(AES.block_size).unpadder()
            result = await self._loop.run_in_executor(
                None, lambda:
                (unpadder.update(padded_result) + unpadder.finalize()))

        return result
Exemplo n.º 24
0
import ssl
from cryptography.hazmat import backends
from cryptography.hazmat.primitives.asymmetric import dsa
from cryptography.hazmat.primitives.ciphers.modes import CTR

dsa.generate_private_key(key_size=2048, backend=backends.default_backend())
dsa.generate_private_key(key_size=4096, backend=backends.default_backend())

ssl.wrap_socket(ssl_version=ssl.PROTOCOL_TLS)

mode = CTR(iv)
Exemplo n.º 25
0
 def __init__(self, key, iv):
     cipher = Cipher(AES(key), CTR(iv), backend)
     self.encrypter = cipher.encryptor()
     self.decrypter = cipher.decryptor()
     self.block_size = 128
Exemplo n.º 26
0
    def complete_handshake(self, Y, auth):
        # The server's handshake reply is:
        # SERVER_PK   Y                       [G_LENGTH bytes]
        # AUTH        H(auth_input, t_mac)    [H_LENGTH bytes]

        # The client then checks Y is in G^* [see NOTE below], and computes

        # secret_input = EXP(Y,x) | EXP(B,x) | ID | B | X | Y | PROTOID
        si = self.x.get_shared_key(curve25519.Public(Y), hash_func)
        si += self.x.get_shared_key(self.B, hash_func)
        si += b64decode(self.node['identity'])
        si += self.B.serialize()
        si += self.X.serialize()
        si += Y
        si += 'ntor-curve25519-sha256-1'

        # KEY_SEED = H(secret_input, t_key)
        # verify = H(secret_input, t_verify)
        key_seed = hmac(self.t_key, si)
        verify = hmac(self.t_verify, si)

        # auth_input = verify | ID | B | Y | X | PROTOID | "Server"
        ai = verify
        ai += b64decode(self.node['identity'])
        ai += self.B.serialize()
        ai += Y
        ai += self.X.serialize()
        ai += self.protoid
        ai += 'Server'

        # The client verifies that AUTH == H(auth_input, t_mac).
        if auth != hmac(self.t_mac, ai):
            raise NtorError('auth input does not match.')

        # Both parties check that none of the EXP() operations produced the
        # point at infinity. [NOTE: This is an adequate replacement for
        # checking Y for group membership, if the group is curve25519.]

        # Both parties now have a shared value for KEY_SEED.  They expand this
        # into the keys needed for the Tor relay protocol, using the KDF
        # described in 5.2.2 and the tag m_expand.

        # 5.2.2. KDF-RFC5869

        # For newer KDF needs, Tor uses the key derivation function HKDF from
        # RFC5869, instantiated with SHA256.  (This is due to a construction
        # from Krawczyk.)  The generated key material is:

        #     K = K_1 | K_2 | K_3 | ...

        #     Where H(x,t) is HMAC_SHA256 with value x and key t
        #       and K_1     = H(m_expand | INT8(1) , KEY_SEED )
        #       and K_(i+1) = H(K_i | m_expand | INT8(i+1) , KEY_SEED )
        #       and m_expand is an arbitrarily chosen value,
        #       and INT8(i) is a octet with the value "i".

        # In RFC5869's vocabulary, this is HKDF-SHA256 with info == m_expand,
        # salt == t_key, and IKM == secret_input.
        keys = hkdf(key_seed, length=72, info=self.m_expand)

        # When used in the ntor handshake, the first HASH_LEN bytes form the
        # forward digest Df; the next HASH_LEN form the backward digest Db; the
        # next KEY_LEN form Kf, the next KEY_LEN form Kb, and the final
        # DIGEST_LEN bytes are taken as a nonce to use in the place of KH in the
        # hidden service protocol.  Excess bytes from K are discarded.
        Df, Db, Kf, Kb = struct.unpack('>20s20s16s16s', keys)

        # we do what we can with what we've got.
        del self.X
        del self.x
        del self.B
        del key_seed
        del keys
        del verify
        del ai
        del auth
        del si
        del Y

        self.send_digest = Hash(SHA1(), backend=bend)
        self.send_digest.update(Df)
        self.recv_digest = Hash(SHA1(), backend=bend)
        self.recv_digest.update(Db)

        self.encrypt = Cipher(AES(Kf), CTR('\x00' * 16),
                              backend=bend).encryptor()
        self.decrypt = Cipher(AES(Kb), CTR('\x00' * 16),
                              backend=bend).decryptor()
Exemplo n.º 27
0
def _get_cipher(key):
    backend = default_backend()
    return Cipher(AES(key), CTR(bytes(STATIC_IV)), backend=backend)
Exemplo n.º 28
0
 def test_aes_ctr_always_available(self):
     # AES CTR should always be available in both 0.9.8 and 1.0.0+
     assert backend.cipher_supported(AES(b"\x00" * 16), CTR(
         b"\x00" * 16)) is True
Exemplo n.º 29
0
 def decrypt(self, relay_payload):
     cipher = Cipher(AES(self.decryption_key),
                     CTR(b'\x00' * 16),
                     backend=default_backend()).decryptor()
     return cipher.update(relay_payload)