~eau/passwd

2c176302d6dc1f48e3fd0af2b7dbbfcfb3fed816 — eau 5 years ago f03a78e master
a tiny cleanup for salt hash vs salt profile mismatch.
profile dictates.
3 files changed, 21 insertions(+), 28 deletions(-)

M argon.go
M passwd_test.go
M scrypt.go
M argon.go => argon.go +10 -15
@@ 181,11 181,16 @@ func (p *Argon2Params) generateFromParams(salt, password []byte) (out []byte, er
	var hash bytes.Buffer
	var data []byte

	// if salt mismatch, the profile dictactes, not the hash.
	// the profile dictactes
	psalt := make([]byte, p.Saltlen)
	copy(psalt, salt)

	data = password

	// we want to hmac a secret to have the resulting hash
	if len(p.secret) > 0 {
		data, err = hmacKeyHash(p.secret, salt, password)
		data, err = hmacKeyHash(p.secret, psalt, password)
		if err != nil {
			return nil, err
		}


@@ 194,17 199,16 @@ func (p *Argon2Params) generateFromParams(salt, password []byte) (out []byte, er
	switch p.Version {
	case Argon2i:
		id = idArgon2i
		key = argon2.Key(data, salt, p.Time, p.Memory, p.Thread, p.Keylen)
		key = argon2.Key(data, psalt, p.Time, p.Memory, p.Thread, p.Keylen)
	case Argon2id:
		fallthrough
	default:
		id = idArgon2id
		key = argon2.IDKey(data, salt, p.Time, p.Memory, p.Thread, p.Keylen)
		key = argon2.IDKey(data, psalt, p.Time, p.Memory, p.Thread, p.Keylen)
	}

	// need to b64.
	//salt64 := base64.StdEncoding.EncodeToString(salt)
	salt64 := base64Encode(salt)
	salt64 := base64Encode(psalt)

	// params
	if !p.Masked {


@@ 259,17 263,8 @@ func (p *Argon2Params) compare(hashed, password []byte) error {
		return ErrMismatch
	}

	// yes in case things are padded by mistake depending on storage
	// whatever.. the params tells us what to verify.
	//
	// we had a subtle bug where a shorter salt with the same
	// password encrypted would still match, as such you could have
	// potentially generated thousands of small salted password
	// to bruteforce and ran against the comparison function to
	// find a collision which requires less power, salts HAVE to
	// be the same size that's it.
	hashlen := uint32(len(compared))
	if uint32(len(hashed)) != hashlen || len(salt) != int(p.Saltlen) {
	if uint32(len(hashed)) != hashlen {
		return ErrMismatch
	}


M passwd_test.go => passwd_test.go +1 -1
@@ 310,7 310,7 @@ func TestNewMasked(t *testing.T) {
	}
}

func TestNewCustom(t *testing.T) {
func TestNewCustomMasked(t *testing.T) {
	for i, test := range vectorNewCustomTest {
		myprofileCustom, err := NewCustom(test.params)
		if err != test.expectedNewCustom {

M scrypt.go => scrypt.go +10 -12
@@ 164,24 164,29 @@ func (p *ScryptParams) generateFromParams(salt, password []byte) (out []byte, er
	var params string
	var data []byte

	// if salt mismatch, the profile dictactes, not the hash.
	// the profile dictactes
	psalt := make([]byte, p.Saltlen)
	copy(psalt, salt)

	// password
	data = password

	// we want to hmac a secret to have the resulting hash
	if len(p.secret) > 0 {
		data, err = hmacKeyHash(p.secret, salt, password)
		data, err = hmacKeyHash(p.secret, psalt, password)
		if err != nil {
			return nil, err
		}
	}

	key, err := scrypt.Key(data, salt, int(p.N), int(p.R), int(p.P), int(p.Keylen))
	key, err := scrypt.Key(data, psalt, int(p.N), int(p.R), int(p.P), int(p.Keylen))
	if err != nil {
		return nil, err
	}

	// need to b64.
	//salt64 := base64.StdEncoding.EncodeToString(salt)
	salt64 := base64Encode(salt)
	salt64 := base64Encode(psalt)

	// params
	if !p.Masked {


@@ 233,15 238,8 @@ func (p *ScryptParams) compare(hashed, password []byte) error {
		return ErrMismatch
	}

	// sanity checks.
	// we had a subtle bug where a shorter salt with the same
	// password encrypted would still match, as such you could have
	// potentially generated thousands of small salted password
	// to bruteforce and ran against the comparison function to
	// find a collision which requires less power salts HAVE to
	// be the same size that's it.
	hashlen := uint32(len(compared))
	if uint32(len(hashed)) != hashlen || len(salt) != int(p.Saltlen) {
	if uint32(len(hashed)) != hashlen {
		return ErrMismatch
	}