/* Compute the SCRAM step Hi() as defined in RFC5802 */ static void _mongoc_scram_salt_password (mongoc_scram_t *scram, const char *password, size_t password_len, const uint8_t *salt, size_t salt_len, int64_t iterations) { uint8_t intermediate_digest[MONGOC_SCRAM_HASH_SIZE]; uint8_t start_key[MONGOC_SCRAM_HASH_SIZE]; /* Placeholder for HMAC return size, will always be scram::hashSize for HMAC SHA-1 */ #if !defined(__APPLE__) uint32_t hash_len = 0; #endif int i; int k; uint8_t *output = scram->salted_password; memcpy (start_key, salt, salt_len); start_key[salt_len] = 0; start_key[salt_len + 1] = 0; start_key[salt_len + 2] = 0; start_key[salt_len + 3] = 1; /* U1 = HMAC(input, salt + 0001) */ #if defined(__APPLE__) CCHmac (kCCHmacAlgSHA1, password, password_len, start_key, sizeof (start_key), output); #else HMAC (EVP_sha1 (), password, password_len, start_key, sizeof (start_key), output, &hash_len); #endif memcpy (intermediate_digest, output, MONGOC_SCRAM_HASH_SIZE); /* intermediateDigest contains Ui and output contains the accumulated XOR:ed result */ for (i = 2; i <= iterations; i++) { #if defined(__APPLE__) CCHmac (kCCHmacAlgSHA1, password, password_len, intermediate_digest, sizeof (intermediate_digest), intermediate_digest); #else HMAC (EVP_sha1 (), password, password_len, intermediate_digest, sizeof (intermediate_digest), intermediate_digest, &hash_len); #endif for (k = 0; k < MONGOC_SCRAM_HASH_SIZE; k++) { output[k] ^= intermediate_digest[k]; } } }
static bool _mongoc_scram_generate_client_proof (mongoc_scram_t *scram, uint8_t *outbuf, size_t outbufmax, size_t *outbuflen) { /* ClientKey := HMAC(saltedPassword, "Client Key") */ uint8_t client_key[MONGOC_SCRAM_HASH_SIZE]; uint8_t stored_key[MONGOC_SCRAM_HASH_SIZE]; uint8_t client_signature[MONGOC_SCRAM_HASH_SIZE]; unsigned char client_proof[MONGOC_SCRAM_HASH_SIZE]; #if !defined(__APPLE__) uint32_t hash_len = 0; #endif int i; int r = 0; #if defined(__APPLE__) CCHmac (kCCHmacAlgSHA1, scram->salted_password, MONGOC_SCRAM_HASH_SIZE, (uint8_t *)MONGOC_SCRAM_CLIENT_KEY, strlen (MONGOC_SCRAM_CLIENT_KEY), client_key); /* StoredKey := H(client_key) */ CC_SHA1 (client_key, MONGOC_SCRAM_HASH_SIZE, stored_key); /* ClientSignature := HMAC(StoredKey, AuthMessage) */ CCHmac (kCCHmacAlgSHA1, stored_key, MONGOC_SCRAM_HASH_SIZE, scram->auth_message, scram->auth_messagelen, client_signature); #else HMAC (EVP_sha1 (), scram->salted_password, MONGOC_SCRAM_HASH_SIZE, (uint8_t *)MONGOC_SCRAM_CLIENT_KEY, strlen (MONGOC_SCRAM_CLIENT_KEY), client_key, &hash_len); /* StoredKey := H(client_key) */ SHA1 (client_key, MONGOC_SCRAM_HASH_SIZE, stored_key); /* ClientSignature := HMAC(StoredKey, AuthMessage) */ HMAC (EVP_sha1 (), stored_key, MONGOC_SCRAM_HASH_SIZE, scram->auth_message, scram->auth_messagelen, client_signature, &hash_len); #endif /* ClientProof := ClientKey XOR ClientSignature */ for (i = 0; i < MONGOC_SCRAM_HASH_SIZE; i++) { client_proof[i] = client_key[i] ^ client_signature[i]; } r = mongoc_b64_ntop (client_proof, sizeof (client_proof), (char *)outbuf + *outbuflen, outbufmax - *outbuflen); if (-1 == r) { return false; } *outbuflen += r; return true; }
static size_t s3_sign(unsigned char *digest, kstring_t *key, kstring_t *message) { CCHmac(kCCHmacAlgSHA1, key->s, key->l, message->s, message->l, digest); return CC_SHA1_DIGEST_LENGTH; }