libgocryptfs/internal/configfile/scrypt.go

107 lines
3.2 KiB
Go
Raw Normal View History

Major refactoring: Split up "cryptfs" into several internal packages "git status" for reference: deleted: cryptfs/cryptfs.go deleted: cryptfs/names_core.go modified: integration_tests/cli_test.go modified: integration_tests/helpers.go renamed: cryptfs/config_file.go -> internal/configfile/config_file.go renamed: cryptfs/config_test.go -> internal/configfile/config_test.go renamed: cryptfs/config_test/.gitignore -> internal/configfile/config_test/.gitignore renamed: cryptfs/config_test/PlaintextNames.conf -> internal/configfile/config_test/PlaintextNames.conf renamed: cryptfs/config_test/StrangeFeature.conf -> internal/configfile/config_test/StrangeFeature.conf renamed: cryptfs/config_test/v1.conf -> internal/configfile/config_test/v1.conf renamed: cryptfs/config_test/v2.conf -> internal/configfile/config_test/v2.conf renamed: cryptfs/kdf.go -> internal/configfile/kdf.go renamed: cryptfs/kdf_test.go -> internal/configfile/kdf_test.go renamed: cryptfs/cryptfs_content.go -> internal/contentenc/content.go new file: internal/contentenc/content_api.go renamed: cryptfs/content_test.go -> internal/contentenc/content_test.go renamed: cryptfs/file_header.go -> internal/contentenc/file_header.go renamed: cryptfs/intrablock.go -> internal/contentenc/intrablock.go renamed: cryptfs/address_translation.go -> internal/contentenc/offsets.go new file: internal/cryptocore/crypto_api.go renamed: cryptfs/gcm_go1.4.go -> internal/cryptocore/gcm_go1.4.go renamed: cryptfs/gcm_go1.5.go -> internal/cryptocore/gcm_go1.5.go renamed: cryptfs/nonce.go -> internal/cryptocore/nonce.go renamed: cryptfs/openssl_aead.go -> internal/cryptocore/openssl_aead.go renamed: cryptfs/openssl_benchmark.bash -> internal/cryptocore/openssl_benchmark.bash renamed: cryptfs/openssl_test.go -> internal/cryptocore/openssl_test.go new file: internal/nametransform/name_api.go new file: internal/nametransform/names_core.go renamed: cryptfs/names_diriv.go -> internal/nametransform/names_diriv.go renamed: cryptfs/names_noiv.go -> internal/nametransform/names_noiv.go renamed: cryptfs/names_test.go -> internal/nametransform/names_test.go new file: internal/nametransform/pad16.go renamed: cryptfs/log.go -> internal/toggledlog/log.go renamed: cryptfs/log_go1.4.go -> internal/toggledlog/log_go1.4.go renamed: cryptfs/log_go1.5.go -> internal/toggledlog/log_go1.5.go modified: main.go modified: masterkey.go modified: pathfs_frontend/file.go modified: pathfs_frontend/file_holes.go modified: pathfs_frontend/fs.go modified: pathfs_frontend/fs_dir.go modified: pathfs_frontend/names.go modified: test.bash
2016-02-06 19:20:54 +01:00
package configfile
import (
"log"
"math"
"os"
Major refactoring: Split up "cryptfs" into several internal packages "git status" for reference: deleted: cryptfs/cryptfs.go deleted: cryptfs/names_core.go modified: integration_tests/cli_test.go modified: integration_tests/helpers.go renamed: cryptfs/config_file.go -> internal/configfile/config_file.go renamed: cryptfs/config_test.go -> internal/configfile/config_test.go renamed: cryptfs/config_test/.gitignore -> internal/configfile/config_test/.gitignore renamed: cryptfs/config_test/PlaintextNames.conf -> internal/configfile/config_test/PlaintextNames.conf renamed: cryptfs/config_test/StrangeFeature.conf -> internal/configfile/config_test/StrangeFeature.conf renamed: cryptfs/config_test/v1.conf -> internal/configfile/config_test/v1.conf renamed: cryptfs/config_test/v2.conf -> internal/configfile/config_test/v2.conf renamed: cryptfs/kdf.go -> internal/configfile/kdf.go renamed: cryptfs/kdf_test.go -> internal/configfile/kdf_test.go renamed: cryptfs/cryptfs_content.go -> internal/contentenc/content.go new file: internal/contentenc/content_api.go renamed: cryptfs/content_test.go -> internal/contentenc/content_test.go renamed: cryptfs/file_header.go -> internal/contentenc/file_header.go renamed: cryptfs/intrablock.go -> internal/contentenc/intrablock.go renamed: cryptfs/address_translation.go -> internal/contentenc/offsets.go new file: internal/cryptocore/crypto_api.go renamed: cryptfs/gcm_go1.4.go -> internal/cryptocore/gcm_go1.4.go renamed: cryptfs/gcm_go1.5.go -> internal/cryptocore/gcm_go1.5.go renamed: cryptfs/nonce.go -> internal/cryptocore/nonce.go renamed: cryptfs/openssl_aead.go -> internal/cryptocore/openssl_aead.go renamed: cryptfs/openssl_benchmark.bash -> internal/cryptocore/openssl_benchmark.bash renamed: cryptfs/openssl_test.go -> internal/cryptocore/openssl_test.go new file: internal/nametransform/name_api.go new file: internal/nametransform/names_core.go renamed: cryptfs/names_diriv.go -> internal/nametransform/names_diriv.go renamed: cryptfs/names_noiv.go -> internal/nametransform/names_noiv.go renamed: cryptfs/names_test.go -> internal/nametransform/names_test.go new file: internal/nametransform/pad16.go renamed: cryptfs/log.go -> internal/toggledlog/log.go renamed: cryptfs/log_go1.4.go -> internal/toggledlog/log_go1.4.go renamed: cryptfs/log_go1.5.go -> internal/toggledlog/log_go1.5.go modified: main.go modified: masterkey.go modified: pathfs_frontend/file.go modified: pathfs_frontend/file_holes.go modified: pathfs_frontend/fs.go modified: pathfs_frontend/fs_dir.go modified: pathfs_frontend/names.go modified: test.bash
2016-02-06 19:20:54 +01:00
"golang.org/x/crypto/scrypt"
"github.com/rfjakob/gocryptfs/v2/internal/cryptocore"
"github.com/rfjakob/gocryptfs/v2/internal/exitcodes"
"github.com/rfjakob/gocryptfs/v2/internal/tlog"
)
const (
2016-10-02 06:14:18 +02:00
// ScryptDefaultLogN is the default scrypt logN configuration parameter.
// logN=16 (N=2^16) uses 64MB of memory and takes 4 seconds on my Atom Z3735F
// netbook.
Major refactoring: Split up "cryptfs" into several internal packages "git status" for reference: deleted: cryptfs/cryptfs.go deleted: cryptfs/names_core.go modified: integration_tests/cli_test.go modified: integration_tests/helpers.go renamed: cryptfs/config_file.go -> internal/configfile/config_file.go renamed: cryptfs/config_test.go -> internal/configfile/config_test.go renamed: cryptfs/config_test/.gitignore -> internal/configfile/config_test/.gitignore renamed: cryptfs/config_test/PlaintextNames.conf -> internal/configfile/config_test/PlaintextNames.conf renamed: cryptfs/config_test/StrangeFeature.conf -> internal/configfile/config_test/StrangeFeature.conf renamed: cryptfs/config_test/v1.conf -> internal/configfile/config_test/v1.conf renamed: cryptfs/config_test/v2.conf -> internal/configfile/config_test/v2.conf renamed: cryptfs/kdf.go -> internal/configfile/kdf.go renamed: cryptfs/kdf_test.go -> internal/configfile/kdf_test.go renamed: cryptfs/cryptfs_content.go -> internal/contentenc/content.go new file: internal/contentenc/content_api.go renamed: cryptfs/content_test.go -> internal/contentenc/content_test.go renamed: cryptfs/file_header.go -> internal/contentenc/file_header.go renamed: cryptfs/intrablock.go -> internal/contentenc/intrablock.go renamed: cryptfs/address_translation.go -> internal/contentenc/offsets.go new file: internal/cryptocore/crypto_api.go renamed: cryptfs/gcm_go1.4.go -> internal/cryptocore/gcm_go1.4.go renamed: cryptfs/gcm_go1.5.go -> internal/cryptocore/gcm_go1.5.go renamed: cryptfs/nonce.go -> internal/cryptocore/nonce.go renamed: cryptfs/openssl_aead.go -> internal/cryptocore/openssl_aead.go renamed: cryptfs/openssl_benchmark.bash -> internal/cryptocore/openssl_benchmark.bash renamed: cryptfs/openssl_test.go -> internal/cryptocore/openssl_test.go new file: internal/nametransform/name_api.go new file: internal/nametransform/names_core.go renamed: cryptfs/names_diriv.go -> internal/nametransform/names_diriv.go renamed: cryptfs/names_noiv.go -> internal/nametransform/names_noiv.go renamed: cryptfs/names_test.go -> internal/nametransform/names_test.go new file: internal/nametransform/pad16.go renamed: cryptfs/log.go -> internal/toggledlog/log.go renamed: cryptfs/log_go1.4.go -> internal/toggledlog/log_go1.4.go renamed: cryptfs/log_go1.5.go -> internal/toggledlog/log_go1.5.go modified: main.go modified: masterkey.go modified: pathfs_frontend/file.go modified: pathfs_frontend/file_holes.go modified: pathfs_frontend/fs.go modified: pathfs_frontend/fs_dir.go modified: pathfs_frontend/names.go modified: test.bash
2016-02-06 19:20:54 +01:00
ScryptDefaultLogN = 16
// From RFC7914, section 2:
// At the current time, r=8 and p=1 appears to yield good
// results, but as memory latency and CPU parallelism increase, it is
// likely that the optimum values for both r and p will increase.
// We reject all lower values that we might get through modified config files.
scryptMinR = 8
scryptMinP = 1
// logN=10 takes 6ms on a Pentium G630. This should be fast enough for all
// purposes. We reject lower values.
scryptMinLogN = 10
// We always generate 32-byte salts. Anything smaller than that is rejected.
scryptMinSaltLen = 32
)
2016-10-02 06:14:18 +02:00
// ScryptKDF is an instance of the scrypt key deriviation function.
type ScryptKDF struct {
// Salt is the random salt that is passed to scrypt
Salt []byte
// N: scrypt CPU/Memory cost parameter
N int
// R: scrypt block size parameter
R int
// P: scrypt parallelization parameter
P int
// KeyLen is the output data length
KeyLen int
}
2016-10-02 06:14:18 +02:00
// NewScryptKDF returns a new instance of ScryptKDF.
func NewScryptKDF(logN int) ScryptKDF {
var s ScryptKDF
Major refactoring: Split up "cryptfs" into several internal packages "git status" for reference: deleted: cryptfs/cryptfs.go deleted: cryptfs/names_core.go modified: integration_tests/cli_test.go modified: integration_tests/helpers.go renamed: cryptfs/config_file.go -> internal/configfile/config_file.go renamed: cryptfs/config_test.go -> internal/configfile/config_test.go renamed: cryptfs/config_test/.gitignore -> internal/configfile/config_test/.gitignore renamed: cryptfs/config_test/PlaintextNames.conf -> internal/configfile/config_test/PlaintextNames.conf renamed: cryptfs/config_test/StrangeFeature.conf -> internal/configfile/config_test/StrangeFeature.conf renamed: cryptfs/config_test/v1.conf -> internal/configfile/config_test/v1.conf renamed: cryptfs/config_test/v2.conf -> internal/configfile/config_test/v2.conf renamed: cryptfs/kdf.go -> internal/configfile/kdf.go renamed: cryptfs/kdf_test.go -> internal/configfile/kdf_test.go renamed: cryptfs/cryptfs_content.go -> internal/contentenc/content.go new file: internal/contentenc/content_api.go renamed: cryptfs/content_test.go -> internal/contentenc/content_test.go renamed: cryptfs/file_header.go -> internal/contentenc/file_header.go renamed: cryptfs/intrablock.go -> internal/contentenc/intrablock.go renamed: cryptfs/address_translation.go -> internal/contentenc/offsets.go new file: internal/cryptocore/crypto_api.go renamed: cryptfs/gcm_go1.4.go -> internal/cryptocore/gcm_go1.4.go renamed: cryptfs/gcm_go1.5.go -> internal/cryptocore/gcm_go1.5.go renamed: cryptfs/nonce.go -> internal/cryptocore/nonce.go renamed: cryptfs/openssl_aead.go -> internal/cryptocore/openssl_aead.go renamed: cryptfs/openssl_benchmark.bash -> internal/cryptocore/openssl_benchmark.bash renamed: cryptfs/openssl_test.go -> internal/cryptocore/openssl_test.go new file: internal/nametransform/name_api.go new file: internal/nametransform/names_core.go renamed: cryptfs/names_diriv.go -> internal/nametransform/names_diriv.go renamed: cryptfs/names_noiv.go -> internal/nametransform/names_noiv.go renamed: cryptfs/names_test.go -> internal/nametransform/names_test.go new file: internal/nametransform/pad16.go renamed: cryptfs/log.go -> internal/toggledlog/log.go renamed: cryptfs/log_go1.4.go -> internal/toggledlog/log_go1.4.go renamed: cryptfs/log_go1.5.go -> internal/toggledlog/log_go1.5.go modified: main.go modified: masterkey.go modified: pathfs_frontend/file.go modified: pathfs_frontend/file_holes.go modified: pathfs_frontend/fs.go modified: pathfs_frontend/fs_dir.go modified: pathfs_frontend/names.go modified: test.bash
2016-02-06 19:20:54 +01:00
s.Salt = cryptocore.RandBytes(cryptocore.KeyLen)
if logN <= 0 {
Major refactoring: Split up "cryptfs" into several internal packages "git status" for reference: deleted: cryptfs/cryptfs.go deleted: cryptfs/names_core.go modified: integration_tests/cli_test.go modified: integration_tests/helpers.go renamed: cryptfs/config_file.go -> internal/configfile/config_file.go renamed: cryptfs/config_test.go -> internal/configfile/config_test.go renamed: cryptfs/config_test/.gitignore -> internal/configfile/config_test/.gitignore renamed: cryptfs/config_test/PlaintextNames.conf -> internal/configfile/config_test/PlaintextNames.conf renamed: cryptfs/config_test/StrangeFeature.conf -> internal/configfile/config_test/StrangeFeature.conf renamed: cryptfs/config_test/v1.conf -> internal/configfile/config_test/v1.conf renamed: cryptfs/config_test/v2.conf -> internal/configfile/config_test/v2.conf renamed: cryptfs/kdf.go -> internal/configfile/kdf.go renamed: cryptfs/kdf_test.go -> internal/configfile/kdf_test.go renamed: cryptfs/cryptfs_content.go -> internal/contentenc/content.go new file: internal/contentenc/content_api.go renamed: cryptfs/content_test.go -> internal/contentenc/content_test.go renamed: cryptfs/file_header.go -> internal/contentenc/file_header.go renamed: cryptfs/intrablock.go -> internal/contentenc/intrablock.go renamed: cryptfs/address_translation.go -> internal/contentenc/offsets.go new file: internal/cryptocore/crypto_api.go renamed: cryptfs/gcm_go1.4.go -> internal/cryptocore/gcm_go1.4.go renamed: cryptfs/gcm_go1.5.go -> internal/cryptocore/gcm_go1.5.go renamed: cryptfs/nonce.go -> internal/cryptocore/nonce.go renamed: cryptfs/openssl_aead.go -> internal/cryptocore/openssl_aead.go renamed: cryptfs/openssl_benchmark.bash -> internal/cryptocore/openssl_benchmark.bash renamed: cryptfs/openssl_test.go -> internal/cryptocore/openssl_test.go new file: internal/nametransform/name_api.go new file: internal/nametransform/names_core.go renamed: cryptfs/names_diriv.go -> internal/nametransform/names_diriv.go renamed: cryptfs/names_noiv.go -> internal/nametransform/names_noiv.go renamed: cryptfs/names_test.go -> internal/nametransform/names_test.go new file: internal/nametransform/pad16.go renamed: cryptfs/log.go -> internal/toggledlog/log.go renamed: cryptfs/log_go1.4.go -> internal/toggledlog/log_go1.4.go renamed: cryptfs/log_go1.5.go -> internal/toggledlog/log_go1.5.go modified: main.go modified: masterkey.go modified: pathfs_frontend/file.go modified: pathfs_frontend/file_holes.go modified: pathfs_frontend/fs.go modified: pathfs_frontend/fs_dir.go modified: pathfs_frontend/names.go modified: test.bash
2016-02-06 19:20:54 +01:00
s.N = 1 << ScryptDefaultLogN
} else {
s.N = 1 << uint32(logN)
}
s.R = 8 // Always 8
s.P = 1 // Always 1
Major refactoring: Split up "cryptfs" into several internal packages "git status" for reference: deleted: cryptfs/cryptfs.go deleted: cryptfs/names_core.go modified: integration_tests/cli_test.go modified: integration_tests/helpers.go renamed: cryptfs/config_file.go -> internal/configfile/config_file.go renamed: cryptfs/config_test.go -> internal/configfile/config_test.go renamed: cryptfs/config_test/.gitignore -> internal/configfile/config_test/.gitignore renamed: cryptfs/config_test/PlaintextNames.conf -> internal/configfile/config_test/PlaintextNames.conf renamed: cryptfs/config_test/StrangeFeature.conf -> internal/configfile/config_test/StrangeFeature.conf renamed: cryptfs/config_test/v1.conf -> internal/configfile/config_test/v1.conf renamed: cryptfs/config_test/v2.conf -> internal/configfile/config_test/v2.conf renamed: cryptfs/kdf.go -> internal/configfile/kdf.go renamed: cryptfs/kdf_test.go -> internal/configfile/kdf_test.go renamed: cryptfs/cryptfs_content.go -> internal/contentenc/content.go new file: internal/contentenc/content_api.go renamed: cryptfs/content_test.go -> internal/contentenc/content_test.go renamed: cryptfs/file_header.go -> internal/contentenc/file_header.go renamed: cryptfs/intrablock.go -> internal/contentenc/intrablock.go renamed: cryptfs/address_translation.go -> internal/contentenc/offsets.go new file: internal/cryptocore/crypto_api.go renamed: cryptfs/gcm_go1.4.go -> internal/cryptocore/gcm_go1.4.go renamed: cryptfs/gcm_go1.5.go -> internal/cryptocore/gcm_go1.5.go renamed: cryptfs/nonce.go -> internal/cryptocore/nonce.go renamed: cryptfs/openssl_aead.go -> internal/cryptocore/openssl_aead.go renamed: cryptfs/openssl_benchmark.bash -> internal/cryptocore/openssl_benchmark.bash renamed: cryptfs/openssl_test.go -> internal/cryptocore/openssl_test.go new file: internal/nametransform/name_api.go new file: internal/nametransform/names_core.go renamed: cryptfs/names_diriv.go -> internal/nametransform/names_diriv.go renamed: cryptfs/names_noiv.go -> internal/nametransform/names_noiv.go renamed: cryptfs/names_test.go -> internal/nametransform/names_test.go new file: internal/nametransform/pad16.go renamed: cryptfs/log.go -> internal/toggledlog/log.go renamed: cryptfs/log_go1.4.go -> internal/toggledlog/log_go1.4.go renamed: cryptfs/log_go1.5.go -> internal/toggledlog/log_go1.5.go modified: main.go modified: masterkey.go modified: pathfs_frontend/file.go modified: pathfs_frontend/file_holes.go modified: pathfs_frontend/fs.go modified: pathfs_frontend/fs_dir.go modified: pathfs_frontend/names.go modified: test.bash
2016-02-06 19:20:54 +01:00
s.KeyLen = cryptocore.KeyLen
return s
}
2016-10-02 06:14:18 +02:00
// DeriveKey returns a new key from a supplied password.
func (s *ScryptKDF) DeriveKey(pw []byte) []byte {
s.validateParams()
k, err := scrypt.Key(pw, s.Salt, s.N, s.R, s.P, s.KeyLen)
if err != nil {
log.Panicf("DeriveKey failed: %v", err)
}
return k
}
// LogN - N is saved as 2^LogN, but LogN is much easier to work with.
// This function gives you LogN = Log2(N).
2016-10-02 06:14:18 +02:00
func (s *ScryptKDF) LogN() int {
return int(math.Log2(float64(s.N)) + 0.5)
}
// validateParams checks that all parameters are at or above hardcoded limits.
// If not, it exists with an error message.
// This makes sure we do not get weak parameters passed through a
// rougue gocryptfs.conf.
func (s *ScryptKDF) validateParams() {
minN := 1 << scryptMinLogN
if s.N < minN {
tlog.Fatal.Println("Fatal: scryptn below 10 is too low to make sense")
os.Exit(exitcodes.ScryptParams)
}
if s.R < scryptMinR {
tlog.Fatal.Printf("Fatal: scrypt parameter R below minimum: value=%d, min=%d", s.R, scryptMinR)
os.Exit(exitcodes.ScryptParams)
}
if s.P < scryptMinP {
tlog.Fatal.Printf("Fatal: scrypt parameter P below minimum: value=%d, min=%d", s.P, scryptMinP)
os.Exit(exitcodes.ScryptParams)
}
if len(s.Salt) < scryptMinSaltLen {
tlog.Fatal.Printf("Fatal: scrypt salt length below minimum: value=%d, min=%d", len(s.Salt), scryptMinSaltLen)
os.Exit(exitcodes.ScryptParams)
}
if s.KeyLen < cryptocore.KeyLen {
tlog.Fatal.Printf("Fatal: scrypt parameter KeyLen below minimum: value=%d, min=%d", s.KeyLen, cryptocore.KeyLen)
os.Exit(exitcodes.ScryptParams)
}
}