0,0 → 1,69 |
""" crypto.keyedHash.michael |
|
A reference implementation of the Michael Message Integrety Chek (MIC) |
that is defined in IEEE 802.11 Task Group 'i' |
|
Michael is a 64-bit MIC, with a design strength of 20 bits. |
|
Copyright © (c) 2002 by Paul A. Lambert |
Read LICENSE.txt for license information. |
""" |
from struct import pack, unpack |
from binascii_plus import * |
|
class Michael: |
""" The Michael keyed hash as defined in IEEE 802.11i D2.0 """ |
def __init__(self, key = None): |
self.name = 'Michael' |
self.blocksize = 1 # single octets can be hashed by padding to raw block size |
self.raw_block_size = 4 # operates on 32 bits or 4 byte blocks |
self.digest_size = 8 # MIC size of 64 bits or 8 bytes |
self.keySize = 8 # key size is 8 octets |
self.strength = 20 |
if key != None: |
self.setKey(key) |
|
def __del__(self): |
self.setKey(8*chr(0)) # feable attempt to clear keys on exit |
|
def setKey(self,key): |
""" setKey(key) ... key is binary string """ |
assert( len(key)== self.keySize), 'Key must be 8 octets' |
self._key = unpack('<II', key) # unpack into 2 32bit integers |
|
def __call__(self,data,more=None): |
return self.hash(data) |
|
def hash(self,data): |
""" Michael keyed hash """ |
fullBlocks, extraOctets = divmod(len(data),4) |
paddedData = data + chr(0x5a) + chr(0)*(7-extraOctets) |
l, r = self._key |
for i in range(fullBlocks+2): |
mSub_i = unpack('<I', paddedData[i*4:i*4+4])[0] # ith block as 32 bit integer |
l = l ^ mSub_i |
l, r = b(l,r) |
digest = pack('<II', l, r ) |
return digest |
|
def update(self,data): |
raise 'No update method supported for Michael keyed hash' |
def digest(self): |
raise 'No digest method supported for Michael keyed hash' |
def final(self,data): |
raise 'No final method supported for Michael keyed hash' |
|
def b(l,r): |
""" The 'b' block function for the IEEE 802.11i Michael Integrity Check """ |
r ^= (((l<<17) & 0xffffffffL)|((l>>15) & 0x1ffffL)) # r = r ^ (l <<< 17) |
l = (l+r) & 0xffffffffL # l = (l+r) mod 2**32 |
r ^= ((l & 0xff00ff00L)>>8)|((l & 0x00ff00ffL)<<8) # r = r ^ XSWAP(l) |
l = (l+r) & 0xffffffffL # l = (l+r) mod 2**32 |
r ^= (((l<<3) & 0xffffffffL) | ((l>>29)& 0x7)) # r = r ^ (l <<< 3) |
l = (l+r) & 0xffffffffL # l = (l+r) mod 2**32 |
r ^= (((l<<30L) & 0xffffffffL)|((l>>2) & 0x3fffffff)) # r = r ^ (l >>> 2) |
l = (l+r) & 0xffffffffL # l = (l+r) mod 2**32 |
return (l,r) |
|
|
|