mirror of
https://github.com/jeremyd/ergo.git
synced 2026-05-29 21:29:27 -07:00
implement SCRAM-SHA-256
This commit is contained in:
76
vendor/github.com/xdg-go/pbkdf2/pbkdf2.go
generated
vendored
Normal file
76
vendor/github.com/xdg-go/pbkdf2/pbkdf2.go
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
// Copyright 2021 by David A. Golden. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
// Package pbkdf2 implements password-based key derivation using the PBKDF2
|
||||
// algorithm described in RFC 2898 and RFC 8018.
|
||||
//
|
||||
// It provides a drop-in replacement for `golang.org/x/crypto/pbkdf2`, with
|
||||
// the following benefits:
|
||||
//
|
||||
// - Released as a module with semantic versioning
|
||||
//
|
||||
// - Does not pull in dependencies for unrelated `x/crypto/*` packages
|
||||
//
|
||||
// - Supports Go 1.9+
|
||||
//
|
||||
// See https://tools.ietf.org/html/rfc8018#section-4 for security considerations
|
||||
// in the selection of a salt and iteration count.
|
||||
package pbkdf2
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"encoding/binary"
|
||||
"hash"
|
||||
)
|
||||
|
||||
// Key generates a derived key from a password using the PBKDF2 algorithm. The
|
||||
// inputs include salt bytes, the iteration count, desired key length, and a
|
||||
// constructor for a hashing function. For example, for a 32-byte key using
|
||||
// SHA-256:
|
||||
//
|
||||
// key := Key([]byte("trustNo1"), salt, 10000, 32, sha256.New)
|
||||
func Key(password, salt []byte, iterCount, keyLen int, h func() hash.Hash) []byte {
|
||||
prf := hmac.New(h, password)
|
||||
hLen := prf.Size()
|
||||
numBlocks := keyLen / hLen
|
||||
// Get an extra block if keyLen is not an even number of hLen blocks.
|
||||
if keyLen%hLen > 0 {
|
||||
numBlocks++
|
||||
}
|
||||
|
||||
Ti := make([]byte, hLen)
|
||||
Uj := make([]byte, hLen)
|
||||
dk := make([]byte, 0, hLen*numBlocks)
|
||||
buf := make([]byte, 4)
|
||||
|
||||
for i := uint32(1); i <= uint32(numBlocks); i++ {
|
||||
// Initialize Uj for j == 1 from salt and block index.
|
||||
// Initialize Ti = U1.
|
||||
binary.BigEndian.PutUint32(buf, i)
|
||||
prf.Reset()
|
||||
prf.Write(salt)
|
||||
prf.Write(buf)
|
||||
Uj = Uj[:0]
|
||||
Uj = prf.Sum(Uj)
|
||||
|
||||
// Ti = U1 ^ U2 ^ ... ^ Ux
|
||||
copy(Ti, Uj)
|
||||
for j := 2; j <= iterCount; j++ {
|
||||
prf.Reset()
|
||||
prf.Write(Uj)
|
||||
Uj = Uj[:0]
|
||||
Uj = prf.Sum(Uj)
|
||||
for k := range Uj {
|
||||
Ti[k] ^= Uj[k]
|
||||
}
|
||||
}
|
||||
|
||||
// DK = concat(T1, T2, ... Tn)
|
||||
dk = append(dk, Ti...)
|
||||
}
|
||||
|
||||
return dk[0:keyLen]
|
||||
}
|
||||
Reference in New Issue
Block a user