1#include "libc.h"
2#include <crypt.h>
3
4struct crypt_data;
5
6char* __crypt_des(const char*, const char*, char*);
7char* __crypt_md5(const char*, const char*, char*);
8char* __crypt_blowfish(const char*, const char*, char*);
9char* __crypt_sha256(const char*, const char*, char*);
10char* __crypt_sha512(const char*, const char*, char*);
11
12char* __crypt_r(const char* key, const char* salt, struct crypt_data* data) {
13    /* Per the crypt_r API, the caller has provided a pointer to
14     * struct crypt_data; however, this implementation does not
15     * use the structure to store any internal state, and treats
16     * it purely as a char buffer for storing the result. */
17    char* output = (char*)data;
18    if (salt[0] == '$' && salt[1] && salt[2]) {
19        if (salt[1] == '1' && salt[2] == '$')
20            return __crypt_md5(key, salt, output);
21        if (salt[1] == '2' && salt[3] == '$')
22            return __crypt_blowfish(key, salt, output);
23        if (salt[1] == '5' && salt[2] == '$')
24            return __crypt_sha256(key, salt, output);
25        if (salt[1] == '6' && salt[2] == '$')
26            return __crypt_sha512(key, salt, output);
27    }
28    return __crypt_des(key, salt, output);
29}
30
31weak_alias(__crypt_r, crypt_r);
32