hkdf.cpp 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. /*
  2. * Based on
  3. * 1. OpenSSL lib
  4. * 2. PurpleI2P source code
  5. * 3. cppcodec lib
  6. *
  7. * PUBLIC DOMAIN C++ WRAPPER
  8. * acetone, 2022
  9. */
  10. #include "hkdf.h"
  11. #include <openssl/kdf.h>
  12. #include <openssl/hmac.h>
  13. namespace FriendlyCrypto {
  14. std::array<uint8_t, 32> hkdf (const std::array<uint8_t, 32> &key, const std::string &info, const uint8_t *salt) noexcept
  15. {
  16. EVP_PKEY_CTX* pctx = EVP_PKEY_CTX_new_id (EVP_PKEY_HKDF, nullptr);
  17. EVP_PKEY_derive_init (pctx);
  18. EVP_PKEY_CTX_set_hkdf_md (pctx, EVP_sha256());
  19. if (key.size())
  20. {
  21. EVP_PKEY_CTX_set1_hkdf_salt (pctx, salt, 32);
  22. EVP_PKEY_CTX_set1_hkdf_key (pctx, key.data(), key.size());
  23. }
  24. else // zerolen
  25. {
  26. EVP_PKEY_CTX_hkdf_mode (pctx, EVP_PKEY_HKDEF_MODE_EXPAND_ONLY);
  27. uint8_t tempKey[32]; unsigned int len;
  28. HMAC(EVP_sha256(), salt, 32, nullptr, 0, tempKey, &len);
  29. EVP_PKEY_CTX_set1_hkdf_key (pctx, tempKey, len);
  30. }
  31. if (info.length () > 0)
  32. {
  33. EVP_PKEY_CTX_add1_hkdf_info (pctx, info.c_str(), info.length());
  34. }
  35. std::array<uint8_t, 32> out;
  36. size_t len = out.size();
  37. EVP_PKEY_derive (pctx, out.data(), &len);
  38. EVP_PKEY_CTX_free (pctx);
  39. return out;
  40. }
  41. } // namespace