how to generate peapv0-mschapv2 ms-mppe keys?

574 views Asked by At

I am developing a custom radius server to authenticate wireless clients, using peapv0-mschapv2, at the final step, not sure how to generate the ms-mppe-send-key and ms-mppe-revc-key within the Access-Accept packet, i have follow rfc3079 to generate a 128 bit session keys, but with the last step, not sure what to do with the rc4_key() function,

from rfc3079

GetNewKeyFromSHA(MasterSendKey, MasterSendKey, 16, SendSessionKey) GetNewKeyFromSHA(MasterReceiveKey, MasterReceiveKey, 16, ReceiveSessionKey)

Finally, the RC4 tables are initialized using the new session keys:

  rc4_key(SendRC4key, 16, SendSessionKey)
  rc4_key(ReceiveRC4key, 16, ReceiveSessionKey)

i generated a 16 bytes SendSessionKey and a 16 bytes ReceiveSessionKey, but not sure about where SendRC4Key and ReceiveRC4Key come from. doesn't say with rfc :(

then i tried to use SendSessionKey and ReceiveSessionKey to follow rfc2548 and encrypted a ms-mppe-send-key and ms-mppe-recv-key and send to client, but doesn't work, client keep resetting and start over from client hello. when i do some searching online, looks like free radius using 32 bytes keys to do the encryption and send to client. not sure how to get a 32 bytes SendSessionKey too. Thank you advance for any help!!

1

There are 1 answers

0
YanXi On BEST ANSWER

I had found out that peapv0-ms-chapv2 use tls material to generate two 32 bytes keys. rfc didn't make it clear, confuse me until i try to use the tls method to generate the keys and give it a try, and it worked.

public static void ComputeMPPEKeys(byte[] masterSecret, byte[] ClientRandom, byte[] serverRandom, out byte[] mppeSendKey, out byte[] mppeRecvKey)
    {
        //PRF(master secret, "client EAP encryption", random) is computed up to 128 bytes, 
        //the value random defined as the concatenation of the handshake message fields client_hello.random and server_hello.random(in that order),
        //and the value PRF("", "client EAP encryption", random) is computed up to 64 bytes(where "" is an empty string).
        var random = new List<byte>();
        random.AddRange(ClientRandom);
        random.AddRange(serverRandom);
        var label = "client EAP encryption";
        var firstResult = PRF(masterSecret, label, random.ToArray(), 128);

        //not really needed
        var secondResult = PRF(new byte[0], label, random.ToArray(), 64);

        mppeRecvKey = firstResult.Take(32).ToArray();
        mppeSendKey = firstResult.Skip(32).Take(32).ToArray();

    }