Merge "[AWARE] Add NDP channel info to HAL 1.2"
diff --git a/automotive/vehicle/2.0/IVehicle.hal b/automotive/vehicle/2.0/IVehicle.hal
index d962de0..1b1d391 100644
--- a/automotive/vehicle/2.0/IVehicle.hal
+++ b/automotive/vehicle/2.0/IVehicle.hal
@@ -43,7 +43,7 @@
* For VehiclePropertyChangeMode::ON_CHANGE properties, it must return the
* latest available value.
*
- * Some properties like AUDIO_VOLUME requires to pass additional data in
+ * Some properties like RADIO_PRESET requires to pass additional data in
* GET request in VehiclePropValue object.
*
* If there is no data available yet, which can happen during initial stage,
diff --git a/camera/device/3.2/default/CameraDevice.cpp b/camera/device/3.2/default/CameraDevice.cpp
index 295ee32..dfbb976 100644
--- a/camera/device/3.2/default/CameraDevice.cpp
+++ b/camera/device/3.2/default/CameraDevice.cpp
@@ -40,9 +40,11 @@
mCameraDeviceNames(cameraDeviceNames) {
mCameraIdInt = atoi(mCameraId.c_str());
// Should not reach here as provider also validate ID
- if (mCameraIdInt < 0 || mCameraIdInt >= module->getNumberOfCameras()) {
+ if (mCameraIdInt < 0) {
ALOGE("%s: Invalid camera id: %s", __FUNCTION__, mCameraId.c_str());
mInitFail = true;
+ } else if (mCameraIdInt >= mModule->getNumberOfCameras()) {
+ ALOGI("%s: Adding a new camera id: %s", __FUNCTION__, mCameraId.c_str());
}
mDeviceVersion = mModule->getDeviceVersion(mCameraIdInt);
diff --git a/camera/provider/2.4/default/CameraProvider.cpp b/camera/provider/2.4/default/CameraProvider.cpp
index ed974a5..e9588a7 100644
--- a/camera/provider/2.4/default/CameraProvider.cpp
+++ b/camera/provider/2.4/default/CameraProvider.cpp
@@ -66,6 +66,46 @@
using ::android::hardware::camera::common::V1_0::CameraMetadataType;
using ::android::hardware::camera::common::V1_0::Status;
+void CameraProvider::addDeviceNames(int camera_id, CameraDeviceStatus status, bool cam_new)
+{
+ char cameraId[kMaxCameraIdLen];
+ snprintf(cameraId, sizeof(cameraId), "%d", camera_id);
+ std::string cameraIdStr(cameraId);
+
+ mCameraIds.add(cameraIdStr);
+
+ // initialize mCameraDeviceNames and mOpenLegacySupported
+ mOpenLegacySupported[cameraIdStr] = false;
+ int deviceVersion = mModule->getDeviceVersion(camera_id);
+ auto deviceNamePair = std::make_pair(cameraIdStr,
+ getHidlDeviceName(cameraIdStr, deviceVersion));
+ mCameraDeviceNames.add(deviceNamePair);
+ if (cam_new) {
+ mCallbacks->cameraDeviceStatusChange(deviceNamePair.second, status);
+ }
+ if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_2 &&
+ mModule->isOpenLegacyDefined()) {
+ // try open_legacy to see if it actually works
+ struct hw_device_t* halDev = nullptr;
+ int ret = mModule->openLegacy(cameraId, CAMERA_DEVICE_API_VERSION_1_0, &halDev);
+ if (ret == 0) {
+ mOpenLegacySupported[cameraIdStr] = true;
+ halDev->close(halDev);
+ deviceNamePair = std::make_pair(cameraIdStr,
+ getHidlDeviceName(cameraIdStr, CAMERA_DEVICE_API_VERSION_1_0));
+ mCameraDeviceNames.add(deviceNamePair);
+ if (cam_new) {
+ mCallbacks->cameraDeviceStatusChange(deviceNamePair.second, status);
+ }
+ } else if (ret == -EBUSY || ret == -EUSERS) {
+ // Looks like this provider instance is not initialized during
+ // system startup and there are other camera users already.
+ // Not a good sign but not fatal.
+ ALOGW("%s: open_legacy try failed!", __FUNCTION__);
+ }
+ }
+}
+
/**
* static callback forwarding methods from HAL to instance
*/
@@ -75,6 +115,7 @@
int new_status) {
CameraProvider* cp = const_cast<CameraProvider*>(
static_cast<const CameraProvider*>(callbacks));
+ bool found = false;
if (cp == nullptr) {
ALOGE("%s: callback ops is null", __FUNCTION__);
@@ -92,8 +133,13 @@
if (cameraIdStr.compare(deviceNamePair.first) == 0) {
cp->mCallbacks->cameraDeviceStatusChange(
deviceNamePair.second, status);
+ found = true;
}
}
+
+ if (!found) {
+ cp->addDeviceNames(camera_id, status, true);
+ }
}
}
@@ -251,32 +297,8 @@
snprintf(cameraId, sizeof(cameraId), "%d", i);
std::string cameraIdStr(cameraId);
mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;
- mCameraIds.add(cameraIdStr);
- // initialize mCameraDeviceNames and mOpenLegacySupported
- mOpenLegacySupported[cameraIdStr] = false;
- int deviceVersion = mModule->getDeviceVersion(i);
- mCameraDeviceNames.add(
- std::make_pair(cameraIdStr,
- getHidlDeviceName(cameraIdStr, deviceVersion)));
- if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_2 &&
- mModule->isOpenLegacyDefined()) {
- // try open_legacy to see if it actually works
- struct hw_device_t* halDev = nullptr;
- int ret = mModule->openLegacy(cameraId, CAMERA_DEVICE_API_VERSION_1_0, &halDev);
- if (ret == 0) {
- mOpenLegacySupported[cameraIdStr] = true;
- halDev->close(halDev);
- mCameraDeviceNames.add(
- std::make_pair(cameraIdStr,
- getHidlDeviceName(cameraIdStr, CAMERA_DEVICE_API_VERSION_1_0)));
- } else if (ret == -EBUSY || ret == -EUSERS) {
- // Looks like this provider instance is not initialized during
- // system startup and there are other camera users already.
- // Not a good sign but not fatal.
- ALOGW("%s: open_legacy try failed!", __FUNCTION__);
- }
- }
+ addDeviceNames(i);
}
return false; // mInitFailed
diff --git a/camera/provider/2.4/default/CameraProvider.h b/camera/provider/2.4/default/CameraProvider.h
index 4980711..2cf251e 100644
--- a/camera/provider/2.4/default/CameraProvider.h
+++ b/camera/provider/2.4/default/CameraProvider.h
@@ -112,6 +112,9 @@
const struct camera_module_callbacks* callbacks,
const char* camera_id,
int new_status);
+
+ void addDeviceNames(int camera_id, CameraDeviceStatus status = CameraDeviceStatus::PRESENT,
+ bool cam_new = false);
};
extern "C" ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name);
diff --git a/health/2.0/IHealthInfoCallback.hal b/health/2.0/IHealthInfoCallback.hal
index 737ea72..15352ee 100644
--- a/health/2.0/IHealthInfoCallback.hal
+++ b/health/2.0/IHealthInfoCallback.hal
@@ -16,8 +16,6 @@
package android.hardware.health@2.0;
-import @1.0::HealthInfo;
-
/**
* IHealthInfoCallback is the callback interface to
* {@link IHealthInfoBus.registerCallback}.
@@ -28,5 +26,5 @@
* registered callbacks after health info changes.
* @param info the updated HealthInfo
*/
- oneway healthInfoChanged(@1.0::HealthInfo info);
+ oneway healthInfoChanged(HealthInfo info);
};
diff --git a/health/2.0/default/Health.cpp b/health/2.0/default/Health.cpp
index b1227a3..7a3e650 100644
--- a/health/2.0/default/Health.cpp
+++ b/health/2.0/default/Health.cpp
@@ -155,10 +155,28 @@
return Result::SUCCESS;
}
-void Health::notifyListeners(const HealthInfo& info) {
+void Health::notifyListeners(HealthInfo* healthInfo) {
+ std::vector<StorageInfo> info;
+ get_storage_info(info);
+
+ std::vector<DiskStats> stats;
+ get_disk_stats(stats);
+
+ int32_t currentAvg = 0;
+
+ struct BatteryProperty prop;
+ status_t ret = battery_monitor_->getProperty(BATTERY_PROP_CURRENT_AVG, &prop);
+ if (ret == OK) {
+ currentAvg = static_cast<int32_t>(prop.valueInt64);
+ }
+
+ healthInfo->batteryCurrentAverage = currentAvg;
+ healthInfo->diskStats = stats;
+ healthInfo->storageInfos = info;
+
std::lock_guard<std::mutex> _lock(callbacks_lock_);
for (auto it = callbacks_.begin(); it != callbacks_.end();) {
- auto ret = (*it)->healthInfoChanged(info);
+ auto ret = (*it)->healthInfoChanged(*healthInfo);
if (!ret.isOk() && ret.isDeadObject()) {
it = callbacks_.erase(it);
} else {
diff --git a/health/2.0/default/include/health2/Health.h b/health/2.0/default/include/health2/Health.h
index fc86789..134cdc6 100644
--- a/health/2.0/default/include/health2/Health.h
+++ b/health/2.0/default/include/health2/Health.h
@@ -22,7 +22,6 @@
namespace implementation {
using V1_0::BatteryStatus;
-using V1_0::HealthInfo;
using ::android::hidl::base::V1_0::IBase;
@@ -38,7 +37,7 @@
Health(struct healthd_config* c);
// TODO(b/62229583): clean up and hide these functions after update() logic is simplified.
- void notifyListeners(const HealthInfo& info);
+ void notifyListeners(HealthInfo* info);
// Methods from IHealth follow.
Return<Result> registerCallback(const sp<IHealthInfoCallback>& callback) override;
diff --git a/health/2.0/libhealthhalutils/Android.bp b/health/2.0/libhealthhalutils/Android.bp
index 1bd934b..5686520 100644
--- a/health/2.0/libhealthhalutils/Android.bp
+++ b/health/2.0/libhealthhalutils/Android.bp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+// Convenience library for (hwbinder) clients to choose the correct health
+// service instance.
cc_library_static {
name: "libhealthhalutils",
srcs: ["HealthHalUtils.cpp"],
diff --git a/health/2.0/libstoragehealthdefault/Android.bp b/health/2.0/libstoragehealthdefault/Android.bp
index 986e1ef..cef04fe 100644
--- a/health/2.0/libstoragehealthdefault/Android.bp
+++ b/health/2.0/libstoragehealthdefault/Android.bp
@@ -1,5 +1,22 @@
-// Copyright 2018 The Android Open Source Project
+/*
+ * 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.
+ */
+// Default implementation for (passthrough) clients that statically links to
+// android.hardware.health@2.0-impl but do no query for storage related
+// information.
cc_library_static {
srcs: ["StorageHealthDefault.cpp"],
name: "libhealthstoragedefault",
diff --git a/health/2.0/types.hal b/health/2.0/types.hal
index c74076e..fe33c88 100644
--- a/health/2.0/types.hal
+++ b/health/2.0/types.hal
@@ -141,7 +141,7 @@
/**
* Average battery current in uA. Will be 0 if unsupported.
*/
- int64_t batteryCurrentAverage;
+ int32_t batteryCurrentAverage;
/**
* Disk Statistics. Will be an empty vector if unsupported.
*/
diff --git a/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp b/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp
index 85dab44..972bc7f 100644
--- a/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp
+++ b/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp
@@ -68,7 +68,7 @@
class Callback : public IHealthInfoCallback {
public:
- Return<void> healthInfoChanged(const V1_0::HealthInfo&) override {
+ Return<void> healthInfoChanged(const HealthInfo&) override {
std::lock_guard<std::mutex> lock(mMutex);
mInvoked = true;
mInvokedNotify.notify_all();
diff --git a/keymaster/4.0/support/Android.bp b/keymaster/4.0/support/Android.bp
index 748fed3..6b8dcdc 100644
--- a/keymaster/4.0/support/Android.bp
+++ b/keymaster/4.0/support/Android.bp
@@ -26,11 +26,18 @@
"attestation_record.cpp",
"authorization_set.cpp",
"key_param_output.cpp",
+ "Keymaster3.cpp",
+ "Keymaster4.cpp",
],
export_include_dirs: ["include"],
shared_libs: [
+ "android.hardware.keymaster@3.0",
"android.hardware.keymaster@4.0",
+ "libbase",
"libcrypto",
+ "libhardware",
"libhidlbase",
+ "libhidltransport",
+ "libutils",
]
}
diff --git a/keymaster/4.0/support/Keymaster3.cpp b/keymaster/4.0/support/Keymaster3.cpp
new file mode 100644
index 0000000..6dfe85b
--- /dev/null
+++ b/keymaster/4.0/support/Keymaster3.cpp
@@ -0,0 +1,325 @@
+/*
+ **
+ ** Copyright 2017, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+#include <keymasterV4_0/Keymaster3.h>
+
+#include <android-base/logging.h>
+#include <hardware/hw_auth_token.h>
+
+namespace android {
+namespace hardware {
+namespace keymaster {
+namespace V4_0 {
+namespace support {
+
+using android::hardware::details::StatusOf;
+
+namespace {
+
+ErrorCode convert(V3_0::ErrorCode error) {
+ return static_cast<ErrorCode>(error);
+}
+
+V3_0::KeyPurpose convert(KeyPurpose purpose) {
+ return static_cast<V3_0::KeyPurpose>(purpose);
+}
+
+V3_0::KeyFormat convert(KeyFormat purpose) {
+ return static_cast<V3_0::KeyFormat>(purpose);
+}
+
+V3_0::KeyParameter convert(const KeyParameter& param) {
+ V3_0::KeyParameter converted;
+ converted.tag = static_cast<V3_0::Tag>(param.tag);
+ static_assert(sizeof(converted.f) == sizeof(param.f), "This function assumes sizes match");
+ memcpy(&converted.f, ¶m.f, sizeof(param.f));
+ converted.blob = param.blob;
+ return converted;
+}
+
+KeyParameter convert(const V3_0::KeyParameter& param) {
+ KeyParameter converted;
+ converted.tag = static_cast<Tag>(param.tag);
+ static_assert(sizeof(converted.f) == sizeof(param.f), "This function assumes sizes match");
+ memcpy(&converted.f, ¶m.f, sizeof(param.f));
+ converted.blob = param.blob;
+ return converted;
+}
+
+hidl_vec<V3_0::KeyParameter> convert(const hidl_vec<KeyParameter>& params) {
+ hidl_vec<V3_0::KeyParameter> converted(params.size());
+ for (size_t i = 0; i < params.size(); ++i) {
+ converted[i] = convert(params[i]);
+ }
+ return converted;
+}
+
+hidl_vec<KeyParameter> convert(const hidl_vec<V3_0::KeyParameter>& params) {
+ hidl_vec<KeyParameter> converted(params.size());
+ for (size_t i = 0; i < params.size(); ++i) {
+ converted[i] = convert(params[i]);
+ }
+ return converted;
+}
+
+template <typename T, typename OutIter>
+inline static OutIter copy_bytes_to_iterator(const T& value, OutIter dest) {
+ const uint8_t* value_ptr = reinterpret_cast<const uint8_t*>(&value);
+ return std::copy(value_ptr, value_ptr + sizeof(value), dest);
+}
+
+constexpr size_t kHmacSize = 32;
+
+inline static hidl_vec<uint8_t> authToken2HidlVec(const HardwareAuthToken& token) {
+ static_assert(1 /* version size */ + sizeof(token.challenge) + sizeof(token.userId) +
+ sizeof(token.authenticatorId) + sizeof(token.authenticatorType) +
+ sizeof(token.timestamp) + kHmacSize ==
+ sizeof(hw_auth_token_t),
+ "HardwareAuthToken content size does not match hw_auth_token_t size");
+
+ hidl_vec<uint8_t> result;
+ result.resize(sizeof(hw_auth_token_t));
+ auto pos = result.begin();
+ *pos++ = 0; // Version byte
+ pos = copy_bytes_to_iterator(token.challenge, pos);
+ pos = copy_bytes_to_iterator(token.userId, pos);
+ pos = copy_bytes_to_iterator(token.authenticatorId, pos);
+ auto auth_type = htonl(static_cast<uint32_t>(token.authenticatorType));
+ pos = copy_bytes_to_iterator(auth_type, pos);
+ auto timestamp = htonq(token.timestamp);
+ pos = copy_bytes_to_iterator(timestamp, pos);
+ if (token.mac.size() != kHmacSize) {
+ std::fill(pos, pos + kHmacSize, 0);
+ } else {
+ std::copy(token.mac.begin(), token.mac.end(), pos);
+ }
+
+ return result;
+}
+
+hidl_vec<V3_0::KeyParameter> convertAndAddAuthToken(const hidl_vec<KeyParameter>& params,
+ const HardwareAuthToken& authToken) {
+ hidl_vec<V3_0::KeyParameter> converted(params.size() + 1);
+ for (size_t i = 0; i < params.size(); ++i) {
+ converted[i] = convert(params[i]);
+ }
+ converted[params.size()].tag = V3_0::Tag::AUTH_TOKEN;
+ converted[params.size()].blob = authToken2HidlVec(authToken);
+
+ return converted;
+}
+
+KeyCharacteristics convert(const V3_0::KeyCharacteristics& chars) {
+ KeyCharacteristics converted;
+ converted.hardwareEnforced = convert(chars.teeEnforced);
+ converted.softwareEnforced = convert(chars.softwareEnforced);
+ return converted;
+}
+
+} // namespace
+
+void Keymaster3::getVersionIfNeeded() {
+ if (haveVersion_) return;
+
+ auto rc = km3_dev_->getHardwareFeatures(
+ [&](bool isSecure, bool supportsEllipticCurve, bool supportsSymmetricCryptography,
+ bool supportsAttestation, bool supportsAllDigests, const hidl_string& keymasterName,
+ const hidl_string& keymasterAuthorName) {
+ securityLevel_ =
+ isSecure ? SecurityLevel::TRUSTED_ENVIRONMENT : SecurityLevel::SOFTWARE;
+ supportsEllipticCurve_ = supportsEllipticCurve;
+ supportsSymmetricCryptography_ = supportsSymmetricCryptography;
+ supportsAttestation_ = supportsAttestation;
+ supportsAllDigests_ = supportsAllDigests;
+ keymasterName_ = keymasterName;
+ authorName_ = keymasterAuthorName;
+ });
+
+ CHECK(rc.isOk()) << "Got error " << rc.description() << " trying to get hardware features";
+
+ if (securityLevel_ == SecurityLevel::SOFTWARE) {
+ majorVersion_ = 3;
+ } else if (supportsAttestation_) {
+ majorVersion_ = 3; // Could be 2, doesn't matter.
+ } else if (supportsSymmetricCryptography_) {
+ majorVersion_ = 1;
+ } else {
+ majorVersion_ = 0;
+ }
+}
+
+Keymaster::VersionResult Keymaster3::halVersion() {
+ getVersionIfNeeded();
+ return {ErrorCode::OK, majorVersion_, securityLevel_, supportsEllipticCurve_};
+}
+
+Return<void> Keymaster3::getHardwareInfo(Keymaster3::getHardwareInfo_cb _hidl_cb) {
+ getVersionIfNeeded();
+ _hidl_cb(securityLevel_, keymasterName_ + " (wrapped by keystore::Keymaster3)", authorName_);
+ return Void();
+}
+
+Return<ErrorCode> Keymaster3::addRngEntropy(const hidl_vec<uint8_t>& data) {
+ auto rc = km3_dev_->addRngEntropy(data);
+ if (!rc.isOk()) {
+ return StatusOf<V3_0::ErrorCode, ErrorCode>(rc);
+ }
+ return convert(rc);
+}
+
+Return<void> Keymaster3::generateKey(const hidl_vec<KeyParameter>& keyParams,
+ generateKey_cb _hidl_cb) {
+ auto cb = [&](V3_0::ErrorCode error, const hidl_vec<uint8_t>& keyBlob,
+ const V3_0::KeyCharacteristics& characteristics) {
+ _hidl_cb(convert(error), keyBlob, convert(characteristics));
+ };
+ auto rc = km3_dev_->generateKey(convert(keyParams), cb);
+ rc.isOk(); // move ctor prereq
+ return rc;
+}
+
+Return<void> Keymaster3::getKeyCharacteristics(const hidl_vec<uint8_t>& keyBlob,
+ const hidl_vec<uint8_t>& clientId,
+ const hidl_vec<uint8_t>& appData,
+ getKeyCharacteristics_cb _hidl_cb) {
+ auto cb = [&](V3_0::ErrorCode error, const V3_0::KeyCharacteristics& chars) {
+ _hidl_cb(convert(error), convert(chars));
+ };
+
+ auto rc = km3_dev_->getKeyCharacteristics(keyBlob, clientId, appData, cb);
+ rc.isOk(); // move ctor prereq
+ return rc;
+}
+
+Return<void> Keymaster3::importKey(const hidl_vec<KeyParameter>& params, KeyFormat keyFormat,
+ const hidl_vec<uint8_t>& keyData, importKey_cb _hidl_cb) {
+ auto cb = [&](V3_0::ErrorCode error, const hidl_vec<uint8_t>& keyBlob,
+ const V3_0::KeyCharacteristics& chars) {
+ _hidl_cb(convert(error), keyBlob, convert(chars));
+ };
+ auto rc = km3_dev_->importKey(convert(params), convert(keyFormat), keyData, cb);
+ rc.isOk(); // move ctor prereq
+ return rc;
+}
+
+Return<void> Keymaster3::exportKey(KeyFormat exportFormat, const hidl_vec<uint8_t>& keyBlob,
+ const hidl_vec<uint8_t>& clientId,
+ const hidl_vec<uint8_t>& appData, exportKey_cb _hidl_cb) {
+ auto cb = [&](V3_0::ErrorCode error, const hidl_vec<uint8_t>& keyMaterial) {
+ _hidl_cb(convert(error), keyMaterial);
+ };
+ auto rc = km3_dev_->exportKey(convert(exportFormat), keyBlob, clientId, appData, cb);
+ rc.isOk(); // move ctor prereq
+ return rc;
+}
+
+Return<void> Keymaster3::attestKey(const hidl_vec<uint8_t>& keyToAttest,
+ const hidl_vec<KeyParameter>& attestParams,
+ attestKey_cb _hidl_cb) {
+ auto cb = [&](V3_0::ErrorCode error, const hidl_vec<hidl_vec<uint8_t>>& certChain) {
+ _hidl_cb(convert(error), certChain);
+ };
+ auto rc = km3_dev_->attestKey(keyToAttest, convert(attestParams), cb);
+ rc.isOk(); // move ctor prereq
+ return rc;
+}
+
+Return<void> Keymaster3::upgradeKey(const hidl_vec<uint8_t>& keyBlobToUpgrade,
+ const hidl_vec<KeyParameter>& upgradeParams,
+ upgradeKey_cb _hidl_cb) {
+ auto cb = [&](V3_0::ErrorCode error, const hidl_vec<uint8_t>& upgradedKeyBlob) {
+ _hidl_cb(convert(error), upgradedKeyBlob);
+ };
+ auto rc = km3_dev_->upgradeKey(keyBlobToUpgrade, convert(upgradeParams), cb);
+ rc.isOk(); // move ctor prereq
+ return rc;
+}
+
+Return<ErrorCode> Keymaster3::deleteKey(const hidl_vec<uint8_t>& keyBlob) {
+ auto rc = km3_dev_->deleteKey(keyBlob);
+ if (!rc.isOk()) return StatusOf<V3_0::ErrorCode, ErrorCode>(rc);
+ return convert(rc);
+}
+
+Return<ErrorCode> Keymaster3::deleteAllKeys() {
+ auto rc = km3_dev_->deleteAllKeys();
+ if (!rc.isOk()) return StatusOf<V3_0::ErrorCode, ErrorCode>(rc);
+ return convert(rc);
+}
+
+Return<ErrorCode> Keymaster3::destroyAttestationIds() {
+ auto rc = km3_dev_->destroyAttestationIds();
+ if (!rc.isOk()) return StatusOf<V3_0::ErrorCode, ErrorCode>(rc);
+ return convert(rc);
+}
+
+Return<void> Keymaster3::begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
+ const hidl_vec<KeyParameter>& inParams,
+ const HardwareAuthToken& authToken, begin_cb _hidl_cb) {
+ auto cb = [&](V3_0::ErrorCode error, const hidl_vec<V3_0::KeyParameter>& outParams,
+ OperationHandle operationHandle) {
+ _hidl_cb(convert(error), convert(outParams), operationHandle);
+ };
+
+ auto rc =
+ km3_dev_->begin(convert(purpose), key, convertAndAddAuthToken(inParams, authToken), cb);
+ rc.isOk(); // move ctor prereq
+ return rc;
+}
+
+Return<void> Keymaster3::update(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
+ const hidl_vec<uint8_t>& input, const HardwareAuthToken& authToken,
+ const VerificationToken& /* verificationToken */,
+ update_cb _hidl_cb) {
+ auto cb = [&](V3_0::ErrorCode error, uint32_t inputConsumed,
+ const hidl_vec<V3_0::KeyParameter>& outParams, const hidl_vec<uint8_t>& output) {
+ _hidl_cb(convert(error), inputConsumed, convert(outParams), output);
+ };
+
+ auto rc =
+ km3_dev_->update(operationHandle, convertAndAddAuthToken(inParams, authToken), input, cb);
+ rc.isOk(); // move ctor prereq
+ return rc;
+}
+
+Return<void> Keymaster3::finish(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
+ const hidl_vec<uint8_t>& input, const hidl_vec<uint8_t>& signature,
+ const HardwareAuthToken& authToken,
+ const VerificationToken& /* verificationToken */,
+ finish_cb _hidl_cb) {
+ auto cb = [&](V3_0::ErrorCode error, const hidl_vec<V3_0::KeyParameter>& outParams,
+ const hidl_vec<uint8_t>& output) {
+ _hidl_cb(convert(error), convert(outParams), output);
+ };
+
+ auto rc = km3_dev_->finish(operationHandle, convertAndAddAuthToken(inParams, authToken), input,
+ signature, cb);
+ rc.isOk(); // move ctor prereq
+ return rc;
+}
+
+Return<ErrorCode> Keymaster3::abort(uint64_t operationHandle) {
+ auto rc = km3_dev_->abort(operationHandle);
+ if (!rc.isOk()) return StatusOf<V3_0::ErrorCode, ErrorCode>(rc);
+ return convert(rc);
+}
+
+} // namespace support
+} // namespace V4_0
+} // namespace keymaster
+} // namespace hardware
+} // namespace android
diff --git a/keymaster/4.0/support/Keymaster4.cpp b/keymaster/4.0/support/Keymaster4.cpp
new file mode 100644
index 0000000..fdf78ae
--- /dev/null
+++ b/keymaster/4.0/support/Keymaster4.cpp
@@ -0,0 +1,48 @@
+/*
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include <keymasterV4_0/Keymaster4.h>
+
+#include <android-base/logging.h>
+
+namespace android {
+namespace hardware {
+namespace keymaster {
+namespace V4_0 {
+namespace support {
+
+void Keymaster4::getVersionIfNeeded() {
+ if (haveVersion_) return;
+
+ auto rc = dev_->getHardwareInfo([&](SecurityLevel securityLevel, auto...) {
+ securityLevel_ = securityLevel;
+ haveVersion_ = true;
+ });
+
+ CHECK(rc.isOk()) << "Got error " << rc.description() << " trying to get hardware info";
+}
+
+Keymaster::VersionResult Keymaster4::halVersion() {
+ getVersionIfNeeded();
+ return {ErrorCode::OK, halMajorVersion(), securityLevel_, true};
+}
+
+} // namespace support
+} // namespace V4_0
+} // namespace keymaster
+} // namespace hardware
+} // namespace android
diff --git a/keymaster/4.0/support/include/keymasterV4_0/Keymaster.h b/keymaster/4.0/support/include/keymasterV4_0/Keymaster.h
new file mode 100644
index 0000000..2686fcd
--- /dev/null
+++ b/keymaster/4.0/support/include/keymasterV4_0/Keymaster.h
@@ -0,0 +1,58 @@
+/*
+ **
+ ** Copyright 2017, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+#ifndef HARDWARE_INTERFACES_KEYMASTER_40_SUPPORT_KEYMASTER_H_
+#define HARDWARE_INTERFACES_KEYMASTER_40_SUPPORT_KEYMASTER_H_
+
+#include <android/hardware/keymaster/4.0/IKeymasterDevice.h>
+
+namespace android {
+namespace hardware {
+namespace keymaster {
+namespace V4_0 {
+namespace support {
+
+/**
+ * Keymaster abstracts the underlying V4_0::IKeymasterDevice. There is one implementation
+ * (Keymaster4) which is a trivial passthrough and one that wraps a V3_0::IKeymasterDevice.
+ *
+ * The reason for adding this additional layer, rather than simply using the latest HAL directly and
+ * subclassing it to wrap any older HAL, is because this provides a place to put additional methods
+ * which clients can use when they need to distinguish between different underlying HAL versions,
+ * while still having to use only the latest interface.
+ */
+class Keymaster : public IKeymasterDevice {
+ public:
+ virtual ~Keymaster() {}
+
+ struct VersionResult {
+ ErrorCode error;
+ uint8_t majorVersion;
+ SecurityLevel securityLevel;
+ bool supportsEc;
+ };
+
+ virtual VersionResult halVersion() = 0;
+};
+
+} // namespace support
+} // namespace V4_0
+} // namespace keymaster
+} // namespace hardware
+} // namespace android
+
+#endif // HARDWARE_INTERFACES_KEYMASTER_40_SUPPORT_KEYMASTER_H_
diff --git a/keymaster/4.0/support/include/keymasterV4_0/Keymaster3.h b/keymaster/4.0/support/include/keymasterV4_0/Keymaster3.h
new file mode 100644
index 0000000..051e570
--- /dev/null
+++ b/keymaster/4.0/support/include/keymasterV4_0/Keymaster3.h
@@ -0,0 +1,129 @@
+/*
+ **
+ ** Copyright 2017, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+#ifndef HARDWARE_INTERFACES_KEYMASTER_40_SUPPORT_KEYMASTER_3_H_
+#define HARDWARE_INTERFACES_KEYMASTER_40_SUPPORT_KEYMASTER_3_H_
+
+#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
+
+#include "Keymaster.h"
+
+namespace android {
+namespace hardware {
+namespace keymaster {
+namespace V4_0 {
+namespace support {
+
+using IKeymaster3Device = ::android::hardware::keymaster::V3_0::IKeymasterDevice;
+
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::details::return_status;
+
+class Keymaster3 : public Keymaster {
+ public:
+ using WrappedIKeymasterDevice = IKeymaster3Device;
+ Keymaster3(sp<IKeymaster3Device> km3_dev) : km3_dev_(km3_dev), haveVersion_(false) {}
+
+ VersionResult halVersion() override;
+
+ Return<void> getHardwareInfo(getHardwareInfo_cb _hidl_cb);
+
+ Return<void> getHmacSharingParameters(getHmacSharingParameters_cb _hidl_cb) override {
+ _hidl_cb(ErrorCode::UNIMPLEMENTED, {});
+ return Void();
+ }
+
+ Return<void> computeSharedHmac(const hidl_vec<HmacSharingParameters>&,
+ computeSharedHmac_cb _hidl_cb) override {
+ _hidl_cb(ErrorCode::UNIMPLEMENTED, {});
+ return Void();
+ }
+
+ Return<void> verifyAuthorization(uint64_t, const hidl_vec<KeyParameter>&,
+ const HardwareAuthToken&,
+ verifyAuthorization_cb _hidl_cb) override {
+ _hidl_cb(ErrorCode::UNIMPLEMENTED, {});
+ return Void();
+ }
+
+ Return<ErrorCode> addRngEntropy(const hidl_vec<uint8_t>& data) override;
+ Return<void> generateKey(const hidl_vec<KeyParameter>& keyParams,
+ generateKey_cb _hidl_cb) override;
+ Return<void> getKeyCharacteristics(const hidl_vec<uint8_t>& keyBlob,
+ const hidl_vec<uint8_t>& clientId,
+ const hidl_vec<uint8_t>& appData,
+ getKeyCharacteristics_cb _hidl_cb) override;
+ Return<void> importKey(const hidl_vec<KeyParameter>& params, KeyFormat keyFormat,
+ const hidl_vec<uint8_t>& keyData, importKey_cb _hidl_cb) override;
+
+ Return<void> importWrappedKey(const hidl_vec<uint8_t>&, const hidl_vec<uint8_t>&,
+ const hidl_vec<uint8_t>&, importWrappedKey_cb _hidl_cb) {
+ _hidl_cb(ErrorCode::UNIMPLEMENTED, {}, {});
+ return Void();
+ }
+
+ Return<void> exportKey(KeyFormat exportFormat, const hidl_vec<uint8_t>& keyBlob,
+ const hidl_vec<uint8_t>& clientId, const hidl_vec<uint8_t>& appData,
+ exportKey_cb _hidl_cb) override;
+ Return<void> attestKey(const hidl_vec<uint8_t>& keyToAttest,
+ const hidl_vec<KeyParameter>& attestParams,
+ attestKey_cb _hidl_cb) override;
+ Return<void> upgradeKey(const hidl_vec<uint8_t>& keyBlobToUpgrade,
+ const hidl_vec<KeyParameter>& upgradeParams,
+ upgradeKey_cb _hidl_cb) override;
+ Return<ErrorCode> deleteKey(const hidl_vec<uint8_t>& keyBlob) override;
+ Return<ErrorCode> deleteAllKeys() override;
+ Return<ErrorCode> destroyAttestationIds() override;
+ Return<void> begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
+ const hidl_vec<KeyParameter>& inParams, const HardwareAuthToken& authToken,
+ begin_cb _hidl_cb) override;
+ Return<void> update(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
+ const hidl_vec<uint8_t>& input, const HardwareAuthToken& authToken,
+ const VerificationToken& verificationToken, update_cb _hidl_cb) override;
+ Return<void> finish(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
+ const hidl_vec<uint8_t>& input, const hidl_vec<uint8_t>& signature,
+ const HardwareAuthToken& authToken,
+ const VerificationToken& verificationToken, finish_cb _hidl_cb) override;
+ Return<ErrorCode> abort(uint64_t operationHandle) override;
+
+ private:
+ void getVersionIfNeeded();
+
+ sp<IKeymaster3Device> km3_dev_;
+
+ bool haveVersion_;
+ uint8_t majorVersion_;
+ SecurityLevel securityLevel_;
+ bool supportsEllipticCurve_;
+ bool supportsSymmetricCryptography_;
+ bool supportsAttestation_;
+ bool supportsAllDigests_;
+ std::string keymasterName_;
+ std::string authorName_;
+};
+
+} // namespace support
+} // namespace V4_0
+} // namespace keymaster
+} // namespace hardware
+} // namespace android
+
+#endif // HARDWARE_INTERFACES_KEYMASTER_40_SUPPORT_KEYMASTER_3_H_
diff --git a/keymaster/4.0/support/include/keymasterV4_0/Keymaster4.h b/keymaster/4.0/support/include/keymasterV4_0/Keymaster4.h
new file mode 100644
index 0000000..ffddcac
--- /dev/null
+++ b/keymaster/4.0/support/include/keymasterV4_0/Keymaster4.h
@@ -0,0 +1,153 @@
+/*
+ **
+ ** Copyright 2017, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+#ifndef HARDWARE_INTERFACES_KEYMASTER_40_SUPPORT_KEYMASTER_4_H_
+#define HARDWARE_INTERFACES_KEYMASTER_40_SUPPORT_KEYMASTER_4_H_
+
+#include "Keymaster.h"
+
+namespace android {
+namespace hardware {
+namespace keymaster {
+namespace V4_0 {
+namespace support {
+
+using android::sp;
+using IKeymaster4Device = ::android::hardware::keymaster::V4_0::IKeymasterDevice;
+
+class Keymaster4 : public Keymaster {
+ public:
+ using WrappedIKeymasterDevice = IKeymaster4Device;
+ Keymaster4(sp<IKeymasterDevice> km4_dev) : haveVersion_(false), dev_(km4_dev) {}
+
+ uint8_t halMajorVersion() { return 4; }
+
+ VersionResult halVersion() override;
+
+ Return<void> getHardwareInfo(getHardwareInfo_cb _hidl_cb) override {
+ return dev_->getHardwareInfo(_hidl_cb);
+ }
+
+ Return<void> getHmacSharingParameters(getHmacSharingParameters_cb _hidl_cb) override {
+ return dev_->getHmacSharingParameters(_hidl_cb);
+ }
+
+ Return<void> computeSharedHmac(const hidl_vec<HmacSharingParameters>& params,
+ computeSharedHmac_cb _hidl_cb) override {
+ return dev_->computeSharedHmac(params, _hidl_cb);
+ }
+
+ Return<void> verifyAuthorization(uint64_t operationHandle, const hidl_vec<KeyParameter>& params,
+ const HardwareAuthToken& authToken,
+ verifyAuthorization_cb _hidl_cb) override {
+ return dev_->verifyAuthorization(operationHandle, params, authToken, _hidl_cb);
+ }
+
+ Return<ErrorCode> addRngEntropy(const hidl_vec<uint8_t>& data) override {
+ return dev_->addRngEntropy(data);
+ }
+
+ Return<void> generateKey(const hidl_vec<KeyParameter>& keyParams,
+ generateKey_cb _hidl_cb) override {
+ return dev_->generateKey(keyParams, _hidl_cb);
+ }
+
+ Return<void> getKeyCharacteristics(const hidl_vec<uint8_t>& keyBlob,
+ const hidl_vec<uint8_t>& clientId,
+ const hidl_vec<uint8_t>& appData,
+ getKeyCharacteristics_cb _hidl_cb) override {
+ return dev_->getKeyCharacteristics(keyBlob, clientId, appData, _hidl_cb);
+ }
+
+ Return<void> importKey(const hidl_vec<KeyParameter>& params, KeyFormat keyFormat,
+ const hidl_vec<uint8_t>& keyData, importKey_cb _hidl_cb) override {
+ return dev_->importKey(params, keyFormat, keyData, _hidl_cb);
+ }
+
+ Return<void> importWrappedKey(const hidl_vec<uint8_t>& wrappedKeyData,
+ const hidl_vec<uint8_t>& wrappingKeyBlob,
+ const hidl_vec<uint8_t>& maskingKey,
+ importWrappedKey_cb _hidl_cb) {
+ return dev_->importWrappedKey(wrappedKeyData, wrappingKeyBlob, maskingKey, _hidl_cb);
+ }
+
+ Return<void> exportKey(KeyFormat exportFormat, const hidl_vec<uint8_t>& keyBlob,
+ const hidl_vec<uint8_t>& clientId, const hidl_vec<uint8_t>& appData,
+ exportKey_cb _hidl_cb) override {
+ return dev_->exportKey(exportFormat, keyBlob, clientId, appData, _hidl_cb);
+ }
+
+ Return<void> attestKey(const hidl_vec<uint8_t>& keyToAttest,
+ const hidl_vec<KeyParameter>& attestParams,
+ attestKey_cb _hidl_cb) override {
+ return dev_->attestKey(keyToAttest, attestParams, _hidl_cb);
+ }
+
+ Return<void> upgradeKey(const hidl_vec<uint8_t>& keyBlobToUpgrade,
+ const hidl_vec<KeyParameter>& upgradeParams,
+ upgradeKey_cb _hidl_cb) override {
+ return dev_->upgradeKey(keyBlobToUpgrade, upgradeParams, _hidl_cb);
+ }
+
+ Return<ErrorCode> deleteKey(const hidl_vec<uint8_t>& keyBlob) override {
+ return dev_->deleteKey(keyBlob);
+ }
+
+ Return<ErrorCode> deleteAllKeys() override { return dev_->deleteAllKeys(); }
+
+ Return<ErrorCode> destroyAttestationIds() override { return dev_->destroyAttestationIds(); }
+
+ Return<void> begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
+ const hidl_vec<KeyParameter>& inParams, const HardwareAuthToken& authToken,
+ begin_cb _hidl_cb) override {
+ return dev_->begin(purpose, key, inParams, authToken, _hidl_cb);
+ }
+
+ Return<void> update(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
+ const hidl_vec<uint8_t>& input, const HardwareAuthToken& authToken,
+ const VerificationToken& verificationToken, update_cb _hidl_cb) override {
+ return dev_->update(operationHandle, inParams, input, authToken, verificationToken,
+ _hidl_cb);
+ }
+
+ Return<void> finish(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
+ const hidl_vec<uint8_t>& input, const hidl_vec<uint8_t>& signature,
+ const HardwareAuthToken& authToken,
+ const VerificationToken& verificationToken, finish_cb _hidl_cb) override {
+ return dev_->finish(operationHandle, inParams, input, signature, authToken,
+ verificationToken, _hidl_cb);
+ }
+
+ Return<ErrorCode> abort(uint64_t operationHandle) override {
+ return dev_->abort(operationHandle);
+ }
+
+ private:
+ void getVersionIfNeeded();
+
+ bool haveVersion_;
+ SecurityLevel securityLevel_;
+ sp<IKeymaster4Device> dev_;
+};
+
+} // namespace support
+} // namespace V4_0
+} // namespace keymaster
+} // namespace hardware
+} // namespace android
+
+#endif // HARDWARE_INTERFACES_KEYMASTER_40_SUPPORT_KEYMASTER_4_H_
diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
index 04b5829..b0bb68e 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -513,6 +513,26 @@
return ImportKey(key_desc, format, key_material, &key_blob_, &key_characteristics_);
}
+ ErrorCode ImportWrappedKey(string wrapped_key, string wrapping_key,
+ const AuthorizationSet& wrapping_key_desc, string masking_key) {
+ ErrorCode error;
+
+ ImportKey(wrapping_key_desc, KeyFormat::PKCS8, wrapping_key);
+
+ EXPECT_TRUE(keymaster_
+ ->importWrappedKey(HidlBuf(wrapped_key), key_blob_, HidlBuf(masking_key),
+ [&](ErrorCode hidl_error, const HidlBuf& hidl_key_blob,
+ const KeyCharacteristics& hidl_key_characteristics) {
+ error = hidl_error;
+ key_blob_ = hidl_key_blob;
+ key_characteristics_ = hidl_key_characteristics;
+
+ })
+ .isOk());
+
+ return error;
+ }
+
ErrorCode ExportKey(KeyFormat format, const HidlBuf& key_blob, const HidlBuf& client_id,
const HidlBuf& app_data, HidlBuf* key_material) {
ErrorCode error;
@@ -2487,6 +2507,111 @@
VerifyMessage(message, signature, AuthorizationSetBuilder().Digest(Digest::SHA_2_256));
}
+auto wrapped_key = hex2str(
+ "30820173020100048201006F5C273914D9E7EAB667FE62456A57DE64BED4A57DB3EFBB77E6907C82CC36B0BD12CB8A"
+ "85F3F8BC08A26C58186DB5C35636063388A04AE5579D3BDC057F9BB0EB6FDDA5E836DBB1F18A4546A64BA06E3D0132"
+ "AAA3306676638C786FAF0722E6E4145E0C91B009C422691F9F42F9F179DA93E16E7793DE5960E77A387433F0B43E49"
+ "3A7CF77ECA25BA724CC02F916D5792CAA76BC0756D3DB5D110D209B8B30285E9653D91FD89E953F351D82ACE1422CC"
+ "A146F8BD0C2F4CC32D1F81D894F4650043DB46109869696319A1A011BB003F2EBD8FA20B4A43F3226C1F182A39AE81"
+ "A35B9B7590A48B6A6874C9CC0EE0CD9528FB908688B4111932DF478CD7A92B50040CD796B02C370F1FA4CC0124F130"
+ "280201033023A1083106020100020101A203020120A30402020100A4053103020101A60531030201400420CCD54085"
+ "5F833A5E1480BFD2D36FAF3AEEE15DF5BEABE2691BC82DDE2A7AA91004107CB81BDDCD09E8F4DF575726279F3229");
+
+auto wrapped_key_masked = hex2str(
+ "30820173020100048201009059BB6E48F8036ABE1800D9C74F3DB5F20448F035C2C78AFBCC28AF26581061298CAC78"
+ "A8CA5B79721B60B74490555168488ED696C8930D00463C6FC81BF0B6E4E26C93E018D0E3DC8754C6B261E0A7C3A6DA"
+ "1A223EB59ACA8E13348F14B9E944AF3C224906C1ABFE21ADDEE81FC641D45E092C6B0A75A9BA56C05529AE47ECA0D5"
+ "CD3568501CF04D47391FC695EDE19A3022B347D1BDC6C792A08AA014F87DD4BBD44777B14D7D2273191DDCFE4E8512"
+ "EFA677A14E68E5D820C5513331D687C08B6317FA64D404231D05C74CDD9AEB89D253FBE07154B2080CF4ACA5E1EFCB"
+ "53EB193E8A01DD5F9634B65EF9B49899003E245FDA6A3B137FAC1263E55A6E1D040C6D9721D08589581AB49204A330"
+ "280201033023A1083106020100020101A203020120A30402020100A4053103020101A60531030201400420A61C6E24"
+ "7E25B3E6E69AA78EB03C2D4AC20D1F99A9A024A76F35C8E2CAB9B68D04101FF7A0E793B9EE4AECEBB9AC4C545254");
+
+auto wrapping_key = hex2str(
+ "308204be020100300d06092a864886f70d0101010500048204a8308204a40201000282010100aec367931d8900ce56"
+ "b0067f7d70e1fc653f3f34d194c1fed50018fb43db937b06e673a837313d56b1c725150a3fef86acbddc41bb759c28"
+ "54eae32d35841efb5c18d82bc90a1cb5c1d55adf245b02911f0b7cda88c421ff0ebafe7c0d23be312d7bd5921ffaea"
+ "1347c157406fef718f682643e4e5d33c6703d61c0cf7ac0bf4645c11f5c1374c3886427411c449796792e0bef75dec"
+ "858a2123c36753e02a95a96d7c454b504de385a642e0dfc3e60ac3a7ee4991d0d48b0172a95f9536f02ba13cecccb9"
+ "2b727db5c27e5b2f5cec09600b286af5cf14c42024c61ddfe71c2a8d7458f185234cb00e01d282f10f8fc6721d2aed"
+ "3f4833cca2bd8fa62821dd55020301000102820100431447b6251908112b1ee76f99f3711a52b6630960046c2de70d"
+ "e188d833f8b8b91e4d785caeeeaf4f0f74414e2cda40641f7fe24f14c67a88959bdb27766df9e710b630a03adc683b"
+ "5d2c43080e52bee71e9eaeb6de297a5fea1072070d181c822bccff087d63c940ba8a45f670feb29fb4484d1c95e6d2"
+ "579ba02aae0a00900c3ebf490e3d2cd7ee8d0e20c536e4dc5a5097272888cddd7e91f228b1c4d7474c55b8fcd618c4"
+ "a957bbddd5ad7407cc312d8d98a5caf7e08f4a0d6b45bb41c652659d5a5ba05b663737a8696281865ba20fbdd7f851"
+ "e6c56e8cbe0ddbbf24dc03b2d2cb4c3d540fb0af52e034a2d06698b128e5f101e3b51a34f8d8b4f8618102818100de"
+ "392e18d682c829266cc3454e1d6166242f32d9a1d10577753e904ea7d08bff841be5bac82a164c5970007047b8c517"
+ "db8f8f84e37bd5988561bdf503d4dc2bdb38f885434ae42c355f725c9a60f91f0788e1f1a97223b524b5357fdf72e2"
+ "f696bab7d78e32bf92ba8e1864eab1229e91346130748a6e3c124f9149d71c743502818100c95387c0f9d35f137b57"
+ "d0d65c397c5e21cc251e47008ed62a542409c8b6b6ac7f8967b3863ca645fcce49582a9aa17349db6c4a95affdae0d"
+ "ae612e1afac99ed39a2d934c880440aed8832f9843163a47f27f392199dc1202f9a0f9bd08308007cb1e4e7f583093"
+ "66a7de25f7c3c9b880677c068e1be936e81288815252a8a102818057ff8ca1895080b2cae486ef0adfd791fb0235c0"
+ "b8b36cd6c136e52e4085f4ea5a063212a4f105a3764743e53281988aba073f6e0027298e1c4378556e0efca0e14ece"
+ "1af76ad0b030f27af6f0ab35fb73a060d8b1a0e142fa2647e93b32e36d8282ae0a4de50ab7afe85500a16f43a64719"
+ "d6e2b9439823719cd08bcd03178102818100ba73b0bb28e3f81e9bd1c568713b101241acc607976c4ddccc90e65b65"
+ "56ca31516058f92b6e09f3b160ff0e374ec40d78ae4d4979fde6ac06a1a400c61dd31254186af30b22c10582a8a43e"
+ "34fe949c5f3b9755bae7baa7b7b7a6bd03b38cef55c86885fc6c1978b9cee7ef33da507c9df6b9277cff1e6aaa5d57"
+ "aca528466102818100c931617c77829dfb1270502be9195c8f2830885f57dba869536811e6864236d0c4736a0008a1"
+ "45af36b8357a7c3d139966d04c4e00934ea1aede3bb6b8ec841dc95e3f579751e2bfdfe27ae778983f959356210723"
+ "287b0affcc9f727044d48c373f1babde0724fa17a4fd4da0902c7c9b9bf27ba61be6ad02dfddda8f4e6822");
+
+string zero_masking_key =
+ hex2str("0000000000000000000000000000000000000000000000000000000000000000");
+string masking_key = hex2str("D796B02C370F1FA4CC0124F14EC8CBEBE987E825246265050F399A51FD477DFC");
+
+class ImportWrappedKeyTest : public KeymasterHidlTest {};
+
+TEST_F(ImportWrappedKeyTest, Success) {
+ auto wrapping_key_desc = AuthorizationSetBuilder()
+ .RsaEncryptionKey(2048, 65537)
+ .Digest(Digest::SHA1)
+ .Padding(PaddingMode::RSA_OAEP)
+ .Authorization(TAG_PURPOSE, KeyPurpose::WRAP_KEY);
+
+ ASSERT_EQ(ErrorCode::OK,
+ ImportWrappedKey(wrapped_key, wrapping_key, wrapping_key_desc, zero_masking_key));
+
+ string message = "Hello World!";
+ auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
+ string ciphertext = EncryptMessage(message, params);
+ string plaintext = DecryptMessage(ciphertext, params);
+ EXPECT_EQ(message, plaintext);
+}
+
+TEST_F(ImportWrappedKeyTest, SuccessMasked) {
+ auto wrapping_key_desc = AuthorizationSetBuilder()
+ .RsaEncryptionKey(2048, 65537)
+ .Digest(Digest::SHA1)
+ .Padding(PaddingMode::RSA_OAEP)
+ .Authorization(TAG_PURPOSE, KeyPurpose::WRAP_KEY);
+
+ ASSERT_EQ(ErrorCode::OK,
+ ImportWrappedKey(wrapped_key_masked, wrapping_key, wrapping_key_desc, masking_key));
+}
+
+TEST_F(ImportWrappedKeyTest, WrongMask) {
+ auto wrapping_key_desc = AuthorizationSetBuilder()
+ .RsaEncryptionKey(2048, 65537)
+ .Digest(Digest::SHA1)
+ .Padding(PaddingMode::RSA_OAEP)
+ .Authorization(TAG_PURPOSE, KeyPurpose::WRAP_KEY);
+
+ ASSERT_EQ(
+ ErrorCode::VERIFICATION_FAILED,
+ ImportWrappedKey(wrapped_key_masked, wrapping_key, wrapping_key_desc, zero_masking_key));
+}
+
+TEST_F(ImportWrappedKeyTest, WrongPurpose) {
+ auto wrapping_key_desc = AuthorizationSetBuilder()
+ .RsaEncryptionKey(2048, 65537)
+ .Digest(Digest::SHA1)
+ .Padding(PaddingMode::RSA_OAEP);
+
+ ASSERT_EQ(
+ ErrorCode::INCOMPATIBLE_PURPOSE,
+ ImportWrappedKey(wrapped_key_masked, wrapping_key, wrapping_key_desc, zero_masking_key));
+}
+
typedef KeymasterHidlTest EncryptionOperationsTest;
/*