fscrypt: Wrapped key support for FBE

Commit imported from:

https: //github.com/LineageOS/android_system_vold/commit/ce024f07c23d0649635a336fff389332b9806f48
Change-Id: I924a9fcbac7d790609fbafcf8c12654fdb267e32
diff --git a/crypto/fscrypt/Keymaster.cpp b/crypto/fscrypt/Keymaster.cpp
index aad4387..ab39ef8 100755
--- a/crypto/fscrypt/Keymaster.cpp
+++ b/crypto/fscrypt/Keymaster.cpp
@@ -138,6 +138,32 @@
     return true;
 }
 
+bool Keymaster::exportKey(km::KeyFormat format, KeyBuffer& kmKey, const std::string& clientId,
+                          const std::string& appData, std::string* key) {
+    auto kmKeyBlob = km::support::blob2hidlVec(std::string(kmKey.data(), kmKey.size()));
+    auto emptyAssign = NULL;
+    auto kmClientId = (clientId == "!") ? emptyAssign: km::support::blob2hidlVec(clientId);
+    auto kmAppData = (appData == "!") ? emptyAssign: km::support::blob2hidlVec(appData);
+    km::ErrorCode km_error;
+    auto hidlCb = [&](km::ErrorCode ret, const hidl_vec<uint8_t>& exportedKeyBlob) {
+        km_error = ret;
+        if (km_error != km::ErrorCode::OK) return;
+        if(key)
+            key->assign(reinterpret_cast<const char*>(&exportedKeyBlob[0]),
+                            exportedKeyBlob.size());
+    };
+    auto error = mDevice->exportKey(format, kmKeyBlob, kmClientId, kmAppData, hidlCb);
+    if (!error.isOk()) {
+        LOG(ERROR) << "export_key failed: " << error.description();
+        return false;
+    }
+    if (km_error != km::ErrorCode::OK) {
+        LOG(ERROR) << "export_key failed, code " << int32_t(km_error);
+        return false;
+    }
+    return true;
+}
+
 bool Keymaster::deleteKey(const std::string& key) {
     auto keyBlob = km::support::blob2hidlVec(key);
     auto error = mDevice->deleteKey(keyBlob);