security: support 224-bit and 521-bit NIST elliptic curves

Change-Id: I28d2e5162e1e8fd7261828d435b059093b6989ea
diff --git a/src/security/key-params.cpp b/src/security/key-params.cpp
index a908b43..e18ae67 100644
--- a/src/security/key-params.cpp
+++ b/src/security/key-params.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2017 Regents of the University of California.
+ * Copyright (c) 2013-2018 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -25,8 +25,10 @@
 
 static const uint32_t MIN_RSA_KEY_SIZE = 1024;
 static const uint32_t DEFAULT_RSA_KEY_SIZE = 2048;
-static const uint32_t EC_KEY_SIZES[] = {256, 384};
+static const uint32_t EC_KEY_SIZES[] = {224, 256, 384, 521};
+static const uint32_t DEFAULT_EC_KEY_SIZE = 256;
 static const uint32_t AES_KEY_SIZES[] = {128, 192, 256};
+static const uint32_t DEFAULT_AES_KEY_SIZE = 128;
 
 KeyParams::KeyParams(KeyType keyType, KeyIdType keyIdType)
   : m_keyType(keyType)
@@ -51,7 +53,7 @@
 RsaKeyParamsInfo::checkKeySize(uint32_t size)
 {
   if (size < MIN_RSA_KEY_SIZE)
-    BOOST_THROW_EXCEPTION(KeyParams::Error("Unsupported RSA key size"));
+    BOOST_THROW_EXCEPTION(KeyParams::Error("Unsupported RSA key size " + to_string(size)));
   return size;
 }
 
@@ -68,13 +70,13 @@
     if (EC_KEY_SIZES[i] == size)
       return size;
   }
-  BOOST_THROW_EXCEPTION(KeyParams::Error("Unsupported EC key size"));
+  BOOST_THROW_EXCEPTION(KeyParams::Error("Unsupported EC key size " + to_string(size)));
 }
 
 uint32_t
 EcKeyParamsInfo::getDefaultSize()
 {
-  return EC_KEY_SIZES[0];
+  return DEFAULT_EC_KEY_SIZE;
 }
 
 uint32_t
@@ -84,13 +86,13 @@
     if (AES_KEY_SIZES[i] == size)
       return size;
   }
-  BOOST_THROW_EXCEPTION(KeyParams::Error("Unsupported AES key size"));
+  BOOST_THROW_EXCEPTION(KeyParams::Error("Unsupported AES key size " + to_string(size)));
 }
 
 uint32_t
 AesKeyParamsInfo::getDefaultSize()
 {
-  return AES_KEY_SIZES[0];
+  return DEFAULT_AES_KEY_SIZE;
 }
 
 } // namespace detail
diff --git a/src/security/transform/private-key.cpp b/src/security/transform/private-key.cpp
index 84a1875..4c6a763 100644
--- a/src/security/transform/private-key.cpp
+++ b/src/security/transform/private-key.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2017 Regents of the University of California.
+ * Copyright (c) 2013-2018 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -401,14 +401,20 @@
 
   int ret;
   switch (keySize) {
-    case 256:
-      ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_X9_62_prime256v1); // same as secp256r1
-      break;
-    case 384:
-      ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_secp384r1);
-      break;
-    default:
-      BOOST_THROW_EXCEPTION(PrivateKey::Error("Unsupported EC key length"));
+  case 224:
+    ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_secp224r1);
+    break;
+  case 256:
+    ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_X9_62_prime256v1); // same as secp256r1
+    break;
+  case 384:
+    ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_secp384r1);
+    break;
+  case 521:
+    ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_secp521r1);
+    break;
+  default:
+    BOOST_THROW_EXCEPTION(std::invalid_argument("Unsupported EC key length " + to_string(keySize)));
   }
   if (ret <= 0)
     BOOST_THROW_EXCEPTION(PrivateKey::Error("Failed to set EC curve"));
diff --git a/src/security/transform/private-key.hpp b/src/security/transform/private-key.hpp
index fb4978a..e1af107 100644
--- a/src/security/transform/private-key.hpp
+++ b/src/security/transform/private-key.hpp
@@ -257,10 +257,10 @@
 /**
  * @brief Generate a private key according to @p keyParams
  *
- * @note The public key can be derived from the private key.
+ * @note The corresponding public key can be derived from the private key.
  *
  * @throw std::invalid_argument the specified key type is not supported
- * @throw std::runtime_error    key generation fails
+ * @throw PrivateKey::Error     key generation failed
  */
 unique_ptr<PrivateKey>
 generatePrivateKey(const KeyParams& keyParams);