"Fossies" - the Fresh Open Source Software Archive

Member "revelation-0.5.4/src/bundle/AfSplitter.py" (4 Oct 2020, 3678 Bytes) of package /linux/privat/revelation-0.5.4.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "AfSplitter.py" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 0.5.3_vs_0.5.4.

    1 """Implementation of anti-forensic information splitting
    2 
    3 The AFsplitter supports secure data destruction crucial for secure on-disk key
    4 management. The key idea is to bloat information and therefor improving the
    5 chance of destroying a single bit of it. The information is bloated in such a
    6 way, that a single missing bit causes the original information become
    7 unrecoverable. The theory behind AFsplitter is presented in TKS1.
    8 
    9 The interface is simple. It consists of two functions:
   10 
   11 AFSplit(data, stripes, digesttype='sha1')
   12 AFMerge(data, stripes, digesttype='sha1')
   13 
   14 AFSplit operates on data and returns information splitted data.  AFMerge does
   15 just the opposite: uses the information stored in data to recover the original
   16 splitted data.
   17 
   18 http://clemens.endorphin.org/AFsplitter
   19 TKS1 paper from http://clemens.endorphin.org/publications
   20 
   21 Copyright 2006 John Lenz <lenz@cs.wisc.edu>
   22 
   23 This program is free software; you can redistribute it and/or
   24 modify it under the terms of the GNU General Public License
   25 as published by the Free Software Foundation; either version 2
   26 of the License, or (at your option) any later version.
   27 
   28 This program is distributed in the hope that it will be useful,
   29 but WITHOUT ANY WARRANTY; without even the implied warranty of
   30 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   31 GNU General Public License for more details.
   32 
   33 You should have received a copy of the GNU General Public License
   34 along with this program; if not, write to the Free Software
   35 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   36 
   37 http://www.gnu.org/copyleft/gpl.html
   38 """
   39 
   40 
   41 import hashlib, string, math, struct
   42 
   43 import Cryptodome.Random as Random
   44 
   45 def _xor(a, b):
   46     """Internal function to performs XOR on two strings a and b"""
   47 
   48     return bytes([x ^ y for (x, y) in zip(a, b)])
   49 
   50 def _diffuse(block, size, digest):
   51     """Internal function to diffuse information inside a buffer"""
   52 
   53     # Compute the number of full blocks, and the size of the leftover block
   54     digest_size = hashlib.new(digest).digest_size
   55     full_blocks = int(math.floor(float(len(block)) / float(digest_size)))
   56     padding = len(block) % digest_size
   57 
   58     # hash the full blocks
   59     ret = b""
   60     for i in range(0, full_blocks):
   61         hash = hashlib.new(digest)
   62         hash.update(struct.pack(">I", i))
   63         hash.update(block[i*digest_size:(i+1)*digest_size])
   64         ret += hash.digest()
   65 
   66     # Hash the remaining data
   67     if padding > 0:
   68         hash = hashlib.new(digest)
   69         hash.update(struct.pack(">I", full_blocks))
   70         hash.update(block[full_blocks * digest_size:])
   71         ret += hash.digest()[:padding]
   72 
   73     return ret
   74 
   75 def AFSplit(data, stripes, digesttype='sha1'):
   76     """AF-Split data using digesttype.  Returned data size will be len(data) * stripes"""
   77 
   78     blockSize = len(data)
   79 
   80     rand = Random.new()
   81 
   82     bufblock = [0] * blockSize
   83 
   84     ret = b""
   85     for i in range(0, stripes-1):
   86 
   87         # Get some random data
   88         r = rand.read(blockSize)
   89 
   90         ret += r
   91         bufblock = _xor(r, bufblock)
   92         bufblock = _diffuse(bufblock, blockSize, digesttype)
   93 
   94     ret += _xor(bufblock, data)
   95     return ret
   96 
   97 def AFMerge(data, stripes, digesttype='sha1'):
   98     """AF-Merge data using digesttype.  len(data) must be a multiple of stripes"""
   99 
  100     if len(data) % stripes != 0:
  101         raise ValueError("ERROR: data is not a multiple of strips")
  102 
  103     blockSize = len(data) // stripes
  104 
  105     bufblock = [0] * blockSize
  106     for i in range(0, stripes - 1):
  107         bufblock = _xor(data[i*blockSize:(i+1)*blockSize], bufblock)
  108         bufblock = _diffuse(bufblock, blockSize, digesttype)
  109 
  110     return _xor(data[(stripes-1)*blockSize:], bufblock)