Re: questions about PRF in eap-sim-11.txt
From: Michael Richardson (mcrsandelman.ottawa.on.ca)
Date: Mon, 15 Sep 2003 22:02:34 -0500 (CDT)
-----BEGIN PGP SIGNED MESSAGE-----


>>>>> "Joseph" == Joseph Salowey <jsalowey [at] cisco.com> writes:
    Joseph> Unfortunately this is not quite as trivial as it seems. The NIST
    Joseph> documents are confusing. 

    Joseph> Although the function G is derived from SHA-1 my interpretation
    Joseph> of  FIPS 186-2 Appendix 3.3 is that it is slightly different.  In
    Joseph> particular in SHA-1 the length is appended to the message and in
    Joseph> function G it is not. 

  Aha. Thank you for this explanation.
  After a bit of code reading, I have the following code:

(regular sha1.c code...)

void SHA1FinalNoLen(unsigned char digest[20], SHA1_CTX* context)
{
  unsigned long i, j;

    for (i = 0; i < 20; i++) {
        digest[i] = (unsigned char)
         ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
    }

    /* Wipe variables */
    i = j = 0;
    memset(context->buffer, 0, 64);
    memset(context->state, 0, 20);
    memset(context->count, 0, 8);

#ifdef SHA1HANDSOFF  /* make SHA1Transform overwrite it's own static vars */
    SHA1Transform(context->state, context->buffer);
#endif
}

/*
 * we do it in 8-bit chunks, because we have to keep the numbers
 * in network byte order (i.e. MSB)
 *
 * make it a structure so that we can do structure assignments.
 */
typedef struct onesixty {
        u_int8_t p[20];
} onesixty;

static void onesixty_add_mod(onesixty *sum, onesixty *a, onesixty *b)
{
        u_int32_t s;
        int i, carry;

        carry = 0;
        for(i=19; i>=0; i--) { 
                s = a->p[i] + b->p[i] + carry;
                sum->p[i] = s & 0xff;
                carry = s >> 8;
        }
}

void fips186_2prf(u_int8_t mk[20], u_int8_t finalkey[160])
{
        SHA1_CTX context;
        int j, s;
        onesixty xval, xkey, w_0, w_1, sum, one;
        u_int8_t *f;
        char zeros[64];
        
        /*
         * let XKEY := MK,
         *
         * Step 3: For j = 0 to 3 do     
         *   a. XVAL = XKEY 
         *   b. w_0 = SHA1(XVAL) 
         *   c. XKEY = (1 + XKEY + w_0) mod 2^160
         *   d. XVAL = XKEY 
         *   e. w_1 = SHA1(XVAL) 
         *   f. XKEY = (1 + XKEY + w_1) mod 2^160
         * 3.3 x_j = w_0|w_1 
         *
         */
        memcpy(&xkey, mk, sizeof(xkey));
        
        /* make the value 1 */
        memset(&one,  0, sizeof(one));
        one.p[19]=1;
        
        f=finalkey;
        
        for(j=0; j<3; j++) {
                /*   a. XVAL = XKEY  */
                xval = xkey;
                
                /*   b. w_0 = SHA1(XVAL)  */
                SHA1Init(&context);

                memset(zeros, 0, sizeof(zeros));
                memcpy(zeros, xval.p, 20);
                SHA1Transform(context.state, zeros);
                SHA1FinalNoLen(w_0.p, &context);
                
                /*   c. XKEY = (1 + XKEY + w_0) mod 2^160 */
                onesixty_add_mod(&sum,  &xkey, &w_0);
                onesixty_add_mod(&xkey, &sum,  &one);
                
                /*   d. XVAL = XKEY  */
                xval = xkey;
                
                /*   e. w_1 = SHA1(XVAL)  */
                SHA1Init(&context);

                memset(zeros, 0, sizeof(zeros));
                memcpy(zeros, xval.p, 20);
                SHA1Transform(context.state, zeros);
                SHA1FinalNoLen(w_1.p, &context);
                
                /*   f. XKEY = (1 + XKEY + w_1) mod 2^160 */
                onesixty_add_mod(&sum,  &xkey, &w_1);
                onesixty_add_mod(&xkey, &sum,  &one);
                
                /* now store it away */
                memcpy(f, &w_0, 20);
                f += 20;
                
                memcpy(f, &w_1, 20);
                f += 20;
        }
}

]      Out and about in Ottawa.    hmmm... beer.                |  firewalls  [
]   Michael Richardson, Sandelman Software Works, Ottawa, ON    |net architect[
] mcr [at] sandelman.ottawa.on.ca http://www.sandelman.ottawa.on.ca/ |device 
driver[
] panic("Just another Debian/notebook using, kernel hacking, security guy");  [
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (GNU/Linux)
Comment: Finger me for keys - custom hacks make this fully PGP2 compat

iQCVAwUBP2Z8/4qHRg3pndX9AQFn8QP/RmPkYoPXdBs4oTatJW06+atLAZvlY8E0
wTGD7+v1PQ3lMbl/oMUM2jXzxKCldoljCGtSt/BfynEHsOn1cvdu/KlyI3Fu6+nu
0MqmAo8O/l3/zT5gXb/ARkKirehRzM5pyjLhlLK8CGK4a/e/ic4mQUmlZXap9Ymx
8FMcRvObPOU=
=QUyY
-----END PGP SIGNATURE-----

Results generated by Tiger Technologies using MHonArc.