Need clarification on reading data from fgets()/fgetc()

This is a discussion on Need clarification on reading data from fgets()/fgetc() within the C Programming forums, part of the General Programming Boards category; Hi, Currently i have a program which use openssl libraries to generate random number using the API unsigned char salt[32]; ...

  1. #1
    Registered User
    Join Date
    Mar 2012
    Posts
    19

    Need clarification on reading data from fgets()/fgetc()

    Hi,

    Currently i have a program which use openssl libraries to generate random number using the API

    unsigned char salt[32];
    RAND_bytes(salt, 32).

    Below are my printf's
    printf("%c", salt[0]); -> I see some special characters getting printed (not human readbale)
    pirntf("%x":, salt[0]) -> i see correct value

    sampl eo/p of RAND_bytes(): fc8d1ffbde2b3f10e21f9e57b87d86079e9f04f2810cb66269 3fbaffeaa6

    Need help to understand this....

    Now i store the salt() to a file as below
    fprintf(saltfile, "%02x", salt_value[i]); [ assume file operations to be performed before executing this statement is done].
    When i see the contents of file, they are correct as expected.

    Now i do a fgets() to read 32 bytes on the above file, it reds 32 characters which is not the full random vale i got above coz fgets() or fgetc() treats each encountered character as one char read.
    Now to store the above salt value, i would need a 64 byte of array but i want to have 32 bytes array like i have salt and replicate the contents of the array same as that of salt() array when reading from a file...

    Pleas help me to understand this... thanks

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by pkumarn View Post
    Code:
    unsigned char salt[32];
    RAND_bytes(salt, 32). 
    printf("%c", salt[0]); -> I see some special characters getting printed (not human readbale)
    "salt" here is not a text representation of the value, it is not even a string. It is a 32 element unsigned char array. (Unsigned) char arrays are commonly used this way in C because a char is one byte*. I think you know how the salt is used, why it has a specific size in bytes, and why each byte value in the array can have any one of 256 values possible for an 8 bit (1 byte) region in memory. This means a 32 byte array has 2^(32*8) possibilities.

    [* although the standard does not guarantee this -- it could actually be more than one byte. But this is still the practice.]

    However, there are only 128 ascii printable character values; ascii uses 7 bit values, and in C these are stored in 8 bit bytes. Look:

    Code:
    char a = 'a';
    printf("%d %x %c\n", a, a, a);
    You get: 97 61 a
    Do you understand now that you are confusing hexadecimal notation, which uses digits 0 1 2 3 4 5 6 7 8 9 a b c d e f, for ascii characters? Hex is used with byte values because base 16 is a power of two number, and so the representation of a value in the range 0-255 (decimal) is very tidy in hex: 0-ff.

    So, eg, the first two bytes in that salt, fc 8d, in decimal would be: 252 141. Neither of those is a printable ascii character, and even if they were, there is no meaningful purpose in looking at them that way.

    Now i do a fgets() to read 32 bytes on the above file, it reds 32 characters
    Of course it did. You asked it to read 32 bytes, into a char array. If each char is 1 byte (again, it pretty much always is), then that is 32 characters. All you have to do is look at that hexadecimal representation of the salt to see that the hexadecimal representation is more than 32 "characters" (actually, hex digits) long. And if you think for a moment, eureka, if each byte is 2 hex digits, a hex representation of an array of 32 unsigned chars (ie, 32 byte values) will be 64 hex digits long.

    Now to store the above salt value, i would need a 64 byte of array but i want to have 32 bytes array like i have salt and replicate the contents of the array same as that of salt() array when reading from a file...
    You have two choices:

    1) Store the salt as text, a hex representation, which will be 64 chars long. This means the file is human readable, but when you read the value back in, you must convert those textual hex digits to a numerical value. For this you can cast the return value of strtoul() to a char, using 16 as the last parameter to indicate the base (hexadecimal). But you have to do this one byte (2 hex digits) at a time.

    2) Write the salt out as an array of 32 byte values using a lower level function (ie, not fprintf, which converts to text). This is simpler and more efficient in a sense, but then the file (which will be 32 bytes, not 64) is not human readable. You then read it back directly into an array using a lower level read function.
    Last edited by MK27; 03-16-2012 at 06:50 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User
    Join Date
    Mar 2012
    Posts
    19
    Thanks for the reply. So when i do strlen(salt) i get result of 32 which is correct. Now my concern is i need to pass this salt to below fucntion in openssl PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, const unsigned char *salt, int saltlen, int iter,
    int keylen, unsigned char *out)


    Here when i input arr salt() directly to above function with saltlen =32, it gives me wrong result. But the same works, if i copy the array to a file in human readble ASCII character and then store into an array of 64 bytes, i get the expected result... as i know above function treats each readable character i.e, in my case f & c as separately. Am i right? Any suggestions?

  4. #4
    Registered User
    Join Date
    Mar 2012
    Posts
    19
    I wrote a sample program as below by using array salt_value directly without going through the file stuff and i am getting wrong result.
    Code:
    ===================================================================
    #include <stdio.h>
    #include <openssl/rand.h>
    #include <types.h>
    #include <string.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    
    #include <malloc.h>
    
    
    #include <openssl/hmac.h>
    #include <openssl/evp.h>
    #include <openssl/engine.h>
    #include <openssl/aes.h>
    
    
    #include <proto.h>
    #define KEY_LEN    32// 32 bytes - 256 bits
    #define KEK_KEY_LEN   5
    #define ITERATION   1000
    
    
    //unsigned char salt_value[32]={"5d85947b4292ea6463faf6893451232"}; 
    unsigned char salt_value[33];
    unsigned char AESkey[33];
    unsigned char XTSkey[33];
    /*unsigned char *salt_value;
    unsigned char *AESkey;
    unsigned char *XTSkey;
    unsigned char * temp_salt_value;
    */
    u8 fuse_key[KEY_LEN+1];
    
    
        u8 *out;
        u8 *rspHMAC;
    
    
    void main()
    {
        u8 pwd[]= "Virident";
        s32 i=0;
        s32 len =0;
        s32 ret;
    
    
        RAND_bytes(salt_value, KEY_LEN);
    
    
    	
        printf("\n salt_value[0] = %x; salt_value[31]= %x", salt_value[0], salt_value[31]);
        printf("\n strlen(salt_value) = %d; sizeof(salt_value) = %d\n", strlen(salt_value), sizeof(salt_value));
    	//printf("\n salt_value = %s", salt_value);
    	
        for(i = 0; i < KEY_LEN; i++) {
            printf(" %02x", salt_value[i]);
    	}
    
    
        printf("\n salt value= ");
        for(i = 0; i < KEY_LEN; i++) {
            printf("%02x", salt_value[i]);
        }
        rspHMAC = (unsigned char *) malloc(sizeof(char) * KEY_LEN);
        out = (unsigned char *) malloc(sizeof(char) * KEK_KEY_LEN);
    
    
        printf("\n ************** Entered spHMAC() function ************* ");
    	
        printf("\n strlen(salt_value) = %d", strlen(salt_value));	
        ret = PKCS5_PBKDF2_HMAC_SHA1(pwd, strlen(pwd), (u8 *)salt_value, 64, ITERATION, KEK_KEY_LEN, out);
        printf("\n PKCS#5 :");
    
    
        for(len = 0; len < KEK_KEY_LEN; len++){
            printf("%02x", out[len]);
           /* o/p of PKCS5 is stored in buf "out". This cannot be used directly as each out[len] will have 2 char
           but for key gen, we need to consider each char of out as a value. - Needs sentence reframing
             */
       }
       printf("\n ");
    
    
    =====================================================
    Website: Password-Based Key Derivation Function 2 (PBKDF2)
    The derived 40-bit key is: c5c6526b3b


    My result:
    salt_value[0] = 58; salt_value[31]= b2
    strlen(salt_value) = 32; sizeof(salt_value) = 33
    58 18 ba 6b ba 24 53 b7 c1 80 eb 1f 93 7a 98 29 16 6c 50 a9 27 f1 49 b2 72 54 3a e5 70 b5 66 b2
    salt value= 5818ba6bba2453b7c180eb1f937a9829166c50a927f149b272 543ae570b566b2
    ************** Entered spHMAC() function *************
    strlen(salt_value) = 32
    PKCS#5 :fd03d3c1ce


    I clearly see my result doesn't match with the website result.


    When i modify the same program with previous method of coying salt_value[] to a file, then read back into 64 bytes array and pass it to PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
    const unsigned char *salt, int saltlen, int iter,
    int keylen, unsigned char *out)


    with 64 as len, my results match with those of website..

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. clarification on fgetc definition
    By Satya in forum C Programming
    Replies: 5
    Last Post: 02-29-2012, 10:15 PM
  2. fgetc Reading 65535 is 255?
    By cboard_member in forum C++ Programming
    Replies: 6
    Last Post: 03-12-2006, 11:11 AM
  3. fgets not working after fgetc
    By 1978Corvette in forum C Programming
    Replies: 3
    Last Post: 01-22-2006, 05:33 PM
  4. reading from a file... fgetc??
    By demi222 in forum C Programming
    Replies: 13
    Last Post: 10-14-2005, 04:32 PM
  5. fgetc or fgets
    By flightsimdude in forum C Programming
    Replies: 4
    Last Post: 09-18-2003, 04:05 PM

Tags for this Thread


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21