From bcec6536a4f9898a836fa9d8a279331a714522d5 Mon Sep 17 00:00:00 2001 From: Alexander Scheel Date: Wed, 7 Feb 2024 13:59:12 -0500 Subject: [PATCH] Correct descriptions of M1 & M2 per RFC 5054 As far as I can tell from the code, what is defined as: > key = compute_premaster_secret(...) does not include the given hash invocation step. While RFC 5054 is unclearly worded (see comment below), SRP-6 is clear that M1 should not include K = H(S) and thus this description of the protocol is incorrect. As far as I can tell, nobody else uses this computation of M1 (with K = H(S) as a parameter) and thus it should be dropped from the tabular and comment descriptions. See also: https://github.com/bcgit/bc-csharp/issues/506#issuecomment-1932665252 Signed-off-by: Alexander Scheel --- srp/src/lib.rs | 7 +++---- srp/src/utils.rs | 8 +++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/srp/src/lib.rs b/srp/src/lib.rs index bec6c11..d4a2dac 100644 --- a/srp/src/lib.rs +++ b/srp/src/lib.rs @@ -25,10 +25,9 @@ //! |`a_pub = g^a` | — `a_pub`, `I` —> | (lookup `s`, `v` for given `I`) | //! |`x = PH(P, s)` | <— `b_pub`, `s` — | `b_pub = k*v + g^b` | //! |`u = H(a_pub ‖ b_pub)` | | `u = H(a_pub ‖ b_pub)` | -//! |`s = (b_pub - k*g^x)^(a+u*x)` | | `S = (b_pub - k*g^x)^(a+u*x)` | -//! |`K = H(s)` | | `K = H(s)` | -//! |`M1 = H(A ‖ B ‖ K)` | — `M1` —> | (verify `M1`) | -//! |(verify `M2`) | <— `M2` — | `M2 = H(A ‖ M1 ‖ K)` | +//! |`S = (b_pub - k*g^x)^(a+u*x)` | | `S = (b_pub - k*g^x)^(a+u*x)` | +//! |`M1 = H(A ‖ B ‖ S)` | — `M1` —> | (verify `M1`) | +//! |(verify `M2`) | <— `M2` — | `M2 = H(A ‖ M1 ‖ S)` | //! //! Variables and notations have the following meaning: //! diff --git a/srp/src/utils.rs b/srp/src/utils.rs index 0d77129..e11d842 100644 --- a/srp/src/utils.rs +++ b/srp/src/utils.rs @@ -27,8 +27,10 @@ pub fn compute_k(params: &SrpGroup) -> BigUint { BigUint::from_bytes_be(d.finalize().as_slice()) } -// M1 = H(A, B, K) this doesn't follow the spec but apparently no one does for M1 -// M1 should equal = H(H(N) XOR H(g) | H(U) | s | A | B | K) according to the spec +// M1 = H(A, B, S) follows SRP-6 required by a strict interpretation of RFC +// 5054; this doesn't follow RFC 2945, where +// M1 = H(H(N) XOR H(g) | H(U) | s | A | B | K) +// as RFC 5054 doesn't mandate its use. #[must_use] pub fn compute_m1(a_pub: &[u8], b_pub: &[u8], key: &[u8]) -> Output { let mut d = D::new(); @@ -38,7 +40,7 @@ pub fn compute_m1(a_pub: &[u8], b_pub: &[u8], key: &[u8]) -> Output(a_pub: &[u8], m1: &Output, key: &[u8]) -> Output { let mut d = D::new();