nss_sha512crypt.c revision 2951a9a84bd85f384213a3e071ffc167907df2d7
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce/* This file is based on the work of Ulrich Drepper
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce * (http://people.redhat.com/drepper/SHA-crypt.txt). I have replaced the
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce * included SHA512 implementation by calls to NSS
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce * (http://www.mozilla.org/projects/security/pki/nss/).
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce * Sumit Bose <sbose@redhat.com>
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce/* SHA512-based UNIX crypt implementation.
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce Released into the Public Domain by Ulrich Drepper <drepper@redhat.com>. */
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce/* Define our magic string to mark salt for SHA512 "encryption" replacement. */
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce#define SALT_PREF_SIZE (sizeof(sha512_salt_prefix) - 1)
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce/* Prefix for optional rounds specification. */
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce#define ROUNDS_SIZE (sizeof(sha512_rounds_prefix) - 1)
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce/* Table with characters for base64 transformation. */
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce/* base64 conversion function */
41cd6072648bb7a9e14e56ed38004a2947f67657Jakub Hrozekstatic inline void b64_from_24bit(char **dest, size_t *len, size_t n,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce for (i = 0; i < n; i++) {
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce#define PTR_2_INT(x) ((x) - ((__typeof__ (x)) NULL))
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce const char *salt,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce unsigned char temp_result[64] __attribute__((__aligned__(ALIGN64)));
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce unsigned char alt_result[64] __attribute__((__aligned__(ALIGN64)));
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce unsigned int part;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce /* Find beginning of salt string. The prefix should normally always be
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce * present. Just in case it is not. */
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (strncmp(salt, sha512_salt_prefix, SALT_PREF_SIZE) == 0) {
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce /* Skip salt prefix. */
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (strncmp(salt, sha512_rounds_prefix, ROUNDS_SIZE) == 0) {
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce unsigned long int srounds;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce const char *num;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce salt_len = MIN(strcspn(salt, "$"), SALT_LEN_MAX);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce key = copied_key = memcpy(tmp + ALIGN64 - PTR_2_INT(tmp) % ALIGN64, key, key_len);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce salt = copied_salt = memcpy(tmp + ALIGN64 - PTR_2_INT(tmp) % ALIGN64, salt, salt_len);
goto done;
if (rounds_custom) {
if (n < 0 || n >= buflen) {
goto done;
cp += n;
buflen -= n;
goto done;
p1 = 0;
if (buflen == 0) {
goto done;
if (buflen == 0) {
goto done;
done:
return ret;
char *hash;
int ret;
return ret;
int ret;
return EIO;
if (!salt) {
return ENOMEM;
return EIO;
return EOK;