Skip to content

Commit

Permalink
Correct descriptions of M1 & M2 per RFC 5054
Browse files Browse the repository at this point in the history
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: bcgit/bc-csharp#506 (comment)

Signed-off-by: Alexander Scheel <[email protected]>
  • Loading branch information
cipherboy committed Feb 7, 2024
1 parent c31ab6c commit bcec653
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 7 deletions.
7 changes: 3 additions & 4 deletions srp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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:
//!
Expand Down
8 changes: 5 additions & 3 deletions srp/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ pub fn compute_k<D: Digest>(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<D: Digest>(a_pub: &[u8], b_pub: &[u8], key: &[u8]) -> Output<D> {
let mut d = D::new();
Expand All @@ -38,7 +40,7 @@ pub fn compute_m1<D: Digest>(a_pub: &[u8], b_pub: &[u8], key: &[u8]) -> Output<D
d.finalize()
}

// M2 = H(A, M1, K)
// M2 = H(A, M1, S)
#[must_use]
pub fn compute_m2<D: Digest>(a_pub: &[u8], m1: &Output<D>, key: &[u8]) -> Output<D> {
let mut d = D::new();
Expand Down

0 comments on commit bcec653

Please sign in to comment.