feat(auth): add support for ED25519 and ED448 89/37689/1
authorOlivier Roques <oroques@cisco.com>
Thu, 17 Nov 2022 11:26:23 +0000 (11:26 +0000)
committerOlivier Roques <oroques+fdio@cisco.com>
Tue, 22 Nov 2022 13:07:51 +0000 (13:07 +0000)
Ref: HICN-818

Signed-off-by: Olivier Roques <oroques@cisco.com>
Change-Id: I8672f022b74be387e16496660a78edf3c1da4bf1

libtransport/includes/hicn/transport/auth/crypto_hash.h
libtransport/includes/hicn/transport/auth/crypto_suite.h
libtransport/includes/hicn/transport/auth/signer.h
libtransport/includes/hicn/transport/auth/verifier.h
libtransport/src/auth/crypto_hash.cc
libtransport/src/auth/crypto_suite.cc
libtransport/src/auth/signer.cc
libtransport/src/auth/verifier.cc
libtransport/src/test/test_auth.cc

index 29ea271..fbe1d51 100644 (file)
@@ -27,8 +27,6 @@ extern "C" {
 namespace transport {
 namespace auth {
 
-typedef const EVP_MD *(*CryptoHashEVP)(void);
-
 enum class CryptoHashType : uint8_t {
   UNKNOWN,
   SHA256,
@@ -57,8 +55,6 @@ class CryptoHash {
   // Compute the hash of given buffer
   void computeDigest(const uint8_t *buffer, std::size_t len);
   void computeDigest(const std::vector<uint8_t> &buffer);
-
-  // Compute the hash of given membuf
   void computeDigest(const utils::MemBuf *buffer);
 
   // Return the computed hash
@@ -82,8 +78,8 @@ class CryptoHash {
   // Reset hash
   void reset();
 
-  // Return OpenSSL EVP function associated to a given hash type
-  static CryptoHashEVP getEVP(CryptoHashType hash_type);
+  // Return the OpenSSL EVP_MD pointer associated to a given hash type
+  static const EVP_MD *getMD(CryptoHashType hash_type);
 
   // Return hash size
   static std::size_t getSize(CryptoHashType hash_type);
index ed21abb..f3b5352 100644 (file)
@@ -26,22 +26,24 @@ namespace auth {
 
 enum class CryptoSuite : uint8_t {
   UNKNOWN,
+  DSA_BLAKE2B512,
+  DSA_BLAKE2S256,
+  DSA_SHA256,
+  DSA_SHA512,
   ECDSA_BLAKE2B512,
   ECDSA_BLAKE2S256,
   ECDSA_SHA256,
   ECDSA_SHA512,
-  RSA_BLAKE2B512,
-  RSA_BLAKE2S256,
-  RSA_SHA256,
-  RSA_SHA512,
+  ED25519,
+  ED448,
   HMAC_BLAKE2B512,
   HMAC_BLAKE2S256,
   HMAC_SHA256,
   HMAC_SHA512,
-  DSA_BLAKE2B512,
-  DSA_BLAKE2S256,
-  DSA_SHA256,
-  DSA_SHA512,
+  RSA_BLAKE2B512,
+  RSA_BLAKE2S256,
+  RSA_SHA256,
+  RSA_SHA512,
 };
 
 // Return the suite associated to the given NID
@@ -53,5 +55,7 @@ std::string getStringSuite(CryptoSuite suite);
 // Return the hash type associated to the given suite
 CryptoHashType getHashType(CryptoSuite suite);
 
+// Return the OpenSSL EVP_MD pointer associated to a given suite
+const EVP_MD *getMD(CryptoSuite suite);
 }  // namespace auth
 }  // namespace transport
index e1b3cae..f9e07ef 100644 (file)
@@ -42,6 +42,7 @@ class Signer {
 
   // Sign a packet.
   virtual void signPacket(PacketPtr packet);
+  virtual void signBuffer(const uint8_t *buffer, std::size_t len);
   virtual void signBuffer(const std::vector<uint8_t> &buffer);
   virtual void signBuffer(const utils::MemBuf *buffer);
 
@@ -82,6 +83,7 @@ class VoidSigner : public Signer {
   VoidSigner() = default;
 
   void signPacket(PacketPtr packet) override;
+  void signBuffer(const uint8_t *buffer, std::size_t len) override;
   void signBuffer(const std::vector<uint8_t> &buffer) override;
   void signBuffer(const utils::MemBuf *buffer) override;
 };
index c891383..2e086df 100644 (file)
@@ -54,12 +54,15 @@ class Verifier {
 
   // Verify a single packet or buffer.
   virtual bool verifyPacket(PacketPtr packet);
+  virtual bool verifyBuffer(const uint8_t *buffer, std::size_t len,
+                            const utils::MemBuf::Ptr &signature,
+                            CryptoSuite suite) = 0;
   virtual bool verifyBuffer(const std::vector<uint8_t> &buffer,
                             const utils::MemBuf::Ptr &signature,
-                            CryptoHashType hash_type) = 0;
+                            CryptoSuite suite) = 0;
   virtual bool verifyBuffer(const utils::MemBuf *buffer,
                             const utils::MemBuf::Ptr &signature,
-                            CryptoHashType hash_type) = 0;
+                            CryptoSuite suite) = 0;
 
   // Verify a batch of packets. Return a mapping from packet suffixes to their
   // VerificationPolicy.
@@ -110,12 +113,15 @@ class VoidVerifier : public Verifier {
   // and always returns true.
  public:
   bool verifyPacket(PacketPtr packet) override;
+  bool verifyBuffer(const uint8_t *buffer, std::size_t len,
+                    const utils::MemBuf::Ptr &signature,
+                    CryptoSuite suite) override;
   bool verifyBuffer(const std::vector<uint8_t> &buffer,
                     const utils::MemBuf::Ptr &signature,
-                    CryptoHashType hash_type) override;
+                    CryptoSuite suite) override;
   bool verifyBuffer(const utils::MemBuf *buffer,
                     const utils::MemBuf::Ptr &signature,
-                    CryptoHashType hash_type) override;
+                    CryptoSuite suite) override;
 
   PolicyMap verifyPackets(const std::vector<PacketPtr> &packets) override;
 
@@ -143,12 +149,15 @@ class AsymmetricVerifier : public Verifier {
   void useCertificate(const std::string &cert_path);
   void useCertificate(std::shared_ptr<X509> cert);
 
+  bool verifyBuffer(const uint8_t *buffer, std::size_t len,
+                    const utils::MemBuf::Ptr &signature,
+                    CryptoSuite suite) override;
   bool verifyBuffer(const std::vector<uint8_t> &buffer,
                     const utils::MemBuf::Ptr &signature,
-                    CryptoHashType hash_type) override;
+                    CryptoSuite suite) override;
   bool verifyBuffer(const utils::MemBuf *buffer,
                     const utils::MemBuf::Ptr &signature,
-                    CryptoHashType hash_type) override;
+                    CryptoSuite suite) override;
 
  private:
   std::shared_ptr<EVP_PKEY> key_;
@@ -166,12 +175,15 @@ class SymmetricVerifier : public Verifier {
   // Create and set a symmetric key from a passphrase.
   void setPassphrase(const std::string &passphrase);
 
+  bool verifyBuffer(const uint8_t *buffer, std::size_t len,
+                    const utils::MemBuf::Ptr &signature,
+                    CryptoSuite suite) override;
   bool verifyBuffer(const std::vector<uint8_t> &buffer,
                     const utils::MemBuf::Ptr &signature,
-                    CryptoHashType hash_type) override;
+                    CryptoSuite suite) override;
   bool verifyBuffer(const utils::MemBuf *buffer,
                     const utils::MemBuf::Ptr &signature,
-                    CryptoHashType hash_type) override;
+                    CryptoSuite suite) override;
 
  protected:
   std::shared_ptr<EVP_PKEY> key_;
index bc2d524..0f6e9ab 100644 (file)
@@ -63,14 +63,16 @@ bool CryptoHash::operator==(const CryptoHash &other) const {
 }
 
 void CryptoHash::computeDigest(const uint8_t *buffer, size_t len) {
-  CryptoHashEVP hash_evp = CryptoHash::getEVP(digest_type_);
-
-  if (hash_evp == nullptr) {
+  const EVP_MD *hash_md = CryptoHash::getMD(digest_type_);
+  if (hash_md == nullptr) {
     throw errors::RuntimeException("Unknown hash type");
   }
 
-  EVP_Digest(buffer, len, digest_->writableData(),
-             (unsigned int *)&digest_size_, (*hash_evp)(), nullptr);
+  if (EVP_Digest(buffer, len, digest_->writableData(),
+                 reinterpret_cast<unsigned int *>(&digest_size_), hash_md,
+                 nullptr) != 1) {
+    throw errors::RuntimeException("Digest computation failed.");
+  };
 }
 
 void CryptoHash::computeDigest(const std::vector<uint8_t> &buffer) {
@@ -78,33 +80,12 @@ void CryptoHash::computeDigest(const std::vector<uint8_t> &buffer) {
 }
 
 void CryptoHash::computeDigest(const utils::MemBuf *buffer) {
-  CryptoHashEVP hash_evp = CryptoHash::getEVP(digest_type_);
-
-  if (hash_evp == nullptr) {
-    throw errors::RuntimeException("Unknown hash type");
-  }
-
-  EVP_MD_CTX *mcdtx = EVP_MD_CTX_new();
-  const utils::MemBuf *p = buffer;
-
-  if (EVP_DigestInit_ex(mcdtx, (*hash_evp)(), nullptr) == 0) {
-    throw errors::RuntimeException("Digest initialization failed");
-  }
-
-  do {
-    if (EVP_DigestUpdate(mcdtx, p->data(), p->length()) != 1) {
-      throw errors::RuntimeException("Digest update failed");
-    }
-
-    p = p->next();
-  } while (p != buffer);
-
-  if (EVP_DigestFinal_ex(mcdtx, digest_->writableData(),
-                         (unsigned int *)&digest_size_) != 1) {
-    throw errors::RuntimeException("Digest computation failed");
+  if (buffer->isChained()) {
+    throw errors::RuntimeException(
+        "Digest of chained membuf is not supported.");
   }
 
-  EVP_MD_CTX_free(mcdtx);
+  computeDigest(buffer->data(), buffer->length());
 }
 
 const utils::MemBuf::Ptr &CryptoHash::getDigest() const { return digest_; }
@@ -159,41 +140,33 @@ void CryptoHash::reset() {
   digest_->setLength(0);
 }
 
-CryptoHashEVP CryptoHash::getEVP(CryptoHashType hash_type) {
+const EVP_MD *CryptoHash::getMD(CryptoHashType hash_type) {
   switch (hash_type) {
     case CryptoHashType::SHA256:
-      return &EVP_sha256;
+      return EVP_sha256();
     case CryptoHashType::SHA512:
-      return &EVP_sha512;
+      return EVP_sha512();
     case CryptoHashType::BLAKE2S256:
-      return &EVP_blake2s256;
+      return EVP_blake2s256();
     case CryptoHashType::BLAKE2B512:
-      return &EVP_blake2b512;
+      return EVP_blake2b512();
     default:
       return nullptr;
   }
 }
 
 size_t CryptoHash::getSize(CryptoHashType hash_type) {
-  CryptoHashEVP hash_evp = CryptoHash::getEVP(hash_type);
-
-  if (hash_evp == nullptr) {
-    return 0;
-  }
-
-  return EVP_MD_size((*hash_evp)());
+  const EVP_MD *hash_md = CryptoHash::getMD(hash_type);
+  return hash_md == nullptr ? 0 : EVP_MD_size(hash_md);
 }
 
 bool CryptoHash::compareDigest(const uint8_t *digest1, const uint8_t *digest2,
                                CryptoHashType hash_type) {
-  CryptoHashEVP hash_evp = CryptoHash::getEVP(hash_type);
-
-  if (hash_evp == nullptr) {
-    return false;
-  }
-
-  return !static_cast<bool>(
-      memcmp(digest1, digest2, CryptoHash::getSize(hash_type)));
+  const EVP_MD *hash_md = CryptoHash::getMD(hash_type);
+  return hash_md == nullptr
+             ? false
+             : !static_cast<bool>(
+                   memcmp(digest1, digest2, CryptoHash::getSize(hash_type)));
 }
 
 }  // namespace auth
index 44de852..e7b097a 100644 (file)
@@ -20,6 +20,10 @@ namespace auth {
 
 CryptoSuite getSuite(int nid) {
   switch (nid) {
+    case NID_ED25519:
+      return CryptoSuite::ED25519;
+    case NID_ED448:
+      return CryptoSuite::ED448;
     case NID_ecdsa_with_SHA256:
       return CryptoSuite::ECDSA_SHA256;
     case NID_ecdsa_with_SHA512:
@@ -43,6 +47,10 @@ CryptoSuite getSuite(int nid) {
 
 std::string getStringSuite(CryptoSuite suite) {
   switch (suite) {
+    case CryptoSuite::ED25519:
+      return "ED25519";
+    case CryptoSuite::ED448:
+      return "ED448";
     case CryptoSuite::ECDSA_BLAKE2B512:
       return "ECDSA_BLAKE2B512";
     case CryptoSuite::ECDSA_BLAKE2S256:
@@ -82,30 +90,42 @@ std::string getStringSuite(CryptoSuite suite) {
 
 CryptoHashType getHashType(CryptoSuite suite) {
   switch (suite) {
+    case CryptoSuite::DSA_BLAKE2B512:
     case CryptoSuite::ECDSA_BLAKE2B512:
-    case CryptoSuite::RSA_BLAKE2B512:
     case CryptoSuite::HMAC_BLAKE2B512:
-    case CryptoSuite::DSA_BLAKE2B512:
+    case CryptoSuite::RSA_BLAKE2B512:
       return CryptoHashType::BLAKE2B512;
+    case CryptoSuite::DSA_BLAKE2S256:
     case CryptoSuite::ECDSA_BLAKE2S256:
-    case CryptoSuite::RSA_BLAKE2S256:
     case CryptoSuite::HMAC_BLAKE2S256:
-    case CryptoSuite::DSA_BLAKE2S256:
+    case CryptoSuite::RSA_BLAKE2S256:
       return CryptoHashType::BLAKE2S256;
+    case CryptoSuite::DSA_SHA256:
     case CryptoSuite::ECDSA_SHA256:
-    case CryptoSuite::RSA_SHA256:
+    case CryptoSuite::ED25519:
+    case CryptoSuite::ED448:
     case CryptoSuite::HMAC_SHA256:
-    case CryptoSuite::DSA_SHA256:
+    case CryptoSuite::RSA_SHA256:
       return CryptoHashType::SHA256;
+    case CryptoSuite::DSA_SHA512:
     case CryptoSuite::ECDSA_SHA512:
-    case CryptoSuite::RSA_SHA512:
     case CryptoSuite::HMAC_SHA512:
-    case CryptoSuite::DSA_SHA512:
+    case CryptoSuite::RSA_SHA512:
       return CryptoHashType::SHA512;
     default:
       return CryptoHashType::UNKNOWN;
   }
 }
 
+const EVP_MD *getMD(CryptoSuite suite) {
+  switch (suite) {
+    case CryptoSuite::ED25519:
+    case CryptoSuite::ED448:
+      return nullptr;
+    default:
+      return CryptoHash::getMD(getHashType(suite));
+  }
+}
+
 }  // namespace auth
 }  // namespace transport
index 4841801..5fcb242 100644 (file)
@@ -86,87 +86,47 @@ void Signer::signPacket(PacketPtr packet) {
   }
 }
 
-void Signer::signBuffer(const std::vector<uint8_t> &buffer) {
-  DCHECK(key_ != nullptr);
-  CryptoHashEVP hash_evp = CryptoHash::getEVP(getHashType());
-
-  if (hash_evp == nullptr) {
-    throw errors::RuntimeException("Unknown hash type");
-  }
-
-  std::shared_ptr<EVP_MD_CTX> mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_free);
+void Signer::signBuffer(const uint8_t *buffer, std::size_t len) {
+  const EVP_MD *hash_md = getMD(suite_);
 
-  if (mdctx == nullptr) {
-    throw errors::RuntimeException("Digest context allocation failed");
+  std::shared_ptr<EVP_MD_CTX> md_ctx(EVP_MD_CTX_new(), EVP_MD_CTX_free);
+  if (md_ctx == nullptr) {
+    throw errors::RuntimeException("Signature context allocation failed");
   }
 
-  if (EVP_DigestSignInit(mdctx.get(), nullptr, (*hash_evp)(), nullptr,
-                         key_.get()) != 1) {
-    throw errors::RuntimeException("Digest initialization failed");
-  }
-
-  if (EVP_DigestSignUpdate(mdctx.get(), buffer.data(), buffer.size()) != 1) {
-    throw errors::RuntimeException("Digest update failed");
+  if (EVP_DigestSignInit(md_ctx.get(), nullptr, hash_md, nullptr, key_.get()) !=
+      1) {
+    throw errors::RuntimeException("Signature initialization failed");
   }
 
-  if (EVP_DigestSignFinal(mdctx.get(), nullptr, &signature_len_) != 1) {
-    throw errors::RuntimeException("Digest computation failed");
-  }
+  if (EVP_DigestSign(md_ctx.get(), nullptr, &signature_len_, buffer, len) !=
+      1) {
+    throw errors::RuntimeException("Signature length computation failed");
+  };
 
   DCHECK(signature_len_ <= signature_->tailroom());
   signature_->setLength(signature_len_);
 
-  if (EVP_DigestSignFinal(mdctx.get(), signature_->writableData(),
-                          &signature_len_) != 1) {
-    throw errors::RuntimeException("Digest computation failed");
-  }
+  if (EVP_DigestSign(md_ctx.get(), signature_->writableData(), &signature_len_,
+                     buffer, len) != 1) {
+    throw errors::RuntimeException("Signature computation failed");
+  };
 
   DCHECK(signature_len_ <= signature_->tailroom());
   signature_->setLength(signature_len_);
 }
 
-void Signer::signBuffer(const utils::MemBuf *buffer) {
-  DCHECK(key_ != nullptr);
-  CryptoHashEVP hash_evp = CryptoHash::getEVP(getHashType());
-
-  if (hash_evp == nullptr) {
-    throw errors::RuntimeException("Unknown hash type");
-  }
-
-  const utils::MemBuf *p = buffer;
-  std::shared_ptr<EVP_MD_CTX> mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_free);
-
-  if (mdctx == nullptr) {
-    throw errors::RuntimeException("Digest context allocation failed");
-  }
-
-  if (EVP_DigestSignInit(mdctx.get(), nullptr, (*hash_evp)(), nullptr,
-                         key_.get()) != 1) {
-    throw errors::RuntimeException("Digest initialization failed");
-  }
-
-  do {
-    if (EVP_DigestSignUpdate(mdctx.get(), p->data(), p->length()) != 1) {
-      throw errors::RuntimeException("Digest update failed");
-    }
-
-    p = p->next();
-  } while (p != buffer);
-
-  if (EVP_DigestSignFinal(mdctx.get(), nullptr, &signature_len_) != 1) {
-    throw errors::RuntimeException("Digest computation failed");
-  }
-
-  DCHECK(signature_len_ <= signature_->tailroom());
-  signature_->setLength(signature_len_);
+void Signer::signBuffer(const std::vector<uint8_t> &buffer) {
+  signBuffer(buffer.data(), buffer.size());
+}
 
-  if (EVP_DigestSignFinal(mdctx.get(), signature_->writableData(),
-                          &signature_len_) != 1) {
-    throw errors::RuntimeException("Digest computation failed");
+void Signer::signBuffer(const utils::MemBuf *buffer) {
+  if (buffer->isChained()) {
+    throw errors::RuntimeException(
+        "Signature of chained membuf is not supported.");
   }
 
-  DCHECK(signature_len_ <= signature_->tailroom());
-  signature_->setLength(signature_len_);
+  signBuffer(buffer->data(), buffer->length());
 }
 
 const utils::MemBuf::Ptr &Signer::getSignature() const { return signature_; }
@@ -208,6 +168,8 @@ void Signer::display() {
 // ---------------------------------------------------------
 void VoidSigner::signPacket(PacketPtr packet) {}
 
+void VoidSigner::signBuffer(const uint8_t *buffer, std::size_t len) {}
+
 void VoidSigner::signBuffer(const std::vector<uint8_t> &buffer) {}
 
 void VoidSigner::signBuffer(const utils::MemBuf *buffer) {}
@@ -258,20 +220,12 @@ void AsymmetricSigner::setKey(CryptoSuite suite, std::shared_ptr<EVP_PKEY> key,
 
   signature_len_ = EVP_PKEY_size(key_.get());
   DCHECK(signature_len_ <= signature_->tailroom());
-
   signature_->setLength(signature_len_);
 
-  size_t enc_pbk_len = i2d_PublicKey(pub_key.get(), nullptr);
-  DCHECK(enc_pbk_len >= 0);
-
-  uint8_t *enc_pbkey_raw = nullptr;
-  i2d_PublicKey(pub_key.get(), &enc_pbkey_raw);
-  DCHECK(enc_pbkey_raw != nullptr);
-
+  // Key ID is not supported yet.
+  uint8_t id[8] = {0};
   key_id_ = CryptoHash(getHashType());
-  key_id_.computeDigest(enc_pbkey_raw, enc_pbk_len);
-
-  OPENSSL_free(enc_pbkey_raw);
+  key_id_.computeDigest(id, 8);
 }
 
 size_t AsymmetricSigner::getSignatureFieldSize() const {
@@ -296,18 +250,20 @@ SymmetricSigner::SymmetricSigner(CryptoSuite suite,
                                    (const unsigned char *)passphrase.c_str(),
                                    passphrase.size()),
       EVP_PKEY_free);
-  key_id_ = CryptoHash(getHashType());
-
-  CryptoHashEVP hash_evp = CryptoHash::getEVP(getHashType());
 
-  if (hash_evp == nullptr) {
+  const EVP_MD *hash_md = getMD(suite_);
+  if (hash_md == nullptr) {
     throw errors::RuntimeException("Unknown hash type");
   }
 
-  signature_len_ = EVP_MD_size((*hash_evp)());
+  signature_len_ = EVP_MD_size(hash_md);
   DCHECK(signature_len_ <= signature_->tailroom());
   signature_->setLength(signature_len_);
-  key_id_.computeDigest((uint8_t *)passphrase.c_str(), passphrase.size());
+
+  // Key ID is not supported yet.
+  uint8_t id[8] = {0};
+  key_id_ = CryptoHash(getHashType());
+  key_id_.computeDigest(id, 8);
 }
 
 }  // namespace auth
index f930383..0919aec 100644 (file)
@@ -42,9 +42,8 @@ bool Verifier::verifyPacket(PacketPtr packet) {
     throw errors::MalformedAHPacketException();
   }
 
-  // Get crypto suite, hash type, signature length
+  // Get crypto suite
   CryptoSuite suite = packet->getValidationAlgorithm();
-  CryptoHashType hash_type = getHashType(suite);
 
   // Copy IP+TCP / ICMP header before zeroing them
   u8 header_copy[HICN_HDRLEN_MAX];
@@ -69,8 +68,8 @@ bool Verifier::verifyPacket(PacketPtr packet) {
   packet->resetForHash();
 
   // Check signatures
-  bool valid_packet = verifyBuffer(static_cast<utils::MemBuf *>(packet),
-                                   signature_raw, hash_type);
+  bool valid_packet =
+      verifyBuffer(static_cast<utils::MemBuf *>(packet), signature_raw, suite);
 
   // Restore header
   packet->loadHeader(header_copy, header_len);
@@ -183,15 +182,21 @@ void Verifier::callVerificationFailedCallback(Suffix suffix,
 // ---------------------------------------------------------
 bool VoidVerifier::verifyPacket(PacketPtr packet) { return true; }
 
+bool VoidVerifier::verifyBuffer(const uint8_t *buffer, std::size_t len,
+                                const utils::MemBuf::Ptr &signature,
+                                CryptoSuite suite) {
+  return true;
+}
+
 bool VoidVerifier::verifyBuffer(const std::vector<uint8_t> &buffer,
                                 const utils::MemBuf::Ptr &signature,
-                                CryptoHashType hash_type) {
+                                CryptoSuite suite) {
   return true;
 }
 
 bool VoidVerifier::verifyBuffer(const utils::MemBuf *buffer,
                                 const utils::MemBuf::Ptr &signature,
-                                CryptoHashType hash_type) {
+                                CryptoSuite suite) {
   return true;
 }
 
@@ -250,65 +255,40 @@ void AsymmetricVerifier::useCertificate(std::shared_ptr<X509> cert) {
       std::shared_ptr<EVP_PKEY>(X509_get_pubkey(cert.get()), ::EVP_PKEY_free);
 }
 
-bool AsymmetricVerifier::verifyBuffer(const std::vector<uint8_t> &buffer,
+bool AsymmetricVerifier::verifyBuffer(const uint8_t *buffer, std::size_t len,
                                       const utils::MemBuf::Ptr &signature,
-                                      CryptoHashType hash_type) {
-  CryptoHashEVP hash_evp = CryptoHash::getEVP(hash_type);
+                                      CryptoSuite suite) {
+  const EVP_MD *hash_md = getMD(suite);
 
-  if (hash_evp == nullptr) {
-    throw errors::RuntimeException("Unknown hash type");
+  std::shared_ptr<EVP_MD_CTX> md_ctx(EVP_MD_CTX_new(), EVP_MD_CTX_free);
+  if (md_ctx == nullptr) {
+    throw errors::RuntimeException("Signature context allocation failed");
   }
 
-  std::shared_ptr<EVP_MD_CTX> mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_free);
-
-  if (mdctx == nullptr) {
-    throw errors::RuntimeException("Digest context allocation failed");
-  }
-
-  if (EVP_DigestVerifyInit(mdctx.get(), nullptr, (*hash_evp)(), nullptr,
+  if (EVP_DigestVerifyInit(md_ctx.get(), nullptr, hash_md, nullptr,
                            key_.get()) != 1) {
-    throw errors::RuntimeException("Digest initialization failed");
+    throw errors::RuntimeException("Signature initialization failed");
   }
 
-  if (EVP_DigestVerifyUpdate(mdctx.get(), buffer.data(), buffer.size()) != 1) {
-    throw errors::RuntimeException("Digest update failed");
-  }
+  return EVP_DigestVerify(md_ctx.get(), signature->data(), signature->length(),
+                          buffer, len) == 1;
+};
 
-  return EVP_DigestVerifyFinal(mdctx.get(), signature->data(),
-                               signature->length()) == 1;
+bool AsymmetricVerifier::verifyBuffer(const std::vector<uint8_t> &buffer,
+                                      const utils::MemBuf::Ptr &signature,
+                                      CryptoSuite suite) {
+  return verifyBuffer(buffer.data(), buffer.size(), signature, suite);
 }
 
 bool AsymmetricVerifier::verifyBuffer(const utils::MemBuf *buffer,
                                       const utils::MemBuf::Ptr &signature,
-                                      CryptoHashType hash_type) {
-  CryptoHashEVP hash_evp = CryptoHash::getEVP(hash_type);
-
-  if (hash_evp == nullptr) {
-    throw errors::RuntimeException("Unknown hash type");
+                                      CryptoSuite suite) {
+  if (buffer->isChained()) {
+    throw errors::RuntimeException(
+        "Signature of chained membuf is not supported.");
   }
 
-  const utils::MemBuf *p = buffer;
-  std::shared_ptr<EVP_MD_CTX> mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_free);
-
-  if (mdctx == nullptr) {
-    throw errors::RuntimeException("Digest context allocation failed");
-  }
-
-  if (EVP_DigestVerifyInit(mdctx.get(), nullptr, (*hash_evp)(), nullptr,
-                           key_.get()) != 1) {
-    throw errors::RuntimeException("Digest initialization failed");
-  }
-
-  do {
-    if (EVP_DigestVerifyUpdate(mdctx.get(), p->data(), p->length()) != 1) {
-      throw errors::RuntimeException("Digest update failed");
-    }
-
-    p = p->next();
-  } while (p != buffer);
-
-  return EVP_DigestVerifyFinal(mdctx.get(), signature->data(),
-                               signature->length()) == 1;
+  return verifyBuffer(buffer->data(), buffer->length(), signature, suite);
 }
 
 // ---------------------------------------------------------
@@ -327,83 +307,63 @@ void SymmetricVerifier::setPassphrase(const std::string &passphrase) {
       EVP_PKEY_free);
 }
 
-bool SymmetricVerifier::verifyBuffer(const std::vector<uint8_t> &buffer,
+bool SymmetricVerifier::verifyBuffer(const uint8_t *buffer, std::size_t len,
                                      const utils::MemBuf::Ptr &signature,
-                                     CryptoHashType hash_type) {
-  CryptoHashEVP hash_evp = CryptoHash::getEVP(hash_type);
-
-  if (hash_evp == nullptr) {
+                                     CryptoSuite suite) {
+  const EVP_MD *hash_md = getMD(suite);
+  if (hash_md == nullptr) {
     throw errors::RuntimeException("Unknown hash type");
   }
 
   const utils::MemBuf::Ptr &signature_bis =
       core::PacketManager<>::getInstance().getMemBuf();
-  signature_bis->append(signature->length());
   size_t signature_bis_len;
-  std::shared_ptr<EVP_MD_CTX> mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_free);
 
-  if (mdctx == nullptr) {
-    throw errors::RuntimeException("Digest context allocation failed");
+  std::shared_ptr<EVP_MD_CTX> md_ctx(EVP_MD_CTX_new(), EVP_MD_CTX_free);
+  if (md_ctx == nullptr) {
+    throw errors::RuntimeException("Signature context allocation failed");
   }
 
-  if (EVP_DigestSignInit(mdctx.get(), nullptr, (*hash_evp)(), nullptr,
-                         key_.get()) != 1) {
-    throw errors::RuntimeException("Digest initialization failed");
+  if (EVP_DigestSignInit(md_ctx.get(), nullptr, hash_md, nullptr, key_.get()) !=
+      1) {
+    throw errors::RuntimeException("Signature initialization failed");
   }
 
-  if (EVP_DigestSignUpdate(mdctx.get(), buffer.data(), buffer.size()) != 1) {
-    throw errors::RuntimeException("Digest update failed");
-  }
+  if (EVP_DigestSign(md_ctx.get(), nullptr, &signature_bis_len, buffer, len) !=
+      1) {
+    throw errors::RuntimeException("Signature length computation failed");
+  };
 
-  if (EVP_DigestSignFinal(mdctx.get(), signature_bis->writableData(),
-                          &signature_bis_len) != 1) {
-    throw errors::RuntimeException("Digest computation failed");
-  }
+  DCHECK(signature_bis_len <= signature_bis->tailroom());
+  signature_bis->append(signature_bis_len);
+
+  if (EVP_DigestSign(md_ctx.get(), signature_bis->writableData(),
+                     &signature_bis_len, buffer, len) != 1) {
+    throw errors::RuntimeException("Signature computation failed");
+  };
+
+  DCHECK(signature_bis_len <= signature_bis->tailroom());
+  signature_bis->setLength(signature_bis_len);
 
   return signature->length() == signature_bis_len &&
          *signature == *signature_bis;
 }
 
-bool SymmetricVerifier::verifyBuffer(const utils::MemBuf *buffer,
+bool SymmetricVerifier::verifyBuffer(const std::vector<uint8_t> &buffer,
                                      const utils::MemBuf::Ptr &signature,
-                                     CryptoHashType hash_type) {
-  CryptoHashEVP hash_evp = CryptoHash::getEVP(hash_type);
-
-  if (hash_evp == nullptr) {
-    throw errors::RuntimeException("Unknown hash type");
-  }
-
-  const utils::MemBuf *p = buffer;
-  const utils::MemBuf::Ptr &signature_bis =
-      core::PacketManager<>::getInstance().getMemBuf();
-  signature_bis->append(signature->length());
-  size_t signature_bis_len;
-  std::shared_ptr<EVP_MD_CTX> mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_free);
-
-  if (mdctx == nullptr) {
-    throw errors::RuntimeException("Digest context allocation failed");
-  }
-
-  if (EVP_DigestSignInit(mdctx.get(), nullptr, (*hash_evp)(), nullptr,
-                         key_.get()) != 1) {
-    throw errors::RuntimeException("Digest initialization failed");
-  }
-
-  do {
-    if (EVP_DigestSignUpdate(mdctx.get(), p->data(), p->length()) != 1) {
-      throw errors::RuntimeException("Digest update failed");
-    }
-
-    p = p->next();
-  } while (p != buffer);
+                                     CryptoSuite suite) {
+  return verifyBuffer(buffer.data(), buffer.size(), signature, suite);
+}
 
-  if (EVP_DigestSignFinal(mdctx.get(), signature_bis->writableData(),
-                          &signature_bis_len) != 1) {
-    throw errors::RuntimeException("Digest computation failed");
+bool SymmetricVerifier::verifyBuffer(const utils::MemBuf *buffer,
+                                     const utils::MemBuf::Ptr &signature,
+                                     CryptoSuite suite) {
+  if (buffer->isChained()) {
+    throw errors::RuntimeException(
+        "Signature of chained membuf is not supported.");
   }
 
-  return signature->length() == signature_bis_len &&
-         *signature == *signature_bis;
+  return verifyBuffer(buffer->data(), buffer->length(), signature, suite);
 }
 
 }  // namespace auth
index 2ee3c07..5440d37 100644 (file)
@@ -122,7 +122,7 @@ TEST_F(AuthTest, AsymmetricBufferRSA) {
 
   std::shared_ptr<AsymmetricVerifier> verif =
       std::make_shared<AsymmetricVerifier>(pubKey);
-  bool res = verif->verifyBuffer(buffer, sig, CryptoHashType::SHA256);
+  bool res = verif->verifyBuffer(buffer, sig, CryptoSuite::RSA_SHA256);
   EXPECT_EQ(res, true);
 }
 
@@ -160,7 +160,7 @@ TEST_F(AuthTest, AsymmetricBufferDSA) {
 
   std::shared_ptr<AsymmetricVerifier> verif =
       std::make_shared<AsymmetricVerifier>(pubKey);
-  bool res = verif->verifyBuffer(buffer, sig, CryptoHashType::SHA256);
+  bool res = verif->verifyBuffer(buffer, sig, CryptoSuite::RSA_SHA256);
   EXPECT_EQ(res, true);
 }
 
@@ -235,7 +235,7 @@ TEST_F(AuthTest, AsymmetricBufferECDSA) {
 
   std::shared_ptr<AsymmetricVerifier> verif =
       std::make_shared<AsymmetricVerifier>(pubKey);
-  bool res = verif->verifyBuffer(buffer, sig, CryptoHashType::SHA256);
+  bool res = verif->verifyBuffer(buffer, sig, CryptoSuite::RSA_SHA256);
   EXPECT_EQ(res, true);
 }  // namespace auth
 
@@ -290,7 +290,7 @@ TEST_F(AuthTest, HMACbuffer) {
   signer->signBuffer(buffer);
   utils::MemBuf::Ptr sig = signer->getSignature();
   SymmetricVerifier hmac(PASSPHRASE);
-  bool res = hmac.verifyBuffer(buffer, sig, CryptoHashType::SHA256);
+  bool res = hmac.verifyBuffer(buffer, sig, CryptoSuite::RSA_SHA256);
   EXPECT_EQ(res, true);
 }