| 67 | } |
| 68 | |
| 69 | bool KeybufManager::Finalize(bool use_key_cache) |
| 70 | { |
| 71 | if (!m_bActive) |
| 72 | return true; |
| 73 | |
| 74 | if (m_bFinalized) |
| 75 | throw std::exception("KeybufManger::Finalize called when already finalized"); |
| 76 | |
| 77 | if (!m_total_len || m_bufs.size() < 1) |
| 78 | throw std::exception("KeybufManger::Finalize called with no buffers"); |
| 79 | |
| 80 | LockZeroBuffer<BYTE> DecryptBuf(static_cast<DWORD>(m_total_len), true); |
| 81 | |
| 82 | size_t offset = 0; |
| 83 | for (size_t i = 0; i < m_bufs.size(); i++) { |
| 84 | memcpy(DecryptBuf.m_buf + offset, m_bufs[i].ptr, m_bufs[i].len); |
| 85 | SecureZeroMemory(m_bufs[i].ptr, m_bufs[i].len); |
| 86 | offset += m_bufs[i].len; |
| 87 | } |
| 88 | |
| 89 | get_sys_random_bytes(m_optional_entropy, sizeof(m_optional_entropy)); |
| 90 | |
| 91 | DATA_BLOB key_blob; |
| 92 | DATA_BLOB enc_key_blob; |
| 93 | DATA_BLOB optional_entropy; |
| 94 | |
| 95 | optional_entropy.cbData = static_cast<DWORD>(sizeof(m_optional_entropy)); |
| 96 | optional_entropy.pbData = m_optional_entropy; |
| 97 | |
| 98 | key_blob.cbData = static_cast<DWORD>(DecryptBuf.m_len); |
| 99 | key_blob.pbData = DecryptBuf.m_buf; |
| 100 | |
| 101 | bool bResult = CryptProtectData(&key_blob, NULL, &optional_entropy, NULL, NULL, 0, &enc_key_blob); |
| 102 | |
| 103 | if (!bResult) { |
| 104 | return false; |
| 105 | } |
| 106 | |
| 107 | m_encryptedBuf.resize(enc_key_blob.cbData); |
| 108 | memcpy(&m_encryptedBuf[0], enc_key_blob.pbData, enc_key_blob.cbData); |
| 109 | |
| 110 | LocalFree(enc_key_blob.pbData); |
| 111 | |
| 112 | if (use_key_cache) { |
| 113 | m_key_cache_id = KeyCache::GetInstance()->Register(m_total_len); |
| 114 | if (!m_key_cache_id) |
| 115 | bResult = false; |
| 116 | } |
| 117 | |
| 118 | return bResult; |
| 119 | } |
| 120 | |
| 121 | |
| 122 | bool KeybufManager::EnterInternal() |
no test coverage detected