Skip to content

Commit c34b59f

Browse files
Unix4evertalos-bot
authored andcommitted
feat: expose more encryption options in the LUKS module
Add `xchacha12,aes-adiantum-plain64` and `xchacha20,aes-adiantum-plain64` ciphers. Expose handles for tweaking `--sector-size` and `--key-size`. Provide a way to set some of the `--perf` flags. Signed-off-by: Artem Chernyshev <artem.0xD2@gmail.com>
1 parent 30c2bc3 commit c34b59f

File tree

3 files changed

+103
-5
lines changed

3 files changed

+103
-5
lines changed

blockdevice/encryption/luks/luks.go

Lines changed: 80 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,21 @@ import (
2727
// Cipher LUKS2 cipher type.
2828
type Cipher int
2929

30+
var keySizeDefaults = map[Cipher]uint{
31+
AESXTSPlain64Cipher: 512,
32+
XChaCha12Cipher: 256,
33+
XChaCha20Cipher: 256,
34+
}
35+
3036
// String converts to command line string parameter value.
3137
func (c Cipher) String() (string, error) {
3238
switch c {
3339
case AESXTSPlain64Cipher:
3440
return AESXTSPlain64CipherString, nil
41+
case XChaCha12Cipher:
42+
return XChaCha12String, nil
43+
case XChaCha20Cipher:
44+
return XChaCha20String, nil
3545
default:
3646
return "", fmt.Errorf("unknown cipher kind %d", c)
3747
}
@@ -44,6 +54,10 @@ func ParseCipherKind(s string) (Cipher, error) {
4454
fallthrough
4555
case AESXTSPlain64CipherString:
4656
return AESXTSPlain64Cipher, nil
57+
case XChaCha12String:
58+
return XChaCha12Cipher, nil
59+
case XChaCha20String:
60+
return XChaCha20Cipher, nil
4761
default:
4862
return 0, fmt.Errorf("unknown cipher kind %s", s)
4963
}
@@ -52,16 +66,50 @@ func ParseCipherKind(s string) (Cipher, error) {
5266
const (
5367
// AESXTSPlain64CipherString string representation of aes-xts-plain64 cipher.
5468
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"
5573
// AESXTSPlain64Cipher represents aes-xts-plain64 encryption cipher.
5674
AESXTSPlain64Cipher Cipher = iota
75+
// XChaCha12Cipher represents xchacha12 encryption cipher.
76+
XChaCha12Cipher
77+
// XChaCha20Cipher represents xchacha20 encryption cipher.
78+
XChaCha20Cipher
5779
)
5880

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+
59104
// LUKS implements LUKS2 encryption provider.
60105
type LUKS struct {
106+
perfOptions []string
61107
cipher Cipher
62108
iterTime time.Duration
63109
pbkdfForceIterations uint
64110
pbkdfMemory uint64
111+
blockSize uint64
112+
keySize uint
65113
}
66114

67115
// New creates new LUKS2 encryption provider.
@@ -74,6 +122,10 @@ func New(cipher Cipher, options ...Option) *LUKS {
74122
option(l)
75123
}
76124

125+
if l.keySize == 0 {
126+
l.keySize = keySizeDefaults[cipher]
127+
}
128+
77129
return l
78130
}
79131

@@ -86,6 +138,7 @@ func (l *LUKS) Open(deviceName string, key *encryption.Key) (string, error) {
86138

87139
args := []string{"luksOpen", deviceName, mappedName, "--key-file=-"}
88140
args = append(args, keyslotArgs(key)...)
141+
args = append(args, l.perfArgs()...)
89142

90143
err := l.runCommand(args, key.Value)
91144
if err != nil {
@@ -105,6 +158,11 @@ func (l *LUKS) Encrypt(deviceName string, key *encryption.Key) error {
105158
args := []string{"luksFormat", "--type", "luks2", "--key-file=-", "-c", cipher, deviceName}
106159
args = append(args, l.argonArgs()...)
107160
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+
}
108166

109167
err = l.runCommand(args, key.Value)
110168
if err != nil {
@@ -134,6 +192,7 @@ func (l *LUKS) AddKey(devname string, key, newKey *encryption.Key) error {
134192
}
135193

136194
args = append(args, l.argonArgs()...)
195+
args = append(args, l.encryptionArgs()...)
137196
args = append(args, keyslotArgs(newKey)...)
138197

139198
return l.runCommand(args, buffer.Bytes())
@@ -159,6 +218,7 @@ func (l *LUKS) SetKey(devname string, oldKey, newKey *encryption.Key) error {
159218
}
160219

161220
args = append(args, l.argonArgs()...)
221+
args = append(args, l.perfArgs()...)
162222

163223
return l.runCommand(args, buffer.Bytes())
164224
}
@@ -223,8 +283,6 @@ func (l *LUKS) ReadKeyslots(deviceName string) (*encryption.Keyslots, error) {
223283
return keyslots, nil
224284
}
225285

226-
// CheckKey try using the key
227-
228286
// runCommand executes cryptsetup with arguments.
229287
func (l *LUKS) runCommand(args []string, stdin []byte) error {
230288
_, err := cmd.RunContext(cmd.WithStdin(
@@ -270,6 +328,26 @@ func (l *LUKS) argonArgs() []string {
270328
return args
271329
}
272330

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+
273351
func keyslotArgs(key *encryption.Key) []string {
274352
if key.Slot != encryption.AnyKeyslot {
275353
return []string{fmt.Sprintf("--key-slot=%d", key.Slot)}

blockdevice/encryption/luks/luks_test.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ func (suite *LUKSSuite) TestEncrypt() {
5959
provider := luks.New(
6060
luks.AESXTSPlain64Cipher,
6161
luks.WithIterTime(time.Millisecond*100),
62+
luks.WithPerfOptions(luks.PerfSameCPUCrypt),
6263
)
6364

6465
_, err = g.Add(bootSize, gpt.WithPartitionName("boot"))
@@ -153,9 +154,7 @@ func TestLUKSSuite(t *testing.T) {
153154
t.Skip("can't run the test as non-root")
154155
}
155156

156-
hostname, _ := os.Hostname() //nolint: errcheck
157-
158-
if hostname == "buildkitsandbox" {
157+
if hostname, _ := os.Hostname(); hostname == "buildkitsandbox" { //nolint:errcheck
159158
t.Skip("test not supported under buildkit as partition devices are not propagated from /dev")
160159
}
161160

blockdevice/encryption/luks/options.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,24 @@ func WithPBKDFMemory(value uint64) Option {
3030
l.pbkdfMemory = value
3131
}
3232
}
33+
34+
// WithKeySize sets generated key size.
35+
func WithKeySize(value uint) Option {
36+
return func(l *LUKS) {
37+
l.keySize = value
38+
}
39+
}
40+
41+
// WithBlockSize sets block size.
42+
func WithBlockSize(value uint64) Option {
43+
return func(l *LUKS) {
44+
l.blockSize = value
45+
}
46+
}
47+
48+
// WithPerfOptions enables encryption perf options.
49+
func WithPerfOptions(options ...string) Option {
50+
return func(l *LUKS) {
51+
l.perfOptions = options
52+
}
53+
}

0 commit comments

Comments
 (0)