|
18 | 18 | #include <algorithm> |
19 | 19 | #include <cstring> |
20 | 20 | #if OPENSSL_VERSION_MAJOR >= 3 |
| 21 | +#include <openssl/core_names.h> |
| 22 | +#include <openssl/params.h> |
21 | 23 | #include <openssl/provider.h> |
| 24 | +#if OPENSSL_VERSION_NUMBER >= 0x30200000L |
| 25 | +#include <openssl/thread.h> |
| 26 | +#endif |
22 | 27 | #endif |
23 | 28 | #if OPENSSL_WITH_PQC |
24 | 29 | struct PQCMapping { |
@@ -2006,6 +2011,102 @@ DataPointer pbkdf2(const Digest& md, |
2006 | 2011 | return {}; |
2007 | 2012 | } |
2008 | 2013 |
|
| 2014 | +#if OPENSSL_VERSION_NUMBER >= 0x30200000L |
| 2015 | +#ifndef OPENSSL_NO_ARGON2 |
| 2016 | +DataPointer argon2(const Buffer<const char>& pass, |
| 2017 | + const Buffer<const unsigned char>& salt, |
| 2018 | + uint32_t lanes, |
| 2019 | + size_t length, |
| 2020 | + uint32_t memcost, |
| 2021 | + uint32_t iter, |
| 2022 | + uint32_t version, |
| 2023 | + const Buffer<const unsigned char>& secret, |
| 2024 | + const Buffer<const unsigned char>& ad, |
| 2025 | + Argon2Type type) { |
| 2026 | + ClearErrorOnReturn clearErrorOnReturn; |
| 2027 | + |
| 2028 | + std::string_view algorithm; |
| 2029 | + switch (type) { |
| 2030 | + case Argon2Type::ARGON2I: |
| 2031 | + algorithm = "ARGON2I"; |
| 2032 | + break; |
| 2033 | + case Argon2Type::ARGON2D: |
| 2034 | + algorithm = "ARGON2D"; |
| 2035 | + break; |
| 2036 | + case Argon2Type::ARGON2ID: |
| 2037 | + algorithm = "ARGON2ID"; |
| 2038 | + break; |
| 2039 | + default: |
| 2040 | + // Invalid Argon2 type |
| 2041 | + return {}; |
| 2042 | + } |
| 2043 | + |
| 2044 | + // creates a new library context to avoid locking when running concurrently |
| 2045 | + auto ctx = DeleteFnPtr<OSSL_LIB_CTX, OSSL_LIB_CTX_free>{OSSL_LIB_CTX_new()}; |
| 2046 | + if (!ctx) { |
| 2047 | + return {}; |
| 2048 | + } |
| 2049 | + |
| 2050 | + // required if threads > 1 |
| 2051 | + if (lanes > 1 && OSSL_set_max_threads(ctx.get(), lanes) != 1) { |
| 2052 | + return {}; |
| 2053 | + } |
| 2054 | + |
| 2055 | + auto kdf = DeleteFnPtr<EVP_KDF, EVP_KDF_free>{ |
| 2056 | + EVP_KDF_fetch(ctx.get(), algorithm.data(), nullptr)}; |
| 2057 | + if (!kdf) { |
| 2058 | + return {}; |
| 2059 | + } |
| 2060 | + |
| 2061 | + auto kctx = |
| 2062 | + DeleteFnPtr<EVP_KDF_CTX, EVP_KDF_CTX_free>{EVP_KDF_CTX_new(kdf.get())}; |
| 2063 | + if (!kctx) { |
| 2064 | + return {}; |
| 2065 | + } |
| 2066 | + |
| 2067 | + std::vector<OSSL_PARAM> params; |
| 2068 | + params.reserve(9); |
| 2069 | + |
| 2070 | + params.push_back(OSSL_PARAM_construct_octet_string( |
| 2071 | + OSSL_KDF_PARAM_PASSWORD, |
| 2072 | + const_cast<char*>(pass.len > 0 ? pass.data : ""), |
| 2073 | + pass.len)); |
| 2074 | + params.push_back(OSSL_PARAM_construct_octet_string( |
| 2075 | + OSSL_KDF_PARAM_SALT, const_cast<unsigned char*>(salt.data), salt.len)); |
| 2076 | + params.push_back(OSSL_PARAM_construct_uint32(OSSL_KDF_PARAM_THREADS, &lanes)); |
| 2077 | + params.push_back( |
| 2078 | + OSSL_PARAM_construct_uint32(OSSL_KDF_PARAM_ARGON2_LANES, &lanes)); |
| 2079 | + params.push_back( |
| 2080 | + OSSL_PARAM_construct_uint32(OSSL_KDF_PARAM_ARGON2_MEMCOST, &memcost)); |
| 2081 | + params.push_back(OSSL_PARAM_construct_uint32(OSSL_KDF_PARAM_ITER, &iter)); |
| 2082 | + |
| 2083 | + if (ad.len != 0) { |
| 2084 | + params.push_back(OSSL_PARAM_construct_octet_string( |
| 2085 | + OSSL_KDF_PARAM_ARGON2_AD, const_cast<unsigned char*>(ad.data), ad.len)); |
| 2086 | + } |
| 2087 | + |
| 2088 | + if (secret.len != 0) { |
| 2089 | + params.push_back(OSSL_PARAM_construct_octet_string( |
| 2090 | + OSSL_KDF_PARAM_SECRET, |
| 2091 | + const_cast<unsigned char*>(secret.data), |
| 2092 | + secret.len)); |
| 2093 | + } |
| 2094 | + |
| 2095 | + params.push_back(OSSL_PARAM_construct_end()); |
| 2096 | + |
| 2097 | + auto dp = DataPointer::Alloc(length); |
| 2098 | + if (dp && EVP_KDF_derive(kctx.get(), |
| 2099 | + reinterpret_cast<unsigned char*>(dp.get()), |
| 2100 | + length, |
| 2101 | + params.data()) == 1) { |
| 2102 | + return dp; |
| 2103 | + } |
| 2104 | + |
| 2105 | + return {}; |
| 2106 | +} |
| 2107 | +#endif |
| 2108 | +#endif |
| 2109 | + |
2009 | 2110 | // ============================================================================ |
2010 | 2111 |
|
2011 | 2112 | EVPKeyPointer::PrivateKeyEncodingConfig::PrivateKeyEncodingConfig( |
|
0 commit comments