source: trunk/lib/bletchley/chosen.py @ 43

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

moved to dedicated repository

File size: 2.8 KB
Line 
1'''
2A collection of tools to assist in analyzing encrypted blobs of data
3through chosen plaintext attacks.
4
5Copyright (C) 2011-2012 Virtual Security Research, LLC
6Author: Timothy D. Morgan
7
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License, version 3,
10 as published by the Free Software Foundation.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program.  If not, see <http://www.gnu.org/licenses/>.
19'''
20
21import sys
22from buffertools import blockWiseDiff
23
24
25# Chosen plaintext attack on ECB encryption
26#
27# The encryptionOracle should accept a single string argument,
28# encrypt that argument as part of a larger (unknown) plaintext string,
29# and then return the ciphertext.
30#
31# This function will then return a dictionary with information about the
32# algorithm and chosen string attributes, including:
33#  block_size - the algorithm's block size
34#  chosen_offset - the chosen string's offset within the plaintext
35#  fragment_length - the length of a chosen from the chosen_offset to the
36#                    end of its current block
37#
38def ECB_FindChosenOffset(encryptionOracle):
39    ret_val = {}
40
41    # Guaranteed to have one block boundary on 128 bit block ciphers
42    chosen_length = 17
43    chosen = 'O'*chosen_length
44    base = encryptionOracle(chosen)
45
46    chosen = 'X' + 'O'*(chosen_length-1)
47    test_result = encryptionOracle(chosen)
48
49    different_blocks = blockWiseDiff(1, base, test_result)
50    block_size = len(different_blocks)
51    # Sanity check
52    different_blocks = blockWiseDiff(block_size, base, test_result)
53    if different_blocks == None:
54        sys.stderr.write("ERROR: Block size test yielded undiff-able ciphertexts.\n")
55        return None
56    if len(different_blocks) > 1:
57        sys.stderr.write("ERROR: Block size test yielded multiple altered blocks (not ECB mode?).\n")
58        return None
59
60    for i in range(2,chosen_length):
61        chosen = 'X'*i + 'O'*(chosen_length-i)
62        test_result = encryptionOracle(chosen)
63        different_blocks = blockWiseDiff(block_size, base, test_result)
64       
65        if different_blocks == None or len(different_blocks) == 0 or len(different_blocks) > 2:
66            sys.stderr.write("ERROR: Offset detection yielded inconsistent block diffs.\n")
67            return None
68        if len(different_blocks) == 2:
69            break
70
71    ret_val['block_size'] = block_size
72    ret_val['fragment_length'] = i-1
73    ret_val['chosen_offset'] = max(different_blocks)*block_size - ret_val['fragment_length']
74
75    return ret_val
Note: See TracBrowser for help on using the repository browser.