security: Add ECDSA signature signing and validation

Change-Id: I2f193e9d643498a68579ae59a7f524ff446dcb9e
Refs: #1660
diff --git a/src/security/sec-tpm-file.cpp b/src/security/sec-tpm-file.cpp
index 6634f68..03ce634 100644
--- a/src/security/sec-tpm-file.cpp
+++ b/src/security/sec-tpm-file.cpp
@@ -142,6 +142,51 @@
             chmod(publicKeyFileName.c_str(), 0000444);
             return;
           }
+        case KEY_TYPE_ECDSA:
+          {
+            using namespace CryptoPP;
+
+            const EcdsaKeyParams& ecdsaParams = static_cast<const EcdsaKeyParams&>(params);
+
+            OID curveName;
+            switch (ecdsaParams.getKeySize())
+              {
+              case 256:
+                curveName = ASN1::secp256r1();
+                break;
+              case 384:
+                curveName = ASN1::secp384r1();
+                break;
+              default:
+                curveName = ASN1::secp256r1();
+              }
+
+            AutoSeededRandomPool rng;
+
+            ECDSA<ECP, SHA256>::PrivateKey privateKey;
+            DL_GroupParameters_EC<ECP> cryptoParams(curveName);
+            cryptoParams.SetEncodeAsOID(true);
+            privateKey.Initialize(rng, cryptoParams);
+
+            ECDSA<ECP, SHA256>::PublicKey publicKey;
+            privateKey.MakePublicKey(publicKey);
+            publicKey.AccessGroupParameters().SetEncodeAsOID(true);
+
+            string privateKeyFileName = keyFileName + ".pri";
+            Base64Encoder privateKeySink(new FileSink(privateKeyFileName.c_str()));
+            privateKey.DEREncode(privateKeySink);
+            privateKeySink.MessageEnd();
+
+            string publicKeyFileName = keyFileName + ".pub";
+            Base64Encoder publicKeySink(new FileSink(publicKeyFileName.c_str()));
+            publicKey.Save(publicKeySink);
+            publicKeySink.MessageEnd();
+
+            /*set file permission*/
+            chmod(privateKeyFileName.c_str(), 0000400);
+            chmod(publicKeyFileName.c_str(), 0000444);
+            return;
+          }
         default:
           throw Error("Unsupported key type!");
         }
@@ -258,31 +303,79 @@
       using namespace CryptoPP;
       AutoSeededRandomPool rng;
 
-      //Read private key
-      ByteQueue bytes;
-      FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(),
-                      true, new Base64Decoder);
-      file.TransferTo(bytes);
-      bytes.MessageEnd();
-      RSA::PrivateKey privateKey;
-      privateKey.Load(bytes);
+      //Read public key
+      shared_ptr<PublicKey> pubkeyPtr;
+      pubkeyPtr = getPublicKeyFromTpm(keyName);
 
-      //Sign message
-      switch (digestAlgorithm)
+      switch (pubkeyPtr->getKeyType())
         {
-        case DIGEST_ALGORITHM_SHA256:
+          case KEY_TYPE_RSA:
+            {
+              //Read private key
+              ByteQueue bytes;
+              FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(),
+                              true, new Base64Decoder);
+              file.TransferTo(bytes);
+              bytes.MessageEnd();
+              RSA::PrivateKey privateKey;
+              privateKey.Load(bytes);
+
+              //Sign message
+              switch (digestAlgorithm)
+                {
+                case DIGEST_ALGORITHM_SHA256:
+                  {
+                    RSASS<PKCS1v15, SHA256>::Signer signer(privateKey);
+
+                    OBufferStream os;
+                    StringSource(data, dataLength,
+                                 true,
+                                 new SignerFilter(rng, signer, new FileSink(os)));
+
+                    return Block(Tlv::SignatureValue, os.buf());
+                  }
+                default:
+                  throw Error("Unsupported digest algorithm!");
+                }
+            }
+        case KEY_TYPE_ECDSA:
           {
-            RSASS<PKCS1v15, SHA256>::Signer signer(privateKey);
+            //Read private key
+            ByteQueue bytes;
+            FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(),
+                            true, new Base64Decoder);
+            file.TransferTo(bytes);
+            bytes.MessageEnd();
 
-            OBufferStream os;
-            StringSource(data, dataLength,
-                         true,
-                         new SignerFilter(rng, signer, new FileSink(os)));
+            //Sign message
+            switch (digestAlgorithm)
+              {
+              case DIGEST_ALGORITHM_SHA256:
+                {
+                  ECDSA<ECP, SHA256>::PrivateKey privateKey;
+                  privateKey.Load(bytes);
+                  ECDSA<ECP, SHA256>::Signer signer(privateKey);
 
-            return Block(Tlv::SignatureValue, os.buf());
+                  OBufferStream os;
+                  StringSource(data, dataLength,
+                               true,
+                               new SignerFilter(rng, signer, new FileSink(os)));
+
+                  uint8_t buf[200];
+                  size_t bufSize = DSAConvertSignatureFormat(buf, 200, DSA_DER,
+                                                             os.buf()->buf(), os.buf()->size(),
+                                                             DSA_P1363);
+
+                  shared_ptr<Buffer> sigBuffer = make_shared<Buffer>(buf, bufSize);
+
+                  return Block(Tlv::SignatureValue, sigBuffer);
+                }
+              default:
+                throw Error("Unsupported digest algorithm!");
+              }
           }
         default:
-          throw Error("Unsupported digest algorithm!");
+          throw Error("Unsupported key type!");
         }
     }
   catch (CryptoPP::Exception& e)