blob: 79a680af284a5600b64a1d143770d7c17acbbce2 [file] [log] [blame]
// Copyright 2022 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/os_crypt/app_bound_encryption_win.h"
#include <objbase.h>
#include <string.h>
#include <windows.h>
#include <wrl/client.h>
#include "base/logging.h"
#include "base/win/com_init_util.h"
#include "base/win/scoped_bstr.h"
#include "chrome/elevation_service/elevation_service_idl.h"
#include "chrome/install_static/install_util.h"
namespace os_crypt {
HRESULT EncryptAppBoundString(ProtectionLevel protection_level,
const std::string& plaintext,
std::string& ciphertext,
DWORD& last_error) {
base::win::AssertComInitialized();
Microsoft::WRL::ComPtr<IElevator> elevator;
last_error = ERROR_GEN_FAILURE;
HRESULT hr = ::CoCreateInstance(
install_static::GetElevatorClsid(), nullptr, CLSCTX_LOCAL_SERVER,
install_static::GetElevatorIid(), IID_PPV_ARGS_Helper(&elevator));
if (FAILED(hr))
return hr;
hr = ::CoSetProxyBlanket(
elevator.Get(), RPC_C_AUTHN_DEFAULT, RPC_C_AUTHZ_DEFAULT,
COLE_DEFAULT_PRINCIPAL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_DYNAMIC_CLOAKING);
if (FAILED(hr))
return hr;
base::win::ScopedBstr plaintext_data;
::memcpy(plaintext_data.AllocateBytes(plaintext.length()), plaintext.data(),
plaintext.length());
base::win::ScopedBstr encrypted_data;
hr = elevator->EncryptData(protection_level, plaintext_data.Get(),
encrypted_data.Receive(), &last_error);
if (FAILED(hr))
return hr;
ciphertext.assign(
reinterpret_cast<std::string::value_type*>(encrypted_data.Get()),
encrypted_data.ByteLength());
last_error = ERROR_SUCCESS;
return S_OK;
}
HRESULT DecryptAppBoundString(const std::string& ciphertext,
std::string& plaintext,
DWORD& last_error) {
DCHECK(!ciphertext.empty());
base::win::AssertComInitialized();
Microsoft::WRL::ComPtr<IElevator> elevator;
last_error = ERROR_GEN_FAILURE;
HRESULT hr = ::CoCreateInstance(
install_static::GetElevatorClsid(), nullptr, CLSCTX_LOCAL_SERVER,
install_static::GetElevatorIid(), IID_PPV_ARGS_Helper(&elevator));
if (FAILED(hr))
return hr;
hr = ::CoSetProxyBlanket(
elevator.Get(), RPC_C_AUTHN_DEFAULT, RPC_C_AUTHZ_DEFAULT,
COLE_DEFAULT_PRINCIPAL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_DYNAMIC_CLOAKING);
if (FAILED(hr))
return hr;
base::win::ScopedBstr ciphertext_data;
::memcpy(ciphertext_data.AllocateBytes(ciphertext.length()),
ciphertext.data(), ciphertext.length());
base::win::ScopedBstr plaintext_data;
hr = elevator->DecryptData(ciphertext_data.Get(), plaintext_data.Receive(),
&last_error);
if (FAILED(hr))
return hr;
plaintext.assign(
reinterpret_cast<std::string::value_type*>(plaintext_data.Get()),
plaintext_data.ByteLength());
last_error = ERROR_SUCCESS;
return S_OK;
}
} // namespace os_crypt