source: lib/bletchley/buffertools.py @ 7

Last change on this file since 7 was 7, checked in by tmorgan, 12 years ago

renamed function

File size: 3.7 KB
Line 
1'''
2A collection of tools to manipulate buffers of encrypted content
3
4Copyright (C) 2011-2012 Virtual Security Research, LLC
5Author: Timothy D. Morgan, Jason A. Donenfeld
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License, version 3,
9 as published by the Free Software Foundation.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program.  If not, see <http://www.gnu.org/licenses/>.
18'''
19
20import sys
21import zlib
22
23# Computes the block-wise differences between two strings
24# Blobs must be the same length and their length must be a multiple of block_size
25#
26# Returns a list of block numbers that are different from one another. 
27# Examples:
28# blockWiseDiff(8, '1234567812345678', '12345678XXXXXXXX')
29# => [1]
30#
31# blockWiseDiff(1, '12345', '12345')
32# => []
33#
34
35def blockWiseDiff(block_size, blob1, blob2):
36    if len(blob1) != len(blob2):
37        sys.stderr.write("ERROR: Ciphertexts not the same length.\n")
38        return None
39
40    if (len(blob1) % block_size) != 0:
41        sys.stderr.write("ERROR: Ciphertexts do not have an even multiple of blocks.\n")
42        return None
43
44    blocks1 = [blob1[o:o+block_size] for o in range(0,len(blob1),block_size)]
45    blocks2 = [blob2[o:o+block_size] for o in range(0,len(blob2),block_size)]
46
47    ret_val = []
48    for b in range(0,len(blocks1)):
49        if blocks1[b] != blocks2[b]:
50            ret_val.append(b)
51
52    return ret_val
53
54
55
56def blockWiseColorMap(block_size, blobs):
57    '''
58    Accepts a sequence of blobs and compares all individual blocks
59    (of block_size) within those blobs.  Returns a dictionary where the
60    keys are blocks from the original blobs whose values were repeated
61    at least once. (Unique blocks in the original blobs will not be
62    represented in the return value.) The values of the returned
63    dictionary are a 32bit integer hash value of the blocks they are
64    associated with.
65    '''
66    block_counts = {}
67    for blob in blobs:
68        for block_off in range(0,len(blob),block_size):
69            block = blob[block_off:block_off+block_size]
70            count = block_counts.get(block, None)
71            if count == 0:
72                block_counts[block] = 1 # more than one exists
73            elif count == None:
74                block_counts[block] = 0  # one exists
75
76    colors = {}
77    for block,count in block_counts.iteritems():
78        if count == 1:
79            # mask needed for portability
80            colors[block] = zlib.crc32(block)%0xFFFFFFFF 
81
82    return colors
83
84
85
86# XORs two buffers (bytes/bytearrays) and returns result
87#
88# If buffers not the same length, returned buffer length
89# will be that of the shorter buffer.
90#
91def xorBuffers(buff1, buff2):
92    max_len = min(len(buff1), len(buff2))
93
94    ret_val = bytearray(buff1[0:max_len])
95    other = bytearray(buff2[0:max_len])
96    for i in range(0,len(ret_val)):
97        ret_val[i] ^= other[i]
98
99    return ret_val
100
101
102def splitBuffer(buf, block_size):
103        '''
104        Splits a buffer into evenly sized blocks.
105        '''
106        return [buf[i:i + block_size] for i in xrange(0, len(buf), block_size)]
107
108def iterBuffer(buf, block_size):
109        '''
110        Iterates through a buffer in evenly sized blocks.
111        '''
112        return (buf[i:i + block_size] for i in xrange(0, len(buf), block_size))
113
114def pkcs7PadBuffer(buf, block_size):
115        '''
116        Pads the end of a buffer using PKCS#5/PKCS#7 padding.
117        '''
118        padding = block_size - (len(buf) % block_size)
119        return buf + (chr(padding) * padding)
Note: See TracBrowser for help on using the repository browser.