Saturday, December 18, 2010

Erase keys and credit card numbers in Python

Not to start a long discussion on system security and the advisability of doing crypto in potentially compromised environments, suffice it to say it is still good practice to erase keys, credit card numbers, and other sensitive information when no longer needed. Overwriting the sensitive content with garbage will not prevent leakage but it can reduce the likelihood.

Unfortunately Python's assignment statement
  key = "Kilroy was here!"
    ...
  key = "qwerty" 
does not overwrite previous string values. True, key now points to "qwerty" but this is a new string. The old string is not overwritten and still resides in memory flagged for garbage collection. When it will be collected and reused is indeterminate, and even then, there is no assurance it will be overwritten. This problem is common to many scripting languages, not just Python.

Python's ctypes' c_buffer() has an interesting property. Operations on the buffer's contents occur in a fixed memory location making it attractive for the later clearing of sensitive content. Consider this:
  from ctypes import c_buffer, addressof

  TEMPLATE = '  %s: key location: 0x%X, value: %s'

  # instantiate key
  key = c_buffer(16)
  print '  key: %s' % key

  # set the key value
  key.value = 'Kilroy was here!'
  print TEMPLATE % ('set', addressof(key), key.value)

  # use the key in some way
  pass

  # overwrite the key
  key.value = '-'*16
  print TEMPLATE % ('clr', addressof(key), key.value)
If you are using ctypes to access an AES routine written in C, simply pass the variable key which, as it turns out, is essentially a pointer to the character array. The above approach also works for other data types such as int and ulong.

Enjoy.

Labels: , ,

Sunday, August 09, 2009

Using Python ctypes to access C lib global data

I want to access global data in a C library from within a Python program. The Python ctypes documentation tells you how to call functions, set up arguments and other things. But if you want to access global data, well, the doc is lacking a good example. This may help. (I'm assuming you are generally familiar with ctypes.)

Suppose you have a C library with several functions and a single global data item named "myGlobal" of type unsigned long. Load the library as "lib" and you can access myGlobal with this snippet.
    myGlobal = c_ulong.in_dll(lib, "myGlobal").value
print(" myGlobal = %d" % myGlobal)
If you have several global variables and have organized them as a C struct named "G"....
    struct {
// reference with a "G." prefix
unsigned long value1;
unsigned long value2;
unsigned long value3;
} G;
...your Python code might include a snippet like this.
    class AllMyGlobals(Structure):
_fields_ = [("value1", c_ulong),
("value2", c_ulong),
("value3", c_ulong)]

G = AllMyGlobals.in_dll(lib, "G")
print(" G.value1 = %d" % G.value1)
print(" G.value2 = %d" % G.value2)
print(" G.value3 = %d" % G.value3)
Changing one of those values in the C library is easy too.
    G.value2 = 1234
Enjoy.
 

Labels: ,

Sunday, November 04, 2007

Python access to CryptMT, Dragon, HC, LEX, NLS, Rabbit (eSTREAM ciphers)

The last couple of months have been heads down and very long hours with my day job. I'm back now to personal projects and put together another Python wrapper for these ciphers using the eSTREAM APIs. See http://www.seanet.com/~bugbee/crypto
 

Labels: , , ,

Monday, June 11, 2007

Fast stream ciphers from eSTREAM

Several years ago the EU (European Union), through a project called NESSIE, analyzed and recommended a number of cryptographic primitives. You can learn more about NESSIE from the links below. One category in which they were not satisfied and made no recommendation is stream ciphers, so they launched a new project, eSTREAM, expressly for the evaluation of stream ciphers. eSTREAM is now in Phase 3, the final evaluation phase, and there are a number of promising candidates.
    NESSIE
        http://en.wikipedia.org/wiki/NESSIE
        https://www.cosic.esat.kuleuven.be/nessie/
    eSTREAM
        http://en.wikipedia.org/wiki/ESTREAM
        http://www.ecrypt.eu.org/stream/

Personally, I like Salsa20. I benchmarked Salsa20 as encrypting over 100 MB per second on a lowly 1.5 GHz G4 PPC mini Mac. ...128-bit encryption strength, memory resident data (no I/O), and before Python's GC kicked in. This is more than 3x faster than AES-128 on the same machine. Others I like are Sosemanuk and Phelix, but Phelix didn't advance to Phase 3. Ugh. Well, two out of three isn't bad.

The core routines are written in C so I wrote ctypes wrappers to access Salsa20, Sosemanuk, Phelix and others. I'm making that code available, free for any use.
        http://www.seanet.com/~bugbee/crypto

Enjoy.
 

Labels: , , ,

Sunday, June 10, 2007

A Python ctypes wrapper for LibTomCrypt

Recently I wrote a Python ctypes wrapper for LibTomCrypt. I'm making that code available, free for any use.

pyTomCrypt v0.20 implements most of Tom's crypto library:
    - public key algorithms: RSA, DSA, ECDSA, ECDH
    - hash algorithms:
      md2, md4, md5, rmd128, rmd160, rmd256, rmd320,
      sha1, sha224, sha256, sha384, sha512, tiger, whirlpool
    - symmetric ciphers:
      aes, rijndael, twofish, blowfish, des, des3, cast5,
      kasumi, anubis, kseed, khazad, noekeon, rc2, rc5, rc6,
      xtea, skipjack
    - modes: ecb, cbc, ctr, cfb, ofb
    - MACs: HMAC, OMAC, PMAC, Pelican, XCBC, F9
    - PRNGs: fortuna, rc4, sprng, yarrow, sober128
and is based on:
    - libtomcrypt 1.17
    - libtommath 0.41 (default)
    - tomsfastmath 0.12 (optional)

See...
    http://libtom.org
    http://www.seanet.com/~bugbee/crypto

Enjoy.
 

Labels: , ,