From 4ef1a332d19bfa04b9d7b623d0641879fa00985e Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Wed, 7 May 2014 15:14:12 -0700 Subject: [PATCH] Add crypto_pwhash_scryptxsalsa208sha256_str() --- .../crypto_scrypt-common.c | 8 +-- .../pwhash_scryptxsalsa208sha256.c | 62 +++++++++++++++++++ .../crypto_pwhash_scryptxsalsa208sha256.h | 20 +++++- 3 files changed, 85 insertions(+), 5 deletions(-) diff --git a/src/libsodium/crypto_pwhash/scryptxsalsa208sha256/crypto_scrypt-common.c b/src/libsodium/crypto_pwhash/scryptxsalsa208sha256/crypto_scrypt-common.c index 0df27f03..2101e7e9 100644 --- a/src/libsodium/crypto_pwhash/scryptxsalsa208sha256/crypto_scrypt-common.c +++ b/src/libsodium/crypto_pwhash/scryptxsalsa208sha256/crypto_scrypt-common.c @@ -29,8 +29,7 @@ #define BYTES2CHARS(bytes) \ ((((bytes) * 8) + 5) / 6) -#define HASH_SIZE 32 /* bytes */ -#define HASH_LEN BYTES2CHARS(HASH_SIZE) /* base-64 chars */ +#define HASH_LEN BYTES2CHARS(crypto_pwhash_scryptxsalsa208sha256_STRHASHBYTES) /* base-64 chars */ static const char * const itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; @@ -113,7 +112,7 @@ uint8_t * escrypt_r(escrypt_local_t * local, const uint8_t * passwd, size_t passwdlen, const uint8_t * setting, uint8_t * buf, size_t buflen) { - uint8_t hash[HASH_SIZE]; + uint8_t hash[crypto_pwhash_scryptxsalsa208sha256_STRHASHBYTES]; escrypt_kdf_t escrypt_kdf; const uint8_t *src; const uint8_t *salt; @@ -186,7 +185,8 @@ escrypt_gensalt_r(uint32_t N_log2, uint32_t r, uint32_t p, uint8_t * buf, size_t buflen) { uint8_t *dst; - size_t prefixlen = 3 + 1 + 5 + 5; + size_t prefixlen = + (sizeof "$7$" - 1U) + (1U /* N_log2 */) + (5U /* r */) + (5U /* p */); size_t saltlen = BYTES2CHARS(srclen); size_t need; diff --git a/src/libsodium/crypto_pwhash/scryptxsalsa208sha256/pwhash_scryptxsalsa208sha256.c b/src/libsodium/crypto_pwhash/scryptxsalsa208sha256/pwhash_scryptxsalsa208sha256.c index 1b254657..6ada4696 100644 --- a/src/libsodium/crypto_pwhash/scryptxsalsa208sha256/pwhash_scryptxsalsa208sha256.c +++ b/src/libsodium/crypto_pwhash/scryptxsalsa208sha256/pwhash_scryptxsalsa208sha256.c @@ -6,6 +6,12 @@ #include "crypto_pwhash_scryptxsalsa208sha256.h" #include "crypto_scrypt.h" +#include "randombytes.h" + +#define BYTES2CHARS(bytes) ((((bytes) * 8) + 5) / 6) +#define SETTING_SIZE(saltbytes) \ + (sizeof "$7$" - 1U) + \ + (1U /* N_log2 */) + (5U /* r */) + (5U /* p */) + BYTES2CHARS(saltbytes) static int pickparams(const size_t memlimit, unsigned long long opslimit, @@ -48,6 +54,12 @@ crypto_pwhash_scryptxsalsa208sha256_saltbytes(void) return crypto_pwhash_scryptxsalsa208sha256_SALTBYTES; } +size_t +crypto_pwhash_scryptxsalsa208sha256_strbytes(void) +{ + return crypto_pwhash_scryptxsalsa208sha256_STRBYTES; +} + int crypto_pwhash_scryptxsalsa208sha256(unsigned char * const out, unsigned long long outlen, @@ -75,3 +87,53 @@ crypto_pwhash_scryptxsalsa208sha256(unsigned char * const out, (uint64_t) (1) << N_log2, r, p, out, (size_t) outlen); } + +int +crypto_pwhash_scryptxsalsa208sha256_str(char * const out, + const char * const passwd, + unsigned long long passwdlen, + size_t memlimit, + unsigned long long opslimit) +{ + uint8_t salt[crypto_pwhash_scryptxsalsa208sha256_STRSALTBYTES]; + char setting[crypto_pwhash_scryptxsalsa208sha256_STRSETTINGBYTES + 1U]; + escrypt_local_t escrypt_local; + uint32_t N_log2; + uint32_t p; + uint32_t r; + + if (passwdlen > SIZE_MAX) { + errno = EFBIG; + return -1; + } + if (pickparams(memlimit, opslimit, &N_log2, &p, &r) != 0) { + errno = EINVAL; + return -1; + } + randombytes_buf(salt, sizeof salt); + if (escrypt_gensalt_r(N_log2, r, p, salt, sizeof salt, + (uint8_t *) setting, sizeof setting) == NULL) { + errno = EINVAL; + return -1; + } + if (escrypt_init_local(&escrypt_local) != 0) { + return -1; + } + if (escrypt_r(&escrypt_local, (const uint8_t *) passwd, (size_t) passwdlen, + (const uint8_t *) setting, (uint8_t *) out, + crypto_pwhash_scryptxsalsa208sha256_STRBYTES) == NULL) { + errno = EINVAL; + return -1; + } + escrypt_free_local(&escrypt_local); + + (void) sizeof + (int[SETTING_SIZE(crypto_pwhash_scryptxsalsa208sha256_STRSALTBYTES) + == crypto_pwhash_scryptxsalsa208sha256_STRSETTINGBYTES ? 1 : -1]); + (void) sizeof + (int[crypto_pwhash_scryptxsalsa208sha256_STRSETTINGBYTES + 1U + + crypto_pwhash_scryptxsalsa208sha256_STRHASHBYTES_ENCODED + 1U + == crypto_pwhash_scryptxsalsa208sha256_STRBYTES ? 1 : -1]); + + return 0; +} diff --git a/src/libsodium/include/sodium/crypto_pwhash_scryptxsalsa208sha256.h b/src/libsodium/include/sodium/crypto_pwhash_scryptxsalsa208sha256.h index c3ea1a40..eba37679 100644 --- a/src/libsodium/include/sodium/crypto_pwhash_scryptxsalsa208sha256.h +++ b/src/libsodium/include/sodium/crypto_pwhash_scryptxsalsa208sha256.h @@ -7,6 +7,13 @@ #include "export.h" #define crypto_pwhash_scryptxsalsa208sha256_SALTBYTES 32 +#define crypto_pwhash_scryptxsalsa208sha256_STRBYTES 102 +#define crypto_pwhash_scryptxsalsa208sha256_STRPREFIXBYTES 14 +#define crypto_pwhash_scryptxsalsa208sha256_STRSETTINGBYTES 57 +#define crypto_pwhash_scryptxsalsa208sha256_STRSALTBYTES 32 +#define crypto_pwhash_scryptxsalsa208sha256_STRSALTBYTES_ENCODED 43 +#define crypto_pwhash_scryptxsalsa208sha256_STRHASHBYTES 32 +#define crypto_pwhash_scryptxsalsa208sha256_STRHASHBYTES_ENCODED 43 #ifdef __cplusplus # if __GNUC__ @@ -18,6 +25,9 @@ extern "C" { SODIUM_EXPORT size_t crypto_pwhash_scryptxsalsa208sha256_saltbytes(void); +SODIUM_EXPORT +size_t crypto_pwhash_scryptxsalsa208sha256_strbytes(void); + SODIUM_EXPORT int crypto_pwhash_scryptxsalsa208sha256(unsigned char * const out, unsigned long long outlen, @@ -26,7 +36,15 @@ int crypto_pwhash_scryptxsalsa208sha256(unsigned char * const out, const unsigned char * const salt, size_t memlimit, unsigned long long opslimit); - + +SODIUM_EXPORT +int +crypto_pwhash_scryptxsalsa208sha256_str(char * const out, + const char * const passwd, + unsigned long long passwdlen, + size_t memlimit, + unsigned long long opslimit); + #ifdef __cplusplus } #endif