KeyStore: use security level to chose keymaster device

Keymaster4 introduces security levels. Android devices
may have multiple keymaster implementations, one for each
possible security level, where the presence of a strong
security level implies the presence of all lower levels.

This patch adds code that enumerates all keymaster device
implementations available from ServiceManager and populates
Keystore's keymaster device database with at most one keymaster
implementation per security level. It gives precedence to
newer versions if multiple implementations exist for the same security
level.

The security level is chosen by a set of flags passed to the keystore
operations generate, import, addRngEntropy.
For existing keys the right security level is chosen by the blob flags.

To that end a new flag KEYSTORE_FLAG_STRONGBOX was added, and the
security level is expressed through a combination of
KEYSTORE_FLAG_FALLBACK (F) and KEYSTORE_FLAG_STRONGBOX (S).
Encoding is as follows:

             F     S
Software     1     X (don't care)
TEE          0     0
Strongbox    0     1

Some operations in keystore cli2 where amended with the optional
--seclevel flags. Allowing the user to chose the security level for the
given operation. Possible options are "software", "strongbox", and "tee"
where tee is the default value.

Test: Existing KeyStore CTS tests run

Change-Id: I01ef238f5e7067e480cf9b171630237236046bb1
diff --git a/keystore/keystore_cli_v2.cpp b/keystore/keystore_cli_v2.cpp
index 9e184e8..6e995e0 100644
--- a/keystore/keystore_cli_v2.cpp
+++ b/keystore/keystore_cli_v2.cpp
@@ -39,8 +39,8 @@
     printf("Usage: keystore_client_v2 <command> [options]\n");
     printf("Commands: brillo-platform-test [--prefix=<test_name_prefix>] [--test_for_0_3]\n"
            "          list-brillo-tests\n"
-           "          add-entropy --input=<entropy>\n"
-           "          generate --name=<key_name>\n"
+           "          add-entropy --input=<entropy> [--seclevel=software|strongbox|tee(default)]\n"
+           "          generate --name=<key_name> [--seclevel=software|strongbox|tee(default)]\n"
            "          get-chars --name=<key_name>\n"
            "          export --name=<key_name>\n"
            "          delete --name=<key_name>\n"
@@ -48,7 +48,8 @@
            "          exists --name=<key_name>\n"
            "          list [--prefix=<key_name_prefix>]\n"
            "          sign-verify --name=<key_name>\n"
-           "          [en|de]crypt --name=<key_name> --in=<file> --out=<file>\n");
+           "          [en|de]crypt --name=<key_name> --in=<file> --out=<file>\n"
+           "                       [--seclevel=software|strongbox|tee(default)]\n");
     exit(1);
 }
 
@@ -76,8 +77,9 @@
     std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
     AuthorizationSet hardware_enforced_characteristics;
     AuthorizationSet software_enforced_characteristics;
-    auto result = keystore->generateKey("tmp", parameters, &hardware_enforced_characteristics,
-                                        &software_enforced_characteristics);
+    auto result =
+        keystore->generateKey("tmp", parameters, 0 /*flags*/, &hardware_enforced_characteristics,
+                              &software_enforced_characteristics);
     const char kBoldRedAbort[] = "\033[1;31mABORT\033[0m";
     if (!result.isOk()) {
         LOG(ERROR) << "Failed to generate key: " << result;
@@ -254,14 +256,14 @@
     }
 }
 
-int AddEntropy(const std::string& input) {
+int AddEntropy(const std::string& input, int32_t flags) {
     std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
-    int32_t result = keystore->addRandomNumberGeneratorEntropy(input);
+    int32_t result = keystore->addRandomNumberGeneratorEntropy(input, flags);
     printf("AddEntropy: %d\n", result);
     return result;
 }
 
-int GenerateKey(const std::string& name) {
+int GenerateKey(const std::string& name, int32_t flags) {
     std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
     AuthorizationSetBuilder params;
     params.RsaSigningKey(2048, 65537)
@@ -274,7 +276,7 @@
         .Authorization(TAG_NO_AUTH_REQUIRED);
     AuthorizationSet hardware_enforced_characteristics;
     AuthorizationSet software_enforced_characteristics;
-    auto result = keystore->generateKey(name, params, &hardware_enforced_characteristics,
+    auto result = keystore->generateKey(name, params, flags, &hardware_enforced_characteristics,
                                         &software_enforced_characteristics);
     printf("GenerateKey: %d\n", int32_t(result));
     if (result.isOk()) {
@@ -399,11 +401,11 @@
 }
 
 int Encrypt(const std::string& key_name, const std::string& input_filename,
-            const std::string& output_filename) {
+            const std::string& output_filename, int32_t flags) {
     std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
     std::string input = ReadFile(input_filename);
     std::string output;
-    if (!keystore->encryptWithAuthentication(key_name, input, &output)) {
+    if (!keystore->encryptWithAuthentication(key_name, input, flags, &output)) {
         printf("EncryptWithAuthentication failed.\n");
         return 1;
     }
@@ -424,6 +426,18 @@
     return 0;
 }
 
+uint32_t securityLevelOption2Flags(const CommandLine& cmd) {
+    if (cmd.HasSwitch("seclevel")) {
+        auto str = cmd.GetSwitchValueASCII("seclevel");
+        if (str == "strongbox") {
+            return KEYSTORE_FLAG_STRONGBOX;
+        } else if (str == "software") {
+            return KEYSTORE_FLAG_FALLBACK;
+        }
+    }
+    return KEYSTORE_FLAG_NONE;
+}
+
 }  // namespace
 
 int main(int argc, char** argv) {
@@ -439,9 +453,11 @@
     } else if (args[0] == "list-brillo-tests") {
         return ListTestCases();
     } else if (args[0] == "add-entropy") {
-        return AddEntropy(command_line->GetSwitchValueASCII("input"));
+        return AddEntropy(command_line->GetSwitchValueASCII("input"),
+                          securityLevelOption2Flags(*command_line));
     } else if (args[0] == "generate") {
-        return GenerateKey(command_line->GetSwitchValueASCII("name"));
+        return GenerateKey(command_line->GetSwitchValueASCII("name"),
+                           securityLevelOption2Flags(*command_line));
     } else if (args[0] == "get-chars") {
         return GetCharacteristics(command_line->GetSwitchValueASCII("name"));
     } else if (args[0] == "export") {
@@ -457,9 +473,9 @@
     } else if (args[0] == "sign-verify") {
         return SignAndVerify(command_line->GetSwitchValueASCII("name"));
     } else if (args[0] == "encrypt") {
-        return Encrypt(command_line->GetSwitchValueASCII("name"),
-                       command_line->GetSwitchValueASCII("in"),
-                       command_line->GetSwitchValueASCII("out"));
+        return Encrypt(
+            command_line->GetSwitchValueASCII("name"), command_line->GetSwitchValueASCII("in"),
+            command_line->GetSwitchValueASCII("out"), securityLevelOption2Flags(*command_line));
     } else if (args[0] == "decrypt") {
         return Decrypt(command_line->GetSwitchValueASCII("name"),
                        command_line->GetSwitchValueASCII("in"),