problem with encryption function sending hex values

Discussion in 'C Programming' started by Fernando Barsoba, Nov 27, 2005.

  1. Dear all,

    I have been posting about a problem trying to encrypt certain data using
    HMAC-SHA1 functions. I posted that my problem was solved, but
    unfortunately, I was being overly optimistic. I am really desperate now,
    because I havent' been able to locate the origin of the problem for a
    couple of days now..

    PROBLEM: the message digest obtained differs each time I execute the
    code, but works perfectly when applying the "control", that is the test
    case #3 from RFC 2202 that I show below.

    I did my best trying to create a code that can be compiled and executed
    and that clearly shows the problem. I would really appreciate any help,
    I have to finish this project in a couple of days and I have been stuck
    here for a long while..

    Explanation of functions:
    - I send an array over a function that obtains a message digest applying
    hmac-sha1. This authentication function requires a message and a key.
    The message simulates and IP header of lenght=31 (I hardcoded the value
    for clarity).
    - The 'build_ip_packet' function does bit manipulatation therefore the
    final message is just gibberish, but their hexadecimal content is valid
    and represents the ip packet.
    - I treat the message with the function 'hexString_to_hexRepresent'
    because I thought that this translation had to be made (hex to its hex
    representation)
    - Finally, 'icv_Calculation' performs the message digest calculation.
    - 'icv_Calculation_test' uses the same function but sends to it the test
    case #3 from RFC 2202
    - 'pr_hexstring' prints out the result.

    RFC 2202 has different test cases. #3 is the following:
    test_case = 3
    key = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
    key_len = 20
    data = 0xdd repeated 50 times
    data_len = 50
    digest = 0x125d7342b9ac11cd91a39af48aa17b4f63f175d3

    http://www.zvon.org/tmRFC/RFC2202/Output/index.html

    As you can see executing the program, I get the correct result in my
    second icv call. However, the first call shows completely different
    results each time I call it. Why is that?

    output:
    $ ./icv_test.exe
    0xf28b25b3793ff29a248932ebe8fa6114934be0f2
    0x125d7342b9ac11cd91a39af48aa17b4f63f175d3

    Again, thank you in advance for any help that you can provide me.

    I attach the complete code. It's a lot, but if someone wants to try,
    they are complementary functions that are needed but they are not the
    origin of the problem. 'main' and first level functions is where the
    core of the problem may be.

    You may find string conversions which may not have much sense.. i
    apologize for that, I can't think clearly anymore.. :-(

    Fernando

    -------------------------- main.c ----------------
    #include <netinet/in.h> /* sockaddr_in{} and other Internet defns */
    #include <arpa/inet.h> /* inet(3) functions */
    #include <errno.h>
    #include <netdb.h>
    #include <signal.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <netinet/ip.h>
    #include <sys/types.h>

    #include "hmac-sha1.h"


    #define HEADER_OFFSET 20
    #define IP_VERSION 4

    typedef struct {
    char * message;
    char dest_ip[20];
    char src_ip[20];
    int msg_length;
    int port;
    char * key;
    char algorithm;
    } CONF_PARAMS;

    void build_ip_packet(unsigned char *packet, unsigned short length,
    CONF_PARAMS *cnf) {
    struct ip *iphdr;
    int packet_size;

    struct in_addr ipsrc_addr, ipdst_addr; /* 'in_addr' structures needed
    to change byte ordering */

    packet_size = sizeof(struct ip) + cnf->msg_length; /* obtain size
    for datagram */

    bzero(packet, packet_size); /* fills with 0; deprecated, change
    with memset */
    iphdr = (struct ip *)packet; /* assign ip header structure to our
    IP packet */

    inet_aton(cnf->src_ip, &ipsrc_addr);
    inet_aton(cnf->dest_ip, &ipdst_addr);

    /* IP header construction */
    iphdr->ip_v = IP_VERSION; /* version = 4, IP */
    iphdr->ip_hl = 5; /* length = 5, no option */
    iphdr->ip_tos = 0;
    iphdr->ip_len = htons(length); /* length of the datagram */
    iphdr->ip_id = htons(getpid()); /* identification for this packet,
    assigned process id */
    iphdr->ip_off = 0;
    iphdr->ip_ttl = 64; /* time to live = 64 */
    iphdr->ip_p = 51; /* protocol number = 51, AH code */
    iphdr->ip_src = ipsrc_addr;
    iphdr->ip_dst = ipdst_addr;
    iphdr->ip_sum = 0;

    // iphdr->ip_sum = in_cksum((u_short *) iphdr, (iphdr->ip_hl) << 2);
    /* calculate checksum */

    memcpy(packet + HEADER_OFFSET, cnf->message, cnf->msg_length); /* copy
    data to end ip packet, which is
    20 bytes by default. If options included,
    this value has to be changed */
    return;
    }

    /* Convert the single hexadecimal digit 'c' to the corresponding
    integer, or -1 if 'c' is not a hex digit. */
    int hexdigit_to_int(char c) {
    if (c >= '0' && c <= '9') return c - '0';
    switch (c) {
    case 'a': case 'A': return 10;
    case 'b': case 'B': return 11;
    case 'c': case 'C': return 12;
    case 'd': case 'D': return 13;
    case 'e': case 'E': return 14;
    case 'f': case 'F': return 15;
    default: {
    return -1;
    }
    }
    }


    /* Convert the hexadecimal representation of a sequence of bytes to
    the sequence of bytes. */
    /* Returns a malloc()-allocated block of strlen(hex) / 2 bytes if
    successful or a null pointer otherwise. */
    unsigned char* hexstr_to_bytes(const char* hex) {
    size_t l = strlen(hex);
    size_t n = 0;
    unsigned char* result;
    if (l % 2 != 0) return NULL;

    result = malloc(l / 2);
    if (!result) return NULL;

    for (n = 0; n < l; n += 2) {
    int d1 = hexdigit_to_int(hex[n]);
    int d2 = hexdigit_to_int(hex[n+1]);
    if (d1 < 0 || d2 < 0) {
    free(result);
    return NULL;
    }
    result[n/2] = (d1 << 4) + d2;
    }
    return result;
    }


    unsigned char* hexString_to_hexRepresent(const char *payload, const char
    *hexvalue, int payload_size, int output_size) {
    int ii, tt=payload_size;
    unsigned char hexvalue2[payload_size*2];
    memcpy(hexvalue2, hexvalue, payload_size*2);
    for (ii = 0 ; ii < tt ; ii++)
    sprintf(hexvalue2+(ii*2), "%02x", payload[ii]);
    unsigned char *msgICV;
    msgICV = hexstr_to_bytes(hexvalue2);
    return msgICV;
    }

    void icv_Calculation_test(char p_output[20]) {
    uint8_t
    tmp_msgtest[]="DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD";
    char tmp_key[]="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
    unsigned char* key, *msgtest;
    key = hexstr_to_bytes(tmp_key);
    msgtest = hexstr_to_bytes(tmp_msgtest);
    uint8_t outputsha[20];

    int size_message, size_key;
    size_message = strlen(msgtest);
    size_key = strlen(key)-1;

    hmac_sha(key, size_key, msgtest, size_message, outputsha,
    sizeof(outputsha));
    strcpy(p_output, outputsha);
    free(key);
    free(msgtest);
    return;
    }

    unsigned char * icv_Calculation(unsigned char *hdrs, int hdrs_len,
    CONF_PARAMS *cnf, uint8_t *output, int output_len) {
    unsigned char outputshax[20];
    unsigned char payloadh[hdrs_len];
    memcpy(payloadh, hdrs, hdrs_len);

    if (cnf->algorithm == 's' )
    hmac_sha(cnf->key,strlen(cnf->key), payloadh, hdrs_len, outputshax,
    sizeof(outputshax));

    unsigned char * ret_output=malloc(20);
    memcpy(ret_output, outputshax, 20);
    return ret_output;
    }


    /* Function to print strings in hex */
    void pr_hexstring(FILE* fp, unsigned char* s, int t) {
    int i;
    fprintf(fp, "0x");
    for (i = 0 ; i < t ; i++) {
    fprintf(fp, "%02x", s);
    }
    fprintf(fp, "\n");
    }



    int main(int argc, char **argv) {
    CONF_PARAMS * cnf;
    cnf = malloc(sizeof(*cnf));

    cnf->message = "hello world";
    cnf->key = "Jefe";
    strcpy(cnf->dest_ip, "192.168.2.2");
    strcpy(cnf->src_ip, "192.168.2.2");
    cnf->msg_length = strlen(cnf->message);
    cnf->algorithm='s';

    unsigned char packet[31];
    build_ip_packet(packet, sizeof(packet), cnf);

    unsigned char m_output[20];
    unsigned char d_packet[sizeof(packet)*2];
    unsigned char * p_icv = hexString_to_hexRepresent(packet, d_packet ,
    sizeof(packet), strlen(m_output));

    unsigned char *ret_output = icv_Calculation(p_icv, 31, cnf, m_output, 20);

    pr_hexstring(stdout, ret_output, 20);

    char p_output_sha[20];
    icv_Calculation_test(p_output_sha);

    pr_hexstring(stdout, p_output_sha, 20);

    free(ret_output);
    free(p_icv);
    free(cnf);
    exit(0);
    }


    ---------------------------------------------------------------

    ---------------------- hmac-sha1.h ----------------------------

    #ifndef HMACSHA1_H_
    #define HMACSHA1_H_

    #include "sha1.h"


    #ifndef SHA_DIGESTSIZE
    #define SHA_DIGESTSIZE 20
    #endif

    #ifndef SHA_BLOCKSIZE
    #define SHA_BLOCKSIZE 64
    #endif

    void pr_sha(FILE*, unsigned char*, int);
    void truncate_sha1 (uint8_t*, uint8_t*, int);
    void hmac_sha (uint8_t*, int, uint8_t*, int, uint8_t*, int);

    #endif /*HMACSHA1_H_*/

    ---------------------------------------------------------------


    ---------------------- hmac-sha1.c ----------------------------
    #include <stdio.h>
    #include "sha1.h"
    #include "hmac-sha1.h"
    /*
    * From sha1.h ------------------------
    *
    * sha1_context;
    * void sha1_starts( sha1_context *ctx );
    * void sha1_update( sha1_context *ctx, uint8 *input, uint32 length );
    * void sha1_finish( sha1_context *ctx, uint8 digest[20] );
    *
    */

    /* Function to print the digest */
    void pr_sha(FILE* fp, unsigned char* s, int t) {
    int i;
    fprintf(fp, "0x");
    for (i = 0 ; i < t ; i++)
    fprintf(fp, "%02x", s);
    fprintf(fp, "0");
    }

    void truncate_sha1 (
    uint8_t* d1, /* data to be truncated */
    uint8_t* d2, /* truncated data */
    int len /* length in bytes to keep */
    ) {
    int i;
    for (i=0; i < len; i++)
    d2 = d1;
    }

    /* Function to compute the digest */
    void hmac_sha (
    uint8_t* k, /* secret key */
    int lk, /* length of the key in bytes */
    uint8_t* d, /* data */
    int ld, /* length of data in bytes */
    uint8_t* out, /* output buffer, at least "t" bytes */
    int t
    ) {
    sha1_context ictx, octx;
    uint8_t isha[SHA_DIGESTSIZE], osha[SHA_DIGESTSIZE];
    uint8_t key[SHA_DIGESTSIZE];
    uint8_t buf[SHA_BLOCKSIZE];
    int i;
    if (lk > SHA_BLOCKSIZE) {

    sha1_context tctx;

    sha1_starts(&tctx);
    sha1_update(&tctx, k, lk);
    sha1_finish(&tctx, key);

    k = key;
    lk = SHA_DIGESTSIZE;
    }

    /**** Inner Digest ****/

    sha1_starts(&ictx);

    /* Pad the key for inner digest */
    for (i = 0 ; i < lk ; ++i)
    buf = k ^ 0x36;
    for (i = lk ; i < SHA_BLOCKSIZE ; ++i) buf = 0x36;

    sha1_update(&ictx, buf, SHA_BLOCKSIZE);
    sha1_update(&ictx, d, ld);

    sha1_finish(&ictx, isha);

    /**** Outter Digest ****/

    sha1_starts(&octx);

    /* Pad the key for outter digest */

    for (i = 0 ; i < lk ; ++i)
    buf = k ^ 0x5C;
    for (i = lk ; i < SHA_BLOCKSIZE ; ++i)
    buf = 0x5C;

    sha1_update(&octx, buf, SHA_BLOCKSIZE);
    sha1_update(&octx, isha, SHA_DIGESTSIZE);

    sha1_finish(&octx, osha);

    /* truncate and print the results */
    t = t > SHA_DIGESTSIZE ? SHA_DIGESTSIZE : t;
    truncate_sha1(osha, out, t);


    }

    ----------------------------------------------------------------

    ---------------------- sha1.h ----------------------------

    #ifndef _SHA1_H
    #define _SHA1_H

    #ifndef uint8
    #define uint8 unsigned char
    #endif

    #ifndef uint32
    #define uint32 unsigned long int
    #endif

    typedef struct
    {
    uint32 total[2];
    uint32 state[5];
    uint8 buffer[64];
    }
    sha1_context;

    void sha1_starts( sha1_context *ctx );
    void sha1_update( sha1_context *ctx, uint8 *input, uint32 length );
    void sha1_finish( sha1_context *ctx, uint8 digest[20] );

    #endif /* sha1.h */

    ----------------------------------------------------------------

    ---------------------- sha1.c ----------------------------

    /*
    * FIPS-180-1 compliant SHA-1 implementation
    *
    * Copyright (C) 2001-2003 Christophe Devine
    *
    * This program is free software; you can redistribute it and/or modify
    * it under the terms of the GNU General Public License as published by
    * the Free Software Foundation; either version 2 of the License, or
    * (at your option) any later version.
    *
    * This program is distributed in the hope that it will be useful,
    * but WITHOUT ANY WARRANTY; without even the implied warranty of
    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    * GNU General Public License for more details.
    *
    * You should have received a copy of the GNU General Public License
    * along with this program; if not, write to the Free Software
    * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA
    */

    #include <string.h>

    #include "sha1.h"

    #define GET_UINT32(n,b,i) \
    { \
    (n) = ( (uint32) (b)[(i) ] << 24 ) \
    | ( (uint32) (b)[(i) + 1] << 16 ) \
    | ( (uint32) (b)[(i) + 2] << 8 ) \
    | ( (uint32) (b)[(i) + 3] ); \
    }

    #define PUT_UINT32(n,b,i) \
    { \
    (b)[(i) ] = (uint8) ( (n) >> 24 ); \
    (b)[(i) + 1] = (uint8) ( (n) >> 16 ); \
    (b)[(i) + 2] = (uint8) ( (n) >> 8 ); \
    (b)[(i) + 3] = (uint8) ( (n) ); \
    }

    void sha1_starts( sha1_context *ctx )
    {
    ctx->total[0] = 0;
    ctx->total[1] = 0;

    ctx->state[0] = 0x67452301;
    ctx->state[1] = 0xEFCDAB89;
    ctx->state[2] = 0x98BADCFE;
    ctx->state[3] = 0x10325476;
    ctx->state[4] = 0xC3D2E1F0;
    }

    void sha1_process( sha1_context *ctx, uint8 data[64] )
    {
    uint32 temp, W[16], A, B, C, D, E;

    GET_UINT32( W[0], data, 0 );
    GET_UINT32( W[1], data, 4 );
    GET_UINT32( W[2], data, 8 );
    GET_UINT32( W[3], data, 12 );
    GET_UINT32( W[4], data, 16 );
    GET_UINT32( W[5], data, 20 );
    GET_UINT32( W[6], data, 24 );
    GET_UINT32( W[7], data, 28 );
    GET_UINT32( W[8], data, 32 );
    GET_UINT32( W[9], data, 36 );
    GET_UINT32( W[10], data, 40 );
    GET_UINT32( W[11], data, 44 );
    GET_UINT32( W[12], data, 48 );
    GET_UINT32( W[13], data, 52 );
    GET_UINT32( W[14], data, 56 );
    GET_UINT32( W[15], data, 60 );

    #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))

    #define R(t) \
    ( \
    temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \
    W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \
    ( W[t & 0x0F] = S(temp,1) ) \
    )

    #define P(a,b,c,d,e,x) \
    { \
    e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
    }

    A = ctx->state[0];
    B = ctx->state[1];
    C = ctx->state[2];
    D = ctx->state[3];
    E = ctx->state[4];

    #define F(x,y,z) (z ^ (x & (y ^ z)))
    #define K 0x5A827999

    P( A, B, C, D, E, W[0] );
    P( E, A, B, C, D, W[1] );
    P( D, E, A, B, C, W[2] );
    P( C, D, E, A, B, W[3] );
    P( B, C, D, E, A, W[4] );
    P( A, B, C, D, E, W[5] );
    P( E, A, B, C, D, W[6] );
    P( D, E, A, B, C, W[7] );
    P( C, D, E, A, B, W[8] );
    P( B, C, D, E, A, W[9] );
    P( A, B, C, D, E, W[10] );
    P( E, A, B, C, D, W[11] );
    P( D, E, A, B, C, W[12] );
    P( C, D, E, A, B, W[13] );
    P( B, C, D, E, A, W[14] );
    P( A, B, C, D, E, W[15] );
    P( E, A, B, C, D, R(16) );
    P( D, E, A, B, C, R(17) );
    P( C, D, E, A, B, R(18) );
    P( B, C, D, E, A, R(19) );

    #undef K
    #undef F

    #define F(x,y,z) (x ^ y ^ z)
    #define K 0x6ED9EBA1

    P( A, B, C, D, E, R(20) );
    P( E, A, B, C, D, R(21) );
    P( D, E, A, B, C, R(22) );
    P( C, D, E, A, B, R(23) );
    P( B, C, D, E, A, R(24) );
    P( A, B, C, D, E, R(25) );
    P( E, A, B, C, D, R(26) );
    P( D, E, A, B, C, R(27) );
    P( C, D, E, A, B, R(28) );
    P( B, C, D, E, A, R(29) );
    P( A, B, C, D, E, R(30) );
    P( E, A, B, C, D, R(31) );
    P( D, E, A, B, C, R(32) );
    P( C, D, E, A, B, R(33) );
    P( B, C, D, E, A, R(34) );
    P( A, B, C, D, E, R(35) );
    P( E, A, B, C, D, R(36) );
    P( D, E, A, B, C, R(37) );
    P( C, D, E, A, B, R(38) );
    P( B, C, D, E, A, R(39) );

    #undef K
    #undef F

    #define F(x,y,z) ((x & y) | (z & (x | y)))
    #define K 0x8F1BBCDC

    P( A, B, C, D, E, R(40) );
    P( E, A, B, C, D, R(41) );
    P( D, E, A, B, C, R(42) );
    P( C, D, E, A, B, R(43) );
    P( B, C, D, E, A, R(44) );
    P( A, B, C, D, E, R(45) );
    P( E, A, B, C, D, R(46) );
    P( D, E, A, B, C, R(47) );
    P( C, D, E, A, B, R(48) );
    P( B, C, D, E, A, R(49) );
    P( A, B, C, D, E, R(50) );
    P( E, A, B, C, D, R(51) );
    P( D, E, A, B, C, R(52) );
    P( C, D, E, A, B, R(53) );
    P( B, C, D, E, A, R(54) );
    P( A, B, C, D, E, R(55) );
    P( E, A, B, C, D, R(56) );
    P( D, E, A, B, C, R(57) );
    P( C, D, E, A, B, R(58) );
    P( B, C, D, E, A, R(59) );

    #undef K
    #undef F

    #define F(x,y,z) (x ^ y ^ z)
    #define K 0xCA62C1D6

    P( A, B, C, D, E, R(60) );
    P( E, A, B, C, D, R(61) );
    P( D, E, A, B, C, R(62) );
    P( C, D, E, A, B, R(63) );
    P( B, C, D, E, A, R(64) );
    P( A, B, C, D, E, R(65) );
    P( E, A, B, C, D, R(66) );
    P( D, E, A, B, C, R(67) );
    P( C, D, E, A, B, R(68) );
    P( B, C, D, E, A, R(69) );
    P( A, B, C, D, E, R(70) );
    P( E, A, B, C, D, R(71) );
    P( D, E, A, B, C, R(72) );
    P( C, D, E, A, B, R(73) );
    P( B, C, D, E, A, R(74) );
    P( A, B, C, D, E, R(75) );
    P( E, A, B, C, D, R(76) );
    P( D, E, A, B, C, R(77) );
    P( C, D, E, A, B, R(78) );
    P( B, C, D, E, A, R(79) );

    #undef K
    #undef F

    ctx->state[0] += A;
    ctx->state[1] += B;
    ctx->state[2] += C;
    ctx->state[3] += D;
    ctx->state[4] += E;
    }

    void sha1_update( sha1_context *ctx, uint8 *input, uint32 length )
    {
    uint32 left, fill;

    if( ! length ) return;

    left = ctx->total[0] & 0x3F;
    fill = 64 - left;

    ctx->total[0] += length;
    ctx->total[0] &= 0xFFFFFFFF;

    if( ctx->total[0] < length )
    ctx->total[1]++;

    if( left && length >= fill )
    {
    memcpy( (void *) (ctx->buffer + left),
    (void *) input, fill );
    sha1_process( ctx, ctx->buffer );
    length -= fill;
    input += fill;
    left = 0;
    }

    while( length >= 64 )
    {
    sha1_process( ctx, input );
    length -= 64;
    input += 64;
    }

    if( length )
    {
    memcpy( (void *) (ctx->buffer + left),
    (void *) input, length );
    }
    }

    static uint8 sha1_padding[64] =
    {
    0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    };

    void sha1_finish( sha1_context *ctx, uint8 digest[20] )
    {
    uint32 last, padn;
    uint32 high, low;
    uint8 msglen[8];

    high = ( ctx->total[0] >> 29 )
    | ( ctx->total[1] << 3 );
    low = ( ctx->total[0] << 3 );

    PUT_UINT32( high, msglen, 0 );
    PUT_UINT32( low, msglen, 4 );

    last = ctx->total[0] & 0x3F;
    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );

    sha1_update( ctx, sha1_padding, padn );
    sha1_update( ctx, msglen, 8 );

    PUT_UINT32( ctx->state[0], digest, 0 );
    PUT_UINT32( ctx->state[1], digest, 4 );
    PUT_UINT32( ctx->state[2], digest, 8 );
    PUT_UINT32( ctx->state[3], digest, 12 );
    PUT_UINT32( ctx->state[4], digest, 16 );
    }

    ----------------------------------------------------------------
     
    Fernando Barsoba, Nov 27, 2005
    #1
    1. Advertising

  2. Fernando Barsoba

    FBM Guest

    Fernando Barsoba wrote:
    > Dear all,
    >
    > I have been posting about a problem trying to encrypt certain data using
    > HMAC-SHA1 functions. I posted that my problem was solved, but
    > unfortunately, I was being overly optimistic. I am really desperate now,
    > because I havent' been able to locate the origin of the problem for a
    > couple of days now..
    >
    > PROBLEM: the message digest obtained differs each time I execute the
    > code, but works perfectly when applying the "control", that is the test
    > case #3 from RFC 2202 that I show below.
    >
    > I did my best trying to create a code that can be compiled and executed
    > and that clearly shows the problem. I would really appreciate any help,
    > I have to finish this project in a couple of days and I have been stuck
    > here for a long while..
    >
    > Explanation of functions:
    > - I send an array over a function that obtains a message digest applying
    > hmac-sha1. This authentication function requires a message and a key.
    > The message simulates and IP header of lenght=31 (I hardcoded the value
    > for clarity).
    > - The 'build_ip_packet' function does bit manipulatation therefore the
    > final message is just gibberish, but their hexadecimal content is valid
    > and represents the ip packet.
    > - I treat the message with the function 'hexString_to_hexRepresent'
    > because I thought that this translation had to be made (hex to its hex
    > representation)
    > - Finally, 'icv_Calculation' performs the message digest calculation.
    > - 'icv_Calculation_test' uses the same function but sends to it the test
    > case #3 from RFC 2202
    > - 'pr_hexstring' prints out the result.
    >
    > RFC 2202 has different test cases. #3 is the following:
    > test_case = 3
    > key = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
    > key_len = 20
    > data = 0xdd repeated 50 times
    > data_len = 50
    > digest = 0x125d7342b9ac11cd91a39af48aa17b4f63f175d3
    >
    > http://www.zvon.org/tmRFC/RFC2202/Output/index.html
    >
    > As you can see executing the program, I get the correct result in my
    > second icv call. However, the first call shows completely different
    > results each time I call it. Why is that?
    >
    > output:
    > $ ./icv_test.exe
    > 0xf28b25b3793ff29a248932ebe8fa6114934be0f2
    > 0x125d7342b9ac11cd91a39af48aa17b4f63f175d3
    >
    > Again, thank you in advance for any help that you can provide me.
    >
    > I attach the complete code. It's a lot, but if someone wants to try,
    > they are complementary functions that are needed but they are not the
    > origin of the problem. 'main' and first level functions is where the
    > core of the problem may be.
    >
    > You may find string conversions which may not have much sense.. i
    > apologize for that, I can't think clearly anymore.. :-(
    >
    > Fernando
    >
    > -------------------------- main.c ----------------
    > #include <netinet/in.h> /* sockaddr_in{} and other Internet defns */
    > #include <arpa/inet.h> /* inet(3) functions */
    > #include <errno.h>
    > #include <netdb.h>
    > #include <signal.h>
    > #include <stdio.h>
    > #include <stdlib.h>
    > #include <string.h>
    > #include <unistd.h>
    > #include <netinet/ip.h>
    > #include <sys/types.h>
    >
    > #include "hmac-sha1.h"
    >
    >
    > #define HEADER_OFFSET 20
    > #define IP_VERSION 4
    >
    > typedef struct {
    > char * message;
    > char dest_ip[20];
    > char src_ip[20];
    > int msg_length;
    > int port;
    > char * key;
    > char algorithm;
    > } CONF_PARAMS;
    >
    > void build_ip_packet(unsigned char *packet, unsigned short length,
    > CONF_PARAMS *cnf) {
    > struct ip *iphdr;
    > int packet_size;
    >
    > struct in_addr ipsrc_addr, ipdst_addr; /* 'in_addr' structures needed
    > to change byte ordering */
    >
    > packet_size = sizeof(struct ip) + cnf->msg_length; /* obtain size
    > for datagram */
    >
    > bzero(packet, packet_size); /* fills with 0; deprecated, change
    > with memset */
    > iphdr = (struct ip *)packet; /* assign ip header structure to our
    > IP packet */
    >
    > inet_aton(cnf->src_ip, &ipsrc_addr);
    > inet_aton(cnf->dest_ip, &ipdst_addr);
    >
    > /* IP header construction */
    > iphdr->ip_v = IP_VERSION; /* version = 4, IP */
    > iphdr->ip_hl = 5; /* length = 5, no option */
    > iphdr->ip_tos = 0;
    > iphdr->ip_len = htons(length); /* length of the datagram */
    > iphdr->ip_id = htons(getpid()); /* identification for this packet,
    > assigned process id */
    > iphdr->ip_off = 0;
    > iphdr->ip_ttl = 64; /* time to live = 64 */
    > iphdr->ip_p = 51; /* protocol number = 51, AH code */
    > iphdr->ip_src = ipsrc_addr;
    > iphdr->ip_dst = ipdst_addr;
    > iphdr->ip_sum = 0;
    >
    > // iphdr->ip_sum = in_cksum((u_short *) iphdr, (iphdr->ip_hl) << 2);
    > /* calculate checksum */
    >
    > memcpy(packet + HEADER_OFFSET, cnf->message, cnf->msg_length); /* copy
    > data to end ip packet, which is
    > 20 bytes by default. If options included,
    > this value has to be changed */
    > return;
    > }
    >
    > /* Convert the single hexadecimal digit 'c' to the corresponding
    > integer, or -1 if 'c' is not a hex digit. */
    > int hexdigit_to_int(char c) {
    > if (c >= '0' && c <= '9') return c - '0';
    > switch (c) {
    > case 'a': case 'A': return 10;
    > case 'b': case 'B': return 11;
    > case 'c': case 'C': return 12;
    > case 'd': case 'D': return 13;
    > case 'e': case 'E': return 14;
    > case 'f': case 'F': return 15;
    > default: {
    > return -1;
    > }
    > }
    > }
    >
    >
    > /* Convert the hexadecimal representation of a sequence of bytes to
    > the sequence of bytes. */
    > /* Returns a malloc()-allocated block of strlen(hex) / 2 bytes if
    > successful or a null pointer otherwise. */
    > unsigned char* hexstr_to_bytes(const char* hex) {
    > size_t l = strlen(hex);
    > size_t n = 0;
    > unsigned char* result;
    > if (l % 2 != 0) return NULL;
    >
    > result = malloc(l / 2);
    > if (!result) return NULL;
    >
    > for (n = 0; n < l; n += 2) {
    > int d1 = hexdigit_to_int(hex[n]);
    > int d2 = hexdigit_to_int(hex[n+1]);
    > if (d1 < 0 || d2 < 0) {
    > free(result);
    > return NULL;
    > }
    > result[n/2] = (d1 << 4) + d2;
    > }
    > return result;
    > }
    >
    >
    > unsigned char* hexString_to_hexRepresent(const char *payload, const char
    > *hexvalue, int payload_size, int output_size) {
    > int ii, tt=payload_size;
    > unsigned char hexvalue2[payload_size*2];
    > memcpy(hexvalue2, hexvalue, payload_size*2);
    > for (ii = 0 ; ii < tt ; ii++)
    > sprintf(hexvalue2+(ii*2), "%02x", payload[ii]);
    > unsigned char *msgICV;
    > msgICV = hexstr_to_bytes(hexvalue2);
    > return msgICV;
    > }
    >
    > void icv_Calculation_test(char p_output[20]) {
    > uint8_t
    > tmp_msgtest[]="DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD";
    > char tmp_key[]="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
    > unsigned char* key, *msgtest;
    > key = hexstr_to_bytes(tmp_key);
    > msgtest = hexstr_to_bytes(tmp_msgtest);
    > uint8_t outputsha[20];
    >
    > int size_message, size_key;
    > size_message = strlen(msgtest);
    > size_key = strlen(key)-1;
    >
    > hmac_sha(key, size_key, msgtest, size_message, outputsha,
    > sizeof(outputsha));
    > strcpy(p_output, outputsha);
    > free(key);
    > free(msgtest);
    > return;
    > }
    >
    > unsigned char * icv_Calculation(unsigned char *hdrs, int hdrs_len,
    > CONF_PARAMS *cnf, uint8_t *output, int output_len) {
    > unsigned char outputshax[20];
    > unsigned char payloadh[hdrs_len];
    > memcpy(payloadh, hdrs, hdrs_len);
    >
    > if (cnf->algorithm == 's' )
    > hmac_sha(cnf->key,strlen(cnf->key), payloadh, hdrs_len, outputshax,
    > sizeof(outputshax));
    >
    > unsigned char * ret_output=malloc(20);
    > memcpy(ret_output, outputshax, 20);
    > return ret_output;
    > }
    >
    >
    > /* Function to print strings in hex */
    > void pr_hexstring(FILE* fp, unsigned char* s, int t) {
    > int i;
    > fprintf(fp, "0x");
    > for (i = 0 ; i < t ; i++) {
    > fprintf(fp, "%02x", s);
    > }
    > fprintf(fp, "\n");
    > }
    >
    >
    >
    > int main(int argc, char **argv) {
    > CONF_PARAMS * cnf;
    > cnf = malloc(sizeof(*cnf));
    >
    > cnf->message = "hello world";
    > cnf->key = "Jefe";
    > strcpy(cnf->dest_ip, "192.168.2.2");
    > strcpy(cnf->src_ip, "192.168.2.2");
    > cnf->msg_length = strlen(cnf->message);
    > cnf->algorithm='s';
    >
    > unsigned char packet[31];
    > build_ip_packet(packet, sizeof(packet), cnf);
    >
    > unsigned char m_output[20];
    > unsigned char d_packet[sizeof(packet)*2];
    > unsigned char * p_icv = hexString_to_hexRepresent(packet, d_packet ,
    > sizeof(packet), strlen(m_output));
    >
    > unsigned char *ret_output = icv_Calculation(p_icv, 31, cnf, m_output, 20);
    >
    > pr_hexstring(stdout, ret_output, 20);
    >
    > char p_output_sha[20];
    > icv_Calculation_test(p_output_sha);
    >
    > pr_hexstring(stdout, p_output_sha, 20);
    >
    > free(ret_output);
    > free(p_icv);
    > free(cnf);
    > exit(0);
    > }
    >
    >
    > ---------------------------------------------------------------
    >
    > ---------------------- hmac-sha1.h ----------------------------
    >
    > #ifndef HMACSHA1_H_
    > #define HMACSHA1_H_
    >
    > #include "sha1.h"
    >
    >
    > #ifndef SHA_DIGESTSIZE
    > #define SHA_DIGESTSIZE 20
    > #endif
    >
    > #ifndef SHA_BLOCKSIZE
    > #define SHA_BLOCKSIZE 64
    > #endif
    >
    > void pr_sha(FILE*, unsigned char*, int);
    > void truncate_sha1 (uint8_t*, uint8_t*, int);
    > void hmac_sha (uint8_t*, int, uint8_t*, int, uint8_t*, int);
    >
    > #endif /*HMACSHA1_H_*/
    >
    > ---------------------------------------------------------------
    >
    >
    > ---------------------- hmac-sha1.c ----------------------------
    > #include <stdio.h>
    > #include "sha1.h"
    > #include "hmac-sha1.h"
    > /*
    > * From sha1.h ------------------------
    > *
    > * sha1_context;
    > * void sha1_starts( sha1_context *ctx );
    > * void sha1_update( sha1_context *ctx, uint8 *input, uint32 length );
    > * void sha1_finish( sha1_context *ctx, uint8 digest[20] );
    > *
    > */
    >
    > /* Function to print the digest */
    > void pr_sha(FILE* fp, unsigned char* s, int t) {
    > int i;
    > fprintf(fp, "0x");
    > for (i = 0 ; i < t ; i++)
    > fprintf(fp, "%02x", s);
    > fprintf(fp, "0");
    > }
    >
    > void truncate_sha1 (
    > uint8_t* d1, /* data to be truncated */
    > uint8_t* d2, /* truncated data */
    > int len /* length in bytes to keep */
    > ) {
    > int i;
    > for (i=0; i < len; i++)
    > d2 = d1;
    > }
    >
    > /* Function to compute the digest */
    > void hmac_sha (
    > uint8_t* k, /* secret key */
    > int lk, /* length of the key in bytes */
    > uint8_t* d, /* data */
    > int ld, /* length of data in bytes */
    > uint8_t* out, /* output buffer, at least "t" bytes */
    > int t
    > ) {
    > sha1_context ictx, octx;
    > uint8_t isha[SHA_DIGESTSIZE], osha[SHA_DIGESTSIZE];
    > uint8_t key[SHA_DIGESTSIZE];
    > uint8_t buf[SHA_BLOCKSIZE];
    > int i;
    > if (lk > SHA_BLOCKSIZE) {
    >
    > sha1_context tctx;
    >
    > sha1_starts(&tctx);
    > sha1_update(&tctx, k, lk);
    > sha1_finish(&tctx, key);
    >
    > k = key;
    > lk = SHA_DIGESTSIZE;
    > }
    >
    > /**** Inner Digest ****/
    >
    > sha1_starts(&ictx);
    >
    > /* Pad the key for inner digest */
    > for (i = 0 ; i < lk ; ++i)
    > buf = k ^ 0x36;
    > for (i = lk ; i < SHA_BLOCKSIZE ; ++i) buf = 0x36;
    >
    > sha1_update(&ictx, buf, SHA_BLOCKSIZE);
    > sha1_update(&ictx, d, ld);
    >
    > sha1_finish(&ictx, isha);
    >
    > /**** Outter Digest ****/
    >
    > sha1_starts(&octx);
    >
    > /* Pad the key for outter digest */
    >
    > for (i = 0 ; i < lk ; ++i)
    > buf = k ^ 0x5C;
    > for (i = lk ; i < SHA_BLOCKSIZE ; ++i)
    > buf = 0x5C;
    >
    > sha1_update(&octx, buf, SHA_BLOCKSIZE);
    > sha1_update(&octx, isha, SHA_DIGESTSIZE);
    >
    > sha1_finish(&octx, osha);
    >
    > /* truncate and print the results */
    > t = t > SHA_DIGESTSIZE ? SHA_DIGESTSIZE : t;
    > truncate_sha1(osha, out, t);
    >
    >
    > }
    >
    > ----------------------------------------------------------------
    >
    > ---------------------- sha1.h ----------------------------
    >
    > #ifndef _SHA1_H
    > #define _SHA1_H
    >
    > #ifndef uint8
    > #define uint8 unsigned char
    > #endif
    >
    > #ifndef uint32
    > #define uint32 unsigned long int
    > #endif
    >
    > typedef struct
    > {
    > uint32 total[2];
    > uint32 state[5];
    > uint8 buffer[64];
    > }
    > sha1_context;
    >
    > void sha1_starts( sha1_context *ctx );
    > void sha1_update( sha1_context *ctx, uint8 *input, uint32 length );
    > void sha1_finish( sha1_context *ctx, uint8 digest[20] );
    >
    > #endif /* sha1.h */
    >
    > ----------------------------------------------------------------
    >
    > ---------------------- sha1.c ----------------------------
    >
    > /*
    > * FIPS-180-1 compliant SHA-1 implementation
    > *
    > * Copyright (C) 2001-2003 Christophe Devine
    > *
    > * This program is free software; you can redistribute it and/or modify
    > * it under the terms of the GNU General Public License as published by
    > * the Free Software Foundation; either version 2 of the License, or
    > * (at your option) any later version.
    > *
    > * This program is distributed in the hope that it will be useful,
    > * but WITHOUT ANY WARRANTY; without even the implied warranty of
    > * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    > * GNU General Public License for more details.
    > *
    > * You should have received a copy of the GNU General Public License
    > * along with this program; if not, write to the Free Software
    > * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    > 02111-1307 USA
    > */
    >
    > #include <string.h>
    >
    > #include "sha1.h"
    >
    > #define GET_UINT32(n,b,i) \
    > { \
    > (n) = ( (uint32) (b)[(i) ] << 24 ) \
    > | ( (uint32) (b)[(i) + 1] << 16 ) \
    > | ( (uint32) (b)[(i) + 2] << 8 ) \
    > | ( (uint32) (b)[(i) + 3] ); \
    > }
    >
    > #define PUT_UINT32(n,b,i) \
    > { \
    > (b)[(i) ] = (uint8) ( (n) >> 24 ); \
    > (b)[(i) + 1] = (uint8) ( (n) >> 16 ); \
    > (b)[(i) + 2] = (uint8) ( (n) >> 8 ); \
    > (b)[(i) + 3] = (uint8) ( (n) ); \
    > }
    >
    > void sha1_starts( sha1_context *ctx )
    > {
    > ctx->total[0] = 0;
    > ctx->total[1] = 0;
    >
    > ctx->state[0] = 0x67452301;
    > ctx->state[1] = 0xEFCDAB89;
    > ctx->state[2] = 0x98BADCFE;
    > ctx->state[3] = 0x10325476;
    > ctx->state[4] = 0xC3D2E1F0;
    > }
    >
    > void sha1_process( sha1_context *ctx, uint8 data[64] )
    > {
    > uint32 temp, W[16], A, B, C, D, E;
    >
    > GET_UINT32( W[0], data, 0 );
    > GET_UINT32( W[1], data, 4 );
    > GET_UINT32( W[2], data, 8 );
    > GET_UINT32( W[3], data, 12 );
    > GET_UINT32( W[4], data, 16 );
    > GET_UINT32( W[5], data, 20 );
    > GET_UINT32( W[6], data, 24 );
    > GET_UINT32( W[7], data, 28 );
    > GET_UINT32( W[8], data, 32 );
    > GET_UINT32( W[9], data, 36 );
    > GET_UINT32( W[10], data, 40 );
    > GET_UINT32( W[11], data, 44 );
    > GET_UINT32( W[12], data, 48 );
    > GET_UINT32( W[13], data, 52 );
    > GET_UINT32( W[14], data, 56 );
    > GET_UINT32( W[15], data, 60 );
    >
    > #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
    >
    > #define R(t) \
    > ( \
    > temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \
    > W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \
    > ( W[t & 0x0F] = S(temp,1) ) \
    > )
    >
    > #define P(a,b,c,d,e,x) \
    > { \
    > e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
    > }
    >
    > A = ctx->state[0];
    > B = ctx->state[1];
    > C = ctx->state[2];
    > D = ctx->state[3];
    > E = ctx->state[4];
    >
    > #define F(x,y,z) (z ^ (x & (y ^ z)))
    > #define K 0x5A827999
    >
    > P( A, B, C, D, E, W[0] );
    > P( E, A, B, C, D, W[1] );
    > P( D, E, A, B, C, W[2] );
    > P( C, D, E, A, B, W[3] );
    > P( B, C, D, E, A, W[4] );
    > P( A, B, C, D, E, W[5] );
    > P( E, A, B, C, D, W[6] );
    > P( D, E, A, B, C, W[7] );
    > P( C, D, E, A, B, W[8] );
    > P( B, C, D, E, A, W[9] );
    > P( A, B, C, D, E, W[10] );
    > P( E, A, B, C, D, W[11] );
    > P( D, E, A, B, C, W[12] );
    > P( C, D, E, A, B, W[13] );
    > P( B, C, D, E, A, W[14] );
    > P( A, B, C, D, E, W[15] );
    > P( E, A, B, C, D, R(16) );
    > P( D, E, A, B, C, R(17) );
    > P( C, D, E, A, B, R(18) );
    > P( B, C, D, E, A, R(19) );
    >
    > #undef K
    > #undef F
    >
    > #define F(x,y,z) (x ^ y ^ z)
    > #define K 0x6ED9EBA1
    >
    > P( A, B, C, D, E, R(20) );
    > P( E, A, B, C, D, R(21) );
    > P( D, E, A, B, C, R(22) );
    > P( C, D, E, A, B, R(23) );
    > P( B, C, D, E, A, R(24) );
    > P( A, B, C, D, E, R(25) );
    > P( E, A, B, C, D, R(26) );
    > P( D, E, A, B, C, R(27) );
    > P( C, D, E, A, B, R(28) );
    > P( B, C, D, E, A, R(29) );
    > P( A, B, C, D, E, R(30) );
    > P( E, A, B, C, D, R(31) );
    > P( D, E, A, B, C, R(32) );
    > P( C, D, E, A, B, R(33) );
    > P( B, C, D, E, A, R(34) );
    > P( A, B, C, D, E, R(35) );
    > P( E, A, B, C, D, R(36) );
    > P( D, E, A, B, C, R(37) );
    > P( C, D, E, A, B, R(38) );
    > P( B, C, D, E, A, R(39) );
    >
    > #undef K
    > #undef F
    >
    > #define F(x,y,z) ((x & y) | (z & (x | y)))
    > #define K 0x8F1BBCDC
    >
    > P( A, B, C, D, E, R(40) );
    > P( E, A, B, C, D, R(41) );
    > P( D, E, A, B, C, R(42) );
    > P( C, D, E, A, B, R(43) );
    > P( B, C, D, E, A, R(44) );
    > P( A, B, C, D, E, R(45) );
    > P( E, A, B, C, D, R(46) );
    > P( D, E, A, B, C, R(47) );
    > P( C, D, E, A, B, R(48) );
    > P( B, C, D, E, A, R(49) );
    > P( A, B, C, D, E, R(50) );
    > P( E, A, B, C, D, R(51) );
    > P( D, E, A, B, C, R(52) );
    > P( C, D, E, A, B, R(53) );
    > P( B, C, D, E, A, R(54) );
    > P( A, B, C, D, E, R(55) );
    > P( E, A, B, C, D, R(56) );
    > P( D, E, A, B, C, R(57) );
    > P( C, D, E, A, B, R(58) );
    > P( B, C, D, E, A, R(59) );
    >
    > #undef K
    > #undef F
    >
    > #define F(x,y,z) (x ^ y ^ z)
    > #define K 0xCA62C1D6
    >
    > P( A, B, C, D, E, R(60) );
    > P( E, A, B, C, D, R(61) );
    > P( D, E, A, B, C, R(62) );
    > P( C, D, E, A, B, R(63) );
    > P( B, C, D, E, A, R(64) );
    > P( A, B, C, D, E, R(65) );
    > P( E, A, B, C, D, R(66) );
    > P( D, E, A, B, C, R(67) );
    > P( C, D, E, A, B, R(68) );
    > P( B, C, D, E, A, R(69) );
    > P( A, B, C, D, E, R(70) );
    > P( E, A, B, C, D, R(71) );
    > P( D, E, A, B, C, R(72) );
    > P( C, D, E, A, B, R(73) );
    > P( B, C, D, E, A, R(74) );
    > P( A, B, C, D, E, R(75) );
    > P( E, A, B, C, D, R(76) );
    > P( D, E, A, B, C, R(77) );
    > P( C, D, E, A, B, R(78) );
    > P( B, C, D, E, A, R(79) );
    >
    > #undef K
    > #undef F
    >
    > ctx->state[0] += A;
    > ctx->state[1] += B;
    > ctx->state[2] += C;
    > ctx->state[3] += D;
    > ctx->state[4] += E;
    > }
    >
    > void sha1_update( sha1_context *ctx, uint8 *input, uint32 length )
    > {
    > uint32 left, fill;
    >
    > if( ! length ) return;
    >
    > left = ctx->total[0] & 0x3F;
    > fill = 64 - left;
    >
    > ctx->total[0] += length;
    > ctx->total[0] &= 0xFFFFFFFF;
    >
    > if( ctx->total[0] < length )
    > ctx->total[1]++;
    >
    > if( left && length >= fill )
    > {
    > memcpy( (void *) (ctx->buffer + left),
    > (void *) input, fill );
    > sha1_process( ctx, ctx->buffer );
    > length -= fill;
    > input += fill;
    > left = 0;
    > }
    >
    > while( length >= 64 )
    > {
    > sha1_process( ctx, input );
    > length -= 64;
    > input += 64;
    > }
    >
    > if( length )
    > {
    > memcpy( (void *) (ctx->buffer + left),
    > (void *) input, length );
    > }
    > }
    >
    > static uint8 sha1_padding[64] =
    > {
    > 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    > 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    > 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    > 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    > };
    >
    > void sha1_finish( sha1_context *ctx, uint8 digest[20] )
    > {
    > uint32 last, padn;
    > uint32 high, low;
    > uint8 msglen[8];
    >
    > high = ( ctx->total[0] >> 29 )
    > | ( ctx->total[1] << 3 );
    > low = ( ctx->total[0] << 3 );
    >
    > PUT_UINT32( high, msglen, 0 );
    > PUT_UINT32( low, msglen, 4 );
    >
    > last = ctx->total[0] & 0x3F;
    > padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
    >
    > sha1_update( ctx, sha1_padding, padn );
    > sha1_update( ctx, msglen, 8 );
    >
    > PUT_UINT32( ctx->state[0], digest, 0 );
    > PUT_UINT32( ctx->state[1], digest, 4 );
    > PUT_UINT32( ctx->state[2], digest, 8 );
    > PUT_UINT32( ctx->state[3], digest, 12 );
    > PUT_UINT32( ctx->state[4], digest, 16 );
    > }
    >
    > ----------------------------------------------------------------
     
    FBM, Nov 28, 2005
    #2
    1. Advertising

  3. Fernando Barsoba wrote:
    > Dear all,
    >
    > I have been posting about a problem trying to encrypt certain data using
    > HMAC-SHA1 functions. I posted that my problem was solved, but
    > unfortunately, I was being overly optimistic. I am really desperate now,
    > because I havent' been able to locate the origin of the problem for a
    > couple of days now..
    >
    > PROBLEM: the message digest obtained differs each time I execute the
    > code, but works perfectly when applying the "control", that is the test
    > case #3 from RFC 2202 that I show below.


    Thanks to all. Posting the code made me realize what the problem was. It
    turns out that:

    > phdr->ip_id = htons(getpid()); /* identification for this packet, assigned process


    made the icv generate a complete message digest every time the program
    was executed.

    Pretty silly after all!

    Thanks,

    Fernando
     
    Fernando Barsoba, Nov 28, 2005
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    10
    Views:
    6,274
    Neredbojias
    Aug 19, 2005
  2. Bengt Richter
    Replies:
    6
    Views:
    488
    Juha Autero
    Aug 19, 2003
  3. jack
    Replies:
    4
    Views:
    596
  4. Bill Seitz
    Replies:
    18
    Views:
    2,005
    Bill Seitz
    Sep 16, 2004
  5. tim

    hex string to hex value

    tim, Nov 22, 2005, in forum: Python
    Replies:
    8
    Views:
    18,969
Loading...

Share This Page