MAC Calculation help needed

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

MAC Calculation help needed

Suchindra Chandrahas
Hi All,
             I am doing the following to calculate MAC
as per SSL v3 handshake:

        printf("\nRESULT: Plain Record encryption:\n");
                for ( i = 0; i < rec_len; i ++)
                        printf("%x ", rec[i]);

                total_length = rec_len + 16
                /* 16 is the size of MAC */

                s2n(tot_len, p);
                MD5_Init(&ctx);
                MD5_Update(&ctx,ssl->wMACptr,16);
/* Doubtful here. wMACptr is Write MAC key of the
client. However, i am not sure whether to use wMACkey
or do a RC4_set_key(wMACptr...) and then use the
result */
                MD5_Update(&ctx,pad_1_md5,48);


                /* The following sequence is only for 2 digit
sequence number as of now
            but the total sequence number is 8 bytes
unsigned char representation */

                seq[0] = (ssl->write_seq & 0xff00)>>8;
                seq[1] = ssl->write_seq & 0xff;
                MD5_Update(&ctx, seq, 8);

                ihash[0] = 0;
                MD5_Update(&ctx, ihash, 1);


                ihash[0] = (rec_len & 0xff00) >>8;
                ihash[1] = rec_len & 0xff;
                MD5_Update(&ctx, ihash, 2);
                MD5_Update(&ctx, rec, rec_len);
                MD5_Final(dgst,&ctx);
                //MD5_Init(&ctx);
               
                MD5_Update(&ctx,ssl->wMACptr,16);
                MD5_Update(&ctx,pad_2_md5,48);
                MD5_Update(&ctx,dgst,16);
                MD5_Final(dgst,&ctx);


                printf("\n\nRESULT: MAC Calculated:\n");
                for ( i = 0; i < 16; i ++)
                        printf("%x ", dgst[i]);

                for ( i = 0; i < rec_len; i ++)
                        *p++ = rec[i];
                for (i = 0; i < 16; i ++)
                        *p++ = dgst[i];

                printf("\nINFO: Record Unencrypted:\n");
                for ( i = 5; i < tot_len + 5; i ++)
                        printf("%x ", buf[i]);

Does the calculation of MD5 (stream cipher is used in
this case, RC4-128), require a separate RC4_set_key()
function to be used on ssl->wMACptr (Write MAC key of
client)?

I just modified Wireshark to print all the keys etc
during SSL packet sniffing, and it uses 64 byte key
material. However, my Write MAC key, Read MAC key,
Write Key, Read Key are all fine as per comparison

I am implementing an opensource ssl fuzzing client
without using openssl libraries extensively

Thanks for your help in advance, and Regards,
Suchindra Chandrahas


      ____________________________________________________________________________________
Be a better friend, newshound, and
know-it-all with Yahoo! Mobile.  Try it now.  http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ 

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: MAC Calculation help needed

Marek.Marcola
On Mon, 2007-12-17 at 19:39 -0800, Suchindra Chandrahas wrote:

> Hi All,
>              I am doing the following to calculate MAC
> as per SSL v3 handshake:
>
> printf("\nRESULT: Plain Record encryption:\n");
> for ( i = 0; i < rec_len; i ++)
> printf("%x ", rec[i]);
>
>                 total_length = rec_len + 16
>                 /* 16 is the size of MAC */
>
> s2n(tot_len, p);
> MD5_Init(&ctx);
> MD5_Update(&ctx,ssl->wMACptr,16);
> /* Doubtful here. wMACptr is Write MAC key of the
> client. However, i am not sure whether to use wMACkey
> or do a RC4_set_key(wMACptr...) and then use the
> result */
> MD5_Update(&ctx,pad_1_md5,48);
>
>
> /* The following sequence is only for 2 digit
> sequence number as of now
>   but the total sequence number is 8 bytes
> unsigned char representation */
>
> seq[0] = (ssl->write_seq & 0xff00)>>8;
> seq[1] = ssl->write_seq & 0xff;
> MD5_Update(&ctx, seq, 8);
>
> ihash[0] = 0;
> MD5_Update(&ctx, ihash, 1);
>
>
> ihash[0] = (rec_len & 0xff00) >>8;
> ihash[1] = rec_len & 0xff;
> MD5_Update(&ctx, ihash, 2);
> MD5_Update(&ctx, rec, rec_len);
> MD5_Final(dgst,&ctx);
> //MD5_Init(&ctx);
>
> MD5_Update(&ctx,ssl->wMACptr,16);
> MD5_Update(&ctx,pad_2_md5,48);
> MD5_Update(&ctx,dgst,16);
> MD5_Final(dgst,&ctx);
>
>
> printf("\n\nRESULT: MAC Calculated:\n");
> for ( i = 0; i < 16; i ++)
> printf("%x ", dgst[i]);
>
> for ( i = 0; i < rec_len; i ++)
> *p++ = rec[i];
> for (i = 0; i < 16; i ++)
> *p++ = dgst[i];
>
> printf("\nINFO: Record Unencrypted:\n");
> for ( i = 5; i < tot_len + 5; i ++)
> printf("%x ", buf[i]);
>
> Does the calculation of MD5 (stream cipher is used in
> this case, RC4-128), require a separate RC4_set_key()
> function to be used on ssl->wMACptr (Write MAC key of
> client)?
SSL record MAC calculation is independent of negotiated stream cipher
(and stream cipher is not used in this MAC calculation)

Example code of SSL packet MAC calculation:
-------------------------------------------

/**
 * Calculate SSL3 record message digest.
 *
 * @param    ssl     SSL parameters
 * @param    role    local role    
 * @param    proto   record layer protocol
 * @param    buf     buffer
 * @param    len     buffer length
 * @param    dgst    return record message digest
 * @return    0
 */
int ssl3_md(ssl_t * ssl, int role, int proto, char *buf, int len, uint8_t * dgst)
{
    md_t md;
    uint8_t *mac;
    uint8_t *seq;
    uint8_t tmp[3];
    int i;

    LOG_API4("ssl=[%p],proto=%d,len=%d,role=%d", ssl, proto, len, role);

    if (role == SSL_SERVER) {
        mac = ssl->server_mac;
        seq = ssl->server_seq;
    } else {
        mac = ssl->client_mac;
        seq = ssl->client_seq;
    }

    md_init(&md, ssl->md_id);
    md_update(&md, mac, md.size);
    md_update(&md, pad_1, 40);
    md_update(&md, seq, 8);
    tmp[0] = (uint8_t) (proto);
    tmp[1] = (uint8_t) (len >> 8 & 0xFF);
    tmp[2] = (uint8_t) (len >> 0 & 0xFF);
    md_update(&md, tmp, sizeof(tmp));
    md_update(&md, buf, len);
    md_final(&md, dgst, NULL);

    md_init(&md, ssl->md_id);
    md_update(&md, mac, md.size);
    md_update(&md, pad_2, 40);
    md_update(&md, dgst, md.size);
    md_final(&md, dgst, NULL);

    /* increment packet sequence number */
    for (i = 7; i >= 0; i--) {
        seq[i]++;
        if (seq[i] != 0) {
            break;
        }
    }

    LOG_API4("rc=%d", 0);
    return (0);
}

Best regards,
--
Marek Marcola <[hidden email]>

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: MAC Calculation help needed

Suchindra Chandrahas
Hi Merek,
                   Thanks a lot for replying! I changed a lot of code and downloaded wireshark source and made debug messages larger in number. I finally debugged step by step and kept on rectifying the code.

Now the MAC is fine!!!
Wireshark Debug Messages Say So!

I am getting the error:

31218:error:1408E098:SSL routines:SSL3_GET_MESSAGE:excessive message size:s3_both.c:449



Saw in openssl code and this one is seen:

                  /* At this point we have got an MS SGC second client
                         * hello (maybe we should always allow the client to
                         * start a new handshake?). We need to restart the mac.
                         * Don't increment {num,total}_renegotiations because
                         * we have not completed the handshake. */
                        ssl3_init_finished_mac(s);
                        }

                s->s3->tmp.message_type= *(p++);

                n2l3(p,l);
                if (l > (unsigned long)max)
                        {
                        al=SSL_AD_ILLEGAL_PARAMETER;
                        SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_EXCESSIVE_MESSAGE_SIZE);
                        goto f_err;
                        }
                if (l > (INT_MAX-4)) /* BUF_MEM_grow takes an 'int' parameter */
                        {
                        al=SSL_AD_ILLEGAL_PARAMETER;
                        SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_EXCESSIVE_MESSAGE_SIZE);
                        goto f_err;
                        }
                if (l && !BUF_MEM_grow_clean(s->init_buf,(int)l+4))
                        {
                        SSLerr(SSL_F_SSL3_GET_MESSAGE,ERR_R_BUF_LIB);
                        goto err;
                        }


It openssl expecting any parameter that i am not passing?, or does the mistake mean something related to a part of ClientFinished message?

Thanks and Regards,
Suchindra Chandrahas


Marek Marcola <[hidden email]> wrote:
On Mon, 2007-12-17 at 19:39 -0800, Suchindra Chandrahas wrote:

> Hi All,
> I am doing the following to calculate MAC
> as per SSL v3 handshake:
>
> printf("\nRESULT: Plain Record encryption:\n");
> for ( i = 0; i < rec_len; i ++)
> printf("%x ", rec[i]);
>
> total_length = rec_len + 16
> /* 16 is the size of MAC */
>
> s2n(tot_len, p);
> MD5_Init(&ctx);
> MD5_Update(&ctx,ssl->wMACptr,16);
> /* Doubtful here. wMACptr is Write MAC key of the
> client. However, i am not sure whether to use wMACkey
> or do a RC4_set_key(wMACptr...) and then use the
> result */
> MD5_Update(&ctx,pad_1_md5,48);
>
>
> /* The following sequence is only for 2 digit
> sequence number as of now
> but the total sequence number is 8 bytes
> unsigned char representation */
>
> seq[0] = (ssl->write_seq & 0xff00)>>8;
> seq[1] = ssl->write_seq & 0xff;
> MD5_Update(&ctx, seq, 8);
>
> ihash[0] = 0;
> MD5_Update(&ctx, ihash, 1);
>
>
> ihash[0] = (rec_len & 0xff00) >>8;
> ihash[1] = rec_len & 0xff;
> MD5_Update(&ctx, ihash, 2);
> MD5_Update(&ctx, rec, rec_len);
> MD5_Final(dgst,&ctx);
> //MD5_Init(&ctx);
>
> MD5_Update(&ctx,ssl->wMACptr,16);
> MD5_Update(&ctx,pad_2_md5,48);
> MD5_Update(&ctx,dgst,16);
> MD5_Final(dgst,&ctx);
>
>
> printf("\n\nRESULT: MAC Calculated:\n");
> for ( i = 0; i < 16; i ++)
> printf("%x ", dgst[i]);
>
> for ( i = 0; i < rec_len; i ++)
> *p++ = rec[i];
> for (i = 0; i < 16; i ++)
> *p++ = dgst[i];
>
> printf("\nINFO: Record Unencrypted:\n");
> for ( i = 5; i < tot_len + 5; i ++)
> printf("%x ", buf[i]);
>
> Does the calculation of MD5 (stream cipher is used in
> this case, RC4-128), require a separate RC4_set_key()
> function to be used on ssl->wMACptr (Write MAC key of
> client)?
SSL record MAC calculation is independent of negotiated stream cipher
(and stream cipher is not used in this MAC calculation)

Example code of SSL packet MAC calculation:
-------------------------------------------

/**
* Calculate SSL3 record message digest.
*
* @param ssl SSL parameters
* @param role local role
* @param proto record layer protocol
* @param buf buffer
* @param len buffer length
* @param dgst return record message digest
* @return 0
*/
int ssl3_md(ssl_t * ssl, int role, int proto, char *buf, int len, uint8_t * dgst)
{
md_t md;
uint8_t *mac;
uint8_t *seq;
uint8_t tmp[3];
int i;

LOG_API4("ssl=[%p],proto=%d,len=%d,role=%d", ssl, proto, len, role);

if (role == SSL_SERVER) {
mac = ssl->server_mac;
seq = ssl->server_seq;
} else {
mac = ssl->client_mac;
seq = ssl->client_seq;
}

md_init(&md, ssl->md_id);
md_update(&md, mac, md.size);
md_update(&md, pad_1, 40);
md_update(&md, seq, 8);
tmp[0] = (uint8_t) (proto);
tmp[1] = (uint8_t) (len >> 8 & 0xFF);
tmp[2] = (uint8_t) (len >> 0 & 0xFF);
md_update(&md, tmp, sizeof(tmp));
md_update(&md, buf, len);
md_final(&md, dgst, NULL);

md_init(&md, ssl->md_id);
md_update(&md, mac, md.size);
md_update(&md, pad_2, 40);
md_update(&md, dgst, md.size);
md_final(&md, dgst, NULL);

/* increment packet sequence number */
for (i = 7; i >= 0; i--) {
seq[i]++;
if (seq[i] != 0) {
break;
}
}

LOG_API4("rc=%d", 0);
return (0);
}

Best regards,
--
Marek Marcola

______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List [hidden email]
Automated List Manager [hidden email]


Looking for last minute shopping deals? Find them fast with Yahoo! Search.
Reply | Threaded
Open this post in threaded view
|

Re: MAC Calculation help needed

Suchindra Chandrahas
In reply to this post by Marek.Marcola
Hi Merek,
                     In the following function,
md_update(&md, pad_2, 40);
                     Is pad_2 and pad_1 (before), of size 40 bytes. I think i am a wrong somewhere, cos i put them as 48 bytes for md5 and 40 bytes for sha

Please let me know if i am wrong

Thanks and Regards,
Suchindra Chandrahas



Marek Marcola <[hidden email]> wrote:
On Mon, 2007-12-17 at 19:39 -0800, Suchindra Chandrahas wrote:

> Hi All,
> I am doing the following to calculate MAC
> as per SSL v3 handshake:
>
> printf("\nRESULT: Plain Record encryption:\n");
> for ( i = 0; i < rec_len; i ++)
> printf("%x ", rec[i]);
>
> total_length = rec_len + 16
> /* 16 is the size of MAC */
>
> s2n(tot_len, p);
> MD5_Init(&ctx);
> MD5_Update(&ctx,ssl->wMACptr,16);
> /* Doubtful here. wMACptr is Write MAC key of the
> client. However, i am not sure whether to use wMACkey
> or do a RC4_set_key(wMACptr...) and then use the
> result */
> MD5_Update(&ctx,pad_1_md5,48);
>
>
> /* The following sequence is only for 2 digit
> sequence number as of now
> but the total sequence number is 8 bytes
> unsigned char representation */
>
> seq[0] = (ssl->write_seq & 0xff00)>>8;
> seq[1] = ssl->write_seq & 0xff;
> MD5_Update(&ctx, seq, 8);
>
> ihash[0] = 0;
> MD5_Update(&ctx, ihash, 1);
>
>
> ihash[0] = (rec_len & 0xff00) >>8;
> ihash[1] = rec_len & 0xff;
> MD5_Update(&ctx, ihash, 2);
> MD5_Update(&ctx, rec, rec_len);
> MD5_Final(dgst,&ctx);
> //MD5_Init(&ctx);
>
> MD5_Update(&ctx,ssl->wMACptr,16);
> MD5_Update(&ctx,pad_2_md5,48);
> MD5_Update(&ctx,dgst,16);
> MD5_Final(dgst,&ctx);
>
>
> printf("\n\nRESULT: MAC Calculated:\n");
> for ( i = 0; i < 16; i ++)
> printf("%x ", dgst[i]);
>
> for ( i = 0; i < rec_len; i ++)
> *p++ = rec[i];
> for (i = 0; i < 16; i ++)
> *p++ = dgst[i];
>
> printf("\nINFO: Record Unencrypted:\n");
> for ( i = 5; i < tot_len + 5; i ++)
> printf("%x ", buf[i]);
>
> Does the calculation of MD5 (stream cipher is used in
> this case, RC4-128), require a separate RC4_set_key()
> function to be used on ssl->wMACptr (Write MAC key of
> client)?
SSL record MAC calculation is independent of negotiated stream cipher
(and stream cipher is not used in this MAC calculation)

Example code of SSL packet MAC calculation:
-------------------------------------------

/**
* Calculate SSL3 record message digest.
*
* @param ssl SSL parameters
* @param role local role
* @param proto record layer protocol
* @param buf buffer
* @param len buffer length
* @param dgst return record message digest
* @return 0
*/
int ssl3_md(ssl_t * ssl, int role, int proto, char *buf, int len, uint8_t * dgst)
{
md_t md;
uint8_t *mac;
uint8_t *seq;
uint8_t tmp[3];
int i;

LOG_API4("ssl=[%p],proto=%d,len=%d,role=%d", ssl, proto, len, role);

if (role == SSL_SERVER) {
mac = ssl->server_mac;
seq = ssl->server_seq;
} else {
mac = ssl->client_mac;
seq = ssl->client_seq;
}

md_init(&md, ssl->md_id);
md_update(&md, mac, md.size);
md_update(&md, pad_1, 40);
md_update(&md, seq, 8);
tmp[0] = (uint8_t) (proto);
tmp[1] = (uint8_t) (len >> 8 & 0xFF);
tmp[2] = (uint8_t) (len >> 0 & 0xFF);
md_update(&md, tmp, sizeof(tmp));
md_update(&md, buf, len);
md_final(&md, dgst, NULL);

md_init(&md, ssl->md_id);
md_update(&md, mac, md.size);
md_update(&md, pad_2, 40);
md_update(&md, dgst, md.size);
md_final(&md, dgst, NULL);

/* increment packet sequence number */
for (i = 7; i >= 0; i--) {
seq[i]++;
if (seq[i] != 0) {
break;
}
}

LOG_API4("rc=%d", 0);
return (0);
}

Best regards,
--
Marek Marcola

______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List [hidden email]
Automated List Manager [hidden email]


Never miss a thing. Make Yahoo your homepage.
Reply | Threaded
Open this post in threaded view
|

Re: MAC Calculation help needed

Marek.Marcola
On Tue, 2007-12-18 at 07:38 -0800, Suchindra Chandrahas wrote:
> Hi Merek,
>                      In the following function,
> md_update(&md, pad_2, 40);
>                      Is pad_2 and pad_1 (before), of size 40 bytes. I
> think i am a wrong somewhere, cos i put them as 48 bytes for md5 and
> 40 bytes for sha
>
> Please let me know if i am wrong
You are right, this implemetation does not use md5 and this record MAC
calculation use 40 bytes of pad1 and pad2. If, for example, negotiated
ciphersuite will be DES-CBC3-MD5 then in record MAC calculation you
should use 48 bytes of pad1 and pad2.

Best regards,
--
Marek Marcola <[hidden email]>

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]