Skip to content

Commit

Permalink
Make Bcrypt thread safe (#7)
Browse files Browse the repository at this point in the history
* Make Bcrypt thread safe

* swift format
  • Loading branch information
adam-fowler authored May 18, 2021
1 parent 8b949f8 commit 375b64f
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 35 deletions.
29 changes: 2 additions & 27 deletions Sources/CBcrypt/bcrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ static int decode_base64(u_int8_t *, size_t, const char *);
/*
* Generates a salt for this version of crypt.
*/
static int
bcrypt_initsalt_with_csalt(int log_rounds, char *salt, size_t saltbuflen, const uint8_t *csalt)
int
c_hb_bcrypt_initsalt_with_csalt(int log_rounds, char *salt, size_t saltbuflen, const uint8_t *csalt)
{
if (saltbuflen < BCRYPT_SALTSPACE) {
errno = EINVAL;
Expand Down Expand Up @@ -309,28 +309,3 @@ encode_base64(char *b64buffer, const u_int8_t *data, size_t len)
*bp = '\0';
return 0;
}

/*
* classic interface
*/
char *
c_hb_bcrypt_gensalt_with_csalt(u_int8_t log_rounds, const u_int8_t *csalt)
{
static char gsalt[BCRYPT_SALTSPACE];

bcrypt_initsalt_with_csalt(log_rounds, gsalt, sizeof(gsalt), csalt);

return gsalt;
}

char *
c_hb_bcrypt(const char *pass, const char *salt)
{
static char gencrypted[BCRYPT_HASHSPACE];

if (c_hb_bcrypt_hashpass(pass, salt, gencrypted, sizeof(gencrypted)) != 0)
return NULL;

return gencrypted;
}
DEF_WEAK(bcrypt);
6 changes: 3 additions & 3 deletions Sources/CBcrypt/include/bcrypt.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@
#define BCRYPT_WORDS 6 /* Ciphertext words */
#define BCRYPT_MINLOGROUNDS 4 /* we have log2(rounds) in salt */

#define BCRYPT_SALTSPACE (7 + (BCRYPT_MAXSALT * 4 + 2) / 3 + 1)
#define BCRYPT_SALTSPACE 30 /* (7 + (BCRYPT_MAXSALT * 4 + 2) / 3 + 1) */
#define BCRYPT_HASHSPACE 61

/// generate salt given a cost and random buffer of 16 bytes
char *c_hb_bcrypt_gensalt_with_csalt(u_int8_t cost, const uint8_t *csalt);
int c_hb_bcrypt_initsalt_with_csalt(int log_rounds, char *salt, size_t saltbuflen, const uint8_t *csalt);
/// encrypt `pass` using `salt`
char *c_hb_bcrypt(const char *pass, const char *salt);
int c_hb_bcrypt_hashpass(const char *key, const char *salt, char *encrypted, size_t encryptedlen);
/// check `pass` against hash
int c_hb_bcrypt_checkpass(const char *pass, const char *goodhash);
12 changes: 7 additions & 5 deletions Sources/HummingbirdAuth/BCrypt/Bcrypt.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@ public enum Bcrypt {

// create random salt here, instead of using C as arc4random_buf is not always available
let csalt: [UInt8] = (0..<BCRYPT_MAXSALT).map { _ in UInt8.random(in: .min ... .max) }
// can guarantee salt if non nil
let salt = csalt.withUnsafeBufferPointer {
c_hb_bcrypt_gensalt_with_csalt(cost, $0.baseAddress)!
let salt = [CChar](unsafeUninitializedCapacity: Int(BCRYPT_SALTSPACE)) { bytes, _ in
_ = c_hb_bcrypt_initsalt_with_csalt(Int32(cost), bytes.baseAddress, Int(BCRYPT_SALTSPACE), csalt)
}

// create hashed data
let hashedData = [CChar](unsafeUninitializedCapacity: Int(BCRYPT_HASHSPACE)) { bytes, _ in
_ = c_hb_bcrypt_hashpass(text, salt, bytes.baseAddress, Int(BCRYPT_HASHSPACE))
}

// can guarantee hash data is valid as salt was created correctly
let hashedData = c_hb_bcrypt(text, salt)!
return String(cString: hashedData)
}

Expand Down

0 comments on commit 375b64f

Please sign in to comment.