bool passwordMatchesPBKDF2Hash(const char password[], HashData *theHash){ static __thread unsigned char hash[2048]; #ifdef USE_COMMON_CRYPTO CCKeyDerivationPBKDF(kCCPBKDF2, password, strlen(password), theHash->salt, 32, kCCPRFHmacAlgSHA512, theHash->rounds, hash, 128); #else PKCS5_PBKDF2_HMAC(password, strlen(password), theHash->salt, 32, theHash->rounds, EVP_sha512(), 128, hash); /* static __thread mbedtls_md_context_t sha512_ctx; const mbedtls_md_info_t *info_sha512; mbedtls_md_init( &sha512_ctx ); info_sha512 = mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 ); mbedtls_md_setup( &sha512_ctx, info_sha512, 1 ); mbedtls_pkcs5_pbkdf2_hmac (&sha512_ctx, (const unsigned char *)password, strlen(password), theHash->salt, 32, theHash->rounds, 128, hash); mbedtls_md_free( &sha512_ctx ); */ #endif if (memcmp(theHash->hash, hash, 128) == 0){ return true; } return false; }
static int pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt, size_t salt_len, unsigned rounds, uint8_t *derived_key, size_t derived_key_len) { CCKeyDerivationPBKDF(kCCPBKDF2, (const char *)pw, pw_len, salt, salt_len, kCCPRFHmacAlgSHA1, rounds, derived_key, derived_key_len); return 0; }
virtual bool makeKey(const char *password, int passwordLength, const byte *salt, int saltLength, int numIterations, CipherKey *outKey) { int ret = CCKeyDerivationPBKDF(kCCPBKDF2, password, passwordLength, salt, saltLength, prf_, numIterations, outKey->data(), outKey->size()); if (ret != 0) { PLOG(ERROR) << "CCKeyDerivationPBKDF failed"; return false; } return true; }
C4Err PASS_TO_KEY (const uint8_t *password, unsigned long password_len, uint8_t *salt, unsigned long salt_len, unsigned int rounds, uint8_t *key_buf, unsigned long key_len ) { C4Err err = kC4Err_NoErr; #if _USES_COMMON_CRYPTO_ if( CCKeyDerivationPBKDF( kCCPBKDF2, (const char*)password, password_len, salt, salt_len, kCCPRFHmacAlgSHA256, rounds, key_buf, key_len) != kCCSuccess) err = kC4Err_BadParams; #else int status = CRYPT_OK; status = pkcs_5_alg2(password, password_len, salt, salt_len, rounds, find_hash("sha256"), key_buf, &key_len); CKSTAT; done: if(status != CRYPT_OK) err = sCrypt2C4Err(status); #endif return err; }
uint CCCalibratePBKDF(CCPBKDFAlgorithm algorithm, size_t passwordLen, size_t saltLen, CCPseudoRandomAlgorithm prf, size_t derivedKeyLen, uint32_t msec) { char *password; uint8_t *salt; uint64_t startTime, endTime, elapsedTime; uint8_t *derivedKey; int i; CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); if (derivedKeyLen == 0) return -1; // bad parameters if (saltLen == 0 || saltLen > CC_MAX_PRF_WORKSPACE) return -1; // out of bounds parameters if (passwordLen == 0 ) passwordLen = 1; if(algorithm != kCCPBKDF2) return -1; if((password = malloc(passwordLen)) == NULL) return -1; for(i=0; i<passwordLen; i++) password[i] = 'a'; if((salt = malloc(saltLen)) == NULL) return -1; for(i=0; i<saltLen; i++) salt[i] = i%256; if((derivedKey = malloc(derivedKeyLen)) == NULL) return -1; for(elapsedTime = 0, i=0; i < 5 && elapsedTime == 0; i++) { startTime = timer(); if(CCKeyDerivationPBKDF(algorithm, password, passwordLen, salt, saltLen, prf, ROUNDMEASURE, derivedKey, derivedKeyLen)) return -2; endTime = timer(); elapsedTime = endTime - startTime; } if(elapsedTime == 0) return 123456; // arbitrary, but something is seriously wrong free(password); free(salt); free(derivedKey); return (msec * ROUNDMEASURE)/elapsedTime; }
static SecKeyRef secDeriveKeyFromAnswers(CFArrayRef answers, CFLocaleRef theLocale) { static const uint8_t salt[16] = { 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x1F }; static const int saltLen = sizeof(salt); SecKeyRef theKey = NULL; uint8_t rawKeyData[RETURN_KEY_SIZE]; CFIndex encodedAnswers = 0; CFIndex numAnswers = CFArrayGetCount(answers); const size_t concatenatedAnswersSize = MAXANSWERBUFF * numAnswers; char *concatenatedAnswers = (char *)malloc(concatenatedAnswersSize); if (concatenatedAnswers == NULL) { return NULL; } concatenatedAnswers[0] = 0; // NUL terminate int i; for (i = 0; i < numAnswers; i++) { CFMutableStringRef answer = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, CFArrayGetValueAtIndex(answers, i)); if (answer) { secNormalize(answer, theLocale); CFIndex theAnswerLen = CFStringGetLength(answer); CFIndex theAnswerSize = CFStringGetMaximumSizeForEncoding(theAnswerLen, kCFStringEncodingUTF8); char *theAnswer = (char *)malloc(theAnswerSize + 1); // add space for NUL byte if (theAnswer) { if (theAnswerLen == CFStringGetBytes(answer, CFRangeMake(0, CFStringGetLength(answer)), kCFStringEncodingUTF8, '?', FALSE, (UInt8*)theAnswer, theAnswerSize, &theAnswerSize)) { theAnswer[theAnswerSize] = 0; // NUL terminate if (strlcat(concatenatedAnswers, theAnswer, concatenatedAnswersSize) < concatenatedAnswersSize) { encodedAnswers += 1; } } bzero(theAnswer, theAnswerSize); free(theAnswer); } CFRelease(answer); } } // one or more of the answers failed to encode if (encodedAnswers != numAnswers) { free(concatenatedAnswers); return NULL; } if (CCKeyDerivationPBKDF(kCCPBKDF2, concatenatedAnswers, strlen(concatenatedAnswers), salt, saltLen, kCCPRFHmacAlgSHA256, PBKDF_ROUNDS, rawKeyData, RETURN_KEY_SIZE)) { free(concatenatedAnswers); return NULL; } CFDataRef keyData = CFDataCreate(kCFAllocatorDefault, rawKeyData, RETURN_KEY_SIZE); if (keyData) { CFMutableDictionaryRef params = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if (params) { CFErrorRef error = NULL; CFDictionaryAddValue(params, kSecAttrKeyType, kSecAttrKeyTypeAES); theKey = SecKeyCreateFromData(params, keyData, &error); if (error) { CFRelease(error); } CFRelease(params); } CFRelease(keyData); } bzero(rawKeyData, RETURN_KEY_SIZE); bzero(concatenatedAnswers, concatenatedAnswersSize); free(concatenatedAnswers); return theKey; }
static void pbkdf2_hash(const char *username, size_t username_len, const char *password, size_t password_len, int iterations, unsigned char hash[KDF_HASH_LEN]) { if (CCKeyDerivationPBKDF(kCCPBKDF2, password, password_len, (const uint8_t *)username, username_len, kCCPRFHmacAlgSHA256, iterations, hash, KDF_HASH_LEN) == kCCParamError) die("Failed to compute PBKDF2 for %s", username); }
int decryptInit(int (*writerFunc)(void *, size_t), void *h) { CCCryptorStatus status; int rv; writer = writerFunc; strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.avail_in = 0; strm.next_in = Z_NULL; rv = inflateInit(&strm); if (rv != Z_OK) { printf("zlib init error\n"); return(-1); } getPassword(); memcpy(&header, h, sizeof(header)); if (isZero(encKey, kCCKeySizeAES256) || memcmp(header.keySalt, redsideSalts.keySalt, header.keySaltLen)) { redsideSalts.keySaltLen = header.keySaltLen; memcpy(redsideSalts.keySalt, header.keySalt, sizeof(header.keySalt)); /* AES KEY DERIVATION */ rv = CCKeyDerivationPBKDF(kCCPBKDF2, password, strlen(password), header.keySalt, header.keySaltLen, kCCPRFHmacAlgSHA512, kIterations, encKey, kCCKeySizeAES256); if (rv < 0) { printf("Key derivation: error: %d\n", rv); exit(1); } } if (isZero(hmacKey, kCCKeySizeAES256) || memcmp(header.hmacSalt, redsideSalts.hmacSalt, sizeof(header.hmacSalt))) { redsideSalts.hmacSaltLen = header.hmacSaltLen; memcpy(redsideSalts.hmacSalt, header.hmacSalt, header.hmacSaltLen); /* HMAC KEY DERIVATION */ rv = CCKeyDerivationPBKDF(kCCPBKDF2, password, strlen(password), header.hmacSalt, header.hmacSaltLen, kCCPRFHmacAlgSHA512, kIterations, hmacKey, kCCKeySizeAES256); if (rv < 0) { printf("HMAC Key derivation: error: %d\n", rv); exit(1); } } CCHmacInit(&hmacContext, kCCHmacAlgSHA512, hmacKey, kCCKeySizeAES256); CCHmacInit(&hmacContextPlain, kCCHmacAlgSHA512, hmacKey, kCCKeySizeAES256); status = CCCryptorCreate(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, encKey, kCCKeySizeAES256, header.iv, &cryptorRef); if (status != kCCSuccess) { printf("cryptor init error\n"); return(-1); } return(0); }
int encryptInit(int (*writerFunc)(void *, size_t), int (*seekerFunc)(size_t)) { CCCryptorStatus status; int rv; writer = writerFunc; seeker = seekerFunc; strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; rv = deflateInit(&strm, Z_DEFAULT_COMPRESSION); if (rv != Z_OK) { printf("zlib init error\n"); return(-1); } getPassword(); if (isZero(encKey, kCCKeySizeAES256) || isZero(hmacKey, kCCKeySizeAES256)) { header.keySaltLen = redsideSalts.keySaltLen; memcpy(header.keySalt, redsideSalts.keySalt, header.keySaltLen); /* AES KEY DERIVATION */ rv = CCKeyDerivationPBKDF(kCCPBKDF2, password, strlen(password), header.keySalt, header.keySaltLen, kCCPRFHmacAlgSHA512, kIterations, encKey, kCCKeySizeAES256); if (rv < 0) { printf("Key derivation: error: %d\n", rv); exit(1); } header.hmacSaltLen = redsideSalts.hmacSaltLen; memcpy(header.hmacSalt, redsideSalts.hmacSalt, header.hmacSaltLen); /* HMAC KEY DERIVATION */ rv = CCKeyDerivationPBKDF(kCCPBKDF2, password, strlen(password), header.hmacSalt, header.hmacSaltLen, kCCPRFHmacAlgSHA512, kIterations, hmacKey, kCCKeySizeAES256); if (rv < 0) { printf("HMAC Key derivation: error: %d\n", rv); exit(1); } } if (isZero(header.iv, sizeof(header.iv))) getSalt(header.iv, sizeof(header.iv)); CCHmacInit(&hmacContext, kCCHmacAlgSHA512, hmacKey, kCCKeySizeAES256); CCHmacInit(&hmacContextPlain, kCCHmacAlgSHA512, hmacKey, kCCKeySizeAES256); status = CCCryptorCreate(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, encKey, kCCKeySizeAES256, header.iv, &cryptorRef); if (status != kCCSuccess) { printf("cryptor init error\n"); return(-1); } seeker(sizeof(header)); return(0); }