diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/model/aes_keywrap.py | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/src/model/aes_keywrap.py b/src/model/aes_keywrap.py index 49d02e1..6d99d0c 100755 --- a/src/model/aes_keywrap.py +++ b/src/model/aes_keywrap.py @@ -49,21 +49,26 @@ # #====================================================================== -""" -Python implementation of RFC 5649 AES Key Wrap With Padding, -using PyCrypto to supply the AES code. -""" +from struct import pack, unpack +from os import urandom +from Crypto.Cipher import AES +import unittest + + +verbose = True + class AESKeyWrapWithPadding(object): """ Implementation of AES Key Wrap With Padding from RFC 5649. + using PyCrypto to supply the AES code. """ class UnwrapError(Exception): "Something went wrong during unwrap." def __init__(self, key): - from Crypto.Cipher import AES + self.key = key self.ctx = AES.new(key, AES.MODE_ECB) def _encrypt(self, b1, b2): @@ -79,6 +84,9 @@ class AESKeyWrapWithPadding(object): step = -1 if start > stop else 1 return xrange(start, stop + step, step) + @staticmethod + def bin2hex(bytes, sep = ":"): + return sep.join("{:02x}".format(ord(b)) for b in bytes) def wrap_key(self, Q): """ @@ -89,7 +97,12 @@ class AESKeyWrapWithPadding(object): Returns C, the wrapped ciphertext. """ - from struct import pack, unpack + if verbose: + print("") + print("Performing key wrap.") + print("key: %s" % (self.bin2hex(self.key))) + print("plaintext: %s" % (self.bin2hex(Q))) + print("") m = len(Q) # Plaintext length if m % 8 != 0: # Pad Q if needed @@ -107,9 +120,20 @@ class AESKeyWrapWithPadding(object): # RFC 3394 section 2.2.1 for j in self._start_stop(0, 5): for i in self._start_stop(1, n): + if verbose: + print("Iteration %d, %d" % (j, i)) + + if verbose: + print("Before encrypt: R[0] = %s R[i] = %s" % (self.bin2hex(R[0]), self.bin2hex(R[i]))) + R[0], R[i] = self._encrypt(R[0], R[i]) + + if verbose: + print("After encrypt: R[0] = %s R[i] = %s" % (self.bin2hex(R[0]), self.bin2hex(R[i]))) + W0, W1 = unpack(">LL", R[0]) - W1 ^= n * j + i + xorval = n * j + i + W1 ^= xorval R[0] = pack(">LL", W0, W1) assert len(R) == (n + 1) and all(len(r) == 8 for r in R) @@ -125,8 +149,6 @@ class AESKeyWrapWithPadding(object): Returns Q, the unwrapped plaintext. """ - from struct import pack, unpack - if len(C) % 8 != 0: raise self.UnwrapError("Ciphertext length {} is not an integral number of blocks" .format(len(C))) @@ -168,8 +190,6 @@ if __name__ == "__main__": # Test code from here down - import unittest - class TestAESKeyWrapWithPadding(unittest.TestCase): @staticmethod @@ -306,7 +326,6 @@ if __name__ == "__main__": self.loopback_test("Hello! My name is Inigo Montoya. You killed my AES key wrapper. Prepare to die.") def test_joachim_loopback(self): - from os import urandom I = "31:32:33" K = AESKeyWrapWithPadding(urandom(256/8)) C = K.wrap_key(I) |