|
19 | 19 | #include <algorithm> |
20 | 20 | #include <cstring> |
21 | 21 | #if OPENSSL_VERSION_MAJOR >= 3 |
| 22 | +#include <openssl/core_names.h> |
| 23 | +#include <openssl/params.h> |
22 | 24 | #include <openssl/provider.h> |
| 25 | +#if OPENSSL_VERSION_NUMBER >= 0x30200000L |
| 26 | +#include <openssl/thread.h> |
| 27 | +#endif |
23 | 28 | #endif |
24 | 29 | #if OPENSSL_WITH_PQC |
25 | 30 | struct PQCMapping { |
@@ -1954,6 +1959,102 @@ DataPointer pbkdf2(const EVP_MD* md, |
1954 | 1959 | return {}; |
1955 | 1960 | } |
1956 | 1961 |
|
| 1962 | +#if OPENSSL_VERSION_NUMBER >= 0x30200000L |
| 1963 | +#ifndef OPENSSL_NO_ARGON2 |
| 1964 | +DataPointer argon2(const Buffer<const char>& pass, |
| 1965 | + const Buffer<const unsigned char>& salt, |
| 1966 | + uint32_t lanes, |
| 1967 | + size_t length, |
| 1968 | + uint32_t memcost, |
| 1969 | + uint32_t iter, |
| 1970 | + uint32_t version, |
| 1971 | + const Buffer<const unsigned char>& secret, |
| 1972 | + const Buffer<const unsigned char>& ad, |
| 1973 | + Argon2Type type) { |
| 1974 | + ClearErrorOnReturn clearErrorOnReturn; |
| 1975 | + |
| 1976 | + std::string_view algorithm; |
| 1977 | + switch (type) { |
| 1978 | + case Argon2Type::ARGON2I: |
| 1979 | + algorithm = "ARGON2I"; |
| 1980 | + break; |
| 1981 | + case Argon2Type::ARGON2D: |
| 1982 | + algorithm = "ARGON2D"; |
| 1983 | + break; |
| 1984 | + case Argon2Type::ARGON2ID: |
| 1985 | + algorithm = "ARGON2ID"; |
| 1986 | + break; |
| 1987 | + default: |
| 1988 | + // Invalid Argon2 type |
| 1989 | + return {}; |
| 1990 | + } |
| 1991 | + |
| 1992 | + // creates a new library context to avoid locking when running concurrently |
| 1993 | + auto ctx = DeleteFnPtr<OSSL_LIB_CTX, OSSL_LIB_CTX_free>{OSSL_LIB_CTX_new()}; |
| 1994 | + if (!ctx) { |
| 1995 | + return {}; |
| 1996 | + } |
| 1997 | + |
| 1998 | + // required if threads > 1 |
| 1999 | + if (lanes > 1 && OSSL_set_max_threads(ctx.get(), lanes) != 1) { |
| 2000 | + return {}; |
| 2001 | + } |
| 2002 | + |
| 2003 | + auto kdf = DeleteFnPtr<EVP_KDF, EVP_KDF_free>{ |
| 2004 | + EVP_KDF_fetch(ctx.get(), algorithm.data(), nullptr)}; |
| 2005 | + if (!kdf) { |
| 2006 | + return {}; |
| 2007 | + } |
| 2008 | + |
| 2009 | + auto kctx = |
| 2010 | + DeleteFnPtr<EVP_KDF_CTX, EVP_KDF_CTX_free>{EVP_KDF_CTX_new(kdf.get())}; |
| 2011 | + if (!kctx) { |
| 2012 | + return {}; |
| 2013 | + } |
| 2014 | + |
| 2015 | + std::vector<OSSL_PARAM> params; |
| 2016 | + params.reserve(9); |
| 2017 | + |
| 2018 | + params.push_back(OSSL_PARAM_construct_octet_string( |
| 2019 | + OSSL_KDF_PARAM_PASSWORD, |
| 2020 | + const_cast<char*>(pass.len > 0 ? pass.data : ""), |
| 2021 | + pass.len)); |
| 2022 | + params.push_back(OSSL_PARAM_construct_octet_string( |
| 2023 | + OSSL_KDF_PARAM_SALT, const_cast<unsigned char*>(salt.data), salt.len)); |
| 2024 | + params.push_back(OSSL_PARAM_construct_uint32(OSSL_KDF_PARAM_THREADS, &lanes)); |
| 2025 | + params.push_back( |
| 2026 | + OSSL_PARAM_construct_uint32(OSSL_KDF_PARAM_ARGON2_LANES, &lanes)); |
| 2027 | + params.push_back( |
| 2028 | + OSSL_PARAM_construct_uint32(OSSL_KDF_PARAM_ARGON2_MEMCOST, &memcost)); |
| 2029 | + params.push_back(OSSL_PARAM_construct_uint32(OSSL_KDF_PARAM_ITER, &iter)); |
| 2030 | + |
| 2031 | + if (ad.len != 0) { |
| 2032 | + params.push_back(OSSL_PARAM_construct_octet_string( |
| 2033 | + OSSL_KDF_PARAM_ARGON2_AD, const_cast<unsigned char*>(ad.data), ad.len)); |
| 2034 | + } |
| 2035 | + |
| 2036 | + if (secret.len != 0) { |
| 2037 | + params.push_back(OSSL_PARAM_construct_octet_string( |
| 2038 | + OSSL_KDF_PARAM_SECRET, |
| 2039 | + const_cast<unsigned char*>(secret.data), |
| 2040 | + secret.len)); |
| 2041 | + } |
| 2042 | + |
| 2043 | + params.push_back(OSSL_PARAM_construct_end()); |
| 2044 | + |
| 2045 | + auto dp = DataPointer::Alloc(length); |
| 2046 | + if (dp && EVP_KDF_derive(kctx.get(), |
| 2047 | + reinterpret_cast<unsigned char*>(dp.get()), |
| 2048 | + length, |
| 2049 | + params.data()) == 1) { |
| 2050 | + return dp; |
| 2051 | + } |
| 2052 | + |
| 2053 | + return {}; |
| 2054 | +} |
| 2055 | +#endif |
| 2056 | +#endif |
| 2057 | + |
1957 | 2058 | // ============================================================================ |
1958 | 2059 |
|
1959 | 2060 | EVPKeyPointer::PrivateKeyEncodingConfig::PrivateKeyEncodingConfig( |
|
0 commit comments