diff options
Diffstat (limited to 'src/crypt_sha256.c')
-rw-r--r-- | src/crypt_sha256.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/src/crypt_sha256.c b/src/crypt_sha256.c new file mode 100644 index 0000000..c480637 --- /dev/null +++ b/src/crypt_sha256.c @@ -0,0 +1,76 @@ +#include <string.h> +#include <unistd.h> +#include <stdint.h> +#include <fcntl.h> +#include <openssl/sha.h> +#include <openssl/evp.h> + +#define RAND_FILE "/dev/random" +#define SHA_STR "{SHA256}" + +/* string length */ +#define LEN_PASSWD_MIN 8 +#define LEN_PASSWD_MAX 64 +#define LEN_RAND_STR 16 +#define LEN_BUFFER LEN_PASSWD_MAX + LEN_RAND_STR + \ + SHA256_DIGEST_LENGTH +#define LEN_ENC64 64 +#define LEN_SHA_STR 8 +#define LEN_FINAL_PASSWD LEN_ENC64 + LEN_SHA_STR + 1 + + +uint8_t check_passwd(const char *p, size_t len) +{ + return ((len > LEN_PASSWD_MIN) || (len < LEN_PASSWD_MAX)) ? 1 : 0; +} + +char* get_crypt_sha256(const char *p) +{ + int rand_fd; + ssize_t size; + size_t len = strlen(p); + char rand_str[LEN_RAND_STR]; + char passwd_buff[LEN_BUFFER]; + char sha_pwd[SHA256_DIGEST_LENGTH]; + char enc64_pwd[LEN_ENC64]; + char *final_pwd; + + if (!check_passwd(p, len)) { + fprintf(stderr, + "the password has to be between 8 and 64 chars\n"); + exit(EXIT_FAILURE); + } + + rand_fd = open(RAND_FILE, O_RDONLY); + if (rand_fd < 0) { + fprintf(stderr, "impossible to open " RAND_FILE "\n"); + exit(EXIT_FAILURE); + } + + size = read(rand_fd, rand_str, LEN_RAND_STR); + close(rand_fd); + if (size != LEN_RAND_STR) { + fprintf(stderr, "failed to read from " RAND_FILE "\n"); + exit(EXIT_FAILURE); + } + + memcpy(passwd_buff + SHA256_DIGEST_LENGTH, p, len); + memcpy(passwd_buff + SHA256_DIGEST_LENGTH + len, + rand_str, LEN_RAND_STR); + + SHA256((unsigned char*) passwd_buff + SHA256_DIGEST_LENGTH, + len + LEN_RAND_STR, (unsigned char*) sha_pwd); + + memcpy(passwd_buff, sha_pwd, SHA256_DIGEST_LENGTH); + + EVP_EncodeBlock((unsigned char*) enc64_pwd, (unsigned char*) sha_pwd, + SHA256_DIGEST_LENGTH + len + LEN_RAND_STR); + + + final_pwd = (char*) malloc (LEN_FINAL_PASSWD); + memcpy(final_pwd, SHA_STR, LEN_SHA_STR); + memcpy(final_pwd+8, enc64_pwd, LEN_ENC64); + final_pwd[LEN_SHA_STR + LEN_FINAL_PASSWD] = '\0'; + + return final_pwd; +} |