luks.go is a pure-Go library for working with LUKS-encrypted volumes.
This library focuses on the read-only (unlocking) path — it reads LUKS metadata and recovers volume keys without modifying the LUKS header.
go get github.com/anatol/luks.go
Requires Linux (uses device-mapper via /dev/mapper).
OpenWithHeader)pbkdf2, argon2i, argon2iddev, err := luks.Open("/dev/sda1")
if err != nil {
log.Fatal(err)
}
defer dev.Close()
// Unlock a specific slot and create a device mapper entry.
// Equivalent to: cryptsetup open /dev/sda1 volumename
if err := dev.Unlock(0, []byte("password"), "volumename"); err == luks.ErrPassphraseDoesNotMatch {
log.Fatal("wrong password")
} else if err != nil {
log.Fatal(err)
}
// /dev/mapper/volumename is now available
// Close the mapper when done.
// Equivalent to: cryptsetup close volumename
if err := luks.Lock("volumename"); err != nil {
log.Fatal(err)
}
if err := dev.UnlockAny([]byte("password"), "volumename"); err != nil {
log.Fatal(err)
}
dev, err := luks.OpenWithHeader("/dev/sda1", "/path/to/header.bin")
// Set flags before unlocking
dev.FlagsAdd(luks.FlagAllowDiscards)
dev.FlagsAdd(luks.FlagNoReadWorkqueue, luks.FlagNoWriteWorkqueue)
// Get current flags
flags := dev.FlagsGet()
// Clear all flags
dev.FlagsClear()
Available flags:
FlagAllowDiscards — pass discard/TRIM requests through (SSD-friendly, reduces security)FlagSameCPUCrypt — perform encryption on the same CPU as the IOFlagSubmitFromCryptCPUs — submit IO from crypto CPUsFlagNoReadWorkqueue — bypass read workqueue (Linux 5.9+)FlagNoWriteWorkqueue — bypass write workqueue (Linux 5.9+)UnsealVolume recovers the key without activating the mapper, allowing inspection or
custom dm-crypt setup:
volume, err := dev.UnsealVolume(0, []byte("password"))
if err == luks.ErrPassphraseDoesNotMatch {
log.Fatal("wrong password")
} else if err != nil {
log.Fatal(err)
}
// volume contains encryption parameters; activate when ready
if err := volume.SetupMapper("volumename"); err != nil {
log.Fatal(err)
}
Tokens are LUKS v2 metadata entries (or luksmeta entries for LUKS v1) that carry supplementary information for unlocking tools like clevis or systemd-fido2.
tokens, err := dev.Tokens()
for _, t := range tokens {
fmt.Printf("token %d: type=%s slots=%v\n", t.ID, t.Type, t.Slots)
// t.Payload contains the raw JSON (LUKS v2) or binary (LUKS v1) token data
}
fmt.Println(dev.Version()) // 1 or 2
fmt.Println(dev.UUID())
fmt.Println(dev.Slots()) // active keyslot IDs, sorted by priority (LUKS v2)
fmt.Println(dev.Path())
The unlock process follows these steps for both LUKS v1 and v2:
See LICENSE.
Go
100.0%
luks.go is a pure-Go library for working with LUKS-encrypted volumes.
This library focuses on the read-only (unlocking) path — it reads LUKS metadata and recovers volume keys without modifying the LUKS header.
go get github.com/anatol/luks.go
Requires Linux (uses device-mapper via /dev/mapper).
OpenWithHeader)pbkdf2, argon2i, argon2iddev, err := luks.Open("/dev/sda1")
if err != nil {
log.Fatal(err)
}
defer dev.Close()
// Unlock a specific slot and create a device mapper entry.
// Equivalent to: cryptsetup open /dev/sda1 volumename
if err := dev.Unlock(0, []byte("password"), "volumename"); err == luks.ErrPassphraseDoesNotMatch {
log.Fatal("wrong password")
} else if err != nil {
log.Fatal(err)
}
// /dev/mapper/volumename is now available
// Close the mapper when done.
// Equivalent to: cryptsetup close volumename
if err := luks.Lock("volumename"); err != nil {
log.Fatal(err)
}
if err := dev.UnlockAny([]byte("password"), "volumename"); err != nil {
log.Fatal(err)
}
dev, err := luks.OpenWithHeader("/dev/sda1", "/path/to/header.bin")
// Set flags before unlocking
dev.FlagsAdd(luks.FlagAllowDiscards)
dev.FlagsAdd(luks.FlagNoReadWorkqueue, luks.FlagNoWriteWorkqueue)
// Get current flags
flags := dev.FlagsGet()
// Clear all flags
dev.FlagsClear()
Available flags:
FlagAllowDiscards — pass discard/TRIM requests through (SSD-friendly, reduces security)FlagSameCPUCrypt — perform encryption on the same CPU as the IOFlagSubmitFromCryptCPUs — submit IO from crypto CPUsFlagNoReadWorkqueue — bypass read workqueue (Linux 5.9+)FlagNoWriteWorkqueue — bypass write workqueue (Linux 5.9+)UnsealVolume recovers the key without activating the mapper, allowing inspection or
custom dm-crypt setup:
volume, err := dev.UnsealVolume(0, []byte("password"))
if err == luks.ErrPassphraseDoesNotMatch {
log.Fatal("wrong password")
} else if err != nil {
log.Fatal(err)
}
// volume contains encryption parameters; activate when ready
if err := volume.SetupMapper("volumename"); err != nil {
log.Fatal(err)
}
Tokens are LUKS v2 metadata entries (or luksmeta entries for LUKS v1) that carry supplementary information for unlocking tools like clevis or systemd-fido2.
tokens, err := dev.Tokens()
for _, t := range tokens {
fmt.Printf("token %d: type=%s slots=%v\n", t.ID, t.Type, t.Slots)
// t.Payload contains the raw JSON (LUKS v2) or binary (LUKS v1) token data
}
fmt.Println(dev.Version()) // 1 or 2
fmt.Println(dev.UUID())
fmt.Println(dev.Slots()) // active keyslot IDs, sorted by priority (LUKS v2)
fmt.Println(dev.Path())
The unlock process follows these steps for both LUKS v1 and v2:
See LICENSE.
Go
100.0%