wpa-handshake with python - hashing difficulties
Question: I try to write a Python program which calculates the WPA-handshake, but I have
problems with the hashes. For comparison I installed cowpatty _(to see where I
start beeing wrong)_.

My PMK-generation works fine, but the PTK-calculation alsways seems to be
wrong. I am not sure if I have to format my input _(macadresses and noces)_ or
just give them into the function as a string.

I will give you my routerinformation, which is no problem since I just set it
up for testing.

My program looks as follows:

    
    
    import hmac,hashlib,binascii
    
    passPhrase  = "10zZz10ZZzZ"
    ssid        = "Netgear 2/158" 
    A           = "Pairwise key expansion" 
    APmac       = "001e2ae0bdd0"
    Clientmac   = "cc08e0620bc8"
    ANonce      = "61c9a3f5cdcdf5fae5fd760836b8008c863aa2317022c7a202434554fb38452b"
    SNonce      = "60eff10088077f8b03a0e2fc2fc37e1fe1f30f9f7cfbcfb2826f26f3379c4318"
    B           = min(APmac,Clientmac)+max(APmac,Clientmac)+min(ANonce,SNonce)+max(ANonce,SNonce)
    data="0103005ffe010900200000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
    
    def customPRF512(key,A,B):
        blen = 64
        i    = 0
        R    = ''
        while i<=((blen*8+159)/160):
            hmacsha1 = hmac.new(key,A+chr(0x00)+B+chr(i),sha)
            i+=1
            R = R+hmacsha1.digest()
        return R[:blen]
    
    
    pmk = pbkdf2(passPhrase, ssid, 4096, 32) #no sourcecode, since b2a_p(pmk) output fits to those of cowpatty
    
    ptk = customPRF512(pmk,A,B) #the prf-function fits the pseudocode in the ieee, but does not give me the correct output (like cowpatty does)
    # and i have no idea why :(
    
    print b2a_p(pmk),"\n\n\n"
    print b2a_p(ptk),"\n\n\n"
    
    mic1 = hmac.new(ptk[0:16],data)
    print mic1.hexdigest() #should be the mic-calculation, not sure if this is correct...
    

the desired outputs _(which cowpatty confirmed)_ are:

    
    
    PMK is
     01b8 09f9 ab2f b5dc 4798 4f52 fb2d 112e
     13d8 4ccb 6b86 d4a7 193e c529 9f85 1c48
    
    Calculated PTK for "10zZz10ZZzZ" is
     bf49 a95f 0494 f444 2716 2f38 696e f8b6 
     428b cf8b a3c6 f0d7 245a d314 a14c 0d18
     efd6 38aa e653 c908 a7ab c648 0a7f 4068
     2479 c970 8aaa abc3 eb7e da28 9d06 d535
    
    Calculated MIC with "10zZz10ZZzZ" is
     4528 2522 bc67 07d6 a70a 0317 a3ed 48f0
    

Maybe someone of you could tell me, why my program simply doesn't work. Do the
hmac-functions work correctly? Is my input formatted wrong? Do I have to
regard endianess anywhere? Thanks for your time in advance, I would appreciate
any help!


Answer: Alright, I figured it out by myself... more by desperate testing and some
luck, than successful research, which lead to nothing long enough. Instead of
using the MAC-adresses and nonces as the strings they were, I had to unhexlify
them. I used

    
    
    a2b_hex() #alternatively unhexlify()
    

My final code looks somewhat like this, defs excluded:

    
    
    import hmac,hashlib,binascii
    passPhrase="10zZz10ZZzZ"
    ssid        = "Netgear 2/158"
    A           = "Pairwise key expansion"
    APmac       = a2b_hex("001e2ae0bdd0")
    Clientmac   = a2b_hex("cc08e0620bc8")
    ANonce      = a2b_hex("61c9a3f5cdcdf5fae5fd760836b8008c863aa2317022c7a202434554fb38452b")
    SNonce      = a2b_hex("60eff10088077f8b03a0e2fc2fc37e1fe1f30f9f7cfbcfb2826f26f3379c4318")
    B           = min(APmac,Clientmac)+max(APmac,Clientmac)+min(ANonce,SNonce)+max(ANonce,SNonce)
    data        = a2b_hex("0103005ffe01090020000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
    
    pmk     = pbkdf2(passPhrase, ssid, 4096, 32) 
    ptk     = customPRF512(pmk,A,B)
    mic     = hmac.new(ptk[0:16],data)
    
    print "desiredpmk:\t","01b809f9ab2fb5dc47984f52fb2d112e13d84ccb6b86d4a7193ec5299f851c48"
    print "pmk:\t\t",b2a_hex(pmk),"\n"
    print "desired ptk:\t","bf49a95f0494f44427162f38696ef8b6"
    print "ptk:\t\t",b2a_hex(ptk[0:16]),"\n"
    print "desired mic:\t","45282522bc6707d6a70a0317a3ed48f0"
    print "mic:\t\t",mic.hexdigest(),"\n"
    

So the answers to my questions were: yes, hashfunctions work correctly, yes,
input is formatted wrong, no, no endianess-issues.

