1

char *crypt_r(const char *key, const char *setting, void *data)

What is one supposed to pass as data argument? I can't find the docs for this. The Linux version uses the crypt_data type but that's not available in this header.

http://www.openwall.com/crypt/

XTF
  • 1,091
  • 1
  • 13
  • 31

1 Answers1

0

This is a tricky interface because it wants to allocate and then recycle an opaque-to-the-caller buffer of opaque-to-the-caller size, which is not something that is easy in C.

If I'm reading the OpenWall crypt(3) manpage (PDF) correctly, you should be able to get the crypt_data struct declared by defining _GNU_SOURCE before including any system headers (not just before including crypt.h). Or, you could use crypt_ra, something like this. (Note: C++ <string> and <vector> used to avoid a bunch of tedious memory allocation cruft which would obscure the important parts of the example. Crash-on-failure behavior for the same reason. Not tested at all; not even compiled.)

#define _OW_SOURCE
#include <crypt.h>
#include <string>
#include <vector>

using std::vector;
using std::string;

void crypt_many(vector<string> &encrypted,
                vector<string> const &passwords,
                const char *setting)
{
    void *buffer = 0;
    int bufsiz = 0;

    encrypted.clear();
    encrypted.reserve(passwords.size());
    for (auto p = passwords.begin(), limit = passwords.end();
         p != limit; p++)
    {
        char *enc = crypt_ra(p->c_str(), setting, &buffer, &bufsiz);
        if (!enc) abort();
        encrypted.push_back(string(enc));
    }

    free(buffer);
}

On the first call to crypt_ra, it allocates some amount of memory using malloc and stashes it in buffer (and the size in bufsiz), and does some precomputation, whose results are saved in buffer; the returned enc pointer also points in there. On subsequent calls, it reuses the space and the precomputed tables, and it may resize the buffer if it notices it's not big enough (this is why the buffer size is an argument). You, the caller, don't touch buffer or bufsiz at all, except that it is your responsibility to free buffer when you're done using crypt_ra.

zwol
  • 135,547
  • 38
  • 252
  • 361
  • You shouldn't be using the same setting / salt for multiple passwords should you? – XTF May 01 '17 at 19:17
  • @XTF I *think* it will generate a new random salt for each password if you supply only an algorithm-selection code in the "setting" string, but I could have misunderstood the documentation. – zwol May 01 '17 at 20:40
  • AFAIK `setting` should come from `crypt_gensalt()` and the random bits come from its `input` parameter. – XTF May 02 '17 at 07:31