summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarren Krahn <dkrahn@google.com>2016-01-12 08:01:04 -0800
committerDarren Krahn <dkrahn@google.com>2016-02-01 18:07:11 -0800
commit9caf492818a4cc51ba471534d3fcaa84c9ce0278 (patch)
tree76215be9020d1975bd13687b21f0b46e73e94482
parent0e860e79fefad0327d7256ebf6ea273eeacc8e6f (diff)
downloadtpm-9caf492818a4cc51ba471534d3fcaa84c9ce0278.tar.gz
trunks: Create an Android.mk file for trunks and enable binder.
This includes a trunksd.rc file which starts the service as root, seccomp policies, and a few other changes to get trunks working on brillo. BUG=25360556 TEST=unit tests on target TEST=manual test on all brilloemulator*-eng boards Change-Id: I9bca71480b7b2c79e0c24c9dc346f225d1d69ef9
-rw-r--r--trunks/Android.mk206
-rw-r--r--trunks/aidl/android/trunks/ITrunks.aidl24
-rw-r--r--trunks/aidl/android/trunks/ITrunksClient.aidl21
-rw-r--r--trunks/background_command_transceiver.cc1
-rw-r--r--trunks/binder_interface.h26
-rw-r--r--trunks/dbus_interface.h2
-rw-r--r--trunks/ftdi/mpsse.c28
-rw-r--r--trunks/ftdi/mpsse.h28
-rw-r--r--trunks/hmac_authorization_delegate_test.cc4
-rw-r--r--trunks/interface.proto (renamed from trunks/dbus_interface.proto)2
-rw-r--r--trunks/policy_session_test.cc4
-rw-r--r--trunks/resource_manager.cc12
-rw-r--r--trunks/resource_manager_test.cc6
-rw-r--r--trunks/scoped_key_handle_test.cc4
-rw-r--r--trunks/session_manager_impl.cc3
-rw-r--r--trunks/session_manager_test.cc10
-rw-r--r--trunks/tpm_generated_test.cc8
-rw-r--r--trunks/tpm_simulator_handle.cc6
-rw-r--r--trunks/tpm_state_test.cc8
-rw-r--r--trunks/tpm_utility_impl.cc1
-rw-r--r--trunks/tpm_utility_test.cc182
-rw-r--r--trunks/trunks_binder_proxy.cc121
-rw-r--r--trunks/trunks_binder_proxy.h53
-rw-r--r--trunks/trunks_binder_service.cc120
-rw-r--r--trunks/trunks_binder_service.h90
-rw-r--r--trunks/trunks_client.cc9
-rw-r--r--trunks/trunks_client_test.cc5
-rw-r--r--trunks/trunks_dbus_proxy.cc (renamed from trunks/trunks_proxy.cc)18
-rw-r--r--trunks/trunks_dbus_proxy.h (renamed from trunks/trunks_proxy.h)29
-rw-r--r--trunks/trunks_dbus_service.cc (renamed from trunks/trunks_service.cc)39
-rw-r--r--trunks/trunks_dbus_service.h79
-rw-r--r--trunks/trunks_factory.h1
-rw-r--r--trunks/trunks_factory_impl.cc22
-rw-r--r--trunks/trunks_factory_impl.h6
-rw-r--r--trunks/trunks_service.h69
-rw-r--r--trunks/trunksd-seccomp-arm.policy45
-rw-r--r--trunks/trunksd-seccomp-arm64.policy (renamed from trunks/trunksd-seccomp-amd64.policy)37
-rw-r--r--trunks/trunksd-seccomp-x86.policy50
-rw-r--r--trunks/trunksd-seccomp-x86_64.policy83
-rw-r--r--trunks/trunksd-simulator.rc8
-rw-r--r--trunks/trunksd.cc113
-rw-r--r--trunks/trunksd.rc8
42 files changed, 1229 insertions, 362 deletions
diff --git a/trunks/Android.mk b/trunks/Android.mk
new file mode 100644
index 0000000..521293d
--- /dev/null
+++ b/trunks/Android.mk
@@ -0,0 +1,206 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+# Common variables
+# ========================================================
+trunksCppExtension := .cc
+trunksCFlags := -Wall -Werror -Wno-unused-parameter -DUSE_BINDER_IPC
+trunksIncludes := $(LOCAL_PATH)/.. external/gtest/include
+trunksSharedLibraries := \
+ libbinder \
+ libbinderwrapper \
+ libbrillo \
+ libbrillo-binder \
+ libchrome \
+ libchrome-crypto \
+ libcrypto \
+ libprotobuf-cpp-lite \
+ libutils \
+
+# libtrunks_generated
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := libtrunks_generated
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_CPP_EXTENSION := $(trunksCppExtension)
+LOCAL_CFLAGS := $(trunksCFlags)
+LOCAL_CLANG := true
+proto_include := $(call local-generated-sources-dir)/proto/$(LOCAL_PATH)/..
+aidl_include := $(call local-generated-sources-dir)/aidl-generated/include
+LOCAL_C_INCLUDES := $(proto_include) $(aidl_include) $(trunksIncludes)
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(proto_include) $(aidl_include)
+LOCAL_SHARED_LIBRARIES := $(trunksSharedLibraries)
+LOCAL_SRC_FILES := \
+ interface.proto \
+ aidl/android/trunks/ITrunks.aidl \
+ aidl/android/trunks/ITrunksClient.aidl \
+
+LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/aidl
+include $(BUILD_STATIC_LIBRARY)
+
+# libtrunks_common
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := libtrunks_common
+LOCAL_CPP_EXTENSION := $(trunksCppExtension)
+LOCAL_CFLAGS := $(trunksCFlags)
+LOCAL_CLANG := true
+LOCAL_C_INCLUDES := $(trunksIncludes)
+LOCAL_SHARED_LIBRARIES := $(trunksSharedLibraries)
+LOCAL_STATIC_LIBRARIES := libtrunks_generated
+LOCAL_SRC_FILES := \
+ background_command_transceiver.cc \
+ blob_parser.cc \
+ error_codes.cc \
+ hmac_authorization_delegate.cc \
+ hmac_session_impl.cc \
+ password_authorization_delegate.cc \
+ policy_session_impl.cc \
+ scoped_key_handle.cc \
+ session_manager_impl.cc \
+ tpm_generated.cc \
+ tpm_state_impl.cc \
+ tpm_utility_impl.cc \
+ trunks_factory_impl.cc \
+
+include $(BUILD_STATIC_LIBRARY)
+
+# trunksd
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := trunksd
+LOCAL_CPP_EXTENSION := $(trunksCppExtension)
+LOCAL_CFLAGS := $(trunksCFlags)
+ifeq ($(BRILLOEMULATOR),true)
+LOCAL_CFLAGS += -DUSE_SIMULATOR
+endif
+LOCAL_CLANG := true
+ifeq ($(BRILLOEMULATOR),true)
+LOCAL_INIT_RC := trunksd-simulator.rc
+else
+LOCAL_INIT_RC := trunksd.rc
+endif
+LOCAL_C_INCLUDES := $(trunksIncludes)
+LOCAL_SHARED_LIBRARIES := \
+ $(trunksSharedLibraries) \
+ libbrillo-minijail \
+ libminijail \
+
+ifeq ($(BRILLOEMULATOR),true)
+LOCAL_SHARED_LIBRARIES += libtpm2
+endif
+LOCAL_STATIC_LIBRARIES := \
+ libtrunks_generated \
+ libtrunks_common \
+
+LOCAL_REQUIRED_MODULES := \
+ com.android.Trunks.conf \
+ trunksd-seccomp.policy \
+
+LOCAL_SRC_FILES := \
+ resource_manager.cc \
+ tpm_handle.cc \
+ tpm_simulator_handle.cc \
+ trunks_binder_service.cc \
+ trunksd.cc \
+
+include $(BUILD_EXECUTABLE)
+
+# trunksd-seccomp.policy
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := trunksd-seccomp.policy
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT)/usr/share/policy/
+LOCAL_SRC_FILES := trunksd-seccomp-$(TARGET_ARCH).policy
+include $(BUILD_PREBUILT)
+
+# libtrunks
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := libtrunks
+LOCAL_CPP_EXTENSION := $(trunksCppExtension)
+LOCAL_CFLAGS := $(trunksCFlags)
+LOCAL_CLANG := true
+LOCAL_C_INCLUDES := $(trunksIncludes)
+LOCAL_SHARED_LIBRARIES := $(trunksSharedLibraries)
+LOCAL_STATIC_LIBRARIES := \
+ libtrunks_common \
+ libtrunks_generated \
+
+LOCAL_SRC_FILES := \
+ trunks_binder_proxy.cc \
+
+include $(BUILD_SHARED_LIBRARY)
+
+# trunks_client
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := trunks_client
+LOCAL_CPP_EXTENSION := $(trunksCppExtension)
+LOCAL_CFLAGS := $(trunksCFlags)
+LOCAL_CLANG := true
+LOCAL_C_INCLUDES := $(trunksIncludes)
+LOCAL_SHARED_LIBRARIES := $(trunksSharedLibraries) libtrunks
+LOCAL_STATIC_LIBRARIES := libtrunks_common
+LOCAL_SRC_FILES := \
+ trunks_client.cc \
+ trunks_client_test.cc \
+
+include $(BUILD_EXECUTABLE)
+
+# Target unit tests
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := trunks_test
+LOCAL_MODULE_TAGS := debug
+LOCAL_CPP_EXTENSION := $(trunksCppExtension)
+LOCAL_CFLAGS := $(trunksCFlags)
+LOCAL_CLANG := true
+LOCAL_C_INCLUDES := $(trunksIncludes)
+LOCAL_SHARED_LIBRARIES := $(trunksSharedLibraries)
+LOCAL_SRC_FILES := \
+ background_command_transceiver_test.cc \
+ hmac_authorization_delegate_test.cc \
+ hmac_session_test.cc \
+ mock_authorization_delegate.cc \
+ mock_blob_parser.cc \
+ mock_command_transceiver.cc \
+ mock_hmac_session.cc \
+ mock_policy_session.cc \
+ mock_session_manager.cc \
+ mock_tpm.cc \
+ mock_tpm_state.cc \
+ mock_tpm_utility.cc \
+ password_authorization_delegate_test.cc \
+ policy_session_test.cc \
+ resource_manager.cc \
+ resource_manager_test.cc \
+ scoped_key_handle_test.cc \
+ session_manager_test.cc \
+ tpm_generated_test.cc \
+ tpm_state_test.cc \
+ tpm_utility_test.cc \
+ trunks_factory_for_test.cc \
+
+LOCAL_STATIC_LIBRARIES := \
+ libgmock \
+ libgtest \
+ libBionicGtestMain \
+ libtrunks_common \
+ libtrunks_generated \
+
+include $(BUILD_NATIVE_TEST)
diff --git a/trunks/aidl/android/trunks/ITrunks.aidl b/trunks/aidl/android/trunks/ITrunks.aidl
new file mode 100644
index 0000000..6d075fe
--- /dev/null
+++ b/trunks/aidl/android/trunks/ITrunks.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.trunks;
+
+import android.trunks.ITrunksClient;
+
+interface ITrunks {
+ oneway void SendCommand(in byte[] command, in ITrunksClient client);
+ byte[] SendCommandAndWait(in byte[] command);
+}
diff --git a/trunks/aidl/android/trunks/ITrunksClient.aidl b/trunks/aidl/android/trunks/ITrunksClient.aidl
new file mode 100644
index 0000000..31a0d0b
--- /dev/null
+++ b/trunks/aidl/android/trunks/ITrunksClient.aidl
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.trunks;
+
+interface ITrunksClient {
+ oneway void OnCommandResponse(in byte[] response);
+}
diff --git a/trunks/background_command_transceiver.cc b/trunks/background_command_transceiver.cc
index cc96e69..aa18000 100644
--- a/trunks/background_command_transceiver.cc
+++ b/trunks/background_command_transceiver.cc
@@ -22,6 +22,7 @@
#include <base/logging.h>
#include <base/single_thread_task_runner.h>
#include <base/synchronization/waitable_event.h>
+#include <base/thread_task_runner_handle.h>
namespace {
diff --git a/trunks/binder_interface.h b/trunks/binder_interface.h
new file mode 100644
index 0000000..a9e0fba
--- /dev/null
+++ b/trunks/binder_interface.h
@@ -0,0 +1,26 @@
+//
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef TRUNKS_BINDER_INTERFACE_H_
+#define TRUNKS_BINDER_INTERFACE_H_
+
+namespace trunks {
+
+constexpr char kTrunksServiceName[] = "trunks_service";
+
+}; // namespace trunks
+
+#endif // TRUNKS_BINDER_INTERFACE_H_
diff --git a/trunks/dbus_interface.h b/trunks/dbus_interface.h
index e438683..aad78fc 100644
--- a/trunks/dbus_interface.h
+++ b/trunks/dbus_interface.h
@@ -19,7 +19,7 @@
namespace trunks {
-#ifdef __ANDROID__
+#if defined(__ANDROID__)
constexpr char kTrunksInterface[] = "com.android.Trunks";
constexpr char kTrunksServicePath[] = "/com/android/Trunks";
constexpr char kTrunksServiceName[] = "com.android.Trunks";
diff --git a/trunks/ftdi/mpsse.c b/trunks/ftdi/mpsse.c
index 5171324..b109bb0 100644
--- a/trunks/ftdi/mpsse.c
+++ b/trunks/ftdi/mpsse.c
@@ -1,19 +1,17 @@
/*
-/*
-/*Copyright (C) 2015 The Android Open Source Project
-/*
-/*Licensed under the Apache License, Version 2.0 (the "License");
-/*you may not use this file except in compliance with the License.
-/*You may obtain a copy of the License at
-/*
-/* http://www.apache.org/licenses/LICENSE-2.0
-/*
-/*Unless required by applicable law or agreed to in writing, software
-/*distributed under the License is distributed on an "AS IS" BASIS,
-/*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-/*See the License for the specific language governing permissions and
-/*limitations under the License.
- */
+ *Copyright (C) 2015 The Android Open Source Project
+ *
+ *Licensed under the Apache License, Version 2.0 (the "License");
+ *you may not use this file except in compliance with the License.
+ *You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing, software
+ *distributed under the License is distributed on an "AS IS" BASIS,
+ *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *See the License for the specific language governing permissions and
+ *limitations under the License.
*
* This file was copied from https://github.com/devttys0/libmpsse.git (sha1
* f1a6744b), and modified to suite the Chromium OS project.
diff --git a/trunks/ftdi/mpsse.h b/trunks/ftdi/mpsse.h
index c0c3c9d..f73eede 100644
--- a/trunks/ftdi/mpsse.h
+++ b/trunks/ftdi/mpsse.h
@@ -1,19 +1,17 @@
/*
-/*
-/*Copyright (C) 2015 The Android Open Source Project
-/*
-/*Licensed under the Apache License, Version 2.0 (the "License");
-/*you may not use this file except in compliance with the License.
-/*You may obtain a copy of the License at
-/*
-/* http://www.apache.org/licenses/LICENSE-2.0
-/*
-/*Unless required by applicable law or agreed to in writing, software
-/*distributed under the License is distributed on an "AS IS" BASIS,
-/*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-/*See the License for the specific language governing permissions and
-/*limitations under the License.
- */
+ *Copyright (C) 2015 The Android Open Source Project
+ *
+ *Licensed under the Apache License, Version 2.0 (the "License");
+ *you may not use this file except in compliance with the License.
+ *You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing, software
+ *distributed under the License is distributed on an "AS IS" BASIS,
+ *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *See the License for the specific language governing permissions and
+ *limitations under the License.
*
* This file was copied from https://github.com/devttys0/libmpsse.git (sha1
* f1a6744b), and modified to suite the Chromium OS project.
diff --git a/trunks/hmac_authorization_delegate_test.cc b/trunks/hmac_authorization_delegate_test.cc
index 025c80a..6a4e2e3 100644
--- a/trunks/hmac_authorization_delegate_test.cc
+++ b/trunks/hmac_authorization_delegate_test.cc
@@ -27,7 +27,7 @@ TEST(HmacAuthorizationDelegateTest, UninitializedSessionTest) {
std::string dummy;
std::string p_hash("test");
EXPECT_FALSE(delegate.GetCommandAuthorization(p_hash, false, false, &dummy));
- EXPECT_EQ(0, dummy.size());
+ EXPECT_EQ(0u, dummy.size());
EXPECT_FALSE(delegate.CheckResponseAuthorization(p_hash, dummy));
EXPECT_FALSE(delegate.EncryptCommandParameter(&dummy));
EXPECT_FALSE(delegate.DecryptResponseParameter(&dummy));
@@ -41,7 +41,7 @@ TEST(HmacAuthorizationDelegateTest, SessionKeyTest) {
TPM_HANDLE dummy_handle = HMAC_SESSION_FIRST;
EXPECT_TRUE(delegate.InitSession(dummy_handle, nonce, nonce, std::string(),
std::string(), false));
- EXPECT_EQ(0, delegate.session_key_.size());
+ EXPECT_EQ(0u, delegate.session_key_.size());
std::string dummy_auth = std::string("authorization");
std::string dummy_salt = std::string("salt");
diff --git a/trunks/dbus_interface.proto b/trunks/interface.proto
index c38b57a..03797eb 100644
--- a/trunks/dbus_interface.proto
+++ b/trunks/interface.proto
@@ -1,7 +1,7 @@
option optimize_for = LITE_RUNTIME;
package trunks;
-// The messages in this file correspond to the trunksd D-Bus interface. Each
+// The messages in this file correspond to the trunksd IPC interface. Each
// exported method is represented here by a request and response protobuf.
// Inputs for the SendCommand method.
diff --git a/trunks/policy_session_test.cc b/trunks/policy_session_test.cc
index c2d93e8..5d9e8c5 100644
--- a/trunks/policy_session_test.cc
+++ b/trunks/policy_session_test.cc
@@ -109,7 +109,7 @@ TEST_F(PolicySessionTest, GetDigestSuccess) {
.WillOnce(DoAll(SetArgPointee<2>(policy_digest),
Return(TPM_RC_SUCCESS)));
EXPECT_EQ(TPM_RC_SUCCESS, session.GetDigest(&digest));
- EXPECT_EQ(SHA256_DIGEST_SIZE, digest.size());
+ EXPECT_EQ(static_cast<size_t>(SHA256_DIGEST_SIZE), digest.size());
}
TEST_F(PolicySessionTest, GetDigestFailure) {
@@ -167,7 +167,7 @@ TEST_F(PolicySessionTest, PolicyPCRSuccess) {
EXPECT_EQ(TPM_RC_SUCCESS, session.PolicyPCR(pcr_index, pcr_digest));
uint8_t pcr_select_index = pcr_index / 8;
uint8_t pcr_select_byte = 1 << (pcr_index % 8);
- EXPECT_EQ(pcr_select.count, 1);
+ EXPECT_EQ(pcr_select.count, 1u);
EXPECT_EQ(pcr_select.pcr_selections[0].hash, TPM_ALG_SHA256);
EXPECT_EQ(pcr_select.pcr_selections[0].sizeof_select, PCR_SELECT_MIN);
EXPECT_EQ(pcr_select.pcr_selections[0].pcr_select[pcr_select_index],
diff --git a/trunks/resource_manager.cc b/trunks/resource_manager.cc
index 5955d97..82dd18d 100644
--- a/trunks/resource_manager.cc
+++ b/trunks/resource_manager.cc
@@ -64,15 +64,11 @@ ResourceManager::~ResourceManager() {}
void ResourceManager::Initialize() {
TPM_RC result = factory_.GetTpm()->StartupSync(TPM_SU_CLEAR, nullptr);
// Ignore TPM_RC_INITIALIZE, that means it was already started.
- if (result != TPM_RC_SUCCESS && result != TPM_RC_INITIALIZE) {
- LOG(ERROR) << "TPM startup failure: " << GetErrorString(result);
- exit(-1);
- }
+ CHECK(result == TPM_RC_SUCCESS || result == TPM_RC_INITIALIZE)
+ << "TPM startup failure: " << GetErrorString(result);
result = factory_.GetTpm()->SelfTestSync(YES /* Full test. */, nullptr);
- if (result != TPM_RC_SUCCESS) {
- LOG(ERROR) << "TPM self-test failure: " << GetErrorString(result);
- exit(-1);
- }
+ CHECK_EQ(result, TPM_RC_SUCCESS) << "TPM self-test failure: "
+ << GetErrorString(result);
// Full control of the TPM is assumed and required. Existing transient object
// and session handles are mercilessly flushed.
for (UINT32 handle_type : {HR_TRANSIENT,
diff --git a/trunks/resource_manager_test.cc b/trunks/resource_manager_test.cc
index 5d2f43e..4aafbaf 100644
--- a/trunks/resource_manager_test.cc
+++ b/trunks/resource_manager_test.cc
@@ -230,7 +230,9 @@ class ResourceManagerTest : public testing::Test {
// Creates a TPMS_CONTEXT with the given sequence field.
TPMS_CONTEXT CreateContext(UINT64 sequence) {
- TPMS_CONTEXT context = {sequence};
+ TPMS_CONTEXT context;
+ memset(&context, 0, sizeof(context));
+ context.sequence = sequence;
return context;
}
@@ -756,7 +758,7 @@ TEST_F(ResourceManagerTest, ExternalContext) {
EXPECT_EQ(context_save_response1, actual_response);
// Invoke a context gap (which will cause context1 to be mapped to context2).
- EXPECT_CALL(tpm_, ContextLoadSync(Field(&TPMS_CONTEXT::sequence, Eq(1)),
+ EXPECT_CALL(tpm_, ContextLoadSync(Field(&TPMS_CONTEXT::sequence, Eq(1u)),
_, _))
.WillOnce(Return(TPM_RC_SUCCESS));
EXPECT_CALL(tpm_, ContextSaveSync(kArbitrarySessionHandle, _, _, _))
diff --git a/trunks/scoped_key_handle_test.cc b/trunks/scoped_key_handle_test.cc
index 2d91917..3f40be6 100644
--- a/trunks/scoped_key_handle_test.cc
+++ b/trunks/scoped_key_handle_test.cc
@@ -65,7 +65,7 @@ TEST_F(ScopedKeyHandleTest, ReleaseTest) {
TPM_HANDLE handle = TPM_RH_FIRST;
ScopedKeyHandle scoped_handle(factory_, handle);
EXPECT_EQ(handle, scoped_handle.release());
- EXPECT_EQ(0, scoped_handle.get());
+ EXPECT_EQ(0u, scoped_handle.get());
}
TEST_F(ScopedKeyHandleTest, ResetAndFlush) {
@@ -88,7 +88,7 @@ TEST_F(ScopedKeyHandleTest, NullReset) {
EXPECT_CALL(mock_tpm_, FlushContextSync(handle, _))
.WillOnce(Return(TPM_RC_SUCCESS));
scoped_handle.reset();
- EXPECT_EQ(0, scoped_handle.get());
+ EXPECT_EQ(0u, scoped_handle.get());
}
} // namespace trunks
diff --git a/trunks/session_manager_impl.cc b/trunks/session_manager_impl.cc
index f1a648f..9370ec9 100644
--- a/trunks/session_manager_impl.cc
+++ b/trunks/session_manager_impl.cc
@@ -24,6 +24,7 @@
#include <crypto/scoped_openssl_types.h>
#include <openssl/err.h>
#include <openssl/evp.h>
+#include <openssl/mem.h>
#include <openssl/rand.h>
#include <openssl/rsa.h>
@@ -83,7 +84,7 @@ TPM_RC SessionManagerImpl::StartSession(
reinterpret_cast<unsigned char*>(string_as_array(&salt));
CHECK_EQ(RAND_bytes(salt_buffer, salt.size()), 1)
<< "Error generating a cryptographically random salt.";
- // First we enccrypt the cryptographically secure salt using PKCS1_OAEP
+ // First we encrypt the cryptographically secure salt using PKCS1_OAEP
// padded RSA public key encryption. This is specified in TPM2.0
// Part1 Architecture, Appendix B.10.2.
std::string encrypted_salt;
diff --git a/trunks/session_manager_test.cc b/trunks/session_manager_test.cc
index 4b38835..eb99331 100644
--- a/trunks/session_manager_test.cc
+++ b/trunks/session_manager_test.cc
@@ -18,10 +18,12 @@
#include <vector>
+#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
+#include "trunks/error_codes.h"
#include "trunks/mock_tpm.h"
#include "trunks/tpm_generated.h"
#include "trunks/tpm_utility.h"
@@ -60,7 +62,7 @@ class SessionManagerTest : public testing::Test {
"D3C74E721ACA97F7ADBE2CCF7B4BCC165F7380F48065F2C8370F25F066091259"
"D14EA362BAF236E3CD8771A94BDEDA3900577143A238AB92B6C55F11DEFAFB31"
"7D1DC5B6AE210C52B008D87F2A7BFF6EB5C4FB32D6ECEC6505796173951A3167";
- std::vector<uint8> bytes;
+ std::vector<uint8_t> bytes;
CHECK(base::HexStringToBytes(kValidModulus, &bytes));
CHECK_EQ(bytes.size(), 256u);
TPM2B_PUBLIC_KEY_RSA rsa;
@@ -126,9 +128,9 @@ TEST_F(SessionManagerTest, StartSessionBadSaltingKey) {
EXPECT_CALL(mock_tpm_, ReadPublicSync(kSaltingKey, _, _, _, _, nullptr))
.WillOnce(DoAll(SetArgPointee<2>(public_data),
Return(TPM_RC_SUCCESS)));
- EXPECT_EQ(TPM_RC_FAILURE, session_manager_.StartSession(TPM_SE_TRIAL,
- TPM_RH_NULL, "",
- false, delegate_));
+ EXPECT_EQ(TRUNKS_RC_SESSION_SETUP_ERROR,
+ session_manager_.StartSession(TPM_SE_TRIAL, TPM_RH_NULL, "", false,
+ delegate_));
}
TEST_F(SessionManagerTest, StartSessionFailure) {
diff --git a/trunks/tpm_generated_test.cc b/trunks/tpm_generated_test.cc
index 6a7e15e..6048153 100644
--- a/trunks/tpm_generated_test.cc
+++ b/trunks/tpm_generated_test.cc
@@ -54,14 +54,14 @@ TEST(GeneratorTest, SerializeParseStruct) {
std::string buffer;
TPM_RC rc = Serialize_TPM2B_CREATION_DATA(data, &buffer);
ASSERT_EQ(TPM_RC_SUCCESS, rc);
- EXPECT_EQ(35, buffer.size());
+ EXPECT_EQ(35u, buffer.size());
TPM2B_CREATION_DATA data2;
memset(&data2, 0, sizeof(TPM2B_CREATION_DATA));
std::string buffer_before = buffer;
std::string buffer_parsed;
rc = Parse_TPM2B_CREATION_DATA(&buffer, &data2, &buffer_parsed);
ASSERT_EQ(TPM_RC_SUCCESS, rc);
- EXPECT_EQ(0, buffer.size());
+ EXPECT_EQ(0u, buffer.size());
EXPECT_EQ(buffer_before, buffer_parsed);
EXPECT_EQ(buffer_before.size() - 2, data2.size);
EXPECT_EQ(0, memcmp(&data.creation_data,
@@ -81,7 +81,7 @@ TEST(GeneratorTest, ParseBufferOverflow) {
// Case 1: Sufficient source but overflow the destination.
std::string malformed1 = "\x10\x00";
malformed1 += std::string(0x1000, 'A');
- ASSERT_GT(0x1000, sizeof(tmp.buffer));
+ ASSERT_GT(0x1000u, sizeof(tmp.buffer));
EXPECT_EQ(TPM_RC_INSUFFICIENT,
Parse_TPM2B_MAX_BUFFER(&malformed1, &tmp, nullptr));
// Case 2: Sufficient destination but overflow the source.
@@ -249,7 +249,7 @@ TEST(GeneratorTest, SynchronousCommandResponseTest) {
EXPECT_EQ(creation_hash.size, 1);
EXPECT_EQ(creation_hash.buffer[0], 'b');
EXPECT_EQ(creation_ticket.tag, 0x8002);
- EXPECT_EQ(creation_ticket.hierarchy, 0x40000007);
+ EXPECT_EQ(creation_ticket.hierarchy, 0x40000007u);
EXPECT_EQ(creation_ticket.digest.size, 0);
EXPECT_EQ(key_name.size, 3);
EXPECT_EQ(key_name.name[0], 'K');
diff --git a/trunks/tpm_simulator_handle.cc b/trunks/tpm_simulator_handle.cc
index 4402a95..0ef8210 100644
--- a/trunks/tpm_simulator_handle.cc
+++ b/trunks/tpm_simulator_handle.cc
@@ -18,7 +18,7 @@
#include <unistd.h>
-#ifdef USE_SIMULATOR
+#if defined(USE_SIMULATOR)
extern "C" {
#include <tpm2/TpmBuildSwitches.h>
#include <tpm2/_TPM_Init_fp.h>
@@ -41,7 +41,7 @@ TpmSimulatorHandle::TpmSimulatorHandle() {}
TpmSimulatorHandle::~TpmSimulatorHandle() {}
bool TpmSimulatorHandle::Init() {
-#ifdef USE_SIMULATOR
+#if defined(USE_SIMULATOR)
// Initialize TPM.
CHECK_EQ(chdir("/data/misc/trunksd"), 0);
_plat__Signal_PowerOn();
@@ -61,7 +61,7 @@ void TpmSimulatorHandle::SendCommand(const std::string& command,
}
std::string TpmSimulatorHandle::SendCommandAndWait(const std::string& command) {
-#ifdef USE_SIMULATOR
+#if defined(USE_SIMULATOR)
unsigned int response_size;
unsigned char* response;
std::string mutable_command(command);
diff --git a/trunks/tpm_state_test.cc b/trunks/tpm_state_test.cc
index 5833607..8bf4f39 100644
--- a/trunks/tpm_state_test.cc
+++ b/trunks/tpm_state_test.cc
@@ -195,10 +195,10 @@ TEST_F(TpmStateTest, FlagsClear) {
EXPECT_FALSE(tpm_state.WasShutdownOrderly());
EXPECT_FALSE(tpm_state.IsRSASupported());
EXPECT_FALSE(tpm_state.IsECCSupported());
- EXPECT_EQ(0, tpm_state.GetLockoutCounter());
- EXPECT_EQ(0, tpm_state.GetLockoutThreshold());
- EXPECT_EQ(0, tpm_state.GetLockoutInterval());
- EXPECT_EQ(0, tpm_state.GetLockoutRecovery());
+ EXPECT_EQ(0u, tpm_state.GetLockoutCounter());
+ EXPECT_EQ(0u, tpm_state.GetLockoutThreshold());
+ EXPECT_EQ(0u, tpm_state.GetLockoutInterval());
+ EXPECT_EQ(0u, tpm_state.GetLockoutRecovery());
}
TEST_F(TpmStateTest, FlagsSet) {
diff --git a/trunks/tpm_utility_impl.cc b/trunks/tpm_utility_impl.cc
index c99beb6..b3e0756 100644
--- a/trunks/tpm_utility_impl.cc
+++ b/trunks/tpm_utility_impl.cc
@@ -215,7 +215,6 @@ TPM_RC TpmUtilityImpl::AllocatePCR(const std::string& platform_password) {
++pcr_allocation.count;
}
for (auto pcr_type : pcr_banks_to_remove) {
- memset(&pcr_allocation, 0, sizeof(pcr_allocation));
pcr_allocation.pcr_selections[pcr_allocation.count].hash = pcr_type;
pcr_allocation.pcr_selections[pcr_allocation.count].sizeof_select =
PCR_SELECT_MAX;
diff --git a/trunks/tpm_utility_test.cc b/trunks/tpm_utility_test.cc
index 18436ba..a245cdd 100644
--- a/trunks/tpm_utility_test.cc
+++ b/trunks/tpm_utility_test.cc
@@ -86,6 +86,56 @@ class TpmUtilityTest : public testing::Test {
return utility_.CreateSaltingKey(owner_password);
}
+ void SetExistingKeyHandleExpectation(TPM_HANDLE handle) {
+ TPMS_CAPABILITY_DATA capability_data = {};
+ TPML_HANDLE& handles = capability_data.data.handles;
+ handles.count = 1;
+ handles.handle[0] = handle;
+ EXPECT_CALL(mock_tpm_,
+ GetCapabilitySync(TPM_CAP_HANDLES, handle, _, _, _, _))
+ .WillRepeatedly(
+ DoAll(SetArgPointee<4>(capability_data), Return(TPM_RC_SUCCESS)));
+ }
+
+ void PopulatePCRSelection(bool has_sha1_pcrs,
+ bool make_sha1_bank_empty,
+ bool has_sha256_pcrs,
+ TPML_PCR_SELECTION* pcrs) {
+ memset(pcrs, 0, sizeof(TPML_PCR_SELECTION));
+ // By convention fill SHA-256 first. This is a bit brittle because order is
+ // not important but it simplifies comparison to memcmp.
+ if (has_sha256_pcrs) {
+ pcrs->pcr_selections[pcrs->count].hash = TPM_ALG_SHA256;
+ pcrs->pcr_selections[pcrs->count].sizeof_select = PCR_SELECT_MIN;
+ for (int i = 0; i < PCR_SELECT_MIN; ++i) {
+ pcrs->pcr_selections[pcrs->count].pcr_select[i] = 0xff;
+ }
+ ++pcrs->count;
+ }
+ if (has_sha1_pcrs) {
+ pcrs->pcr_selections[pcrs->count].hash = TPM_ALG_SHA1;
+ if (make_sha1_bank_empty) {
+ pcrs->pcr_selections[pcrs->count].sizeof_select = PCR_SELECT_MAX;
+ } else {
+ pcrs->pcr_selections[pcrs->count].sizeof_select = PCR_SELECT_MIN;
+ for (int i = 0; i < PCR_SELECT_MIN; ++i) {
+ pcrs->pcr_selections[pcrs->count].pcr_select[i] = 0xff;
+ }
+ }
+ ++pcrs->count;
+ }
+ }
+
+ void SetExistingPCRSExpectation(bool has_sha1_pcrs, bool has_sha256_pcrs) {
+ TPMS_CAPABILITY_DATA capability_data = {};
+ TPML_PCR_SELECTION& pcrs = capability_data.data.assigned_pcr;
+ PopulatePCRSelection(has_sha1_pcrs, false, has_sha256_pcrs, &pcrs);
+ EXPECT_CALL(mock_tpm_,
+ GetCapabilitySync(TPM_CAP_PCRS, _, _, _, _, _))
+ .WillRepeatedly(
+ DoAll(SetArgPointee<4>(capability_data), Return(TPM_RC_SUCCESS)));
+ }
+
protected:
TrunksFactoryForTest factory_;
NiceMock<MockBlobParser> mock_blob_parser_;
@@ -142,18 +192,18 @@ TEST_F(TpmUtilityTest, ShutdownTest) {
}
TEST_F(TpmUtilityTest, InitializeTpmAlreadyInit) {
+ SetExistingPCRSExpectation(false, true);
EXPECT_EQ(TPM_RC_SUCCESS, utility_.InitializeTpm());
EXPECT_EQ(TPM_RC_SUCCESS, utility_.InitializeTpm());
}
TEST_F(TpmUtilityTest, InitializeTpmSuccess) {
- EXPECT_CALL(mock_tpm_, PCR_AllocateSync(_, _, _, _, _, _, _, _))
- .WillOnce(DoAll(SetArgPointee<3>(YES),
- Return(TPM_RC_SUCCESS)));
+ SetExistingPCRSExpectation(false, true);
EXPECT_EQ(TPM_RC_SUCCESS, utility_.InitializeTpm());
}
TEST_F(TpmUtilityTest, InitializeTpmBadAuth) {
+ SetExistingPCRSExpectation(false, true);
// Reject attempts to set platform auth.
EXPECT_CALL(mock_tpm_, HierarchyChangeAuthSync(TPM_RH_PLATFORM, _, _, _))
.WillRepeatedly(Return(TPM_RC_FAILURE));
@@ -161,36 +211,74 @@ TEST_F(TpmUtilityTest, InitializeTpmBadAuth) {
}
TEST_F(TpmUtilityTest, InitializeTpmDisablePHFails) {
- EXPECT_CALL(mock_tpm_, PCR_AllocateSync(_, _, _, _, _, _, _, _))
- .WillOnce(DoAll(SetArgPointee<3>(YES),
- Return(TPM_RC_SUCCESS)));
+ SetExistingPCRSExpectation(false, true);
// Reject attempts to disable the platform hierarchy.
EXPECT_CALL(mock_tpm_, HierarchyControlSync(_, _, TPM_RH_PLATFORM, _, _))
.WillRepeatedly(Return(TPM_RC_FAILURE));
EXPECT_EQ(TPM_RC_FAILURE, utility_.InitializeTpm());
}
-TEST_F(TpmUtilityTest, AllocatePCRSuccess) {
- TPML_PCR_SELECTION pcr_allocation;
+TEST_F(TpmUtilityTest, AllocatePCRFromNone) {
+ SetExistingPCRSExpectation(false, false);
+ TPML_PCR_SELECTION new_pcr_allocation;
EXPECT_CALL(mock_tpm_, PCR_AllocateSync(TPM_RH_PLATFORM, _, _, _, _, _, _, _))
- .WillOnce(DoAll(SaveArg<2>(&pcr_allocation),
+ .WillOnce(DoAll(SaveArg<2>(&new_pcr_allocation),
SetArgPointee<3>(YES),
Return(TPM_RC_SUCCESS)));
- EXPECT_EQ(TPM_RC_SUCCESS, utility_.AllocatePCR(""));
- EXPECT_EQ(1, pcr_allocation.count);
- EXPECT_EQ(TPM_ALG_SHA256, pcr_allocation.pcr_selections[0].hash);
- EXPECT_EQ(PCR_SELECT_MIN, pcr_allocation.pcr_selections[0].sizeof_select);
- EXPECT_EQ(0xFF, pcr_allocation.pcr_selections[0].pcr_select[0]);
- EXPECT_EQ(0xFF, pcr_allocation.pcr_selections[0].pcr_select[1]);
+ ASSERT_EQ(TPM_RC_SUCCESS, utility_.AllocatePCR(""));
+ ASSERT_EQ(1u, new_pcr_allocation.count);
+ TPML_PCR_SELECTION expected_pcr_allocation;
+ PopulatePCRSelection(false, false, true, &expected_pcr_allocation);
+ ASSERT_EQ(0, memcmp(&expected_pcr_allocation, &new_pcr_allocation,
+ sizeof(TPML_PCR_SELECTION)));
+}
+
+TEST_F(TpmUtilityTest, AllocatePCRFromSHA1Only) {
+ SetExistingPCRSExpectation(true, false);
+ TPML_PCR_SELECTION new_pcr_allocation;
+ EXPECT_CALL(mock_tpm_, PCR_AllocateSync(TPM_RH_PLATFORM, _, _, _, _, _, _, _))
+ .WillOnce(DoAll(SaveArg<2>(&new_pcr_allocation),
+ SetArgPointee<3>(YES),
+ Return(TPM_RC_SUCCESS)));
+ ASSERT_EQ(TPM_RC_SUCCESS, utility_.AllocatePCR(""));
+ ASSERT_EQ(2u, new_pcr_allocation.count);
+ TPML_PCR_SELECTION expected_pcr_allocation;
+ PopulatePCRSelection(true, true, true, &expected_pcr_allocation);
+ ASSERT_EQ(0, memcmp(&expected_pcr_allocation, &new_pcr_allocation,
+ sizeof(TPML_PCR_SELECTION)));
+}
+
+TEST_F(TpmUtilityTest, AllocatePCRFromSHA1AndSHA256) {
+ SetExistingPCRSExpectation(true, true);
+ TPML_PCR_SELECTION new_pcr_allocation;
+ EXPECT_CALL(mock_tpm_, PCR_AllocateSync(TPM_RH_PLATFORM, _, _, _, _, _, _, _))
+ .WillOnce(DoAll(SaveArg<2>(&new_pcr_allocation),
+ SetArgPointee<3>(YES),
+ Return(TPM_RC_SUCCESS)));
+ ASSERT_EQ(TPM_RC_SUCCESS, utility_.AllocatePCR(""));
+ ASSERT_EQ(1u, new_pcr_allocation.count);
+ TPML_PCR_SELECTION expected_pcr_allocation;
+ PopulatePCRSelection(true, true, false, &expected_pcr_allocation);
+ ASSERT_EQ(0, memcmp(&expected_pcr_allocation, &new_pcr_allocation,
+ sizeof(TPML_PCR_SELECTION)));
+}
+
+TEST_F(TpmUtilityTest, AllocatePCRFromSHA256Only) {
+ SetExistingPCRSExpectation(false, true);
+ EXPECT_CALL(mock_tpm_, PCR_AllocateSync(TPM_RH_PLATFORM, _, _, _, _, _, _, _))
+ .Times(0);
+ ASSERT_EQ(TPM_RC_SUCCESS, utility_.AllocatePCR(""));
}
TEST_F(TpmUtilityTest, AllocatePCRCommandFailure) {
+ SetExistingPCRSExpectation(false, false);
EXPECT_CALL(mock_tpm_, PCR_AllocateSync(_, _, _, _, _, _, _, _))
.WillOnce(Return(TPM_RC_FAILURE));
EXPECT_EQ(TPM_RC_FAILURE, utility_.AllocatePCR(""));
}
TEST_F(TpmUtilityTest, AllocatePCRTpmFailure) {
+ SetExistingPCRSExpectation(false, false);
EXPECT_CALL(mock_tpm_, PCR_AllocateSync(_, _, _, _, _, _, _, _))
.WillOnce(DoAll(SetArgPointee<3>(NO),
Return(TPM_RC_SUCCESS)));
@@ -306,7 +394,7 @@ TEST_F(TpmUtilityTest, GenerateRandomSuccess) {
// This number is larger than the max bytes the GetRandom call can return.
// Therefore we expect software to make multiple calls to fill this many
// bytes.
- int num_bytes = 72;
+ size_t num_bytes = 72;
std::string random_data;
TPM2B_DIGEST large_random;
large_random.size = 32;
@@ -325,7 +413,7 @@ TEST_F(TpmUtilityTest, GenerateRandomSuccess) {
}
TEST_F(TpmUtilityTest, GenerateRandomFails) {
- int num_bytes = 5;
+ size_t num_bytes = 5;
std::string random_data;
EXPECT_CALL(mock_tpm_, GetRandomSync(_, _, nullptr))
.WillOnce(Return(TPM_RC_FAILURE));
@@ -342,7 +430,7 @@ TEST_F(TpmUtilityTest, ExtendPCRSuccess) {
Return(TPM_RC_SUCCESS)));
EXPECT_EQ(TPM_RC_SUCCESS, utility_.ExtendPCR(1, "test digest",
&mock_authorization_delegate_));
- EXPECT_EQ(1, digests.count);
+ EXPECT_EQ(1u, digests.count);
EXPECT_EQ(TPM_ALG_SHA256, digests.digests[0].hash_alg);
std::string hash_string = crypto::SHA256HashString("test digest");
EXPECT_EQ(0, memcmp(hash_string.data(),
@@ -447,7 +535,7 @@ TEST_F(TpmUtilityTest, AsymmetricEncryptFail) {
}
TEST_F(TpmUtilityTest, AsymmetricEncryptBadParams) {
- TPM_HANDLE key_handle;
+ TPM_HANDLE key_handle = TPM_RH_FIRST;
std::string plaintext;
std::string ciphertext;
TPM2B_PUBLIC public_area;
@@ -579,11 +667,9 @@ TEST_F(TpmUtilityTest, AsymmetricDecryptFail) {
}
TEST_F(TpmUtilityTest, AsymmetricDecryptBadParams) {
- TPM_HANDLE key_handle;
- std::string key_name;
+ TPM_HANDLE key_handle = TPM_RH_FIRST;
std::string plaintext;
std::string ciphertext;
- std::string password;
TPM2B_PUBLIC public_area;
public_area.public_area.type = TPM_ALG_RSA;
public_area.public_area.object_attributes = kDecrypt | kRestricted;
@@ -1297,13 +1383,13 @@ TEST_F(TpmUtilityTest, CreateRSAKeyPairSuccess) {
EXPECT_EQ(public_area.public_area.object_attributes & kSign, kSign);
EXPECT_EQ(public_area.public_area.object_attributes & kUserWithAuth,
kUserWithAuth);
- EXPECT_EQ(public_area.public_area.object_attributes & kAdminWithPolicy, 0);
+ EXPECT_EQ(public_area.public_area.object_attributes & kAdminWithPolicy, 0u);
EXPECT_EQ(public_area.public_area.parameters.rsa_detail.scheme.scheme,
TPM_ALG_NULL);
- EXPECT_EQ(1, creation_pcrs.count);
+ EXPECT_EQ(1u, creation_pcrs.count);
EXPECT_EQ(TPM_ALG_SHA256, creation_pcrs.pcr_selections[0].hash);
EXPECT_EQ(PCR_SELECT_MIN, creation_pcrs.pcr_selections[0].sizeof_select);
- EXPECT_EQ(1 << (creation_pcr % 8),
+ EXPECT_EQ(1u << (creation_pcr % 8),
creation_pcrs.pcr_selections[0].pcr_select[creation_pcr / 8]);
}
@@ -1320,7 +1406,7 @@ TEST_F(TpmUtilityTest, CreateRSAKeyPairDecryptKeySuccess) {
"", false, kNoCreationPCR, &mock_authorization_delegate_, &key_blob,
nullptr));
EXPECT_EQ(public_area.public_area.object_attributes & kDecrypt, kDecrypt);
- EXPECT_EQ(public_area.public_area.object_attributes & kSign, 0);
+ EXPECT_EQ(public_area.public_area.object_attributes & kSign, 0u);
EXPECT_EQ(public_area.public_area.parameters.rsa_detail.scheme.scheme,
TPM_ALG_NULL);
}
@@ -1341,15 +1427,15 @@ TEST_F(TpmUtilityTest, CreateRSAKeyPairSignKeySuccess) {
TpmUtility::AsymmetricKeyUsage::kSignKey, 2048, 0x10001, key_auth,
policy_digest, true /* use_only_policy_authorization */, kNoCreationPCR,
&mock_authorization_delegate_, &key_blob, nullptr));
- EXPECT_EQ(public_area.public_area.object_attributes & kDecrypt, 0);
+ EXPECT_EQ(public_area.public_area.object_attributes & kDecrypt, 0u);
EXPECT_EQ(public_area.public_area.object_attributes & kSign, kSign);
- EXPECT_EQ(public_area.public_area.object_attributes & kUserWithAuth, 0);
+ EXPECT_EQ(public_area.public_area.object_attributes & kUserWithAuth, 0u);
EXPECT_EQ(public_area.public_area.object_attributes & kAdminWithPolicy,
kAdminWithPolicy);
EXPECT_EQ(public_area.public_area.parameters.rsa_detail.scheme.scheme,
TPM_ALG_NULL);
EXPECT_EQ(public_area.public_area.parameters.rsa_detail.key_bits, 2048);
- EXPECT_EQ(public_area.public_area.parameters.rsa_detail.exponent, 0x10001);
+ EXPECT_EQ(public_area.public_area.parameters.rsa_detail.exponent, 0x10001u);
EXPECT_EQ(public_area.public_area.auth_policy.size, policy_digest.size());
EXPECT_EQ(0, memcmp(public_area.public_area.auth_policy.buffer,
policy_digest.data(), policy_digest.size()));
@@ -1897,17 +1983,11 @@ TEST_F(TpmUtilityTest, SetKnownPasswordFailure) {
}
TEST_F(TpmUtilityTest, RootKeysSuccess) {
- EXPECT_CALL(mock_tpm_, ReadPublicSync(_, _, _, _, _, _))
- .Times(2)
- .WillRepeatedly(Return(TPM_RC_FAILURE));
EXPECT_EQ(TPM_RC_SUCCESS, CreateStorageRootKeys("password"));
}
TEST_F(TpmUtilityTest, RootKeysHandleConsistency) {
TPM_HANDLE test_handle = 42;
- EXPECT_CALL(mock_tpm_, ReadPublicSync(_, _, _, _, _, _))
- .Times(2)
- .WillRepeatedly(Return(TPM_RC_FAILURE));
EXPECT_CALL(mock_tpm_, CreatePrimarySyncShort(_, _, _, _, _, _, _, _, _, _))
.WillRepeatedly(DoAll(SetArgPointee<3>(test_handle),
Return(TPM_RC_SUCCESS)));
@@ -1917,33 +1997,24 @@ TEST_F(TpmUtilityTest, RootKeysHandleConsistency) {
}
TEST_F(TpmUtilityTest, RootKeysCreateFailure) {
- EXPECT_CALL(mock_tpm_, ReadPublicSync(_, _, _, _, _, _))
- .WillRepeatedly(Return(TPM_RC_FAILURE));
EXPECT_CALL(mock_tpm_, CreatePrimarySyncShort(_, _, _, _, _, _, _, _, _, _))
.WillRepeatedly(Return(TPM_RC_FAILURE));
EXPECT_EQ(TPM_RC_FAILURE, CreateStorageRootKeys("password"));
}
TEST_F(TpmUtilityTest, RootKeysPersistFailure) {
- EXPECT_CALL(mock_tpm_, ReadPublicSync(_, _, _, _, _, _))
- .WillRepeatedly(Return(TPM_RC_FAILURE));
EXPECT_CALL(mock_tpm_, EvictControlSync(_, _, _, _, _, _))
.WillRepeatedly(Return(TPM_RC_FAILURE));
EXPECT_EQ(TPM_RC_FAILURE, CreateStorageRootKeys("password"));
}
TEST_F(TpmUtilityTest, RootKeysAlreadyExist) {
- EXPECT_CALL(mock_tpm_, ReadPublicSync(_, _, _, _, _, _))
- .Times(2)
- .WillRepeatedly(Return(TPM_RC_SUCCESS));
+ SetExistingKeyHandleExpectation(kRSAStorageRootKey);
+ SetExistingKeyHandleExpectation(kECCStorageRootKey);
EXPECT_EQ(TPM_RC_SUCCESS, CreateStorageRootKeys("password"));
}
TEST_F(TpmUtilityTest, SaltingKeySuccess) {
- EXPECT_CALL(mock_tpm_, ReadPublicSync(_, _, _, _, _, _))
- .WillOnce(Return(TPM_RC_SUCCESS));
- EXPECT_CALL(mock_tpm_, ReadPublicSync(kSaltingKey, _, _, _, _, _))
- .WillOnce(Return(TPM_RC_FAILURE));
TPM2B_PUBLIC public_area;
EXPECT_CALL(mock_tpm_, CreateSyncShort(_, _, _, _, _, _, _, _, _, _))
.WillOnce(DoAll(SaveArg<2>(&public_area),
@@ -1953,10 +2024,6 @@ TEST_F(TpmUtilityTest, SaltingKeySuccess) {
}
TEST_F(TpmUtilityTest, SaltingKeyConsistency) {
- EXPECT_CALL(mock_tpm_, ReadPublicSync(_, _, _, _, _, _))
- .WillOnce(Return(TPM_RC_SUCCESS));
- EXPECT_CALL(mock_tpm_, ReadPublicSync(kSaltingKey, _, _, _, _, _))
- .WillOnce(Return(TPM_RC_FAILURE));
TPM_HANDLE test_handle = 42;
EXPECT_CALL(mock_tpm_, LoadSync(_, _, _, _, _, _, _))
.WillRepeatedly(DoAll(SetArgPointee<4>(test_handle),
@@ -1967,38 +2034,25 @@ TEST_F(TpmUtilityTest, SaltingKeyConsistency) {
}
TEST_F(TpmUtilityTest, SaltingKeyCreateFailure) {
- EXPECT_CALL(mock_tpm_, ReadPublicSync(_, _, _, _, _, _))
- .WillOnce(Return(TPM_RC_SUCCESS));
- EXPECT_CALL(mock_tpm_, ReadPublicSync(kSaltingKey, _, _, _, _, _))
- .WillOnce(Return(TPM_RC_FAILURE));
EXPECT_CALL(mock_tpm_, CreateSyncShort(_, _, _, _, _, _, _, _, _, _))
.WillRepeatedly(Return(TPM_RC_FAILURE));
EXPECT_EQ(TPM_RC_FAILURE, CreateSaltingKey("password"));
}
TEST_F(TpmUtilityTest, SaltingKeyLoadFailure) {
- EXPECT_CALL(mock_tpm_, ReadPublicSync(_, _, _, _, _, _))
- .WillOnce(Return(TPM_RC_SUCCESS));
- EXPECT_CALL(mock_tpm_, ReadPublicSync(kSaltingKey, _, _, _, _, _))
- .WillOnce(Return(TPM_RC_FAILURE));
EXPECT_CALL(mock_tpm_, LoadSync(_, _, _, _, _, _, _))
.WillRepeatedly(Return(TPM_RC_FAILURE));
EXPECT_EQ(TPM_RC_FAILURE, CreateSaltingKey("password"));
}
TEST_F(TpmUtilityTest, SaltingKeyPersistFailure) {
- EXPECT_CALL(mock_tpm_, ReadPublicSync(_, _, _, _, _, _))
- .WillOnce(Return(TPM_RC_SUCCESS));
- EXPECT_CALL(mock_tpm_, ReadPublicSync(kSaltingKey, _, _, _, _, _))
- .WillOnce(Return(TPM_RC_FAILURE));
EXPECT_CALL(mock_tpm_, EvictControlSync(_, _, _, _, _, _))
.WillRepeatedly(Return(TPM_RC_FAILURE));
EXPECT_EQ(TPM_RC_FAILURE, CreateSaltingKey("password"));
}
TEST_F(TpmUtilityTest, SaltingKeyAlreadyExists) {
- EXPECT_CALL(mock_tpm_, ReadPublicSync(kSaltingKey, _, _, _, _, _))
- .WillOnce(Return(TPM_RC_SUCCESS));
+ SetExistingKeyHandleExpectation(kSaltingKey);
EXPECT_EQ(TPM_RC_SUCCESS, CreateSaltingKey("password"));
}
diff --git a/trunks/trunks_binder_proxy.cc b/trunks/trunks_binder_proxy.cc
new file mode 100644
index 0000000..772afc7
--- /dev/null
+++ b/trunks/trunks_binder_proxy.cc
@@ -0,0 +1,121 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "trunks/trunks_binder_proxy.h"
+
+#include <base/bind.h>
+#include <base/callback.h>
+#include <base/logging.h>
+#include <binderwrapper/binder_wrapper.h>
+#include <utils/Errors.h>
+
+#include "android/trunks/BnTrunksClient.h"
+#include "android/trunks/BpTrunks.h"
+#include "trunks/binder_interface.h"
+#include "trunks/error_codes.h"
+#include "trunks/interface.pb.h"
+
+namespace {
+
+// Implements ITrunksClient and forwards response data to a ResponseCallback.
+class ResponseObserver : public android::trunks::BnTrunksClient {
+ public:
+ ResponseObserver(const trunks::CommandTransceiver::ResponseCallback& callback)
+ : callback_(callback) {}
+
+ // ITrunksClient interface.
+ android::binder::Status OnCommandResponse(
+ const std::vector<int8_t>& response_proto_data) override {
+ trunks::SendCommandResponse response_proto;
+ if (!response_proto.ParseFromArray(response_proto_data.data(),
+ response_proto_data.size())) {
+ LOG(ERROR) << "TrunksBinderProxy: Bad response data.";
+ callback_.Run(
+ trunks::CreateErrorResponse(trunks::SAPI_RC_MALFORMED_RESPONSE));
+ }
+ callback_.Run(response_proto.response());
+ return android::binder::Status::ok();
+ }
+
+ private:
+ trunks::CommandTransceiver::ResponseCallback callback_;
+};
+
+} // namespace
+
+namespace trunks {
+
+bool TrunksBinderProxy::Init() {
+ android::sp<android::IBinder> service_binder =
+ android::BinderWrapper::GetOrCreateInstance()->GetService(
+ kTrunksServiceName);
+ if (!service_binder.get()) {
+ LOG(ERROR) << "TrunksBinderProxy: Trunks service does not exist.";
+ return false;
+ }
+ trunks_service_ = new android::trunks::BpTrunks(service_binder);
+ return true;
+}
+
+void TrunksBinderProxy::SendCommand(const std::string& command,
+ const ResponseCallback& callback) {
+ SendCommandRequest command_proto;
+ command_proto.set_command(command);
+ std::vector<int8_t> command_proto_data;
+ command_proto_data.resize(command_proto.ByteSize());
+ if (!command_proto.SerializeToArray(command_proto_data.data(),
+ command_proto_data.size())) {
+ LOG(ERROR) << "TrunksBinderProxy: Failed to serialize protobuf.";
+ callback.Run(CreateErrorResponse(TRUNKS_RC_IPC_ERROR));
+ return;
+ }
+ android::sp<ResponseObserver> observer(new ResponseObserver(callback));
+ android::binder::Status status =
+ trunks_service_->SendCommand(command_proto_data, observer);
+ if (!status.isOk()) {
+ LOG(ERROR) << "TrunksBinderProxy: Binder error: " << status.toString8();
+ callback.Run(CreateErrorResponse(TRUNKS_RC_IPC_ERROR));
+ return;
+ }
+}
+
+std::string TrunksBinderProxy::SendCommandAndWait(const std::string& command) {
+ SendCommandRequest command_proto;
+ command_proto.set_command(command);
+ std::vector<int8_t> command_proto_data;
+ command_proto_data.resize(command_proto.ByteSize());
+ if (!command_proto.SerializeToArray(command_proto_data.data(),
+ command_proto_data.size())) {
+ LOG(ERROR) << "TrunksBinderProxy: Failed to serialize protobuf.";
+ return CreateErrorResponse(TRUNKS_RC_IPC_ERROR);
+ }
+ std::vector<int8_t> response_proto_data;
+ android::binder::Status status = trunks_service_->SendCommandAndWait(
+ command_proto_data, &response_proto_data);
+ if (!status.isOk()) {
+ LOG(ERROR) << "TrunksBinderProxy: Binder error: " << status.toString8();
+ return CreateErrorResponse(TRUNKS_RC_IPC_ERROR);
+ }
+ trunks::SendCommandResponse response_proto;
+ if (!response_proto.ParseFromArray(response_proto_data.data(),
+ response_proto_data.size())) {
+ LOG(ERROR) << "TrunksBinderProxy: Bad response data.";
+ return trunks::CreateErrorResponse(trunks::SAPI_RC_MALFORMED_RESPONSE);
+ }
+ return response_proto.response();
+}
+
+} // namespace trunks
diff --git a/trunks/trunks_binder_proxy.h b/trunks/trunks_binder_proxy.h
new file mode 100644
index 0000000..359094a
--- /dev/null
+++ b/trunks/trunks_binder_proxy.h
@@ -0,0 +1,53 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef TRUNKS_TRUNKS_BINDER_PROXY_H_
+#define TRUNKS_TRUNKS_BINDER_PROXY_H_
+
+#include <string>
+
+#include "android/trunks/ITrunks.h"
+#include "trunks/command_transceiver.h"
+#include "trunks/trunks_export.h"
+
+namespace trunks {
+
+// TrunksBinderProxy is a CommandTransceiver implementation that forwards all
+// commands to the trunksd binder daemon. See TrunksBinderService for details on
+// how the commands are handled once they reach trunksd.
+class TRUNKS_EXPORT TrunksBinderProxy : public CommandTransceiver {
+ public:
+ TrunksBinderProxy() = default;
+ ~TrunksBinderProxy() override = default;
+
+ // Initializes the client. Returns true on success.
+ bool Init() override;
+
+ // Asynchronous calls assume a message loop and binder watcher have already
+ // been configured elsewhere.
+ void SendCommand(const std::string& command,
+ const ResponseCallback& callback) override;
+ std::string SendCommandAndWait(const std::string& command) override;
+
+ private:
+ android::sp<android::trunks::ITrunks> trunks_service_;
+
+ DISALLOW_COPY_AND_ASSIGN(TrunksBinderProxy);
+};
+
+} // namespace trunks
+
+#endif // TRUNKS_TRUNKS_BINDER_PROXY_H_
diff --git a/trunks/trunks_binder_service.cc b/trunks/trunks_binder_service.cc
new file mode 100644
index 0000000..028aa3c
--- /dev/null
+++ b/trunks/trunks_binder_service.cc
@@ -0,0 +1,120 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "trunks/trunks_binder_service.h"
+
+#include <sysexits.h>
+
+#include <base/bind.h>
+#include <binderwrapper/binder_wrapper.h>
+
+#include "trunks/binder_interface.h"
+#include "trunks/command_transceiver.h"
+#include "trunks/error_codes.h"
+#include "trunks/interface.pb.h"
+
+namespace {
+
+// If |command| is a valid command protobuf, provides the |command_data| and
+// returns true. Otherwise, returns false.
+bool ParseCommandProto(const std::vector<int8_t>& command,
+ std::string* command_data) {
+ trunks::SendCommandRequest request_proto;
+ if (!request_proto.ParseFromArray(command.data(), command.size()) ||
+ !request_proto.has_command() || request_proto.command().empty()) {
+ return false;
+ }
+ *command_data = request_proto.command();
+ return true;
+}
+
+void CreateResponseProto(const std::string& data,
+ std::vector<int8_t>* response) {
+ trunks::SendCommandResponse response_proto;
+ response_proto.set_response(data);
+ response->resize(response_proto.ByteSize());
+ CHECK(response_proto.SerializeToArray(response->data(), response->size()))
+ << "TrunksBinderService: Failed to serialize protobuf.";
+}
+
+} // namespace
+
+namespace trunks {
+
+int TrunksBinderService::OnInit() {
+ android::BinderWrapper::Create();
+ if (!watcher_.Init()) {
+ LOG(ERROR) << "TrunksBinderService: BinderWatcher::Init failed.";
+ return EX_UNAVAILABLE;
+ }
+ binder_ = new BinderServiceInternal(this);
+ if (!android::BinderWrapper::Get()->RegisterService(
+ kTrunksServiceName, android::IInterface::asBinder(binder_))) {
+ LOG(ERROR) << "TrunksBinderService: RegisterService failed.";
+ return EX_UNAVAILABLE;
+ }
+ LOG(INFO) << "Trunks: Binder service registered.";
+ return brillo::Daemon::OnInit();
+}
+
+TrunksBinderService::BinderServiceInternal::BinderServiceInternal(
+ TrunksBinderService* service)
+ : service_(service) {}
+
+android::binder::Status TrunksBinderService::BinderServiceInternal::SendCommand(
+ const std::vector<int8_t>& command,
+ const android::sp<android::trunks::ITrunksClient>& client) {
+ auto callback =
+ base::Bind(&TrunksBinderService::BinderServiceInternal::OnResponse,
+ GetWeakPtr(), client);
+ std::string command_data;
+ if (!ParseCommandProto(command, &command_data)) {
+ LOG(ERROR) << "TrunksBinderService: Bad command data.";
+ callback.Run(CreateErrorResponse(SAPI_RC_BAD_PARAMETER));
+ return android::binder::Status::ok();
+ }
+ service_->transceiver_->SendCommand(command_data, callback);
+ return android::binder::Status::ok();
+}
+
+void TrunksBinderService::BinderServiceInternal::OnResponse(
+ const android::sp<android::trunks::ITrunksClient>& client,
+ const std::string& response) {
+ std::vector<int8_t> binder_response;
+ CreateResponseProto(response, &binder_response);
+ android::binder::Status status = client->OnCommandResponse(binder_response);
+ if (!status.isOk()) {
+ LOG(ERROR) << "TrunksBinderService: Failed to send response to client: "
+ << status.toString8();
+ }
+}
+
+android::binder::Status
+TrunksBinderService::BinderServiceInternal::SendCommandAndWait(
+ const std::vector<int8_t>& command,
+ std::vector<int8_t>* response) {
+ std::string command_data;
+ if (!ParseCommandProto(command, &command_data)) {
+ LOG(ERROR) << "TrunksBinderService: Bad command data.";
+ CreateResponseProto(CreateErrorResponse(SAPI_RC_BAD_PARAMETER), response);
+ return android::binder::Status::ok();
+ }
+ CreateResponseProto(service_->transceiver_->SendCommandAndWait(command_data),
+ response);
+ return android::binder::Status::ok();
+}
+
+} // namespace trunks
diff --git a/trunks/trunks_binder_service.h b/trunks/trunks_binder_service.h
new file mode 100644
index 0000000..7f809ac
--- /dev/null
+++ b/trunks/trunks_binder_service.h
@@ -0,0 +1,90 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef TRUNKS_TRUNKS_BINDER_SERVICE_H_
+#define TRUNKS_TRUNKS_BINDER_SERVICE_H_
+
+#include <base/memory/weak_ptr.h>
+#include <brillo/binder_watcher.h>
+#include <brillo/daemons/daemon.h>
+
+#include "android/trunks/BnTrunks.h"
+#include "trunks/command_transceiver.h"
+
+namespace trunks {
+
+// TrunksBinderService registers for and handles all incoming binder calls for
+// the trunksd system daemon.
+//
+// Example Usage:
+//
+// TrunksBinderService service;
+// service.set_transceiver(&my_transceiver);
+// service.Run();
+class TrunksBinderService : public brillo::Daemon {
+ public:
+ TrunksBinderService() = default;
+ ~TrunksBinderService() override = default;
+
+ // The |transceiver| will be the target of all incoming TPM commands. This
+ // class does not take ownership of |transceiver|.
+ void set_transceiver(CommandTransceiver* transceiver) {
+ transceiver_ = transceiver;
+ }
+
+ protected:
+ int OnInit() override;
+
+ private:
+ friend class BinderServiceInternal;
+ class BinderServiceInternal : public android::trunks::BnTrunks {
+ public:
+ BinderServiceInternal(TrunksBinderService* service);
+ ~BinderServiceInternal() override = default;
+
+ // ITrunks interface.
+ android::binder::Status SendCommand(
+ const std::vector<int8_t>& command,
+ const android::sp<android::trunks::ITrunksClient>& client) override;
+ android::binder::Status SendCommandAndWait(
+ const std::vector<int8_t>& command,
+ std::vector<int8_t>* response) override;
+
+ private:
+ void OnResponse(const android::sp<android::trunks::ITrunksClient>& client,
+ const std::string& response);
+
+ base::WeakPtr<BinderServiceInternal> GetWeakPtr() {
+ return weak_factory_.GetWeakPtr();
+ }
+
+ TrunksBinderService* service_;
+
+ // Declared last so weak pointers are invalidated first on destruction.
+ base::WeakPtrFactory<BinderServiceInternal> weak_factory_{this};
+ };
+
+ CommandTransceiver* transceiver_ = nullptr;
+ brillo::BinderWatcher watcher_;
+ android::sp<BinderServiceInternal> binder_;
+
+ DISALLOW_COPY_AND_ASSIGN(TrunksBinderService);
+};
+
+} // namespace trunks
+
+
+#endif // TRUNKS_TRUNKS_BINDER_SERVICE_H_
diff --git a/trunks/trunks_client.cc b/trunks/trunks_client.cc
index 4975470..ac29bf1 100644
--- a/trunks/trunks_client.cc
+++ b/trunks/trunks_client.cc
@@ -33,7 +33,6 @@
#include "trunks/tpm_utility.h"
#include "trunks/trunks_client_test.h"
#include "trunks/trunks_factory_impl.h"
-#include "trunks/trunks_proxy.h"
namespace {
@@ -143,14 +142,8 @@ int main(int argc, char **argv) {
return 0;
}
- CommandTransceiver* proxy = new trunks::TrunksProxy();
-
- if (!proxy->Init()) {
- LOG(ERROR) << "Error initializing proxy to communicate with TPM.";
- return -1;
- }
scoped_ptr<TrunksFactory> factory = scoped_ptr<TrunksFactory>(
- new trunks::TrunksFactoryImpl(proxy));
+ new trunks::TrunksFactoryImpl(true /* failure_is_fatal */));
if (cl->HasSwitch("status")) {
return DumpStatus(factory.get());
diff --git a/trunks/trunks_client_test.cc b/trunks/trunks_client_test.cc
index 594747a..fc78b19 100644
--- a/trunks/trunks_client_test.cc
+++ b/trunks/trunks_client_test.cc
@@ -57,7 +57,8 @@ std::string GetOpenSSLError() {
namespace trunks {
-TrunksClientTest::TrunksClientTest() : factory_(new TrunksFactoryImpl()) {
+TrunksClientTest::TrunksClientTest()
+ : factory_(new TrunksFactoryImpl(true /* failure_is_fatal */)) {
crypto::EnsureOpenSSLInit();
}
@@ -987,7 +988,7 @@ bool TrunksClientTest::PerformRSAEncrpytAndDecrpyt(
void TrunksClientTest::GenerateRSAKeyPair(std::string* modulus,
std::string* prime_factor,
std::string* public_key) {
-#ifdef OPENSSL_IS_BORINGSSL
+#if defined(OPENSSL_IS_BORINGSSL)
crypto::ScopedRSA rsa(RSA_new());
crypto::ScopedBIGNUM exponent(BN_new());
CHECK(BN_set_word(exponent.get(), RSA_F4));
diff --git a/trunks/trunks_proxy.cc b/trunks/trunks_dbus_proxy.cc
index ddef65b..9c2dfae 100644
--- a/trunks/trunks_proxy.cc
+++ b/trunks/trunks_dbus_proxy.cc
@@ -14,15 +14,15 @@
// limitations under the License.
//
-#include "trunks/trunks_proxy.h"
+#include "trunks/trunks_dbus_proxy.h"
#include <base/bind.h>
#include <brillo/bind_lambda.h>
#include <brillo/dbus/dbus_method_invoker.h>
#include "trunks/dbus_interface.h"
-#include "trunks/dbus_interface.pb.h"
#include "trunks/error_codes.h"
+#include "trunks/interface.pb.h"
namespace {
@@ -36,15 +36,15 @@ const int kDBusMaxTimeout = 5 * 60 * 1000;
namespace trunks {
-TrunksProxy::TrunksProxy() : weak_factory_(this) {}
+TrunksDBusProxy::TrunksDBusProxy() : weak_factory_(this) {}
-TrunksProxy::~TrunksProxy() {
+TrunksDBusProxy::~TrunksDBusProxy() {
if (bus_) {
bus_->ShutdownAndBlock();
}
}
-bool TrunksProxy::Init() {
+bool TrunksDBusProxy::Init() {
dbus::Bus::Options options;
options.bus_type = dbus::Bus::SYSTEM;
bus_ = new dbus::Bus(options);
@@ -55,10 +55,10 @@ bool TrunksProxy::Init() {
return (object_proxy_ != nullptr);
}
-void TrunksProxy::SendCommand(const std::string& command,
+void TrunksDBusProxy::SendCommand(const std::string& command,
const ResponseCallback& callback) {
if (origin_thread_id_ != base::PlatformThread::CurrentId()) {
- LOG(ERROR) << "Error TrunksProxy cannot be shared by multiple threads.";
+ LOG(ERROR) << "Error TrunksDBusProxy cannot be shared by multiple threads.";
callback.Run(CreateErrorResponse(TRUNKS_RC_IPC_ERROR));
}
SendCommandRequest tpm_command_proto;
@@ -81,9 +81,9 @@ void TrunksProxy::SendCommand(const std::string& command,
tpm_command_proto);
}
-std::string TrunksProxy::SendCommandAndWait(const std::string& command) {
+std::string TrunksDBusProxy::SendCommandAndWait(const std::string& command) {
if (origin_thread_id_ != base::PlatformThread::CurrentId()) {
- LOG(ERROR) << "Error TrunksProxy cannot be shared by multiple threads.";
+ LOG(ERROR) << "Error TrunksDBusProxy cannot be shared by multiple threads.";
return CreateErrorResponse(TRUNKS_RC_IPC_ERROR);
}
SendCommandRequest tpm_command_proto;
diff --git a/trunks/trunks_proxy.h b/trunks/trunks_dbus_proxy.h
index 858b1ea..aa60e63 100644
--- a/trunks/trunks_proxy.h
+++ b/trunks/trunks_dbus_proxy.h
@@ -14,10 +14,8 @@
// limitations under the License.
//
-#ifndef TRUNKS_TRUNKS_PROXY_H_
-#define TRUNKS_TRUNKS_PROXY_H_
-
-#include "trunks/command_transceiver.h"
+#ifndef TRUNKS_TRUNKS_DBUS_PROXY_H_
+#define TRUNKS_TRUNKS_DBUS_PROXY_H_
#include <string>
@@ -26,18 +24,19 @@
#include <dbus/bus.h>
#include <dbus/object_proxy.h>
+#include "trunks/command_transceiver.h"
#include "trunks/trunks_export.h"
namespace trunks {
-// TrunksProxy is a CommandTransceiver implementation that forwards all commands
-// to the trunksd D-Bus daemon. See TrunksService for details on how the
-// commands are handled once they reach trunksd. TrunksProxy must be used in
-// only one thread.
-class TRUNKS_EXPORT TrunksProxy: public CommandTransceiver {
+// TrunksDBusProxy is a CommandTransceiver implementation that forwards all
+// commands to the trunksd D-Bus daemon. See TrunksDBusService for details on
+// how the commands are handled once they reach trunksd. A TrunksDBusProxy
+// instance must be used in only one thread.
+class TRUNKS_EXPORT TrunksDBusProxy: public CommandTransceiver {
public:
- TrunksProxy();
- ~TrunksProxy() override;
+ TrunksDBusProxy();
+ ~TrunksDBusProxy() override;
// Initializes the D-Bus client. Returns true on success.
bool Init() override;
@@ -48,7 +47,7 @@ class TRUNKS_EXPORT TrunksProxy: public CommandTransceiver {
std::string SendCommandAndWait(const std::string& command) override;
private:
- base::WeakPtr<TrunksProxy> GetWeakPtr() {
+ base::WeakPtr<TrunksDBusProxy> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
@@ -57,11 +56,11 @@ class TRUNKS_EXPORT TrunksProxy: public CommandTransceiver {
dbus::ObjectProxy* object_proxy_;
// Declared last so weak pointers are invalidated first on destruction.
- base::WeakPtrFactory<TrunksProxy> weak_factory_;
+ base::WeakPtrFactory<TrunksDBusProxy> weak_factory_;
- DISALLOW_COPY_AND_ASSIGN(TrunksProxy);
+ DISALLOW_COPY_AND_ASSIGN(TrunksDBusProxy);
};
} // namespace trunks
-#endif // TRUNKS_TRUNKS_PROXY_H_
+#endif // TRUNKS_TRUNKS_DBUS_PROXY_H_
diff --git a/trunks/trunks_service.cc b/trunks/trunks_dbus_service.cc
index f1aa34e..23a266e 100644
--- a/trunks/trunks_service.cc
+++ b/trunks/trunks_dbus_service.cc
@@ -14,42 +14,43 @@
// limitations under the License.
//
-#include "trunks/trunks_service.h"
+#include "trunks/trunks_dbus_service.h"
#include <base/bind.h>
#include <brillo/bind_lambda.h>
#include "trunks/dbus_interface.h"
-#include "trunks/dbus_interface.pb.h"
#include "trunks/error_codes.h"
+#include "trunks/interface.pb.h"
namespace trunks {
+using brillo::dbus_utils::AsyncEventSequencer;
using brillo::dbus_utils::DBusMethodResponse;
-TrunksService::TrunksService(const scoped_refptr<dbus::Bus>& bus,
- CommandTransceiver* transceiver)
- : trunks_dbus_object_(nullptr, bus, dbus::ObjectPath(kTrunksServicePath)),
- transceiver_(transceiver),
- weak_factory_(this) {}
+TrunksDBusService::TrunksDBusService()
+ : brillo::DBusServiceDaemon(trunks::kTrunksServiceName) {}
-void TrunksService::Register(const CompletionAction& callback) {
+void TrunksDBusService::RegisterDBusObjectsAsync(
+ AsyncEventSequencer* sequencer) {
+ trunks_dbus_object_.reset(new brillo::dbus_utils::DBusObject(
+ nullptr, bus_, dbus::ObjectPath(kTrunksServicePath)));
brillo::dbus_utils::DBusInterface* dbus_interface =
- trunks_dbus_object_.AddOrGetInterface(kTrunksInterface);
- dbus_interface->AddMethodHandler(kSendCommand,
- base::Unretained(this),
- &TrunksService::HandleSendCommand);
- trunks_dbus_object_.RegisterAsync(callback);
+ trunks_dbus_object_->AddOrGetInterface(kTrunksInterface);
+ dbus_interface->AddMethodHandler(kSendCommand, base::Unretained(this),
+ &TrunksDBusService::HandleSendCommand);
+ trunks_dbus_object_->RegisterAsync(
+ sequencer->GetHandler("Failed to register D-Bus object.", true));
}
-void TrunksService::HandleSendCommand(
- std::unique_ptr<DBusMethodResponse<
- const SendCommandResponse&>> response_sender,
+void TrunksDBusService::HandleSendCommand(
+ std::unique_ptr<DBusMethodResponse<const SendCommandResponse&>>
+ response_sender,
const SendCommandRequest& request) {
// Convert |response_sender| to a shared_ptr so |transceiver_| can safely
// copy the callback.
- using SharedResponsePointer = std::shared_ptr<
- DBusMethodResponse<const SendCommandResponse&>>;
+ using SharedResponsePointer =
+ std::shared_ptr<DBusMethodResponse<const SendCommandResponse&>>;
// A callback that constructs the response protobuf and sends it.
auto callback = [](const SharedResponsePointer& response,
const std::string& response_from_tpm) {
@@ -58,7 +59,7 @@ void TrunksService::HandleSendCommand(
response->Return(tpm_response_proto);
};
if (!request.has_command() || request.command().empty()) {
- LOG(ERROR) << "TrunksService: Invalid request.";
+ LOG(ERROR) << "TrunksDBusService: Invalid request.";
callback(SharedResponsePointer(std::move(response_sender)),
CreateErrorResponse(SAPI_RC_BAD_PARAMETER));
return;
diff --git a/trunks/trunks_dbus_service.h b/trunks/trunks_dbus_service.h
new file mode 100644
index 0000000..5a7a697
--- /dev/null
+++ b/trunks/trunks_dbus_service.h
@@ -0,0 +1,79 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef TRUNKS_TRUNKS_DBUS_SERVICE_H_
+#define TRUNKS_TRUNKS_DBUS_SERVICE_H_
+
+#include <memory>
+#include <string>
+
+#include <base/memory/weak_ptr.h>
+#include <brillo/daemons/dbus_daemon.h>
+#include <brillo/dbus/dbus_method_response.h>
+#include <brillo/dbus/dbus_object.h>
+
+#include "trunks/command_transceiver.h"
+#include "trunks/interface.pb.h"
+
+namespace trunks {
+
+// TrunksDBusService registers for and handles all incoming D-Bus messages for
+// the trunksd system daemon.
+//
+// Example Usage:
+//
+// TrunksDBusService service;
+// service.set_transceiver(&my_transceiver);
+// service.Run();
+class TrunksDBusService : public brillo::DBusServiceDaemon {
+ public:
+ TrunksDBusService();
+ ~TrunksDBusService() override = default;
+
+ // The |transceiver| will be the target of all incoming TPM commands. This
+ // class does not take ownership of |transceiver|.
+ void set_transceiver(CommandTransceiver* transceiver) {
+ transceiver_ = transceiver;
+ }
+
+ protected:
+ // Exports D-Bus methods.
+ void RegisterDBusObjectsAsync(
+ brillo::dbus_utils::AsyncEventSequencer* sequencer) override;
+
+ private:
+ // Handles calls to the 'SendCommand' method.
+ void HandleSendCommand(
+ std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
+ const SendCommandResponse&>> response_sender,
+ const SendCommandRequest& request);
+
+ base::WeakPtr<TrunksDBusService> GetWeakPtr() {
+ return weak_factory_.GetWeakPtr();
+ }
+
+ std::unique_ptr<brillo::dbus_utils::DBusObject> trunks_dbus_object_;
+ CommandTransceiver* transceiver_ = nullptr;
+
+ // Declared last so weak pointers are invalidated first on destruction.
+ base::WeakPtrFactory<TrunksDBusService> weak_factory_{this};
+ DISALLOW_COPY_AND_ASSIGN(TrunksDBusService);
+};
+
+} // namespace trunks
+
+
+#endif // TRUNKS_TRUNKS_DBUS_SERVICE_H_
diff --git a/trunks/trunks_factory.h b/trunks/trunks_factory.h
index b90baa6..92046cf 100644
--- a/trunks/trunks_factory.h
+++ b/trunks/trunks_factory.h
@@ -28,6 +28,7 @@ namespace trunks {
class AuthorizationDelegate;
class BlobParser;
+class CommandTransceiver;
class HmacSession;
class PolicySession;
class SessionManager;
diff --git a/trunks/trunks_factory_impl.cc b/trunks/trunks_factory_impl.cc
index 935aba8..8b832c4 100644
--- a/trunks/trunks_factory_impl.cc
+++ b/trunks/trunks_factory_impl.cc
@@ -16,6 +16,8 @@
#include "trunks/trunks_factory_impl.h"
+#include <base/logging.h>
+
#include "trunks/blob_parser.h"
#include "trunks/hmac_session_impl.h"
#include "trunks/password_authorization_delegate.h"
@@ -24,16 +26,28 @@
#include "trunks/tpm_generated.h"
#include "trunks/tpm_state_impl.h"
#include "trunks/tpm_utility_impl.h"
-#include "trunks/trunks_proxy.h"
+#if defined(USE_BINDER_IPC)
+#include "trunks/trunks_binder_proxy.h"
+#else
+#include "trunks/trunks_dbus_proxy.h"
+#endif
namespace trunks {
-TrunksFactoryImpl::TrunksFactoryImpl() {
- default_transceiver_.reset(new TrunksProxy());
+TrunksFactoryImpl::TrunksFactoryImpl(bool failure_is_fatal) {
+#if defined(USE_BINDER_IPC)
+ default_transceiver_.reset(new TrunksBinderProxy());
+#else
+ default_transceiver_.reset(new TrunksDBusProxy());
+#endif
transceiver_ = default_transceiver_.get();
tpm_.reset(new Tpm(transceiver_));
if (!transceiver_->Init()) {
- LOG(ERROR) << "Error initializing transceiver.";
+ if (failure_is_fatal) {
+ LOG(FATAL) << "Error initializing default IPC proxy.";
+ } else {
+ LOG(ERROR) << "Error initializing default IPC proxy.";
+ }
}
}
diff --git a/trunks/trunks_factory_impl.h b/trunks/trunks_factory_impl.h
index 084aab7..03d25bf 100644
--- a/trunks/trunks_factory_impl.h
+++ b/trunks/trunks_factory_impl.h
@@ -30,13 +30,13 @@
namespace trunks {
class Tpm;
-class TrunksProxy;
// TrunksFactoryImpl is the default TrunksFactory implementation.
class TRUNKS_EXPORT TrunksFactoryImpl : public TrunksFactory {
public:
- // Uses TrunksProxy as the default CommandTransceiver to pass to the TPM.
- TrunksFactoryImpl();
+ // Uses an IPC proxy as the default CommandTransceiver. If |failure_is_fatal|
+ // is set then a failure to initialize the proxy will abort.
+ explicit TrunksFactoryImpl(bool failure_is_fatal);
// TrunksFactoryImpl does not take ownership of |transceiver|. This
// transceiver is forwarded down to the Tpm instance maintained by
// this factory.
diff --git a/trunks/trunks_service.h b/trunks/trunks_service.h
deleted file mode 100644
index 94ea16f..0000000
--- a/trunks/trunks_service.h
+++ /dev/null
@@ -1,69 +0,0 @@
-//
-// Copyright (C) 2014 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#ifndef TRUNKS_TRUNKS_SERVICE_H_
-#define TRUNKS_TRUNKS_SERVICE_H_
-
-#include <string>
-
-#include <base/memory/weak_ptr.h>
-#include <brillo/dbus/dbus_method_response.h>
-#include <brillo/dbus/dbus_object.h>
-
-#include "trunks/dbus_interface.pb.h"
-#include "trunks/tpm_handle.h"
-
-namespace trunks {
-
-using CompletionAction =
- brillo::dbus_utils::AsyncEventSequencer::CompletionAction;
-
-// TrunksService registers for and handles all incoming D-Bus messages for the
-// trunksd system daemon.
-class TrunksService {
- public:
- // The |transceiver| will be the target of all incoming TPM commands.
- TrunksService(const scoped_refptr<dbus::Bus>& bus,
- CommandTransceiver* transceiver);
- virtual ~TrunksService() = default;
-
- // Connects to D-Bus system bus and exports Trunks methods.
- void Register(const CompletionAction& callback);
-
- private:
- // Handles calls to the 'SendCommand' method.
- void HandleSendCommand(
- std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
- const SendCommandResponse&>> response_sender,
- const SendCommandRequest& request);
-
- base::WeakPtr<TrunksService> GetWeakPtr() {
- return weak_factory_.GetWeakPtr();
- }
-
- brillo::dbus_utils::DBusObject trunks_dbus_object_;
- CommandTransceiver* transceiver_;
-
- // Declared last so weak pointers are invalidated first on destruction.
- base::WeakPtrFactory<TrunksService> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(TrunksService);
-};
-
-} // namespace trunks
-
-
-#endif // TRUNKS_TRUNKS_SERVICE_H_
diff --git a/trunks/trunksd-seccomp-arm.policy b/trunks/trunksd-seccomp-arm.policy
index 80af7a6..40b0c1a 100644
--- a/trunks/trunksd-seccomp-arm.policy
+++ b/trunks/trunksd-seccomp-arm.policy
@@ -14,7 +14,6 @@
# limitations under the License.
#
-# Tested on daisy
gettid: 1
getuid32: 1
geteuid32: 1
@@ -27,28 +26,24 @@ clock_getres: 1
clock_gettime: 1
gettimeofday: 1
-socket: arg0 == 0x1 || arg0 == 0x10
-socketpair: 1
-connect: 1
-getsockname: 1
-pipe: 1
-send: 1
-sendmsg: 1
-recvmsg: 1
-
-epoll_create: 1
-epoll_wait: 1
+epoll_create1: 1
+epoll_pwait: 1
epoll_ctl: 1
-poll: 1
+openat: 1
read: 1
write: 1
+writev: 1
close: 1
-
fstat64: 1
-stat64: 1
_llseek: 1
+lseek: 1
fcntl64: 1
+readlinkat: 1
+faccessat: 1
+pipe2: 1
+socket: 1
+connect: 1
futex: 1
@@ -56,7 +51,27 @@ restart_syscall: 1
exit: 1
exit_group: 1
rt_sigreturn: 1
+sigaltstack: 1
+personality: 1
brk: 1
mmap2: 1
munmap: 1
+madvise: 1
+
+# Allow thread creation.
+mprotect: 1
+clone: 1
+set_robust_list: 1
+# This is attempted but apparently not necessary; return EPERM.
+prctl: return 1
+gettid: 1
+set_tid_address: 1
+
+rt_sigprocmask: 1
+signalfd4: 1
+ioctl: 1
+getpriority: 1
+exit: 1
+exit_group: 1
+chdir: 1
diff --git a/trunks/trunksd-seccomp-amd64.policy b/trunks/trunksd-seccomp-arm64.policy
index 225e2ed..7581d3c 100644
--- a/trunks/trunksd-seccomp-amd64.policy
+++ b/trunks/trunksd-seccomp-arm64.policy
@@ -14,7 +14,6 @@
# limitations under the License.
#
-# Tested on lumpy
gettid: 1
getuid: 1
geteuid: 1
@@ -26,31 +25,25 @@ getresgid: 1
clock_getres: 1
clock_gettime: 1
gettimeofday: 1
-time: 1
-# Allow socket(domain==PF_LOCAL) or socket(domain==PF_NETLINK)
-socket: arg0 == 0x1 || arg0 == 0x10
-socketpair: 1
-connect: 1
-getsockname: 1
-pipe: 1
-sendmsg: 1
-sendto: 1
-recvmsg: 1
-
-epoll_create: 1
-epoll_wait: 1
+epoll_create1: 1
+epoll_pwait: 1
epoll_ctl: 1
-poll: 1
+openat: 1
read: 1
write: 1
+writev: 1
close: 1
-
fstat: 1
-stat: 1
lseek: 1
fcntl: 1
+readlinkat: 1
+faccessat: 1
+pipe2: 1
+socket: 1
+connect: 1
+sendto: 1
futex: 1
@@ -58,10 +51,13 @@ restart_syscall: 1
exit: 1
exit_group: 1
rt_sigreturn: 1
+sigaltstack: 1
+personality: 1
brk: 1
mmap: 1
munmap: 1
+madvise: 1
# Allow thread creation.
mprotect: 1
@@ -69,6 +65,13 @@ clone: 1
set_robust_list: 1
# This is attempted but apparently not necessary; return EPERM.
prctl: return 1
+gettid: 1
+set_tid_address: 1
rt_sigprocmask: 1
signalfd4: 1
+ioctl: 1
+getpriority: 1
+exit: 1
+exit_group: 1
+chdir: 1
diff --git a/trunks/trunksd-seccomp-x86.policy b/trunks/trunksd-seccomp-x86.policy
index 3c5495d..575ccb8 100644
--- a/trunks/trunksd-seccomp-x86.policy
+++ b/trunks/trunksd-seccomp-x86.policy
@@ -14,7 +14,6 @@
# limitations under the License.
#
-# Tested on alex board
gettid: 1
getuid32: 1
geteuid32: 1
@@ -28,18 +27,28 @@ clock_gettime: 1
gettimeofday: 1
time: 1
+epoll_create: 1
+epoll_create1: 1
+epoll_wait: 1
+epoll_pwait: 1
+epoll_ctl: 1
+poll: 1
+
+openat: 1
read: 1
write: 1
+writev: 1
close: 1
-
-brk: 1
-mmap2: 1
-munmap: 1
-
fstat64: 1
+fstatat64: 1
stat64: 1
_llseek: 1
+lseek: 1
fcntl64: 1
+readlinkat: 1
+faccessat: 1
+pipe2: 1
+socketcall: 1
futex: 1
@@ -47,8 +56,29 @@ restart_syscall: 1
exit: 1
exit_group: 1
rt_sigreturn: 1
+sigaltstack: 1
+sigaction: 1
+personality: 1
-epoll_create: 1
-epoll_wait: 1
-epoll_ctl: 1
-poll: 1
+brk: 1
+mmap2: 1
+munmap: 1
+madvise: 1
+
+# Allow thread creation.
+mprotect: 1
+clone: 1
+set_robust_list: 1
+# This is attempted but apparently not necessary; return EPERM.
+prctl: return 1
+set_thread_area: 1
+gettid: 1
+set_tid_address: 1
+
+rt_sigprocmask: 1
+signalfd4: 1
+ioctl: 1
+getpriority: 1
+exit: 1
+exit_group: 1
+chdir: 1
diff --git a/trunks/trunksd-seccomp-x86_64.policy b/trunks/trunksd-seccomp-x86_64.policy
new file mode 100644
index 0000000..aa8650b
--- /dev/null
+++ b/trunks/trunksd-seccomp-x86_64.policy
@@ -0,0 +1,83 @@
+#
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+gettid: 1
+getuid: 1
+geteuid: 1
+getgid: 1
+getegid: 1
+getresuid: 1
+getresgid: 1
+
+clock_getres: 1
+clock_gettime: 1
+gettimeofday: 1
+time: 1
+
+epoll_create: 1
+epoll_create1: 1
+epoll_wait: 1
+epoll_pwait: 1
+epoll_ctl: 1
+poll: 1
+
+openat: 1
+read: 1
+write: 1
+writev: 1
+close: 1
+fstat: 1
+stat: 1
+lseek: 1
+fcntl: 1
+readlinkat: 1
+faccessat: 1
+pipe2: 1
+socket: 1
+connect: 1
+
+futex: 1
+
+restart_syscall: 1
+exit: 1
+exit_group: 1
+rt_sigaction: 1
+rt_sigreturn: 1
+sigaltstack: 1
+personality: 1
+
+brk: 1
+mmap: 1
+munmap: 1
+madvise: 1
+
+# Allow thread creation.
+mprotect: 1
+clone: 1
+set_robust_list: 1
+# This is attempted but apparently not necessary; return EPERM.
+prctl: return 1
+set_thread_area: 1
+gettid: 1
+set_tid_address: 1
+
+rt_sigprocmask: 1
+signalfd4: 1
+ioctl: 1
+getpriority: 1
+exit: 1
+exit_group: 1
+chdir: 1
diff --git a/trunks/trunksd-simulator.rc b/trunks/trunksd-simulator.rc
new file mode 100644
index 0000000..4ac8ca9
--- /dev/null
+++ b/trunks/trunksd-simulator.rc
@@ -0,0 +1,8 @@
+on post-fs-data
+ mkdir /data/misc/trunksd 0700 system system
+
+service trunksd /system/bin/trunksd --simulator
+ class late_start
+ user root
+ group root
+ oneshot
diff --git a/trunks/trunksd.cc b/trunks/trunksd.cc
index 4eb7f05..ae3c3fd 100644
--- a/trunks/trunksd.cc
+++ b/trunks/trunksd.cc
@@ -20,28 +20,35 @@
#include <base/bind.h>
#include <base/command_line.h>
#include <base/threading/thread.h>
-#include <brillo/daemons/dbus_daemon.h>
#include <brillo/minijail/minijail.h>
#include <brillo/syslog_logging.h>
#include <brillo/userdb_utils.h>
#include "trunks/background_command_transceiver.h"
-#include "trunks/dbus_interface.h"
#include "trunks/resource_manager.h"
#include "trunks/tpm_handle.h"
#include "trunks/tpm_simulator_handle.h"
+#if defined(USE_BINDER_IPC)
+#include "trunks/trunks_binder_service.h"
+#else
+#include "trunks/trunks_dbus_service.h"
+#endif
#include "trunks/trunks_factory_impl.h"
#include "trunks/trunks_ftdi_spi.h"
-#include "trunks/trunks_service.h"
-
-using brillo::dbus_utils::AsyncEventSequencer;
namespace {
const uid_t kRootUID = 0;
+#if defined(__ANDROID__)
+const char kTrunksUser[] = "system";
+const char kTrunksGroup[] = "system";
+const char kTrunksSeccompPath[] =
+ "/system/usr/share/policy/trunksd-seccomp.policy";
+#else
const char kTrunksUser[] = "trunks";
const char kTrunksGroup[] = "trunks";
const char kTrunksSeccompPath[] = "/usr/share/policy/trunksd-seccomp.policy";
+#endif
const char kBackgroundThreadName[] = "trunksd_background_thread";
void InitMinijailSandbox() {
@@ -49,7 +56,7 @@ void InitMinijailSandbox() {
gid_t trunks_gid;
CHECK(brillo::userdb::GetUserInfo(kTrunksUser, &trunks_uid, &trunks_gid))
<< "Error getting trunks uid and gid.";
- CHECK_EQ(getuid(), kRootUID) << "Trunks Daemon not initialized as root.";
+ CHECK_EQ(getuid(), kRootUID) << "trunksd not initialized as root.";
brillo::Minijail* minijail = brillo::Minijail::GetInstance();
struct minijail* jail = minijail->New();
minijail->DropRoot(jail, kTrunksUser, kTrunksGroup);
@@ -57,59 +64,13 @@ void InitMinijailSandbox() {
minijail->Enter(jail);
minijail->Destroy(jail);
CHECK_EQ(getuid(), trunks_uid)
- << "TrunksDaemon was not able to drop to trunks user.";
+ << "trunksd was not able to drop user privilege.";
CHECK_EQ(getgid(), trunks_gid)
- << "TrunksDaemon was not able to drop to trunks group.";
+ << "trunksd was not able to drop group privilege.";
}
} // namespace
-class TrunksDaemon : public brillo::DBusServiceDaemon {
- public:
- explicit TrunksDaemon(trunks::CommandTransceiver* transceiver) :
- brillo::DBusServiceDaemon(trunks::kTrunksServiceName) {
- transceiver_.reset(transceiver);
- background_thread_.reset(new base::Thread(kBackgroundThreadName));
- CHECK(background_thread_->Start());
- // Chain together command transceivers:
- // [IPC] --> TrunksService --> BackgroundCommandTransceiver -->
- // ResourceManager --> TpmHandle --> [TPM]
- factory_.reset(new trunks::TrunksFactoryImpl(transceiver_.get()));
- resource_manager_.reset(new trunks::ResourceManager(
- *factory_,
- transceiver_.get()));
- background_thread_->task_runner()->PostNonNestableTask(
- FROM_HERE,
- base::Bind(&trunks::ResourceManager::Initialize,
- base::Unretained(resource_manager_.get())));
- background_transceiver_.reset(
- new trunks::BackgroundCommandTransceiver(
- resource_manager_.get(),
- background_thread_->task_runner()));
- }
-
- protected:
- void RegisterDBusObjectsAsync(AsyncEventSequencer* sequencer) override {
- trunks_service_.reset(new trunks::TrunksService(
- bus_,
- background_transceiver_.get()));
- trunks_service_->Register(
- sequencer->GetHandler("Register() failed.", true));
- }
-
-
- private:
- std::unique_ptr<trunks::TrunksService> trunks_service_;
- std::unique_ptr<trunks::CommandTransceiver> transceiver_;
- // Thread for executing TPM comands.
- std::unique_ptr<base::Thread> background_thread_;
- std::unique_ptr<trunks::TrunksFactory> factory_;
- std::unique_ptr<trunks::ResourceManager> resource_manager_;
- std::unique_ptr<trunks::CommandTransceiver> background_transceiver_;
-
- DISALLOW_COPY_AND_ASSIGN(TrunksDaemon);
-};
-
int main(int argc, char **argv) {
base::CommandLine::Init(argc, argv);
base::CommandLine *cl = base::CommandLine::ForCurrentProcess();
@@ -118,17 +79,45 @@ int main(int argc, char **argv) {
flags |= brillo::kLogToStderr;
}
brillo::InitLog(flags);
- trunks::CommandTransceiver *transceiver;
+
+ // Create a service instance before anything else so objects like
+ // AtExitManager exist.
+#if defined(USE_BINDER_IPC)
+ trunks::TrunksBinderService service;
+#else
+ trunks::TrunksDBusService service;
+#endif
+
+ // Chain together command transceivers:
+ // [IPC] --> BackgroundCommandTransceiver
+ // --> ResourceManager
+ // --> TpmHandle
+ // --> [TPM]
+ trunks::CommandTransceiver *low_level_transceiver;
if (cl->HasSwitch("ftdi")) {
- transceiver = new trunks::TrunksFtdiSpi();
+ LOG(INFO) << "Sending commands to FTDI SPI.";
+ low_level_transceiver = new trunks::TrunksFtdiSpi();
} else if (cl->HasSwitch("simulator")) {
- transceiver = new trunks::TpmSimulatorHandle();
+ LOG(INFO) << "Sending commands to simulator.";
+ low_level_transceiver = new trunks::TpmSimulatorHandle();
} else {
- transceiver = new trunks::TpmHandle();
+ low_level_transceiver = new trunks::TpmHandle();
}
- CHECK(transceiver->Init()) << "Error initializing transceiver";
- TrunksDaemon daemon(transceiver);
+ CHECK(low_level_transceiver->Init())
+ << "Error initializing TPM communication.";
+ // This needs to be *after* opening the TPM handle and *before* starting the
+ // background thread.
InitMinijailSandbox();
- LOG(INFO) << "Trunks Service Started";
- return daemon.Run();
+ base::Thread background_thread(kBackgroundThreadName);
+ CHECK(background_thread.Start()) << "Failed to start background thread.";
+ trunks::TrunksFactoryImpl factory(low_level_transceiver);
+ trunks::ResourceManager resource_manager(factory, low_level_transceiver);
+ background_thread.task_runner()->PostNonNestableTask(
+ FROM_HERE, base::Bind(&trunks::ResourceManager::Initialize,
+ base::Unretained(&resource_manager)));
+ trunks::BackgroundCommandTransceiver background_transceiver(
+ &resource_manager, background_thread.task_runner());
+ service.set_transceiver(&background_transceiver);
+ LOG(INFO) << "Trunks service started.";
+ return service.Run();
}
diff --git a/trunks/trunksd.rc b/trunks/trunksd.rc
new file mode 100644
index 0000000..f672515
--- /dev/null
+++ b/trunks/trunksd.rc
@@ -0,0 +1,8 @@
+on post-fs-data
+ mkdir /data/misc/trunksd 0700 system system
+
+service trunksd /system/bin/trunksd
+ class late_start
+ user root
+ group root
+ oneshot