Merge "Update VTS test to blacklist only non-GPS satellites" into pi-dev
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 00d0aa5..531e44e 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -64,3 +64,5 @@
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/vndk/android.hardware.tests*)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/vndk-sp/android.hardware.graphics.allocator*)
$(call add-clean-step, find $(PRODUCT_OUT)/system $(PRODUCT_OUT)/vendor -type f -name "android\.hardware\.configstore\@1\.1*" -print0 | xargs -0 rm -f)
+$(call add-clean-step, find $(PRODUCT_OUT)/system $(PRODUCT_OUT)/vendor -type f -name "android\.hardware\.configstore*" -print0 | xargs -0 rm -f)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/etc/seccomp_policy/configstore@1.0.policy)
diff --git a/audio/4.0/types.hal b/audio/4.0/types.hal
index 7b2035b..6b46b10 100644
--- a/audio/4.0/types.hal
+++ b/audio/4.0/types.hal
@@ -184,9 +184,9 @@
* Simple processing as constant gain adjustment must be DIRECT.
*/
enum AudioMicrophoneChannelMapping : uint32_t {
- UNUSED = 0, /** Channel not used */
- DIRECT = 1, /** Channel used and signal not processed */
- PROCESSED = 2, /** Channel used and signal has some process */
+ UNUSED = 0, /* Channel not used */
+ DIRECT = 1, /* Channel used and signal not processed */
+ PROCESSED = 2, /* Channel used and signal has some process */
};
/**
diff --git a/audio/common/all-versions/default/service/android.hardware.audio@2.0-service.rc b/audio/common/all-versions/default/service/android.hardware.audio@2.0-service.rc
index a76770d..8217b94 100644
--- a/audio/common/all-versions/default/service/android.hardware.audio@2.0-service.rc
+++ b/audio/common/all-versions/default/service/android.hardware.audio@2.0-service.rc
@@ -9,3 +9,5 @@
# and its .rc file has an "onrestart restart audio-hal" rule, thus
# an additional auto-restart from the init process isn't needed.
oneshot
+ interface android.hardware.audio@4.0::IDevicesFactory default
+ interface android.hardware.audio@2.0::IDevicesFactory default
diff --git a/automotive/vehicle/2.0/Android.bp b/automotive/vehicle/2.0/Android.bp
index 91255d0..6af774e 100644
--- a/automotive/vehicle/2.0/Android.bp
+++ b/automotive/vehicle/2.0/Android.bp
@@ -41,6 +41,7 @@
"VehicleAreaDoor",
"VehicleAreaMirror",
"VehicleAreaSeat",
+ "VehicleAreaWheel",
"VehicleAreaWindow",
"VehicleDisplay",
"VehicleGear",
@@ -68,7 +69,6 @@
"VmsOfferingMessageIntegerValuesIndex",
"VmsPublisherInformationIntegerValuesIndex",
"VmsSubscriptionsStateIntegerValuesIndex",
- "Wheel",
],
gen_java: true,
}
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
index 012af1e..4ae94c0 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
@@ -40,7 +40,12 @@
constexpr int VEHICLE_MAP_SERVICE = (int)VehicleProperty::VEHICLE_MAP_SERVICE;
constexpr int WHEEL_TICK = (int)VehicleProperty::WHEEL_TICK;
constexpr int ALL_WHEELS =
- (int)(Wheel::LEFT_FRONT | Wheel::RIGHT_FRONT | Wheel::LEFT_REAR | Wheel::RIGHT_REAR);
+ (int)(VehicleAreaWheel::LEFT_FRONT | VehicleAreaWheel::RIGHT_FRONT |
+ VehicleAreaWheel::LEFT_REAR | VehicleAreaWheel::RIGHT_REAR);
+constexpr int HVAC_LEFT = (int)(VehicleAreaSeat::ROW_1_LEFT | VehicleAreaSeat::ROW_2_LEFT |
+ VehicleAreaSeat::ROW_2_CENTER);
+constexpr int HVAC_RIGHT = (int)(VehicleAreaSeat::ROW_1_RIGHT | VehicleAreaSeat::ROW_2_RIGHT);
+constexpr int HVAC_ALL = HVAC_LEFT | HVAC_RIGHT;
/**
* This property is used for test purpose to generate fake events. Here is the test package that
@@ -273,8 +278,7 @@
{.config = {.prop = toInt(VehicleProperty::HVAC_POWER_ON),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{
- .areaId = (VehicleAreaSeat::ROW_1_LEFT | VehicleAreaSeat::ROW_1_RIGHT)}},
+ .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}},
// TODO(bryaneyler): Ideally, this is generated dynamically from
// kHvacPowerProperties.
.configArray =
@@ -297,66 +301,56 @@
{.config = {.prop = toInt(VehicleProperty::HVAC_MAX_DEFROST_ON),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{
- .areaId = (VehicleAreaSeat::ROW_1_LEFT | VehicleAreaSeat::ROW_1_RIGHT)}}},
+ .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
.initialValue = {.int32Values = {0}}},
{.config = {.prop = toInt(VehicleProperty::HVAC_RECIRC_ON),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{
- .areaId = (VehicleAreaSeat::ROW_1_LEFT | VehicleAreaSeat::ROW_1_RIGHT)}}},
+ .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
.initialValue = {.int32Values = {1}}},
{.config = {.prop = toInt(VehicleProperty::HVAC_AUTO_RECIRC_ON),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{
- .areaId = (VehicleAreaSeat::ROW_1_LEFT | VehicleAreaSeat::ROW_1_RIGHT)}}},
+ .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
.initialValue = {.int32Values = {0}}},
{.config = {.prop = toInt(VehicleProperty::HVAC_AC_ON),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{
- .areaId = (VehicleAreaSeat::ROW_1_LEFT | VehicleAreaSeat::ROW_1_RIGHT)}}},
+ .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
.initialValue = {.int32Values = {1}}},
{.config = {.prop = toInt(VehicleProperty::HVAC_MAX_AC_ON),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{
- .areaId = (VehicleAreaSeat::ROW_1_LEFT | VehicleAreaSeat::ROW_1_RIGHT)}}},
+ .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
.initialValue = {.int32Values = {0}}},
{.config = {.prop = toInt(VehicleProperty::HVAC_AUTO_ON),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{
- .areaId = (VehicleAreaSeat::ROW_1_LEFT | VehicleAreaSeat::ROW_1_RIGHT)}}},
+ .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
.initialValue = {.int32Values = {1}}},
{.config = {.prop = toInt(VehicleProperty::HVAC_DUAL_ON),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{
- .areaId = (VehicleAreaSeat::ROW_1_LEFT | VehicleAreaSeat::ROW_1_RIGHT)}}},
+ .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
.initialValue = {.int32Values = {0}}},
{.config = {.prop = toInt(VehicleProperty::HVAC_FAN_SPEED),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.areaConfigs = {VehicleAreaConfig{
- .areaId = (VehicleAreaSeat::ROW_1_LEFT | VehicleAreaSeat::ROW_1_RIGHT),
- .minInt32Value = 1,
- .maxInt32Value = 7}}},
+ .areaId = HVAC_ALL, .minInt32Value = 1, .maxInt32Value = 7}}},
.initialValue = {.int32Values = {3}}},
{.config = {.prop = toInt(VehicleProperty::HVAC_FAN_DIRECTION),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{
- .areaId = (VehicleAreaSeat::ROW_1_LEFT | VehicleAreaSeat::ROW_1_RIGHT)}}},
+ .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
.initialValue = {.int32Values = {toInt(VehicleHvacFanDirection::FACE)}}},
{.config = {.prop = toInt(VehicleProperty::HVAC_STEERING_WHEEL_HEAT),
@@ -370,17 +364,13 @@
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.areaConfigs = {VehicleAreaConfig{
- .areaId = toInt(VehicleAreaSeat::ROW_1_LEFT),
- .minFloatValue = 16,
- .maxFloatValue = 32,
+ .areaId = HVAC_LEFT, .minFloatValue = 16, .maxFloatValue = 32,
},
VehicleAreaConfig{
- .areaId = toInt(VehicleAreaSeat::ROW_1_RIGHT),
- .minFloatValue = 16,
- .maxFloatValue = 32,
+ .areaId = HVAC_RIGHT, .minFloatValue = 16, .maxFloatValue = 32,
}}},
- .initialAreaValues = {{toInt(VehicleAreaSeat::ROW_1_LEFT), {.floatValues = {16}}},
- {toInt(VehicleAreaSeat::ROW_1_RIGHT), {.floatValues = {20}}}}},
+ .initialAreaValues = {{HVAC_LEFT, {.floatValues = {16}}},
+ {HVAC_RIGHT, {.floatValues = {20}}}}},
{.config =
{
@@ -495,8 +485,7 @@
{.config = {.prop = toInt(VehicleProperty::AP_POWER_STATE_REPORT),
.access = VehiclePropertyAccess::WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .configArray = {3}},
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE},
.initialValue = {.int32Values = {toInt(VehicleApPowerStateReport::BOOT_COMPLETE), 0}}},
{.config = {.prop = toInt(VehicleProperty::DISPLAY_BRIGHTNESS),
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
index fb54195..07695bf 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
@@ -139,10 +139,11 @@
return status;
}
} else if (mHvacPowerProps.count(propValue.prop)) {
- // TODO(75328113): this should be handled by property status
auto hvacPowerOn = mPropStore->readValueOrNull(
toInt(VehicleProperty::HVAC_POWER_ON),
- (VehicleAreaSeat::ROW_1_LEFT | VehicleAreaSeat::ROW_1_RIGHT));
+ (VehicleAreaSeat::ROW_1_LEFT | VehicleAreaSeat::ROW_1_RIGHT |
+ VehicleAreaSeat::ROW_2_LEFT | VehicleAreaSeat::ROW_2_CENTER |
+ VehicleAreaSeat::ROW_2_RIGHT));
if (hvacPowerOn && hvacPowerOn->value.int32Values.size() == 1
&& hvacPowerOn->value.int32Values[0] == 0) {
diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index 23f9b77..57179df 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -91,7 +91,7 @@
SEAT = 0x05000000,
/** DOOR maps to enum VehicleAreaDoor */
DOOR = 0x06000000,
- /** WHEEL maps to enum Wheel */
+ /** WHEEL maps to enum VehicleAreaWheel */
WHEEL = 0x07000000,
MASK = 0x0f000000,
@@ -501,7 +501,8 @@
/**
* Tire pressure
*
- * The min/max range is used to indicate the recommended tire pressure.
+ * min/max value indicates tire pressure sensor range. Each tire will have a separate min/max
+ * value denoted by its areaConfig.areaId.
*
* @change_mode VehiclePropertyChangeMode:CONTINUOUS
* @access VehiclePropertyAccess:READ
@@ -510,7 +511,7 @@
TIRE_PRESSURE = (
0x0309
| VehiclePropertyGroup:SYSTEM
- | VehiclePropertyType:MIXED
+ | VehiclePropertyType:FLOAT
| VehicleArea:WHEEL),
/**
@@ -1090,8 +1091,8 @@
* It is assumed that AP's power state is controller by separate power
* controller.
*
- * For configuration information, VehiclePropConfig.configFlags can
- * have bit flag combining values in VehicleApPowerStateConfigFlag.
+ * For configuration information, VehiclePropConfig.configArray can have bit flag combining
+ * values in VehicleApPowerStateConfigFlag.
*
* int32Values[0] : VehicleApPowerStateReq enum value
* int32Values[1] : additional parameter relevant for each state,
@@ -2582,14 +2583,6 @@
*/
vec<VehicleAreaConfig> areaConfigs;
- /**
- * Configuration flags for this property.
- *
- * For example, it may store the number of presets that are stored by the
- * radio module.
- */
- int32_t configFlags;
-
/** Contains additional configuration parameters */
vec<int32_t> configArray;
@@ -2754,7 +2747,7 @@
INTERNAL_ERROR = 5,
};
-enum Wheel : int32_t {
+enum VehicleAreaWheel : int32_t {
UNKNOWN = 0x0,
LEFT_FRONT = 0x1,
diff --git a/broadcastradio/1.0/types.hal b/broadcastradio/1.0/types.hal
index 8c3ec11..259c7c9 100644
--- a/broadcastradio/1.0/types.hal
+++ b/broadcastradio/1.0/types.hal
@@ -136,7 +136,8 @@
uint32_t numAudioSources;
/** the hardware supports capture of audio source from audio HAL */
bool supportsCapture;
- vec<BandConfig> bands; /** band descriptors */
+ /** band descriptors */
+ vec<BandConfig> bands;
};
enum MetadataType : int32_t {
@@ -229,6 +230,7 @@
*/
uint32_t signalStrength;
- vec<MetaData> metadata; /** Metadata: PTY, song title etc. */
+ /** Metadata: PTY, song title etc. */
+ vec<MetaData> metadata;
};
diff --git a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
index 571b80c..62b0037 100644
--- a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
+++ b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
@@ -137,29 +137,30 @@
}
Return<void> TunerCallbackMock::onCurrentProgramInfoChanged(const ProgramInfo& info) {
- auto logically = utils::getType(info.logicallyTunedTo);
- if (logically != IdentifierType::INVALID) {
- EXPECT_TRUE(logically == IdentifierType::AMFM_FREQUENCY ||
- logically == IdentifierType::RDS_PI ||
- logically == IdentifierType::HD_STATION_ID_EXT ||
- logically == IdentifierType::DAB_SID_EXT ||
- logically == IdentifierType::DRMO_SERVICE_ID ||
- logically == IdentifierType::SXM_SERVICE_ID ||
- (logically >= IdentifierType::VENDOR_START &&
- logically <= IdentifierType::VENDOR_END) ||
- logically > IdentifierType::SXM_CHANNEL);
+ for (auto&& id : info.selector) {
+ EXPECT_NE(IdentifierType::INVALID, utils::getType(id));
}
+ auto logically = utils::getType(info.logicallyTunedTo);
+ /* This field is required for currently tuned program and should be INVALID
+ * for entries from the program list.
+ */
+ EXPECT_TRUE(
+ logically == IdentifierType::AMFM_FREQUENCY || logically == IdentifierType::RDS_PI ||
+ logically == IdentifierType::HD_STATION_ID_EXT ||
+ logically == IdentifierType::DAB_SID_EXT || logically == IdentifierType::DRMO_SERVICE_ID ||
+ logically == IdentifierType::SXM_SERVICE_ID ||
+ (logically >= IdentifierType::VENDOR_START && logically <= IdentifierType::VENDOR_END) ||
+ logically > IdentifierType::SXM_CHANNEL);
+
auto physically = utils::getType(info.physicallyTunedTo);
- if (physically != IdentifierType::INVALID) {
- EXPECT_TRUE(physically == IdentifierType::AMFM_FREQUENCY ||
- physically == IdentifierType::DAB_ENSEMBLE ||
- physically == IdentifierType::DRMO_FREQUENCY ||
- physically == IdentifierType::SXM_CHANNEL ||
- (physically >= IdentifierType::VENDOR_START &&
- physically <= IdentifierType::VENDOR_END) ||
- physically > IdentifierType::SXM_CHANNEL);
- }
+ // ditto (see "logically" above)
+ EXPECT_TRUE(
+ physically == IdentifierType::AMFM_FREQUENCY ||
+ physically == IdentifierType::DAB_ENSEMBLE ||
+ physically == IdentifierType::DRMO_FREQUENCY || physically == IdentifierType::SXM_CHANNEL ||
+ (physically >= IdentifierType::VENDOR_START && physically <= IdentifierType::VENDOR_END) ||
+ physically > IdentifierType::SXM_CHANNEL);
if (logically == IdentifierType::AMFM_FREQUENCY) {
auto ps = utils::getMetadataString(info, MetadataKey::RDS_PS);
diff --git a/broadcastradio/common/tests/IdentifierIterator_test.cpp b/broadcastradio/common/tests/IdentifierIterator_test.cpp
index 5bf222b..75e0d49 100644
--- a/broadcastradio/common/tests/IdentifierIterator_test.cpp
+++ b/broadcastradio/common/tests/IdentifierIterator_test.cpp
@@ -33,8 +33,8 @@
};
// clang-format on
- auto it = utils::begin(sel);
- auto end = utils::end(sel);
+ auto it = V2_0::begin(sel);
+ auto end = V2_0::end(sel);
ASSERT_NE(end, it);
EXPECT_EQ(sel.primaryId, *it);
@@ -46,8 +46,8 @@
TEST(IdentifierIteratorTest, empty) {
V2_0::ProgramSelector sel{};
- auto it = utils::begin(sel);
- auto end = utils::end(sel);
+ auto it = V2_0::begin(sel);
+ auto end = V2_0::end(sel);
ASSERT_NE(end, it++); // primary id is always present
ASSERT_EQ(end, it);
@@ -57,8 +57,8 @@
V2_0::ProgramSelector sel1{};
V2_0::ProgramSelector sel2{};
- auto it1 = utils::begin(sel1);
- auto it2 = utils::begin(sel2);
+ auto it1 = V2_0::begin(sel1);
+ auto it2 = V2_0::begin(sel2);
EXPECT_NE(it1, it2);
}
@@ -66,8 +66,8 @@
TEST(IdentifierIteratorTest, increments) {
V2_0::ProgramSelector sel{{}, {{}, {}}};
- auto it = utils::begin(sel);
- auto end = utils::end(sel);
+ auto it = V2_0::begin(sel);
+ auto end = V2_0::end(sel);
auto pre = it;
auto post = it;
@@ -102,8 +102,8 @@
auto isRdsPi = std::bind(typeEquals, _1, IdentifierType::RDS_PI);
auto isFreq = std::bind(typeEquals, _1, IdentifierType::AMFM_FREQUENCY);
- auto end = utils::end(sel);
- auto it = std::find_if(utils::begin(sel), end, isRdsPi);
+ auto end = V2_0::end(sel);
+ auto it = std::find_if(V2_0::begin(sel), end, isRdsPi);
ASSERT_NE(end, it);
EXPECT_EQ(rds_pi1, it->value);
@@ -111,7 +111,7 @@
ASSERT_NE(end, it);
EXPECT_EQ(rds_pi2, it->value);
- it = std::find_if(utils::begin(sel), end, isFreq);
+ it = std::find_if(V2_0::begin(sel), end, isFreq);
ASSERT_NE(end, it);
EXPECT_EQ(freq1, it->value);
@@ -120,4 +120,17 @@
EXPECT_EQ(freq2, it->value);
}
+TEST(IdentifierIteratorTest, rangeLoop) {
+ V2_0::ProgramSelector sel{{}, {{}, {}, {}}};
+
+ unsigned count = 0;
+ for (auto&& id : sel) {
+ ASSERT_EQ(0u, id.type);
+ count++;
+ }
+
+ const auto expectedCount = 1 + sel.secondaryIds.size();
+ ASSERT_EQ(expectedCount, count);
+}
+
} // anonymous namespace
diff --git a/broadcastradio/common/utils2x/Utils.cpp b/broadcastradio/common/utils2x/Utils.cpp
index 6fe9554..3e20b35 100644
--- a/broadcastradio/common/utils2x/Utils.cpp
+++ b/broadcastradio/common/utils2x/Utils.cpp
@@ -81,14 +81,6 @@
return mPos == rhs.mPos;
}
-IdentifierIterator begin(const V2_0::ProgramSelector& sel) {
- return IdentifierIterator(sel);
-}
-
-IdentifierIterator end(const V2_0::ProgramSelector& sel) {
- return IdentifierIterator(sel) + 1 /* primary id */ + sel.secondaryIds.size();
-}
-
FrequencyBand getBand(uint64_t freq) {
// keep in sync with
// frameworks/base/services/core/java/com/android/server/broadcastradio/hal2/Utils.java
@@ -411,6 +403,18 @@
}
} // namespace utils
+
+namespace V2_0 {
+
+utils::IdentifierIterator begin(const ProgramSelector& sel) {
+ return utils::IdentifierIterator(sel);
+}
+
+utils::IdentifierIterator end(const ProgramSelector& sel) {
+ return utils::IdentifierIterator(sel) + 1 /* primary id */ + sel.secondaryIds.size();
+}
+
+} // namespace V2_0
} // namespace broadcastradio
} // namespace hardware
} // namespace android
diff --git a/broadcastradio/common/utils2x/include/broadcastradio-utils-2x/Utils.h b/broadcastradio/common/utils2x/include/broadcastradio-utils-2x/Utils.h
index 5e51941..c4aecb2 100644
--- a/broadcastradio/common/utils2x/include/broadcastradio-utils-2x/Utils.h
+++ b/broadcastradio/common/utils2x/include/broadcastradio-utils-2x/Utils.h
@@ -69,9 +69,6 @@
size_t mPos = 0;
};
-IdentifierIterator begin(const V2_0::ProgramSelector& sel);
-IdentifierIterator end(const V2_0::ProgramSelector& sel);
-
/**
* Guesses band from the frequency value.
*
@@ -153,6 +150,13 @@
V2_0::ProgramIdentifier make_hdradio_station_name(const std::string& name);
} // namespace utils
+
+namespace V2_0 {
+
+utils::IdentifierIterator begin(const ProgramSelector& sel);
+utils::IdentifierIterator end(const ProgramSelector& sel);
+
+} // namespace V2_0
} // namespace broadcastradio
} // namespace hardware
} // namespace android
diff --git a/camera/common/1.0/default/CameraModule.cpp b/camera/common/1.0/default/CameraModule.cpp
index 9217a82..dc4e0f0 100644
--- a/camera/common/1.0/default/CameraModule.cpp
+++ b/camera/common/1.0/default/CameraModule.cpp
@@ -306,7 +306,7 @@
return ret;
}
CameraMetadata m;
- m = rawInfo.static_camera_characteristics;
+ m.append(rawInfo.static_camera_characteristics);
deriveCameraCharacteristicsKeys(rawInfo.device_version, m);
cameraInfo = rawInfo;
cameraInfo.static_camera_characteristics = m.release();
diff --git a/camera/device/3.2/default/CameraDeviceSession.cpp b/camera/device/3.2/default/CameraDeviceSession.cpp
index 1cef882..8d00264 100644
--- a/camera/device/3.2/default/CameraDeviceSession.cpp
+++ b/camera/device/3.2/default/CameraDeviceSession.cpp
@@ -18,6 +18,7 @@
#include <android/log.h>
#include <set>
+#include <cutils/properties.h>
#include <utils/Trace.h>
#include <hardware/gralloc.h>
#include <hardware/gralloc1.h>
@@ -31,9 +32,16 @@
namespace implementation {
// Size of request metadata fast message queue. Change to 0 to always use hwbinder buffer.
-static constexpr size_t CAMERA_REQUEST_METADATA_QUEUE_SIZE = 1 << 20 /* 1MB */;
+static constexpr int32_t CAMERA_REQUEST_METADATA_QUEUE_SIZE = 1 << 20 /* 1MB */;
// Size of result metadata fast message queue. Change to 0 to always use hwbinder buffer.
-static constexpr size_t CAMERA_RESULT_METADATA_QUEUE_SIZE = 1 << 20 /* 1MB */;
+static constexpr int32_t CAMERA_RESULT_METADATA_QUEUE_SIZE = 1 << 20 /* 1MB */;
+
+// Metadata sent by HAL will be replaced by a compact copy
+// if their (total size >= compact size + METADATA_SHRINK_ABS_THRESHOLD &&
+// total_size >= compact size * METADATA_SHRINK_REL_THRESHOLD)
+// Heuristically picked by size of one page
+static constexpr int METADATA_SHRINK_ABS_THRESHOLD = 4096;
+static constexpr int METADATA_SHRINK_REL_THRESHOLD = 2;
HandleImporter CameraDeviceSession::sHandleImporter;
const int CameraDeviceSession::ResultBatcher::NOT_BATCHED;
@@ -88,14 +96,30 @@
return true;
}
+ int32_t reqFMQSize = property_get_int32("ro.camera.req.fmq.size", /*default*/-1);
+ if (reqFMQSize < 0) {
+ reqFMQSize = CAMERA_REQUEST_METADATA_QUEUE_SIZE;
+ } else {
+ ALOGV("%s: request FMQ size overridden to %d", __FUNCTION__, reqFMQSize);
+ }
+
mRequestMetadataQueue = std::make_unique<RequestMetadataQueue>(
- CAMERA_REQUEST_METADATA_QUEUE_SIZE, false /* non blocking */);
+ static_cast<size_t>(reqFMQSize),
+ false /* non blocking */);
if (!mRequestMetadataQueue->isValid()) {
ALOGE("%s: invalid request fmq", __FUNCTION__);
return true;
}
+
+ int32_t resFMQSize = property_get_int32("ro.camera.res.fmq.size", /*default*/-1);
+ if (resFMQSize < 0) {
+ resFMQSize = CAMERA_RESULT_METADATA_QUEUE_SIZE;
+ } else {
+ ALOGV("%s: result FMQ size overridden to %d", __FUNCTION__, resFMQSize);
+ }
mResultMetadataQueue = std::make_shared<RequestMetadataQueue>(
- CAMERA_RESULT_METADATA_QUEUE_SIZE, false /* non blocking */);
+ static_cast<size_t>(resFMQSize),
+ false /* non blocking */);
if (!mResultMetadataQueue->isValid()) {
ALOGE("%s: invalid result fmq", __FUNCTION__);
return true;
@@ -780,13 +804,11 @@
mOverridenRequest.update(
ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST,
defaultBoost, 1);
- const camera_metadata_t *metaBuffer =
- mOverridenRequest.getAndLock();
- convertToHidl(metaBuffer, outMetadata);
- mOverridenRequest.unlock(metaBuffer);
- } else {
- convertToHidl(rawRequest, outMetadata);
}
+ const camera_metadata_t *metaBuffer =
+ mOverridenRequest.getAndLock();
+ convertToHidl(metaBuffer, outMetadata);
+ mOverridenRequest.unlock(metaBuffer);
}
}
return status;
@@ -1362,6 +1384,62 @@
return OK;
}
+// Static helper method to copy/shrink capture result metadata sent by HAL
+void CameraDeviceSession::sShrinkCaptureResult(
+ camera3_capture_result* dst, const camera3_capture_result* src,
+ std::vector<::android::hardware::camera::common::V1_0::helper::CameraMetadata>* mds,
+ std::vector<const camera_metadata_t*>* physCamMdArray,
+ bool handlePhysCam) {
+ *dst = *src;
+ if (sShouldShrink(src->result)) {
+ mds->emplace_back(sCreateCompactCopy(src->result));
+ dst->result = mds->back().getAndLock();
+ }
+
+ if (handlePhysCam) {
+ // First determine if we need to create new camera_metadata_t* array
+ bool needShrink = false;
+ for (uint32_t i = 0; i < src->num_physcam_metadata; i++) {
+ if (sShouldShrink(src->physcam_metadata[i])) {
+ needShrink = true;
+ }
+ }
+
+ if (!needShrink) return;
+
+ physCamMdArray->reserve(src->num_physcam_metadata);
+ dst->physcam_metadata = physCamMdArray->data();
+ for (uint32_t i = 0; i < src->num_physcam_metadata; i++) {
+ if (sShouldShrink(src->physcam_metadata[i])) {
+ mds->emplace_back(sCreateCompactCopy(src->physcam_metadata[i]));
+ dst->physcam_metadata[i] = mds->back().getAndLock();
+ } else {
+ dst->physcam_metadata[i] = src->physcam_metadata[i];
+ }
+ }
+ }
+}
+
+bool CameraDeviceSession::sShouldShrink(const camera_metadata_t* md) {
+ size_t compactSize = get_camera_metadata_compact_size(md);
+ size_t totalSize = get_camera_metadata_size(md);
+ if (totalSize >= compactSize + METADATA_SHRINK_ABS_THRESHOLD &&
+ totalSize >= compactSize * METADATA_SHRINK_REL_THRESHOLD) {
+ ALOGV("Camera metadata should be shrunk from %zu to %zu", totalSize, compactSize);
+ return true;
+ }
+ return false;
+}
+
+camera_metadata_t* CameraDeviceSession::sCreateCompactCopy(const camera_metadata_t* src) {
+ size_t compactSize = get_camera_metadata_compact_size(src);
+ void* buffer = calloc(1, compactSize);
+ if (buffer == nullptr) {
+ ALOGE("%s: Allocating %zu bytes failed", __FUNCTION__, compactSize);
+ }
+ return copy_camera_metadata(buffer, compactSize, src);
+}
+
/**
* Static callback forwarding methods from HAL to instance
*/
@@ -1372,7 +1450,13 @@
const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));
CaptureResult result = {};
- status_t ret = d->constructCaptureResult(result, hal_result);
+ camera3_capture_result shadowResult;
+ bool handlePhysCam = (d->mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_5);
+ std::vector<::android::hardware::camera::common::V1_0::helper::CameraMetadata> compactMds;
+ std::vector<const camera_metadata_t*> physCamMdArray;
+ sShrinkCaptureResult(&shadowResult, hal_result, &compactMds, &physCamMdArray, handlePhysCam);
+
+ status_t ret = d->constructCaptureResult(result, &shadowResult);
if (ret == OK) {
d->mResultBatcher.processCaptureResult(result);
}
diff --git a/camera/device/3.2/default/CameraDeviceSession.h b/camera/device/3.2/default/CameraDeviceSession.h
index 269cc06..af90e5a 100644
--- a/camera/device/3.2/default/CameraDeviceSession.h
+++ b/camera/device/3.2/default/CameraDeviceSession.h
@@ -141,7 +141,7 @@
};
camera3_device_t* mDevice;
- uint32_t mDeviceVersion;
+ const uint32_t mDeviceVersion;
bool mIsAELockAvailable;
bool mDerivePostRawSensKey;
uint32_t mNumPartialResults;
@@ -329,6 +329,17 @@
status_t constructCaptureResult(CaptureResult& result,
const camera3_capture_result *hal_result);
+
+ // Static helper method to copy/shrink capture result metadata sent by HAL
+ // Temporarily allocated metadata copy will be hold in mds
+ static void sShrinkCaptureResult(
+ camera3_capture_result* dst, const camera3_capture_result* src,
+ std::vector<::android::hardware::camera::common::V1_0::helper::CameraMetadata>* mds,
+ std::vector<const camera_metadata_t*>* physCamMdArray,
+ bool handlePhysCam);
+ static bool sShouldShrink(const camera_metadata_t* md);
+ static camera_metadata_t* sCreateCompactCopy(const camera_metadata_t* src);
+
private:
struct TrampolineSessionInterface_3_2 : public ICameraDeviceSession {
diff --git a/camera/device/3.4/default/CameraDeviceSession.cpp b/camera/device/3.4/default/CameraDeviceSession.cpp
index 9722c75..6a18161 100644
--- a/camera/device/3.4/default/CameraDeviceSession.cpp
+++ b/camera/device/3.4/default/CameraDeviceSession.cpp
@@ -479,31 +479,40 @@
const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));
CaptureResult result = {};
- status_t ret = d->constructCaptureResult(result.v3_2, hal_result);
+ camera3_capture_result shadowResult;
+ bool handlePhysCam = (d->mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_5);
+ std::vector<::android::hardware::camera::common::V1_0::helper::CameraMetadata> compactMds;
+ std::vector<const camera_metadata_t*> physCamMdArray;
+ sShrinkCaptureResult(&shadowResult, hal_result, &compactMds, &physCamMdArray, handlePhysCam);
+
+ status_t ret = d->constructCaptureResult(result.v3_2, &shadowResult);
if (ret != OK) {
return;
}
- if (hal_result->num_physcam_metadata > d->mPhysicalCameraIds.size()) {
- ALOGE("%s: Fatal: Invalid num_physcam_metadata %u", __FUNCTION__,
- hal_result->num_physcam_metadata);
- return;
- }
- result.physicalCameraMetadata.resize(hal_result->num_physcam_metadata);
- for (uint32_t i = 0; i < hal_result->num_physcam_metadata; i++) {
- std::string physicalId = hal_result->physcam_ids[i];
- if (d->mPhysicalCameraIds.find(physicalId) == d->mPhysicalCameraIds.end()) {
- ALOGE("%s: Fatal: Invalid physcam_ids[%u]: %s", __FUNCTION__,
- i, hal_result->physcam_ids[i]);
+ if (handlePhysCam) {
+ if (shadowResult.num_physcam_metadata > d->mPhysicalCameraIds.size()) {
+ ALOGE("%s: Fatal: Invalid num_physcam_metadata %u", __FUNCTION__,
+ shadowResult.num_physcam_metadata);
return;
}
- V3_2::CameraMetadata physicalMetadata;
- V3_2::implementation::convertToHidl(hal_result->physcam_metadata[i], &physicalMetadata);
- PhysicalCameraMetadata physicalCameraMetadata = {
- .fmqMetadataSize = 0,
- .physicalCameraId = physicalId,
- .metadata = physicalMetadata };
- result.physicalCameraMetadata[i] = physicalCameraMetadata;
+ result.physicalCameraMetadata.resize(shadowResult.num_physcam_metadata);
+ for (uint32_t i = 0; i < shadowResult.num_physcam_metadata; i++) {
+ std::string physicalId = shadowResult.physcam_ids[i];
+ if (d->mPhysicalCameraIds.find(physicalId) == d->mPhysicalCameraIds.end()) {
+ ALOGE("%s: Fatal: Invalid physcam_ids[%u]: %s", __FUNCTION__,
+ i, shadowResult.physcam_ids[i]);
+ return;
+ }
+ V3_2::CameraMetadata physicalMetadata;
+ V3_2::implementation::convertToHidl(
+ shadowResult.physcam_metadata[i], &physicalMetadata);
+ PhysicalCameraMetadata physicalCameraMetadata = {
+ .fmqMetadataSize = 0,
+ .physicalCameraId = physicalId,
+ .metadata = physicalMetadata };
+ result.physicalCameraMetadata[i] = physicalCameraMetadata;
+ }
}
d->mResultBatcher_3_4.processCaptureResult_3_4(result);
}
diff --git a/compatibility_matrices/Android.mk b/compatibility_matrices/Android.mk
index 86fe00d..3702cf0 100644
--- a/compatibility_matrices/Android.mk
+++ b/compatibility_matrices/Android.mk
@@ -66,7 +66,7 @@
LOCAL_KERNEL_CONFIG_DATA_PATHS := \
4.4.107:$(my_kernel_config_data)/p/android-4.4 \
4.9.84:$(my_kernel_config_data)/p/android-4.9 \
- 4.14.40:$(my_kernel_config_data)/p/android-4.14 \
+ 4.14.42:$(my_kernel_config_data)/p/android-4.14 \
include $(BUILD_FRAMEWORK_COMPATIBILITY_MATRIX)
diff --git a/compatibility_matrices/compatibility_matrix.3.xml b/compatibility_matrices/compatibility_matrix.3.xml
index 2c5d431..f271642 100644
--- a/compatibility_matrices/compatibility_matrix.3.xml
+++ b/compatibility_matrices/compatibility_matrix.3.xml
@@ -113,7 +113,7 @@
</hal>
<hal format="hidl" optional="false">
<name>android.hardware.configstore</name>
- <version>1.0</version>
+ <version>1.0-1</version>
<interface>
<name>ISurfaceFlingerConfigs</name>
<instance>default</instance>
diff --git a/configstore/1.0/default/android.hardware.configstore@1.0-service.rc b/configstore/1.0/default/android.hardware.configstore@1.0-service.rc
deleted file mode 100644
index 40fb498..0000000
--- a/configstore/1.0/default/android.hardware.configstore@1.0-service.rc
+++ /dev/null
@@ -1,4 +0,0 @@
-service vendor.configstore-hal-1-0 /vendor/bin/hw/android.hardware.configstore@1.0-service
- class hal animation
- user system
- group system
diff --git a/configstore/1.1/Android.bp b/configstore/1.1/Android.bp
new file mode 100644
index 0000000..2b6e6fa
--- /dev/null
+++ b/configstore/1.1/Android.bp
@@ -0,0 +1,23 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.configstore@1.1",
+ root: "android.hardware",
+ vndk: {
+ enabled: true,
+ },
+ srcs: [
+ "types.hal",
+ "ISurfaceFlingerConfigs.hal",
+ ],
+ interfaces: [
+ "android.hardware.configstore@1.0",
+ "android.hidl.base@1.0",
+ ],
+ types: [
+ "DisplayOrientation",
+ "OptionalDisplayOrientation",
+ ],
+ gen_java: true,
+}
+
diff --git a/configstore/1.1/ISurfaceFlingerConfigs.hal b/configstore/1.1/ISurfaceFlingerConfigs.hal
new file mode 100644
index 0000000..3a69594
--- /dev/null
+++ b/configstore/1.1/ISurfaceFlingerConfigs.hal
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.configstore@1.1;
+
+import @1.0::ISurfaceFlingerConfigs;
+
+/**
+ * New revision of ISurfaceFlingerConfigs
+ */
+interface ISurfaceFlingerConfigs extends @1.0::ISurfaceFlingerConfigs {
+ /**
+ * Returns the orientation of the primary display device.
+ */
+ primaryDisplayOrientation() generates (OptionalDisplayOrientation value);
+};
diff --git a/configstore/1.0/default/Android.mk b/configstore/1.1/default/Android.mk
similarity index 69%
rename from configstore/1.0/default/Android.mk
rename to configstore/1.1/default/Android.mk
index 22d7c92..40f621b 100644
--- a/configstore/1.0/default/Android.mk
+++ b/configstore/1.1/default/Android.mk
@@ -2,15 +2,15 @@
################################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.configstore@1.0-service
+LOCAL_MODULE := android.hardware.configstore@1.1-service
# seccomp is not required for coverage build.
ifneq ($(NATIVE_COVERAGE),true)
-LOCAL_REQUIRED_MODULES_arm64 := configstore@1.0.policy
+LOCAL_REQUIRED_MODULES_arm64 := configstore@1.1.policy
endif
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_INIT_RC := android.hardware.configstore@1.0-service.rc
+LOCAL_INIT_RC := android.hardware.configstore@1.1-service.rc
LOCAL_SRC_FILES:= service.cpp
include $(LOCAL_PATH)/surfaceflinger.mk
@@ -22,16 +22,17 @@
libhwminijail \
liblog \
libutils \
- android.hardware.configstore@1.0
+ android.hardware.configstore@1.0 \
+ android.hardware.configstore@1.1
include $(BUILD_EXECUTABLE)
# seccomp filter for configstore
ifeq ($(TARGET_ARCH), $(filter $(TARGET_ARCH), arm64))
include $(CLEAR_VARS)
-LOCAL_MODULE := configstore@1.0.policy
+LOCAL_MODULE := configstore@1.1.policy
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/seccomp_policy
-LOCAL_SRC_FILES := seccomp_policy/configstore@1.0-$(TARGET_ARCH).policy
+LOCAL_SRC_FILES := seccomp_policy/configstore@1.1-$(TARGET_ARCH).policy
include $(BUILD_PREBUILT)
endif
diff --git a/configstore/1.0/default/SurfaceFlingerConfigs.cpp b/configstore/1.1/default/SurfaceFlingerConfigs.cpp
similarity index 70%
rename from configstore/1.0/default/SurfaceFlingerConfigs.cpp
rename to configstore/1.1/default/SurfaceFlingerConfigs.cpp
index 3239274..da3081c 100644
--- a/configstore/1.0/default/SurfaceFlingerConfigs.cpp
+++ b/configstore/1.1/default/SurfaceFlingerConfigs.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.1 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,10 +16,13 @@
#include "SurfaceFlingerConfigs.h"
+#include <android/hardware/configstore/1.1/types.h>
+#include <log/log.h>
+
namespace android {
namespace hardware {
namespace configstore {
-namespace V1_0 {
+namespace V1_1 {
namespace implementation {
// Methods from ::android::hardware::configstore::V1_0::ISurfaceFlingerConfigs
@@ -139,10 +142,59 @@
return Void();
}
+// Methods from ::android::hardware::configstore::V1_1::ISurfaceFlingerConfigs
+// follow.
+
+#ifdef PRIMARY_DISPLAY_ORIENTATION
+static_assert(PRIMARY_DISPLAY_ORIENTATION == 0 || PRIMARY_DISPLAY_ORIENTATION == 90 ||
+ PRIMARY_DISPLAY_ORIENTATION == 180 || PRIMARY_DISPLAY_ORIENTATION == 270,
+ "Primary display orientation must be 0/90/180/270");
+#endif
+
+Return<void> SurfaceFlingerConfigs::primaryDisplayOrientation(
+ primaryDisplayOrientation_cb _hidl_cb) {
+ using ::android::hardware::configstore::V1_1::DisplayOrientation;
+
+ bool specified = false;
+ DisplayOrientation value = DisplayOrientation::ORIENTATION_0;
+
+ int orientation = 0;
+#ifdef PRIMARY_DISPLAY_ORIENTATION
+ specified = true;
+ orientation = PRIMARY_DISPLAY_ORIENTATION;
+#endif
+
+ switch (orientation) {
+ case 0: {
+ value = DisplayOrientation::ORIENTATION_0;
+ break;
+ }
+ case 90: {
+ value = DisplayOrientation::ORIENTATION_90;
+ break;
+ }
+ case 180: {
+ value = DisplayOrientation::ORIENTATION_180;
+ break;
+ }
+ case 270: {
+ value = DisplayOrientation::ORIENTATION_270;
+ break;
+ }
+ default: {
+ // statically checked above -> memory corruption
+ LOG_ALWAYS_FATAL("Invalid orientation %d", orientation);
+ }
+ }
+
+ _hidl_cb({specified, value});
+ return Void();
+}
+
// Methods from ::android::hidl::base::V1_0::IBase follow.
} // namespace implementation
-} // namespace V1_0
+} // namespace V1_1
} // namespace configstore
} // namespace hardware
} // namespace android
diff --git a/configstore/1.0/default/SurfaceFlingerConfigs.h b/configstore/1.1/default/SurfaceFlingerConfigs.h
similarity index 74%
rename from configstore/1.0/default/SurfaceFlingerConfigs.h
rename to configstore/1.1/default/SurfaceFlingerConfigs.h
index 32e5fc3..3714e81 100644
--- a/configstore/1.0/default/SurfaceFlingerConfigs.h
+++ b/configstore/1.1/default/SurfaceFlingerConfigs.h
@@ -1,17 +1,17 @@
-#ifndef ANDROID_HARDWARE_CONFIGSTORE_V1_0_SURFACEFLINGERCONFIGS_H
-#define ANDROID_HARDWARE_CONFIGSTORE_V1_0_SURFACEFLINGERCONFIGS_H
+#ifndef ANDROID_HARDWARE_CONFIGSTORE_V1_1_SURFACEFLINGERCONFIGS_H
+#define ANDROID_HARDWARE_CONFIGSTORE_V1_1_SURFACEFLINGERCONFIGS_H
-#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
+#include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
namespace android {
namespace hardware {
namespace configstore {
-namespace V1_0 {
+namespace V1_1 {
namespace implementation {
-using ::android::hardware::configstore::V1_0::ISurfaceFlingerConfigs;
+using ::android::hardware::configstore::V1_1::ISurfaceFlingerConfigs;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::sp;
@@ -32,13 +32,17 @@
Return<void> maxFrameBufferAcquiredBuffers(maxFrameBufferAcquiredBuffers_cb _hidl_cb) override;
Return<void> startGraphicsAllocatorService(startGraphicsAllocatorService_cb _hidl_cb) override;
+ // Methods from
+ // ::android::hardware::configstore::V1_1::ISurfaceFlingerConfigs follow.
+ Return<void> primaryDisplayOrientation(primaryDisplayOrientation_cb _hidl_cb) override;
+
// Methods from ::android::hidl::base::V1_0::IBase follow.
};
} // namespace implementation
-} // namespace V1_0
+} // namespace V1_1
} // namespace configstore
} // namespace hardware
} // namespace android
-#endif // ANDROID_HARDWARE_CONFIGSTORE_V1_0_SURFACEFLINGERCONFIGS_H
+#endif // ANDROID_HARDWARE_CONFIGSTORE_V1_1_SURFACEFLINGERCONFIGS_H
diff --git a/configstore/1.1/default/android.hardware.configstore@1.1-service.rc b/configstore/1.1/default/android.hardware.configstore@1.1-service.rc
new file mode 100644
index 0000000..105678a
--- /dev/null
+++ b/configstore/1.1/default/android.hardware.configstore@1.1-service.rc
@@ -0,0 +1,4 @@
+service vendor.configstore-hal /vendor/bin/hw/android.hardware.configstore@1.1-service
+ class hal animation
+ user system
+ group system
diff --git a/configstore/1.0/default/seccomp_policy/configstore@1.0-arm64.policy b/configstore/1.1/default/seccomp_policy/configstore@1.1-arm64.policy
similarity index 100%
rename from configstore/1.0/default/seccomp_policy/configstore@1.0-arm64.policy
rename to configstore/1.1/default/seccomp_policy/configstore@1.1-arm64.policy
diff --git a/configstore/1.0/default/service.cpp b/configstore/1.1/default/service.cpp
similarity index 77%
rename from configstore/1.0/default/service.cpp
rename to configstore/1.1/default/service.cpp
index c9c81a0..3b4e774 100644
--- a/configstore/1.0/default/service.cpp
+++ b/configstore/1.1/default/service.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.1 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-#define LOG_TAG "android.hardware.configstore@1.0-service"
+#define LOG_TAG "android.hardware.configstore@1.1-service"
-#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
+#include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h>
#include <hidl/HidlTransportSupport.h>
#include <hwminijail/HardwareMinijail.h>
@@ -24,8 +24,8 @@
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
-using android::hardware::configstore::V1_0::ISurfaceFlingerConfigs;
-using android::hardware::configstore::V1_0::implementation::SurfaceFlingerConfigs;
+using android::hardware::configstore::V1_1::ISurfaceFlingerConfigs;
+using android::hardware::configstore::V1_1::implementation::SurfaceFlingerConfigs;
using android::hardware::SetupMinijail;
using android::sp;
using android::status_t;
@@ -34,7 +34,7 @@
int main() {
configureRpcThreadpool(10, true);
- SetupMinijail("/vendor/etc/seccomp_policy/configstore@1.0.policy");
+ SetupMinijail("/vendor/etc/seccomp_policy/configstore@1.1.policy");
sp<ISurfaceFlingerConfigs> surfaceFlingerConfigs = new SurfaceFlingerConfigs;
status_t status = surfaceFlingerConfigs->registerAsService();
diff --git a/configstore/1.0/default/surfaceflinger.mk b/configstore/1.1/default/surfaceflinger.mk
similarity index 92%
rename from configstore/1.0/default/surfaceflinger.mk
rename to configstore/1.1/default/surfaceflinger.mk
index f7487d5..51f06e1 100644
--- a/configstore/1.0/default/surfaceflinger.mk
+++ b/configstore/1.1/default/surfaceflinger.mk
@@ -58,3 +58,7 @@
ifneq ($(SF_START_GRAPHICS_ALLOCATOR_SERVICE),)
LOCAL_CFLAGS += -DSTART_GRAPHICS_ALLOCATOR_SERVICE
endif
+
+ifneq ($(SF_PRIMARY_DISPLAY_ORIENTATION),)
+ LOCAL_CFLAGS += -DPRIMARY_DISPLAY_ORIENTATION=$(SF_PRIMARY_DISPLAY_ORIENTATION)
+endif
diff --git a/configstore/1.1/types.hal b/configstore/1.1/types.hal
new file mode 100644
index 0000000..adc5747
--- /dev/null
+++ b/configstore/1.1/types.hal
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.configstore@1.1;
+
+/**
+ * Orientation in degrees.
+ */
+enum DisplayOrientation : uint8_t {
+ ORIENTATION_0,
+ ORIENTATION_90,
+ ORIENTATION_180,
+ ORIENTATION_270,
+};
+
+struct OptionalDisplayOrientation {
+ bool specified;
+ DisplayOrientation value;
+};
diff --git a/configstore/utils/Android.bp b/configstore/utils/Android.bp
index 93e52f1..cb4e6eb 100644
--- a/configstore/utils/Android.bp
+++ b/configstore/utils/Android.bp
@@ -28,11 +28,13 @@
shared_libs: [
"android.hardware.configstore@1.0",
+ "android.hardware.configstore@1.1",
"libbase",
"libhidlbase"
],
export_shared_lib_headers: [
"android.hardware.configstore@1.0",
+ "android.hardware.configstore@1.1",
"libbase",
"libhidlbase"
],
diff --git a/configstore/utils/include/configstore/Utils.h b/configstore/utils/include/configstore/Utils.h
index b107a20..e04f57d 100644
--- a/configstore/utils/include/configstore/Utils.h
+++ b/configstore/utils/include/configstore/Utils.h
@@ -18,6 +18,7 @@
#define ANDROID_HARDWARE_CONFIGSTORE_UTILS_H
#include <android/hardware/configstore/1.0/types.h>
+#include <android/hardware/configstore/1.1/types.h>
#include <hidl/Status.h>
#include <sstream>
@@ -34,13 +35,20 @@
} // namespace details
namespace configstore {
-// import types from V1_0
+// import types from configstore
+using ::android::hardware::configstore::V1_1::DisplayOrientation;
using ::android::hardware::configstore::V1_0::OptionalBool;
using ::android::hardware::configstore::V1_0::OptionalInt32;
using ::android::hardware::configstore::V1_0::OptionalUInt32;
using ::android::hardware::configstore::V1_0::OptionalInt64;
using ::android::hardware::configstore::V1_0::OptionalUInt64;
using ::android::hardware::configstore::V1_0::OptionalString;
+using ::android::hardware::configstore::V1_1::OptionalDisplayOrientation;
+
+static inline std::ostream& operator<<(std::ostream& os, DisplayOrientation orientation) {
+ os << ::android::hardware::configstore::V1_1::toString(orientation);
+ return os;
+}
// a function to retrieve and cache the service handle
// for a particular interface
@@ -141,6 +149,12 @@
return get<OptionalString, I, func>(defValue);
}
+template <typename I, android::hardware::Return<void> (I::*func)(
+ std::function<void(const OptionalDisplayOrientation&)>)>
+DisplayOrientation getDisplayOrientation(DisplayOrientation defValue) {
+ return get<OptionalDisplayOrientation, I, func>(defValue);
+}
+
} // namespace configstore
} // namespace hardware
} // namespace android
diff --git a/confirmationui/1.0/default/service.cpp b/confirmationui/1.0/default/service.cpp
index 58ec66a..39f3f62 100644
--- a/confirmationui/1.0/default/service.cpp
+++ b/confirmationui/1.0/default/service.cpp
@@ -27,6 +27,7 @@
using android::hardware::confirmationui::V1_0::implementation::ConfirmationUI;
int main() {
+ ::android::hardware::configureRpcThreadpool(1, true /*willJoinThreadpool*/);
auto confirmationui = new ConfirmationUI();
auto status = confirmationui->registerAsService();
if (status != android::OK) {
diff --git a/current.txt b/current.txt
index 7d630d2..f45af27 100644
--- a/current.txt
+++ b/current.txt
@@ -250,6 +250,7 @@
c8bc853546dd55584611def2a9fa1d99f657e3366c976d2f60fe6b8aa6d2cb87 android.hardware.thermal@1.1::IThermalCallback
# ABI preserving changes to HALs during Android P
+9e7a0b650d0e461ece2cfec0e1072abf8676f592b41a7fb48f01e88fc3c8f780 android.hardware.broadcastradio@1.0::types
eaeb3e4f3237430a7fdc206bffdf844713f5682990b2d49ea24392e15b5d343f android.hardware.broadcastradio@2.0::ITunerCallback
2804120c1f8522ad15feb7695fe5eece527d399b406c671ea99618194118c316 android.hardware.broadcastradio@2.0::types
cf72ff5a52bfa4d08e9e1000cf3ab5952a2d280c7f13cdad5ab7905c08050766 android.hardware.camera.metadata@3.2::types
@@ -258,10 +259,21 @@
fb92e2b40f8e9d494e8fd3b4ac18499a3216342e7cff160714c3bbf3660b6e79 android.hardware.gnss@1.0::IGnssConfiguration
251594ea9b27447bfa005ebd806e58fb0ae4aad84a69938129c9800ec0c64eda android.hardware.gnss@1.0::IGnssMeasurementCallback
4e7169919d24fbe5573e5bcd683d0bd7abf553a4e6c34c41f9dfc1e12050db07 android.hardware.gnss@1.0::IGnssNavigationMessageCallback
+190ea4898809de6cf379afe318f5fa9564686157b24d9a2d7f5698b0c977d8b2 android.hardware.graphics.bufferqueue@1.0::IGraphicBufferProducer
+25892789b50eb673506b6c5a2cdab5d9aa428d41608aab10280cc898538b524a android.hardware.graphics.composer@2.1::IComposerClient
+e205dd30f5ff99445b706a901de8ebc46c379e9d7c1921d6a327ed2082cfa83d android.hardware.graphics.composer@2.1::types
+a46251718abfada458dc64c41ce94915757bf6c87cfa2d9e99cfb01fa8e32331 android.hardware.graphics.mapper@2.0::IMapper
+bd33ac23c57b4a07632691d2191bc2c93930f57e62f4ccf459748fdaa5c0f480 android.hardware.graphics.mapper@2.0::types
+ad8a28ca3a5549fb9bc24cf5f80ac8f660cc27be885210d76266780aa52ddb8d android.hardware.keymaster@3.0::types
5804ca86611d72e5481f022b3a0c1b334217f2e4988dad25730c42af2d1f4d1c android.hardware.neuralnetworks@1.0::IDevice
12e8dca4ab7d8aadd0ef8f1b438021938e2396139e85db2ed65783b08800aa52 android.hardware.neuralnetworks@1.0::IExecutionCallback
18e6885e184fe48401c2c53f1d1b8bfb07240f40c81ae6b9d2e336fca6efdbb7 android.hardware.neuralnetworks@1.0::types
d4840db8efabdf1e4b344fc981cd36e5fe81a39aff6e199f6d06c1c8da413efd android.hardware.radio@1.0::types
+f96cbc59dfe16c8d0c2a7e06db24d8738a6328b6e90f7b8e1640ea2b4600debd android.hardware.radio@1.1::ISap
+2d86929794795e5c70f4fdb5073485fd05835c9c6f496116687c3d9f32e6df3e android.hardware.radio@1.2::ISap
+905a4af79c8329b39d8b11b08f015137216bb078b427b6986f32884a04bc1bec android.hardware.tv.cec@1.0::types
+aebcd9ff2da05c9d4c439916f40dfd219ba7629919007cb981ebf150064b4f82 android.hardware.usb@1.1::IUsb
+e29fb1941b40a990676f8e9c676a38761defd890b81a9c034608eb7ba6496023 android.hardware.wifi@1.0::IWifiP2pIface
b280c4704dfcc548a9bf127b59b7c3578f460c50cce70a06b66fe0df8b27cff0 android.hardware.wifi@1.0::types
# HALs released in Android P
@@ -272,7 +284,7 @@
d5de64e66b95f135dd42492250a309134b8227203ef3524440798c66b6f5a392 android.hardware.audio@4.0::IStreamIn
888ac906461327fa0bd93854d5109be8c292a33afdb467164826970a8bd5b789 android.hardware.audio@4.0::IStreamOut
15f6ae78e73344c8e7d68847ef03caec64fcd9f951bbcf59957d1712c247fcff android.hardware.audio@4.0::IStreamOutCallback
-e8abfc73b7f3c2095ea4fad83b5f42bced4315de2abcc3199376af880dac451b android.hardware.audio@4.0::types
+61f0eaa4d08547d039e9b1dd7c82abe2c004286d1b9b8153c2491ff46a8a63ca android.hardware.audio@4.0::types
5d47a2ad2c136b8aba067dd45bb10d0ad390dd76340764154f580658f98f4fe6 android.hardware.audio.common@4.0::types
b04b6b364938b80008e61fa2e318bc299622433e57c2e1f6cfba332a3f6e3f15 android.hardware.audio.effect@4.0::IAcousticEchoCancelerEffect
1c17d4ece5c8ba3f7a646a305ee0dd109b0d51372e1bd585812e513cd40e1852 android.hardware.audio.effect@4.0::IAutomaticGainControlEffect
@@ -299,7 +311,7 @@
3b17c1fdfc389e0abe626c37054954b07201127d890c2bc05d47613ec1f4de4f android.hardware.automotive.evs@1.0::types
b3caf524c46a47d67e6453a34419e1881942d059e146cda740502670e9a752c3 android.hardware.automotive.vehicle@2.0::IVehicle
7ce8728b27600e840cacf0a832f6942819fe535f9d3797ae052d5eef5065921c android.hardware.automotive.vehicle@2.0::IVehicleCallback
-44c8b452186b65f5140a224721f238b76ed3adc42460f26b801b561593744c7e android.hardware.automotive.vehicle@2.0::types
+06fa7218fb1500acca69b265a7e697b885933f7146cd6e8d83fe6c1fa06ce876 android.hardware.automotive.vehicle@2.0::types
32cc50cc2a7658ec613c0c2dd2accbf6a05113b749852879e818b8b7b438db19 android.hardware.bluetooth.a2dp@1.0::IBluetoothAudioHost
ff4be64d7992f8bec97dff37f35450e79b3430c61f85f54322ce45bef229dc3b android.hardware.bluetooth.a2dp@1.0::IBluetoothAudioOffload
27f22d2e873e6201f9620cf4d8e2facb25bd0dd30a2b911e441b4600d560fa62 android.hardware.bluetooth.a2dp@1.0::types
@@ -313,6 +325,8 @@
812fa66aa10ba0cba27cfddc2fd7f0ee27a8ab65a1f15aa79fdad97d403e6a14 android.hardware.camera.device@3.4::ICameraDeviceSession
cc288f1f78d1e643eb3d3dbc16e1401d44033d8e6856761f5156814a29986ec7 android.hardware.camera.device@3.4::types
f9278c8beb9d42d96e26d73ecabe1dff1d7e2fb301ab7f737d93e5ffae8d3312 android.hardware.camera.metadata@3.3::types
+f858091b10f7d5927be60573c06df4805275d37226bbb41a732190bfb81457ec android.hardware.configstore@1.1::ISurfaceFlingerConfigs
+5b0fb9842f8b0eb3730b93c30a7925290ab44763ab86bb493bfa58d0f2eeb369 android.hardware.configstore@1.1::types
1a46aeae45b7a0e47f79b7207300532986f9d9cd7060779afc7a529f54d712ab android.hardware.confirmationui@1.0::IConfirmationResultCallback
6d8347ff3cd7de471065ac3e8e68385073630cdeebe9f8fa58cb91cf44436c95 android.hardware.confirmationui@1.0::IConfirmationUI
a3ff916784dce87a56c757ab5c86433f0cdf562280999a5f978a6e8a0f3f19e7 android.hardware.confirmationui@1.0::types
@@ -326,14 +340,15 @@
1a07d1383e847c3deb696ec7a2c9e33b9683772945660448a010b18063da67a4 android.hardware.gnss@1.1::IGnssMeasurement
83e7a10ff3702147bd7ffa04567b20d407a3b16bbb7705644af44d919afe9103 android.hardware.gnss@1.1::IGnssMeasurementCallback
0b96e0254e2168cfecb30c1ed5fb42681652cc00faa68c6e07568fafe64d1d50 android.hardware.graphics.common@1.1::types
+7d2cef99c838fb58038de8bbfd3cdb76ff4797241987077721715297f8d45e34 android.hardware.graphics.common@1.1::types # b/78135149
d9b40a5b09962a5a0780b10fe33a4e607e69e2e088fc83de88a584115b7cb1c0 android.hardware.graphics.composer@2.2::IComposer
e7717f2ff2f6db43b24370ff08e14cd353da3004b32b17740e4a7ed4894b7e45 android.hardware.graphics.composer@2.2::IComposerClient
dd83be076b6b3f10ed62ab34d8c8b95f2415961fb785200eb842e7bfb2b0ee92 android.hardware.graphics.mapper@2.1::IMapper
675682dd3007805c985eaaec91612abc88f4c25b3431fb84070b7584a1a741fb android.hardware.health@2.0::IHealth
434c4c32c00b0e54bb05e40c79503208b40f786a318029a2a4f66e34f10f2a76 android.hardware.health@2.0::IHealthInfoCallback
c9e498f1ade5e26f00d290b4763a9671ec6720f915e7d592844b62e8cb1f9b5c android.hardware.health@2.0::types
-a6cf986593c6ad15fe2ae3a1995d2cae233500bc32c055912a42723bdc076868 android.hardware.keymaster@4.0::IKeymasterDevice
-e15ebdf1e0a326ff5b8a59668d4d8cd3852bd88388eae91de13f5f7e1af50ed1 android.hardware.keymaster@4.0::types
+5c8e06f9945276d1a9e8f7e37cf0ea8894bdb906fa80809cb06c36abb39afc4f android.hardware.keymaster@4.0::IKeymasterDevice
+6695eb5744108035506004dd136068b1aaebe809cf9d4a69c2fe33b73058bb85 android.hardware.keymaster@4.0::types
6d5c646a83538f0f9d8438c259932509f4353410c6c76e56db0d6ca98b69c3bb android.hardware.media.bufferpool@1.0::IAccessor
b8c7ed58aa8740361e63d0ce9e7c94227572a629f356958840b34809d2393a7c android.hardware.media.bufferpool@1.0::IClientManager
4a2c0dc82780e6c90731725a103feab8ab6ecf85a64e049b9cbd2b2c61620fe1 android.hardware.media.bufferpool@1.0::IConnection
diff --git a/graphics/bufferqueue/1.0/IGraphicBufferProducer.hal b/graphics/bufferqueue/1.0/IGraphicBufferProducer.hal
index 87bb814..c59a16c 100644
--- a/graphics/bufferqueue/1.0/IGraphicBufferProducer.hal
+++ b/graphics/bufferqueue/1.0/IGraphicBufferProducer.hal
@@ -546,7 +546,7 @@
*/
disconnect(
int32_t api,
- DisconnectMode mode /** = DisconnectMode::API */
+ DisconnectMode mode /* = DisconnectMode::API */
) generates (
Status status
);
diff --git a/graphics/common/1.1/types.hal b/graphics/common/1.1/types.hal
index 5dca482..423cf44 100644
--- a/graphics/common/1.1/types.hal
+++ b/graphics/common/1.1/types.hal
@@ -124,7 +124,7 @@
/** buffer contains a complete mipmap hierarchy */
GPU_MIPMAP_COMPLETE = 1ULL << 26,
- /** bits 27 and 32-47 must be zero and are reserved for future versions */
+ /* bits 27 and 32-47 must be zero and are reserved for future versions */
};
@export(name="android_dataspace_v1_1_t", value_prefix="HAL_DATASPACE_",
diff --git a/graphics/composer/2.1/IComposerClient.hal b/graphics/composer/2.1/IComposerClient.hal
index f2ff932..5ad46f0 100644
--- a/graphics/composer/2.1/IComposerClient.hal
+++ b/graphics/composer/2.1/IComposerClient.hal
@@ -1138,7 +1138,7 @@
SET_LAYER_Z_ORDER = 0x40a << OPCODE_SHIFT,
SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT = 0x40b << OPCODE_SHIFT,
- /** 0x800 - 0xfff are reserved for vendor extensions */
- /** 0x1000 - 0xffff are reserved */
+ /* 0x800 - 0xfff are reserved for vendor extensions */
+ /* 0x1000 - 0xffff are reserved */
};
};
diff --git a/graphics/composer/2.1/types.hal b/graphics/composer/2.1/types.hal
index 9f0dd8b..eb0a73b 100644
--- a/graphics/composer/2.1/types.hal
+++ b/graphics/composer/2.1/types.hal
@@ -18,15 +18,15 @@
/** Return codes from all functions. */
enum Error : int32_t {
- NONE = 0, /** no error */
- BAD_CONFIG = 1, /** invalid Config */
- BAD_DISPLAY = 2, /** invalid Display */
- BAD_LAYER = 3, /** invalid Layer */
- BAD_PARAMETER = 4, /** invalid width, height, etc. */
- /** 5 is reserved */
- NO_RESOURCES = 6, /** temporary failure due to resource contention */
- NOT_VALIDATED = 7, /** validateDisplay has not been called */
- UNSUPPORTED = 8, /** permanent failure */
+ NONE = 0, /* no error */
+ BAD_CONFIG = 1, /* invalid Config */
+ BAD_DISPLAY = 2, /* invalid Display */
+ BAD_LAYER = 3, /* invalid Layer */
+ BAD_PARAMETER = 4, /* invalid width, height, etc. */
+ /* 5 is reserved */
+ NO_RESOURCES = 6, /* temporary failure due to resource contention */
+ NOT_VALIDATED = 7, /* validateDisplay has not been called */
+ UNSUPPORTED = 8, /* permanent failure */
};
typedef uint32_t Config;
diff --git a/graphics/composer/2.2/utils/vts/ComposerVts.cpp b/graphics/composer/2.2/utils/vts/ComposerVts.cpp
index 357c772..6a32071 100644
--- a/graphics/composer/2.2/utils/vts/ComposerVts.cpp
+++ b/graphics/composer/2.2/utils/vts/ComposerVts.cpp
@@ -45,6 +45,10 @@
return client;
}
+sp<V2_2::IComposerClient> ComposerClient_v2_2::getRaw() const {
+ return mClient_v2_2;
+}
+
std::vector<IComposerClient::PerFrameMetadataKey> ComposerClient_v2_2::getPerFrameMetadataKeys(
Display display) {
std::vector<IComposerClient::PerFrameMetadataKey> keys;
diff --git a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h
index 62ab83f..1c6d7ae 100644
--- a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h
+++ b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h
@@ -63,6 +63,8 @@
ComposerClient_v2_2(const sp<IComposerClient>& client)
: V2_1::vts::ComposerClient(client), mClient_v2_2(client){};
+ sp<V2_2::IComposerClient> getRaw() const;
+
void execute_v2_2(V2_1::vts::TestCommandReader* reader, V2_2::CommandWriterBase* writer);
std::vector<IComposerClient::PerFrameMetadataKey> getPerFrameMetadataKeys(Display display);
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
index 4e41333..f0d2250 100644
--- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
@@ -78,6 +78,11 @@
// explicitly disable vsync
mComposerClient->setVsyncEnabled(mPrimaryDisplay, false);
mComposerCallback->setVsyncAllowed(false);
+
+ mComposerClient->getRaw()->getReadbackBufferAttributes(
+ mPrimaryDisplay, [&](const auto& tmpError, const auto&, const auto&) {
+ mHasReadbackBuffer = tmpError == Error::NONE;
+ });
}
void TearDown() override {
@@ -96,6 +101,7 @@
sp<V2_1::vts::GraphicsComposerCallback> mComposerCallback;
// the first display and is assumed never to be removed
Display mPrimaryDisplay;
+ bool mHasReadbackBuffer;
private:
Display waitForFirstDisplay() {
@@ -257,18 +263,44 @@
}
TEST_F(GraphicsComposerHidlTest, setReadbackBuffer) {
- mComposerClient->setReadbackBuffer(mPrimaryDisplay, nullptr, -1);
-}
+ if (!mHasReadbackBuffer) {
+ return;
+ }
-TEST_F(GraphicsComposerHidlTest, getReadbackBufferFence) {
- int32_t fence;
- mComposerClient->getReadbackBufferFence(mPrimaryDisplay, &fence);
-}
-
-TEST_F(GraphicsComposerHidlTest, getReadbackBufferAttributes) {
PixelFormat pixelFormat;
Dataspace dataspace;
mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay, &pixelFormat, &dataspace);
+ ASSERT_LT(static_cast<PixelFormat>(0), pixelFormat);
+ ASSERT_NE(Dataspace::UNKNOWN, dataspace);
+
+ IMapper::BufferDescriptorInfo info{};
+ Config config = mComposerClient->getActiveConfig(mPrimaryDisplay);
+ info.width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
+ IComposerClient::Attribute::WIDTH);
+ info.height = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
+ IComposerClient::Attribute::HEIGHT);
+ info.layerCount = 1;
+ info.format = pixelFormat;
+ // BufferUsage::COMPOSER_OUTPUT is missing
+ info.usage = static_cast<uint64_t>(BufferUsage::COMPOSER_OVERLAY | BufferUsage::CPU_READ_OFTEN);
+
+ std::unique_ptr<Gralloc> gralloc;
+ const native_handle_t* buffer;
+ ASSERT_NO_FATAL_FAILURE(gralloc = std::make_unique<Gralloc>());
+ ASSERT_NO_FATAL_FAILURE(buffer = gralloc->allocate(info));
+
+ mComposerClient->setReadbackBuffer(mPrimaryDisplay, buffer, -1);
+}
+
+TEST_F(GraphicsComposerHidlTest, getReadbackBufferFenceInactive) {
+ if (!mHasReadbackBuffer) {
+ return;
+ }
+
+ mComposerClient->getRaw()->getReadbackBufferFence(
+ mPrimaryDisplay, [&](const auto& tmpError, const auto&) {
+ ASSERT_EQ(Error::UNSUPPORTED, tmpError) << "readback buffer is active";
+ });
}
/**
diff --git a/graphics/mapper/2.0/IMapper.hal b/graphics/mapper/2.0/IMapper.hal
index 4ee206b..4566135 100644
--- a/graphics/mapper/2.0/IMapper.hal
+++ b/graphics/mapper/2.0/IMapper.hal
@@ -155,7 +155,7 @@
* @param cpuUsage specifies one or more CPU usage flags to request.
* @param accessRegion is the portion of the buffer that the client
* intends to access.
- * @param acquireFence, when non-empty, is a handle containing a file
+ * @param acquireFence when non-empty, is a handle containing a file
* descriptor referring to a sync fence object, which will be
* signaled when it is safe for the mapper to lock the buffer. If
* it is already safe to lock, acquireFence is empty.
@@ -191,7 +191,7 @@
* @param cpuUsage specifies one or more CPU usage flags to request.
* @param accessRegion is the portion of the buffer that the client
* intends to access.
- * @param acquireFence, when non-empty, is a handle containing a file
+ * @param acquireFence when non-empty, is a handle containing a file
* descriptor referring to a sync fence object, which will be
* signaled when it is safe for the mapper to lock the buffer. If
* it is already safe to lock, acquireFence is empty.
diff --git a/graphics/mapper/2.0/types.hal b/graphics/mapper/2.0/types.hal
index e9b2f3a..2291f70 100644
--- a/graphics/mapper/2.0/types.hal
+++ b/graphics/mapper/2.0/types.hal
@@ -17,14 +17,14 @@
package android.hardware.graphics.mapper@2.0;
enum Error : int32_t {
- NONE = 0, /** no error */
- BAD_DESCRIPTOR = 1, /** invalid BufferDescriptor */
- BAD_BUFFER = 2, /** invalid buffer handle */
- BAD_VALUE = 3, /** invalid width, height, etc. */
+ NONE = 0, /* no error */
+ BAD_DESCRIPTOR = 1, /* invalid BufferDescriptor */
+ BAD_BUFFER = 2, /* invalid buffer handle */
+ BAD_VALUE = 3, /* invalid width, height, etc. */
/* 4 is reserved */
- NO_RESOURCES = 5, /** temporary failure due to resource contention */
+ NO_RESOURCES = 5, /* temporary failure due to resource contention */
/* 6 is reserved */
- UNSUPPORTED = 7, /** permanent failure */
+ UNSUPPORTED = 7, /* permanent failure */
};
/**
diff --git a/keymaster/3.0/types.hal b/keymaster/3.0/types.hal
index 6dad23e..72f7d47 100644
--- a/keymaster/3.0/types.hal
+++ b/keymaster/3.0/types.hal
@@ -17,17 +17,17 @@
package android.hardware.keymaster@3.0;
enum TagType : uint32_t {
- INVALID = 0 << 28, /** Invalid type, used to designate a tag as uninitialized */
+ INVALID = 0 << 28, /* Invalid type, used to designate a tag as uninitialized */
ENUM = 1 << 28,
- ENUM_REP = 2 << 28, /** Repeatable enumeration value. */
+ ENUM_REP = 2 << 28, /* Repeatable enumeration value. */
UINT = 3 << 28,
- UINT_REP = 4 << 28, /** Repeatable integer value */
+ UINT_REP = 4 << 28, /* Repeatable integer value */
ULONG = 5 << 28,
DATE = 6 << 28,
BOOL = 7 << 28,
BIGNUM = 8 << 28,
BYTES = 9 << 28,
- ULONG_REP = 10 << 28, /** Repeatable long value */
+ ULONG_REP = 10 << 28, /* Repeatable long value */
};
enum Tag : uint32_t {
@@ -254,12 +254,12 @@
* Possible purposes of a key (or pair).
*/
enum KeyPurpose : uint32_t {
- ENCRYPT = 0, /** Usable with RSA, EC and AES keys. */
- DECRYPT = 1, /** Usable with RSA, EC and AES keys. */
- SIGN = 2, /** Usable with RSA, EC and HMAC keys. */
- VERIFY = 3, /** Usable with RSA, EC and HMAC keys. */
- DERIVE_KEY = 4, /** Usable with EC keys. */
- WRAP_KEY = 5, /** Usable with wrapping keys. */
+ ENCRYPT = 0, /* Usable with RSA, EC and AES keys. */
+ DECRYPT = 1, /* Usable with RSA, EC and AES keys. */
+ SIGN = 2, /* Usable with RSA, EC and HMAC keys. */
+ VERIFY = 3, /* Usable with RSA, EC and HMAC keys. */
+ DERIVE_KEY = 4, /* Usable with EC keys. */
+ WRAP_KEY = 5, /* Usable with wrapping keys. */
};
/**
diff --git a/keymaster/4.0/IKeymasterDevice.hal b/keymaster/4.0/IKeymasterDevice.hal
index aef81c7..6c09ef3 100644
--- a/keymaster/4.0/IKeymasterDevice.hal
+++ b/keymaster/4.0/IKeymasterDevice.hal
@@ -20,46 +20,234 @@
import android.hardware.keymaster@3.0::KeyFormat;
/**
- * Keymaster device definition. For thorough documentation see the implementer's reference, at
- * https://source.android.com/security/keystore/implementer-ref.html
+ * Keymaster device definition.
+ *
+ * == Features ==
+ *
+ * An IKeymasterDevice provides cryptographic services, including the following categories of
+ * operations:
+ *
+ * o Key generation
+ * o Import and export (public only) of asymmetric keys
+ * o Import of raw symmetric keys
+ * o Asymmetric encryption and decryption with appropriate padding modes
+ * o Asymmetric signing and verification with digesting and appropriate padding modes
+ * o Symmetric encryption and decryption in appropriate modes, including an AEAD mode
+ * o Generation and verification of symmetric message authentication codes
+ * o Attestation to the presence and configuration of asymmetric keys.
+ *
+ * Protocol elements, such as purpose, mode and padding, as well as access control constraints, must
+ * be specified by the caller when keys are generated or imported and must be permanently bound to
+ * the key, ensuring that the key cannot be used in any other way.
+ *
+ * In addition to the list above, IKeymasterDevice implementations must provide one more service
+ * which is not exposed as an API but used internally: Random number generation. The random number
+ * generator must be high-quality and must be used for generation of keys, initialization vectors,
+ * random padding and other elements of secure protocols that require randomness.
+ *
+ * == Types of IKeymasterDevices ==
+ *
+ * All of the operations and storage of key material must occur in a secure environment. Secure
+ * environments may be either:
+ *
+ * 1. Isolated execution environments, such as a separate virtual machine, hypervisor or
+ * purpose-built trusted execution environment like ARM TrustZone. The isolated environment
+ * must provide complete separation from the Android kernel and user space (collectively called
+ * the "non-secure world", or NSW) so that nothing running in the NSW can observe or manipulate
+ * the results of any computation in the isolated environment. Isolated execution environments
+ * are identified by the SecurityLevel TRUSTED_ENVIRONMENT.
+ *
+ * 2. Completely separate, purpose-built and certified secure CPUs, called "StrongBox" devices.
+ * Examples of StrongBox devices are embedded Secure Elements (eSE) or on-SoC secure processing
+ * units (SPU). StrongBox environments are identified by the SecurityLevel STRONGBOX. To
+ * qualify as a StrongBox, a device must meet the requirements specified in CDD 9.11.2.
+ *
+ * == Necessary Primitives ==
+ *
+ * All IKeymasterDevice implementations must provide support for the following:
+ *
+ * o RSA
+ *
+ * - TRUSTED_ENVIRONMENT IKeymasterDevices must support 2048, 3072 and 4096-bit keys.
+ * STRONGBOX IKeymasterDevices must support 2048-bit keys.
+ * - Public exponent F4 (2^16+1)
+ * - Unpadded, RSASSA-PSS and RSASSA-PKCS1-v1_5 padding modes for RSA signing
+ * - TRUSTED_ENVIRONMENT IKeymasterDevices must support MD5, SHA1, SHA-2 224, SHA-2 256, SHA-2
+ * 384 and SHA-2 512 digest modes for RSA signing. STRONGBOX IKeymasterDevices must support
+ * SHA-2 256.
+ * - Unpadded, RSAES-OAEP and RSAES-PKCS1-v1_5 padding modes for RSA encryption.
+ *
+ * o ECDSA
+ *
+ * - TRUSTED_ENVIRONMENT IKeymasterDevices must support NIST curves P-224, P-256, P-384 and
+ * P-521. STRONGBOX IKeymasterDevices must support NIST curve P-256.
+ * - TRUSTED_ENVIRONMENT IKeymasterDevices must support SHA1, SHA-2 224, SHA-2 256, SHA-2
+ * 384 and SHA-2 512 digest modes. STRONGBOX IKeymasterDevices must support SHA-2 256.
+ *
+ * o AES
+ *
+ * - 128 and 256-bit keys
+ * - CBC, CTR, ECB and GCM modes. The GCM mode must not allow the use of tags smaller than 96
+ * bits or nonce lengths other than 96 bits.
+ * - CBC and ECB modes must support unpadded and PKCS7 padding modes. With no padding CBC and
+ * ECB-mode operations must fail with ErrorCode::INVALID_INPUT_LENGTH if the input isn't a
+ * multiple of the AES block size. With PKCS7 padding, GCM and CTR operations must fail with
+ * ErrorCode::INCOMPATIBLE_PADDING_MODE.
+ *
+ * o 3DES
+ *
+ * - 168-bit keys.
+ * - CBC and ECB mode.
+
+ * - CBC and ECB modes must support unpadded and PKCS7 padding modes. With no padding CBC and
+ * ECB-mode operations must fail with ErrorCode::INVALID_INPUT_LENGTH if the input isn't a
+ * multiple of the DES block size.
+ *
+ * o HMAC
+ *
+ * - Any key size that is between 64 and 512 bits (inclusive) and a multiple of 8 must be
+ * supported. STRONGBOX IKeymasterDevices must not support keys larger than 512 bits.
+ * - TRUSTED_ENVIRONMENT IKeymasterDevices must support MD-5, SHA1, SHA-2-224, SHA-2-256,
+ * SHA-2-384 and SHA-2-512. STRONGBOX IKeymasterDevices must support SHA-2-256.
+ *
+ * == Key Access Control ==
+ *
+ * Hardware-based keys that can never be extracted from the device don't provide much security if an
+ * attacker can use them at will (though they're more secure than keys which can be
+ * exfiltrated). Therefore, IKeymasterDevice must enforce access controls.
+ *
+ * Access controls are defined as an "authorization list" of tag/value pairs. Authorization tags
+ * are 32-bit integers from the Tag enum, and the values are a variety of types, defined in the
+ * TagType enum. Some tags may be repeated to specify multiple values. Whether a tag may be
+ * repeated is specified in the documentation for the tag and in the TagType. When a key is created
+ * or imported, the caller specifies an authorization list. The IKeymasterDevice must divide the
+ * caller-provided authorizations into two lists, those it enforces in hardware and those it does
+ * not. These two lists are returned as the "hardwareEnforced" and "softwareEnforced" elements of
+ * the KeyCharacteristics struct. The IKeymasterDevice must also add the following authorizations
+ * to the appropriate list:
+ *
+ * o Tag::OS_VERSION, must be hardware-enforced.
+ * o Tag::OS_PATCHLEVEL, must be hardware-enforced.
+ * o Tag::VENDOR_PATCHLEVEL, must be hardware-enforced.
+ * o Tag::BOOT_PATCHLEVEL, must be hardware-enforced.
+ * o Tag::CREATION_DATETIME, must be software-enforced, unless the IKeymasterDevice has access to
+ * a secure time service.
+ * o Tag::ORIGIN, must be hardware-enforced.
+ *
+ * The IKeymasterDevice must accept arbitrary, unknown tags and return them in the softwareEnforced
+ * list.
+ *
+ * All authorization tags and their values, both hardwareEnforced and softwareEnforced, including
+ * unknown tags, must be cryptographically bound to the private/secret key material such that any
+ * modification of the portion of the key blob that contains the authorization list makes it
+ * impossible for the secure environment to obtain the private/secret key material. The recommended
+ * approach to meet this requirement is to use the full set of authorization tags associated with a
+ * key as input to a secure key derivation function used to derive a key that is used to encrypt the
+ * private/secret key material.
+ *
+ * IKeymasterDevice implementations must place any tags they cannot fully and completely enforce in
+ * the softwareEnforced list. For example, Tag::ORIGINATION_EXPIRE_DATETIME provides the date and
+ * time after which a key may not be used to encrypt or sign new messages. Unless the
+ * IKeymasterDevice has access to a secure source of current date/time information, it is not
+ * possible for the IKeymasterDevice to enforce this tag. An IKeymasterDevice implementation may
+ * not rely on the non-secure world's notion of time, because it could be controlled by an attacker.
+ * Similarly, it cannot rely on GPSr time, even if it has exclusive control of the GPSr, because
+ * that might be spoofed by attacker RF signals.
+ *
+ * It is recommended that IKeymasterDevices not enforce any tags they place in the softwareEnforced
+ * list. The IKeymasterDevice caller must enforce them, and it is unnecessary to enforce them
+ * twice.
+ *
+ * Some tags must be enforced by the IKeymasterDevice. See the detailed documentation on each Tag
+ * in types.hal.
+ *
+ * == Root of Trust Binding ==
+ *
+ * IKeymasterDevice keys must be bound to a root of trust, which is a bitstring that must be
+ * provided to the secure environment (by an unspecified, implementation-defined mechanism) during
+ * startup, preferably by the bootloader. This bitstring must be cryptographically bound to every
+ * key managed by the IKeymasterDevice. As above, the recommended mechanism for this cryptographic
+ * binding is to include the Root of Trust data in the input to the key derivation function used to
+ * derive a key that is used to encryp the private/secret key material.
+ *
+ * The root of trust consists of a bitstring that must be derived from the public key used by
+ * Verified Boot to verify the signature on the boot image and from the the lock state of the
+ * device. If the public key is changed to allow a different system image to be used or if the lock
+ * state is changed, then all of the IKeymasterDevice-protected keys created by the previous system
+ * state must be unusable, unless the previous state is restored. The goal is to increase the value
+ * of the software-enforced key access controls by making it impossible for an attacker-installed
+ * operating system to use IKeymasterDevice keys.
+ *
+ * == Version Binding ==
+ *
+ * All keys must also be bound to the operating system and patch level of the system image and the
+ * patch levels of the vendor image and boot image. This ensures that an attacker who discovers a
+ * weakness in an old version of the software cannot roll a device back to the vulnerable version
+ * and use keys created with the newer version. In addition, when a key with a given version and
+ * patch level is used on a device that has been upgraded to a newer version or patch level, the key
+ * must be upgraded (See IKeymasterDevice::upgradeKey()) before it can be used, and the previous
+ * version of the key must be invalidated. In this way, as the device is upgraded, the keys will
+ * "ratchet" forward along with the device, but any reversion of the device to a previous release
+ * will cause the keys to be unusable.
+ *
+ * This version information must be associated with every key as a set of tag/value pairs in the
+ * hardwareEnforced authorization list. Tag::OS_VERSION, Tag::OS_PATCHLEVEL,
+ * Tag::VENDOR_PATCHLEVEL, and Tag::BOOT_PATCHLEVEL must be cryptographically bound to every
+ * IKeymasterDevice key, as described in the Key Access Control section above.
*/
+
interface IKeymasterDevice {
/**
- * Returns information about the underlying Keymaster hardware.
+ * Returns information about the underlying IKeymasterDevice hardware.
*
- * @return security level of the Keymaster implementation accessed through this HAL.
+ * @return security level of the IKeymasterDevice implementation accessed through this HAL.
*
- * @return keymasterName is the name of the Keymaster implementation.
+ * @return keymasterName is the name of the IKeymasterDevice implementation.
*
- * @return keymasterAuthorName is the name of the author of the Keymaster implementation
+ * @return keymasterAuthorName is the name of the author of the IKeymasterDevice implementation
* (organization name, not individual).
*/
getHardwareInfo()
generates (SecurityLevel securityLevel, string keymasterName, string keymasterAuthorName);
/**
- * Start the creation of an HMAC key, shared with another Keymaster implementation. Any device
- * with a StrongBox Keymaster has two Keymaster instances, because there must be a TEE Keymaster
- * as well. The HMAC key used to MAC and verify authentication tokens must be shared between
- * TEE and StrongBox so they can each validate tokens produced by the other. This method is the
- * first step in the process for for agreeing on a shared key. It is called by Keystore during
- * startup if and only if Keystore loads multiple Keymaster HALs. Keystore calls it on each of
- * the HAL instances and collects the results in preparation for the second step.
+ * Start the creation of an HMAC key, shared with another IKeymasterDevice implementation. Any
+ * device with a StrongBox IKeymasterDevice has two IKeymasterDevice instances, because there
+ * must be a TEE Keymaster as well. The HMAC key used to MAC and verify authentication tokens
+ * (HardwareAuthToken, VerificationToken and ConfirmationToken all use this HMAC key) must be
+ * shared between TEE and StrongBox so they can each validate tokens produced by the other.
+ * This method is the first step in the process for for agreeing on a shared key. It is called
+ * by Android during startup. The system calls it on each of the HAL instances and collects the
+ * results in preparation for the second step.
+ *
+ * @return error ErrorCode::OK on success, ErrorCode::UNIMPLEMENTED if HMAC agreement is not
+ * implemented (note that all 4.0::IKeymasterDevice HALS must implement HMAC agreement,
+ * regardless of whether or not the HAL will be used on a device with StrongBox), or
+ * ErrorCode::UNKNOWN_ERROR if the parameters cannot be returned.
+ *
+ * @return params The HmacSharingParameters to use. As specified in the HmacSharingParameters
+ * documentation in types.hal, the seed must contain the same value in every invocation
+ * of the method on a given device, and the nonce must return the same value for every
+ * invocation during a boot session.
*/
getHmacSharingParameters() generates (ErrorCode error, HmacSharingParameters params);
/**
- * Complete the creation of an HMAC key, shared with another Keymaster implementation. Any
- * device with a StrongBox Keymaster has two Keymasters instances, because there must be a TEE
- * Keymaster as well. The HMAC key used to MAC and verify authentication tokens must be shared
- * between TEE and StrongBox so they can each validate tokens produced by the other. This
- * method is the second and final step in the process for agreeing on a shared key. It is
- * called by Keystore during startup if and only if Keystore loads multiple Keymaster HALs.
- * Keystore calls it on each of the HAL instances, and sends to it all of the
- * HmacSharingParameters returned by all HALs.
+ * Complete the creation of an HMAC key, shared with another IKeymasterDevice implementation.
+ * Any device with a StrongBox IKeymasterDevice has two IKeymasterDevice instances, because
+ * there must be a TEE IKeymasterDevice as well. The HMAC key used to MAC and verify
+ * authentication tokens must be shared between TEE and StrongBox so they can each validate
+ * tokens produced by the other. This method is the second and final step in the process for
+ * agreeing on a shared key. It is called by Android during startup. The system calls it on
+ * each of the HAL instances, and sends to it all of the HmacSharingParameters returned by all
+ * HALs.
*
- * This method computes the shared 32-byte HMAC ``H'' as follows (all Keymaster instances
+ * To ensure consistent ordering of the HmacSharingParameters, the caller must sort the
+ * parameters lexicographically. See the support/keymaster_utils.cpp for an operator< that
+ * defines the appropriate ordering.
+ *
+ * This method computes the shared 32-byte HMAC ``H'' as follows (all IKeymasterDevice instances
* perform the same computation to arrive at the same result):
*
* H = CKDF(key = K,
@@ -70,25 +258,27 @@
*
* ``CKDF'' is the standard AES-CMAC KDF from NIST SP 800-108 in counter mode (see Section
* 5.1 of the referenced publication). ``key'', ``context'', and ``label'' are
- * defined in the standard. The counter is prefixed, as shown in the construction on
- * page 12 of the standard. The label string is UTF-8 encoded.
+ * defined in the standard. The counter is prefixed and length L appended, as shown
+ * in the construction on page 12 of the standard. The label string is UTF-8 encoded.
*
* ``K'' is a pre-established shared secret, set up during factory reset. The mechanism for
* establishing this shared secret is implementation-defined, but see below for a
- * recommended approach, which assumes that the TEE Keymaster does not have storage
- * available to it, but the StrongBox Keymaster does.
+ * recommended approach, which assumes that the TEE IKeymasterDevice does not have
+ * storage available to it, but the StrongBox IKeymasterDevice does.
*
- * <b>CRITICAL SECURITY REQUIREMENT</b>: All keys created by a Keymaster instance must
+ * CRITICAL SECURITY REQUIREMENT: All keys created by a IKeymasterDevice instance must
* be cryptographically bound to the value of K, such that establishing a new K
* permanently destroys them.
*
* ``||'' represents concatenation.
*
* ``Pi'' is the i'th HmacSharingParameters value in the params vector. Note that at
- * present only two Keymaster implementations are supported, but this mechanism
+ * present only two IKeymasterDevice implementations are supported, but this mechanism
* extends without modification to any number of implementations. Encoding of an
* HmacSharingParameters is the concatenation of its two fields, i.e. seed || nonce.
*
+ * Note that the label "KeymasterSharedMac" is the 18-byte UTF-8 encoding of the string.
+ *
* Process for establishing K:
*
* Any method of securely establishing K that ensures that an attacker cannot obtain or
@@ -98,19 +288,19 @@
* have secure persistent storage. This model was chosen because StrongBox has secure
* persistent storage (by definition), but the TEE may not. The instance without storage is
* assumed to be able to derive a unique hardware-bound key (HBK) which is used only for
- * this purpose, and is not derivable outside of the secure environment..
+ * this purpose, and is not derivable outside the secure environment.
*
- * In what follows, T is the Keymaster instance without storage, S is the Keymaster instance
- * with storage:
+ * In what follows, T is the IKeymasterDevice instance without storage, S is the
+ * IKeymasterDevice instance with storage:
*
- * 1. T generates an ephemeral EC P-256 key pair K1
+ * 1. T generates an ephemeral EC P-256 key pair K1.
* 2. T sends K1_pub to S, signed with T's attestation key.
* 3. S validates the signature on K1_pub.
* 4. S generates an ephemeral EC P-256 key pair K2.
* 5. S sends {K1_pub, K2_pub}, to T, signed with S's attestation key.
- * 6. T validates the signature on {K1_pub, K2_pub}
+ * 6. T validates the signature on {K1_pub, K2_pub}.
* 7. T uses {K1_priv, K2_pub} with ECDH to compute session secret Q.
- * 8. T generates a random seed S
+ * 8. T generates a random seed S.
* 9. T computes K = KDF(HBK, S), where KDF is some secure key derivation function.
* 10. T sends M = AES-GCM-ENCRYPT(Q, {S || K}) to S.
* 10. S uses {K2_priv, K1_pub} with ECDH to compute session secret Q.
@@ -121,40 +311,54 @@
* T receives the computeSharedHmac call, it uses the seed provided by S to compute K. S,
* of course, has K stored.
*
- * @param params The HmacSharingParameters data returned by all Keymaster instances when
+ * @param params The HmacSharingParameters data returned by all IKeymasterDevice instances when
* getHmacSharingParameters was called.
*
- * @return sharingCheck A 32-byte value used to verify that all Keymaster instances have
+ * @return error ErrorCode::OK in the event that there is no error. ErrorCode::INVALID_ARGUMENT
+ * if one of the provided parameters is not the value returned by the prior call to
+ * getHmacParameters().
+ *
+ * @return sharingCheck A 32-byte value used to verify that all IKeymasterDevice instances have
* computed the same shared HMAC key. The sharingCheck value is computed as follows:
*
* sharingCheck = HMAC(H, "Keymaster HMAC Verification")
*
- * The string is UTF-8 encoded. If the returned values of all Keymaster instances don't
- * match, Keystore will assume that HMAC agreement failed.
+ * The string is UTF-8 encoded, 27 bytes in length. If the returned values of all
+ * IKeymasterDevice instances don't match, Keystore will assume that HMAC agreement
+ * failed.
*/
computeSharedHmac(vec<HmacSharingParameters> params)
generates (ErrorCode error, vec<uint8_t> sharingCheck);
/**
- * Verify authorizations for another Keymaster instance.
+ * Verify authorizations for another IKeymasterDevice instance.
*
- * On systems with both a StrongBox and a TEE Keymaster instance it is sometimes useful to ask
- * the TEE Keymaster to verify authorizations for a key hosted in StrongBox.
+ * On systems with both a StrongBox and a TEE IKeymasterDevice instance it is sometimes useful
+ * to ask the TEE IKeymasterDevice to verify authorizations for a key hosted in StrongBox.
*
* For every StrongBox operation, Keystore is required to call this method on the TEE Keymaster,
* passing in the StrongBox key's hardwareEnforced authorization list and the operation handle
- * returned by StrongBox begin(). The TEE Keymaster must validate all of the authorizations it
- * can and return those it validated in the VerificationToken. If it cannot verify any, the
- * parametersVerified field of the VerificationToken must be empty. Keystore must then pass the
- * VerificationToken to the subsequent invocations of StrongBox update() and finish().
+ * returned by StrongBox begin(). The TEE IKeymasterDevice must validate all of the
+ * authorizations it can and return those it validated in the VerificationToken. If it cannot
+ * verify any, the parametersVerified field of the VerificationToken must be empty. Keystore
+ * must then pass the VerificationToken to the subsequent invocations of StrongBox update() and
+ * finish().
*
* StrongBox implementations must return ErrorCode::UNIMPLEMENTED.
*
* @param operationHandle the operation handle returned by StrongBox Keymaster's begin().
*
- * @param parametersToVerify Set of authorizations to verify.
+ * @param parametersToVerify Set of authorizations to verify. The caller may provide an empty
+ * vector if the only required information is the TEE timestamp.
*
* @param authToken A HardwareAuthToken if needed to authorize key usage.
+ *
+ * @return error ErrorCode::OK on success or ErrorCode::UNIMPLEMENTED if the IKeymasterDevice is
+ * a StrongBox. If the IKeymasterDevice cannot verify one or more elements of
+ * parametersToVerify it must not return an error code, but just omit the unverified
+ * parameter from the VerificationToken.
+ *
+ * @return token the verification token. See VerificationToken in types.hal for details.
*/
verifyAuthorization(uint64_t operationHandle, vec<KeyParameter> parametersToVerify,
HardwareAuthToken authToken)
@@ -162,53 +366,143 @@
/**
- * Adds entropy to the RNG used by Keymaster. Entropy added through this method is guaranteed
- * not to be the only source of entropy used, and the mixing function is required to be secure,
- * in the sense that if the RNG is seeded (from any source) with any data the attacker cannot
- * predict (or control), then the RNG output is indistinguishable from random. Thus, if the
- * entropy from any source is good, the output must be good.
+ * Adds entropy to the RNG used by Keymaster. Entropy added through this method must not be the
+ * only source of entropy used, and a secure mixing function must be used to mix the entropy
+ * provided by this method with internally-generated entropy. The mixing function must be
+ * secure in the sense that if any one of the mixing function inputs is provided with any data
+ * the attacker cannot predict (or control), then the output of the seeded CRNG is
+ * indistinguishable from random. Thus, if the entropy from any source is good, the output must
+ * be good.
*
- * @param data Bytes to be mixed into the RNG.
+ * @param data Bytes to be mixed into the CRNG seed. The caller must not provide more than 2
+ * KiB of data per invocation.
*
- * @return error See the ErrorCode enum in types.hal.
+ * @return error ErrorCode::OK on success; ErrorCode::INVALID_INPUT_LENGTH if the caller
+ * provides more than 2 KiB of data.
*/
addRngEntropy(vec<uint8_t> data) generates (ErrorCode error);
/**
- * Generates a key, or key pair, returning a key blob and a description of the key.
+ * Generates a new cryptographic key, specifying associated parameters, which must be
+ * cryptographically bound to the key. IKeymasterDevice implementations must disallow any use
+ * of a key in any way inconsistent with the authorizations specified at generation time. With
+ * respect to parameters that the secure environment cannot enforce, the secure envionment's
+ * obligation is limited to ensuring that the unenforceable parameters associated with the key
+ * cannot be modified, so that every call to getKeyCharacteristics returns the original
+ * values. In addition, the characteristics returned by generateKey places parameters correctly
+ * in the hardware-enforced and software-enforced lists. See getKeyCharacteristics for more
+ * details.
*
- * @param keyParams Key generation parameters are defined as Keymaster tag/value pairs, provided
- * in params. See Tag in types.hal for the full list.
+ * In addition to the parameters provided, generateKey must add the following to the returned
+ * characteristics.
*
- * @return error See the ErrorCode enum in types.hal.
+ * o Tag::ORIGIN with the value KeyOrigin::GENERATED.
*
- * @return keyBlob Opaque, encrypted descriptor of the generated key. A recommended
- * implementation strategy is to include an encrypted copy of the key material, wrapped
- * in a key unavailable outside secure hardware.
+ * o Tag::BLOB_USAGE_REQUIREMENTS with the appropriate value (see KeyBlobUsageRequirements in
+ * types.hal).
*
- * @return keyCharacteristics Description of the generated key. See KeyCharacteristis in
- * types.hal.
+ * o Tag::CREATION_DATETIME with the appropriate value. Note that it is expected that this will
+ * generally be added by the HAL, not by the secure environment, and that it will be in the
+ * software-enforced list. It must be cryptographically bound to the key, like all tags.
+ *
+ * o Tag::OS_VERSION, Tag::OS_PATCHLEVEL, Tag::VENDOR_PATCHLEVEL and Tag::BOOT_PATCHLEVEL with
+ * appropriate values.
+ *
+ * The parameters provided to generateKey depend on the type of key being generated. This
+ * section summarizes the necessary and optional tags for each type of key. Tag::ALGORITHM is
+ * always necessary, to specify the type.
+ *
+ * == RSA Keys ==
+ *
+ * The following parameters are required to generate an RSA key:
+ *
+ * o Tag::Key_SIZE specifies the size of the public modulus, in bits. If omitted, generateKey
+ * must return ErrorCode::UNSUPPORTED_KEY_SIZE. Required values for TEE IKeymasterDevice
+ * implementations are 1024, 2048, 3072 and 4096. StrongBox IKeymasterDevice implementations
+ * must support 2048.
+ *
+ * o Tag::RSA_PUBLIC_EXPONENT specifies the RSA public exponent value. If omitted, generateKey
+ * must return ErrorCode::INVALID_ARGUMENT. The values 3 and 65537 must be supported. It is
+ * recommended to support all prime values up to 2^64. If provided with a non-prime value,
+ * generateKey must return ErrorCode::INVALID_ARGUMENT.
+ *
+ * The following parameters are not necessary to generate a usable RSA key, but generateKey must
+ * not return an error if they are omitted:
+ *
+ * o Tag::PURPOSE specifies allowed purposes. All KeyPurpose values (see types.hal) must be
+ * supported for RSA keys.
+ *
+ * o Tag::DIGEST specifies digest algorithms that may be used with the new key. TEE
+ * IKeymasterDevice implementatiosn must support all Digest values (see types.hal) for RSA
+ * keys. StrongBox IKeymasterDevice implementations must support SHA_2_256.
+ *
+ * o Tag::PADDING specifies the padding modes that may be used with the new
+ * key. IKeymasterDevice implementations must support PaddingMode::NONE,
+ * PaddingMode::RSA_OAEP, PaddingMode::RSA_PSS, PaddingMode::RSA_PKCS1_1_5_ENCRYPT and
+ * PaddingMode::RSA_PKCS1_1_5_SIGN for RSA keys.
+ *
+ * == ECDSA Keys ==
+ *
+ * Either Tag::KEY_SIZE or Tag::EC_CURVE must be provided to generate an ECDSA key. If neither
+ * is provided, generateKey must return ErrorCode::UNSUPPORTED_KEY_SIZE. If Tag::KEY_SIZE is
+ * provided, the possible values are 224, 256, 384 and 521, and must be mapped to Tag::EC_CURVE
+ * values P_224, P_256, P_384 and P_521, respectively. TEE IKeymasterDevice implementations
+ * must support all curves. StrongBox implementations must support P_256.
+ *
+ * == AES Keys ==
+ *
+ * Only Tag::KEY_SIZE is required to generate an AES key. If omitted, generateKey must return
+ * ErrorCode::UNSUPPORTED_KEY_SIZE. 128 and 256-bit key sizes must be supported.
+ *
+ * If Tag::BLOCK_MODE is specified with value BlockMode::GCM, then the caller must also provide
+ * Tag::MIN_MAC_LENGTH. If omitted, generateKey must return ErrorCode::MISSING_MIN_MAC_LENGTH.
+ *
+ *
+ * @param keyParams Key generation parameters are defined as IKeymasterDevice tag/value pairs,
+ * provided in params. See above for detailed specifications of which tags are required
+ * for which types of keys.
+ *
+ * @return keyBlob Opaque descriptor of the generated key. The recommended implementation
+ * strategy is to include an encrypted copy of the key material, wrapped in a key
+ * unavailable outside secure hardware.
+ *
+ * @return keyCharacteristics Description of the generated key. See the getKeyCharacteristics
+ * method below.
*/
generateKey(vec<KeyParameter> keyParams)
generates (ErrorCode error, vec<uint8_t> keyBlob, KeyCharacteristics keyCharacteristics);
/**
- * Imports a key, or key pair, returning a key blob and/or a description of the key.
+ * Imports key material into an IKeymasterDevice. Key definition parameters and return values
+ * are the same as for generateKey, with the following exceptions:
*
- * @param keyParams Key generation parameters are defined as Keymaster tag/value pairs, provided
- * in params. See Tag for the full list.
+ * o Tag::KEY_SIZE is not necessary in the input parameters. If not provided, the
+ * IKeymasterDevice must deduce the value from the provided key material and add the tag and
+ * value to the key characteristics. If Tag::KEY_SIZE is provided, the IKeymasterDevice must
+ * validate it against the key material. In the event of a mismatch, importKey must return
+ * ErrorCode::IMPORT_PARAMETER_MISMATCH.
*
- * @param keyFormat The format of the key material to import.
+ * o Tag::RSA_PUBLIC_EXPONENT (for RSA keys only) is not necessary in the input parameters. If
+ * not provided, the IKeymasterDevice must deduce the value from the provided key material and
+ * add the tag and value to the key characteristics. If Tag::RSA_PUBLIC_EXPONENT is provided,
+ * the IKeymasterDevice must validate it against the key material. In the event of a
+ * mismatch, importKey must return ErrorCode::IMPORT_PARAMETER_MISMATCH.
+ *
+ * o Tag::ORIGIN (returned in keyCharacteristics) must have the value KeyOrigin::IMPORTED.
+ *
+ * @param keyParams Key generation parameters are defined as IKeymasterDevice tag/value pairs,
+ * provided in params.
+ *
+ * @param keyFormat The format of the key material to import. See KeyFormat in types.hal.
*
* @pram keyData The key material to import, in the format specifed in keyFormat.
*
- * @return error See the ErrorCode enum.
+ * @return keyBlob Opaque descriptor of the imported key. The recommended implementation
+ * strategy is to include an encrypted copy of the key material, wrapped in a key
+ * unavailable outside secure hardware.
*
- * @return keyBlob Opaque, encrypted descriptor of the generated key, which will generally
- * contain a copy of the key material, wrapped in a key unavailable outside secure
- * hardware.
- *
- * @return keyCharacteristics Decription of the generated key.
+ * @return keyCharacteristics Decription of the generated key. See the getKeyCharacteristics
+ * method below.
*/
importKey(vec<KeyParameter> keyParams, KeyFormat keyFormat, vec<uint8_t> keyData)
generates (ErrorCode error, vec<uint8_t> keyBlob, KeyCharacteristics keyCharacteristics);
@@ -241,10 +535,10 @@
* o keyParams is the characteristics of the key to be imported (as with generateKey or
* importKey). If the secure import is successful, these characteristics must be
* associated with the key exactly as if the key material had been insecurely imported
- * with the @3.0::IKeymasterDevice::importKey.
+ * with the @3.0::IKeymasterDevice::importKey. See attestKey() for documentation of the
+ * AuthorizationList schema.
* o encryptedTransportKey is a 256-bit AES key, XORed with a masking key and then encrypted
- * in RSA-OAEP mode (SHA-256 digest, SHA-1 MGF1 digest) with the wrapping key specified by
- * wrappingKeyBlob.
+ * with the wrapping key specified by wrappingKeyBlob.
* o keyDescription is a KeyDescription, above.
* o encryptedKey is the key material of the key to be imported, in format keyFormat, and
* encrypted with encryptedEphemeralKey in AES-GCM mode, with the DER-encoded
@@ -266,10 +560,7 @@
* that the origin tag should be set to SECURELY_IMPORTED.
*
* @param wrappingKeyBlob The opaque key descriptor returned by generateKey() or importKey().
- * This key must have been created with Purpose::WRAP_KEY, and must be a key algorithm
- * that supports encryption and must be at least as strong (in key size) as the key to be
- * imported (per NIST key length recommendations: 112 bits symmetric is equivalent to
- * 2048-bit RSA or 224-bit EC, 128 bits symmetric ~ 3072-bit RSA or 256-bit EC, etc.).
+ * This key must have been created with Purpose::WRAP_KEY.
*
* @param maskingKey The 32-byte value XOR'd with the transport key in the SecureWrappedKey
* structure.
@@ -291,8 +582,6 @@
* If the wrappedKeyData does not contain such a tag and value, this argument must be
* ignored.
*
- * @return error See the ErrorCode enum.
- *
* @return keyBlob Opaque descriptor of the imported key. It is recommended that the keyBlob
* contain a copy of the key material, wrapped in a key unavailable outside secure
* hardware.
@@ -303,10 +592,18 @@
generates(ErrorCode error, vec<uint8_t> keyBlob, KeyCharacteristics keyCharacteristics);
/**
- * Returns the characteristics of the specified key, if the keyBlob is valid (implementations
- * must fully validate the integrity of the key).
+ * Returns parameters associated with the provided key, divided into two sets: hardware-enforced
+ * and software-enforced. The description here applies equally to the key characteristics lists
+ * returned by generateKey, importKey and importWrappedKey. The characteristics returned by
+ * this method completely describe the type and usage of the specified key.
*
- * @param keyBlob The opaque descriptor returned by generateKey() or importKey();
+ * The rule that IKeymasterDevice implementations must use for deciding whether a given tag
+ * belongs in the hardware-enforced or software-enforced list is that if the meaning of the tag
+ * is fully assured by secure hardware, it is hardware enforced. Otherwise, it's software
+ * enforced.
+ *
+ *
+ * @param keyBlob The opaque descriptor returned by generateKey, importKey or importWrappedKey.
*
* @param clientId An opaque byte string identifying the client. This value must match the
* Tag::APPLICATION_ID data provided during key generation/import. Without the correct
@@ -318,9 +615,7 @@
* value, it must be computationally infeasible for the secure hardware to obtain the key
* material.
*
- * @return error See the ErrorCode enum in types.hal.
- *
- * @return keyCharacteristics Decription of the generated key. See KeyCharacteristis in
+ * @return keyCharacteristics Decription of the generated key. See KeyCharacteristics in
* types.hal.
*/
getKeyCharacteristics(vec<uint8_t> keyBlob, vec<uint8_t> clientId, vec<uint8_t> appData)
@@ -344,8 +639,6 @@
* value, it must be computationally infeasible for the secure hardware to obtain the key
* material.
*
- * @return error See the ErrorCode enum in types.hal.
- *
* @return keyMaterial The public key material in PKCS#8 format.
*/
exportKey(KeyFormat keyFormat, vec<uint8_t> keyBlob, vec<uint8_t> clientId,
@@ -353,56 +646,191 @@
/**
* Generates a signed X.509 certificate chain attesting to the presence of keyToAttest in
- * Keymaster. The certificate must contain an extension with OID 1.3.6.1.4.1.11129.2.1.17 and
- * value defined in:
+ * Keymaster.
*
- * https://developer.android.com/training/articles/security-key-attestation.html.
+ * The certificates in the chain must be ordered such that each certificate is signed by the
+ * subsequent one, up to the root which must be self-signed. The first certificate in the chain
+ * signs the public key info of the attested key and must contain the following entries (see RFC
+ * 5280 for details on each):
+ *
+ * o version -- with value 2
+ *
+ * o serialNumber -- with value 1 (same value for all keys)
+ *
+ * o signature -- contains an the AlgorithmIdentifier of the algorithm used to sign, must be
+ * ECDSA for EC keys, RSA for RSA keys.
+ *
+ * o issuer -- must contain the same value as the Subject field of the next certificate.
+ *
+ * o validity -- SEQUENCE of two dates, containing the values of Tag::ACTIVE_DATETIME and
+ * Tag::USAGE_EXPIRE_DATETIME. The tag values are in milliseconds since Jan 1, 1970; see RFD
+ * 5280 for the correct representation in certificates. If Tag::ACTIVE_DATETIME is not
+ * present in the key, the IKeymasterDevice must use the value of Tag::CREATION_DATETIME. If
+ * Tag::USAGE_EXPIRE_DATETIME is not present, the IKeymasterDevice must use the expiration
+ * date of the batch attestation certificate (see below).
+ *
+ * o subject -- CN="Android Keystore Key" (same value for all keys)
+ *
+ * o subjectPublicKeyInfo -- X.509 SubjectPublicKeyInfo containing the attested public key.
+ *
+ * o Key Usage extension -- digitalSignature bit must be set iff the attested key has
+ * KeyPurpose::SIGN. dataEncipherment bit must be set iff the attested key has
+ * KeyPurpose::DECRYPT. keyEncipherment bit must be set iff the attested key has
+ * KeyPurpose::KEY_WRAP. All other bits must be clear.
+ *
+ * In addition to the above, the attestation certificate must contain an extension with OID
+ * 1.3.6.1.4.1.11129.2.1.17 and value according to the KeyDescription schema defined as:
+ *
+ * KeyDescription ::= SEQUENCE {
+ * attestationVersion INTEGER, # Value 3
+ * attestationSecurityLevel SecurityLevel, # See below
+ * keymasterVersion INTEGER, # Value 4
+ * keymasterSecurityLevel SecurityLevel, # See below
+ * attestationChallenge OCTET_STRING, # Tag::ATTESTATION_CHALLENGE from attestParams
+ * uniqueId OCTET_STRING, # Empty unless key has Tag::INCLUDE_UNIQUE_ID
+ * softwareEnforced AuthorizationList, # See below
+ * hardwareEnforced AuthorizationList, # See below
+ * }
+ *
+ * SecurityLevel ::= ENUMERATED {
+ * Software (0),
+ * TrustedEnvironment (1),
+ * StrongBox (2),
+ * }
+ *
+ * RootOfTrust ::= SEQUENCE {
+ * verifiedBootKey OCTET_STRING,
+ * deviceLocked BOOLEAN,
+ * verifiedBootState VerifiedBootState,
+ * # verifiedBootHash must contain 32-byte value that represents the state of all binaries
+ * # or other components validated by verified boot. Updating any verified binary or
+ * # component must cause this value to change.
+ * verifiedBootHash OCTET_STRING,
+ * }
+ *
+ * VerifiedBootState ::= ENUMERATED {
+ * Verified (0),
+ * SelfSigned (1),
+ * Unverified (2),
+ * Failed (3),
+ * }
+ *
+ * AuthorizationList ::= SEQUENCE {
+ * purpose [1] EXPLICIT SET OF INTEGER OPTIONAL,
+ * algorithm [2] EXPLICIT INTEGER OPTIONAL,
+ * keySize [3] EXPLICIT INTEGER OPTIONAL.
+ * blockMode [4] EXPLICIT SET OF INTEGER OPTIONAL,
+ * digest [5] EXPLICIT SET OF INTEGER OPTIONAL,
+ * padding [6] EXPLICIT SET OF INTEGER OPTIONAL,
+ * ecCurve [10] EXPLICIT INTEGER OPTIONAL,
+ * rsaPublicExponent [200] EXPLICIT INTEGER OPTIONAL,
+ * rollbackResistance [303] EXPLICIT NULL OPTIONAL,
+ * activeDateTime [400] EXPLICIT INTEGER OPTIONAL
+ * originationExpireDateTime [401] EXPLICIT INTEGER OPTIONAL
+ * usageExpireDateTime [402] EXPLICIT INTEGER OPTIONAL
+ * noAuthRequired [503] EXPLICIT NULL OPTIONAL,
+ * userAuthType [504] EXPLICIT INTEGER OPTIONAL,
+ * authTimeout [505] EXPLICIT INTEGER OPTIONAL,
+ * allowWhileOnBody [506] EXPLICIT NULL OPTIONAL,
+ * trustedUserPresenceReq [507] EXPLICIT NULL OPTIONAL,
+ * trustedConfirmationReq [508] EXPLICIT NULL OPTIONAL,
+ * unlockedDeviceReq [509] EXPLICIT NULL OPTIONAL,
+ * allApplications [600] EXPLICIT NULL OPTIONAL,
+ * applicationId [601] EXPLICIT OCTET_STRING OPTIONAL,
+ * creationDateTime [701] EXPLICIT INTEGER OPTIONAL,
+ * origin [702] EXPLICIT INTEGER OPTIONAL,
+ * rollbackResistant [703] EXPLICIT NULL OPTIONAL,
+ * rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL,
+ * osVersion [705] EXPLICIT INTEGER OPTIONAL,
+ * osPatchLevel [706] EXPLICIT INTEGER OPTIONAL,
+ * attestationChallenge [708] EXPLICIT OCTET_STRING OPTIONAL,
+ * attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL,
+ * attestationIdBrand [710] EXPLICIT OCTET_STRING OPTIONAL,
+ * attestationIdDevice [711] EXPLICIT OCTET_STRING OPTIONAL,
+ * attestationIdProduct [712] EXPLICIT OCTET_STRING OPTIONAL,
+ * attestationIdSerial [713] EXPLICIT OCTET_STRING OPTIONAL,
+ * attestationIdImei [714] EXPLICIT OCTET_STRING OPTIONAL,
+ * attestationIdMeid [715] EXPLICIT OCTET_STRING OPTIONAL,
+ * attestationIdManufacturer [716] EXPLICIT OCTET_STRING OPTIONAL,
+ * attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL,
+ * vendorPatchLevel [718] EXPLICIT INTEGER OPTIONAL,
+ * bootPatchLevel [718] EXPLICIT INTEGER OPTIONAL,
+ * }
+ *
+ * The above schema is mostly a straightforward translation of the IKeymasterDevice tag/value
+ * parameter lists to ASN.1:
+ *
+ * o TagType::ENUM, TagType::UINT, TagType::ULONG and TagType::DATE tags are represented as
+ * ASN.1 INTEGER.
+ *
+ * o TagType::ENUM_REP, TagType::UINT_REP and TagType::ULONG_REP tags are represented as ASN.1
+ * SET of INTEGER.
+ *
+ * o TagType::BOOL tags are represented as ASN.1 NULL. All entries in AuthorizationList are
+ * OPTIONAL, so the presence of the tag means "true", absence means "false".
+ *
+ * o TagType::BYTES tags are represented as ASN.1 OCTET_STRING.
+ *
+ * The numeric ASN.1 tag numbers are the same values as the IKeymasterDevice Tag enum values,
+ * except with the TagType modifier stripped.
+ *
+ * The attestation certificate must be signed by a "batch" key, which must be securely
+ * pre-installed into the device, generally in the factory, and securely stored to prevent
+ * access or extraction. The batch key must be used only for signing attestation certificates.
+ * The batch attestation certificate must be signed by a chain or zero or more intermediates
+ * leading to a self-signed roots. The intermediate and root certificate signing keys must not
+ * exist anywhere on the device.
+ *
+ * == ID Attestation ==
+ *
+ * ID attestation is a special case of key attestation in which unique device ID values are
+ * included in the signed attestation certificate.
*
* @param keyToAttest The opaque descriptor returned by generateKey() or importKey(). The
* referenced key must be asymmetric.
*
- * @param attestParams Parameters for the attestation, notably Tag::ATTESTATION_CHALLENGE.
- *
- * @return error See the ErrorCode enum in types.hal.
+ * @param attestParams Parameters for the attestation. Must contain Tag::ATTESTATION_CHALLENGE,
+ * the value of which must be put in the attestationChallenge field of the KeyDescription
+ * ASN.1 structure defined above.
*
* @return certChain The attestation certificate, and additional certificates back to the root
* attestation certificate, which clients will need to check against a known-good value.
+ * The certificates must be DER-encoded.
*/
attestKey(vec<uint8_t> keyToAttest, vec<KeyParameter> attestParams)
generates (ErrorCode error, vec<vec<uint8_t>> certChain);
/**
- * Upgrades an old key blob. Keys can become "old" in two ways: Keymaster can be upgraded to a
- * new version with an incompatible key blob format, or the system can be updated to invalidate
- * the OS version (OS_VERSION tag), system patch level (OS_PATCHLEVEL tag), vendor patch level
- * (VENDOR_PATCH_LEVEL tag), boot patch level (BOOT_PATCH_LEVEL tag) or other,
+ * Upgrades an old key blob. Keys can become "old" in two ways: IKeymasterDevice can be
+ * upgraded to a new version with an incompatible key blob format, or the system can be updated
+ * to invalidate the OS version (OS_VERSION tag), system patch level (OS_PATCHLEVEL tag), vendor
+ * patch level (VENDOR_PATCH_LEVEL tag), boot patch level (BOOT_PATCH_LEVEL tag) or other,
* implementation-defined patch level (keymaster implementers are encouraged to extend this HAL
- * with a minor version extension to define validatable patch levels for other images; tags
- * must be defined in the implemeter's namespace, starting at 10000). In either case,
- * attempts to use an old key blob with getKeyCharacteristics(), exportKey(), attestKey() or
- * begin() must result in Keymaster returning ErrorCode::KEY_REQUIRES_UPGRADE. The caller must
- * use this method to upgrade the key blob.
+ * with a minor version extension to define validatable patch levels for other images; tags must
+ * be defined in the implementer's namespace, starting at 10000). In either case, attempts to
+ * use an old key blob with getKeyCharacteristics(), exportKey(), attestKey() or begin() must
+ * result in IKeymasterDevice returning ErrorCode::KEY_REQUIRES_UPGRADE. The caller must use
+ * this method to upgrade the key blob.
*
- * If upgradeKey is asked to update a key with any version or patch level that is higher than
- * the current system version or patch level, it must return ErrorCode::INVALID_ARGUMENT. There
- * is one exception: it is always permissible to "upgrade" from any OS_VERSION number to
- * OS_VERSION 0. For example, if the key has OS_VERSION 080001, it is permisible to upgrade the
- * key if the current system version is 080100, because the new version is larger, or if the
- * current system version is 0, because upgrades to 0 are always allowed. If the system version
- * were 080000, however, keymaster must return ErrorCode::INVALID_ARGUMENT because that value is
- * smaller than 080001.
+ * The upgradeKey method must examine each version or patch level associated with the key. If
+ * any one of them is higher than the corresponding current device value upgradeKey() must
+ * return ErrorCode::INVALID_ARGUMENT. There is one exception: it is always permissible to
+ * "downgrade" from any OS_VERSION number to OS_VERSION 0. For example, if the key has
+ * OS_VERSION 080001, it is permisible to upgrade the key if the current system version is
+ * 080100, because the new version is larger, or if the current system version is 0, because
+ * upgrades to 0 are always allowed. If the system version were 080000, however, keymaster must
+ * return ErrorCode::INVALID_ARGUMENT because that value is smaller than 080001. Values other
+ * than OS_VERSION must never be downgraded.
*
* Note that Keymaster versions 2 and 3 required that the system and boot images have the same
- * patch level and OS version. This requirement is relaxed for Keymaster 4, and the OS version
- * in the boot image footer is no longer used.
+ * patch level and OS version. This requirement is relaxed for 4.0::IKeymasterDevice, and the
+ * OS version in the boot image footer is no longer used.
*
* @param keyBlobToUpgrade The opaque descriptor returned by generateKey() or importKey();
*
* @param upgradeParams A parameter list containing any parameters needed to complete the
* upgrade, including Tag::APPLICATION_ID and Tag::APPLICATION_DATA.
*
- * @return error See the ErrorCode enum.
- *
* @return upgradedKeyBlob A new key blob that references the same key as keyBlobToUpgrade, but
* is in the new format, or has the new version data.
*/
@@ -416,8 +844,6 @@
* unusable.
*
* @param keyBlob The opaque descriptor returned by generateKey() or importKey();
- *
- * @return error See the ErrorCode enum.
*/
deleteKey(vec<uint8_t> keyBlob) generates (ErrorCode error);
@@ -441,8 +867,6 @@
* must never attest any device ids.
*
* This is a NOP if device id attestation is not supported.
- *
- * @return error See the ErrorCode enum.
*/
destroyAttestationIds() generates (ErrorCode error);
@@ -452,12 +876,180 @@
* to update(), finish() or abort().
*
* It is critical that each call to begin() be paired with a subsequent call to finish() or
- * abort(), to allow the Keymaster implementation to clean up any internal operation state. The
- * caller's failure to do this may leak internal state space or other internal resources and may
- * eventually cause begin() to return ErrorCode::TOO_MANY_OPERATIONS when it runs out of space
- * for operations. Any result other than ErrorCode::OK from begin(), update() or finish()
- * implicitly aborts the operation, in which case abort() need not be called (and must return
- * ErrorCode::INVALID_OPERATION_HANDLE if called).
+ * abort(), to allow the IKeymasterDevice implementation to clean up any internal operation
+ * state. The caller's failure to do this may leak internal state space or other internal
+ * resources and may eventually cause begin() to return ErrorCode::TOO_MANY_OPERATIONS when it
+ * runs out of space for operations. Any result other than ErrorCode::OK from begin(), update()
+ * or finish() implicitly aborts the operation, in which case abort() need not be called (and
+ * must return ErrorCode::INVALID_OPERATION_HANDLE if called). IKeymasterDevice implementations
+ * must support 16 concurrent operations.
+ *
+ * If Tag::APPLICATION_ID or Tag::APPLICATION_DATA were specified during key generation or
+ * import, calls to begin must include those tags with the originally-specified values in the
+ * inParams argument to this method. If not, begin() must return ErrorCode::INVALID_KEY_BLOB.
+ *
+ * == Authorization Enforcement ==
+ *
+ * The following key authorization parameters must be enforced by the IKeymasterDevice secure
+ * environment if the tags were returned in the "hardwareEnforced" list in the
+ * KeyCharacteristics. Public key operations, meaning KeyPurpose::ENCRYPT and
+ * KeyPurpose::VERIFY must be allowed to succeed even if authorization requirements are not met.
+ *
+ * -- All Key Types --
+ *
+ * The tags in this section apply to all key types. See below for additional key type-specific
+ * tags.
+ *
+ * o Tag::PURPOSE: The purpose specified in the begin() call must match one of the purposes in
+ * the key authorizations. If the specified purpose does not match, begin() must return
+ * ErrorCode::UNSUPPORTED_PURPOSE.
+ *
+ * o Tag::ACTIVE_DATETIME can only be enforced if a trusted UTC time source is available. If
+ * the current date and time is prior to the tag value, begin() must return
+ * ErrorCode::KEY_NOT_YET_VALID.
+ *
+ * o Tag::ORIGINATION_EXPIRE_DATETIME can only be enforced if a trusted UTC time source is
+ * available. If the current date and time is later than the tag value and the purpose is
+ * KeyPurpose::ENCRYPT or KeyPurpose::SIGN, begin() must return ErrorCode::KEY_EXPIRED.
+ *
+ * o Tag::USAGE_EXPIRE_DATETIME can only be enforced if a trusted UTC time source is
+ * available. If the current date and time is later than the tag value and the purpose is
+ * KeyPurpose::DECRYPT or KeyPurpose::VERIFY, begin() must return ErrorCode::KEY_EXPIRED.
+
+ * o Tag::MIN_SECONDS_BETWEEN_OPS must be compared with a trusted relative timer indicating the
+ * last use of the key. If the last use time plus the tag value is less than the current
+ * time, begin() must return ErrorCode::KEY_RATE_LIMIT_EXCEEDED. See the tag description for
+ * important implementation details.
+
+ * o Tag::MAX_USES_PER_BOOT must be compared against a secure counter that tracks the uses of
+ * the key since boot time. If the count of previous uses exceeds the tag value, begin() must
+ * return ErrorCode::KEY_MAX_OPS_EXCEEDED.
+ *
+ * o Tag::USER_SECURE_ID must be enforced by this method if and only if the key also has
+ * Tag::AUTH_TIMEOUT (if it does not have Tag::AUTH_TIMEOUT, the Tag::USER_SECURE_ID
+ * requirement must be enforced by update() and finish()). If the key has both, then this
+ * method must receive a non-empty HardwareAuthToken in the authToken argument. For the auth
+ * token to be valid, all of the following have to be true:
+ *
+ * o The HMAC field must validate correctly.
+ *
+ * o At least one of the Tag::USER_SECURE_ID values from the key must match at least one of
+ * the secure ID values in the token.
+ *
+ * o The key must have a Tag::USER_AUTH_TYPE that matches the auth type in the token.
+ *
+ * o The timestamp in the auth token plus the value of the Tag::AUTH_TIMEOUT must be less than
+ * the current secure timestamp (which is a monotonic timer counting milliseconds since
+ * boot.)
+ *
+ * If any of these conditions are not met, begin() must return
+ * ErrorCode::KEY_USER_NOT_AUTHENTICATED.
+ *
+ * o Tag::CALLER_NONCE allows the caller to specify a nonce or initialization vector (IV). If
+ * the key doesn't have this tag, but the caller provided Tag::NONCE to this method,
+ * ErrorCode::CALLER_NONCE_PROHIBITED must be returned.
+ *
+ * o Tag::BOOTLOADER_ONLY specifies that only the bootloader may use the key. If this method is
+ * called with a bootloader-only key after the bootloader has finished executing, it must
+ * return ErrorCode::INVALID_KEY_BLOB. The mechanism for notifying the IKeymasterDevice that
+ * the bootloader has finished executing is implementation-defined.
+ *
+ * -- RSA Keys --
+ *
+ * All RSA key operations must specify exactly one padding mode in inParams. If unspecified or
+ * specified more than once, the begin() must return ErrorCode::UNSUPPORTED_PADDING_MODE.
+ *
+ * RSA signing and verification operations need a digest, as do RSA encryption and decryption
+ * operations with OAEP padding mode. For those cases, the caller must specify exactly one
+ * digest in inParams. If unspecified or specified more than once, begin() must return
+ * ErrorCode::UNSUPPORTED_DIGEST.
+ *
+ * Private key operations (KeyPurpose::DECRYPT and KeyPurpose::SIGN) need authorization of
+ * digest and padding, which means that the key authorizations need to contain the specified
+ * values. If not, begin() must return ErrorCode::INCOMPATIBLE_DIGEST or
+ * ErrorCode::INCOMPATIBLE_PADDING, as appropriate. Public key operations (KeyPurpose::ENCRYPT
+ * and KeyPurpose::VERIFY) are permitted with unauthorized digest or padding modes.
+ *
+ * With the exception of PaddingMode::NONE, all RSA padding modes are applicable only to certain
+ * purposes. Specifically, PaddingMode::RSA_PKCS1_1_5_SIGN and PaddingMode::RSA_PSS only
+ * support signing and verification, while PaddingMode::RSA_PKCS1_1_5_ENCRYPT and
+ * PaddingMode::RSA_OAEP only support encryption and decryption. begin() must return
+ * ErrorCode::UNSUPPORTED_PADDING_MODE if the specified mode does not support the specified
+ * purpose.
+ *
+ * There are some important interactions between padding modes and digests:
+ *
+ * o PaddingMode::NONE indicates that a "raw" RSA operation is performed. If signing or
+ * verifying, Digest::NONE is specified for the digest. No digest is necessary for unpadded
+ * encryption or decryption.
+ *
+ * o PaddingMode::RSA_PKCS1_1_5_SIGN padding requires a digest. The digest may be Digest::NONE,
+ * in which case the Keymaster implementation cannot build a proper PKCS#1 v1.5 signature
+ * structure, because it cannot add the DigestInfo structure. Instead, the IKeymasterDevice
+ * must construct 0x00 || 0x01 || PS || 0x00 || M, where M is the provided message and PS is a
+ * random padding string at least eight bytes in length. The size of the RSA key has to be at
+ * least 11 bytes larger than the message, otherwise begin() must return
+ * ErrorCode::INVALID_INPUT_LENGTH.
+ *
+ * o PaddingMode::RSA_PKCS1_1_1_5_ENCRYPT padding does not require a digest.
+ *
+ * o PaddingMode::RSA_PSS padding requires a digest, which may not be Digest::NONE. If
+ * Digest::NONE is specified, the begin() must return ErrorCode::INCOMPATIBLE_DIGEST. In
+ * addition, the size of the RSA key must be at least 2 + D bytes larger than the output size
+ * of the digest, where D is the size of the digest, in bytes. Otherwise begin() must
+ * return ErrorCode::INCOMPATIBLE_DIGEST. The salt size must be D.
+ *
+ * o PaddingMode::RSA_OAEP padding requires a digest, which may not be Digest::NONE. If
+ * Digest::NONE is specified, begin() must return ErrorCode::INCOMPATIBLE_DIGEST. The OAEP
+ * mask generation function must be MGF1 and the MGF1 digest must be SHA1, regardless of the
+ * OAEP digest specified.
+ *
+ * -- EC Keys --
+ *
+ * EC key operations must specify exactly one padding mode in inParams. If unspecified or
+ * specified more than once, begin() must return ErrorCode::UNSUPPORTED_PADDING_MODE.
+ *
+ * Private key operations (KeyPurpose::SIGN) need authorization of digest and padding, which
+ * means that the key authorizations must contain the specified values. If not, begin() must
+ * return ErrorCode::INCOMPATIBLE_DIGEST. Public key operations (KeyPurpose::VERIFY) are
+ * permitted with unauthorized digest or padding.
+ *
+ * -- AES Keys --
+ *
+ * AES key operations must specify exactly one block mode (Tag::BLOCK_MODE) and one padding mode
+ * (Tag::PADDING) in inParams. If either value is unspecified or specified more than once,
+ * begin() must return ErrorCode::UNSUPPORTED_BLOCK_MODE or
+ * ErrorCode::UNSUPPORTED_PADDING_MODE. The specified modes must be authorized by the key,
+ * otherwise begin() must return ErrorCode::INCOMPATIBLE_BLOCK_MODE or
+ * ErrorCode::INCOMPATIBLE_PADDING_MODE.
+ *
+ * If the block mode is BlockMode::GCM, inParams must specify Tag::MAC_LENGTH, and the specified
+ * value must be a multiple of 8 that is not greater than 128 or less than the value of
+ * Tag::MIN_MAC_LENGTH in the key authorizations. For MAC lengths greater than 128 or
+ * non-multiples of 8, begin() must return ErrorCode::UNSUPPORTED_MAC_LENGTH. For values less
+ * than the key's minimum length, begin() must return ErrorCode::INVALID_MAC_LENGTH.
+ *
+ * If the block mode is BlockMode::GCM or BlockMode::CTR, the specified padding mode must be
+ * PaddingMode::NONE. For BlockMode::ECB or BlockMode::CBC, the mode may be PaddingMode::NONE
+ * or PaddingMode::PKCS7. If the padding mode doesn't meet these conditions, begin() must
+ * return ErrorCode::INCOMPATIBLE_PADDING_MODE.
+ *
+ * If the block mode is BlockMode::CBC, BlockMode::CTR, or BlockMode::GCM, an initialization
+ * vector or nonce is required. In most cases, callers shouldn't provide an IV or nonce and the
+ * IKeymasterDevice implementation must generate a random IV or nonce and return it via
+ * Tag::NONCE in outParams. CBC and CTR IVs are 16 bytes. GCM nonces are 12 bytes. If the key
+ * authorizations contain Tag::CALLER_NONCE, then the caller may provide an IV/nonce with
+ * Tag::NONCE in inParams. If a nonce is provided when Tag::CALLER_NONCE is not authorized,
+ * begin() must return ErrorCode::CALLER_NONCE_PROHIBITED. If a nonce is not provided when
+ * Tag::CALLER_NONCE is authorized, IKeymasterDevice msut generate a random IV/nonce.
+ *
+ * -- HMAC keys --
+ *
+ * HMAC key operations must specify Tag::MAC_LENGTH in inParams. The specified value must be a
+ * multiple of 8 that is not greater than the digest length or less than the value of
+ * Tag::MIN_MAC_LENGTH in the key authorizations. For MAC lengths greater than the digest
+ * length or non-multiples of 8, begin() must return ErrorCode::UNSUPPORTED_MAC_LENGTH. For
+ * values less than the key's minimum length, begin() must return ErrorCode::INVALID_MAC_LENGTH.
*
* @param purpose The purpose of the operation, one of KeyPurpose::ENCRYPT, KeyPurpose::DECRYPT,
* KeyPurpose::SIGN or KeyPurpose::VERIFY. Note that for AEAD modes, encryption and
@@ -466,7 +1058,7 @@
*
* @param keyBlob The opaque key descriptor returned by generateKey() or importKey(). The key
* must have a purpose compatible with purpose and all of its usage requirements must be
- * satisfied, or begin() must return an appropriate error code.
+ * satisfied, or begin() must return an appropriate error code (see above).
*
* @param inParams Additional parameters for the operation. If Tag::APPLICATION_ID or
* Tag::APPLICATION_DATA were provided during generation, they must be provided here, or
@@ -478,8 +1070,6 @@
* @param authToken Authentication token. Callers that provide no token must set all numeric
* fields to zero and the MAC must be an empty vector.
*
- * @return error See the ErrorCode enum in types.hal.
- *
* @return outParams Output parameters. Used to return additional data from the operation
* initialization, notably to return the IV or nonce from operations that generate an IV
* or nonce.
@@ -493,13 +1083,87 @@
/**
* Provides data to, and possibly receives output from, an ongoing cryptographic operation begun
- * with begin().
+ * with begin(). The operation is specified by the operationHandle paramater.
*
* If operationHandle is invalid, update() must return ErrorCode::INVALID_OPERATION_HANDLE.
*
- * update() may not consume all of the data provided in the data buffer. update() must return
- * the amount consumed in inputConsumed. The caller may provide the unconsumed data in a
- * subsequent call.
+ * To provide more flexibility for buffer handling, implementations of this method have the
+ * option of consuming less data than was provided. The caller is responsible for looping to
+ * feed the rest of the data in subsequent calls. The amount of input consumed must be returned
+ * in the inputConsumed parameter. Implementations must always consume at least one byte, unless
+ * the operation cannot accept any more; if more than zero bytes are provided and zero bytes are
+ * consumed, callers must consider this an error and abort the operation.
+ *
+ * Implementations may also choose how much data to return, as a result of the update. This is
+ * only relevant for encryption and decryption operations, because signing and verification
+ * return no data until finish. It is recommended to return data as early as possible, rather
+ * than buffer it.
+ *
+ * If this method returns an error code other than ErrorCode::OK, the operation is aborted and
+ * the operation handle must be invalidated. Any future use of the handle, with this method,
+ * finish, or abort, must return ErrorCode::INVALID_OPERATION_HANDLE.
+ *
+ * == Authorization Enforcement ==
+ *
+ * Key authorization enforcement is performed primarily in begin(). The one exception is the
+ * case where the key has:
+
+ * o One or more Tag::USER_SECURE_IDs, and
+ *
+ * o Does not have a Tag::AUTH_TIMEOUT
+ *
+ * In this case, the key requires an authorization per operation, and the update method must
+ * receive a non-empty and valid HardwareAuthToken. For the auth token to be valid, all of the
+ * following has to be true:
+ *
+ * o The HMAC field must validate correctly.
+ *
+ * o At least one of the Tag::USER_SECURE_ID values from the key must match at least one of
+ * the secure ID values in the token.
+ *
+ * o The key must have a Tag::USER_AUTH_TYPE that matches the auth type in the token.
+ *
+ * o The challenge field in the auth token must contain the operationHandle
+ *
+ * If any of these conditions are not met, update() must return
+ * ErrorCode::KEY_USER_NOT_AUTHENTICATED.
+ *
+ * The caller must provide the auth token on every call to update() and finish().
+ *
+ * -- RSA keys --
+ *
+ * For signing and verification operations with Digest::NONE, this method must accept the entire
+ * block to be signed or verified in a single update. It may not consume only a portion of the
+ * block in these cases. However, the caller may choose to provide the data in multiple updates,
+ * and update() must accept the data this way as well. If the caller provides more data to sign
+ * than can be used (length of data exceeds RSA key size), update() must return
+ * ErrorCode::INVALID_INPUT_LENGTH.
+ *
+ * -- ECDSA keys --
+ *
+ * For signing and verification operations with Digest::NONE, this method must accept the entire
+ * block to be signed or verified in a single update. This method may not consume only a
+ * portion of the block. However, the caller may choose to provide the data in multiple updates
+ * and update() must accept the data this way as well. If the caller provides more data to sign
+ * than can be used, the data is silently truncated. (This differs from the handling of excess
+ * data provided in similar RSA operations. The reason for this is compatibility with legacy
+ * clients.)
+ *
+ * -- AES keys --
+ *
+ * AES GCM mode supports "associated authentication data," provided via the Tag::ASSOCIATED_DATA
+ * tag in the inParams argument. The associated data may be provided in repeated calls
+ * (important if the data is too large to send in a single block) but must always precede data
+ * to be encrypted or decrypted. An update call may receive both associated data and data to
+ * encrypt/decrypt, but subsequent updates must not include associated data. If the caller
+ * provides associated data to an update call after a call that includes data to
+ * encrypt/decrypt, update() must return ErrorCode::INVALID_TAG.
+ *
+ * For GCM encryption, the AEAD tag must be appended to the ciphertext by finish(). During
+ * decryption, the last Tag::MAC_LENGTH bytes of the data provided to the last update call must
+ * be the AEAD tag. Since a given invocation of update cannot know if it's the last invocation,
+ * it must process all but the tag length and buffer the possible tag data for processing during
+ * finish().
*
* @param operationHandle The operation handle returned by begin().
*
@@ -513,16 +1177,18 @@
* @param authToken Authentication token. Callers that provide no token must set all numeric
* fields to zero and the MAC must be an empty vector.
*
- * @param verificationToken Verification token, used to prove that another Keymaster HAL has
- * verified some parameters, and to deliver the other HAL's current timestamp, if needed.
- * If not provided, all fields must be initialized to zero and vectors empty.
+ * @param verificationToken Verification token, used to prove that another IKeymasterDevice HAL
+ * has verified some parameters, and to deliver the other HAL's current timestamp, if
+ * needed. If not provided, all fields must be initialized to zero and vectors must be
+ * empty.
*
* @return error See the ErrorCode enum in types.hal.
*
* @return inputConsumed Amount of data that was consumed by update(). If this is less than the
* amount provided, the caller may provide the remainder in a subsequent call to
- * update() or finish(). Every call to update must consume at least one byte, and
- * implementations should consume as much data as reasonably possible for each call.
+ * update() or finish(). Every call to update must consume at least one byte, unless
+ * the input is empty, and implementations should consume as much data as reasonably
+ * possible for each call.
*
* @return outParams Output parameters, used to return additional data from the operation.
*
@@ -536,6 +1202,86 @@
/**
* Finalizes a cryptographic operation begun with begin() and invalidates operationHandle.
*
+ * This method is the last one called in an operation, so all processed data must be returned.
+ *
+ * Whether it completes successfully or returns an error, this method finalizes the operation
+ * and therefore must invalidate the provided operation handle. Any future use of the handle,
+ * with finish(), update(), or abort(), must return ErrorCode::INVALID_OPERATION_HANDLE.
+ *
+ * Signing operations return the signature as the output. Verification operations accept the
+ * signature in the signature parameter, and return no output.
+ *
+ * == Authorization enforcement ==
+ *
+ * Key authorization enforcement is performed primarily in begin(). The exceptions are
+ * authorization per operation keys and confirmation-required keys.
+ *
+ * Authorization per operation keys are the case where the key has one or more
+ * Tag::USER_SECURE_IDs, and does not have a Tag::AUTH_TIMEOUT. In this case, the key requires
+ * an authorization per operation, and the finish method must receive a non-empty and valid
+ * authToken. For the auth token to be valid, all of the following has to be true:
+ *
+ * o The HMAC field must validate correctly.
+ *
+ * o At least one of the Tag::USER_SECURE_ID values from the key must match at least one of
+ * the secure ID values in the token.
+ *
+ * o The key must have a Tag::USER_AUTH_TYPE that matches the auth type in the token.
+ *
+ * o The challenge field in the auth token must contain the operationHandle
+ *
+ * If any of these conditions are not met, update() must return
+ * ErrorCode::KEY_USER_NOT_AUTHENTICATED.
+ *
+ * The caller must provide the auth token on every call to update() and finish().
+ *
+ * Confirmation-required keys are keys that were generated with
+ * Tag::TRUSTED_CONFIRMATION_REQUIRED. For these keys, when doing a signing operation the
+ * caller must pass a KeyParameter Tag::CONFIRMATION_TOKEN to finish(). Implementations must
+ * check the confirmation token by computing the 32-byte HMAC-SHA256 over all of the
+ * to-be-signed data, prefixed with the 18-byte UTF-8 encoded string "confirmation token". If
+ * the computed value does not match the Tag::CONFIRMATION_TOKEN parameter, finish() must not
+ * produce a signature and must return ErrorCode::NO_USER_CONFIRMATION.
+ *
+ * -- RSA keys --
+ *
+ * Some additional requirements, depending on the padding mode:
+ *
+ * o PaddingMode::NONE. For unpadded signing and encryption operations, if the provided data is
+ * shorter than the key, the data must be zero-padded on the left before
+ * signing/encryption. If the data is the same length as the key, but numerically larger,
+ * finish() must return ErrorCode::INVALID_ARGUMENT. For verification and decryption
+ * operations, the data must be exactly as long as the key. Otherwise, return
+ * ErrorCode::INVALID_INPUT_LENGTH.
+ *
+ * o PaddingMode::RSA_PSS. For PSS-padded signature operations, the PSS salt length must match
+ * the size of the PSS digest selected. The digest specified with Tag::DIGEST in inputParams
+ * on begin() must be used as the PSS digest algorithm, MGF1 must be used as the mask
+ * generation function and SHA1 must be used as the MGF1 digest algorithm.
+ *
+ * o PaddingMode::RSA_OAEP. The digest specified with Tag::DIGEST in inputParams on begin is
+ * used as the OAEP digest algorithm, MGF1 must be used as the mask generation function and
+ * and SHA1 must be used as the MGF1 digest algorithm.
+ *
+ * -- ECDSA keys --
+ *
+ * If the data provided for unpadded signing or verification is too long, truncate it.
+ *
+ * -- AES keys --
+ *
+ * Some additional conditions, depending on block mode:
+ *
+ * o BlockMode::ECB or BlockMode::CBC. If padding is PaddingMode::NONE and the data length is
+ * not a multiple of the AES block size, finish() must return
+ * ErrorCode::INVALID_INPUT_LENGTH. If padding is PaddingMode::PKCS7, pad the data per the
+ * PKCS#7 specification, including adding an additional padding block if the data is a multiple
+ * of the block length.
+ *
+ * o BlockMode::GCM. During encryption, after processing all plaintext, compute the tag
+ * (Tag::MAC_LENGTH bytes) and append it to the returned ciphertext. During decryption,
+ * process the last Tag::MAC_LENGTH bytes as the tag. If tag verification fails, finish()
+ * must return ErrorCode::VERIFICATION_FAILED.
+ *
* @param operationHandle The operation handle returned by begin(). This handle must be invalid
* when finish() returns.
*
@@ -551,11 +1297,9 @@
* @param authToken Authentication token. Callers that provide no token must set all numeric
* fields to zero and the MAC must be an empty vector.
*
- * @param verificationToken Verification token, used to prove that another Keymaster HAL has
- * verified some parameters, and to deliver the other HAL's current timestamp, if needed.
- * If not provided, all fields must be initialized to zero and vectors empty.
- *
- * @return error See the ErrorCode enum in types.hal.
+ * @param verificationToken Verification token, used to prove that another IKeymasterDevice HAL
+ * has verified some parameters, and to deliver the other HAL's current timestamp, if
+ * needed. If not provided, all fields must be initialized to zero and vectors empty.
*
* @return outParams Any output parameters generated by finish().
*
diff --git a/keymaster/4.0/default/service.cpp b/keymaster/4.0/default/service.cpp
index cfb960a..fdcc6ba 100644
--- a/keymaster/4.0/default/service.cpp
+++ b/keymaster/4.0/default/service.cpp
@@ -24,6 +24,7 @@
using android::hardware::keymaster::V4_0::SecurityLevel;
int main() {
+ ::android::hardware::configureRpcThreadpool(1, true /* willJoinThreadpool */);
auto keymaster = ::keymaster::V4_0::ng::CreateKeymasterDevice(SecurityLevel::SOFTWARE);
auto status = keymaster->registerAsService();
if (status != android::OK) {
diff --git a/keymaster/4.0/support/Keymaster.cpp b/keymaster/4.0/support/Keymaster.cpp
index 066bca4..444298b 100644
--- a/keymaster/4.0/support/Keymaster.cpp
+++ b/keymaster/4.0/support/Keymaster.cpp
@@ -156,17 +156,19 @@
for (auto& keymaster : keymasters) {
if (keymaster->halVersion().majorVersion < 4) continue;
LOG(DEBUG) << "Computing HMAC for " << *keymaster;
- auto rc = keymaster->computeSharedHmac(params, [&](auto error, auto& curSharingCheck) {
- CHECK(error == ErrorCode::OK)
- << "Failed to get HMAC parameters from " << *keymaster << " error " << error;
- if (firstKeymaster) {
- sharingCheck = curSharingCheck;
- firstKeymaster = false;
- }
- // TODO: Validate that curSharingCheck == sharingCheck. b/77588764
- // CHECK(curSharingCheck == sharingCheck) << "HMAC computation failed for " <<
- // *keymaster;
- });
+ auto rc = keymaster->computeSharedHmac(
+ params, [&](ErrorCode error, const hidl_vec<uint8_t>& curSharingCheck) {
+ CHECK(error == ErrorCode::OK)
+ << "Failed to get HMAC parameters from " << *keymaster << " error " << error;
+ if (firstKeymaster) {
+ sharingCheck = curSharingCheck;
+ firstKeymaster = false;
+ }
+ CHECK(curSharingCheck == sharingCheck)
+ << "HMAC computation failed for " << *keymaster //
+ << " Expected: " << sharingCheck //
+ << " got: " << curSharingCheck;
+ });
CHECK(rc.isOk()) << "Failed to communicate with " << *keymaster
<< " error: " << rc.description();
}
diff --git a/keymaster/4.0/types.hal b/keymaster/4.0/types.hal
index 47fd1ed..85f181a 100644
--- a/keymaster/4.0/types.hal
+++ b/keymaster/4.0/types.hal
@@ -59,83 +59,364 @@
enum Tag : uint32_t {
INVALID = TagType:INVALID | 0,
- /*
- * Tags that must be semantically enforced by hardware and software implementations.
+ /**
+ * Tag::PURPOSE specifies the set of purposes for which the key may be used. Possible values
+ * are defined in the KeyPurpose enumeration.
+ *
+ * This tag is repeatable; keys may be generated with multiple values, although an operation has
+ * a single purpose. When begin() is called to start an operation, the purpose of the operation
+ * is specified. If the purpose specified for the operation is not authorized by the key (the
+ * key didn't have a corresponding Tag::PURPOSE provided during generation/import), the
+ * operation must fail with ErrorCode::INCOMPATIBLE_PURPOSE.
+ *
+ * Must be hardware-enforced.
*/
+ PURPOSE = TagType:ENUM_REP | 1,
- /* Crypto parameters */
- PURPOSE = TagType:ENUM_REP | 1, /* KeyPurpose. */
- ALGORITHM = TagType:ENUM | 2, /* Algorithm. */
- KEY_SIZE = TagType:UINT | 3, /* Key size in bits. */
+ /**
+ * Tag::ALGORITHM specifies the cryptographic algorithm with which the key is used. This tag
+ * must be provided to generateKey and importKey, and must be specified in the wrapped key
+ * provided to importWrappedKey.
+ *
+ * Must be hardware-enforced.
+ */
+ ALGORITHM = TagType:ENUM | 2,
+
+ /**
+ * Tag::KEY_SIZE pecifies the size, in bits, of the key, measuring in the normal way for the
+ * key's algorithm. For example, for RSA keys, Tag::KEY_SIZE specifies the size of the public
+ * modulus. For AES keys it specifies the length of the secret key material. For 3DES keys it
+ * specifies the length of the key material, not counting parity bits (though parity bits must
+ * be provided for import, etc.). Since only three-key 3DES keys are supported, 3DES
+ * Tag::KEY_SIZE must be 168.
+ *
+ * Must be hardware-enforced.
+ */
+ KEY_SIZE = TagType:UINT | 3,
+
+ /**
+ * Tag::BLOCK_MODE specifies the block cipher mode(s) with which the key may be used. This tag
+ * is only relevant to AES and 3DES keys. Possible values are defined by the BlockMode enum.
+ *
+ * This tag is repeatable for key generation/import. For AES and 3DES operations the caller
+ * must specify a Tag::BLOCK_MODE in the additionalParams argument of begin(). If the mode is
+ * missing or the specified mode is not in the modes specified for the key during
+ * generation/import, the operation must fail with ErrorCode::INCOMPATIBLE_BLOCK_MODE.
+ *
+ * Must be hardware-enforced.
+ */
BLOCK_MODE = TagType:ENUM_REP | 4, /* BlockMode. */
- DIGEST = TagType:ENUM_REP | 5, /* Digest. */
- PADDING = TagType:ENUM_REP | 6, /* PaddingMode. */
- CALLER_NONCE = TagType:BOOL | 7, /* Allow caller to specify nonce or IV. */
- MIN_MAC_LENGTH = TagType:UINT | 8, /* Minimum length of MAC or AEAD authentication tag in
- * bits. */
- // 9 reserved
- EC_CURVE = TagType:ENUM | 10, /* EcCurve. */
- /* Algorithm-specific. */
+ /**
+ * Tag::DIGEST specifies the digest algorithms that may be used with the key to perform signing
+ * and verification operations. This tag is relevant to RSA, ECDSA and HMAC keys. Possible
+ * values are defined by the Digest enum.
+ *
+ * This tag is repeatable for key generation/import. For signing and verification operations,
+ * the caller must specify a digest in the additionalParams argument of begin(). If the digest
+ * is missing or the specified digest is not in the digests associated with the key, the
+ * operation must fail with ErrorCode::INCOMPATIBLE_DIGEST.
+ *
+ * Must be hardware-enforced.
+ */
+ DIGEST = TagType:ENUM_REP | 5,
+
+ /**
+ * Tag::PADDING specifies the padding modes that may be used with the key. This tag is relevant
+ * to RSA, AES and 3DES keys. Possible values are defined by the PaddingMode enum.
+ *
+ * PaddingMode::RSA_OAEP and PaddingMode::RSA_PKCS1_1_5_ENCRYPT are used only for RSA
+ * encryption/decryption keys and specify RSA OAEP padding and RSA PKCS#1 v1.5 randomized
+ * padding, respectively. PaddingMode::RSA_PSS and PaddingMode::RSA_PKCS1_1_5_SIGN are used
+ * only for RSA signing/verification keys and specify RSA PSS padding and RSA PKCS#1 v1.5
+ * deterministic padding, respectively.
+ *
+ * PaddingMode::NONE may be used with either RSA, AES or 3DES keys. For AES or 3DES keys, if
+ * PaddingMode::NONE is used with block mode ECB or CBC and the data to be encrypted or
+ * decrypted is not a multiple of the AES block size in length, the call to finish() must fail
+ * with ErrorCode::INVALID_INPUT_LENGTH.
+ *
+ * PaddingMode::PKCS7 may only be used with AES and 3DES keys, and only with ECB and CBC modes.
+ *
+ * In any case, if the caller specifies a padding mode that is not usable with the key's
+ * algorithm, the generation or import method must return ErrorCode::INCOMPATIBLE_PADDING_MODE.
+ *
+ * This tag is repeatable. A padding mode must be specified in the call to begin(). If the
+ * specified mode is not authorized for the key, the operation must fail with
+ * ErrorCode::INCOMPATIBLE_BLOCK_MODE.
+ *
+ * Must be hardware-enforced.
+ */
+ PADDING = TagType:ENUM_REP | 6,
+
+ /**
+ * Tag::CALLER_NONCE specifies that the caller can provide a nonce for nonce-requiring
+ * operations. This tag is boolean, so the possible values are true (if the tag is present) and
+ * false (if the tag is not present).
+ *
+ * This tag is used only for AES and 3DES keys, and is only relevant for CBC, CTR and GCM block
+ * modes. If the tag is not present in a key's authorization list, implementations must reject
+ * any operation that provides Tag::NONCE to begin() with ErrorCode::CALLER_NONCE_PROHIBITED.
+ *
+ * Must be hardware-enforced.
+ */
+ CALLER_NONCE = TagType:BOOL | 7,
+
+ /**
+ * Tag::MIN_MAC_LENGTH specifies the minimum length of MAC that can be requested or verified
+ * with this key for HMAC keys and AES keys that support GCM mode.
+ *
+ * This value is the minimum MAC length, in bits. It must be a multiple of 8 bits. For HMAC
+ * keys, the value must be least 64 and no more than 512. For GCM keys, the value must be at
+ * least 96 and no more than 128. If the provided value violates these requirements,
+ * generateKey() or importKey() must return ErrorCode::UNSUPPORTED_KEY_SIZE.
+ *
+ * Must be hardware-enforced.
+ */
+ MIN_MAC_LENGTH = TagType:UINT | 8,
+
+ // Tag 9 reserved
+
+ /**
+ * Tag::EC_CURVE specifies the elliptic curve. EC key generation requests may have
+ * Tag:EC_CURVE, Tag::KEY_SIZE, or both. If both are provided and the size and curve do not
+ * match, IKeymasterDevice must return ErrorCode::INVALID_ARGUMENT.
+ *
+ * Must be hardware-enforced.
+ */
+ EC_CURVE = TagType:ENUM | 10,
+
+ /**
+ * Tag::RSA_PUBLIC_EXPONENT specifies the value of the public exponent for an RSA key pair.
+ * This tag is relevant only to RSA keys, and is required for all RSA keys.
+ *
+ * The value is a 64-bit unsigned integer that satisfies the requirements of an RSA public
+ * exponent. This value must be a prime number. IKeymasterDevice implementations must support
+ * the value 2^16+1 and may support other reasonable values. If no exponent is specified or if
+ * the specified exponent is not supported, key generation must fail with
+ * ErrorCode::INVALID_ARGUMENT.
+ *
+ * Must be hardware-enforced.
+ */
RSA_PUBLIC_EXPONENT = TagType:ULONG | 200,
- // 201 reserved for ECIES
- INCLUDE_UNIQUE_ID = TagType:BOOL | 202, /* If true, attestation certificates for this key must
- * contain an application-scoped and time-bounded
- * device-unique ID.*/
- /* Other hardware-enforced. */
- BLOB_USAGE_REQUIREMENTS = TagType:ENUM | 301, /* KeyBlobUsageRequirements. */
- BOOTLOADER_ONLY = TagType:BOOL | 302, /* Usable only by bootloader. */
- ROLLBACK_RESISTANCE = TagType:BOOL | 303, /* Whether key is rollback-resistant. Specified
- * in the key description provided to generateKey
- * or importKey if rollback resistance is desired.
- * If the implementation cannot provide rollback
- * resistance, it must return
- * ROLLBACK_RESISTANCE_UNAVAILABLE. */
+ // Tag 201 reserved
- /* HARDWARE_TYPE specifies the type of the secure hardware that is requested for the key
- * generation / import. See the SecurityLevel enum. In the absence of this tag, keystore must
- * use TRUSTED_ENVIRONMENT. If this tag is present and the requested hardware type is not
- * available, Keymaster returns HARDWARE_TYPE_UNAVAILABLE. This tag is not included in
- * attestations, but hardware type must be reflected in the Keymaster SecurityLevel of the
- * attestation header. */
+ /**
+ * Tag::INCLUDE_UNIQUE_ID is specified during key generation to indicate that an attestation
+ * certificate for the generated key should contain an application-scoped and time-bounded
+ * device-unique ID. See Tag::UNIQUE_ID.
+ *
+ * Must be hardware-enforced.
+ */
+ INCLUDE_UNIQUE_ID = TagType:BOOL | 202,
+
+ /**
+ * Tag::BLOB_USAGE_REQUIREMENTS specifies the necessary system environment conditions for the
+ * generated key to be used. Possible values are defined by the KeyBlobUsageRequirements enum.
+ *
+ * This tag is specified by the caller during key generation or import to require that the key
+ * is usable in the specified condition. If the caller specifies Tag::BLOB_USAGE_REQUIREMENTS
+ * with value KeyBlobUsageRequirements::STANDALONE the IKeymasterDevice must return a key blob
+ * that can be used without file system support. This is critical for devices with encrypted
+ * disks, where the file system may not be available until after a Keymaster key is used to
+ * decrypt the disk.
+ *
+ * Must be hardware-enforced.
+ */
+ BLOB_USAGE_REQUIREMENTS = TagType:ENUM | 301,
+
+ /**
+ * Tag::BOOTLOADER_ONLY specifies only the bootloader can use the key.
+ *
+ * Any attempt to use a key with Tag::BOOTLOADER_ONLY from the Android system must fail with
+ * ErrorCode::INVALID_KEY_BLOB.
+ *
+ * Must be hardware-enforced.
+ */
+ BOOTLOADER_ONLY = TagType:BOOL | 302,
+
+ /**
+ * Tag::ROLLBACK_RESISTANCE specifies that the key has rollback resistance, meaning that when
+ * deleted with deleteKey() or deleteAllKeys(), the key is guaranteed to be permanently deleted
+ * and unusable. It's possible that keys without this tag could be deleted and then restored
+ * from backup.
+ *
+ * This tag is specified by the caller during key generation or import to require. If the
+ * IKeymasterDevice cannot guarantee rollback resistance for the specified key, it must return
+ * ErrorCode::ROLLBACK_RESISTANCE_UNAVAILABLE. IKeymasterDevice implementations are not
+ * required to support rollback resistance.
+ *
+ * Must be hardwared-enforced.
+ */
+ ROLLBACK_RESISTANCE = TagType:BOOL | 303,
+
+ // Reserved for future use.
HARDWARE_TYPE = TagType:ENUM | 304,
- /*
- * Tags that should be semantically enforced by hardware if possible and will otherwise be
- * enforced by software (keystore).
+ /**
+ * Tag::ACTIVE_DATETIME specifies the date and time at which the key becomes active, in
+ * milliseconds since Jan 1, 1970. If a key with this tag is used prior to the specified date
+ * and time, IKeymasterDevice::begin() must return ErrorCode::KEY_NOT_YET_VALID;
+ *
+ * Need not be hardware-enforced.
*/
+ ACTIVE_DATETIME = TagType:DATE | 400, /* Start of validity. */
- /* Key validity period */
- ACTIVE_DATETIME = TagType:DATE | 400, /* Start of validity. */
- ORIGINATION_EXPIRE_DATETIME = TagType:DATE | 401, /* Date when new "messages" should no longer
- * be created. */
- USAGE_EXPIRE_DATETIME = TagType:DATE | 402, /* Date when existing "messages" should no
- * longer be trusted. */
- MIN_SECONDS_BETWEEN_OPS = TagType:UINT | 403, /* Minimum elapsed time between
- * cryptographic operations with the key. */
- MAX_USES_PER_BOOT = TagType:UINT | 404, /* Number of times the key can be used per
- * boot. */
+ /**
+ * Tag::ORIGINATION_EXPIRE_DATETIME specifies the date and time at which the key expires for
+ * signing and encryption purposes. After this time, any attempt to use a key with
+ * KeyPurpose::SIGN or KeyPurpose::ENCRYPT provided to begin() must fail with
+ * ErrorCode::KEY_EXPIRED.
+ *
+ * The value is a 64-bit integer representing milliseconds since January 1, 1970.
+ *
+ * Need not be hardware-enforced.
+ */
+ ORIGINATION_EXPIRE_DATETIME = TagType:DATE | 401,
- /* User authentication */
- // 500 reserved
- USER_ID = TagType:UINT | 501, /* Android ID of authorized user or authenticator(s), */
+ /**
+ * Tag::USAGE_EXPIRE_DATETIME specifies the date and time at which the key expires for
+ * verification and decryption purposes. After this time, any attempt to use a key with
+ * KeyPurpose::VERIFY or KeyPurpose::DECRYPT provided to begin() must fail with
+ * ErrorCode::KEY_EXPIRED.
+ *
+ * The value is a 64-bit integer representing milliseconds since January 1, 1970.
+ *
+ * Need not be hardware-enforced.
+ */
+ USAGE_EXPIRE_DATETIME = TagType:DATE | 402,
+
+ /**
+ * Tag::MIN_SECONDS_BETWEEN_OPS specifies the minimum amount of time that elapses between
+ * allowed operations using a key. This can be used to rate-limit uses of keys in contexts
+ * where unlimited use may enable brute force attacks.
+ *
+ * The value is a 32-bit integer representing seconds between allowed operations.
+ *
+ * When a key with this tag is used in an operation, the IKeymasterDevice must start a timer
+ * during the finish() or abort() call. Any call to begin() that is received before the timer
+ * indicates that the interval specified by Tag::MIN_SECONDS_BETWEEN_OPS has elapsed must fail
+ * with ErrorCode::KEY_RATE_LIMIT_EXCEEDED. This implies that the IKeymasterDevice must keep a
+ * table of use counters for keys with this tag. Because memory is often limited, this table
+ * may have a fixed maximum size and Keymaster may fail operations that attempt to use keys with
+ * this tag when the table is full. The table must acommodate at least 8 in-use keys and
+ * aggressively reuse table slots when key minimum-usage intervals expire. If an operation
+ * fails because the table is full, Keymaster returns ErrorCode::TOO_MANY_OPERATIONS.
+ *
+ * Must be hardware-enforced.
+ */
+ MIN_SECONDS_BETWEEN_OPS = TagType:UINT | 403,
+
+ /**
+ * Tag::MAX_USES_PER_BOOT specifies the maximum number of times that a key may be used between
+ * system reboots. This is another mechanism to rate-limit key use.
+ *
+ * The value is a 32-bit integer representing uses per boot.
+ *
+ * When a key with this tag is used in an operation, a key-associated counter must be
+ * incremented during the begin() call. After the key counter has exceeded this value, all
+ * subsequent attempts to use the key must fail with ErrorCode::MAX_OPS_EXCEEDED, until the
+ * device is restarted. This implies that the IKeymasterDevice must keep a table of use
+ * counters for keys with this tag. Because Keymaster memory is often limited, this table can
+ * have a fixed maximum size and Keymaster can fail operations that attempt to use keys with
+ * this tag when the table is full. The table needs to acommodate at least 8 keys. If an
+ * operation fails because the table is full, IKeymasterDevice must
+ * ErrorCode::TOO_MANY_OPERATIONS.
+ *
+ * Must be hardware-enforced.
+ */
+ MAX_USES_PER_BOOT = TagType:UINT | 404,
+
+ /**
+ * Tag::USER_ID specifies the ID of the Android user that is permitted to use the key.
+ *
+ * Must not be hardware-enforced.
+ */
+ USER_ID = TagType:UINT | 501,
+
+ /**
+ * Tag::USER_SECURE_ID specifies that a key may only be used under a particular secure user
+ * authentication state. This tag is mutually exclusive with Tag::NO_AUTH_REQUIRED.
+ *
+ * The value is a 64-bit integer specifying the authentication policy state value which must be
+ * present in the userId or authenticatorId field of a HardwareAuthToken provided to begin(),
+ * update(), or finish(). If a key with Tag::USER_SECURE_ID is used without a HardwareAuthToken
+ * with the matching userId or authenticatorId, the IKeymasterDevice must return
+ * ErrorCode::KEY_USER_NOT_AUTHENTICATED.
+ *
+ * Tag::USER_SECURE_ID interacts with Tag::AUTH_TIMEOUT in a very important way. If
+ * Tag::AUTH_TIMEOUT is present in the key's characteristics then the key is a "timeout-based"
+ * key, and may only be used if the difference between the current time when begin() is called
+ * and the timestamp in the HardwareAuthToken is less than the value in Tag::AUTH_TIMEOUT * 1000
+ * (the multiplier is because Tag::AUTH_TIMEOUT is in seconds, but the HardwareAuthToken
+ * timestamp is in milliseconds). Otherwise the IKeymasterDevice must returrn
+ * ErrorCode::KEY_USER_NOT_AUTHENTICATED.
+ *
+ * If Tag::AUTH_TIMEOUT is not present, then the key is an "auth-per-operation" key. In this
+ * case, begin() must not require a HardwareAuthToken with appropriate contents. Instead,
+ * update() and finish() must receive a HardwareAuthToken with Tag::USER_SECURE_ID value in
+ * userId or authenticatorId fields, and the current operation's operation handle in the
+ * challenge field. Otherwise the IKeymasterDevice must returrn
+ * ErrorCode::KEY_USER_NOT_AUTHENTICATED.
+ *
+ * This tag is repeatable. If repeated, and any one of the values matches the HardwareAuthToken
+ * as described above, the key is authorized for use. Otherwise the operation must fail with
+ * ErrorCode::KEY_USER_NOT_AUTHENTICATED.
+ *
+ * Must be hardware-enforced.
+ */
USER_SECURE_ID = TagType:ULONG_REP | 502, /* Secure ID of authorized user or authenticator(s).
- * Disallowed if NO_AUTH_REQUIRED is present. */
- NO_AUTH_REQUIRED = TagType:BOOL | 503, /* If key is usable without authentication. */
- USER_AUTH_TYPE = TagType:ENUM | 504, /* Bitmask of authenticator types allowed when
- * USER_SECURE_ID contains a secure user ID, rather
- * than a secure authenticator ID. Defined in
- * HardwareAuthenticatorType. */
- AUTH_TIMEOUT = TagType:UINT | 505, /* Required freshness of user authentication for
- * private/secret key operations, in seconds. Public
- * key operations require no authentication. If
- * absent, authentication is required for every use.
- * Authentication state is lost when the device is
- * powered off. */
- ALLOW_WHILE_ON_BODY = TagType:BOOL | 506, /* Allow key to be used after authentication timeout
- * if device is still on-body (requires secure
- * on-body sensor. */
+ * Disallowed if NO_AUTH_REQUIRED is present. */
+
+ /**
+ * Tag::NO_AUTH_REQUIRED specifies that no authentication is required to use this key. This tag
+ * is mutually exclusive with Tag::USER_SECURE_ID.
+ *
+ * Must be hardware-enforced.
+ */
+ NO_AUTH_REQUIRED = TagType:BOOL | 503, /* If key is usable without authentication. */
+
+ /**
+ * Tag::USER_AUTH_TYPE specifies the types of user authenticators that may be used to authorize
+ * this key.
+ *
+ * The value is one or more values from HardwareAuthenticatorType, ORed together.
+ *
+ * When IKeymasterDevice is requested to perform an operation with a key with this tag, it must
+ * receive a HardwareAuthToken and one or more bits must be set in both the HardwareAuthToken's
+ * authenticatorType field and the Tag::USER_AUTH_TYPE value. That is, it must be true that
+ *
+ * (token.authenticatorType & tag_user_auth_type) != 0
+ *
+ * where token.authenticatorType is the authenticatorType field of the HardwareAuthToken and
+ * tag_user_auth_type is the value of Tag:USER_AUTH_TYPE.
+ *
+ * Must be hardware-enforced.
+ */
+ USER_AUTH_TYPE = TagType:ENUM | 504,
+
+ /**
+ * Tag::AUTH_TIMEOUT specifies the time in seconds for which the key is authorized for use,
+ * after user authentication. If
+ * Tag::USER_SECURE_ID is present and this tag is not, then the key requies authentication for
+ * every usage (see begin() for the details of the authentication-per-operation flow).
+ *
+ * The value is a 32-bit integer specifying the time in seconds after a successful
+ * authentication of the user specified by Tag::USER_SECURE_ID with the authentication method
+ * specified by Tag::USER_AUTH_TYPE that the key can be used.
+ *
+ * Must be hardware-enforced.
+ */
+ AUTH_TIMEOUT = TagType:UINT | 505,
+
+ /**
+ * Tag::ALLOW_WHILE_ON_BODY specifies that the key may be used after authentication timeout if
+ * device is still on-body (requires on-body sensor).
+ *
+ * Cannot be hardware-enforced.
+ */
+ ALLOW_WHILE_ON_BODY = TagType:BOOL | 506,
/**
* TRUSTED_USER_PRESENCE_REQUIRED is an optional feature that specifies that this key must be
@@ -166,7 +447,7 @@
* the non-secure world, which means an attacker who has compromised Android can spoof
* password authentication.
*
- * Note that no mechanism is defined for delivering proof of presence to Keymaster,
+ * Note that no mechanism is defined for delivering proof of presence to an IKeymasterDevice,
* except perhaps as implied by an auth token. This means that Keymaster must be able to check
* proof of presence some other way. Further, the proof of presence must be performed between
* begin() and the first call to update() or finish(). If the first update() or the finish()
@@ -182,108 +463,408 @@
*/
TRUSTED_USER_PRESENCE_REQUIRED = TagType:BOOL | 507,
- /** TRUSTED_CONFIRMATION_REQUIRED is only applicable to keys with KeyPurpose SIGN, and specifies
- * that this key must not be usable unless the user provides confirmation of the data to be
- * signed. Confirmation is proven to keymaster via an approval token. See CONFIRMATION_TOKEN,
- * as well as the ConfirmatinUI HAL.
+ /** Tag::TRUSTED_CONFIRMATION_REQUIRED is only applicable to keys with KeyPurpose SIGN, and
+ * specifies that this key must not be usable unless the user provides confirmation of the data
+ * to be signed. Confirmation is proven to keymaster via an approval token. See
+ * CONFIRMATION_TOKEN, as well as the ConfirmatinUI HAL.
*
* If an attempt to use a key with this tag does not have a cryptographically valid
* CONFIRMATION_TOKEN provided to finish() or if the data provided to update()/finish() does not
* match the data described in the token, keymaster must return NO_USER_CONFIRMATION. */
TRUSTED_CONFIRMATION_REQUIRED = TagType:BOOL | 508,
- UNLOCKED_DEVICE_REQUIRED = TagType:BOOL | 509, /* Require the device screen to be unlocked if
- * the key is used. */
+ /**
+ *
+ */
+ UNLOCKED_DEVICE_REQUIRED = TagType:BOOL | 509,
- /* Application access control */
- APPLICATION_ID = TagType:BYTES | 601, /* Byte string identifying the authorized application. */
+ /**
+ * Tag::APPLICATION_ID. When provided to generateKey or importKey, this tag specifies data
+ * that is necessary during all uses of the key. In particular, calls to exportKey() and
+ * getKeyCharacteristics() must provide the same value to the clientId parameter, and calls to
+ * begin must provide this tag and the same associated data as part of the inParams set. If
+ * the correct data is not provided, the method must return ErrorCode::INVALID_KEY_BLOB.
+ *
+ * The content of this tag must be bound to the key cryptographically, meaning it must not be
+ * possible for an adversary who has access to all of the secure world secrets but does not have
+ * access to the tag content to decrypt the key without brute-forcing the tag content, which
+ * applications can prevent by specifying sufficiently high-entropy content.
+ *
+ * Must be hardware-enforced.
+ */
+ APPLICATION_ID = TagType:BYTES | 601,
/*
* Semantically unenforceable tags, either because they have no specific meaning or because
* they're informational only.
*/
- APPLICATION_DATA = TagType:BYTES | 700, /* Data provided by authorized application. */
- CREATION_DATETIME = TagType:DATE | 701, /* Key creation time */
- ORIGIN = TagType:ENUM | 702, /* keymaster_key_origin_t. */
- // 703 is unused.
- ROOT_OF_TRUST = TagType:BYTES | 704, /* Root of trust ID. */
- OS_VERSION = TagType:UINT | 705, /* Version of system (keymaster2) */
- OS_PATCHLEVEL = TagType:UINT | 706, /* Patch level of system (keymaster2) */
- UNIQUE_ID = TagType:BYTES | 707, /* Used to provide unique ID in attestation */
- ATTESTATION_CHALLENGE = TagType:BYTES | 708, /* Used to provide challenge in attestation */
- ATTESTATION_APPLICATION_ID = TagType:BYTES | 709, /* Used to identify the set of possible
- * applications of which one has initiated a
- * key attestation */
- ATTESTATION_ID_BRAND = TagType:BYTES | 710, /* Used to provide the device's brand name to be
- * included in attestation */
- ATTESTATION_ID_DEVICE = TagType:BYTES | 711, /* Used to provide the device's device name to
- * be included in attestation */
- ATTESTATION_ID_PRODUCT = TagType:BYTES | 712, /* Used to provide the device's product name to
- * be included in attestation */
- ATTESTATION_ID_SERIAL =
- TagType:BYTES | 713, /* Used to provide the device's serial number to be
- * included in attestation */
- ATTESTATION_ID_IMEI = TagType:BYTES | 714, /* Used to provide the device's IMEI to be included
- * in attestation */
- ATTESTATION_ID_MEID = TagType:BYTES | 715, /* Used to provide the device's MEID to be included
- * in attestation */
- ATTESTATION_ID_MANUFACTURER =
- TagType:BYTES | 716, /* Used to provide the device's manufacturer
- * name to be included in attestation */
- ATTESTATION_ID_MODEL = TagType:BYTES | 717, /* Used to provide the device's model name to be
- * included in attestation */
/**
- * Patch level of vendor image. The value is an integer of the form YYYYMM, where YYYY is the
- * four-digit year when the vendor image was released and MM is the two-digit month. During
- * each boot, the bootloader must provide the patch level of the vendor image to keymaser
- * (mechanism is implemntation-defined). When keymaster keys are created or updated, the
- * VENDOR_PATCHLEVEL tag must be cryptographically bound to the keys, with the current value as
- * provided by the bootloader. When keys are used, keymaster must verify that the
- * VENDOR_PATCHLEVEL bound to the key matches the current value. If they do not match,
- * keymaster must return ErrorCode::KEY_REQUIRES_UPGRADE. The client must then call upgradeKey.
+ * Tag::APPLICATION_DATA. When provided to generateKey or importKey, this tag specifies data
+ * that is necessary during all uses of the key. In particular, calls to exportKey() and
+ * getKeyCharacteristics() must provide the same value to the appData parameter, and calls to
+ * begin must provide this tag and the same associated data as part of the inParams set. If
+ * the correct data is not provided, the method must return ErrorCode::INVALID_KEY_BLOB.
+ *
+ * The content of this tag msut be bound to the key cryptographically, meaning it must not be
+ * possible for an adversary who has access to all of the secure world secrets but does not have
+ * access to the tag content to decrypt the key without brute-forcing the tag content, which
+ * applications can prevent by specifying sufficiently high-entropy content.
+ *
+ * Must be hardware-enforced.
+ */
+ APPLICATION_DATA = TagType:BYTES | 700,
+
+ /**
+ * Tag::CREATION_DATETIME specifies the date and time the key was created, in milliseconds since
+ * January 1, 1970. This tag is optional and informational only.
+ *
+ * Tag::CREATED is informational only, and not enforced by anything. Must be in the
+ * software-enforced list, if provided.
+ */
+ CREATION_DATETIME = TagType:DATE | 701,
+
+ /**
+ * Tag::ORIGIN specifies where the key was created, if known. This tag must not be specified
+ * during key generation or import, and must be added to the key characteristics by the
+ * IKeymasterDevice. The possible values are defined in the KeyOrigin enum.
+ *
+ * Must be hardware-enforced.
+ */
+ ORIGIN = TagType:ENUM | 702,
+
+ // 703 is unused.
+
+ /**
+ * Tag::ROOT_OF_TRUST specifies the root of trust, the key used by verified boot to validate the
+ * operating system booted (if any). This tag is never provided to or returned from Keymaster
+ * in the key characteristics. It exists only to define the tag for use in the attestation
+ * record.
+ *
+ * Must never appear in KeyCharacteristics.
+ */
+ ROOT_OF_TRUST = TagType:BYTES | 704,
+
+ /**
+ * Tag::OS_VERSION specifies the system OS version with which the key may be used. This tag is
+ * never sent to the IKeymasterDevice, but is added to the hardware-enforced authorization list
+ * by the TA. Any attempt to use a key with a Tag::OS_VERSION value different from the
+ * currently-running OS version must cause begin(), getKeyCharacteristics() or exportKey() to
+ * return ErrorCode::KEY_REQUIRES_UPGRADE. See upgradeKey() for details.
+ *
+ * The value of the tag is an integer of the form MMmmss, where MM is the major version number,
+ * mm is the minor version number, and ss is the sub-minor version number. For example, for a
+ * key generated on Android version 4.0.3, the value would be 040003.
+ *
+ * The IKeymasterDevice HAL must read the current OS version from the system property
+ * ro.build.id and deliver it to the secure environment when the HAL is first loaded (mechanism
+ * is implementation-defined). The secure environment must not accept another version until
+ * after the next boot. If the content of ro.build.id has additional version information after
+ * the sub-minor version number, it must not be included in Tag::OS_VERSION. If the content is
+ * non-numeric, the secure environment must use 0 as the system version.
+ *
+ * Must be hardware-enforced.
+ */
+ OS_VERSION = TagType:UINT | 705,
+
+ /**
+ * Tag::OS_PATCHLEVEL specifies the system security patch level with which the key may be used.
+ * This tag is never sent to the keymaster TA, but is added to the hardware-enforced
+ * authorization list by the TA. Any attempt to use a key with a Tag::OS_PATCHLEVEL value
+ * different from the currently-running system patchlevel must cause begin(),
+ * getKeyCharacteristics() or exportKey() to return ErrorCode::KEY_REQUIRES_UPGRADE. See
+ * upgradeKey() for details.
+ *
+ * The value of the tag is an integer of the form YYYYMM, where YYYY is the four-digit year of
+ * the last update and MM is the two-digit month of the last update. For example, for a key
+ * generated on an Android device last updated in December 2015, the value would be 201512.
+ *
+ * The IKeymasterDevice HAL must read the current system patchlevel from the system property
+ * ro.build.version.security_patch and deliver it to the secure environment when the HAL is
+ * first loaded (mechanism is implementation-defined). The secure environment must not accept
+ * another patchlevel until after the next boot.
+ *
+ * Must be hardware-enforced.
+ */
+ OS_PATCHLEVEL = TagType:UINT | 706,
+
+ /**
+ * Tag::UNIQUE_ID specifies a unique, time-based identifier. This tag is never provided to or
+ * returned from Keymaster in the key characteristics. It exists only to define the tag for use
+ * in the attestation record.
+ *
+ * When a key with Tag::INCLUDE_UNIQUE_ID is attested, the unique ID is added to the attestation
+ * record. The value is a 128-bit hash that is unique per device and per calling application,
+ * and changes monthly and on most password resets. It is computed with:
+ *
+ * HMAC_SHA256(T || C || R, HBK)
+ *
+ * Where:
+ *
+ * T is the "temporal counter value", computed by dividing the value of
+ * Tag::CREATION_DATETIME by 2592000000, dropping any remainder. T changes every 30 days
+ * (2592000000 = 30 * 24 * 60 * 60 * 1000).
+ *
+ * C is the value of Tag::ATTESTATION_APPLICATION_ID that is provided to attestKey().
+ *
+ * R is 1 if Tag::RESET_SINCE_ID_ROTATION was provided to attestKey or 0 if the tag was not
+ * provided.
+ *
+ * HBK is a unique hardware-bound secret known to the secure environment and never revealed
+ * by it. The secret must contain at least 128 bits of entropy and be unique to the
+ * individual device (probabilistic uniqueness is acceptable).
+ *
+ * HMAC_SHA256 is the HMAC function, with SHA-2-256 as the hash.
+ *
+ * The output of the HMAC function must be truncated to 128 bits.
+ *
+ * Must be hardware-enforced.
+ */
+ UNIQUE_ID = TagType:BYTES | 707,
+
+ /**
+ * Tag::ATTESTATION_CHALLENGE is used to deliver a "challenge" value to the attestKey() method,
+ * which must place the value in the KeyDescription SEQUENCE of the attestation extension. See
+ * attestKey().
+ *
+ * Must never appear in KeyCharacteristics.
+ */
+ ATTESTATION_CHALLENGE = TagType:BYTES | 708, /* Used to provide challenge in attestation */
+
+ /**
+ * Tag::ATTESTATION_APPLICATION_ID identifies the set of applications which may use a key, used
+ * only with attestKey().
+ *
+ * The content of Tag::ATTESTATION_APPLICATION_ID is a DER-encoded ASN.1 structure, with the
+ * following schema:
+ *
+ * AttestationApplicationId ::= SEQUENCE {
+ * packageInfoRecords SET OF PackageInfoRecord,
+ * signatureDigests SET OF OCTET_STRING,
+ * }
+ *
+ * PackageInfoRecord ::= SEQUENCE {
+ * packageName OCTET_STRING,
+ * version INTEGER,
+ * }
+ *
+ * See system/security/keystore/keystore_attestation_id.cpp for details of construction.
+ * IKeymasterDevice implementers do not need to create or parse the ASN.1 structure, but only
+ * copy the tag value into the attestation record. The DER-encoded string must not exceed 1 KiB
+ * in length.
+ *
+ * Cannot be hardware-enforced.
+ */
+ ATTESTATION_APPLICATION_ID = TagType:BYTES | 709,
+
+ /**
+ * Tag::ATTESTATION_ID_BRAND provides the device's brand name, as returned by Build.BRAND in
+ * Android, to attestKey(). This field is set only when requesting attestation of the device's
+ * identifiers.
+ *
+ * If the device does not support ID attestation (or destroyAttestationIds() was previously
+ * called and the device can no longer attest its IDs), any key attestation request that
+ * includes this tag must fail with ErrorCode::CANNOT_ATTEST_IDS.
+ *
+ * Must never appear in KeyCharacteristics.
+ */
+ ATTESTATION_ID_BRAND = TagType:BYTES | 710,
+
+ /**
+ * Tag::ATTESTATION_ID_DEVICE provides the device's device name, as returned by Build.DEVICE in
+ * Android, to attestKey(). This field is set only when requesting attestation of the device's
+ * identifiers.
+ *
+ * If the device does not support ID attestation (or destroyAttestationIds() was previously
+ * called and the device can no longer attest its IDs), any key attestation request that
+ * includes this tag must fail with ErrorCode::CANNOT_ATTEST_IDS.
+ *
+ * Must never appear in KeyCharacteristics.
+ */
+ ATTESTATION_ID_DEVICE = TagType:BYTES | 711,
+
+ /**
+ * Tag::ATTESTATION_ID_PRODUCT provides the device's product name, as returned by Build.PRODUCT
+ * in Android, to attestKey(). This field is set only when requesting attestation of the
+ * device's identifiers.
+ *
+ * If the device does not support ID attestation (or destroyAttestationIds() was previously
+ * called and the device can no longer attest its IDs), any key attestation request that
+ * includes this tag must fail with ErrorCode::CANNOT_ATTEST_IDS.
+ *
+ * Must never appear in KeyCharacteristics.
+ */
+ ATTESTATION_ID_PRODUCT = TagType:BYTES | 712,
+
+ /**
+ * Tag::ATTESTATION_ID_SERIAL the device's serial number. This field is set only when
+ * requesting attestation of the device's identifiers.
+ *
+ * If the device does not support ID attestation (or destroyAttestationIds() was previously
+ * called and the device can no longer attest its IDs), any key attestation request that
+ * includes this tag must fail with ErrorCode::CANNOT_ATTEST_IDS.
+ *
+ * Must never appear in KeyCharacteristics.
+ */
+ ATTESTATION_ID_SERIAL = TagType:BYTES | 713,
+
+ /**
+ * Tag::ATTESTATION_ID_IMEI provides the IMEIs for all radios on the device to attestKey().
+ * This field is set only when requesting attestation of the device's identifiers.
+ *
+ * If the device does not support ID attestation (or destroyAttestationIds() was previously
+ * called and the device can no longer attest its IDs), any key attestation request that
+ * includes this tag must fail with ErrorCode::CANNOT_ATTEST_IDS.
+ *
+ * Must never appear in KeyCharacteristics.
+ */
+ ATTESTATION_ID_IMEI = TagType:BYTES | 714, /* Used to provide the device's IMEI to be included
+ * in attestation */
+
+ /**
+ * Tag::ATTESTATION_ID_MEID provides the MEIDs for all radios on the device to attestKey().
+ * This field will only be set when requesting attestation of the device's identifiers.
+ *
+ * If the device does not support ID attestation (or destroyAttestationIds() was previously
+ * called and the device can no longer attest its IDs), any key attestation request that
+ * includes this tag must fail with ErrorCode::CANNOT_ATTEST_IDS.
+ *
+ * Must never appear in KeyCharacteristics.
+ */
+ ATTESTATION_ID_MEID = TagType:BYTES | 715, /* Used to provide the device's MEID to be included
+ * in attestation */
+
+ /**
+ * Tag::ATTESTATION_ID_MANUFACTURER provides the device's manufacturer name, as returned by
+ * Build.MANUFACTURER in Android, to attstKey(). This field is set only when requesting
+ * attestation of the device's identifiers.
+ *
+ * If the device does not support ID attestation (or destroyAttestationIds() was previously
+ * called and the device can no longer attest its IDs), any key attestation request that
+ * includes this tag must fail with ErrorCode::CANNOT_ATTEST_IDS.
+ *
+ * Must never appear in KeyCharacteristics.
+ */
+ ATTESTATION_ID_MANUFACTURER = TagType:BYTES | 716,
+
+ /**
+ * Tag::ATTESTATION_ID_MODEL provides the device's model name, as returned by Build.MODEL in
+ * Android, to attestKey(). This field is set only when requesting attestation of the device's
+ * identifiers.
+ *
+ * If the device does not support ID attestation (or destroyAttestationIds() was previously
+ * called and the device can no longer attest its IDs), any key attestation request that
+ * includes this tag must fail with ErrorCode::CANNOT_ATTEST_IDS.
+ *
+ * Must never appear in KeyCharacteristics.
+ */
+ ATTESTATION_ID_MODEL = TagType:BYTES | 717,
+
+ /**
+ * Tag::VENDOR_PATCHLEVEL specifies the vendor image security patch level with which the key may
+ * be used. This tag is never sent to the keymaster TA, but is added to the hardware-enforced
+ * authorization list by the TA. Any attempt to use a key with a Tag::VENDOR_PATCHLEVEL value
+ * different from the currently-running system patchlevel must cause begin(),
+ * getKeyCharacteristics() or exportKey() to return ErrorCode::KEY_REQUIRES_UPGRADE. See
+ * upgradeKey() for details.
+ *
+ * The value of the tag is an integer of the form YYYYMMDD, where YYYY is the four-digit year of
+ * the last update, MM is the two-digit month and DD is the two-digit day of the last
+ * update. For example, for a key generated on an Android device last updated on June 5, 2018,
+ * the value would be 20180605.
+ *
+ * The IKeymasterDevice HAL must read the current vendor patchlevel from the system property
+ * ro.vendor.build.security_patch and deliver it to the secure environment when the HAL is first
+ * loaded (mechanism is implementation-defined). The secure environment must not accept another
+ * patchlevel until after the next boot.
+ *
+ * Must be hardware-enforced.
*/
VENDOR_PATCHLEVEL = TagType:UINT | 718,
/**
- * Patch level of boot image. The value is an integer of the form YYYYMM, where YYYY is the
- * four-digit year when the boot image was released and MM is the two-digit month. During each
- * boot, the bootloader must provide the patch level of the boot image to keymaser (mechanism is
- * implemntation-defined). When keymaster keys are created or updated, the BOOT_PATCHLEVEL tag
- * must be cryptographically bound to the keys, with the current value as provided by the
- * bootloader. When keys are used, keymaster must verify that the BOOT_PATCHLEVEL bound to the
- * key matches the current value. If they do not match, keymaster must return
- * ErrorCode::KEY_REQUIRES_UPGRADE. The client must then call upgradeKey.
+ * Tag::BOOT_PATCHLEVEL specifies the boot image (kernel) security patch level with which the
+ * key may be used. This tag is never sent to the keymaster TA, but is added to the
+ * hardware-enforced authorization list by the TA. Any attempt to use a key with a
+ * Tag::BOOT_PATCHLEVEL value different from the currently-running system patchlevel must
+ * cause begin(), getKeyCharacteristics() or exportKey() to return
+ * ErrorCode::KEY_REQUIRES_UPGRADE. See upgradeKey() for details.
+ *
+ * The value of the tag is an integer of the form YYYYMMDD, where YYYY is the four-digit year of
+ * the last update, MM is the two-digit month and DD is the two-digit day of the last
+ * update. For example, for a key generated on an Android device last updated on June 5, 2018,
+ * the value would be 20180605. If the day is not known, 00 may be substituted.
+ *
+ * During each boot, the bootloader must provide the patch level of the boot image to the secure
+ * envirionment (mechanism is implementation-defined).
+ *
+ * Must be hardware-enforced.
*/
BOOT_PATCHLEVEL = TagType:UINT | 719,
- /* Tags used only to provide data to or receive data from operations */
- ASSOCIATED_DATA = TagType:BYTES | 1000, /* Used to provide associated data for AEAD modes. */
- NONCE = TagType:BYTES | 1001, /* Nonce or Initialization Vector */
- MAC_LENGTH = TagType:UINT | 1003, /* MAC or AEAD authentication tag length in bits. */
-
- RESET_SINCE_ID_ROTATION = TagType:BOOL | 1004, /* Whether the device has beeen factory reset
- * since the last unique ID rotation. Used for
- * key attestation. */
+ /**
+ * Tag::ASSOCIATED_DATA Provides "associated data" for AES-GCM encryption or decryption. This
+ * tag is provided to update and specifies data that is not encrypted/decrypted, but is used in
+ * computing the GCM tag.
+ *
+ * Must never appear KeyCharacteristics.
+ */
+ ASSOCIATED_DATA = TagType:BYTES | 1000,
/**
- * CONFIRMATION_TOKEN is used to deliver a cryptographic token proving that the user confirmed a
- * signing request. The content is a full-length HMAC-SHA256 value. See the ConfirmationUI HAL
- * for details of token computation.
+ * Tag::NONCE is used to provide or return a nonce or Initialization Vector (IV) for AES-GCM,
+ * AES-CBC, AES-CTR, or 3DES-CBC encryption or decryption. This tag is provided to begin during
+ * encryption and decryption operations. It is only provided to begin if the key has
+ * Tag::CALLER_NONCE. If not provided, an appropriate nonce or IV will be randomly generated by
+ * Keymaster and returned from begin.
+ *
+ * The value is a blob, an arbitrary-length array of bytes. Allowed lengths depend on the mode:
+ * GCM nonces are 12 bytes in length; AES-CBC and AES-CTR IVs are 16 bytes in length, 3DES-CBC
+ * IVs are 8 bytes in length.
+ *
+ * Must never appear in KeyCharacteristics.
+ */
+ NONCE = TagType:BYTES | 1001,
+
+ /**
+ * Tag::MAC_LENGTH provides the requested length of a MAC or GCM authentication tag, in bits.
+ *
+ * The value is the MAC length in bits. It must be a multiple of 8 and at least as large as the
+ * value of Tag::MIN_MAC_LENGTH associated with the key. Otherwise, begin() must return
+ * ErrorCode::INVALID_MAC_LENGTH.
+ *
+ * Must never appear in KeyCharacteristics.
+ */
+ MAC_LENGTH = TagType:UINT | 1003,
+
+ /**
+ * Tag::RESET_SINCE_ID_ROTATION specifies whether the device has been factory reset since the
+ * last unique ID rotation. Used for key attestation.
+ *
+ * Must never appear in KeyCharacteristics.
+ */
+ RESET_SINCE_ID_ROTATION = TagType:BOOL | 1004,
+
+ /**
+ * Tag::CONFIRMATION_TOKEN is used to deliver a cryptographic token proving that the user
+ * confirmed a signing request. The content is a full-length HMAC-SHA256 value. See the
+ * ConfirmationUI HAL for details of token computation.
+ *
+ * Must never appear in KeyCharacteristics.
*/
CONFIRMATION_TOKEN = TagType:BYTES | 1005,
};
/**
- * Algorithms provided by keymaser implementations.
+ * Algorithms provided by IKeymasterDevice implementations.
*/
enum Algorithm : uint32_t {
/** Asymmetric algorithms. */
RSA = 1,
- // DSA = 2, -- Removed, do not re-use value 2.
+ // 2 removed, do not reuse.
EC = 3,
- /** Block ciphers algorithms */
+ /** Block cipher algorithms */
AES = 32,
TRIPLE_DES = 33,
@@ -393,12 +974,12 @@
* Possible purposes of a key (or pair).
*/
enum KeyPurpose : uint32_t {
- ENCRYPT = 0, /* Usable with RSA, EC and AES keys. */
- DECRYPT = 1, /* Usable with RSA, EC and AES keys. */
- SIGN = 2, /* Usable with RSA, EC and HMAC keys. */
- VERIFY = 3, /* Usable with RSA, EC and HMAC keys. */
+ ENCRYPT = 0, /* Usable with RSA, EC and AES keys. */
+ DECRYPT = 1, /* Usable with RSA, EC and AES keys. */
+ SIGN = 2, /* Usable with RSA, EC and HMAC keys. */
+ VERIFY = 3, /* Usable with RSA, EC and HMAC keys. */
/* 4 is reserved */
- WRAP_KEY = 5, /* Usable with wrapping keys. */
+ WRAP_KEY = 5, /* Usable with wrapping keys. */
};
/**
@@ -481,6 +1062,8 @@
VERSION_MISMATCH = -101,
UNKNOWN_ERROR = -1000,
+
+ // Implementer's namespace for error codes starts at -10000.
};
/**
@@ -521,39 +1104,10 @@
SOFTWARE = 0,
TRUSTED_ENVIRONMENT = 1,
/**
- * STRONGBOX specifies that the secure hardware satisfies the following requirements:
- *
- * a) Has a discrete CPU. The StrongBox device must not be the same CPU that is used to run
- * the Android non-secure world, or any other untrusted code. The StrongBox CPU must not
- * share cache, RAM or any other critical resources with any device that runs untrusted
- * code.
- *
- * b) Has integral secure storage. The StrongBox device must have its own non-volatile
- * storage that is not accessible by any other hardware component.
- *
- * c) Has a high-quality True Random Number Generator. The StrongBox device must have sole
- * control of and access to a high-quality TRNG which it uses for generating necessary
- * random bits. It must combine the output of this TRNG with caller-provided entropy in a
- * strong CPRNG, as do non-Strongbox Keymaster implementations.
- *
- * d) Is enclosed in tamper-resistant packaging. The StrongBox device must have
- * tamper-resistant packaging which provides obstacles to physical penetration which are
- * higher than those provided by normal integrated circuit packages.
- *
- * e) Provides side-channel resistance. The StrongBox device must implement resistance
- * against common side-channel attacks, including power analysis, timing analysis, EM
- * snooping, etc.
- *
- * Devices with StrongBox Keymasters must also have a non-StrongBox Keymaster, which lives in
- * the higher-performance TEE. Keystore must load both StrongBox (if available) and
- * non-StrongBox HALs and route key generation/import requests appropriately. Callers that want
- * StrongBox keys must add Tag::HARDWARE_TYPE with value SecurityLevel::STRONGBOX to the key
- * description provided to generateKey or importKey. Keytore must route the request to a
- * StrongBox HAL (a HAL whose isStrongBox method returns true). Keymaster implementations that
- * receive a request for a Tag::HARDWARE_TYPE that is inappropriate must fail with
- * ErrorCode::HARDWARE_TYPE_UNAVAILABLE.
+ * STRONGBOX specifies that the secure hardware satisfies the requirements specified in CDD
+ * 9.11.2.
*/
- STRONGBOX = 2, /* See IKeymaster::isStrongBox */
+ STRONGBOX = 2,
};
/**
@@ -564,17 +1118,19 @@
X509 = 0,
/** PCKS#8 format, asymmetric key pair import. */
PKCS8 = 1,
- /** Raw bytes, for symmetric key import and export. */
+ /** Raw bytes, for symmetric key import. */
RAW = 3,
};
struct KeyParameter {
/**
- * Discriminates the uinon/blob field used. The blob cannot be coincided with the union, but
- * only one of "f" and "blob" is ever used at a time. */
+ * Discriminates the union/blob field used. The blob cannot be placed in the union, but only
+ * one of "f" and "blob" may ever be used at a time.
+ */
Tag tag;
+
union IntegerParams {
- /** Enum types */
+ /* Enum types */
Algorithm algorithm;
BlockMode blockMode;
PaddingMode paddingMode;
@@ -587,7 +1143,7 @@
HardwareAuthenticatorType hardwareAuthenticatorType;
SecurityLevel hardwareType;
- /** Other types */
+ /* Other types */
bool boolValue; // Always true, if a boolean tag is present.
uint32_t integer;
uint64_t longInteger;
@@ -597,20 +1153,68 @@
vec<uint8_t> blob;
};
+/**
+ * KeyCharacteristics defines the attributes of a key, including cryptographic parameters, and usage
+ * restrictions. It consits of two vectors of KeyParameters, one for "softwareEnforced" attributes
+ * and one for "hardwareEnforced" attributes.
+ *
+ * KeyCharacteristics objects are returned by generateKey, importKey, importWrappedKey and
+ * getKeyCharacteristics. The IKeymasterDevice secure environment is responsible for allocating the
+ * parameters, all of which are Tags with associated values, to the correct vector. The
+ * hardwareEnforced vector must contain only those attributes which are enforced by secure hardware.
+ * All others should be in the softwareEnforced vector. See the definitions of individual Tag enums
+ * for specification of which must be hardware-enforced, which may be software-enforced and which
+ * must never appear in KeyCharacteristics.
+ */
struct KeyCharacteristics {
vec<KeyParameter> softwareEnforced;
vec<KeyParameter> hardwareEnforced;
};
/**
- * Data used to prove successful authentication.
+ * HardwareAuthToken is used to prove successful user authentication, to unlock the use of a key.
+ *
+ * HardwareAuthTokens are produced by other secure environment applications, notably GateKeeper and
+ * Fingerprint, in response to successful user authentication events. These tokens are passed to
+ * begin(), update(), and finish() to prove that authentication occurred. See those methods for
+ * more details. It is up to the caller to determine which of the generated auth tokens is
+ * appropriate for a given key operation.
*/
struct HardwareAuthToken {
+ /**
+ * challenge is a value that's used to enable authentication tokens to authorize specific
+ * events. The primary use case for challenge is to authorize an IKeymasterDevice cryptographic
+ * operation, for keys that require authentication per operation. See begin() for details.
+ */
uint64_t challenge;
- uint64_t userId; // Secure User ID, not Android user ID.
- uint64_t authenticatorId; // Secure authenticator ID.
+
+ /**
+ * userId is the a "secure" user ID. It is not related to any Android user ID or UID, but is
+ * created in the Gatekeeper application in the secure environment.
+ */
+ uint64_t userId;
+
+ /**
+ * authenticatorId is the a "secure" user ID. It is not related to any Android user ID or UID,
+ * but is created in an authentication application in the secure environment, such as the
+ * Fingerprint application.
+ */
+ uint64_t authenticatorId; // Secure authenticator ID.
+
+ /**
+ * authenticatorType describes the type of authentication that took place, e.g. password or
+ * fingerprint.
+ */
HardwareAuthenticatorType authenticatorType;
+
+ /**
+ * timestamp indicates when the user authentication took place, in milliseconds since some
+ * starting point (generally the most recent device boot) which all of the applications within
+ * one secure environment must agree upon. This timestamp is used to determine whether or not
+ * the authentication occurred recently enough to unlock a key (see Tag::AUTH_TIMEOUT).
+ */
Timestamp timestamp;
+
/**
* MACs are computed with a backward-compatible method, used by Keymaster 3.0, Gatekeeper 1.0
* and Fingerprint 1.0, as well as pre-treble HALs.
@@ -623,7 +1227,8 @@
* where ``||'' represents concatenation, the leading zero is a single byte, and all integers
* are represented as unsigned values, the full width of the type. The challenge, userId and
* authenticatorId values are in machine order, but authenticatorType and timestamp are in
- * network order. This odd construction is compatible with the hw_auth_token_t structure,
+ * network order (big-endian). This odd construction is compatible with the hw_auth_token_t
+ * structure,
*
* Note that mac is a vec rather than an array, not because it's actually variable-length but
* because it could be empty. As documented in the IKeymasterDevice::begin,
diff --git a/light/utils/main.cpp b/light/utils/main.cpp
index d07e799..724e0ee 100644
--- a/light/utils/main.cpp
+++ b/light/utils/main.cpp
@@ -55,5 +55,6 @@
}
});
- return 0;
+ // b/77934844: Avoid running static destructors.
+ _exit(1);
}
diff --git a/media/omx/1.0/vts/functional/audio/media_audio_hidl_test_common.cpp b/media/omx/1.0/vts/functional/audio/media_audio_hidl_test_common.cpp
index 9500094..e7ae083 100644
--- a/media/omx/1.0/vts/functional/audio/media_audio_hidl_test_common.cpp
+++ b/media/omx/1.0/vts/functional/audio/media_audio_hidl_test_common.cpp
@@ -94,6 +94,51 @@
param.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
param.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
break;
+ case 3:
+ param.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
+ param.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
+ param.eChannelMapping[2] = OMX_AUDIO_ChannelCF;
+ break;
+ case 4:
+ param.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
+ param.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
+ param.eChannelMapping[2] = OMX_AUDIO_ChannelLR;
+ param.eChannelMapping[3] = OMX_AUDIO_ChannelRR;
+ break;
+ case 5:
+ param.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
+ param.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
+ param.eChannelMapping[2] = OMX_AUDIO_ChannelCF;
+ param.eChannelMapping[3] = OMX_AUDIO_ChannelLR;
+ param.eChannelMapping[4] = OMX_AUDIO_ChannelRR;
+ break;
+ case 6:
+ param.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
+ param.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
+ param.eChannelMapping[2] = OMX_AUDIO_ChannelCF;
+ param.eChannelMapping[3] = OMX_AUDIO_ChannelLFE;
+ param.eChannelMapping[4] = OMX_AUDIO_ChannelLR;
+ param.eChannelMapping[5] = OMX_AUDIO_ChannelRR;
+ break;
+ case 7:
+ param.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
+ param.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
+ param.eChannelMapping[2] = OMX_AUDIO_ChannelCF;
+ param.eChannelMapping[3] = OMX_AUDIO_ChannelLFE;
+ param.eChannelMapping[4] = OMX_AUDIO_ChannelLR;
+ param.eChannelMapping[5] = OMX_AUDIO_ChannelRR;
+ param.eChannelMapping[6] = OMX_AUDIO_ChannelCS;
+ break;
+ case 8:
+ param.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
+ param.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
+ param.eChannelMapping[2] = OMX_AUDIO_ChannelCF;
+ param.eChannelMapping[3] = OMX_AUDIO_ChannelLFE;
+ param.eChannelMapping[4] = OMX_AUDIO_ChannelLR;
+ param.eChannelMapping[5] = OMX_AUDIO_ChannelRR;
+ param.eChannelMapping[6] = OMX_AUDIO_ChannelLS;
+ param.eChannelMapping[7] = OMX_AUDIO_ChannelRS;
+ break;
default:
EXPECT_TRUE(false);
}
diff --git a/radio/1.1/ISap.hal b/radio/1.1/ISap.hal
index edcf176..0cabccc 100644
--- a/radio/1.1/ISap.hal
+++ b/radio/1.1/ISap.hal
@@ -18,8 +18,7 @@
import @1.0::ISap;
-interface ISap extends @1.0::ISap {
- /**
- * Empty top level interface.
- */
-};
+/**
+ * Empty top level interface.
+ */
+interface ISap extends @1.0::ISap {};
diff --git a/radio/1.2/ISap.hal b/radio/1.2/ISap.hal
index 757027c..65f9b84 100644
--- a/radio/1.2/ISap.hal
+++ b/radio/1.2/ISap.hal
@@ -18,8 +18,7 @@
import @1.1::ISap;
-interface ISap extends @1.1::ISap {
- /**
- * Empty top level interface.
- */
-};
+/**
+ * Empty top level interface.
+ */
+interface ISap extends @1.1::ISap {};
diff --git a/tv/cec/1.0/types.hal b/tv/cec/1.0/types.hal
index a1853a3..c734c4d 100644
--- a/tv/cec/1.0/types.hal
+++ b/tv/cec/1.0/types.hal
@@ -193,7 +193,7 @@
*/
SYSTEM_CEC_CONTROL = 3,
- /** Option 4 not used */
+ /* Option 4 not used */
};
struct CecMessage {
diff --git a/usb/1.1/IUsb.hal b/usb/1.1/IUsb.hal
index 9cedea0..606928b 100644
--- a/usb/1.1/IUsb.hal
+++ b/usb/1.1/IUsb.hal
@@ -18,11 +18,9 @@
import android.hardware.usb@1.0;
-interface IUsb extends android.hardware.usb@1.0::IUsb {
- /**
- * The setCallback function in V1_0 is used to register the V1_1
- * IUsbCallback object as well. The implementation can use the
- * castFrom method to cast the IUsbCallback object.
- */
-};
-
+/*
+ * The setCallback function in V1_0 is used to register the V1_1
+ * IUsbCallback object as well. The implementation can use the
+ * castFrom method to cast the IUsbCallback object.
+ */
+interface IUsb extends android.hardware.usb@1.0::IUsb {};
diff --git a/wifi/1.0/IWifiP2pIface.hal b/wifi/1.0/IWifiP2pIface.hal
index 243748f..b908591 100644
--- a/wifi/1.0/IWifiP2pIface.hal
+++ b/wifi/1.0/IWifiP2pIface.hal
@@ -21,6 +21,4 @@
/**
* Interface used to represent a single NAN iface.
*/
-interface IWifiP2pIface extends IWifiIface {
- /** TODO(rpius): Add methods to the interface. */
-};
+interface IWifiP2pIface extends IWifiIface {};
diff --git a/wifi/1.0/README-NAN.md b/wifi/1.0/README-NAN.md
index f4b3320..645c9f9 100644
--- a/wifi/1.0/README-NAN.md
+++ b/wifi/1.0/README-NAN.md
@@ -14,7 +14,7 @@
# Wi-Fi Aware (NAN) HAL API Usage
-The Wi-Fi Aware (NAN) HAL API is defined in (<i>hardware/interfaces/wifi/\<version\>/</i>):
+The Wi-Fi Aware (NAN) HAL API is defined in (<i>hardware/interfaces/wifi/1.0/</i>):
* IWifiNanIface.hal
* IWifiNanIfaceEventCallback.hal
@@ -23,7 +23,7 @@
The Wi-Fi Aware (NAN) HAL API surface is very large - only a subset is used from the framework.
Understanding of the HAL API subset which is actively used by the Android framework can be deduced
-by reviewing framework code, specifically (<i>frameworks/opt/net/wif/</i>):
+by reviewing framework code, specifically (<i>frameworks/opt/net/wifi/</i>):
* WifiAwareNativeApi.java
* WifiAwareNativeCallback.java
@@ -41,7 +41,7 @@
Format:
* Hard-coded values are in <b>bold</b>, e.g. <b>true</b> or <b>5</b>
-* Assigned but not fixed value are specified using the <i>variable</i> keyword, possibly with some
+* Assigned but not fixed values are specified using the <i>variable</i> keyword, possibly with some
details/constraints
* Unassigned values are specified using the <i>N/A</i> keyword. Unassigned usually means initialized
to 0.
diff --git a/wifi/1.2/README-NAN.md b/wifi/1.2/README-NAN.md
new file mode 100644
index 0000000..00b9169
--- /dev/null
+++ b/wifi/1.2/README-NAN.md
@@ -0,0 +1,231 @@
+Copyright 2018 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.
+
+# Wi-Fi Aware (NAN) HAL API Usage
+
+The Wi-Fi Aware (NAN) HAL API is defined in (<i>hardware/interfaces/wifi/1.0/</i> and
+<i>hardware/interfaces/wifi/1.2/</i>):
+
+* IWifiNanIface.hal
+* IWifiNanIfaceEventCallback.hal
+* types.hal (structure definitions)
+
+Note that the <i>1.2</i> HAL is supplemental to the <i>1.0</i> HAL - not a replacement.
+
+The Wi-Fi Aware (NAN) HAL API surface is very large - only a subset is used from the framework.
+
+Understanding of the HAL API subset which is actively used by the Android framework can be deduced
+by reviewing framework code, specifically (<i>frameworks/opt/net/wifi/</i>):
+
+* WifiAwareNativeApi.java
+* WifiAwareNativeCallback.java
+
+The above framework files determine the API usage - and should be consulted as the authoritative
+reference. Please consult the primary HAL file for documentation - they will not be replicated
+in this document. APIs which are in the HAL but are not listed in this README file are not used by
+the framework.
+
+Note: the HAL API is translated to the legacy HAL API (<i>wifi_nan.h</i>). This README file covers
+the new HAL API only. To understand the mapping between new and legacy HALs please consult
+<i>hardware/interfaces/wifi/\<version\>/default/hidl_struct_util.cpp</i>.
+
+## IWifiNanIface
+
+Format:
+* Hard-coded values are in <b>bold</b>, e.g. <b>true</b> or <b>5</b>
+* Assigned but not fixed values are specified using the <i>variable</i> keyword, possibly with some
+details/constraints
+* Unassigned values are specified using the <i>N/A</i> keyword. Unassigned usually means initialized
+to 0.
+
+APIs:
+
+* registerEventCallback_1_2(IWifiNanIfaceEventCallback_1_2 callback)
+* getCapabilitiesRequest
+* enableRequest_1_2
+ * NanEnableRequest
+ * bool[2] operateInBand
+ * Index [NanBandIndex.NAN_BAND_24GHZ] = <b>true</b>
+ * Index [NanBandIndex.NAN_BAND_5GHZ] = <i>variable</i>
+ * uint8_t hopCountMax = <b>2</b>
+ * NanConfigRequest configParams
+ * uint8_t masterPref = <i>variable</i>
+ * bool disableDiscoveryAddressChangeIndication = <i>variable</i>
+ * bool disableStartedClusterIndication = <i>variable</i>
+ * bool disableJoinedClusterIndication = <i>variable</i>
+ * bool includePublishServiceIdsInBeacon = <b>true</b>
+ * uint8_t numberOfPublishServiceIdsInBeacon = <b>0</b>
+ * bool includeSubscribeServiceIdsInBeacon = <b>true</b>
+ * uint8_t numberOfSubscribeServiceIdsInBeacon = <b>0</b>
+ * uint16_t rssiWindowSize = <b>8</b>
+ * uint32_t macAddressRandomizationIntervalSec = <i>variable</i>
+ * Normal run-time: set to <b>1800</b> (30 minutes)
+ * Tests: set to <b>120</b> (2 minutes)
+ * NanBandSpecificConfig[2] bandSpecificConfig
+ * Index [NanBandIndex.NAN_BAND_24GHZ]
+ * uint8_t rssiClose = <b>60</b>
+ * uint8_t rssiMiddle = <b>70</b>
+ * uint8_t rssiCloseProximity = <b>60</b>
+ * uint8_t dwellTimeMs = <b>200</b>
+ * uint16_t scanPeriodSec = <b>20</b>
+ * bool validDiscoveryWindowIntervalVal = <i>variable</i>
+ * uint8_t discoveryWindowIntervalVal = <i>variable</i>
+ * Index [NanBandIndex.NAN_BAND_5GHZ]
+ * uint8_t rssiClose = <b>60</b>
+ * uint8_t rssiMiddle = <b>75</b>
+ * uint8_t rssiCloseProximity = <b>60</b>
+ * uint8_t dwellTimeMs = <b>200</b>
+ * uint16_t scanPeriodSec = <b>20</b>
+ * bool validDiscoveryWindowIntervalVal = <i>variable</i>
+ * uint8_t discoveryWindowIntervalVal = <i>variable</i>
+ * NanDebugConfig debugConfigs
+ * bool validClusterIdVals = <b>true</b>
+ * uint16_t clusterIdBottomRangeVal = <i>variable</i>
+ * uint16_t clusterIdTopRangeVal = <i>variable</i>
+ * bool validIntfAddrVal = <b>false</b>
+ * MacAddress intfAddrVal = <i>N/A</i>
+ * bool validOuiVal = <b>false</b>
+ * uint32_t ouiVal = <i>N/A</i>
+ * bool validRandomFactorForceVal = <b>false</b>
+ * uint8_t randomFactorForceVal = <i>N/A</i>
+ * bool validHopCountForceVal = <b>false</b>
+ * uint8_t hopCountForceVal = <i>N/A</i>
+ * bool validDiscoveryChannelVal = <b>false</b>
+ * WifiChannelInMhz[2] discoveryChannelMhzVal = <i>N/A</i>
+ * bool validUseBeaconsInBandVal = <b>false</b>
+ * bool[2] useBeaconsInBandVal = <i>N/A</i>
+ * bool validUseSdfInBandVal = <b>false</b>
+ * bool[2] useSdfInBandVal = <i>N/A</i>
+ * NanConfigRequestSupplemental
+ * uint32_t discoveryBeaconIntervalMs = <b>0</b>
+ * uint32_t numberOfSpatialStreamsInDiscovery = <b>0</b>
+ * bool enableDiscoveryWindowEarlyTermination = <b>false</b>
+ * bool enableRanging = <b>true</b>
+* configRequest_1_2
+ * NanConfigRequest: same as for <i>enableRequest_1_2</i>
+* disableRequest
+* startPublishRequest
+ * NanPublishRequest
+ * NanDiscoveryCommonConfig baseConfigs
+ * uint8_t sessionId = <i>variable</i>
+ * uint16_t ttlSec = <i>variable</i>
+ * uint16_t discoveryWindowPeriod = <b>1</b>
+ * uint8_t discoveryCount = <b>0</b>
+ * vec<uint8_t> serviceName = <i>variable</i>
+ * NanMatchAlg discoveryMatchIndicator = <b>NanMatchAlg.MATCH_NEVER</b>
+ * vec<uint8_t> serviceSpecificInfo = <i>variable</i>
+ * vec<uint8_t> extendedServiceSpecificInfo = <i>N/A</i>
+ e vec<uint8_t> rxMatchFilter = <i>variable</i>
+ * vec<uint8_t> txMatchFilter = <i>variable</i>
+ * bool useRssiThreshold = <b>false</b>
+ * bool disableDiscoveryTerminationIndication = <i>variable</i>
+ * bool disableMatchExpirationIndication = <b>true</b>
+ * bool disableFollowupReceivedIndication = <b>false</b>
+ * NanDataPathSecurityConfig securityConfig = <b>NanDataPathSecurityType.OPEN</b>
+ * bool rangingRequired = <b>false</b>
+ * uint32_t rangingIntervalMsec = <i>N/A</i>
+ * bitfield<NanRangingIndication> configRangingIndications = <i>N/A</i>
+ * uint16_t distanceIngressCm = <i>N/A</i>
+ * uint16_t distanceEgressCm = <i>N/A</i>
+ * NanPublishType publishType = <i>variable</i>
+ * NanTxType txType = <b>NanTxType.BROADCAST</b>
+ * bool autoAcceptDataPathRequests = <b>false</b>
+* stopPublishRequest
+* startSubscribeRequest
+ * NanSubscribeRequest
+ * NanDiscoveryCommonConfig baseConfigs
+ * Mostly same as <i>publish</i> above except:
+ * NanMatchAlg discoveryMatchIndicator = <b>NanMatchAlg.MATCH_ONCE</b>
+ * NanSubscribeType subscribeType = <i>variable</i>
+ * NanSrfType srfType = <i>N/A</i>
+ * bool srfRespondIfInAddressSet = <i>N/A</i>
+ * bool shouldUseSrf = <i>N/A</i>
+ * bool isSsiRequiredForMatch = <i>N/A</i>
+ * vec<MacAddress> intfAddr = <i>N/A</i>
+* stopSubscribeRequest
+* transmitFollowupRequest
+ * NanTransmitFollowupRequest
+ * uint8_t discoverySessionId = <i>variable</i>
+ * uint32_t peerId = <i>variable</i>
+ * MacAddress addr = <i>variable</i>
+ * bool isHighPriority = <b>false</b>
+ * bool shouldUseDiscoveryWindow = <b>true</b>
+ * vec<uint8_t> serviceSpecificInfo = <i>variable</i>
+ * vec<uint8_t> extendedServiceSpecificInfo = <i>N/A</i>
+ * bool disableFollowupResultIndication = <b>false</b>
+* createDataInterfaceRequest
+* deleteDataInterfaceRequest
+* initiateDataPathRequest
+ * NanInitiateDataPathRequest
+ * uint32_t peerId = <i>variable</i>
+ * MacAddress peerDiscMacAddr = <i>variable</i>
+ * NanDataPathChannelCfg channelRequestType =
+ <i>NanDataPathChannelCfg.CHANNEL_NOT_REQUESTED</i>
+ * WifiChannelInMhz channel = <b>2437</b> (note that should be ignored though -
+ CHANNEL_NOT_REQUESTED!)
+ * string ifaceName = <i>variable</i>
+ * NanDataPathSecurityConfig securityConfig = <i>variable</i>
+ * vec<uint8_t> appInfo = <i>N/A</i>
+ * vec<uint8_t> serviceNameOutOfBand = <i>variable</i>
+* respondToDataPathIndicationRequest
+ * NanRespondToDataPathIndicationRequest
+ * bool acceptRequest = <i>variable</i>
+ * uint32_t ndpInstanceId = <i>variable</i>
+ * string ifaceName = <i>variable</i>
+ * NanDataPathSecurityConfig securityConfig = <i>variable</i>
+ * vec<uint8_t> appInfo = <i>N/A</i>
+ * vec<uint8_t> serviceNameOutOfBand = <i>variable</i>
+* terminateDataPathRequest
+
+## IWifiNanIfaceEventCallback_1_2
+
+Format:
+* Parameters whose values are <i>ignored</i> will be flagged, otherwise the parameter value is used
+by the framework.
+
+API:
+
+* notifyXxxResponse: all callbacks are used by framework
+* eventClusterEvent
+* eventDisabled
+* eventPublishTerminated
+* eventSubscribeTerminated
+* eventMatch
+ * NanMatchInd (all parameters are used except those listed below)
+ * vec<uint8_t> extendedServiceSpecificInfo: <i>ignored</i>
+ * bool matchOccuredInBeaconFlag: <i>ignored</i>
+ * bool outOfResourceFlag: <i>ignored</i>
+ * uint8_t rssiValue: <i>ignored</i>
+ * NanCipherSuiteType peerCipherType: <i>ignored</i>
+ * bool peerRequiresSecurityEnabledInNdp: <i>ignored</i>
+ * bool peerRequiresRanging: <i>ignored</i>
+ * uint32_t rangingMeasurementInCm: <i>ignored</i>
+ * bitfield<NanRangingIndication> rangingIndicationType: <i>ignored</i>
+* eventMatchExpired: <i>ignored</i>
+* eventFollowupReceived
+ * NanFollowupReceivedInd (all parameters are used except those listed below)
+ * bool receivedInFaw: <i>ignored</i>
+ * vec<uint8_t> extendedServiceSpecificInfo: <i>ignored</i>
+* eventTransmitFollowup
+* eventDataPathRequest
+ * NanDataPathRequestInd (all parameters are used except those listed below)
+ * bool securityRequired: <i>ignored</i>
+ * vec<uint8_t> appInfo: <i>ignored</i>
+* eventDataPathConfirm
+ * NanDataPathConfirmInd (all parameters are used except those listed below)
+ * vec<uint8_t> appInfo: <i>ignored</i>
+* eventDataPathScheduleUpdate
+ * NanDataPathScheduleUpdateInd
+* eventDataPathTerminated
+
diff --git a/wifi/1.2/default/OWNERS b/wifi/1.2/default/OWNERS
index 2878acc..8bfb148 100644
--- a/wifi/1.2/default/OWNERS
+++ b/wifi/1.2/default/OWNERS
@@ -1,2 +1,2 @@
rpius@google.com
-quiche@google.com
+etancohen@google.com