@@ -27,11 +27,21 @@ import (
27
27
// Cipher LUKS2 cipher type.
28
28
type Cipher int
29
29
30
+ var keySizeDefaults = map [Cipher ]uint {
31
+ AESXTSPlain64Cipher : 512 ,
32
+ XChaCha12Cipher : 256 ,
33
+ XChaCha20Cipher : 256 ,
34
+ }
35
+
30
36
// String converts to command line string parameter value.
31
37
func (c Cipher ) String () (string , error ) {
32
38
switch c {
33
39
case AESXTSPlain64Cipher :
34
40
return AESXTSPlain64CipherString , nil
41
+ case XChaCha12Cipher :
42
+ return XChaCha12String , nil
43
+ case XChaCha20Cipher :
44
+ return XChaCha20String , nil
35
45
default :
36
46
return "" , fmt .Errorf ("unknown cipher kind %d" , c )
37
47
}
@@ -44,6 +54,10 @@ func ParseCipherKind(s string) (Cipher, error) {
44
54
fallthrough
45
55
case AESXTSPlain64CipherString :
46
56
return AESXTSPlain64Cipher , nil
57
+ case XChaCha12String :
58
+ return XChaCha12Cipher , nil
59
+ case XChaCha20String :
60
+ return XChaCha20Cipher , nil
47
61
default :
48
62
return 0 , fmt .Errorf ("unknown cipher kind %s" , s )
49
63
}
@@ -52,16 +66,50 @@ func ParseCipherKind(s string) (Cipher, error) {
52
66
const (
53
67
// AESXTSPlain64CipherString string representation of aes-xts-plain64 cipher.
54
68
AESXTSPlain64CipherString = "aes-xts-plain64"
69
+ // XChaCha12String string representation of xchacha12 cipher.
70
+ XChaCha12String = "xchacha12,aes-adiantum-plain64"
71
+ // XChaCha20String string representation of xchacha20 cipher.
72
+ XChaCha20String = "xchacha20,aes-adiantum-plain64"
55
73
// AESXTSPlain64Cipher represents aes-xts-plain64 encryption cipher.
56
74
AESXTSPlain64Cipher Cipher = iota
75
+ // XChaCha12Cipher represents xchacha12 encryption cipher.
76
+ XChaCha12Cipher
77
+ // XChaCha20Cipher represents xchacha20 encryption cipher.
78
+ XChaCha20Cipher
57
79
)
58
80
81
+ const (
82
+ // PerfNoReadWorkqueue sets --perf-no_read_workqueue.
83
+ PerfNoReadWorkqueue = "no_read_workqueue"
84
+ // PerfNoWriteWorkqueue sets --perf-no_write_workqueue.
85
+ PerfNoWriteWorkqueue = "no_write_workqueue"
86
+ // PerfSameCPUCrypt sets --perf-same_cpu_crypt.
87
+ PerfSameCPUCrypt = "same_cpu_crypt"
88
+ )
89
+
90
+ // ValidatePerfOption checks that specified string is a valid perf option.
91
+ func ValidatePerfOption (value string ) error {
92
+ switch value {
93
+ case PerfNoReadWorkqueue :
94
+ fallthrough
95
+ case PerfNoWriteWorkqueue :
96
+ fallthrough
97
+ case PerfSameCPUCrypt :
98
+ return nil
99
+ }
100
+
101
+ return fmt .Errorf ("invalid perf option %v" , value )
102
+ }
103
+
59
104
// LUKS implements LUKS2 encryption provider.
60
105
type LUKS struct {
106
+ perfOptions []string
61
107
cipher Cipher
62
108
iterTime time.Duration
63
109
pbkdfForceIterations uint
64
110
pbkdfMemory uint64
111
+ blockSize uint64
112
+ keySize uint
65
113
}
66
114
67
115
// New creates new LUKS2 encryption provider.
@@ -74,6 +122,10 @@ func New(cipher Cipher, options ...Option) *LUKS {
74
122
option (l )
75
123
}
76
124
125
+ if l .keySize == 0 {
126
+ l .keySize = keySizeDefaults [cipher ]
127
+ }
128
+
77
129
return l
78
130
}
79
131
@@ -86,6 +138,7 @@ func (l *LUKS) Open(deviceName string, key *encryption.Key) (string, error) {
86
138
87
139
args := []string {"luksOpen" , deviceName , mappedName , "--key-file=-" }
88
140
args = append (args , keyslotArgs (key )... )
141
+ args = append (args , l .perfArgs ()... )
89
142
90
143
err := l .runCommand (args , key .Value )
91
144
if err != nil {
@@ -105,6 +158,11 @@ func (l *LUKS) Encrypt(deviceName string, key *encryption.Key) error {
105
158
args := []string {"luksFormat" , "--type" , "luks2" , "--key-file=-" , "-c" , cipher , deviceName }
106
159
args = append (args , l .argonArgs ()... )
107
160
args = append (args , keyslotArgs (key )... )
161
+ args = append (args , l .encryptionArgs ()... )
162
+
163
+ if l .blockSize != 0 {
164
+ args = append (args , fmt .Sprintf ("--sector-size=%d" , l .blockSize ))
165
+ }
108
166
109
167
err = l .runCommand (args , key .Value )
110
168
if err != nil {
@@ -134,6 +192,7 @@ func (l *LUKS) AddKey(devname string, key, newKey *encryption.Key) error {
134
192
}
135
193
136
194
args = append (args , l .argonArgs ()... )
195
+ args = append (args , l .encryptionArgs ()... )
137
196
args = append (args , keyslotArgs (newKey )... )
138
197
139
198
return l .runCommand (args , buffer .Bytes ())
@@ -159,6 +218,7 @@ func (l *LUKS) SetKey(devname string, oldKey, newKey *encryption.Key) error {
159
218
}
160
219
161
220
args = append (args , l .argonArgs ()... )
221
+ args = append (args , l .perfArgs ()... )
162
222
163
223
return l .runCommand (args , buffer .Bytes ())
164
224
}
@@ -223,8 +283,6 @@ func (l *LUKS) ReadKeyslots(deviceName string) (*encryption.Keyslots, error) {
223
283
return keyslots , nil
224
284
}
225
285
226
- // CheckKey try using the key
227
-
228
286
// runCommand executes cryptsetup with arguments.
229
287
func (l * LUKS ) runCommand (args []string , stdin []byte ) error {
230
288
_ , err := cmd .RunContext (cmd .WithStdin (
@@ -270,6 +328,26 @@ func (l *LUKS) argonArgs() []string {
270
328
return args
271
329
}
272
330
331
+ func (l * LUKS ) perfArgs () []string {
332
+ res := []string {}
333
+
334
+ for _ , o := range l .perfOptions {
335
+ res = append (res , fmt .Sprintf ("--perf-%s" , o ))
336
+ }
337
+
338
+ return res
339
+ }
340
+
341
+ func (l * LUKS ) encryptionArgs () []string {
342
+ res := []string {}
343
+
344
+ if l .keySize != 0 {
345
+ res = append (res , fmt .Sprintf ("--key-size=%d" , l .keySize ))
346
+ }
347
+
348
+ return append (res , l .perfArgs ()... )
349
+ }
350
+
273
351
func keyslotArgs (key * encryption.Key ) []string {
274
352
if key .Slot != encryption .AnyKeyslot {
275
353
return []string {fmt .Sprintf ("--key-slot=%d" , key .Slot )}
0 commit comments