コード例 #1
0
    def hashgen(self, n_bits, V):
        '''
        Hashgen, as specified in NIST SP800-90A, Section 10.1.1.4, page 43
        '''

        # Step 1
        mm = (n_bits + self.outlen - 1) / self.outlen

        # Step 2
        data = V

        # Step 3
        W = ''

        # Step 4
        for dummy_ii in range(mm):
            # Step 4.1
            wi = self.hash(data)
            # Step 4.2
            W = W + wi
            # Step 4.3
            data = utilities.binstr_increment(data, self.seedlen)

        # Step 5
        returned_bits = utilities.binstr_leftmost(W, n_bits)

        # Step 6
        return returned_bits
コード例 #2
0
    def generate_algorithm(self, n_bits, additional_input = None):
        '''
        CTR_DRGB_Generate_algorithm, as specified in NIST SP800-90A,
        Section 10.2.1.5, page 56.
        Generate bits either with (10.2.1.5.2) or without (10.2.1.5.2)
        a derivation function.
        '''

        # Step 1
        if self.counter > self.max_interval and not self.reseed_failed:
            return ('RESEED', '')

        # Step 2
        if additional_input:
            if self.derivation:
                # 10.2.1.5.2, Step 2.1
                status, additional_input = self.block_cipher_df(
                    additional_input, self.seedlen)
                if status != 'SUCCESS':
                    return 'ERROR', 'block_cipher_df returned [%s]' % status
            else:
                # 10.2.1.5.1, Step 2.1-2.2
                additional_input = utilities.binstr_zeropad(
                    additional_input, self.seedlen)
            # 10.2.1.5.1, Step 2.3 / 10.2.1.5.2, Step 2.2
            self.update(additional_input)
        else:
            additional_input = utilities.binstr_zeropad('', self.seedlen)

        # Step 3
        temp = ''

        # Step 4
        while len(temp) < (n_bits + 7) / 8:
            # Step 4.1
            self.V = utilities.binstr_increment(self.V, self.outlen)
            # Step 4.2
            output_block = self.block_encrypt(self.key, self.V)
            # Step 4.3
            temp = temp + output_block

        # Step 5
        returned_bits = utilities.binstr_leftmost(temp, n_bits)

        # Step 6
        self.update(additional_input)

        # Step 7
        self.counter += 1

        # Step 8
        if not self.reseed_failed:
            return ('SUCCESS', returned_bits)
        else:
            return ('RESEED', returned_bits)
コード例 #3
0
    def update(self, data):
        '''
        CTR_DRBG_Update as specified in NIST SP800-90A,
        Section 10.2.1.2, page 52.
        Updates the internal state using the provided data.'
        '''

        if (self.seedlen & 7) or (self.keylen & 7) or (self.outlen & 7):
            raise NotImplementedError(
                'Only 0 mod 8 is supported for key/block sizes.')

        if type(data) is not str:
            raise ValueError('CTR_DRBG_Update requires string input.')

        seedlenbytes = self.seedlen / 8
        if len(data) != seedlenbytes:
            raise ValueError(
                ('CTR_DRBG_Update requires exactly seedlen of data '
                 '(received %d bytes, expected %d).') %
                (len(data), seedlenbytes))

        # Step 1
        temp = ''

        # Step 2
        while len(temp) < seedlenbytes:
            # Step 2.1
            self.V = utilities.binstr_increment(self.V, self.outlen)
            # Step 2.2
            output_block = self.block_encrypt(self.key, self.V)
            # Step 2.3
            temp = temp + output_block

        # Step 3-4, the XOR function automatically truncates to match
        # input lengths
        temp = utilities.binstr_xor(data, temp)

        # Step 5
        self.key = temp[:self.keylen / 8]

        # Step 6
        self.V   = temp[self.keylen / 8:][:self.outlen / 8]

        # Step 7
        self.scheduled = False
        return