void CKeyInfo::SetPassword(const Byte *data, UInt32 size) { NSha1::CContext sha; sha.Init(); sha.Update(data, size); DeriveKey(sha, MasterKey); }
static unsigned char* GeneratePasswordHashUsingSHA1(char *password) { unsigned char hashBuf[20], *inputBuf, *key, *final; /* H(0) = H(salt, password) * hashBuf = SHA1Hash(salt, password); * create input buffer for SHA1 from salt and unicode version of password */ unsigned char passwordBuf[512] = {0}; int passwordBufSize; int i; SHA_CTX ctx; /* convert key to UTF-16LE */ passwordBufSize = enc_to_utf16((UTF16*)passwordBuf, 125, (UTF8*)password, strlen(password)); if (passwordBufSize < 0) passwordBufSize = strlen16((UTF16*)passwordBuf); passwordBufSize <<= 1; inputBuf = (unsigned char *)malloc(salt_struct->saltSize + passwordBufSize); memcpy(inputBuf, salt_struct->osalt, salt_struct->saltSize); memcpy(inputBuf + salt_struct->saltSize, passwordBuf, passwordBufSize); SHA1_Init(&ctx); SHA1_Update(&ctx, inputBuf, salt_struct->saltSize + passwordBufSize); SHA1_Final(hashBuf, &ctx); free(inputBuf); /* Generate each hash in turn * H(n) = H(i, H(n-1)) * hashBuf = SHA1Hash(i, hashBuf); */ // Create an input buffer for the hash. This will be 4 bytes larger than // the hash to accommodate the unsigned int iterator value. inputBuf = (unsigned char *)malloc(0x14 + 0x04); // Create a byte array of the integer and put at the front of the input buffer // 1.3.6 says that little-endian byte ordering is expected memcpy(inputBuf + 4, hashBuf, 20); for (i = 0; i < 50000; i++) { *(int *)inputBuf = i; // XXX: size & endianness // 'append' the previously generated hash to the input buffer SHA1_Init(&ctx); SHA1_Update(&ctx, inputBuf, 0x14 + 0x04); SHA1_Final(inputBuf + 4, &ctx); } // Finally, append "block" (0) to H(n) // hashBuf = SHA1Hash(hashBuf, 0); i = 0; memmove(inputBuf, inputBuf + 4, 20); memcpy(inputBuf + 20, &i, 4); // XXX: size & endianness SHA1_Init(&ctx); SHA1_Update(&ctx, inputBuf, 0x14 + 0x04); SHA1_Final(hashBuf, &ctx); free(inputBuf); key = DeriveKey(hashBuf); // Should handle the case of longer key lengths as shown in 2.3.4.9 // Grab the key length bytes of the final hash as the encrypytion key final = (unsigned char *)malloc(salt_struct->keySize/8);
// Called by sqlite and sqlite3_key_interop to attach a key to a database. int sqlite3CodecAttach(sqlite3 *db, int nDb, const void *pKey, int nKeyLen) { int rc = SQLITE_ERROR; HCRYPTKEY hKey = 0; // No key specified, could mean either use the main db's encryption or no encryption if (!pKey || !nKeyLen) { if (!nDb) { return SQLITE_OK; // Main database, no key specified so not encrypted } else // Attached database, use the main database's key { // Get the encryption block for the main database and attempt to duplicate the key // for use by the attached database Pager *p = sqlite3BtreePager(db->aDb[0].pBt); LPCRYPTBLOCK pBlock = (LPCRYPTBLOCK)sqlite3pager_get_codecarg(p); if (!pBlock) return SQLITE_OK; // Main database is not encrypted so neither will be any attached database if (!pBlock->hReadKey) return SQLITE_OK; // Not encrypted if (!CryptDuplicateKey(pBlock->hReadKey, NULL, 0, &hKey)) return rc; // Unable to duplicate the key } } else // User-supplied passphrase, so create a cryptographic key out of it { hKey = DeriveKey(pKey, nKeyLen); if (hKey == MAXDWORD) { sqlite3Error(db, rc, SQLITECRYPTERROR_PROVIDER); return rc; } } // Create a new encryption block and assign the codec to the new attached database if (hKey) { Pager *p = sqlite3BtreePager(db->aDb[nDb].pBt); LPCRYPTBLOCK pBlock = CreateCryptBlock(hKey, p, -1, NULL); if (!pBlock) return SQLITE_NOMEM; sqlite3PagerSetCodec(p, sqlite3Codec, sqlite3CodecSizeChange, sqlite3CodecFree, pBlock); //db->aDb[nDb].pAux = pBlock; //db->aDb[nDb].xFreeAux = DestroyCryptBlock; rc = SQLITE_OK; } return rc; }
bool CHDKeyStore::GetKey(const CKeyID &address, CKey &keyOut) const { LOCK(cs_KeyStore); std::map<CKeyID, CHDPubKey>::const_iterator mi = mapHDPubKeys.find(address); if (mi != mapHDPubKeys.end()) { if (!DeriveKey(mi->second, keyOut)) return false; return true; } return CCryptoKeyStore::GetKey(address, keyOut); }
void Pkcs5Kdf::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt) const { DeriveKey (key, password, salt, GetIterationCount()); }
HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK) { passwOK = false; if (_remSize < 16) return E_NOTIMPL; Byte *p = _bufAligned; UInt16 format = GetUi16(p); if (format != 3) return E_NOTIMPL; UInt16 algId = GetUi16(p + 2); if (algId < kAES128) return E_NOTIMPL; algId -= kAES128; if (algId > 2) return E_NOTIMPL; UInt16 bitLen = GetUi16(p + 4); UInt16 flags = GetUi16(p + 6); if (algId * 64 + 128 != bitLen) return E_NOTIMPL; _key.KeySize = 16 + algId * 8; bool cert = ((flags & 2) != 0); if ((flags & 0x4000) != 0) { // Use 3DES for rd data return E_NOTIMPL; } if (cert) { return E_NOTIMPL; } else { if ((flags & 1) == 0) return E_NOTIMPL; } UInt32 rdSize = GetUi16(p + 8); if (rdSize + 16 > _remSize) return E_NOTIMPL; const unsigned kPadSize = kAesPadAllign; // is equal to blockSize of cipher for rd /* if (cert) { if ((rdSize & 0x7) != 0) return E_NOTIMPL; } else */ { // PKCS7 padding if (rdSize < kPadSize) return E_NOTIMPL; if ((rdSize & (kPadSize - 1)) != 0) return E_NOTIMPL; } memmove(p, p + 10, rdSize); const Byte *p2 = p + rdSize + 10; UInt32 reserved = GetUi32(p2); p2 += 4; /* if (cert) { UInt32 numRecipients = reserved; if (numRecipients == 0) return E_NOTIMPL; { UInt32 hashAlg = GetUi16(p2); hashAlg = hashAlg; UInt32 hashSize = GetUi16(p2 + 2); hashSize = hashSize; p2 += 4; reserved = reserved; // return E_NOTIMPL; for (unsigned r = 0; r < numRecipients; r++) { UInt32 specSize = GetUi16(p2); p2 += 2; p2 += specSize; } } } else */ { if (reserved != 0) return E_NOTIMPL; } UInt32 validSize = GetUi16(p2); p2 += 2; const size_t validOffset = p2 - p; if ((validSize & 0xF) != 0 || validOffset + validSize != _remSize) return E_NOTIMPL; { RINOK(SetKey(_key.MasterKey, _key.KeySize)); RINOK(SetInitVector(_iv, 16)); RINOK(Init()); Filter(p, rdSize); rdSize -= kPadSize; for (unsigned i = 0; i < kPadSize; i++) if (p[(size_t)rdSize + i] != kPadSize) return S_OK; // passwOK = false; } Byte fileKey[32]; NSha1::CContext sha; sha.Init(); sha.Update(_iv, _ivSize); sha.Update(p, rdSize); DeriveKey(sha, fileKey); RINOK(SetKey(fileKey, _key.KeySize)); RINOK(SetInitVector(_iv, 16)); Init(); memmove(p, p + validOffset, validSize); Filter(p, validSize); if (validSize < 4) return E_NOTIMPL; validSize -= 4; if (GetUi32(p + validSize) != CrcCalc(p, validSize)) return S_OK; passwOK = true; return S_OK; }
// Changes the encryption key for an existing database. int sqlite3_rekey(sqlite3 *db, const unsigned char *pKey, int nKeySize) { Btree *pbt = db->aDb[0].pBt; Pager *p = sqlite3BtreePager(pbt); LPCRYPTBLOCK pBlock = (LPCRYPTBLOCK)sqlite3pager_get_codecarg(p); HCRYPTKEY hKey = DeriveKey(pKey, nKeySize); int rc = SQLITE_ERROR; if (hKey == MAXDWORD) { sqlite3Error(db, rc, SQLITECRYPTERROR_PROVIDER); return rc; } if (!pBlock && !hKey) return SQLITE_OK; // Wasn't encrypted to begin with // To rekey a database, we change the writekey for the pager. The readkey remains // the same if (!pBlock) // Encrypt an unencrypted database { pBlock = CreateCryptBlock(hKey, p, -1, NULL); if (!pBlock) return SQLITE_NOMEM; pBlock->hReadKey = 0; // Original database is not encrypted sqlite3PagerSetCodec(sqlite3BtreePager(pbt), sqlite3Codec, sqlite3CodecSizeChange, sqlite3CodecFree, pBlock); //db->aDb[0].pAux = pBlock; //db->aDb[0].xFreeAux = DestroyCryptBlock; } else // Change the writekey for an already-encrypted database { pBlock->hWriteKey = hKey; } // Start a transaction rc = sqlite3BtreeBeginTrans(pbt, 1); if (!rc) { // Rewrite all the pages in the database using the new encryption key Pgno nPage; Pgno nSkip = PAGER_MJ_PGNO(p); DbPage *pPage; Pgno n; rc = sqlite3PagerPagecount(p, &nPage); for(n = 1; rc == SQLITE_OK && n <= nPage; n ++) { if (n == nSkip) continue; rc = sqlite3PagerGet(p, n, &pPage); if(!rc) { rc = sqlite3PagerWrite(pPage); sqlite3PagerUnref(pPage); } } } // If we succeeded, try and commit the transaction if (!rc) { rc = sqlite3BtreeCommit(pbt); } // If we failed, rollback if (rc) { sqlite3BtreeRollback(pbt); } // If we succeeded, destroy any previous read key this database used // and make the readkey equal to the writekey if (!rc) { if (pBlock->hReadKey) { CryptDestroyKey(pBlock->hReadKey); } pBlock->hReadKey = pBlock->hWriteKey; } // We failed. Destroy the new writekey (if there was one) and revert it back to // the original readkey else { if (pBlock->hWriteKey) { CryptDestroyKey(pBlock->hWriteKey); } pBlock->hWriteKey = pBlock->hReadKey; } // If the readkey and writekey are both empty, there's no need for a codec on this // pager anymore. Destroy the crypt block and remove the codec from the pager. if (!pBlock->hReadKey && !pBlock->hWriteKey) { sqlite3PagerSetCodec(p, NULL, NULL, NULL, NULL); } return rc; }
status_t SSO::MBIKeyOld(BString key, BString nonce, BString &response) { const char *kSessionHash = "WS-SecureConversationSESSION KEY HASH"; const char *kSessionEnc = "WS-SecureConversationSESSION KEY ENCRYPTION"; const uint32 kSessionHashLen = strlen(kSessionHash); const uint32 kSessionEncLen = strlen(kSessionEnc); const uint8 kNoncePadding = 8; uchar *key1 = NULL; uchar *key2 = NULL; uchar *key3 = NULL; // Obtain the three keys for the 3DES encryption int32 key1Len = (int32)Base64Decode(key.String(), key.Length(), &key1); int32 key2Len = DeriveKey(key1, key1Len, (uchar *)kSessionHash, kSessionHashLen, &key2); DeriveKey(key1, key1Len, (uchar *)kSessionEnc, kSessionEncLen, &key3); uchar hash[EVP_MAX_MD_SIZE]; unsigned int hashLen = 0; // Key 2 is used as the key to the HMAC-SHA() of the Nonce HMAC(EVP_sha1(), key2, key2Len, (uchar *)nonce.String(), nonce.Length(), hash, &hashLen); // The nonce is padded out by 8 bytes of 0x08 int32 padNonceLen = nonce.Length() + kNoncePadding; uchar *padNonce = (uchar *)calloc(padNonceLen, sizeof(uchar)); memset(padNonce, 0x08, padNonceLen); memcpy(padNonce, nonce.String(), nonce.Length()); const uint32 kKeyLen = 8; uchar cbc_key1[kKeyLen]; uchar cbc_key2[kKeyLen]; uchar cbc_key3[kKeyLen]; // The 3DES CBC key is Key3 memcpy(cbc_key1, key3 + (kKeyLen * 0), sizeof(cbc_key1)); memcpy(cbc_key2, key3 + (kKeyLen * 1), sizeof(cbc_key2)); memcpy(cbc_key3, key3 + (kKeyLen * 2), sizeof(cbc_key3)); des_key_schedule ks1; des_key_schedule ks2; des_key_schedule ks3; // Create 3DES CBC keys DES_set_key(&cbc_key1, &ks1); DES_set_key(&cbc_key2, &ks2); DES_set_key(&cbc_key3, &ks3); // Setup the IV uchar iv[8]; for (int8 i = 0; i < 8; i++) iv[i] = rand() * 255; des_cblock iv3; memcpy(iv3, iv, sizeof(iv)); // Create a buffer used by the 3DES process uchar *buffer = (uchar *)calloc(1024, sizeof(uchar)); // 3DES the nonce DES_ede3_cbc_encrypt(padNonce, buffer, padNonceLen, &ks1, &ks2, &ks3, &iv3, DES_ENCRYPT); // Output the results BufferWriter *result = new BufferWriter(B_SWAP_HOST_TO_LENDIAN); result->WriteInt32(0x0000001C); // Size of header (28) result->WriteInt32(0x00000001); // CBC crypt result->WriteInt32(0x00006603); // Triple DES result->WriteInt32(0x00008004); // SHA1 result->WriteInt32(sizeof(iv)); // Length of IV result->WriteInt32(hashLen); // Length of hash result->WriteInt32(72); // Length of cipher result->WriteData(iv, sizeof(iv)); // IV result->WriteData(hash, hashLen); // Hash result->WriteData(buffer, 72); // Enc char *base64Result = Base64Encode((const char *)result->Buffer(), (int32)result->Offset()); response = base64Result; free(key1); free(key2); free(key3); free(padNonce); free(buffer); free(base64Result); return B_OK; };