aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp25
-rw-r--r--BUILD15
-rw-r--r--OWNERS4
-rw-r--r--libnos/Android.bp12
-rw-r--r--libnos/BUILD3
-rw-r--r--libnos/NuggetClient.cpp9
-rw-r--r--libnos/debug.cpp1
-rw-r--r--libnos/feature.cpp44
-rw-r--r--libnos/generator/Android.bp5
-rw-r--r--libnos/generator/BUILD4
-rw-r--r--libnos/generator/main.cpp36
-rw-r--r--libnos/generator/test/Android.bp18
-rw-r--r--libnos/generator/test/test.cpp4
-rw-r--r--libnos/include/nos/AppClient.h15
-rw-r--r--libnos/include/nos/NuggetClient.h16
-rw-r--r--libnos/include/nos/NuggetClientInterface.h17
-rw-r--r--libnos/include/nos/feature.h29
-rw-r--r--libnos/test/include/nos/MockNuggetClient.h3
-rw-r--r--libnos_datagram/Android.bp6
-rw-r--r--libnos_datagram/BUILD10
-rw-r--r--libnos_datagram/citadel.cpp (renamed from libnos_datagram/citadel.c)130
-rw-r--r--libnos_transport/Android.bp1
-rw-r--r--libnos_transport/BUILD1
-rw-r--r--libnos_transport/test/test.cpp2
-rw-r--r--libnos_transport/transport.c68
-rw-r--r--nugget/include/app_nugget.h88
-rw-r--r--nugget/include/application.h12
-rw-r--r--nugget/include/citadel_events.h42
-rw-r--r--nugget/include/feature_map.h67
-rw-r--r--nugget/include/hals/common.h79
-rw-r--r--nugget/include/hals/weaver.h119
-rw-r--r--nugget/include/nos/device.h (renamed from libnos_datagram/include/nos/device.h)19
-rw-r--r--nugget/proto/Android.bp5
-rw-r--r--nugget/proto/nugget/app/avb/Android.bp18
-rw-r--r--nugget/proto/nugget/app/avb/avb.proto8
-rw-r--r--nugget/proto/nugget/app/identity/Android.bp24
-rw-r--r--nugget/proto/nugget/app/identity/identity.proto43
-rw-r--r--nugget/proto/nugget/app/identity/identity_types.proto1
-rw-r--r--nugget/proto/nugget/app/keymaster/Android.bp24
-rw-r--r--nugget/proto/nugget/app/keymaster/ctdl/Android.bp75
-rw-r--r--nugget/proto/nugget/app/keymaster/ctdl/keymaster.options21
-rw-r--r--nugget/proto/nugget/app/keymaster/ctdl/keymaster.proto658
-rw-r--r--nugget/proto/nugget/app/keymaster/ctdl/keymaster_defs.proto340
-rw-r--r--nugget/proto/nugget/app/keymaster/ctdl/keymaster_types.options12
-rw-r--r--nugget/proto/nugget/app/keymaster/ctdl/keymaster_types.proto136
-rw-r--r--nugget/proto/nugget/app/keymaster/keymaster.proto44
-rw-r--r--nugget/proto/nugget/app/keymaster/keymaster_defs.proto7
-rw-r--r--nugget/proto/nugget/app/keymaster/keymaster_types.options2
-rw-r--r--nugget/proto/nugget/app/weaver/Android.bp18
49 files changed, 2219 insertions, 121 deletions
diff --git a/Android.bp b/Android.bp
index 009de4c..f924e41 100644
--- a/Android.bp
+++ b/Android.bp
@@ -87,7 +87,7 @@ GEN_SERVICE_SOURCE = GEN_SERVICE + " --nos-client-cpp_out=source:$(genDir) "
GEN_SERVICE_HEADER = GEN_SERVICE + " --nos-client-cpp_out=header:$(genDir) "
GEN_SERVICE_MOCK = GEN_SERVICE + " --nos-client-cpp_out=mock:$(genDir) "
-// A special target to be statically linkeed into recovery which is a system
+// A special target to be statically linked into recovery which is a system
// (not vendor) component.
cc_library_static {
name: "libnos_for_recovery",
@@ -100,7 +100,6 @@ cc_library_static {
export_include_dirs: [
"nugget/include",
"libnos/include",
- "libnos_datagram/include",
"libnos_transport/include",
],
srcs: [
@@ -113,7 +112,7 @@ cc_library_static {
],
}
-// A special target to be statically linkeed into fastboot hal.
+// A special target to be statically linked into fastboot hal.
cc_library_static {
name: "libnos_for_fastboot",
recovery: true,
@@ -126,7 +125,6 @@ cc_library_static {
export_include_dirs: [
"nugget/include",
"libnos/include",
- "libnos_datagram/include",
"libnos_transport/include",
],
srcs: [
@@ -139,7 +137,7 @@ cc_library_static {
],
}
-// A special target to be statically linkeed into recovery which is a system
+// A special target to be statically linked into recovery which is a system
// (not vendor) component.
cc_library_static {
name: "libnos_citadel_for_recovery",
@@ -150,14 +148,17 @@ cc_library_static {
],
srcs: [
":libnos_client",
- "libnos_datagram/citadel.c",
+ "libnos_datagram/citadel.cpp",
],
static_libs: [
"libnos_for_recovery",
],
+ shared_libs: [
+ "libbase",
+ ],
}
-// A special target to be statically linkeed into fastboot hal.
+// A special target to be statically linked into fastboot hal.
cc_library_static {
name: "libnos_citadel_for_fastboot",
recovery: true,
@@ -168,11 +169,14 @@ cc_library_static {
],
srcs: [
":libnos_client",
- "libnos_datagram/citadel.c",
+ "libnos_datagram/citadel.cpp",
],
static_libs: [
"libnos_for_fastboot",
],
+ shared_libs: [
+ "libbase",
+ ],
}
// Language and vendor related defaults
@@ -184,6 +188,7 @@ cc_defaults {
"-Wall",
"-Wextra",
"-Werror",
+ "-Wno-gcc-compat",
"-Wno-gnu-zero-variadic-macro-arguments",
"-Wno-zero-length-array",
],
@@ -215,5 +220,7 @@ cc_library {
"libnos_client_defaults",
"nos_cc_defaults",
],
- shared_libs: ["libnos_datagram_citadel"],
+ shared_libs: [
+ "libnos_datagram_citadel",
+ ],
}
diff --git a/BUILD b/BUILD
index 74f705e..c9f246f 100644
--- a/BUILD
+++ b/BUILD
@@ -6,10 +6,25 @@ cc_library(
"nugget/include/application.h",
"nugget/include/avb.h",
"nugget/include/citadel_events.h",
+ "nugget/include/feature_map.h",
"nugget/include/flash_layout.h",
"nugget/include/keymaster.h",
+ "nugget/include/nos/device.h",
"nugget/include/signed_header.h",
],
+ deps = [
+ "nos_headers_hals",
+ ],
+ strip_include_prefix = "nugget/include/",
+ visibility = ["//visibility:public"],
+)
+
+cc_library(
+ name = "nos_headers_hals",
+ hdrs = [
+ "nugget/include/hals/common.h",
+ "nugget/include/hals/weaver.h",
+ ],
strip_include_prefix = "nugget/include/",
visibility = ["//visibility:public"],
)
diff --git a/OWNERS b/OWNERS
index 3505355..2110bb5 100644
--- a/OWNERS
+++ b/OWNERS
@@ -2,6 +2,6 @@
# or people with more than 10 commits last year.
# Please update this list if you find better owner candidates.
wfrichar@google.com
+tommychiu@google.com
+zhakevin@google.com
kroot@google.com
-dybertwang@google.com
-byi@google.com
diff --git a/libnos/Android.bp b/libnos/Android.bp
index f68df27..2fdb924 100644
--- a/libnos/Android.bp
+++ b/libnos/Android.bp
@@ -30,9 +30,17 @@ cc_library {
],
defaults: ["nos_cc_host_supported_defaults"],
header_libs: ["nos_headers"],
- shared_libs: ["libnos_datagram"],
export_include_dirs: ["include"],
- export_shared_lib_headers: ["libnos_datagram"],
+}
+
+cc_library {
+ name: "libnos_feature",
+ srcs: [
+ "feature.cpp",
+ ],
+ defaults: ["nos_cc_host_supported_defaults"],
+ header_libs: ["nos_headers"],
+ export_include_dirs: ["include"],
}
// This part of libnos must be linked with the target's implementation of
diff --git a/libnos/BUILD b/libnos/BUILD
index a03ec8f..627b721 100644
--- a/libnos/BUILD
+++ b/libnos/BUILD
@@ -3,12 +3,14 @@ cc_library(
srcs = [
"NuggetClient.cpp",
"debug.cpp",
+ "feature.cpp",
],
hdrs = [
"include/nos/AppClient.h",
"include/nos/NuggetClient.h",
"include/nos/NuggetClientInterface.h",
"include/nos/debug.h",
+ "include/nos/feature.h",
],
includes = [
"include",
@@ -16,7 +18,6 @@ cc_library(
visibility = ["//visibility:public"],
deps = [
"//host/generic:nos_headers",
- "//host/generic/libnos_datagram",
"//host/generic/libnos_transport",
],
)
diff --git a/libnos/NuggetClient.cpp b/libnos/NuggetClient.cpp
index c361463..d27e19b 100644
--- a/libnos/NuggetClient.cpp
+++ b/libnos/NuggetClient.cpp
@@ -84,6 +84,15 @@ uint32_t NuggetClient::CallApp(uint32_t appId, uint16_t arg,
return status_code;
}
+uint32_t NuggetClient::CallApp(uint32_t appId, uint16_t arg,
+ const void* req_ptr, uint32_t req_len,
+ void* resp_ptr, uint32_t* resp_len) {
+ if (!open_) return APP_ERROR_IO;
+
+ return nos_call_application(&device_, appId, arg, (const uint8_t*)req_ptr,
+ req_len, (uint8_t*)resp_ptr, resp_len);
+}
+
uint32_t NuggetClient::Reset() const {
if (!open_)
diff --git a/libnos/debug.cpp b/libnos/debug.cpp
index 0398d54..cc8a2c2 100644
--- a/libnos/debug.cpp
+++ b/libnos/debug.cpp
@@ -35,6 +35,7 @@ std::string StatusCodeString(uint32_t code) {
ErrorString_helper(APP_ERROR_CHECKSUM)
ErrorString_helper(APP_ERROR_BUSY)
ErrorString_helper(APP_ERROR_TIMEOUT)
+ ErrorString_helper(APP_ERROR_NOT_READY)
default:
if (code >= APP_LINE_NUMBER_BASE && code < MAX_APP_STATUS) {
return "APP_LINE_NUMBER " + std::to_string(code - APP_LINE_NUMBER_BASE);
diff --git a/libnos/feature.cpp b/libnos/feature.cpp
new file mode 100644
index 0000000..6651319
--- /dev/null
+++ b/libnos/feature.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 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 <nos/feature.h>
+
+namespace nos {
+
+bool has_feature(NuggetClientInterface& nug, enum feature_support_app_id app_id,
+ uint32_t feature) {
+ uint32_t feature_id = (app_id << TA_OFFSET) | (feature & FEATURE_MASK);
+
+ std::vector<uint8_t> req(sizeof(feature_id));
+ memcpy(req.data(), &feature_id, sizeof(feature_id));
+
+ std::vector<uint8_t> resp;
+ resp.reserve(sizeof(uint8_t));
+
+ uint32_t rv =
+ nug.CallApp(APP_ID_NUGGET, NUGGET_PARAM_GET_FEATURE_SUPPORT, req, &resp);
+ if (rv != APP_SUCCESS) {
+ return false;
+ }
+
+ if (resp.size() < 1) {
+ return false; // I guess?
+ }
+
+ return !!resp[0];
+}
+
+} // namespace nos
diff --git a/libnos/generator/Android.bp b/libnos/generator/Android.bp
index a7cc964..9e5a688 100644
--- a/libnos/generator/Android.bp
+++ b/libnos/generator/Android.bp
@@ -30,6 +30,9 @@ cc_binary_host {
"nos_proto_defaults",
"nos_cc_defaults",
],
- static_libs: ["libnosprotos"],
+ static_libs: [
+ "libabsl_host",
+ "libnosprotos",
+ ],
shared_libs: ["libprotoc"],
}
diff --git a/libnos/generator/BUILD b/libnos/generator/BUILD
index fc8bc33..1f9ed42 100644
--- a/libnos/generator/BUILD
+++ b/libnos/generator/BUILD
@@ -3,12 +3,10 @@ cc_binary(
srcs = [
"main.cpp",
],
- copts = [
- "-std=c++11",
- ],
visibility = ["//visibility:public"],
deps = [
"//host/generic/nugget/proto:nugget_protobuf_options_cc_proto",
"@com_google_protobuf//:protoc_lib",
+ "@com_google_absl//absl/strings",
],
)
diff --git a/libnos/generator/main.cpp b/libnos/generator/main.cpp
index 04dfa89..51acfa2 100644
--- a/libnos/generator/main.cpp
+++ b/libnos/generator/main.cpp
@@ -24,17 +24,16 @@
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
-#include <google/protobuf/stubs/strutil.h>
+#include "absl/strings/strip.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_join.h"
+#include "absl/strings/str_split.h"
#include "nugget/protobuf/options.pb.h"
using ::google::protobuf::FileDescriptor;
-using ::google::protobuf::JoinStrings;
using ::google::protobuf::MethodDescriptor;
using ::google::protobuf::ServiceDescriptor;
-using ::google::protobuf::Split;
-using ::google::protobuf::SplitStringUsing;
-using ::google::protobuf::StripSuffixString;
using ::google::protobuf::compiler::CodeGenerator;
using ::google::protobuf::compiler::OutputDirectory;
using ::google::protobuf::io::Printer;
@@ -61,8 +60,8 @@ std::string validateServiceOptions(const ServiceDescriptor& service) {
template <typename Descriptor>
std::vector<std::string> Packages(const Descriptor& descriptor) {
- std::vector<std::string> namespaces;
- SplitStringUsing(descriptor.full_name(), ".", &namespaces);
+ std::vector<std::string> namespaces =
+ absl::StrSplit(descriptor.full_name(), '.');
namespaces.pop_back(); // just take the package
return namespaces;
}
@@ -73,23 +72,21 @@ std::string FullyQualifiedIdentifier(const Descriptor& descriptor) {
if (namespaces.empty()) {
return "::" + descriptor.name();
} else {
- std::string namespace_path;
- JoinStrings(namespaces, "::", &namespace_path);
- return "::" + namespace_path + "::" + descriptor.name();
+ return absl::StrCat("::", absl::StrJoin(namespaces, "::"), "::", descriptor.name());
}
}
template <typename Descriptor>
std::string FullyQualifiedHeader(const Descriptor& descriptor) {
- const auto packages = Packages(descriptor);
- const auto file = Split(descriptor.file()->name(), "/").back();
- const auto header = StripSuffixString(file, ".proto") + ".pb.h";
+ const std::vector<std::string> packages = Packages(descriptor);
+ const std::vector<std::string_view> path_components =
+ absl::StrSplit(descriptor.file()->name(), '/');
+ const std::string file(path_components.back());
+ const std::string header = absl::StrCat(absl::StripSuffix(file, ".proto"), ".pb.h");
if (packages.empty()) {
return header;
} else {
- std::string package_path;
- JoinStrings(packages, "/", &package_path);
- return package_path + "/" + header;
+ return absl::StrCat(absl::StrJoin(packages, "/"), "/", header);
}
}
@@ -240,7 +237,7 @@ void GenerateClientSource(Printer& printer, const ServiceDescriptor& service) {
methodVars.insert(vars.begin(), vars.end());
printer.Print(methodVars, R"(
uint32_t $class$::$method_name$(const $method_input_type$& request, $method_output_type$* response) {
- const size_t request_size = request.ByteSize();
+ const size_t request_size = request.ByteSizeLong();
if (request_size > $max_request_size$) {
return APP_ERROR_TOO_MUCH;
}
@@ -270,6 +267,8 @@ uint32_t $class$::$method_name$(const $method_input_type$& request, $method_outp
class CppNuggetServiceClientGenerator : public CodeGenerator {
public:
CppNuggetServiceClientGenerator() = default;
+ CppNuggetServiceClientGenerator(const CppNuggetServiceClientGenerator&) = delete;
+ CppNuggetServiceClientGenerator& operator=(const CppNuggetServiceClientGenerator&) = delete;
~CppNuggetServiceClientGenerator() override = default;
bool Generate(const FileDescriptor* file,
@@ -307,9 +306,6 @@ public:
return true;
}
-
-private:
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CppNuggetServiceClientGenerator);
};
} // namespace
diff --git a/libnos/generator/test/Android.bp b/libnos/generator/test/Android.bp
index 30287aa..e0c4d32 100644
--- a/libnos/generator/test/Android.bp
+++ b/libnos/generator/test/Android.bp
@@ -26,7 +26,11 @@ package {
genrule {
name: "nos_generator_test_service_genc++",
out: ["Hello.client.cpp"],
- srcs: ["nos/generator/test/test.proto"],
+ srcs: [
+ "nos/generator/test/test.proto",
+ ":nugget_options_proto",
+ ":libprotobuf-internal-protos",
+ ],
tools: ["aprotoc", "protoc-gen-nos-client-cpp"],
cmd: GEN_SERVICE_SOURCE + "-Iexternal/nos/host/generic/libnos/generator/test",
}
@@ -34,7 +38,11 @@ genrule {
genrule {
name: "nos_generator_test_service_genc++_headers",
out: ["Hello.client.h"],
- srcs: ["nos/generator/test/test.proto"],
+ srcs: [
+ "nos/generator/test/test.proto",
+ ":nugget_options_proto",
+ ":libprotobuf-internal-protos",
+ ],
tools: ["aprotoc", "protoc-gen-nos-client-cpp"],
cmd: GEN_SERVICE_HEADER + "-Iexternal/nos/host/generic/libnos/generator/test",
}
@@ -42,7 +50,11 @@ genrule {
genrule {
name: "nos_generator_test_service_genc++_mock",
out: ["MockHello.client.h"],
- srcs: ["nos/generator/test/test.proto"],
+ srcs: [
+ "nos/generator/test/test.proto",
+ ":nugget_options_proto",
+ ":libprotobuf-internal-protos",
+ ],
tools: ["aprotoc", "protoc-gen-nos-client-cpp"],
cmd: GEN_SERVICE_MOCK + "-Iexternal/nos/host/generic/libnos/generator/test",
}
diff --git a/libnos/generator/test/test.cpp b/libnos/generator/test/test.cpp
index 4542c88..f6a4835 100644
--- a/libnos/generator/test/test.cpp
+++ b/libnos/generator/test/test.cpp
@@ -79,7 +79,7 @@ TEST(GeneratedServiceClientTest, DataSuccessfullyExchanged) {
GreetResponse response;
response.set_greeting("Hello, Tester age 78");
- std::vector<uint8_t> responseBytes(response.ByteSize());
+ std::vector<uint8_t> responseBytes(response.ByteSizeLong());
ASSERT_TRUE(response.SerializeToArray(responseBytes.data(), responseBytes.size()));
EXPECT_CALL(client, CallApp(_, _, DecodesToProtoMessage(request), _))
@@ -114,7 +114,7 @@ TEST(GeneratedServiceClientTest, AppErrorsPropagatedWithoutResponseDecode) {
GreetResponse response;
response.set_greeting("Ignore me");
- std::vector<uint8_t> responseBytes(response.ByteSize());
+ std::vector<uint8_t> responseBytes(response.ByteSizeLong());
ASSERT_TRUE(response.SerializeToArray(responseBytes.data(), responseBytes.size()));
EXPECT_CALL(client, CallApp(_, _, _, _))
diff --git a/libnos/include/nos/AppClient.h b/libnos/include/nos/AppClient.h
index 0a35d82..1299100 100644
--- a/libnos/include/nos/AppClient.h
+++ b/libnos/include/nos/AppClient.h
@@ -51,6 +51,21 @@ public:
return _client.CallApp(_appId, arg, request, response);
}
+ /**
+ * Call the app.
+ *
+ * @param arg Argument to pass to the app.
+ * @param req_ptr Data to send to the app.
+ * @param req_len Number of bytes to send to the app.
+ * @param resp_ptr Buffer to receive data from the app.
+ * @param resp_len In: Max number of bytes to receive from the app.
+ * Out: Actual number of bytes received from the app.
+ */
+ uint32_t Call(uint16_t arg, const void* req_ptr, uint32_t req_len,
+ void* resp_ptr, uint32_t* resp_len) {
+ return _client.CallApp(_appId, arg, req_ptr, req_len, resp_ptr,
+ resp_len);
+ }
private:
NuggetClientInterface& _client;
diff --git a/libnos/include/nos/NuggetClient.h b/libnos/include/nos/NuggetClient.h
index 9484bd8..c4dc1cb 100644
--- a/libnos/include/nos/NuggetClient.h
+++ b/libnos/include/nos/NuggetClient.h
@@ -73,6 +73,22 @@ public:
std::vector<uint8_t>* response) override;
/**
+ * Call into an app running on Nugget.
+ *
+ * @param app_id The ID of the app to call.
+ * @param arg Argument to pass to the app.
+ * @param req_ptr Data to send to the app.
+ * @param req_len Number of bytes to send to the app.
+ * @param resp_ptr Buffer to receive data from the app.
+ * @param resp_len In: Max number of bytes to receive from the app.
+ * Out: Actual number of bytes received from the app.
+ * @return Status code from the app.
+ */
+ uint32_t CallApp(uint32_t appId, uint16_t arg, const void* req_ptr,
+ uint32_t req_len, void* resp_ptr,
+ uint32_t* resp_len) override;
+
+ /**
* Reset the device. Use with caution; context may be lost.
*/
uint32_t Reset() const override;
diff --git a/libnos/include/nos/NuggetClientInterface.h b/libnos/include/nos/NuggetClientInterface.h
index 8d78185..e14c794 100644
--- a/libnos/include/nos/NuggetClientInterface.h
+++ b/libnos/include/nos/NuggetClientInterface.h
@@ -58,6 +58,23 @@ public:
virtual uint32_t CallApp(uint32_t appId, uint16_t arg,
const std::vector<uint8_t>& request,
std::vector<uint8_t>* response) = 0;
+
+ /**
+ * Call into an app running on Nugget.
+ *
+ * @param app_id The ID of the app to call.
+ * @param arg Argument to pass to the app.
+ * @param req_ptr Data to send to the app.
+ * @param req_len Number of bytes to send to the app.
+ * @param resp_ptr Buffer to receive data from the app.
+ * @param resp_len In: Max number of bytes to receive from the app.
+ * Out: Actual number of bytes received from the app.
+ * @return Status code from the app.
+ */
+ virtual uint32_t CallApp(uint32_t appId, uint16_t arg, const void* req_ptr,
+ uint32_t req_len, void* resp_ptr,
+ uint32_t* resp_len) = 0;
+
/**
* Reset the device. Use with caution; context may be lost.
*/
diff --git a/libnos/include/nos/feature.h b/libnos/include/nos/feature.h
new file mode 100644
index 0000000..0ed6d0a
--- /dev/null
+++ b/libnos/include/nos/feature.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#pragma once
+
+#include <app_nugget.h>
+#include <application.h>
+#include <feature_map.h>
+#include <nos/NuggetClientInterface.h>
+
+namespace nos {
+
+bool has_feature(NuggetClientInterface& nug, enum feature_support_app_id app_id,
+ uint32_t feature);
+
+} // namespace nos
diff --git a/libnos/test/include/nos/MockNuggetClient.h b/libnos/test/include/nos/MockNuggetClient.h
index 48814c9..19e7f00 100644
--- a/libnos/test/include/nos/MockNuggetClient.h
+++ b/libnos/test/include/nos/MockNuggetClient.h
@@ -33,6 +33,9 @@ struct MockNuggetClient : public NuggetClientInterface {
MOCK_METHOD4(CallApp, uint32_t(uint32_t, uint16_t,
const std::vector<uint8_t>&,
std::vector<uint8_t>*));
+ MOCK_METHOD6(CallApp, uint32_t(uint32_t, uint16_t,
+ const void*, uint32_t,
+ void*, uint32_t*));
MOCK_CONST_METHOD0(Reset, uint32_t());
};
diff --git a/libnos_datagram/Android.bp b/libnos_datagram/Android.bp
index 0176e00..f854bd8 100644
--- a/libnos_datagram/Android.bp
+++ b/libnos_datagram/Android.bp
@@ -36,15 +36,17 @@ license {
cc_library {
name: "libnos_datagram",
defaults: ["nos_cc_host_supported_defaults"],
- export_include_dirs: ["include"],
}
cc_library {
name: "libnos_datagram_citadel",
- srcs: ["citadel.c"],
+ srcs: ["citadel.cpp"],
+ header_libs: ["nos_headers"],
defaults: ["nos_cc_defaults"],
shared_libs: [
+ "libbase",
"liblog",
+ "libnos_transport",
"libnos_datagram",
],
}
diff --git a/libnos_datagram/BUILD b/libnos_datagram/BUILD
deleted file mode 100644
index e6f029c..0000000
--- a/libnos_datagram/BUILD
+++ /dev/null
@@ -1,10 +0,0 @@
-cc_library(
- name = "libnos_datagram",
- hdrs = [
- "include/nos/device.h",
- ],
- includes = [
- "./include",
- ],
- visibility = ["//visibility:public"],
-)
diff --git a/libnos_datagram/citadel.c b/libnos_datagram/citadel.cpp
index 7d1d893..199635c 100644
--- a/libnos_datagram/citadel.c
+++ b/libnos_datagram/citadel.cpp
@@ -35,6 +35,9 @@
#include <sys/types.h>
#include <unistd.h>
+#include <android-base/properties.h>
+#include <application.h>
+
/*****************************************************************************/
/* Ideally, this should be in <linux/citadel.h> */
#define CITADEL_IOC_MAGIC 'c'
@@ -43,14 +46,33 @@ struct citadel_ioc_tpm_datagram {
__u32 len;
__u32 command;
};
+
+/* GSA nos call request struct */
+struct gsa_ioc_nos_call_req {
+ __u8 app_id;
+ __u8 reserved;
+ __u16 params;
+ __u32 arg_len;
+ __u64 buf;
+ __u32 reply_len;
+ __u32 call_status;
+};
+
#define CITADEL_IOC_TPM_DATAGRAM _IOW(CITADEL_IOC_MAGIC, 1, \
struct citadel_ioc_tpm_datagram)
#define CITADEL_IOC_RESET _IO(CITADEL_IOC_MAGIC, 2)
+#define GSC_IOC_GSA_NOS_CALL _IOW(CITADEL_IOC_MAGIC, 3, \
+ struct gsa_ioc_nos_call_req)
/*****************************************************************************/
#define DEV_CITADEL "/dev/citadel0"
#define DEV_DAUNTLESS "/dev/gsc0"
+/* Allocate 4KB buffer for GSA mbox data transmission */
+#define MAX_GSA_NOS_CALL_TRANSFER 4096
+static uint8_t gsa_nos_call_buf[MAX_GSA_NOS_CALL_TRANSFER];
+static pthread_mutex_t nos_call_buf_mutex = PTHREAD_MUTEX_INITIALIZER;
+
static pthread_mutex_t in_buf_mutex = PTHREAD_MUTEX_INITIALIZER;
static uint8_t in_buf[MAX_DEVICE_TRANSFER];
static int read_datagram(void *ctx, uint32_t command, uint8_t *buf, uint32_t len) {
@@ -206,6 +228,112 @@ static void close_device(void *ctx) {
free(ctx);
}
+/* Detect if GSA kernel support nos_call interface
+ * Returns true on success or false on failure.
+ */
+static bool detect_gsa_nos_call_interface(int fd) {
+ int ret;
+ errno = 0;
+
+ if (fd < 0) {
+ ALOGE("invalid device handle (%d)", fd);
+ return false;
+ }
+
+ /* Send app_id = 0 and params = 0 to detect GSA IOCTL interface */
+ struct gsa_ioc_nos_call_req gsa_nos_call_req = {
+ .app_id = 0,
+ .reserved = 0,
+ .params = 0,
+ .arg_len = 0,
+ .buf = (unsigned long)gsa_nos_call_buf,
+ .reply_len = 0,
+ .call_status = 0,
+ };
+
+ ret = ioctl(fd, GSC_IOC_GSA_NOS_CALL, &gsa_nos_call_req);
+ if (ret < 0) {
+ ALOGE("can't send GSA mbox command: %s", strerror(errno));
+ }
+
+ /* GSA kernel is not support GSA_NOS_CALL if return EINVAL or ENOTTY */
+ if (!errno) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+static int one_pass_call(void *ctx, uint8_t app_id, uint16_t params,
+ const uint8_t *args, uint32_t arg_len,
+ uint8_t *reply, uint32_t *reply_len,
+ uint32_t *status_code) {
+ *status_code = APP_SUCCESS;
+ int ret;
+ int fd;
+
+ struct gsa_ioc_nos_call_req gsa_nos_call_req = {
+ .app_id = app_id,
+ .reserved = 0,
+ .params = params,
+ .arg_len = arg_len,
+ .buf = (unsigned long)gsa_nos_call_buf,
+ .reply_len = *reply_len,
+ .call_status = *status_code,
+ };
+
+ ALOGD("Calling App 0x%02x with params 0x%04x", app_id, params);
+
+ if (!ctx || (arg_len && !args) ||
+ (reply_len && *reply_len && !reply) ||
+ (arg_len > MAX_GSA_NOS_CALL_TRANSFER) ||
+ (reply_len && *reply_len > MAX_GSA_NOS_CALL_TRANSFER) ||
+ !status_code) {
+ ALOGE("Invalid args to %s()", __func__);
+ return -EINVAL;
+ }
+
+ fd = *(int *)ctx;
+ if (fd < 0) {
+ ALOGE("%s: invalid device\n", __func__);
+ return -ENODEV;
+ }
+
+ /* Lock the out buffer while it is used for this transaction */
+ if (pthread_mutex_lock(&nos_call_buf_mutex) != 0) {
+ ALOGE("%s: failed to lock nos_call_buf_mutex: %s", __func__, strerror(errno));
+ return -errno;
+ }
+
+ if (arg_len) {
+ memcpy(gsa_nos_call_buf, args, arg_len);
+ }
+
+ ret = ioctl(fd, GSC_IOC_GSA_NOS_CALL, &gsa_nos_call_req);
+ if (ret < 0) {
+ ALOGE("can't send GSA mbox command: %s", strerror(errno));
+ goto exit;
+ }
+
+ *status_code = gsa_nos_call_req.call_status;
+ if (reply_len != NULL) {
+ *reply_len = gsa_nos_call_req.reply_len;
+ if (*reply_len) {
+ memcpy(reply, gsa_nos_call_buf, *reply_len);
+ }
+ }
+
+exit:
+ if (pthread_mutex_unlock(&nos_call_buf_mutex) != 0) {
+ ALOGE("%s: failed to unlock nos_call_buf_mutex: %s", __func__,
+ strerror(errno));
+ return -errno;
+ }
+
+ ALOGD("App 0x%02x returning 0x%x", app_id, *status_code);
+ return ret;
+}
+
static const char *default_device(void) {
struct stat statbuf;
int rv;
@@ -256,5 +384,7 @@ int nos_device_open(const char *device_name, struct nos_device *dev) {
dev->ops.wait_for_interrupt = wait_for_interrupt;
dev->ops.reset = reset;
dev->ops.close = close_device;
+ dev->ops.one_pass_call = one_pass_call;
+ dev->use_one_pass_call = detect_gsa_nos_call_interface(fd);
return 0;
}
diff --git a/libnos_transport/Android.bp b/libnos_transport/Android.bp
index 1dd8992..ee519c5 100644
--- a/libnos_transport/Android.bp
+++ b/libnos_transport/Android.bp
@@ -47,7 +47,6 @@ cc_library {
shared_libs: [
"libbase",
"liblog",
- "libnos_datagram",
],
export_include_dirs: ["include"],
}
diff --git a/libnos_transport/BUILD b/libnos_transport/BUILD
index 9fc9017..0d70a0d 100644
--- a/libnos_transport/BUILD
+++ b/libnos_transport/BUILD
@@ -14,7 +14,6 @@ cc_library(
visibility = ["//visibility:public"],
deps = [
"//host/generic:nos_headers",
- "//host/generic/libnos_datagram",
],
)
diff --git a/libnos_transport/test/test.cpp b/libnos_transport/test/test.cpp
index 1090de4..c995c60 100644
--- a/libnos_transport/test/test.cpp
+++ b/libnos_transport/test/test.cpp
@@ -201,7 +201,7 @@ ACTION(ReadStatusV42_Working) {
status->length = STATUS_MAX_LENGTH;
status->version = 42;
status->flags = STATUS_FLAG_WORKING;
- status->crc = 0xaec0;
+ status->crc = 0xf781;
status->reply_crc = 0;
}
diff --git a/libnos_transport/transport.c b/libnos_transport/transport.c
index 855b884..b3a3a40 100644
--- a/libnos_transport/transport.c
+++ b/libnos_transport/transport.c
@@ -191,7 +191,7 @@ static int get_status(const struct transport_context *ctx,
/* Check the CRC, if it fails we will retry */
if (out->crc != our_crc) {
- NLOGW("App %d status CRC mismatch: theirs=%04x ours=%04x",
+ NLOGW("App 0x%02x status CRC mismatch: theirs=%04x ours=%04x",
ctx->app_id, out->crc, our_crc);
continue;
}
@@ -227,8 +227,9 @@ static uint32_t make_ready(const struct transport_context *ctx) {
NLOGE("Failed to inspect app %d", ctx->app_id);
return APP_ERROR_IO;
}
- NLOGD("App %d inspection status=0x%08x reply_len=%d protocol=%d flags=0x%04x",
- ctx->app_id, status.status, status.reply_len, status.version, status.flags);
+ NLOGD("App 0x%02x check status=0x%08x reply_len=%d protocol=%d flags=0x%04x",
+ ctx->app_id, status.status, status.reply_len, status.version,
+ status.flags);
/* If it's already idle then we're ready to proceed */
if (status.status == APP_STATUS_IDLE) {
@@ -236,7 +237,7 @@ static uint32_t make_ready(const struct transport_context *ctx) {
&& (status.flags & STATUS_FLAG_WORKING)) {
/* The app is still working when we don't expect it to be. We won't be
* able to clear the state so might need to force a reset to recover. */
- NLOGE("App %d is still working", ctx->app_id);
+ NLOGE("App 0x%02x is still working", ctx->app_id);
return APP_ERROR_BUSY;
}
return APP_SUCCESS;
@@ -259,7 +260,7 @@ static uint32_t make_ready(const struct transport_context *ctx) {
/* It's ignoring us and is still not ready, so it's broken */
if (status.status != APP_STATUS_IDLE) {
- NLOGE("App %d is not responding", ctx->app_id);
+ NLOGE("App 0x%02x is not responding", ctx->app_id);
return APP_ERROR_IO;
}
@@ -369,17 +370,20 @@ static uint32_t poll_until_done(const struct transport_context *ctx,
poll_count++;
/* Log at higher priority every 16 polls */
if ((poll_count & (16 - 1)) == 0) {
- NLOGD("App %d poll=%d status=0x%08x reply_len=%d flags=0x%04x",
- ctx->app_id, poll_count, status->status, status->reply_len, status->flags);
+ NLOGD("App 0x%02x poll=%d status=0x%08x reply_len=%d flags=0x%04x",
+ ctx->app_id, poll_count, status->status, status->reply_len,
+ status->flags);
} else {
- NLOGV("App %d poll=%d status=0x%08x reply_len=%d flags=0x%04x",
- ctx->app_id, poll_count, status->status, status->reply_len, status->flags);
+ NLOGV("App 0x%02x poll=%d status=0x%08x reply_len=%d flags=0x%04x",
+ ctx->app_id, poll_count, status->status, status->reply_len,
+ status->flags);
}
/* Check whether the app is done */
if (status->status & APP_STATUS_DONE) {
- NLOGD("App %d polled=%d status=0x%08x reply_len=%d flags=0x%04x",
- ctx->app_id, poll_count, status->status, status->reply_len, status->flags);
+ NLOGD("App 0x%02x polled=%d status=0x%08x reply_len=%d flags=0x%04x",
+ ctx->app_id, poll_count, status->status, status->reply_len,
+ status->flags);
return APP_STATUS_CODE(status->status);
}
@@ -387,7 +391,7 @@ static uint32_t poll_until_done(const struct transport_context *ctx,
if (status->version != TRANSPORT_V0
&& !(status->flags & STATUS_FLAG_WORKING)) {
/* The slave has stopped working without being done so it's misbehaving */
- NLOGE("App %d just stopped working", ctx->app_id);
+ NLOGE("App 0x%02x just stopped working", ctx->app_id);
return APP_ERROR_INTERNAL;
}
if (clock_gettime(CLOCK_MONOTONIC, &now) != 0) {
@@ -396,8 +400,8 @@ static uint32_t poll_until_done(const struct transport_context *ctx,
}
} while (timespec_before(&now, &abort_at));
- NLOGE("App %d not done after polling %d times in %d seconds",
- ctx->app_id, poll_count, POLL_LIMIT_SECONDS);
+ NLOGE("App 0x%02x not done after polling %d times in %d seconds", ctx->app_id,
+ poll_count, POLL_LIMIT_SECONDS);
return APP_ERROR_TIMEOUT;
}
@@ -440,7 +444,8 @@ static uint32_t receive_reply(const struct transport_context *ctx,
if (status->version == TRANSPORT_V0) return APP_SUCCESS;
if (crc == status->reply_crc) return APP_SUCCESS;
- NLOGW("App %d reply CRC mismatch: theirs=%04x ours=%04x", ctx->app_id, status->reply_crc, crc);
+ NLOGW("App 0x%02x reply CRC mismatch: theirs=%04x ours=%04x", ctx->app_id,
+ status->reply_crc, crc);
}
NLOGE("Unable to get valid checksum on app %d reply data", ctx->app_id);
@@ -456,6 +461,7 @@ uint32_t nos_call_application(const struct nos_device *dev,
uint8_t *reply, uint32_t *reply_len)
{
uint32_t res;
+ uint32_t status_code;
const struct transport_context ctx = {
.dev = dev,
.app_id = app_id,
@@ -472,10 +478,28 @@ uint32_t nos_call_application(const struct nos_device *dev,
return APP_ERROR_IO;
}
- NLOGD("Calling App %d with params 0x%04x", app_id, params);
+#ifdef ANDROID
+ if (!dev) {
+ NLOGE("Invalid args to %s()", __func__);
+ return APP_ERROR_IO;
+ }
+
+ // Call GSA nos_call IOCTL interface if needed
+ if (dev->use_one_pass_call) {
+ int err = dev->ops.one_pass_call(dev->ctx, app_id, params, args, arg_len,
+ reply, reply_len, &status_code);
+ if (err < 0) {
+ NLOGE("one_pass_call failed: %s", strerror(-err));
+ status_code = APP_ERROR_IO;
+ }
+
+ return status_code;
+ }
+#endif
+
+ NLOGD("Calling App 0x%02x with params 0x%04x", app_id, params);
struct transport_status status;
- uint32_t status_code;
int retries = CRC_RETRY_COUNT;
while (retries--) {
/* Wake up and wait for Citadel to be ready */
@@ -493,16 +517,16 @@ uint32_t nos_call_application(const struct nos_device *dev,
* or more than it can accept but this should not happen. Give to the chip a
* little bit of time and retry calling again. */
if (status_code == APP_ERROR_TOO_MUCH) {
- NLOGD("App %d returning 0x%x, give a retry(%d/%d)",
- app_id, status_code, retries, CRC_RETRY_COUNT);
+ NLOGD("App 0x%02x returning 0x%x, give a retry(%d/%d)", app_id,
+ status_code, retries, CRC_RETRY_COUNT);
usleep(RETRY_WAIT_TIME_US);
continue;
}
if (status_code != APP_ERROR_CHECKSUM) break;
- NLOGW("App %d request checksum error", app_id);
+ NLOGW("App 0x%02x request checksum error", app_id);
}
if (status_code == APP_ERROR_CHECKSUM) {
- NLOGE("App %d request checksum failed too many times", app_id);
+ NLOGE("App 0x%02x request checksum failed too many times", app_id);
status_code = APP_ERROR_IO;
}
@@ -519,6 +543,6 @@ uint32_t nos_call_application(const struct nos_device *dev,
* next call will try again. */
(void)clear_status(&ctx);
- NLOGD("App %d returning 0x%x", app_id, status_code);
+ NLOGD("App 0x%02x returning 0x%x", app_id, status_code);
return status_code;
}
diff --git a/nugget/include/app_nugget.h b/nugget/include/app_nugget.h
index cd8bf33..49ca2de 100644
--- a/nugget/include/app_nugget.h
+++ b/nugget/include/app_nugget.h
@@ -29,8 +29,9 @@ extern "C" {
/* App-specific errors (across all commands) */
enum {
- NUGGET_ERROR_LOCKED = APP_SPECIFIC_ERROR,
+ NUGGET_ERROR_LOCKED = APP_SPECIFIC_ERROR + 0,
NUGGET_ERROR_RETRY,
+ NUGGET_ERROR_VERIFY,
};
/****************************************************************************/
@@ -299,15 +300,15 @@ struct nugget_app_board_id {
uint32_t inv; /* must equal ~type when setting */
} __packed;
-#define NUGGET_PARAM_GET_EVENT_RECORD 0x0010
+#define NUGGET_PARAM_GET_EVENT_REPORT 0x0010
/*
- * This retrieves one pending event_record (defined in citadel_events.h).
+ * This retrieves one pending event_report (defined in citadel_events.h).
* If none are pending, it returns nothing.
*
* @param args <none>
* @param arg_len 0
- * @param reply struct event_record
- * @param reply_len sizeof struct event_record OR 0
+ * @param reply struct event_report
+ * @param reply_len sizeof struct event_report OR 0
*/
#define NUGGET_PARAM_AP_IS_REBOOTING 0x0011
@@ -461,10 +462,27 @@ struct gsa_gsc_psk_persist_storage {
/*
* GSA key provision command
*
- * @param args gsa unique public key
+ * We use the same command id to support multiple GSA-GSC PSK
+ * provision handshaking. List possible args and reply usage by
+ * each case.
+ *
+ * Non-secure PSK provision case:
+ * @param args GSA-GSC PSK (plaintext)
* @param arg_len 32
- * @param reply gsc public key + sha256(pre-shared key)
- * @param reply_len 64 + 32
+ * @param reply GSA-GSC PSK (plaintext)
+ * @param reply_len 32
+ *
+ * Ephemeral ec key handshaking case:
+ * @param args GSA public key
+ * @param arg_len 64
+ * @param reply GSC public key + signature
+ * @param reply_len 64 + 64
+ *
+ * Secure PSK provision case:
+ * @param args encrypted GSA-GSC PSK (nonce + PSK + tag)
+ * @param arg_len 12 + 32 + 16
+ * @param reply <none>
+ * @param reply_len 0
*/
/**
@@ -551,7 +569,8 @@ struct secure_channel_retry_count_persist_storage {
*
* @param args GSA EC public_key + AES_GCM256("MSGA") + AES_GSC_TAG
* @param arg_len 64 + 4 + 16 bytes = 84
- * @param reply GSC EC public_key + AES_GCM256("MSGB") + AES_GSC_TAG OR 1 byte error state
+ * @param reply GSC EC public_key + AES_GCM256("MSGB") + AES_GSC_TAG
+ * OR 1 byte error state
* @param reply_len 64 + 4 + 16 bytes = 84 OR 1
*/
@@ -559,10 +578,55 @@ struct secure_channel_retry_count_persist_storage {
/*
* Secure transport report noise handshake state command
*
- * @param args GSA noise handshake state
- * @param arg_len 1
+ * @param args GSA noise handshake state + report suez state
+ * @param arg_len 2
* @param reply <none>
- * @param reply_len 0
+ * @param reply_len 1
+ */
+
+#define NUGGET_PARAM_GET_BIG_EVENT_REPORT 0x001b
+/*
+ * This retrieves one pending big_event_report (defined in citadel_events.h).
+ * If none are pending, it returns nothing.
+ *
+ * @param args <none>
+ * @param arg_len 0
+ * @param reply struct big_event_report
+ * @param reply_len sizeof struct big_event_report OR 0
+ */
+
+#define NUGGET_PARAM_GET_FEATURE_SUPPORT 0x001c
+/*
+ * Get the specific feature supportness from the specific TA.
+ *
+ * @param args feature_id
+ * @param arg_len 4 byte
+ * @param reply 0 or 1
+ * @param reply_len 1 byte
+ *
+ * @errors APP_ERROR_BOGUS_ARGS
+ */
+
+#define NUGGET_PARAM_SECURE_TRANSPORT_USECASE_HANDSHAKE 0x001d
+/*
+ * Secure transport usecase handshake command
+ *
+ * @param args AES_GCM256(struct secure_transport_usecase) +
+ * AES_GCM_TAG_SIZE
+ * @param arg_len 64 + 16 = 80 bytes
+ * @param reply AES_GCM256(struct secure_transport_usecase) +
+ * AES_GCM_TAG_SIZE OR 1 byte error state
+ * @param reply_len 64 + 16 = 80 OR 1 bytes
+ */
+
+#define NUGGET_PARAM_SECURE_TRANSPORT_TEST 0x001e
+/*
+ * Secure transport test command
+ *
+ * @param args 1008 (1024 - 16 bytes AES_TAG_SIZE) bytes test data
+ * @param arg_len 1008 bytes
+ * @param reply 1008 (1024 - 16 bytes AES_TAG_SIZE) bytes test data
+ * @param reply_len 1008 bytes
*/
/****************************************************************************/
diff --git a/nugget/include/application.h b/nugget/include/application.h
index 1d485c6..053d016 100644
--- a/nugget/include/application.h
+++ b/nugget/include/application.h
@@ -79,9 +79,13 @@ typedef const void * const __private;
#define APP_ID_AVB_TEST 0x11
#define APP_ID_TRANSPORT_TEST 0x12
#define APP_ID_FACEAUTH_TEST 0x13
+#define APP_ID_TEST 0x7f
-/* This app ID should only be used by tests. */
-#define APP_ID_TEST 0xff
+/* OR this with the APP_ID to request no-protobuf messages */
+#define APP_ID_NO_PROTO_FLAG 0x80
+
+/* No-protobuf app, experimental for now */
+#define APP_ID_WEAVER2 (APP_ID_WEAVER | APP_ID_NO_PROTO_FLAG)
/****************************************************************************/
/* Other command fields */
@@ -90,7 +94,7 @@ typedef const void * const __private;
* The Command encoding is:
*
* Bits 31-24 Control flags (reserved)
- * Bits 23-16 Application ID
+ * Bits 23-16 Application ID (bit 23 indicates C protocol, not protobuf)
* Bits 15-0 Parameters (application-specific)
*/
@@ -239,7 +243,7 @@ struct transport_status {
/* Valid range of lengths for the status message */
#define STATUS_MIN_LENGTH 0x10
-#define STATUS_MAX_LENGTH 0xff
+#define STATUS_MAX_LENGTH (sizeof(struct transport_status)) /* 0x10 */
/* Flags used in the status message */
#define STATUS_FLAG_WORKING 0x0001 /* added in v1 */
diff --git a/nugget/include/citadel_events.h b/nugget/include/citadel_events.h
index 24babee..00780ad 100644
--- a/nugget/include/citadel_events.h
+++ b/nugget/include/citadel_events.h
@@ -31,7 +31,7 @@ extern "C" {
* When Citadel needs to tell the AP something without waiting to be asked, the
* process is as follows:
*
- * 1. Citadel adds an event_record to its internal queue, then asserts
+ * 1. Citadel adds an event_report to its internal queue, then asserts
* the CTDL_AP_IRQ signal to notify the AP.
*
* 2. The AP (citadeld) requests pending events from Citadel until they've
@@ -59,12 +59,14 @@ enum event_priority {
* Add to the list, but NEVER change or delete existing entries.
*/
enum event_id {
- EVENT_NONE = 0, // Unused ID, used as empty marker.
- EVENT_ALERT = 1, // Globalsec alert fired.
- EVENT_REBOOTED = 2, // Device rebooted.
- EVENT_UPGRADED = 3, // Device has upgraded.
- EVENT_ALERT_V2 = 4, // Globalsec Alertv2 fired
+ EVENT_NONE = 0, // Unused ID, used as empty marker.
+ EVENT_ALERT = 1, // Globalsec alert fired.
+ EVENT_REBOOTED = 2, // Device rebooted.
+ EVENT_UPGRADED = 3, // Device has upgraded.
+ EVENT_ALERT_V2 = 4, // Globalsec Alertv2 fired
EVENT_SEC_CH_STATE = 5, // Update GSA-GSC secure channel state.
+ EVENT_V1_NO_SUPPORT =
+ 6 // Report a VXX event that can't fit in struct event_report.
};
/*
@@ -76,9 +78,17 @@ enum upgrade_state_def {
UPGRADE_EN_FW_FAIL =2,
};
+/*
+ * Big event header flags.
+ */
+enum hdr_flags {
+ HDR_FLAG_EMPTY_SLOT = 0, // Used to determine empty slot.
+ HDR_FLAG_OCCUPIED_SLOT = 1 // Used to indicate an occupied slot.
+};
+
/* Please do not change the size of this struct */
-#define EVENT_RECORD_SIZE 64
-struct event_record {
+#define EVENT_REPORT_SIZE 64
+struct event_report {
uint64_t reset_count; /* zeroed by Citadel power cycle */
uint64_t uptime_usecs; /* since last Citadel reset */
uint32_t id;
@@ -117,9 +127,23 @@ struct event_record {
} event;
} __packed;
/* Please do not change the size of this struct */
-static_assert(sizeof(struct event_record) == EVENT_RECORD_SIZE,
+static_assert(sizeof(struct event_report) == EVENT_REPORT_SIZE,
"Muting the Immutable");
+struct big_event_report {
+ struct hdr {
+ /* Redundant w.r.t. to v1 event records */
+ uint64_t reset_count;
+ uint64_t uptime_usecs;
+ uint32_t priority;
+
+ uint8_t version;
+ uint8_t flags;
+ uint16_t length;
+ } hdr;
+ uint8_t data[384];
+} __packed;
+
#ifdef __cplusplus
}
#endif
diff --git a/nugget/include/feature_map.h b/nugget/include/feature_map.h
new file mode 100644
index 0000000..7ff697b
--- /dev/null
+++ b/nugget/include/feature_map.h
@@ -0,0 +1,67 @@
+/**
+ * \file
+ * Feature ID format and inline decode functions
+ */
+
+#pragma once
+
+/*****************************************************************************/
+
+#define TA_MASK 0xFF000000
+#define TA_OFFSET 24
+#define TA_FIELD 8 // Max 256 TAs
+
+#define FEATURE_MASK 0x00FFFFFF
+#define FEATURE_OFFSET 0
+#define FEATURE_FIELD 24 // Can support up to 2^24 features
+
+#define TA_FROM_FEATURE_ID(id) \
+ ((enum feature_support_app_id)((id & TA_MASK) >> TA_OFFSET))
+#define MODULE_FROM_FEATURE_ID(id) ((id & FEATURE_MASK) >> FEATURE_OFFSET)
+/*****************************************************************************/
+
+enum feature_support_app_id {
+ feature_id_avb = 0,
+ feature_id_gfa = 1,
+ feature_id_identity = 2,
+ feature_id_keymint = 3,
+ feature_id_nugget = 4,
+ feature_id_weaver = 5,
+
+ /* Please do not change numbers after they've been released */
+
+ feature_id_count, // used in sparse lookup table
+ feature_id_max = 0xff, // 8-bit TA_FIELD
+};
+static_assert(feature_id_count <= feature_id_max,
+ "Too many enum feature_support_app_id values");
+
+enum km_feature_list {
+ km_feature_individual_attest = 0,
+ km_feature_batch_attest = 1,
+ km_feature_gnubby_attest = 2,
+ km_feature_rkp = 3,
+ km_feature_rkp_dice = 4,
+ km_feature_dice = 5,
+ km_feature_multimei = 6,
+
+ /* Please do not change numbers after they've been released */
+
+ km_feature_max = FEATURE_MASK, // 24-bit FEATURE_FIELD
+};
+
+enum nugget_feature_list {
+ nugget_feature_test_image = 0,
+
+ /* Please do not change numbers after they've been released */
+
+ nugget_feature_max = FEATURE_MASK, // 24-bit FEATURE_FIELD
+};
+
+enum weaver_feature_list {
+ weaver_feature_api_no_proto = 0,
+
+ /* Please do not change numbers after they've been released */
+
+ weaver_feature_max = FEATURE_MASK, // 24-bit FEATURE_FIELD
+};
diff --git a/nugget/include/hals/common.h b/nugget/include/hals/common.h
new file mode 100644
index 0000000..ed02484
--- /dev/null
+++ b/nugget/include/hals/common.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#ifndef __packed
+#define __packed __attribute__((packed))
+#endif
+
+/****************************************************************************/
+/**
+ * This should be the start of EVERY request and response struct.
+ *
+ * We don't really need a struct just to hold one integer, but if we need to add
+ * to it later, we'll be glad we did.
+ */
+struct nos2_cmd_hal {
+ uint32_t version;
+} __packed;
+/**
+ * IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT
+ *
+ * Do *NOT* increment the version number with each new dessert release!
+ *
+ * We'll use a (major << 16) | (minor) value for the version. The major
+ * versionn indicates when the command was first supported, and the minor
+ * indicates variations to it since then.
+ *
+ * We're currently working on Android 14 (UDC), so start with that. Bump minor
+ * values ONLY if the behavior changes.
+ *
+ * By including the version struct in every request and response, we can
+ * support multiple minor HAL changes independently. Add a new version
+ * constant below IF AND ONLY IF a command's struct changes or its behavior is
+ * different. THEN use that version internally to
+ *
+ * 1. Reject the command if the version is one you don't know about, AND
+ *
+ * 2. Verify that the incoming struct matches expectations for the versions
+ * you do know about, AND
+ *
+ * 3. Support as many versions as possible, in case Android is downgraded and
+ * Nugget OS is not (or vice-versa), SO
+ *
+ * 4) Make sure to indicate the version in the output structs too, in case the
+ * command has no input args but the output later changes.
+ *
+ * IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT
+ */
+#define NOS2_HAL_VERSION_UDC (14U << 16)
+/* STOP! Don't just randomly add new values here! Read the comment above! */
+
+/****************************************************************************/
+/* Common types */
+
+/* TODO(b/257251378): We'll need some <tag,len,bytes[]> stuff here. */
+
+/****************************************************************************/
+#ifdef __cplusplus
+}
+#endif
diff --git a/nugget/include/hals/weaver.h b/nugget/include/hals/weaver.h
new file mode 100644
index 0000000..29bd67c
--- /dev/null
+++ b/nugget/include/hals/weaver.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "application.h"
+#include "hals/common.h"
+
+/****************************************************************************/
+/* Magic constants
+ *
+ * Only Acropora knows these numbers. The AP has to ask.
+ *
+ * It's a pain to create multiple variable-length arrays using strictly correct
+ * C, but the Weaver service is in the Nugget OS repo so we can hard-code the
+ * sizes here. If it ever changes we'll use the hal.version field to distinguish
+ * which one we're using.
+ *
+ * Still, we want to match the AIDL definitions as closely as possible, to
+ * make our code easier to understand and maintain.
+ */
+#define NOS2_WEAVER_NUM_SLOTS 64
+#define NOS2_WEAVER_KEY_BYTES (128 / 8)
+#define NOS2_WEAVER_VALUE_BYTES (128 / 8)
+static_assert((NOS2_WEAVER_KEY_BYTES & 0x4) == 0,
+ "NOS2_WEAVER_KEY_BYTES is not a multiple of 4");
+static_assert((NOS2_WEAVER_VALUE_BYTES & 0x4) == 0,
+ "NOS2_WEAVER_VALUE_BYTES is not a multiple of 4");
+
+typedef uint8_t nos2_weaver_key_t[NOS2_WEAVER_KEY_BYTES];
+typedef uint8_t nos2_weaver_value_t[NOS2_WEAVER_VALUE_BYTES];
+
+/****************************************************************************/
+/* The command is sent separately from any data */
+
+enum nos2_weaver_cmd {
+ NOS2_WEAVER_GET_CONFIG,
+ NOS2_WEAVER_WRITE,
+ NOS2_WEAVER_READ,
+ NOS2_WEAVER_ERASE_VALUE,
+
+ NOS2_WEAVER_NUM_CMDS
+};
+
+/****************************************************************************/
+/* Request/Response data. Both are optional and depend on the command. */
+
+/** NOS2_WEAVER_GET_CONFIG */
+/* There is no struct nos2_weaver_get_config_request */
+struct nos2_weaver_get_config_response {
+ struct nos2_cmd_hal hal;
+
+ uint32_t slots;
+ uint32_t key_size;
+ uint32_t value_size;
+};
+
+/** NOS2_WEAVER_WRITE */
+struct nos2_weaver_write_request {
+ struct nos2_cmd_hal hal;
+
+ uint32_t slot_id;
+ nos2_weaver_key_t key;
+ nos2_weaver_value_t value;
+};
+/* There is no struct nos2_weaver_write_response */
+
+/** NOS2_WEAVER_READ */
+struct nos2_weaver_read_request {
+ struct nos2_cmd_hal hal;
+
+ uint32_t slot_id;
+ nos2_weaver_key_t key;
+};
+
+enum nos2_weaver_read_status {
+ NOS2_WEAVER_READ_STATUS_OK,
+ NOS2_WEAVER_READ_STATUS_FAILED,
+ NOS2_WEAVER_READ_STATUS_INCORRECT_KEY,
+ NOS2_WEAVER_READ_STATUS_THROTTLE,
+};
+
+struct nos2_weaver_read_response {
+ struct nos2_cmd_hal hal;
+
+ uint32_t timeout;
+ uint32_t status; /* enum nos2_weaver_read_status, but of specified size */
+ /* Put potentially variable-length members at the end. It's NOT, though */
+ nos2_weaver_value_t value;
+};
+
+/** NOS2_WEAVER_ERASE_VALUE */
+struct nos2_weaver_erase_request {
+ struct nos2_cmd_hal hal;
+
+ uint32_t slot_id;
+};
+/* There is no struct nos2_weaver_erase_response */
+
+/****************************************************************************/
+#ifdef __cplusplus
+}
+#endif
diff --git a/libnos_datagram/include/nos/device.h b/nugget/include/nos/device.h
index 2ba57e0..d1fb0d6 100644
--- a/libnos_datagram/include/nos/device.h
+++ b/nugget/include/nos/device.h
@@ -16,6 +16,9 @@
#ifndef NOS_DEVICE_H
#define NOS_DEVICE_H
+#ifdef ANDROID
+#include <stdbool.h>
+#endif
#include <stdint.h>
#ifdef __cplusplus
@@ -69,12 +72,28 @@ struct nos_device_ops {
* The device must not be used after closing.
*/
void (*close)(void *ctx);
+
+#ifdef ANDROID
+ /**
+ * one_pass_call: sending whole data payload directly to GSA FW
+ * and rely on GSA libnos_transport library to communicate with GSC.
+ *
+ * Return 0 on success. A negative value on I/O failure.
+ */
+ int (*one_pass_call)(void *ctx, uint8_t app_id, uint16_t params,
+ const uint8_t *args, uint32_t arg_len,
+ uint8_t *reply, uint32_t *reply_len,
+ uint32_t *status_code);
+#endif
};
struct nos_device {
void *ctx;
struct nos_device_ops ops;
uint32_t config;
+#ifdef ANDROID
+ bool use_one_pass_call;
+#endif
};
/*
diff --git a/nugget/proto/Android.bp b/nugget/proto/Android.bp
index b9f1220..b4ee2a0 100644
--- a/nugget/proto/Android.bp
+++ b/nugget/proto/Android.bp
@@ -43,3 +43,8 @@ cc_library {
},
}
+
+filegroup {
+ name: "nugget_options_proto",
+ srcs: ["nugget/protobuf/options.proto"],
+} \ No newline at end of file
diff --git a/nugget/proto/nugget/app/avb/Android.bp b/nugget/proto/nugget/app/avb/Android.bp
index 136b9d5..53b284a 100644
--- a/nugget/proto/nugget/app/avb/Android.bp
+++ b/nugget/proto/nugget/app/avb/Android.bp
@@ -26,7 +26,11 @@ package {
genrule {
name: "nos_app_avb_service_genc++",
out: ["Avb.client.cpp"],
- srcs: ["avb.proto"],
+ srcs: [
+ "avb.proto",
+ ":nugget_options_proto",
+ ":libprotobuf-internal-protos",
+ ],
tools: ["aprotoc", "protoc-gen-nos-client-cpp"],
cmd: GEN_SERVICE_SOURCE,
}
@@ -34,7 +38,11 @@ genrule {
genrule {
name: "nos_app_avb_service_genc++_headers",
out: ["Avb.client.h"],
- srcs: ["avb.proto"],
+ srcs: [
+ "avb.proto",
+ ":nugget_options_proto",
+ ":libprotobuf-internal-protos",
+ ],
tools: ["aprotoc", "protoc-gen-nos-client-cpp"],
cmd: GEN_SERVICE_HEADER,
}
@@ -42,7 +50,11 @@ genrule {
genrule {
name: "nos_app_avb_service_genc++_mock",
out: ["MockAvb.client.h"],
- srcs: ["avb.proto"],
+ srcs: [
+ "avb.proto",
+ ":nugget_options_proto",
+ ":libprotobuf-internal-protos",
+ ],
tools: ["aprotoc", "protoc-gen-nos-client-cpp"],
cmd: GEN_SERVICE_MOCK,
}
diff --git a/nugget/proto/nugget/app/avb/avb.proto b/nugget/proto/nugget/app/avb/avb.proto
index 9aec71e..99e1882 100644
--- a/nugget/proto/nugget/app/avb/avb.proto
+++ b/nugget/proto/nugget/app/avb/avb.proto
@@ -43,6 +43,7 @@ service Avb {
rpc GetOwnerKey (GetOwnerKeyRequest) returns (GetOwnerKeyResponse);
rpc GetResetChallenge (GetResetChallengeRequest) returns (GetResetChallengeResponse);
rpc ProductionResetTest (ProductionResetTestRequest) returns (ProductionResetTestResponse);
+ rpc GetCarrierLockName (GetCarrierLockNameRequest) returns (GetCarrierLockNameResponse);
}
enum LockIndex {
@@ -192,3 +193,10 @@ message ProductionResetTestResponse {}
message BootloaderDoneRequest {}
message BootloaderDoneResponse {}
+
+// Carrier lock name
+message GetCarrierLockNameRequest {}
+
+message GetCarrierLockNameResponse {
+ string name = 1;
+}
diff --git a/nugget/proto/nugget/app/identity/Android.bp b/nugget/proto/nugget/app/identity/Android.bp
index b65297a..c557182 100644
--- a/nugget/proto/nugget/app/identity/Android.bp
+++ b/nugget/proto/nugget/app/identity/Android.bp
@@ -26,7 +26,13 @@ package {
genrule {
name: "nos_app_identity_service_genc++",
out: ["Identity.client.cpp"],
- srcs: ["identity.proto"],
+ srcs: [
+ "identity.proto",
+ "identity_defs.proto",
+ "identity_types.proto",
+ ":nugget_options_proto",
+ ":libprotobuf-internal-protos",
+ ],
tools: ["aprotoc", "protoc-gen-nos-client-cpp"],
cmd: GEN_SERVICE_SOURCE,
}
@@ -34,7 +40,13 @@ genrule {
genrule {
name: "nos_app_identity_service_genc++_headers",
out: ["Identity.client.h"],
- srcs: ["identity.proto"],
+ srcs: [
+ "identity.proto",
+ "identity_defs.proto",
+ "identity_types.proto",
+ ":nugget_options_proto",
+ ":libprotobuf-internal-protos",
+ ],
tools: ["aprotoc", "protoc-gen-nos-client-cpp"],
cmd: GEN_SERVICE_HEADER,
}
@@ -42,7 +54,13 @@ genrule {
genrule {
name: "nos_app_identity_service_genc++_mock",
out: ["MockIdentity.client.h"],
- srcs: ["identity.proto"],
+ srcs: [
+ "identity.proto",
+ "identity_defs.proto",
+ "identity_types.proto",
+ ":nugget_options_proto",
+ ":libprotobuf-internal-protos",
+ ],
tools: ["aprotoc", "protoc-gen-nos-client-cpp"],
cmd: GEN_SERVICE_MOCK,
}
diff --git a/nugget/proto/nugget/app/identity/identity.proto b/nugget/proto/nugget/app/identity/identity.proto
index a29aa16..58e656e 100644
--- a/nugget/proto/nugget/app/identity/identity.proto
+++ b/nugget/proto/nugget/app/identity/identity.proto
@@ -18,7 +18,6 @@ syntax = "proto3";
package nugget.app.identity;
-import "nugget/app/identity/identity_defs.proto";
import "nugget/app/identity/identity_types.proto";
import "nugget/protobuf/options.proto";
@@ -61,6 +60,11 @@ service Identity {
rpc SessionInitialize (SessionInitializeRequest) returns (SessionInitializeResponse);
rpc SessionSetReaderEphemeralPublicKey (SessionSetReaderEphemeralPublicKeyRequest) returns (SessionSetReaderEphemeralPublicKeyResponse);
rpc SessionSetSessionTranscript (SessionSetSessionTranscriptRequest) returns (SessionSetSessionTranscriptResponse);
+
+ // For Android 14 new APIs
+ rpc ICprepareDeviceAuthentication (ICprepareDeviceAuthenticationRequest) returns (ICprepareDeviceAuthenticationResponse);
+ rpc ICfinishRetrievalWithSignature (ICfinishRetrievalWithSignatureRequest) returns (ICfinishRetrievalWithSignatureResponse);
+ rpc SessionGetEphemeralKeyPair (SessionGetEphemeralKeyPairRequest) returns (SessionGetEphemeralKeyPairResponse);
}
enum RequestType {
@@ -251,7 +255,7 @@ message ICvalidateAccessControlProfileRequest{
uint64 secureUserId = 5;
bytes mac = 6;
uint32 publicKeyOffset = 7;
- uint32 publicKeysize = 8;
+ uint32 publicKeySize = 8;
}
message ICvalidateAccessControlProfileResponse{
@@ -285,6 +289,20 @@ message ICcalcMacKeyResponse{
Result result = 1;
}
+// ICprepareDeviceAuthentication
+message ICprepareDeviceAuthenticationRequest{
+ bytes sessionTranscript = 1;
+ bytes readerEphemeralPublicKey = 2;
+ bytes signingKeyBlob = 3;
+ bytes docType = 4;
+ uint32 numNamespacesWithValues = 5;
+ uint32 expectedDeviceNamespacesSize = 6;
+}
+
+message ICprepareDeviceAuthenticationResponse{
+ Result result = 1;
+}
+
// ICstartRetrieveEntryValue
message ICstartRetrieveEntryValueRequest{
string nameSpace = 1;
@@ -297,6 +315,7 @@ message ICstartRetrieveEntryValueRequest{
message ICstartRetrieveEntryValueResponse{
AccessResult accessCheckResult = 1;
uint32 sessionCookie = 2;
+ Result result = 3;
}
// ICretrieveEntryValue
@@ -322,6 +341,16 @@ message ICfinishRetrievalResponse{
bytes mac = 2;
}
+// ICfinishRetrievalWithSignature
+message ICfinishRetrievalWithSignatureRequest{
+}
+
+message ICfinishRetrievalWithSignatureResponse{
+ Result result = 1;
+ bytes mac = 2;
+ bytes ecdsaSignature = 3;
+}
+
// ICdeleteCredential
message ICdeleteCredentialRequest{
bytes docType = 1;
@@ -369,6 +398,7 @@ message SessionShutdownResponse{
// SessionInitialize
message SessionInitializeRequest{
+ uint32 oemHalVersion = 1;
}
message SessionInitializeResponse{
@@ -394,3 +424,12 @@ message SessionSetSessionTranscriptRequest{
message SessionSetSessionTranscriptResponse{
Result result = 1;
}
+
+// SessionGetEphemeralKeyPair
+message SessionGetEphemeralKeyPairRequest{
+}
+
+message SessionGetEphemeralKeyPairResponse{
+ Result result = 1;
+ bytes ephemeralPrivateKey = 2;
+}
diff --git a/nugget/proto/nugget/app/identity/identity_types.proto b/nugget/proto/nugget/app/identity/identity_types.proto
index 4c50f2c..66420a1 100644
--- a/nugget/proto/nugget/app/identity/identity_types.proto
+++ b/nugget/proto/nugget/app/identity/identity_types.proto
@@ -18,7 +18,6 @@ syntax = "proto3";
package nugget.app.identity;
-import "nugget/protobuf/options.proto";
import "nugget/app/identity/identity_defs.proto";
message Result {
diff --git a/nugget/proto/nugget/app/keymaster/Android.bp b/nugget/proto/nugget/app/keymaster/Android.bp
index 32e3479..8afadc9 100644
--- a/nugget/proto/nugget/app/keymaster/Android.bp
+++ b/nugget/proto/nugget/app/keymaster/Android.bp
@@ -26,7 +26,13 @@ package {
genrule {
name: "nos_app_keymaster_service_genc++",
out: ["Keymaster.client.cpp"],
- srcs: ["keymaster.proto"],
+ srcs: [
+ "keymaster.proto",
+ "keymaster_defs.proto",
+ "keymaster_types.proto",
+ ":nugget_options_proto",
+ ":libprotobuf-internal-protos",
+ ],
tools: ["aprotoc", "protoc-gen-nos-client-cpp"],
cmd: GEN_SERVICE_SOURCE,
}
@@ -34,7 +40,13 @@ genrule {
genrule {
name: "nos_app_keymaster_service_genc++_headers",
out: ["Keymaster.client.h"],
- srcs: ["keymaster.proto"],
+ srcs: [
+ "keymaster.proto",
+ "keymaster_defs.proto",
+ "keymaster_types.proto",
+ ":nugget_options_proto",
+ ":libprotobuf-internal-protos",
+ ],
tools: ["aprotoc", "protoc-gen-nos-client-cpp"],
cmd: GEN_SERVICE_HEADER,
}
@@ -42,7 +54,13 @@ genrule {
genrule {
name: "nos_app_keymaster_service_genc++_mock",
out: ["MockKeymaster.client.h"],
- srcs: ["keymaster.proto"],
+ srcs: [
+ "keymaster.proto",
+ "keymaster_defs.proto",
+ "keymaster_types.proto",
+ ":nugget_options_proto",
+ ":libprotobuf-internal-protos",
+ ],
tools: ["aprotoc", "protoc-gen-nos-client-cpp"],
cmd: GEN_SERVICE_MOCK,
}
diff --git a/nugget/proto/nugget/app/keymaster/ctdl/Android.bp b/nugget/proto/nugget/app/keymaster/ctdl/Android.bp
new file mode 100644
index 0000000..480cceb
--- /dev/null
+++ b/nugget/proto/nugget/app/keymaster/ctdl/Android.bp
@@ -0,0 +1,75 @@
+//
+// Copyright (C) 2017 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 {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "external_nos_host_generic_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["external_nos_host_generic_license"],
+}
+
+// For keymaster 3/4/4.1 @ citadel
+genrule {
+ name: "nos_app_keymaster_service_ctdl_genc++",
+ out: ["Keymaster.client.cpp"],
+ srcs: [
+ "keymaster.proto",
+ "keymaster_defs.proto",
+ "keymaster_types.proto",
+ ":nugget_options_proto",
+ ":libprotobuf-internal-protos",
+ ],
+ tools: ["aprotoc", "protoc-gen-nos-client-cpp"],
+ cmd: GEN_SERVICE_SOURCE,
+}
+
+genrule {
+ name: "nos_app_keymaster_service_ctdl_genc++_headers",
+ out: ["Keymaster.client.h"],
+ srcs: [
+ "keymaster.proto",
+ "keymaster_defs.proto",
+ "keymaster_types.proto",
+ ":nugget_options_proto",
+ ":libprotobuf-internal-protos",
+ ],
+ tools: ["aprotoc", "protoc-gen-nos-client-cpp"],
+ cmd: GEN_SERVICE_HEADER,
+}
+
+genrule {
+ name: "nos_app_keymaster_service_ctdl_genc++_mock",
+ out: ["MockKeymaster.client.h"],
+ srcs: [
+ "keymaster.proto",
+ "keymaster_defs.proto",
+ "keymaster_types.proto",
+ ":nugget_options_proto",
+ ":libprotobuf-internal-protos",
+ ],
+ tools: ["aprotoc", "protoc-gen-nos-client-cpp"],
+ cmd: GEN_SERVICE_MOCK,
+}
+
+cc_library {
+ name: "nos_app_keymaster_ctdl",
+ generated_sources: ["nos_app_keymaster_service_ctdl_genc++"],
+ generated_headers: ["nos_app_keymaster_service_ctdl_genc++_headers"],
+ defaults: ["nos_app_service_defaults"],
+ export_generated_headers: ["nos_app_keymaster_service_ctdl_genc++_headers"],
+}
diff --git a/nugget/proto/nugget/app/keymaster/ctdl/keymaster.options b/nugget/proto/nugget/app/keymaster/ctdl/keymaster.options
new file mode 100644
index 0000000..daec677
--- /dev/null
+++ b/nugget/proto/nugget/app/keymaster/ctdl/keymaster.options
@@ -0,0 +1,21 @@
+nugget.app.keymaster.ctdl.ImportWrappedKeyRequest.initialization_vector max_size:12
+nugget.app.keymaster.ctdl.ImportWrappedKeyRequest.gcm_tag max_size:16
+nugget.app.keymaster.ctdl.ImportWrappedKeyRequest.masking_key max_size:32
+nugget.app.keymaster.ctdl.SetRootOfTrustRequest.digest max_size:32
+nugget.app.keymaster.ctdl.SetBootStateRequest.public_key max_size:32
+nugget.app.keymaster.ctdl.SetBootStateRequest.boot_hash max_size:32
+nugget.app.keymaster.ctdl.ComputeSharedHmacRequest.hmac_sharing_params max_count:10
+nugget.app.keymaster.ctdl.ComputeSharedHmacResponse.sharing_check max_size:32
+nugget.app.keymaster.ctdl.DTupHandshakeRequest.nonce_client max_size:32
+nugget.app.keymaster.ctdl.DTupHandshakeResponse.nonce_citadel max_size:32
+nugget.app.keymaster.ctdl.DTupHandshakeResponse.signature max_size:32
+nugget.app.keymaster.ctdl.DTupFetchInputEventResponse.signature max_size:32
+nugget.app.keymaster.ctdl.GetBootInfoResponse.boot_key max_size:32
+nugget.app.keymaster.ctdl.GetBootInfoResponse.boot_hash max_size:32
+nugget.app.keymaster.ctdl.ProvisionPresharedSecretRequest.preshared_secret max_size:32
+nugget.app.keymaster.ctdl.StartAttestKeyRequest.not_before max_size:15
+nugget.app.keymaster.ctdl.StartAttestKeyRequest.not_after max_size:15
+nugget.app.keymaster.ctdl.StartAttestKeyRequest.caller_issuer_subj_name max_size:100
+nugget.app.keymaster.ctdl.ProvisionPresharedSecretResponse.digest max_size:32
+nugget.app.keymaster.ctdl.ProvisionCertificatesRequest.cert_block max_size: 1024
+nugget.app.keymaster.ctdl.ProvisionCertificatesRequest.digest max_size: 32
diff --git a/nugget/proto/nugget/app/keymaster/ctdl/keymaster.proto b/nugget/proto/nugget/app/keymaster/ctdl/keymaster.proto
new file mode 100644
index 0000000..49f18b1
--- /dev/null
+++ b/nugget/proto/nugget/app/keymaster/ctdl/keymaster.proto
@@ -0,0 +1,658 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+syntax = "proto3";
+
+package nugget.app.keymaster.ctdl;
+
+import "nugget/app/keymaster/ctdl/keymaster_defs.proto";
+import "nugget/app/keymaster/ctdl/keymaster_types.proto";
+import "nugget/protobuf/options.proto";
+
+/*
+ * Keymaster service methods.
+ *
+ * TODO: some methods may be implemented in the host side HAL implementation.
+ */
+service Keymaster {
+ option (nugget.protobuf.app_id) = "KEYMASTER";
+ option (nugget.protobuf.app_name) = "Keymaster";
+ option (nugget.protobuf.app_version) = 1;
+ /*
+ * Both request and response buffers are sized such
+ * that a key-blob may be fully contained.
+ *
+ * TODO: revisit this choice in the event that memory
+ * is running out. Supporting smaller buffers will
+ * require that the keymaster app switch from the
+ * transport API to the datagram API.
+ */
+ option (nugget.protobuf.request_buffer_size) = 3072;
+ option (nugget.protobuf.response_buffer_size) = 2048;
+
+ /*
+ * KM3 methods, from:
+ * ::android::hardware::keymaster::V3_0::IKeymasterDevice
+ */
+ rpc AddRngEntropy (AddRngEntropyRequest) returns (AddRngEntropyResponse);
+ rpc GenerateKey (GenerateKeyRequest) returns (GenerateKeyResponse);
+ rpc GetKeyCharacteristics (GetKeyCharacteristicsRequest) returns (GetKeyCharacteristicsResponse);
+ rpc ImportKey (ImportKeyRequest) returns (ImportKeyResponse);
+ rpc ExportKey (ExportKeyRequest) returns (ExportKeyResponse);
+ rpc StartAttestKey (StartAttestKeyRequest) returns (StartAttestKeyResponse);
+ rpc UpgradeKey (UpgradeKeyRequest) returns (UpgradeKeyResponse);
+ rpc DeleteKey (DeleteKeyRequest) returns (DeleteKeyResponse);
+ rpc DeleteAllKeys (DeleteAllKeysRequest) returns (DeleteAllKeysResponse);
+ rpc DestroyAttestationIds (DestroyAttestationIdsRequest) returns (DestroyAttestationIdsResponse);
+ rpc BeginOperation (BeginOperationRequest) returns (BeginOperationResponse);
+ rpc UpdateOperation (UpdateOperationRequest) returns (UpdateOperationResponse);
+ rpc FinishOperation (FinishOperationRequest) returns (FinishOperationResponse);
+ rpc AbortOperation (AbortOperationRequest) returns (AbortOperationResponse);
+
+ /*
+ * KM4 methods.
+ */
+ rpc ImportWrappedKey (ImportWrappedKeyRequest) returns (ImportKeyResponse);
+
+ /*
+ * Vendor specific methods (bootloader, manufacturing, status,
+ * factory reset, upgrade).
+ */
+ // Only callable by the Bootloader.
+ rpc SetRootOfTrust (SetRootOfTrustRequest) returns (SetRootOfTrustResponse);
+ // Only callable by the Bootloader.
+ rpc SetBootState (SetBootStateRequest) returns (SetBootStateResponse);
+ // Only callable at the Device Factory.
+ rpc ProvisionDeviceIds (ProvisionDeviceIdsRequest) returns (ProvisionDeviceIdsResponse);
+ // Only callable at the Device Factory.
+ rpc ReadTeeBatchCertificate (ReadTeeBatchCertificateRequest) returns (ReadTeeBatchCertificateResponse);
+
+ /*
+ * More KM4 methods.
+ */
+ rpc GetHmacSharingParameters (GetHmacSharingParametersRequest) returns (GetHmacSharingParametersResponse);
+ rpc ComputeSharedHmac (ComputeSharedHmacRequest) returns (ComputeSharedHmacResponse);
+
+ /*
+ * DTup input session methods.
+ */
+ rpc HandshakeDTup (DTupHandshakeRequest) returns (DTupHandshakeResponse);
+ rpc FetchDTupInputEvent (DTupFetchInputEventRequest) returns (DTupFetchInputEventResponse);
+
+ /*
+ * More vendor specific methods.
+ */
+ // Only callable once per boot.
+ rpc SetSystemVersionInfo (SetSystemVersionInfoRequest) returns (SetSystemVersionInfoResponse);
+ rpc GetBootInfo (GetBootInfoRequest) returns (GetBootInfoResponse);
+
+ /*
+ * Called during provisioning by the CitadelProvision tool.
+ */
+ rpc ProvisionPresharedSecret (ProvisionPresharedSecretRequest) returns (ProvisionPresharedSecretResponse);
+
+ /*
+ * Additional attestation methods.
+ */
+ rpc ContinueAttestKey(ContinueAttestKeyRequest) returns (ContinueAttestKeyResponse);
+ rpc FinishAttestKey(FinishAttestKeyRequest) returns (FinishAttestKeyResponse);
+
+ /*
+ * More vendor specific methods.
+ */
+ rpc ProvisionCertificates(ProvisionCertificatesRequest) returns (ProvisionCertificatesResponse);
+
+ /*
+ * KM4.1 methods.
+ */
+ rpc DeviceLocked(DeviceLockedRequest) returns (DeviceLockedResponse);
+ rpc EarlyBootEnded(EarlyBootEndedRequest) returns (EarlyBootEndedResponse);
+
+ /*
+ * More vendor specific methods.
+ */
+ rpc ReadCertificate(ReadCertificateRequest) returns (ReadCertificateResponse);
+ rpc IdentityStartAttestKey (IdentityStartAttestKeyRequest) returns (IdentityStartAttestKeyResponse);
+ rpc IdentityFinishAttestKey (IdentityFinishAttestKeyRequest) returns (IdentityFinishAttestKeyResponse);
+
+ /*
+ * Resume-on-Reboot implementation.
+ */
+ rpc VigoReadVS(VigoReadVSRequest) returns (VigoReadVSResponse);
+ rpc VigoStartChannel(VigoStartChannelRequest)
+ returns (VigoStartChannelResponse);
+ rpc VigoStoreSecret(VigoStoreSecretRequest) returns (VigoStoreSecretResponse);
+ rpc VigoReleaseSecret(VigoReleaseSecretRequest)
+ returns (VigoReleaseSecretResponse);
+
+ /*
+ * pKVM implementation
+ */
+ rpc GetPerFactoryResetValue(GetPerFactoryResetValueRequest) returns (GetPerFactoryResetValueResponse);
+
+ /*
+ * RKP implementation
+ */
+ rpc GenerateRkpKey(GenerateRkpKeyRequest) returns (GenerateRkpKeyResponse);
+ rpc GenerateRkpCsr(GenerateRkpCsrRequest) returns (GenerateRkpCsrResponse);
+
+ /*
+ * Vendor specific method. To export IMEI/DSU to trusty only
+ */
+ rpc ExportDeviceIds(ExportDeviceIdsRequest) returns (ExportDeviceIdsResponse);
+
+ /*
+ * RKP v3 implementation
+ */
+ rpc GenerateRkpCsrV2(GenerateRkpCsrV2Request) returns (GenerateRkpCsrV2Response);
+ // These are implemented with a enum, so new RPCs must be appended, and
+ // deprecated RPCs need placeholders.
+}
+
+/*
+ * KM3 messages.
+ */
+
+// AddEntropy
+message AddRngEntropyRequest {
+ bytes data = 1;
+}
+message AddRngEntropyResponse {
+ ErrorCode error_code = 1;
+}
+
+// GenerateKey
+message GenerateKeyRequest {
+ KeyParameters params = 1;
+ uint64 creation_time_ms = 2; // Rough current time (ms since epoch).
+}
+message GenerateKeyResponse {
+ ErrorCode error_code = 1;
+ KeyBlob blob = 2;
+ KeyCharacteristics characteristics = 3;
+}
+
+// GetKeyCharacteristics
+message GetKeyCharacteristicsRequest {
+ KeyBlob blob = 1;
+ bytes client_id = 2;
+ bytes app_data = 3;
+}
+message GetKeyCharacteristicsResponse {
+ ErrorCode error_code = 1;
+ KeyCharacteristics characteristics = 2;
+}
+
+// ImportKey
+message ImportKeyRequest {
+ KeyParameters params = 1;
+ RSAKey rsa = 2;
+ ECKey ec = 3;
+ SymmetricKey symmetric_key = 4;
+ uint64 creation_time_ms = 5; // Rough current time (ms since epoch).
+};
+message ImportKeyResponse {
+ ErrorCode error_code = 1;
+ KeyBlob blob = 2;
+ KeyCharacteristics characteristics = 3;
+};
+
+// ExportKey
+message ExportKeyRequest {
+ KeyFormat format = 1;
+ KeyBlob blob = 2;
+ bytes client_id = 3;
+ bytes app_data = 4;
+};
+message ExportKeyResponse {
+ ErrorCode error_code = 1;
+ Algorithm algorithm = 2;
+ RSAKey rsa = 3;
+ ECKey ec = 4;
+};
+
+// StartAttestKey
+message StartAttestKeyRequest {
+ KeyBlob blob = 1;
+ KeyParameters params = 2;
+ uint32 attestation_app_id_len = 3;
+ AttestationSelector selector = 4;
+ bytes not_before = 5; // strftime('%Y%m%d%H%M%SZ') [15 octects]
+ bytes not_after = 6; // strftime('%Y%m%d%H%M%SZ') [15 octects]
+ bytes caller_issuer_subj_name = 7;
+ KeyParameters caller_key_params = 8;
+}
+message StartAttestKeyResponse {
+ ErrorCode error_code = 1;
+ OperationHandle handle = 2;
+ bytes certificate_prologue = 3;
+}
+
+// ContinueAttestKeyRequest
+message ContinueAttestKeyRequest {
+ OperationHandle handle = 1;
+ // bytes attestation_app_id = 2; // Unused, contained within params
+ KeyParameters params = 3;
+}
+message ContinueAttestKeyResponse {
+ ErrorCode error_code = 1;
+ bytes certificate_body = 2;
+}
+
+// FinishAttestKeyRequest
+message FinishAttestKeyRequest {
+ OperationHandle handle = 1;
+ KeyBlob caller_blob = 2;
+ KeyParameters caller_key_params = 3;
+}
+message FinishAttestKeyResponse {
+ ErrorCode error_code = 1;
+ bytes certificate_epilogue = 2;
+ ChipFusing chip_fusing = 3;
+ bool nodelocked_ro = 4;
+}
+
+// UpgradeKey
+message UpgradeKeyRequest {
+ KeyBlob blob = 1;
+ KeyParameters params = 2;
+}
+message UpgradeKeyResponse {
+ ErrorCode error_code = 1;
+ KeyBlob blob = 2;
+}
+
+// DeleteKey
+message DeleteKeyRequest {
+ KeyBlob blob = 1;
+}
+message DeleteKeyResponse {
+ ErrorCode error_code = 1;
+}
+
+// DeleteAllKeys
+message DeleteAllKeysRequest {}
+message DeleteAllKeysResponse {
+ ErrorCode error_code = 1;
+}
+
+// DestroyAttestationIds
+message DestroyAttestationIdsRequest {}
+message DestroyAttestationIdsResponse {
+ ErrorCode error_code = 1;
+}
+
+// BeginOperation
+message BeginOperationRequest {
+ KeyPurpose purpose = 1;
+ KeyBlob blob = 2;
+ KeyParameters params = 3;
+ HardwareAuthToken auth_token = 4;
+}
+message BeginOperationResponse {
+ ErrorCode error_code = 1;
+ KeyParameters params = 2;
+ OperationHandle handle = 3;
+ Algorithm algorithm = 4;
+ uint32 key_bits = 5;
+}
+
+// UpdateOperation
+message UpdateOperationRequest {
+ OperationHandle handle = 1;
+ KeyParameters params = 2;
+ bytes input = 3;
+ HardwareAuthToken auth_token = 4;
+ VerificationToken verification_token = 5;
+}
+message UpdateOperationResponse {
+ ErrorCode error_code = 1;
+ uint32 consumed = 2;
+ KeyParameters params = 3;
+ bytes output = 4;
+}
+
+// FinishOperation
+message FinishOperationRequest {
+ OperationHandle handle = 1;
+ KeyParameters params = 2;
+ bytes input = 3;
+ bytes signature = 4;
+ HardwareAuthToken auth_token = 5;
+ VerificationToken verification_token = 6;
+};
+message FinishOperationResponse {
+ ErrorCode error_code = 1;
+ KeyParameters params = 2;
+ bytes output = 3;
+};
+
+// AbortOperation
+message AbortOperationRequest {
+ OperationHandle handle = 1;
+};
+message AbortOperationResponse {
+ ErrorCode error_code = 1;
+};
+
+/*
+ * KM4 messages.
+ */
+
+// ImportWrappedKey
+message ImportWrappedKeyRequest {
+ uint32 key_format = 1;
+ KeyParameters params = 2;
+ bytes rsa_envelope = 3;
+ bytes initialization_vector = 4; // Fixed sized array.
+ bytes encrypted_import_key = 5;
+ bytes aad = 6;
+ bytes gcm_tag = 7; // Fixed sized array.
+ KeyBlob wrapping_key_blob = 8;
+ bytes masking_key = 9; // Fixed sized array.
+ uint64 creation_time_ms = 10; // Rough current time (ms since epoch).
+}
+// ImportWrappedKey returns a ImportKeyResponse.
+
+// GetHmacSharingParametersRequest
+message GetHmacSharingParametersRequest {
+}
+message GetHmacSharingParametersResponse {
+ ErrorCode error_code = 1;
+ HmacSharingParameters hmac_sharing_params = 2;
+}
+
+// ComputeSharedHmacRequest
+message ComputeSharedHmacRequest {
+ repeated HmacSharingParameters hmac_sharing_params = 1;
+}
+message ComputeSharedHmacResponse {
+ ErrorCode error_code = 1;
+ bytes sharing_check = 2;
+}
+
+// DeviceLockedRequest
+message DeviceLockedRequest {
+ bool password_only = 1;
+ VerificationToken verification_token = 2;
+}
+message DeviceLockedResponse {
+ ErrorCode error_code = 1;
+}
+
+// DeviceLockedRequest
+message EarlyBootEndedRequest {}
+message EarlyBootEndedResponse {
+ ErrorCode error_code = 1;
+}
+
+/*
+ * Vendor HAL.
+ */
+
+// SetRootOfTrustRequest
+// Only callable by the Bootloader.
+message SetRootOfTrustRequest {
+ bytes digest = 1; // This is a SHA256 digest.
+}
+message SetRootOfTrustResponse {
+ // Specified in keymaster_defs.proto:ErrorCode
+ ErrorCode error_code = 1;
+}
+
+// SetBootStateRequest
+// Only callable by the Bootloader.
+message SetBootStateRequest {
+ bool is_unlocked = 1;
+ bytes public_key = 2; // This is a SHA256 digest.
+ BootColor color = 3;
+ uint32 system_version = 4; // Deprecated.
+ uint32 system_security_level = 5; // Patch level of the boot partition.
+ bytes boot_hash = 6; // This is a SHA256 digest.
+ uint32 boot_security_level = 7;
+}
+message SetBootStateResponse {
+ // Specified in keymaster_defs.proto:ErrorCode
+ ErrorCode error_code = 1;
+}
+
+// ProvisionDeviceIds
+// Only callable at the Device Factory
+message ProvisionDeviceIdsRequest {
+ bytes product_brand = 1;
+ bytes product_device = 2;
+ bytes product_name = 3;
+ bytes serialno = 4;
+ bytes product_manufacturer = 5;
+ bytes product_model = 6;
+ bytes imei = 7;
+ bytes meid = 8;
+ bytes imei2 = 9;
+}
+message ProvisionDeviceIdsResponse {
+ // Specified in keymaster_defs.proto:ErrorCode
+ ErrorCode error_code = 1;
+ ChipFusing chip_fusing = 2;
+ bool nodelocked_ro = 3;
+}
+
+message ExportDeviceIdsRequest {
+ bytes challenge = 1;
+ bytes challenge_hmac = 2;
+}
+
+message ExportDeviceIdsResponse {
+ ErrorCode error_code = 1;
+ bytes product_brand = 2;
+ bytes product_device = 3;
+ bytes product_name = 4;
+ bytes serialno = 5;
+ bytes product_manufacturer = 6;
+ bytes product_model = 7;
+ bytes imei = 8;
+ bytes meid = 9;
+ bytes ids_hmac = 10;
+}
+
+// ReadTeeBatchCertificate
+// Only callable at the Device Factory
+message ReadTeeBatchCertificateRequest {
+ Algorithm algorithm = 1;
+}
+message ReadTeeBatchCertificateResponse {
+ ErrorCode error_code = 1;
+ RSAKey rsa = 2; // rsa or ec set based on request algorithm selector.
+ ECKey ec = 3;
+ bytes batch_cert = 4;
+}
+
+message DTupHandshakeRequest {
+ bytes nonce_client = 1;
+}
+
+message DTupHandshakeResponse {
+ DTupError error_code = 1;
+ bytes nonce_citadel = 2;
+ bytes signature = 3;
+}
+
+message DTupFetchInputEventRequest {}
+
+message DTupFetchInputEventResponse {
+ DTupError error_code = 1;
+ DTupKeyEvent event = 2;
+ bytes signature = 3;
+}
+
+message SetSystemVersionInfoRequest {
+ uint32 system_version = 1; // getprop "ro.build.version.release"
+ uint32 system_security_level = 2; // getprop "ro.build.version.security_patch"
+ uint32 vendor_security_level = 3; // getprop "ro.vendor.build.security_patch"
+ uint32 vendor_api_level = 4;
+}
+
+message SetSystemVersionInfoResponse {
+ // Specified in keymaster_defs.proto:ErrorCode
+ ErrorCode error_code = 1;
+}
+
+message GetBootInfoRequest {}
+
+message GetBootInfoResponse {
+ ErrorCode error_code = 1;
+ bool is_unlocked = 2;
+ BootColor boot_color = 3;
+ bytes boot_key = 4; // This is a SHA256 digest.
+ bytes boot_hash = 5; // This is a SHA256 digest.
+}
+
+message ProvisionPresharedSecretRequest {
+ bytes preshared_secret = 1;
+ bool get_status = 2;
+}
+message ProvisionPresharedSecretResponse {
+ ErrorCode error_code = 1;
+ PresharedSecretStatus status = 2;
+ BootColor color = 3;
+ bytes digest = 4;
+}
+
+message ProvisionCertificatesRequest {
+ uint32 block_number = 1;
+ bytes cert_block = 2;
+ bytes digest = 3;
+}
+message ProvisionCertificatesResponse {
+ ErrorCode error_code = 1;
+ CertificateStatus cert_status = 2;
+}
+
+message ReadCertificateRequest {
+ AttestationSelector selector = 1;
+ Algorithm algorithm = 2;
+}
+message ReadCertificateResponse {
+ ErrorCode error_code = 1;
+ Certificate cert = 2;
+}
+
+message VigoReadVSRequest {}
+message VigoReadVSResponse {
+ ErrorCode error_code = 1;
+ VigoKey vs_key = 2;
+}
+message VigoStartChannelRequest {
+ VigoKey client_key = 1;
+}
+message VigoStartChannelResponse {
+ ErrorCode error_code = 1;
+ VigoKey server_key = 2;
+ VigoSignature channel_signature = 3;
+}
+message VigoStoreSecretRequest {
+ VigoKey rs_key = 1;
+ VigoSecret secret_encrypted = 2;
+}
+message VigoStoreSecretResponse {
+ ErrorCode error_code = 1;
+}
+message VigoReleaseSecretRequest {
+ VigoSignature rs_signature = 1;
+}
+message VigoReleaseSecretResponse {
+ ErrorCode error_code = 1;
+ VigoSecret secret_encrypted = 2;
+}
+
+// IdentityStartAttestKey
+message IdentityStartAttestKeyRequest {
+ bytes pubkey = 1;
+ KeyParameters params = 2;
+ uint32 attestation_app_id_len = 3;
+ AttestationSelector selector = 4;
+ bytes not_before = 5; // strftime('%y%m%d%H%M%SZ') [15 octects]
+ bytes not_after = 6; // strftime('%y%m%d%H%M%SZ') [15 octects]
+ uint64 creation_time_ms = 7; // Rough current time (ms since epoch).
+ bool use_km_attest_key = 8;
+ bytes caller_issuer_subj_name = 9;
+}
+message IdentityStartAttestKeyResponse {
+ ErrorCode error_code = 1;
+ OperationHandle handle = 2;
+ bytes certificate_prologue = 3;
+}
+
+// IdentityFinishAttestKeyRequest
+message IdentityFinishAttestKeyRequest {
+ OperationHandle handle = 1;
+ bool use_km_attest_key = 2;
+ KeyBlob caller_blob = 3;
+}
+message IdentityFinishAttestKeyResponse {
+ ErrorCode error_code = 1;
+ bytes certificate_epilogue = 2;
+ ChipFusing chip_fusing = 3;
+ bool nodelocked_ro = 4;
+}
+
+// pKVM messages
+message GetPerFactoryResetValueRequest {
+ bool bootloader_only = 1;
+ bytes input = 2;
+}
+message GetPerFactoryResetValueResponse {
+ ErrorCode error_code = 1;
+ bytes output = 2;
+}
+
+// RKP messages
+message GenerateRkpKeyRequest{
+ bool test_mode = 1;
+ KeyParameters params = 2;
+ KeyBlob blob = 3;
+}
+message GenerateRkpKeyResponse{
+ ErrorCode error_code = 1;
+ bytes maced_public_key = 2;
+}
+
+message GenerateRkpCsrRequest{
+ bool test_mode = 1;
+ KeysToSign keys_to_sign = 2;
+ bytes endpoint_enc_cert_chain = 3;
+ bytes challenge = 4;
+}
+message GenerateRkpCsrResponse{
+ ErrorCode error_code = 1;
+ bytes keys_to_sign_mac = 2;
+ bytes device_info_blob = 3;
+ bytes protected_data_blob = 4;
+}
+
+message GenerateRkpCsrV2Request{
+ RkpCsrV2Operation step = 1;
+ bytes challenge = 2;
+ uint32 num_of_public_keys = 3;
+ MacedKey key_to_sign = 4;
+ OperationHandle handle = 5;
+}
+message GenerateRkpCsrV2Response{
+ ErrorCode error_code = 1;
+ OperationHandle handle = 2;
+ bytes device_info_blob = 3;
+ bytes dice_cert_chain = 4;
+ bytes signature = 5;
+}
diff --git a/nugget/proto/nugget/app/keymaster/ctdl/keymaster_defs.proto b/nugget/proto/nugget/app/keymaster/ctdl/keymaster_defs.proto
new file mode 100644
index 0000000..1927026
--- /dev/null
+++ b/nugget/proto/nugget/app/keymaster/ctdl/keymaster_defs.proto
@@ -0,0 +1,340 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+syntax = "proto3";
+
+package nugget.app.keymaster.ctdl;
+
+/*
+ * Minimal type definitions required for building protos. Sourced from:
+ * ::android::hardware::keymaster::V3_0
+ */
+enum TagType {
+ TAG_TYPE_INVALID = 0x0; /* 0 << 16 */
+ ENUM = 0x10000; /* 1 << 16 */
+ ENUM_REP = 0x20000; /* 2 << 16 */
+ UINT = 0x30000; /* 3 << 16 */
+ UINT_REP = 0x40000; /* 4 << 16 */
+ ULONG = 0x50000; /* 5 << 16 */
+ DATE = 0x60000; /* 6 << 16 */
+ BOOL = 0x70000; /* 7 << 16 */
+ BIGNUM_ = 0x80000; /* 8 << 16 */
+ BYTES = 0x90000; /* 9 << 16 */
+ ULONG_REP = 0xA0000; /* 10 << 16 */
+};
+
+enum Tag {
+ TAG_INVALID = 0; // (TagType:INVALID | 0)
+ PURPOSE = 0x20001; // (TagType:ENUM_REP | 1)
+ ALGORITHM = 0x10002; // (TagType:ENUM | 2)
+ KEY_SIZE = 0x30003; // (TagType:UINT | 3)
+ BLOCK_MODE = 0x20004; // (TagType:ENUM_REP | 4)
+ DIGEST = 0x20005; // (TagType:ENUM_REP | 5)
+ PADDING = 0x20006; // (TagType:ENUM_REP | 6)
+ CALLER_NONCE = 0x70007; // (TagType:BOOL | 7)
+ MIN_MAC_LENGTH = 0x30008; // (TagType:UINT | 8)
+ /* RESERVED: KDF = 0x20009; // (TagType:ENUM_REP | 9) */
+ EC_CURVE = 0x1000a; // (TagType:ENUM | 10)
+ RSA_PUBLIC_EXPONENT = 0x500c8; // (TagType:ULONG | 200)
+ /* RESERVED: ECIES_SINGLE_HASH_MODE = 0x700c9; // (TagType:BOOL | 201) */
+ INCLUDE_UNIQUE_ID = 0x700ca; // (TagType:BOOL | 202)
+ RSA_OAEP_MGF_DIGEST = 0x200cb; // (TagType:ENUM_REP | 203)
+ BLOB_USAGE_REQUIREMENTS = 0x1012d; // (TagType:ENUM | 301)
+ BOOTLOADER_ONLY = 0x7012e; // (TagType:BOOL | 302)
+ ROLLBACK_RESISTANCE = 0x7012f; // (TagType:BOOL | 303)
+ HARDWARE_TYPE = 0x10130; // TagType:ENUM | 304,
+ EARLY_BOOT_ONLY = 0x70131; // TagType:BOOL | 305,
+ ACTIVE_DATETIME = 0x60190; // (TagType:DATE | 400)
+ ORIGINATION_EXPIRE_DATETIME = 0x60191; // (TagType:DATE | 401)
+ USAGE_EXPIRE_DATETIME = 0x60192; // (TagType:DATE | 402)
+ MIN_SECONDS_BETWEEN_OPS = 0x30193; // (TagType:UINT | 403)
+ MAX_USES_PER_BOOT = 0x30194; // (TagType:UINT | 404)
+ USAGE_COUNT_LIMIT = 0x30195; // (TagType:UINT | 405)
+ /* RESERVED: ALL_USERS = 0x701f4; // (TagType:BOOL | 500) */
+ USER_ID = 0x301f5; // (TagType:UINT | 501)
+ USER_SECURE_ID = 0xa01f6; // (TagType:ULONG_REP | 502)
+ NO_AUTH_REQUIRED = 0x701f7; // (TagType:BOOL | 503)
+ USER_AUTH_TYPE = 0x101f8; // (TagType:ENUM | 504)
+ AUTH_TIMEOUT = 0x301f9; // (TagType:UINT | 505)
+ ALLOW_WHILE_ON_BODY = 0x701fa; // (TagType:BOOL | 506)
+ TRUSTED_USER_PRESENCE_REQUIRED = 0x701fb; // (TagType:BOOL | 507)
+ TRUSTED_CONFIRMATION_REQUIRED = 0x701fc; // (TagType:BOOL | 508)
+ UNLOCKED_DEVICE_REQUIRED = 0x701fd; // (TagType:BOOL | 509)
+ /* RESERVED: ALL_APPLICATIONS = 0x70258; // (TagType:BOOL | 600) */
+ APPLICATION_ID = 0x90259; // (TagType:BYTES | 601)
+ /* RESERVED: EXPORTABLE = 0x7025a; // (TagType:BOOL | 602) */
+ APPLICATION_DATA = 0x902bc; // (TagType:BYTES | 700)
+ CREATION_DATETIME = 0x602bd; // (TagType:DATE | 701)
+ ORIGIN = 0x102be; // (TagType:ENUM | 702)
+ /* RESERVED: ROLLBACK_RESISTANT = 0x702bf; // (TagType:BOOL | 703) */
+ ROOT_OF_TRUST = 0x902c0; // (TagType:BYTES | 704)
+ OS_VERSION = 0x302c1; // (TagType:UINT | 705)
+ OS_PATCHLEVEL = 0x302c2; // (TagType:UINT | 706)
+ UNIQUE_ID = 0x902c3; // (TagType:BYTES | 707)
+ ATTESTATION_CHALLENGE = 0x902c4; // (TagType:BYTES | 708)
+ ATTESTATION_APPLICATION_ID = 0x902c5; // (TagType:BYTES | 709)
+ ATTESTATION_ID_BRAND = 0x902c6; // (TagType:BYTES | 710)
+ ATTESTATION_ID_DEVICE = 0x902c7; // (TagType:BYTES | 711)
+ ATTESTATION_ID_PRODUCT = 0x902c8; // (TagType:BYTES | 712)
+ ATTESTATION_ID_SERIAL = 0x902c9; // (TagType:BYTES | 713)
+ ATTESTATION_ID_IMEI = 0x902ca; // (TagType:BYTES | 714)
+ ATTESTATION_ID_MEID = 0x902cb; // (TagType:BYTES | 715)
+ ATTESTATION_ID_MANUFACTURER = 0x902cc; // (TagType:BYTES | 716)
+ ATTESTATION_ID_MODEL = 0x902cd; // (TagType:BYTES | 717)
+ VENDOR_PATCHLEVEL = 0x302ce; // (TagType:UINT | 718)
+ BOOT_PATCHLEVEL = 0x302cf; // (TagType:UINT | 719)
+ DEVICE_UNIQUE_ATTESTATION = 0x702d0; // (TagType:BOOL | 720)
+ IDENTITY_CREDENTIAL_KEY = 0x702d1; // (TagType:BOOL | 721)
+ STORAGE_KEY = 0x702d2; // (TagType:BOOL | 722)
+ ATTESTATION_ID_SECOND_IMEI = 0x902d3; // (TagType:BYTES | 723)
+ ASSOCIATED_DATA = 0x903e8; // (TagType:BYTES | 1000)
+ NONCE = 0x903e9; // (TagType:BYTES | 1001)
+ /* RESERVED: AUTH_TOKEN = 0x903ea; // (TagType:BYTES | 1002) */
+ MAC_LENGTH = 0x303eb; // (TagType:UINT | 1003)
+ RESET_SINCE_ID_ROTATION = 0x703ec; // (TagType:BOOL | 1004)
+ CONFIRMATION_TOKEN = 0x903ed; // (TagType:BYTES | 1005)
+ CERTIFICATE_SERIAL = 0x803ee; // (TagType:BIGNUM | 1006)
+ CERTIFICATE_SUBJECT = 0x903ef; // (TagType:BYTES | 1007)
+};
+
+enum Algorithm {
+ RSA = 0;
+ EC = 1;
+ AES = 2;
+ DES = 3;
+ HMAC = 4;
+ ALGORITHM_MAX = 5;
+};
+
+enum BlockMode {
+ ECB = 0;
+ CBC = 1;
+ CTR = 2;
+ GCM = 3;
+ BLOCK_MODE_MAX = 4;
+};
+
+enum PaddingMode {
+ PADDING_NONE = 0;
+ PADDING_RSA_OAEP = 1;
+ PADDING_RSA_PSS = 2;
+ PADDING_RSA_PKCS1_1_5_ENCRYPT = 3;
+ PADDING_RSA_PKCS1_1_5_SIGN = 4;
+ PADDING_PKCS7 = 5;
+ PADDING_MODE_MAX = 6;
+};
+
+enum Digest {
+ DIGEST_NONE = 0;
+ DIGEST_MD5 = 1;
+ DIGEST_SHA1 = 2;
+ DIGEST_SHA_2_224 = 3;
+ DIGEST_SHA_2_256 = 4;
+ DIGEST_SHA_2_384 = 5;
+ DIGEST_SHA_2_512 = 6;
+ DIGEST_MAX = 7;
+};
+
+enum EcCurve {
+ P_224 = 0;
+ P_256 = 1;
+ P_384 = 2;
+ P_521 = 3;
+ EC_CURVE_MAX = 4;
+};
+
+enum KeyOrigin {
+ GENERATED = 0;
+ DERIVED = 1;
+ IMPORTED = 2;
+ UNKNOWN = 3;
+ SECURELY_IMPORTED = 4;
+ KEY_ORIGIN_MAX = 5;
+};
+
+enum KeyBlobUsageRequirements {
+ STANDALONE = 0;
+ REQUIRES_FILE_SYSTEM = 1;
+ KEY_USAGE_MAX = 2;
+};
+
+enum KeyPurpose {
+ ENCRYPT = 0;
+ DECRYPT = 1;
+ SIGN = 2;
+ VERIFY = 3;
+ /* RESERVED: DERIVE_KEY = 4; */
+ WRAP_KEY = 5;
+ AGREE_KEY = 6;
+ ATTEST_KEY = 7;
+ PURPOSE_MAX = 8;
+};
+
+enum ErrorCode {
+ OK = 0;
+ ROOT_OF_TRUST_ALREADY_SET = 1;
+ UNSUPPORTED_PURPOSE = 2;
+ INCOMPATIBLE_PURPOSE = 3;
+ UNSUPPORTED_ALGORITHM = 4;
+ INCOMPATIBLE_ALGORITHM = 5;
+ UNSUPPORTED_KEY_SIZE = 6;
+ UNSUPPORTED_BLOCK_MODE = 7;
+ INCOMPATIBLE_BLOCK_MODE = 8;
+ UNSUPPORTED_MAC_LENGTH = 9;
+ UNSUPPORTED_PADDING_MODE = 10;
+ INCOMPATIBLE_PADDING_MODE = 11;
+ UNSUPPORTED_DIGEST = 12;
+ INCOMPATIBLE_DIGEST = 13;
+ INVALID_EXPIRATION_TIME = 14;
+ INVALID_USER_ID = 15;
+ INVALID_AUTHORIZATION_TIMEOUT = 16;
+ UNSUPPORTED_KEY_FORMAT = 17;
+ INCOMPATIBLE_KEY_FORMAT = 18;
+ UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM = 19;
+ UNSUPPORTED_KEY_VERIFICATION_ALGORITHM = 20;
+ INVALID_INPUT_LENGTH = 21;
+ KEY_EXPORT_OPTIONS_INVALID = 22;
+ DELEGATION_NOT_ALLOWED = 23;
+ KEY_NOT_YET_VALID = 24;
+ KEY_EXPIRED = 25;
+ KEY_USER_NOT_AUTHENTICATED = 26;
+ OUTPUT_PARAMETER_NULL = 27;
+ INVALID_OPERATION_HANDLE = 28;
+ INSUFFICIENT_BUFFER_SPACE = 29;
+ VERIFICATION_FAILED = 30;
+ TOO_MANY_OPERATIONS = 31;
+ UNEXPECTED_NULL_POINTER = 32;
+ INVALID_KEY_BLOB = 33;
+ IMPORTED_KEY_NOT_ENCRYPTED = 34;
+ IMPORTED_KEY_DECRYPTION_FAILED = 35;
+ IMPORTED_KEY_NOT_SIGNED = 36;
+ IMPORTED_KEY_VERIFICATION_FAILED = 37;
+ INVALID_ARGUMENT = 38;
+ UNSUPPORTED_TAG = 39;
+ INVALID_TAG = 40;
+ MEMORY_ALLOCATION_FAILED = 41;
+ IMPORT_PARAMETER_MISMATCH = 42;
+ SECURE_HW_ACCESS_DENIED = 43;
+ OPERATION_CANCELLED = 44;
+ CONCURRENT_ACCESS_CONFLICT = 45;
+ SECURE_HW_BUSY = 46;
+ SECURE_HW_COMMUNICATION_FAILED = 47;
+ UNSUPPORTED_EC_FIELD = 48;
+ MISSING_NONCE = 49;
+ INVALID_NONCE = 50;
+ MISSING_MAC_LENGTH = 51;
+ KEY_RATE_LIMIT_EXCEEDED = 52;
+ CALLER_NONCE_PROHIBITED = 53;
+ KEY_MAX_OPS_EXCEEDED = 54;
+ INVALID_MAC_LENGTH = 55;
+ MISSING_MIN_MAC_LENGTH = 56;
+ UNSUPPORTED_MIN_MAC_LENGTH = 57;
+ UNSUPPORTED_KDF = 58;
+ UNSUPPORTED_EC_CURVE = 59;
+ KEY_REQUIRES_UPGRADE = 60;
+ ATTESTATION_CHALLENGE_MISSING = 61;
+ KEYMASTER_NOT_CONFIGURED = 62;
+ ATTESTATION_APPLICATION_ID_MISSING = 63;
+ CANNOT_ATTEST_IDS = 64;
+ UNIMPLEMENTED = 65;
+ VERSION_MISMATCH = 66;
+ ROLLBACK_RESISTANCE_UNAVAILABLE = 67;
+ HARDWARE_TYPE_UNAVAILABLE = 68;
+ PROOF_OF_PRESENCE_REQUIRED = 69;
+ CONCURRENT_PROOF_OF_PRESENCE_REQUESTED = 70;
+ UNKNOWN_ERROR = 71;
+ INVALID_DEVICE_IDS = 72; // Vendor specific.
+ PRODUCTION_MODE_PROVISIONING = 73; // Vendor specific.
+ NO_USER_CONFIRMATION = 74;
+ KEY_UPGRADE_NOT_REQUIRED = 75; // Vendor specific.
+ DEVICE_LOCKED = 76;
+ EARLY_BOOT_ENDED = 77;
+ ATTESTATION_KEYS_NOT_PROVISIONED = 78;
+ ATTESTATION_IDS_NOT_PROVISIONED = 79;
+ INVALID_OPERATION = 80;
+ STORAGE_KEY_UNSUPPORTED = 81;
+ INCOMPATIBLE_MGF_DIGEST = 82;
+ UNSUPPORTED_MGF_DIGEST = 83;
+ INVALID_MAC = 84; // RKP specific.
+ PRODUCTION_KEY_IN_TEST_REQUEST = 85; // RKP specific.
+ TEST_KEY_IN_PRODUCTION_REQUEST = 86; // RKP specific.
+ INVALID_EEK = 87; // RKP specific.
+};
+
+enum SecurityLevel {
+ SOFTWARE = 0;
+ TRUSTED_ENVIRONMENT = 1;
+ STRONGBOX = 2;
+};
+
+// NOTE: these enum values must be kept in sync with the HAL,
+// as they are used in an HMAC calculation.
+enum HardwareAuthenticatorType {
+ HW_AUTH_NONE = 0;
+ HW_AUTH_PASSWORD = 1;
+ HW_AUTH_FINGERPRINT = 2;
+ // Additional entries must be powers of 2.
+};
+
+enum KeyFormat {
+ X509 = 0; /* for public key export */
+ PKCS8 = 1; /* for asymmetric key pair import */
+ RAW = 3; /* for symmetric key import and export*/
+}
+
+enum DTupError {
+ DTUP_OK = 0;
+ DTUP_NO_EVENT = 1;
+}
+
+/* matches Linux event device codes */
+enum DTupKeyEvent {
+ DTUP_RESERVED = 0;
+ DTUP_VOL_DOWN = 114;
+ DTUP_VOL_UP = 115;
+ DTUP_PWR = 116;
+}
+
+enum BootColor {
+ BOOT_VERIFIED_GREEN = 0;
+ BOOT_SELFSIGNED_YELLOW = 1;
+ BOOT_UNVERIFIED_ORANGE = 2;
+ BOOT_VERIFY_FAILED_RED = 3;
+}
+
+enum ChipFusing {
+ FUSING_PROTO = 0;
+ FUSING_DVT = 1;
+ FUSING_PVT = 2; // Strongbox gen v0 certs.
+ FUSING_PVT_1 = 3; // Strongbox gen v1 certs.
+ FUSING_D_PVT = 4; // Dauntless gen v0 certs.
+ FUSING_D_PVT_1 = 5; // Dauntless gen v1 certs.
+ FUSING_D_PVT_2 = 6; // Dauntless gen v2 certs (D3M2).
+}
+
+enum CertificateStatus {
+ CERT_PREVIOUSLY_PROVISIONED = 0;
+ CERT_MISSING = 1;
+ CERT_CHECKSUM = 2;
+ CERT_UNKNOWN_ERROR = 3;
+ CERT_WRONG_PACKET = 4;
+}
+
+enum RkpCsrV2Operation {
+ RKP_CSR_V2_BEGIN = 0;
+ RKP_CSR_V2_UPDATE = 1;
+ RKP_CSR_V2_FINISH = 2;
+}
diff --git a/nugget/proto/nugget/app/keymaster/ctdl/keymaster_types.options b/nugget/proto/nugget/app/keymaster/ctdl/keymaster_types.options
new file mode 100644
index 0000000..b38e786
--- /dev/null
+++ b/nugget/proto/nugget/app/keymaster/ctdl/keymaster_types.options
@@ -0,0 +1,12 @@
+nugget.app.keymaster.ctdl.KeyParameters.params max_count:20
+nugget.app.keymaster.ctdl.HmacSharingParameters.seed max_size:32
+nugget.app.keymaster.ctdl.HmacSharingParameters.nonce max_size:32
+nugget.app.keymaster.ctdl.HardwareAuthToken.mac max_size:32
+nugget.app.keymaster.ctdl.VerificationToken.mac max_size:32
+nugget.app.keymaster.ctdl.VigoKey.x max_size:64
+nugget.app.keymaster.ctdl.VigoSignature.r max_size:32
+nugget.app.keymaster.ctdl.VigoSignature.s max_size:32
+nugget.app.keymaster.ctdl.VigoSecret.material max_size:32
+nugget.app.keymaster.ctdl.VigoSecret.iv max_size:16
+nugget.app.keymaster.ctdl.VigoSecret.tag max_size:16
+nugget.app.keymaster.ctdl.KeysToSign.keys max_count:20
diff --git a/nugget/proto/nugget/app/keymaster/ctdl/keymaster_types.proto b/nugget/proto/nugget/app/keymaster/ctdl/keymaster_types.proto
new file mode 100644
index 0000000..6a8f5a8
--- /dev/null
+++ b/nugget/proto/nugget/app/keymaster/ctdl/keymaster_types.proto
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+syntax = "proto3";
+
+package nugget.app.keymaster.ctdl;
+
+import "nugget/app/keymaster/ctdl/keymaster_defs.proto";
+
+message KeyParameter {
+ Tag tag = 1; /* Possible values defined here
+ * ::android::hardware::keymaster::V3_0::Tag
+ */
+ uint32 integer = 2;
+ uint64 long_integer = 3;
+ bytes blob = 4;
+}
+
+message KeyParameters {
+ repeated KeyParameter params = 1;
+}
+
+message KeyBlob {
+ bytes blob = 1;
+}
+
+message OperationHandle {
+ uint64 handle = 1;
+}
+
+message Certificate {
+ bytes data = 1;
+}
+
+message CertificateChain {
+ repeated Certificate certificates = 1;
+}
+
+message KeyCharacteristics {
+ KeyParameters software_enforced = 1;
+ KeyParameters tee_enforced = 2;
+}
+
+message HmacSharingParameters {
+ bytes seed = 1;
+ bytes nonce = 2;
+}
+
+message HardwareAuthToken {
+ uint64 challenge = 1;
+ uint64 user_id = 2;
+ uint64 authenticator_id = 3;
+ // Deprecated in favor of tag 7.
+ // HardwareAuthenticatorType authenticator_type = 4;
+ uint64 timestamp = 5;
+ bytes mac = 6;
+ uint32 authenticator_type = 7;
+}
+
+message VerificationToken {
+ uint64 challenge = 1;
+ uint64 timestamp = 2;
+ KeyParameters params_verified = 3;
+ SecurityLevel security_level = 4;
+ bytes mac = 5;
+}
+
+/*
+ * Internal types.
+ */
+message RSAKey {
+ uint32 e = 1;
+ bytes d = 2;
+ bytes n = 3;
+}
+
+message ECKey {
+ /* TODO: should this be EcCurve. */
+ uint32 curve_id = 1;
+ bytes d = 2;
+ bytes x = 3;
+ bytes y = 4;
+}
+
+message SymmetricKey {
+ bytes material = 1;
+}
+
+enum PresharedSecretStatus {
+ NOT_SET = 0;
+ ALREADY_SET = 1;
+}
+
+enum AttestationSelector {
+ ATTEST_TEST = 0;
+ ATTEST_BATCH = 1;
+ ATTEST_INDIVIDUAL = 2;
+ ATTEST_SELF = 3;
+ ATTEST_CALLER = 4;
+}
+
+message VigoKey {
+ bytes x = 1;
+}
+
+message VigoSignature {
+ bytes r = 1;
+ bytes s = 2;
+}
+
+message VigoSecret {
+ bytes material = 1;
+ bytes iv = 2;
+ bytes tag = 3;
+}
+
+message MacedKey{
+ bytes blob = 1;
+}
+
+message KeysToSign {
+ repeated MacedKey keys = 1;
+}
diff --git a/nugget/proto/nugget/app/keymaster/keymaster.proto b/nugget/proto/nugget/app/keymaster/keymaster.proto
index 89710e6..496018a 100644
--- a/nugget/proto/nugget/app/keymaster/keymaster.proto
+++ b/nugget/proto/nugget/app/keymaster/keymaster.proto
@@ -149,6 +149,15 @@ service Keymaster {
rpc GenerateRkpKey(GenerateRkpKeyRequest) returns (GenerateRkpKeyResponse);
rpc GenerateRkpCsr(GenerateRkpCsrRequest) returns (GenerateRkpCsrResponse);
+ /*
+ * Vendor specific method. To export IMEI/DSU to trusty only
+ */
+ rpc ExportDeviceIds(ExportDeviceIdsRequest) returns (ExportDeviceIdsResponse);
+
+ /*
+ * RKP v3 implementation
+ */
+ rpc GenerateRkpCsrV2(GenerateRkpCsrV2Request) returns (GenerateRkpCsrV2Response);
// These are implemented with a enum, so new RPCs must be appended, and
// deprecated RPCs need placeholders.
}
@@ -431,6 +440,7 @@ message ProvisionDeviceIdsRequest {
bytes product_model = 6;
bytes imei = 7;
bytes meid = 8;
+ bytes imei2 = 9;
}
message ProvisionDeviceIdsResponse {
// Specified in keymaster_defs.proto:ErrorCode
@@ -439,6 +449,24 @@ message ProvisionDeviceIdsResponse {
bool nodelocked_ro = 3;
}
+message ExportDeviceIdsRequest {
+ bytes challenge = 1;
+ bytes challenge_hmac = 2;
+}
+
+message ExportDeviceIdsResponse {
+ ErrorCode error_code = 1;
+ bytes product_brand = 2;
+ bytes product_device = 3;
+ bytes product_name = 4;
+ bytes serialno = 5;
+ bytes product_manufacturer = 6;
+ bytes product_model = 7;
+ bytes imei = 8;
+ bytes meid = 9;
+ bytes ids_hmac = 10;
+}
+
// ReadTeeBatchCertificate
// Only callable at the Device Factory
message ReadTeeBatchCertificateRequest {
@@ -473,6 +501,7 @@ message SetSystemVersionInfoRequest {
uint32 system_version = 1; // getprop "ro.build.version.release"
uint32 system_security_level = 2; // getprop "ro.build.version.security_patch"
uint32 vendor_security_level = 3; // getprop "ro.vendor.build.security_patch"
+ uint32 vendor_api_level = 4;
}
message SetSystemVersionInfoResponse {
@@ -612,3 +641,18 @@ message GenerateRkpCsrResponse{
bytes device_info_blob = 3;
bytes protected_data_blob = 4;
}
+
+message GenerateRkpCsrV2Request{
+ RkpCsrV2Operation step = 1;
+ bytes challenge = 2;
+ uint32 num_of_public_keys = 3;
+ MacedKey key_to_sign = 4;
+ OperationHandle handle = 5;
+}
+message GenerateRkpCsrV2Response{
+ ErrorCode error_code = 1;
+ OperationHandle handle = 2;
+ bytes device_info_blob = 3;
+ bytes dice_cert_chain = 4;
+ bytes signature = 5;
+}
diff --git a/nugget/proto/nugget/app/keymaster/keymaster_defs.proto b/nugget/proto/nugget/app/keymaster/keymaster_defs.proto
index dfdfeeb..db352c7 100644
--- a/nugget/proto/nugget/app/keymaster/keymaster_defs.proto
+++ b/nugget/proto/nugget/app/keymaster/keymaster_defs.proto
@@ -99,6 +99,7 @@ enum Tag {
DEVICE_UNIQUE_ATTESTATION = 0x702d0; // (TagType:BOOL | 720)
IDENTITY_CREDENTIAL_KEY = 0x702d1; // (TagType:BOOL | 721)
STORAGE_KEY = 0x702d2; // (TagType:BOOL | 722)
+ ATTESTATION_ID_SECOND_IMEI = 0x902d3; // (TagType:BYTES | 723)
ASSOCIATED_DATA = 0x903e8; // (TagType:BYTES | 1000)
NONCE = 0x903e9; // (TagType:BYTES | 1001)
/* RESERVED: AUTH_TOKEN = 0x903ea; // (TagType:BYTES | 1002) */
@@ -331,3 +332,9 @@ enum CertificateStatus {
CERT_UNKNOWN_ERROR = 3;
CERT_WRONG_PACKET = 4;
}
+
+enum RkpCsrV2Operation {
+ RKP_CSR_V2_BEGIN = 0;
+ RKP_CSR_V2_UPDATE = 1;
+ RKP_CSR_V2_FINISH = 2;
+}
diff --git a/nugget/proto/nugget/app/keymaster/keymaster_types.options b/nugget/proto/nugget/app/keymaster/keymaster_types.options
index 417e181..6ffce96 100644
--- a/nugget/proto/nugget/app/keymaster/keymaster_types.options
+++ b/nugget/proto/nugget/app/keymaster/keymaster_types.options
@@ -1,4 +1,4 @@
-nugget.app.keymaster.KeyParameters.params max_count:20
+nugget.app.keymaster.KeyParameters.params max_count:25
nugget.app.keymaster.HmacSharingParameters.seed max_size:32
nugget.app.keymaster.HmacSharingParameters.nonce max_size:32
nugget.app.keymaster.HardwareAuthToken.mac max_size:32
diff --git a/nugget/proto/nugget/app/weaver/Android.bp b/nugget/proto/nugget/app/weaver/Android.bp
index 6a1dbde..1c4535a 100644
--- a/nugget/proto/nugget/app/weaver/Android.bp
+++ b/nugget/proto/nugget/app/weaver/Android.bp
@@ -26,7 +26,11 @@ package {
genrule {
name: "nos_app_weaver_service_genc++",
out: ["Weaver.client.cpp"],
- srcs: ["weaver.proto"],
+ srcs: [
+ "weaver.proto",
+ ":nugget_options_proto",
+ ":libprotobuf-internal-protos",
+ ],
tools: ["aprotoc", "protoc-gen-nos-client-cpp"],
cmd: GEN_SERVICE_SOURCE,
}
@@ -34,7 +38,11 @@ genrule {
genrule {
name: "nos_app_weaver_service_genc++_headers",
out: ["Weaver.client.h"],
- srcs: ["weaver.proto"],
+ srcs: [
+ "weaver.proto",
+ ":nugget_options_proto",
+ ":libprotobuf-internal-protos",
+ ],
tools: ["aprotoc", "protoc-gen-nos-client-cpp"],
cmd: GEN_SERVICE_HEADER,
}
@@ -42,7 +50,11 @@ genrule {
genrule {
name: "nos_app_weaver_service_genc++_mock",
out: ["MockWeaver.client.h"],
- srcs: ["weaver.proto"],
+ srcs: [
+ "weaver.proto",
+ ":nugget_options_proto",
+ ":libprotobuf-internal-protos",
+ ],
tools: ["aprotoc", "protoc-gen-nos-client-cpp"],
cmd: GEN_SERVICE_MOCK,
}