1

The signature is:

char* crypt_gensalt(const char *prefix, unsigned long count,
    const char *input, int size)

This call:

char data[50] = "111111";
crypt_gensalt("$2a$10$", 10, data, sizeof(data))

generates:

$2a$10$KRCvKRCv..............
  1. What should be used to create the data array?
  2. What is the count in the prefix used for (since the count passed as the integer argument is what is included in the salt?
  3. What is the point of using crypt_gensalt() instead generating a salt from /dev/urandom?

Thank you!

John Cashew
  • 1,078
  • 2
  • 12
  • 28

1 Answers1

1

1) Nothing will create the data array using crypt_gensalt. Why? crypt_gensalt returns a pointer to the setting string that is passed to the crypt function itself. If you want to store the value returned by crypt_gensalt, you must copy the string pointed to by the return to data manually. There is a separate function however, crypt_gensalt_rn that will fill a character array for you. See man 3 crypt_gensalt for details. The declaration from the man page is:

char *crypt_gensalt_rn (const char *prefix, unsigned long count, 
                        const char *input, int size, char *output, 
                        int output_size);

which allowed providing your character array as 'output' to be filled by the function as opposed to returning a pointer to it alone.

You should not include 10 in your prefix, "$2a$" is proper (but see note for "$2y$" below). The count is added by crypt_gensalt and is part of the setting string it returns. Your input string should match the format:

const char *input = "\$2[axy]\$[0-9]{2}\$[./A-Za-z0-9]{53}";

note: you should use "$2y$" as the prefix, instead of "$2a$" as of version 1.2 of the library. e.g. "Version 1.2 adds support for the $2y$ prefix (denoting correctly computed hashes) and a countermeasure to avoid one-correct to many-buggy hash collisions with the $2a$ prefix" See: Openwall Site - Modern password hashing

2) The count in the prefix is the additional number of times the salt generation algorithm is run beyond the default. (if set to 0, the default is used).

3) The purpose is that crypt_gensalt returns a pointer to a null-terminated string formatted to be used as setting in the crypt function call:

char *crypt(const char *key, const char *setting);
David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • Thank you for your reply. When you say "1) Nothing will create the data array using" do you mean that the data parameter passed to crypt_gensalt() should be uninitialized memory? – John Cashew Oct 19 '15 at 17:55
  • crypt_gensalt is implemented with crypt_gensalt_rn. They both generate the salt with the same algorithm. By the way the openwall crypt_gensalt manpage does not mention any of the crypt_gensalt* functions. What source did you find a for a useful man page for that function? – John Cashew Oct 19 '15 at 17:57
  • On opensuse 13.1 it was just `man crypt_gensalt`, but you can find it [**man crypt in pdf**](http://www.openwall.com/crypt/openwall-crypt.3.pdf) from the openwall page. Thanks for the clarification on `crypt_gensalt_rn`, I didn't look at the source code. I added the declaration from the man page I found. – David C. Rankin Oct 19 '15 at 18:17
  • From the first comment, you should initialize all values sent to `crypt_gensalt`, what I meant was that the vanilla `crypt_gensalt` does not take a parameter that it will fill for you compared to the `'output'` parameter that `crypt_gensalt_rn` takes. – David C. Rankin Oct 19 '15 at 18:23
  • Thank for all the replies but my main question is still not answered. How should the random input to crypt_gensalt*() be generated and encoded. The man page says it can be read from /dev/urandom, but what format should it be in (printable chars or 0 to 255)? My guess is that the input is 0-255 without any prefix because it seems crypt_gensalt*() calls BF_encode() which does not seem to a blowfish encoder as the name implies, it seems to be a base64 encoder. – John Cashew Oct 19 '15 at 19:10
  • Oh, now I see which side of the question you are coming from. You are wanting to feed random values to it using something other than `/dev/urandom`. If I recall correctly, `/dev/urandom` is `2-bytes` or a `short`. (`unsigned` for `urandom`) – David C. Rankin Oct 19 '15 at 19:17
  • `/dev/urandom` is a full unsigned (e.g. `od -vAn -N4 -tu4 < /dev/urandom`) – David C. Rankin Oct 19 '15 at 19:23
  • I am happy to use /dev/urandom. No, /dev/urandom is not 2-bytes or a short. You read a byte array from it. – John Cashew Oct 19 '15 at 19:23
  • Yep, just double-checked the man page. I had my brain stuck in bash `$RANDOM` mode... Happens the older you get... – David C. Rankin Oct 19 '15 at 19:25
  • I think I now see where your question is, you take the bytes from `/dev/urandom` as `'input'` to `crypt_gensalt` specifying the `'size'` (number of random bytes) to use. I have found no further documentation on any other specific format of `input` required. – David C. Rankin Oct 19 '15 at 19:30