Ejemplo n.º 1
0
    def encrypt(self, block_iterator):
        eof_iterator = eof_signal_iterator(block_iterator)
        for data, eof in eof_iterator:

            if not self.cipher_block:
                #executed only once, on the first iteration
                self.cipher_block = self.iv
                #just return the IV, to be used as the first 64 bytes of the file
                yield self.cipher_block

            if not eof:
                self.cipher_block = self.cipher.encrypt_block(
                    self._xor(data, self.cipher_block))
            else:
                #executed only once, for the last block of the file
                block = data if not eof else self.padding_scheme.apply(data)
                if len(block) == self.block_size:
                    self.cipher_block = self.cipher.encrypt_block(
                        self._xor(block, self.cipher_block))
                elif len(block) == 2 * self.block_size:
                    last_block = self.cipher.encrypt_block(
                        self._xor(block[:self.block_size], self.cipher_block))
                    #This will append an entire block of padding (??)
                    self.cipher_block = self.cipher.encrypt_block(
                        self._xor(block[self.block_size:], last_block))
                    #set the cipher_block variable to be last block of real data
                    #prepended to the extra block of padding
                    self.cipher_block = last_block + self.cipher_block
                else:
                    raise Exception(
                        "Padding error: Padding scheme returned " +
                        "data that is not a multiple of the block length")
            yield self.cipher_block
Ejemplo n.º 2
0
    def decrypt(self, block_iterator):
        # Wrap file / list iterator inside eof_signal_iterator
        eof_iterator = eof_signal_iterator(block_iterator)

        for data, eof in eof_iterator:
            plaintext = self.cipher.decrypt_block(data)
            block = plaintext if not eof else self.padding_scheme.remove(plaintext)
            yield block
Ejemplo n.º 3
0
    def decrypt(self, block_iterator):
        eof_iterator = eof_signal_iterator(block_iterator)

        #Always get the first 64 bytes of the data as IV. Even if it was already
        #supplied on the command line
        self.cipher_block, eof = next(eof_iterator)

        for data, eof in eof_iterator:
            plaintext = self._xor(self.cipher.decrypt_block(data),
                                  self.cipher_block)
            self.cipher_block = data
            block = plaintext if not eof else \
                self.padding_scheme.remove(plaintext)
            yield block
Ejemplo n.º 4
0
    def decrypt(self, block_iterator):
        # This is similar to encryption, but we check the gmac rather than generate it.
        bits_per_byte = 8
        num_bits = bits_per_byte * self.block_size

        ek_nonce = GP(num_bits, int.from_bytes(self._get_xor_block(0), "little"))
        counter = 1

        eof_iterator = eof_signal_iterator(block_iterator)

        (header_bytes, b) = next(eof_iterator)
        assert not b, "File contained only 1 block"

        A = GP(num_bits, int.from_bytes(header_bytes, "little"))

        zero = 0
        Ek_0_bytes = self.cipher.encrypt_block(zero.to_bytes(self.cipher.block_size, "little"))
        Ek_0 = GP(num_bits, int.from_bytes(Ek_0_bytes, "little"))

        rolling_polynomial = A.mult(Ek_0)

        for ciphertext, eof in eof_iterator:
            if eof:
                break

            xor_block = self._get_xor_block(counter)

            data = self._xor(ciphertext, xor_block)
            counter += 1

            C = GP(num_bits, int.from_bytes(ciphertext, "little"))
            rolling_polynomial = rolling_polynomial.xor(C).mult(Ek_0)


            yield data

        extra_block = len(self.header) << (num_bits // 2)
        extra_block += counter
        extra_block_gp = GP(num_bits, extra_block)
        rolling_polynomial = rolling_polynomial.xor(extra_block_gp).mult(Ek_0)

        gmac = rolling_polynomial.xor(ek_nonce)
        gmac_bytes = gmac.intval().to_bytes(self.block_size, "little")

        if gmac_bytes == ciphertext:
            print("Message verified correctly")
        else:
            print("Message not verified")
Ejemplo n.º 5
0
    def encrypt(self, block_iterator):

        counter = 0
        eof_iterator = eof_signal_iterator(block_iterator)

        for data, eof in eof_iterator:

            xor_block = self._get_xor_block(counter)

            if eof and len(data) < self.block_size:
                xor_block = xor_block[:len(data)]

            ciphertext = self._xor(data, xor_block)
            counter += 1

            yield ciphertext
Ejemplo n.º 6
0
    def encrypt(self, block_iterator):
        # Wrap file / list iterator inside eof_signal_iterator
        eof_iterator = eof_signal_iterator(block_iterator)

        for data, eof in eof_iterator:
            if not eof:
                ciphertext = self.cipher.encrypt_block(data)
            else:
                block = data if not eof else self.padding_scheme.apply(data)
                # Padding should return 1 or 2 blocks
                if len(block) == self.block_size:
                    ciphertext = self.cipher.encrypt_block(block)
                elif len(block) == self.block_size * 2:
                    ciphertext = self.cipher.encrypt_block(block[:self.block_size]) \
                               + self.cipher.encrypt_block(block[self.block_size:])

                else:
                    raise Exception("Padding error: Padding scheme returned data that is not a multiple of the block length")
            yield ciphertext
Ejemplo n.º 7
0
    def encrypt(self, block_iterator):
        bits_per_byte = 8
        num_bits = bits_per_byte * self.block_size

        ek_nonce = GP(num_bits, int.from_bytes(self._get_xor_block(0), "little"))
        counter = 1

        assert len(self.header) <= self.block_size, "Header must be fit in a single block"
        A = GP(num_bits, int.from_bytes(self.header, "little"))

        header_bytes = int.from_bytes(self.header, "little").to_bytes(self.block_size, "little")
        yield header_bytes

        zero = 0
        Ek_0_bytes = self.cipher.encrypt_block(zero.to_bytes(self.cipher.block_size, "little"))
        Ek_0 = GP(num_bits, int.from_bytes(Ek_0_bytes, "little"))

        rolling_polynomial = A.mult(Ek_0)

        eof_iterator = eof_signal_iterator(block_iterator)

        for data, eof in eof_iterator:

            xor_block = self._get_xor_block(counter)

            ciphertext = self._xor(data, xor_block)
            counter += 1

            C = GP(num_bits, int.from_bytes(ciphertext, "little"))
            rolling_polynomial = rolling_polynomial.xor(C).mult(Ek_0)


            yield ciphertext

        extra_block = len(self.header) << (num_bits // 2)
        extra_block += counter
        extra_block_gp = GP(num_bits, extra_block)
        rolling_polynomial = rolling_polynomial.xor(extra_block_gp).mult(Ek_0)

        gmac = rolling_polynomial.xor(ek_nonce)
        yield gmac.intval().to_bytes(self.block_size, "little")