Add ECDSA key generation.

Change-Id: I68a1d46e617124a8ccb7a4b2c09baae89603a5e0
diff --git a/google_keymaster.cpp b/google_keymaster.cpp
index 80d8215..d4bc7a8 100644
--- a/google_keymaster.cpp
+++ b/google_keymaster.cpp
@@ -25,6 +25,7 @@
 
 #include "ae.h"
 #include "dsa_operation.h"
+#include "ecdsa_operation.h"
 #include "google_keymaster.h"
 #include "google_keymaster_utils.h"
 #include "key_blob.h"
@@ -54,7 +55,7 @@
 typedef UniquePtr<ae_ctx, AE_CTX_Delete> Unique_ae_ctx;
 
 keymaster_algorithm_t supported_algorithms[] = {
-    KM_ALGORITHM_RSA, KM_ALGORITHM_DSA,
+    KM_ALGORITHM_RSA, KM_ALGORITHM_DSA, KM_ALGORITHM_ECDSA,
 };
 
 template <typename T>
@@ -92,6 +93,7 @@
     switch (algorithm) {
     case KM_ALGORITHM_RSA:
     case KM_ALGORITHM_DSA:
+    case KM_ALGORITHM_ECDSA:
         response->SetResults(supported_padding);
         break;
     default:
@@ -110,6 +112,7 @@
     switch (algorithm) {
     case KM_ALGORITHM_RSA:
     case KM_ALGORITHM_DSA:
+    case KM_ALGORITHM_ECDSA:
         response->SetResults(supported_digests);
         break;
     default:
@@ -129,6 +132,7 @@
     switch (algorithm) {
     case KM_ALGORITHM_RSA:
     case KM_ALGORITHM_DSA:
+    case KM_ALGORITHM_ECDSA:
         response->SetResults(supported_import_formats);
         break;
     default:
@@ -148,6 +152,7 @@
     switch (algorithm) {
     case KM_ALGORITHM_RSA:
     case KM_ALGORITHM_DSA:
+    case KM_ALGORITHM_ECDSA:
         response->SetResults(supported_export_formats);
         break;
     default:
@@ -185,6 +190,10 @@
         if (!GenerateDsa(request.key_description, response, &hidden_auths))
             return;
         break;
+    case KM_ALGORITHM_ECDSA:
+        if (!GenerateEcdsa(request.key_description, response, &hidden_auths))
+            return;
+        break;
     default:
         response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
         return;
@@ -359,6 +368,27 @@
     return CreateKeyBlob(response, *hidden_auths, key_data.get(), key_data_size);
 }
 
+bool GoogleKeymaster::GenerateEcdsa(const AuthorizationSet& key_auths,
+                                    GenerateKeyResponse* response, AuthorizationSet* hidden_auths) {
+    uint64_t public_exponent = RSA_DEFAULT_EXPONENT;
+    if (!key_auths.GetTagValue(TAG_RSA_PUBLIC_EXPONENT, &public_exponent))
+        AddAuthorization(Authorization(TAG_RSA_PUBLIC_EXPONENT, public_exponent), response);
+
+    uint32_t key_size = RSA_DEFAULT_KEY_SIZE;
+    if (!key_auths.GetTagValue(TAG_KEY_SIZE, &key_size))
+        AddAuthorization(Authorization(TAG_KEY_SIZE, key_size), response);
+
+    UniquePtr<uint8_t[]> key_data;
+    size_t key_data_size;
+    keymaster_error_t error = EcdsaOperation::Generate(key_size, &key_data, &key_data_size);
+    if (error != KM_ERROR_OK) {
+        response->error = error;
+        return false;
+    }
+
+    return CreateKeyBlob(response, *hidden_auths, key_data.get(), key_data_size);
+}
+
 bool GoogleKeymaster::CreateKeyBlob(GenerateKeyResponse* response,
                                     const AuthorizationSet& hidden_auths, uint8_t* key_bytes,
                                     size_t key_length) {