aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRose Hogenson <rosehogenson@posteo.net>2025-10-24 15:18:39 -0700
committerRose Hogenson <rosehogenson@posteo.net>2025-10-24 15:18:39 -0700
commit466cbd5a1be7d274a45506add79c21e06ee53381 (patch)
tree2cd1049b0e063aa7d37da46721365117ef53614f
parentedd01c62855ff5d1b0ef50a1d9350718cb033c84 (diff)
downloadsym-466cbd5a1be7d274a45506add79c21e06ee53381.tar.zst
Use argon2 for password hashing
-rw-r--r--dec.go6
-rw-r--r--enc.go6
-rw-r--r--go.mod1
-rw-r--r--go.sum2
-rw-r--r--oae.go18
-rw-r--r--pwhash.go9
-rw-r--r--sym_test.go4
7 files changed, 24 insertions, 22 deletions
diff --git a/dec.go b/dec.go
index aa551ad..ae9ec33 100644
--- a/dec.go
+++ b/dec.go
@@ -10,7 +10,7 @@ import (
)
func (o *decryptOptions) decrypt(w io.Writer, r io.Reader, password string) error {
- _, err := io.Copy(w, newDecryptingReader(r, password, o.iterations))
+ _, err := io.Copy(w, newDecryptingReader(r, password, o.memory))
return err
}
@@ -27,14 +27,14 @@ func (f *decryptFlags) registerFlags(fs *flag.FlagSet) {
type decryptOptions struct {
decryptFlags
- iterations int
+ memory int
passwordIn func() (string, error)
stdin io.Reader
stdout io.Writer
}
var defaultDecryptOptions = decryptOptions{
- iterations: defaultPBKDF2Iters,
+ memory: defaultArgon2Memory,
passwordIn: termReadPassword,
stdin: os.Stdin,
stdout: os.Stdout,
diff --git a/enc.go b/enc.go
index 5990121..c24cba8 100644
--- a/enc.go
+++ b/enc.go
@@ -28,7 +28,7 @@ func (f *encryptFlags) registerFlags(fs *flag.FlagSet) {
type encryptOptions struct {
encryptFlags
- iterations int
+ memory int
passwordIn func() (string, error)
passwordOut io.Writer
stdin io.Reader
@@ -36,7 +36,7 @@ type encryptOptions struct {
}
var defaultEncryptOptions = encryptOptions{
- iterations: defaultPBKDF2Iters,
+ memory: defaultArgon2Memory,
passwordIn: termReadPassword,
passwordOut: os.Stderr,
stdin: os.Stdin,
@@ -44,7 +44,7 @@ var defaultEncryptOptions = encryptOptions{
}
func (o *encryptOptions) encrypt(w io.Writer, r io.Reader, password string) error {
- writer := newEncryptingWriter(w, password, o.iterations)
+ writer := newEncryptingWriter(w, password, o.memory)
if _, err := io.Copy(writer, r); err != nil {
return err
}
diff --git a/go.mod b/go.mod
index a1f7c9f..db929f6 100644
--- a/go.mod
+++ b/go.mod
@@ -3,6 +3,7 @@ module roseh.moe/cmd/sym
go 1.25.0
require (
+ golang.org/x/crypto v0.43.0
golang.org/x/term v0.36.0
roseh.moe/pkg/wordlist v1.0.2
)
diff --git a/go.sum b/go.sum
index 2b38e1d..56eda83 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,7 @@
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
+golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
diff --git a/oae.go b/oae.go
index 5b6140c..a4eb6c8 100644
--- a/oae.go
+++ b/oae.go
@@ -21,15 +21,15 @@ const (
)
type segmentEncrypter struct {
- password string
- iterations int
+ password string
+ memory int
aead cipher.AEAD
nonce [nonceSize]byte
}
func (se *segmentEncrypter) initialize(salt []byte) error {
- key, err := hashPassword(se.password, salt, se.iterations)
+ key, err := hashPassword(se.password, salt, se.memory)
if err != nil {
return err
}
@@ -83,12 +83,12 @@ type encryptingWriter struct {
initialized bool
}
-func newEncryptingWriter(w io.Writer, password string, iterations int) *encryptingWriter {
+func newEncryptingWriter(w io.Writer, password string, memory int) *encryptingWriter {
return &encryptingWriter{
w: w,
encrypter: segmentEncrypter{
- password: password,
- iterations: iterations,
+ password: password,
+ memory: memory,
},
}
}
@@ -181,12 +181,12 @@ type decryptingReader struct {
readFinalBlock bool
}
-func newDecryptingReader(r io.Reader, password string, iterations int) *decryptingReader {
+func newDecryptingReader(r io.Reader, password string, memory int) *decryptingReader {
return &decryptingReader{
r: bufio.NewReaderSize(r, 0), // we only need .UnreadByte
decrypter: segmentEncrypter{
- password: password,
- iterations: iterations,
+ password: password,
+ memory: memory,
},
}
}
diff --git a/pwhash.go b/pwhash.go
index 31f1487..dabafa7 100644
--- a/pwhash.go
+++ b/pwhash.go
@@ -1,17 +1,16 @@
package main
import (
- "crypto/pbkdf2"
- "crypto/sha256"
"os"
+ "golang.org/x/crypto/argon2"
"golang.org/x/term"
)
-const defaultPBKDF2Iters = 35_000_000
+const defaultArgon2Memory = 64 * 1024
-func hashPassword(password string, salt []byte, iters int) ([]byte, error) {
- return pbkdf2.Key(sha256.New, password, salt, iters, 32)
+func hashPassword(password string, salt []byte, memory int) ([]byte, error) {
+ return argon2.IDKey([]byte(password), salt, 1, uint32(memory), 4, 32), nil
}
func termReadPassword() (string, error) {
diff --git a/sym_test.go b/sym_test.go
index 4d648d3..bb81ab8 100644
--- a/sym_test.go
+++ b/sym_test.go
@@ -9,13 +9,13 @@ import (
var testEncryptOptions = func() encryptOptions {
opts := defaultEncryptOptions
- opts.iterations = 10
+ opts.memory = 1
return opts
}()
var testDecryptOptions = func() decryptOptions {
opts := defaultDecryptOptions
- opts.iterations = 10
+ opts.memory = 1
return opts
}()