Пример #1
0
    def auth_encrypt(self, P, A, seq_num=None):
        """
        Encrypt the data then prepend the explicit part of the nonce. The
        authentication tag is directly appended with the most recent crypto
        API. Additional data may be authenticated without encryption (as A).

        The 'seq_num' should never be used here, it is only a safeguard needed
        because one cipher (ChaCha20Poly1305) using TLS 1.2 logic in record.py
        actually is a _AEADCipher_TLS13 (even though others are not).
        """
        if False in six.itervalues(self.ready):
            raise CipherError(P, A)

        if hasattr(self, "pc_cls"):
            self._cipher.mode._initialization_vector = self._get_nonce()
            self._cipher.mode._tag = None
            encryptor = self._cipher.encryptor()
            encryptor.authenticate_additional_data(A)
            res = encryptor.update(P) + encryptor.finalize()
            res += encryptor.tag
        else:
            if isinstance(self._cipher, AESCCM):
                res = self._cipher.encrypt(self._get_nonce(),
                                           P,
                                           A,
                                           tag_length=self.tag_len)
            else:
                res = self._cipher.encrypt(self._get_nonce(), P, A)

        nonce_explicit = pkcs_i2osp(self.nonce_explicit,
                                    self.nonce_explicit_len)
        self._update_nonce_explicit()
        return nonce_explicit + res
Пример #2
0
    def auth_encrypt(self, P, A, seq_num):
        """
        Encrypt the data, and append the computed authentication code.
        TLS 1.3 does not use additional data, but we leave this option to the
        user nonetheless.

        Note that the cipher's authentication tag must be None when encrypting.
        """
        if False in six.itervalues(self.ready):
            raise CipherError(P, A)

        if hasattr(self, "pc_cls"):
            self._cipher.mode._tag = None
            self._cipher.mode._initialization_vector = self._get_nonce(seq_num)
            encryptor = self._cipher.encryptor()
            encryptor.authenticate_additional_data(A)
            res = encryptor.update(P) + encryptor.finalize()
            res += encryptor.tag
        else:
            if (conf.crypto_valid_advanced
                    and isinstance(self._cipher, AESCCM)):
                res = self._cipher.encrypt(self._get_nonce(seq_num),
                                           P,
                                           A,
                                           tag_length=self.tag_len)
            else:
                res = self._cipher.encrypt(self._get_nonce(seq_num), P, A)
        return res
Пример #3
0
 def encrypt(self, data):
     """
     Encrypt the data. Also, update the cipher iv. This is needed for SSLv3
     and TLS 1.0. For TLS 1.1/1.2, it is overwritten in TLS.post_build().
     """
     if False in six.itervalues(self.ready):
         raise CipherError(data)
     encryptor = self._cipher.encryptor()
     tmp = encryptor.update(data) + encryptor.finalize()
     self.iv = tmp[-self.block_size:]
     return tmp
Пример #4
0
 def decrypt(self, data):
     """
     Decrypt the data. Also, update the cipher iv. This is needed for SSLv3
     and TLS 1.0. For TLS 1.1/1.2, it is overwritten in TLS.pre_dissect().
     If we lack the key, we raise a CipherError which contains the input.
     """
     if False in six.itervalues(self.ready):
         raise CipherError(data)
     decryptor = self._cipher.decryptor()
     tmp = decryptor.update(data) + decryptor.finalize()
     self.iv = data[-self.block_size:]
     return tmp
Пример #5
0
    def auth_decrypt(self, A, C, seq_num=None, add_length=True):
        """
        Decrypt the data and authenticate the associated data (i.e. A).
        If the verification fails, an AEADTagError is raised. It is the user's
        responsibility to catch it if deemed useful. If we lack the key, we
        raise a CipherError which contains the encrypted input.

        Note that we add the TLSCiphertext length to A although we're supposed
        to add the TLSCompressed length. Fortunately, they are the same,
        but the specifications actually messed up here. :'(

        The 'add_length' switch should always be True for TLS, but we provide
        it anyway (mostly for test cases, hum).

        The 'seq_num' should never be used here, it is only a safeguard needed
        because one cipher (ChaCha20Poly1305) using TLS 1.2 logic in record.py
        actually is a _AEADCipher_TLS13 (even though others are not).
        """
        nonce_explicit_str, C, mac = (C[:self.nonce_explicit_len],
                                      C[self.nonce_explicit_len:-self.tag_len],
                                      C[-self.tag_len:])

        if False in six.itervalues(self.ready):
            raise CipherError(nonce_explicit_str, C, mac)

        self.nonce_explicit = pkcs_os2ip(nonce_explicit_str)
        if add_length:
            A += struct.pack("!H", len(C))

        if hasattr(self, "pc_cls"):
            self._cipher.mode._initialization_vector = self._get_nonce()
            self._cipher.mode._tag = mac
            decryptor = self._cipher.decryptor()
            decryptor.authenticate_additional_data(A)
            P = decryptor.update(C)
            try:
                decryptor.finalize()
            except InvalidTag:
                raise AEADTagError(nonce_explicit_str, P, mac)
        else:
            try:
                if isinstance(self._cipher, AESCCM):
                    P = self._cipher.decrypt(self._get_nonce(),
                                             C + mac,
                                             A,
                                             tag_length=self.tag_len)
                else:
                    P = self._cipher.decrypt(self._get_nonce(), C + mac, A)
            except InvalidTag:
                raise AEADTagError(nonce_explicit_str,
                                   "<unauthenticated data>", mac)
        return nonce_explicit_str, P, mac
Пример #6
0
    def auth_decrypt(self, A, C, seq_num):
        """
        Decrypt the data and verify the authentication code (in this order).
        Note that TLS 1.3 is not supposed to use any additional data A.
        If the verification fails, an AEADTagError is raised. It is the user's
        responsibility to catch it if deemed useful. If we lack the key, we
        raise a CipherError which contains the encrypted input.
        """
        C, mac = C[:-self.tag_len], C[-self.tag_len:]
        if False in six.itervalues(self.ready):
            raise CipherError(C, mac)

        if hasattr(self, "pc_cls"):
            self._cipher.mode._initialization_vector = self._get_nonce(seq_num)
            self._cipher.mode._tag = mac
            decryptor = self._cipher.decryptor()
            decryptor.authenticate_additional_data(A)
            P = decryptor.update(C)
            try:
                decryptor.finalize()
            except InvalidTag:
                raise AEADTagError(P, mac)
        else:
            try:
                if (conf.crypto_valid_advanced
                        and isinstance(self._cipher, AESCCM)):
                    P = self._cipher.decrypt(
                        self._get_nonce(seq_num),
                        C + mac,
                        A,  # noqa: E501
                        tag_length=self.tag_len)
                else:
                    if (conf.crypto_valid_advanced
                            and isinstance(self, Cipher_CHACHA20_POLY1305)):
                        A += struct.pack("!H", len(C))
                    P = self._cipher.decrypt(self._get_nonce(seq_num), C + mac,
                                             A)  # noqa: E501
            except InvalidTag:
                raise AEADTagError("<unauthenticated data>", mac)
        return P, mac
Пример #7
0
 def decrypt(self, data):
     if False in six.itervalues(self.ready):
         raise CipherError(data)
     self._dec_updated_with += data
     return self.decryptor.update(data)