summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorLevi Durfee <levi.durfee@gmail.com>2026-01-07 11:35:07 -0500
committerLevi Durfee <levi.durfee@gmail.com>2026-01-07 11:45:18 -0500
commitac5b030f71434123bea60f9b1d918a59f19fed6a (patch)
tree4472e5c976692c20e68218eb9fe6a56cee201d1c /internal
parentb1f9ade1154df9353f19141d3ca719a8bb7936e8 (diff)
Switch to argon2
Diffstat (limited to 'internal')
-rw-r--r--internal/decrypt.go4
-rw-r--r--internal/encrypt.go3
-rw-r--r--internal/goaes.go40
-rw-r--r--internal/internal.go2
4 files changed, 28 insertions, 21 deletions
diff --git a/internal/decrypt.go b/internal/decrypt.go
index 913201f..470e3c5 100644
--- a/internal/decrypt.go
+++ b/internal/decrypt.go
@@ -1,7 +1,7 @@
package internal
-func Decrypt(edek WrappedDEK, ct Ciphertext) ([]byte, error) {
- kek, err := NewKEKFromEnvB64("GOAES_PASSPHRASE", "GOAES_SALT")
+func Decrypt(edek WrappedDEK, ct Ciphertext, salt Salt) ([]byte, error) {
+ kek, err := NewKEKFromEnvB64("GOAES_PASSPHRASE")
if err != nil {
return nil, err
}
diff --git a/internal/encrypt.go b/internal/encrypt.go
index 204c6f2..3ee73d7 100644
--- a/internal/encrypt.go
+++ b/internal/encrypt.go
@@ -1,7 +1,7 @@
package internal
func Encrypt(data []byte) (EncryptedDataPayload, error) {
- kek, err := NewKEKFromEnvB64("GOAES_PASSPHRASE", "GOAES_SALT")
+ kek, salt, err := NewKEKFromEnvB64("GOAES_PASSPHRASE")
if err != nil {
return EncryptedDataPayload{}, err
}
@@ -23,6 +23,7 @@ func Encrypt(data []byte) (EncryptedDataPayload, error) {
return EncryptedDataPayload{
DEK: edek,
+ Salt: salt,
Payload: ct,
}, nil
}
diff --git a/internal/goaes.go b/internal/goaes.go
index 1923b8e..7d4f476 100644
--- a/internal/goaes.go
+++ b/internal/goaes.go
@@ -4,59 +4,63 @@ import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
- "crypto/sha256"
"encoding/base64"
"errors"
"fmt"
"io"
"os"
- "golang.org/x/crypto/pbkdf2"
+ "golang.org/x/crypto/argon2"
)
const (
- keyIterations = 600_000
- keyLength = 32
+ time = 3
+ memory = 256 * 1024
+ threads = 4
+ keyLen = 32
)
-func NewKEKFromEnvB64(passphraseEnvVar, saltEnvVar string) (KEK, error) {
+func NewKEKFromEnvB64(passphraseEnvVar string) (KEK, Salt, error) {
b64Passphrase := os.Getenv(passphraseEnvVar)
if b64Passphrase == "" {
- return nil, fmt.Errorf("%s is not set", passphraseEnvVar)
- }
-
- b64Salt := os.Getenv(saltEnvVar)
- if b64Salt == "" {
- return nil, fmt.Errorf("%s is not set", saltEnvVar)
+ return nil, nil, fmt.Errorf("%s is not set", passphraseEnvVar)
}
passphrase, err := base64.StdEncoding.DecodeString(b64Passphrase)
if err != nil {
- return nil, fmt.Errorf("decode %s base64: %w", passphraseEnvVar, err)
+ return nil, nil, fmt.Errorf("decode %s base64: %w", passphraseEnvVar, err)
}
- salt, err := base64.StdEncoding.DecodeString(b64Salt)
+ salt, err := NewSalt()
if err != nil {
- return nil, fmt.Errorf("decode %s base64: %w", saltEnvVar, err)
+ return nil, nil, fmt.Errorf("failed to create salt %w", err)
}
- raw := pbkdf2.Key(passphrase, salt, keyIterations, keyLength, sha256.New)
+ raw := argon2.IDKey(passphrase, salt, time, memory, threads, keyLen)
if !validAESKeyLen(len(raw)) {
- return nil, errBadKeyLn
+ return nil, nil, errBadKeyLn
}
- return KEK(raw), nil
+ return KEK(raw), Salt(salt), nil
}
func NewDEK() (DEK, error) {
- key := make([]byte, 32) // AES-256
+ key := make([]byte, 32)
if _, err := io.ReadFull(rand.Reader, key); err != nil {
return nil, fmt.Errorf("random DEK gen: %w", err)
}
return DEK(key), nil
}
+func NewSalt() (Salt, error) {
+ key := make([]byte, 32)
+ if _, err := io.ReadFull(rand.Reader, key); err != nil {
+ return nil, fmt.Errorf("random salt gen: %w", err)
+ }
+ return Salt(key), nil
+}
+
func WrapDEK(dek DEK, kek KEK) (WrappedDEK, error) {
edek, err := encryptAEAD([]byte(dek), []byte(kek), aadWrapDEK)
return WrappedDEK(edek), err
diff --git a/internal/internal.go b/internal/internal.go
index 970232c..0a3bb54 100644
--- a/internal/internal.go
+++ b/internal/internal.go
@@ -7,10 +7,12 @@ type (
DEK []byte
WrappedDEK []byte
Ciphertext []byte
+ Salt []byte
)
type EncryptedDataPayload struct {
DEK WrappedDEK
+ Salt Salt
Payload Ciphertext
}