keystore: add API to query storage type

Add an API to query the HAL to see what kind of storage it reports the
device is.

Change-Id: I37951e989ad724e2352df6e321f03f19e58b4fca
diff --git a/keystore/IKeystoreService.cpp b/keystore/IKeystoreService.cpp
index 0803071..520d266 100644
--- a/keystore/IKeystoreService.cpp
+++ b/keystore/IKeystoreService.cpp
@@ -510,6 +510,24 @@
         }
         return ret;
     }
+
+    virtual int32_t is_hardware_backed()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        status_t status = remote()->transact(BnKeystoreService::IS_HARDWARE_BACKED, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("is_hardware_backed() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("is_hardware_backed() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
 };
 
 IMPLEMENT_META_INTERFACE(KeystoreService, "android.security.keystore");
@@ -772,6 +790,13 @@
             reply->writeInt32(ret);
             return NO_ERROR;
         } break;
+        case IS_HARDWARE_BACKED: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            int32_t ret = is_hardware_backed();
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        }
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/keystore/include/keystore/IKeystoreService.h b/keystore/include/keystore/IKeystoreService.h
index 7659f47..6b2f406 100644
--- a/keystore/include/keystore/IKeystoreService.h
+++ b/keystore/include/keystore/IKeystoreService.h
@@ -50,6 +50,7 @@
         UNGRANT = IBinder::FIRST_CALL_TRANSACTION + 18,
         GETMTIME = IBinder::FIRST_CALL_TRANSACTION + 19,
         DUPLICATE = IBinder::FIRST_CALL_TRANSACTION + 20,
+        IS_HARDWARE_BACKED = IBinder::FIRST_CALL_TRANSACTION + 21,
     };
 
     DECLARE_META_INTERFACE(KeystoreService);
@@ -98,6 +99,8 @@
 
     virtual int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey,
             int32_t destUid) = 0;
+
+    virtual int32_t is_hardware_backed() = 0;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp
index 385f005..438a8e4 100644
--- a/keystore/keystore.cpp
+++ b/keystore/keystore.cpp
@@ -742,6 +742,10 @@
         return put(filename, &keyBlob);
     }
 
+    bool isHardwareBacked() const {
+        return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) != 0;
+    }
+
 private:
     static const char* MASTER_KEY_FILE;
     static const int MASTER_KEY_SIZE_BYTES = 16;
@@ -1648,6 +1652,10 @@
         return mKeyStore->put(target, &keyBlob);
     }
 
+    int32_t is_hardware_backed() {
+        return mKeyStore->isHardwareBacked() ? 1 : 0;
+    }
+
 private:
     inline bool isKeystoreUnlocked(State state) {
         switch (state) {