Cybersecurity-Projects/PROJECTS/beginner/steganography-multi-tool/internal/payload/crypto.go

76 lines
1.5 KiB
Go

/*
©AngelaMos | 2026
crypto.go
Argon2id key derivation and AEAD selection for the payload envelope
*/
package payload
import (
"crypto/aes"
"crypto/cipher"
"golang.org/x/crypto/argon2"
"golang.org/x/crypto/chacha20poly1305"
)
type kdfParams struct {
time uint32
memory uint32
threads uint8
}
func paramsForStrength(s Strength) kdfParams {
if s == StrengthHigh {
return kdfParams{time: argonHighTime, memory: argonHighMemory, threads: argonThreads}
}
return kdfParams{time: argonDefaultTime, memory: argonDefaultMemory, threads: argonThreads}
}
func (p kdfParams) valid() bool {
if p.threads == 0 || p.time == 0 {
return false
}
if p.memory > argonMaxMemory {
return false
}
return p.memory >= 8*uint32(p.threads)
}
func deriveKey(passphrase, salt []byte, p kdfParams) []byte {
return argon2.IDKey(passphrase, salt, p.time, p.memory, p.threads, keyLen)
}
func newAEAD(c Cipher, key []byte) (cipher.AEAD, byte, error) {
switch c {
case CipherAES256GCM:
aead, err := gcm(key)
return aead, cipherIDAES256GCM, err
case CipherChaCha20, "":
aead, err := chacha20poly1305.New(key)
return aead, cipherIDChaCha20, err
default:
return nil, 0, ErrUnknownCipher
}
}
func aeadByID(id byte, key []byte) (cipher.AEAD, error) {
switch id {
case cipherIDAES256GCM:
return gcm(key)
case cipherIDChaCha20:
return chacha20poly1305.New(key)
default:
return nil, ErrUnknownCipher
}
}
func gcm(key []byte) (cipher.AEAD, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
return cipher.NewGCM(block)
}