summaryrefslogtreecommitdiffstats
path: root/comm/third_party/botan/src/lib/misc/srp6
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /comm/third_party/botan/src/lib/misc/srp6
parentInitial commit. (diff)
downloadthunderbird-upstream.tar.xz
thunderbird-upstream.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'comm/third_party/botan/src/lib/misc/srp6')
-rw-r--r--comm/third_party/botan/src/lib/misc/srp6/info.txt8
-rw-r--r--comm/third_party/botan/src/lib/misc/srp6/srp6.cpp193
-rw-r--r--comm/third_party/botan/src/lib/misc/srp6/srp6.h155
3 files changed, 356 insertions, 0 deletions
diff --git a/comm/third_party/botan/src/lib/misc/srp6/info.txt b/comm/third_party/botan/src/lib/misc/srp6/info.txt
new file mode 100644
index 0000000000..27b7848f5b
--- /dev/null
+++ b/comm/third_party/botan/src/lib/misc/srp6/info.txt
@@ -0,0 +1,8 @@
+<defines>
+SRP6 -> 20161017
+</defines>
+
+<requires>
+bigint
+dl_group
+</requires>
diff --git a/comm/third_party/botan/src/lib/misc/srp6/srp6.cpp b/comm/third_party/botan/src/lib/misc/srp6/srp6.cpp
new file mode 100644
index 0000000000..0bd9b192ae
--- /dev/null
+++ b/comm/third_party/botan/src/lib/misc/srp6/srp6.cpp
@@ -0,0 +1,193 @@
+/*
+* SRP-6a (RFC 5054 compatatible)
+* (C) 2011,2012,2019 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/srp6.h>
+#include <botan/hash.h>
+#include <botan/dl_group.h>
+#include <botan/numthry.h>
+
+namespace Botan {
+
+namespace {
+
+BigInt hash_seq(const std::string& hash_id,
+ size_t pad_to,
+ const BigInt& in1,
+ const BigInt& in2)
+ {
+ std::unique_ptr<HashFunction> hash_fn(HashFunction::create_or_throw(hash_id));
+
+ hash_fn->update(BigInt::encode_1363(in1, pad_to));
+ hash_fn->update(BigInt::encode_1363(in2, pad_to));
+
+ return BigInt::decode(hash_fn->final());
+ }
+
+BigInt compute_x(const std::string& hash_id,
+ const std::string& identifier,
+ const std::string& password,
+ const std::vector<uint8_t>& salt)
+ {
+ std::unique_ptr<HashFunction> hash_fn(HashFunction::create_or_throw(hash_id));
+
+ hash_fn->update(identifier);
+ hash_fn->update(":");
+ hash_fn->update(password);
+
+ secure_vector<uint8_t> inner_h = hash_fn->final();
+
+ hash_fn->update(salt);
+ hash_fn->update(inner_h);
+
+ secure_vector<uint8_t> outer_h = hash_fn->final();
+
+ return BigInt::decode(outer_h);
+ }
+
+}
+
+std::string srp6_group_identifier(const BigInt& N, const BigInt& g)
+ {
+ /*
+ This function assumes that only one 'standard' SRP parameter set has
+ been defined for a particular bitsize. As of this writing that is the case.
+ */
+ try
+ {
+ const std::string group_name = "modp/srp/" + std::to_string(N.bits());
+
+ DL_Group group(group_name);
+
+ if(group.get_p() == N && group.get_g() == g)
+ return group_name;
+ }
+ catch(...)
+ {
+ }
+
+ // If we didn't return, the group was unknown or did not match
+ throw Invalid_Argument("Invalid or unknown SRP group parameters");
+ }
+
+std::pair<BigInt, SymmetricKey>
+srp6_client_agree(const std::string& identifier,
+ const std::string& password,
+ const std::string& group_id,
+ const std::string& hash_id,
+ const std::vector<uint8_t>& salt,
+ const BigInt& B,
+ RandomNumberGenerator& rng)
+ {
+ DL_Group group(group_id);
+ const size_t a_bits = group.exponent_bits();
+
+ return srp6_client_agree(identifier, password, group, hash_id, salt, B, a_bits, rng);
+ }
+
+std::pair<BigInt, SymmetricKey>
+srp6_client_agree(const std::string& identifier,
+ const std::string& password,
+ const DL_Group& group,
+ const std::string& hash_id,
+ const std::vector<uint8_t>& salt,
+ const BigInt& B,
+ const size_t a_bits,
+ RandomNumberGenerator& rng)
+ {
+ const BigInt& g = group.get_g();
+ const BigInt& p = group.get_p();
+
+ const size_t p_bytes = group.p_bytes();
+
+ if(B <= 0 || B >= p)
+ throw Decoding_Error("Invalid SRP parameter from server");
+
+ const BigInt k = hash_seq(hash_id, p_bytes, p, g);
+
+ const BigInt a(rng, a_bits);
+
+ const BigInt A = group.power_g_p(a, a_bits);
+
+ const BigInt u = hash_seq(hash_id, p_bytes, A, B);
+
+ const BigInt x = compute_x(hash_id, identifier, password, salt);
+
+ const BigInt S = power_mod(group.mod_p(B - (k * power_mod(g, x, p))),
+ group.mod_p(a + (u * x)), p);
+
+ const SymmetricKey Sk(BigInt::encode_1363(S, p_bytes));
+
+ return std::make_pair(A, Sk);
+ }
+
+BigInt generate_srp6_verifier(const std::string& identifier,
+ const std::string& password,
+ const std::vector<uint8_t>& salt,
+ const std::string& group_id,
+ const std::string& hash_id)
+ {
+ DL_Group group(group_id);
+ return generate_srp6_verifier(identifier, password, salt, group, hash_id);
+ }
+
+BigInt generate_srp6_verifier(const std::string& identifier,
+ const std::string& password,
+ const std::vector<uint8_t>& salt,
+ const DL_Group& group,
+ const std::string& hash_id)
+ {
+ const BigInt x = compute_x(hash_id, identifier, password, salt);
+ // FIXME: x should be size of hash fn so avoid computing x.bits() here
+ return group.power_g_p(x, x.bits());
+ }
+
+BigInt SRP6_Server_Session::step1(const BigInt& v,
+ const std::string& group_id,
+ const std::string& hash_id,
+ RandomNumberGenerator& rng)
+ {
+ DL_Group group(group_id);
+ const size_t b_bits = group.exponent_bits();
+
+ return this->step1(v, group, hash_id, b_bits, rng);
+ }
+
+BigInt SRP6_Server_Session::step1(const BigInt& v,
+ const DL_Group& group,
+ const std::string& hash_id,
+ size_t b_bits,
+ RandomNumberGenerator& rng)
+ {
+ const BigInt& g = group.get_g();
+ const BigInt& p = group.get_p();
+
+ m_p_bytes = p.bytes();
+ m_v = v;
+ m_b = BigInt(rng, b_bits);
+ m_p = p;
+ m_hash_id = hash_id;
+
+ const BigInt k = hash_seq(hash_id, m_p_bytes, p, g);
+
+ m_B = group.mod_p(v*k + group.power_g_p(m_b, b_bits));
+
+ return m_B;
+ }
+
+SymmetricKey SRP6_Server_Session::step2(const BigInt& A)
+ {
+ if(A <= 0 || A >= m_p)
+ throw Decoding_Error("Invalid SRP parameter from client");
+
+ const BigInt u = hash_seq(m_hash_id, m_p_bytes, A, m_B);
+
+ const BigInt S = power_mod(A * power_mod(m_v, u, m_p), m_b, m_p);
+
+ return BigInt::encode_1363(S, m_p_bytes);
+ }
+
+}
diff --git a/comm/third_party/botan/src/lib/misc/srp6/srp6.h b/comm/third_party/botan/src/lib/misc/srp6/srp6.h
new file mode 100644
index 0000000000..6bb4b7e7c5
--- /dev/null
+++ b/comm/third_party/botan/src/lib/misc/srp6/srp6.h
@@ -0,0 +1,155 @@
+/*
+* SRP-6a (RFC 5054 compatatible)
+* (C) 2011,2012,2019 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_RFC5054_SRP6_H_
+#define BOTAN_RFC5054_SRP6_H_
+
+#include <botan/bigint.h>
+#include <botan/symkey.h>
+#include <string>
+
+namespace Botan {
+
+class DL_Group;
+class RandomNumberGenerator;
+
+/**
+* SRP6a Client side
+* @param username the username we are attempting login for
+* @param password the password we are attempting to use
+* @param group_id specifies the shared SRP group
+* @param hash_id specifies a secure hash function
+* @param salt is the salt value sent by the server
+* @param B is the server's public value
+* @param rng is a random number generator
+*
+* @return (A,K) the client public key and the shared secret key
+*/
+std::pair<BigInt,SymmetricKey>
+BOTAN_PUBLIC_API(2,0) srp6_client_agree(const std::string& username,
+ const std::string& password,
+ const std::string& group_id,
+ const std::string& hash_id,
+ const std::vector<uint8_t>& salt,
+ const BigInt& B,
+ RandomNumberGenerator& rng);
+
+
+/**
+* SRP6a Client side
+* @param username the username we are attempting login for
+* @param password the password we are attempting to use
+* @param group specifies the shared SRP group
+* @param hash_id specifies a secure hash function
+* @param salt is the salt value sent by the server
+* @param B is the server's public value
+* @param a_bits size of secret exponent in bits
+* @param rng is a random number generator
+*
+* @return (A,K) the client public key and the shared secret key
+*/
+std::pair<BigInt,SymmetricKey> BOTAN_PUBLIC_API(2,11)
+ srp6_client_agree(const std::string& username,
+ const std::string& password,
+ const DL_Group& group,
+ const std::string& hash_id,
+ const std::vector<uint8_t>& salt,
+ const BigInt& B,
+ size_t a_bits,
+ RandomNumberGenerator& rng);
+
+/**
+* Generate a new SRP-6 verifier
+* @param identifier a username or other client identifier
+* @param password the secret used to authenticate user
+* @param salt a randomly chosen value, at least 128 bits long
+* @param group_id specifies the shared SRP group
+* @param hash_id specifies a secure hash function
+*/
+BigInt BOTAN_PUBLIC_API(2,0)
+ generate_srp6_verifier(const std::string& identifier,
+ const std::string& password,
+ const std::vector<uint8_t>& salt,
+ const std::string& group_id,
+ const std::string& hash_id);
+
+/**
+* Generate a new SRP-6 verifier
+* @param identifier a username or other client identifier
+* @param password the secret used to authenticate user
+* @param salt a randomly chosen value, at least 128 bits long
+* @param group specifies the shared SRP group
+* @param hash_id specifies a secure hash function
+*/
+BigInt BOTAN_PUBLIC_API(2,11)
+ generate_srp6_verifier(const std::string& identifier,
+ const std::string& password,
+ const std::vector<uint8_t>& salt,
+ const DL_Group& group,
+ const std::string& hash_id);
+
+/**
+* Return the group id for this SRP param set, or else thrown an
+* exception
+* @param N the group modulus
+* @param g the group generator
+* @return group identifier
+*/
+std::string BOTAN_PUBLIC_API(2,0) srp6_group_identifier(const BigInt& N, const BigInt& g);
+
+/**
+* Represents a SRP-6a server session
+*/
+class BOTAN_PUBLIC_API(2,0) SRP6_Server_Session final
+ {
+ public:
+ /**
+ * Server side step 1
+ * @param v the verification value saved from client registration
+ * @param group_id the SRP group id
+ * @param hash_id the SRP hash in use
+ * @param rng a random number generator
+ * @return SRP-6 B value
+ */
+ BigInt step1(const BigInt& v,
+ const std::string& group_id,
+ const std::string& hash_id,
+ RandomNumberGenerator& rng);
+
+ /**
+ * Server side step 1
+ * This version of step1 added in 2.11
+ *
+ * @param v the verification value saved from client registration
+ * @param group the SRP group
+ * @param hash_id the SRP hash in use
+ * @param rng a random number generator
+ * @param b_bits size of secret exponent in bits
+ * @return SRP-6 B value
+ */
+ BigInt step1(const BigInt& v,
+ const DL_Group& group,
+ const std::string& hash_id,
+ const size_t b_bits,
+ RandomNumberGenerator& rng);
+
+ /**
+ * Server side step 2
+ * @param A the client's value
+ * @return shared symmetric key
+ */
+ SymmetricKey step2(const BigInt& A);
+
+ private:
+ std::string m_hash_id;
+ BigInt m_B, m_b, m_v, m_S, m_p;
+ size_t m_p_bytes = 0;
+ };
+
+}
+
+#endif