/* This file is based on nss_sha512crypt.c which is based on the work of
* Ulrich Drepper (http://people.redhat.com/drepper/SHA-crypt.txt).
*
* libcrypto is used to provide SHA512 and random number generation.
*
* Sumit Bose <sbose@redhat.com>
* George McCollister <georgem@novatech-llc.com>
*/
/* SHA512-based Unix crypt implementation.
Released into the Public Domain by Ulrich Drepper <drepper@redhat.com>. */
#include "config.h"
#include <errno.h>
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "util/sss_endian.h"
#include "sss_openssl.h"
/* Define our magic string to mark salt for SHA512 "encryption" replacement. */
/* Prefix for optional rounds specification. */
/* Table with characters for base64 transformation. */
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
/* base64 conversion function */
{
uint32_t w;
size_t i;
for (i = 0; i < n; i++) {
w >>= 6;
}
*len -= i;
*dest += i;
}
const char *salt,
{
bool rounds_custom = false;
unsigned int part;
int ret;
/* Find beginning of salt string. The prefix should normally always be
* present. Just in case it is not. */
/* Skip salt prefix. */
salt += SALT_PREF_SIZE;
}
unsigned long int srounds;
const char *num;
char *endp;
if (*endp == '$') {
rounds_custom = true;
}
}
}
}
ctx = EVP_MD_CTX_new();
goto done;
}
alt_ctx = EVP_MD_CTX_new();
goto done;
}
/* Prepare for the real work. */
goto done;
}
/* Add the key string. */
/* The last part is the salt string. This must be at most 16
* characters and it ends at the first `$' character (for
* compatibility with existing implementations). */
/* Compute alternate SHA512 sum with input KEY, SALT, and KEY.
* The final result will be added to the first context. */
goto done;
}
/* Add key. */
/* Add salt. */
/* Add key again. */
/* Now get result of this (64 bytes) and add it to the other context. */
/* Add for any character in the key one byte of the alternate sum. */
}
/* Take the binary representation of the length of the key and for every
* 1 add the alternate sum, for every 0 the key. */
if ((cnt & 1) != 0) {
} else {
}
}
/* Create intermediate result. */
/* Start computation of P byte sequence. */
goto done;
}
/* For every character in the password add the entire password. */
}
/* Finish the digest. */
/* Create byte sequence P. */
}
/* Start computation of S byte sequence. */
goto done;
}
/* For every character in the password add the entire salt. */
}
/* Finish the digest. */
/* Create byte sequence S. */
}
/* Repeatedly run the collected hash value through SHA512 to burn CPU cycles. */
goto done;
}
/* Add key or last result. */
if ((cnt & 1) != 0) {
} else {
}
/* Add salt for numbers not divisible by 3. */
if (cnt % 3 != 0) {
}
/* Add key for numbers not divisible by 7. */
if (cnt % 7 != 0) {
}
/* Add key or last result. */
if ((cnt & 1) != 0) {
} else {
}
/* Create intermediate result. */
}
/* Now we can construct the result string.
* It consists of three parts. */
if (buflen <= SALT_PREF_SIZE) {
goto done;
}
buflen -= SALT_PREF_SIZE;
if (rounds_custom) {
if (n < 0 || n >= buflen) {
goto done;
}
cp += n;
buflen -= n;
}
goto done;
}
*cp++ = '$';
/* fuzzyfill the base 64 string */
p1 = 0;
p2 = 21;
p3 = 42;
for (n = 0; n < 21; n++) {
if (buflen == 0) {
goto done;
}
}
/* 64th and last byte */
if (buflen == 0) {
goto done;
}
*cp = '\0';
done:
/* Clear the buffer for the intermediate result so that people attaching
* to processes or reading core dumps cannot get any information. We do it
* in this way to clear correct_words[] inside the SHA512 implementation
* as well. */
return ret;
}
{
char *hash;
int ret;
return ret;
}
{
int ret;
if (!salt) {
return ENOMEM;
}
if (ret == 0) {
return EIO;
}
slen = SALT_LEN_MAX;
*cp = '\0';
return EOK;
}