am cf0de02b: am 368a1f93: Merge "Store the key characteristics for operations"

* commit 'cf0de02b1530d8c219a5eda8f24a3114605c2dad':
  Store the key characteristics for operations
diff --git a/keystore/auth_token_table.h b/keystore/auth_token_table.h
index 7c18367..102e6e4 100644
--- a/keystore/auth_token_table.h
+++ b/keystore/auth_token_table.h
@@ -54,7 +54,6 @@
                                     // (e.g. new fingerprint enrolled).
         OP_HANDLE_REQUIRED = -4,    // The key requires auth per use but op_handle was zero.
         AUTH_TOKEN_NOT_FOUND = -5,
-        AUTH_BAD_PARAMS = -6,
     };
 
     /**
@@ -91,27 +90,6 @@
     }
 
     /**
-     * Find an authorization token that authorizes the operation specified by \p handle on
-     * a key with the characteristics specified in \p blob.
-     *
-     * The table retains ownership of the returned object.
-     */
-    Error FindAuthorization(const keymaster_key_blob_t& blob, keymaster_operation_handle_t handle,
-                            const hw_auth_token_t** found) {
-        KeyBlob key(blob);
-        if (key.error()) {
-            return AUTH_BAD_PARAMS;
-        }
-        AuthorizationSet auths(key.unenforced());
-        for (auto param : key.enforced()) {
-            auths.push_back(param);
-        }
-        return FindAuthorization(auths, handle, found);
-
-    }
-
-
-    /**
      * Mark operation completed.  This allows tokens associated with the specified operation to be
      * superseded by new tokens.
      */
diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp
index f1553cc..a65a34c 100644
--- a/keystore/keystore.cpp
+++ b/keystore/keystore.cpp
@@ -105,16 +105,6 @@
 };
 typedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;
 
-struct keymaster_key_blob_t_Delete {
-    void operator()(keymaster_key_blob_t* blob) const {
-        if (blob) {
-            delete[] blob->key_material;
-        }
-        delete blob;
-    }
-};
-typedef  UniquePtr<keymaster_key_blob_t, keymaster_key_blob_t_Delete> Unique_keymaster_key_blob;
-
 static int keymaster_device_initialize(keymaster0_device_t** dev) {
     int rc;
 
@@ -2722,16 +2712,24 @@
         return true;
     }
 
-    int authorizeOperation(const keymaster_key_blob_t& key,
+    int authorizeOperation(const keymaster_key_characteristics_t& characteristics,
                             keymaster_operation_handle_t handle,
                             std::vector<keymaster_key_param_t>* params,
                             bool failOnTokenMissing=true) {
         if (!checkAllowedOperationParams(*params)) {
             return KM_ERROR_INVALID_ARGUMENT;
         }
+        std::vector<keymaster_key_param_t> allCharacteristics;
+        for (size_t i = 0; i < characteristics.sw_enforced.length; i++) {
+            allCharacteristics.push_back(characteristics.sw_enforced.params[i]);
+        }
+        for (size_t i = 0; i < characteristics.hw_enforced.length; i++) {
+            allCharacteristics.push_back(characteristics.hw_enforced.params[i]);
+        }
         // Check for auth token and add it to the param list if present.
         const hw_auth_token_t* authToken;
-        switch (mAuthTokenTable.FindAuthorization(key, handle, &authToken)) {
+        switch (mAuthTokenTable.FindAuthorization(allCharacteristics.data(),
+                                                  allCharacteristics.size(), handle, &authToken)) {
         case keymaster::AuthTokenTable::OK:
             // Auth token found.
             params->push_back(keymaster_param_blob(KM_TAG_AUTH_TOKEN,
@@ -2756,6 +2754,36 @@
         return KM_ERROR_OK;
     }
 
+    keymaster_error_t getOperationCharacteristics(const keymaster_key_blob_t& key,
+                                    const keymaster1_device_t* dev,
+                                    const std::vector<keymaster_key_param_t>& params,
+                                    keymaster_key_characteristics_t* out) {
+        UniquePtr<keymaster_blob_t> appId;
+        UniquePtr<keymaster_blob_t> appData;
+        for (auto param : params) {
+            if (param.tag == KM_TAG_APPLICATION_ID) {
+                appId.reset(new keymaster_blob_t);
+                appId->data = param.blob.data;
+                appId->data_length = param.blob.data_length;
+            } else if (param.tag == KM_TAG_APPLICATION_DATA) {
+                appData.reset(new keymaster_blob_t);
+                appData->data = param.blob.data;
+                appData->data_length = param.blob.data_length;
+            }
+        }
+        keymaster_key_characteristics_t* result = NULL;
+        if (!dev->get_key_characteristics) {
+            return KM_ERROR_UNIMPLEMENTED;
+        }
+        keymaster_error_t error = dev->get_key_characteristics(dev, &key, appId.get(),
+                                                               appData.get(), &result);
+        if (result) {
+            *out = *result;
+            free(result);
+        }
+        return error;
+    }
+
     void begin(const sp<IBinder>& appToken, const String16& name, keymaster_purpose_t purpose,
                bool pruneable, const KeymasterArguments& params, const uint8_t* entropy,
                size_t entropyLength, KeymasterArguments* outParams, OperationResult* result) {
@@ -2786,10 +2814,17 @@
         keymaster1_device_t* dev = mKeyStore->getDeviceForBlob(keyBlob);
         keymaster_error_t err = KM_ERROR_UNIMPLEMENTED;
         std::vector<keymaster_key_param_t> opParams(params.params);
+        Unique_keymaster_key_characteristics characteristics;
+        characteristics.reset(new keymaster_key_characteristics_t);
+        err = getOperationCharacteristics(key, dev, opParams, characteristics.get());
+        if (err) {
+            result->resultCode = err;
+            return;
+        }
         // Don't require an auth token for the call to begin, authentication can
         // require an operation handle. Update and finish will require the token
         // be present and valid.
-        int32_t authResult = authorizeOperation(key, 0, &opParams,
+        int32_t authResult = authorizeOperation(*characteristics, 0, &opParams,
                                                 /*failOnTokenMissing*/ false);
         if (authResult) {
             result->resultCode = err;
@@ -2833,7 +2868,8 @@
             free(out);
         }
 
-        sp<IBinder> operationToken = mOperationMap.addOperation(handle, dev, appToken, key,
+        sp<IBinder> operationToken = mOperationMap.addOperation(handle, dev, appToken,
+                                                                characteristics.release(),
                                                                 pruneable);
         result->resultCode = ::NO_ERROR;
         result->token = operationToken;
@@ -2844,9 +2880,8 @@
                 size_t dataLength, OperationResult* result) {
         const keymaster1_device_t* dev;
         keymaster_operation_handle_t handle;
-        Unique_keymaster_key_blob key(new keymaster_key_blob_t);
-        *key = {NULL, 0};
-        if (!mOperationMap.getOperation(token, &handle, &dev, key.get())) {
+        const keymaster_key_characteristics_t* characteristics;
+        if (!mOperationMap.getOperation(token, &handle, &dev, &characteristics)) {
             result->resultCode = KM_ERROR_INVALID_OPERATION_HANDLE;
             return;
         }
@@ -2854,7 +2889,7 @@
         size_t output_length = 0;
         size_t consumed = 0;
         std::vector<keymaster_key_param_t> opParams(params.params);
-        int32_t authResult = authorizeOperation(*key, handle, &opParams);
+        int32_t authResult = authorizeOperation(*characteristics, handle, &opParams);
         if (authResult) {
             result->resultCode = authResult;
             return;
@@ -2871,16 +2906,15 @@
                 const uint8_t* signature, size_t signatureLength, OperationResult* result) {
         const keymaster1_device_t* dev;
         keymaster_operation_handle_t handle;
-        Unique_keymaster_key_blob key(new keymaster_key_blob_t);
-        *key = {NULL, 0};
-        if (!mOperationMap.getOperation(token, &handle, &dev, key.get())) {
+        const keymaster_key_characteristics_t* characteristics;
+        if (!mOperationMap.getOperation(token, &handle, &dev, &characteristics)) {
             result->resultCode = KM_ERROR_INVALID_OPERATION_HANDLE;
             return;
         }
         uint8_t* output_buf = NULL;
         size_t output_length = 0;
         std::vector<keymaster_key_param_t> opParams(params.params);
-        int32_t authResult = authorizeOperation(*key, handle, &opParams);
+        int32_t authResult = authorizeOperation(*characteristics, handle, &opParams);
         if (authResult) {
             result->resultCode = authResult;
             return;
@@ -2919,13 +2953,12 @@
     bool isOperationAuthorized(const sp<IBinder>& token) {
         const keymaster1_device_t* dev;
         keymaster_operation_handle_t handle;
-        Unique_keymaster_key_blob key(new keymaster_key_blob_t);
-        *key = {NULL, 0};
-        if(!mOperationMap.getOperation(token, &handle, &dev, key.get())) {
+        const keymaster_key_characteristics_t* characteristics;
+        if (!mOperationMap.getOperation(token, &handle, &dev, &characteristics)) {
             return false;
         }
         std::vector<keymaster_key_param_t> ignored;
-        int32_t authResult = authorizeOperation(*key, handle, &ignored);
+        int32_t authResult = authorizeOperation(*characteristics, handle, &ignored);
         return authResult == KM_ERROR_OK;
     }
 
diff --git a/keystore/operation.cpp b/keystore/operation.cpp
index 2fde0da..e871f83 100644
--- a/keystore/operation.cpp
+++ b/keystore/operation.cpp
@@ -27,9 +27,10 @@
 sp<IBinder> OperationMap::addOperation(keymaster_operation_handle_t handle,
                                        const keymaster1_device_t* dev,
                                        sp<IBinder> appToken,
-                                       const keymaster_key_blob_t& key, bool pruneable) {
+                                       keymaster_key_characteristics_t* characteristics,
+                                       bool pruneable) {
     sp<IBinder> token = new BBinder();
-    mMap[token] = Operation(handle, dev, key, appToken);
+    mMap[token] = std::move(Operation(handle, dev, characteristics, appToken));
     if (pruneable) {
         mLru.push_back(token);
     }
@@ -42,7 +43,7 @@
 
 bool OperationMap::getOperation(sp<IBinder> token, keymaster_operation_handle_t* outHandle,
                                 const keymaster1_device_t** outDevice,
-                                keymaster_key_blob_t* key) {
+                                const keymaster_key_characteristics_t** outCharacteristics) {
     if (!outHandle || !outDevice) {
         return false;
     }
@@ -54,12 +55,8 @@
 
     *outHandle = entry->second.handle;
     *outDevice = entry->second.device;
-    if (key) {
-        key->key_material_size = entry->second.key.key_material_size;
-        uint8_t* material = new uint8_t[key->key_material_size];
-        memcpy(reinterpret_cast<void*>(material), entry->second.key.key_material,
-               key->key_material_size);
-        key->key_material = material;
+    if (outCharacteristics) {
+        *outCharacteristics = entry->second.characteristics.get();
     }
     return true;
 }
@@ -78,7 +75,6 @@
         return false;
     }
     sp<IBinder> appToken = entry->second.appToken;
-    delete[] entry->second.key.key_material;
     mMap.erase(entry);
     auto lruEntry = std::find(mLru.begin(), mLru.end(), token);
     if (lruEntry != mLru.end()) {
@@ -125,19 +121,14 @@
 
 OperationMap::Operation::Operation(keymaster_operation_handle_t handle_,
                                    const keymaster1_device_t* device_,
-                                   const keymaster_key_blob_t& key_,
+                                   keymaster_key_characteristics_t* characteristics_,
                                    sp<IBinder> appToken_)
     : handle(handle_),
       device(device_),
+      characteristics(characteristics_),
       appToken(appToken_) {
-          uint8_t* material = new uint8_t[key_.key_material_size];
-          memcpy(material, key_.key_material, key_.key_material_size);
-          key.key_material = material;
-          key.key_material_size = key_.key_material_size;
 }
 
-OperationMap::Operation::Operation() : handle(0), device(NULL), appToken(NULL) {
-    key.key_material = NULL;
-    key.key_material_size = 0;
+OperationMap::Operation::Operation() : handle(0), device(NULL), characteristics(), appToken(NULL) {
 }
 } // namespace android
diff --git a/keystore/operation.h b/keystore/operation.h
index 6076836..a312528 100644
--- a/keystore/operation.h
+++ b/keystore/operation.h
@@ -27,6 +27,15 @@
 
 namespace android {
 
+struct keymaster_key_characteristics_t_Delete {
+    void operator()(keymaster_key_characteristics_t* characteristics) const {
+        keymaster_free_characteristics(characteristics);
+        delete characteristics;
+    }
+};
+typedef std::unique_ptr<keymaster_key_characteristics_t, keymaster_key_characteristics_t_Delete>
+    Unique_keymaster_key_characteristics;
+
 /**
  * OperationMap handles the translation of keymaster_operation_handle_t's and
  * keymaster1_device_t's to opaque binder tokens that can be used to reference
@@ -39,9 +48,10 @@
     OperationMap(IBinder::DeathRecipient* deathRecipient);
     sp<IBinder> addOperation(keymaster_operation_handle_t handle,
                              const keymaster1_device_t* dev, sp<IBinder> appToken,
-                             const keymaster_key_blob_t& key, bool pruneable);
+                             keymaster_key_characteristics_t* characteristics, bool pruneable);
     bool getOperation(sp<IBinder> token, keymaster_operation_handle_t* outHandle,
-                      const keymaster1_device_t** outDev, keymaster_key_blob_t* outKey);
+                      const keymaster1_device_t** outDev,
+                      const keymaster_key_characteristics_t** outCharacteristics);
     bool removeOperation(sp<IBinder> token);
     bool hasPruneableOperation();
     sp<IBinder> getOldestPruneableOperation();
@@ -53,10 +63,10 @@
     struct Operation {
         Operation();
         Operation(keymaster_operation_handle_t handle, const keymaster1_device_t* device,
-                  const keymaster_key_blob_t& key, sp<IBinder> appToken);
+                  keymaster_key_characteristics_t* characteristics, sp<IBinder> appToken);
         keymaster_operation_handle_t handle;
         const keymaster1_device_t* device;
-        keymaster_key_blob_t key;
+        Unique_keymaster_key_characteristics characteristics;
         sp<IBinder> appToken;
     };
     std::map<sp<IBinder>, struct Operation> mMap;