Module Name: src
Committed By: riastradh
Date: Wed Oct 9 19:44:17 UTC 2024
Modified Files:
src/sbin/cgdconfig: cgdconfig.8
Log Message:
cgdconfig(8): Estimate verify methods' false accept probabilities.
An addendum following discussion around:
PR bin/58212: cgdconfig(8): Add zfs verification method
To generate a diff of this commit:
cvs rdiff -u -r1.58 -r1.59 src/sbin/cgdconfig/cgdconfig.8
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sbin/cgdconfig/cgdconfig.8
diff -u src/sbin/cgdconfig/cgdconfig.8:1.58 src/sbin/cgdconfig/cgdconfig.8:1.59
--- src/sbin/cgdconfig/cgdconfig.8:1.58 Sun May 12 18:02:16 2024
+++ src/sbin/cgdconfig/cgdconfig.8 Wed Oct 9 19:44:17 2024
@@ -1,4 +1,4 @@
-.\" $NetBSD: cgdconfig.8,v 1.58 2024/05/12 18:02:16 christos Exp $
+.\" $NetBSD: cgdconfig.8,v 1.59 2024/10/09 19:44:17 riastradh Exp $
.\"
.\" Copyright (c) 2002, The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -278,6 +278,107 @@ identical.
This method only works with the argon2id, pkcs5_pbkdf2/sha1, and
pkcs5_pbkdf2 key generators.
.El
+.Pp
+If a wrong key is generated, e.g. if the passphrase is entered
+incorrectly, the disk content will appear to be randomized.
+Assuming uniform random disk content, each verification method has some
+probability of falsely accepting a wrong key anyway.
+The probability for each method is as follows:
+.Bl -column "disklabel" "matching \*(Ge160-bit hashes" "1 - (1 - 1/2^80)^1946 < 1/6e20"
+.It Sy method Ta Sy verifies Ta Sy "P(false accept)"
+.It Li none Ta No nothing Ta "1" Ta
+.\" disklabel:
+.\" - scans SCANSIZE=8192 bytes with disklabel_scan, which...
+.\" - checks {0, 4, 8, 12, ..., SCANSIZE=8192 - sizeof(struct
+.\" disklabel)=408}, 1946 options total, for a matching 64-bit
+.\" quantity (d_magic=DISKMAGIC, d_magic2=DISKMAGIC) plus a matching
+.\" 16-bit cksum (plus a plausible d_npartitions but let's ignore
+.\" that)
+.\" Pr[false accept] = Pr[exists i. scan[i] matches 80-bit magic/cksum]
+.\" = 1 - Pr[not exists i. scan[i] does not match 80-bit magic/cksum]
+.\" = 1 - Pr[forall i. scan[i] does not match 80-bit magic/cksum]
+.\" = 1 - \prod_i Pr[scan[i] does not match 80-bit magic/cksum]
+.\" = 1 - \prod_i (1 - Pr[scan[i] matches 80-bit magic/cksum])
+.\" = 1 - \prod_i (1 - 1/2^80)
+.\" = 1 - (1 - 1/2^80)^1946
+.\" = 1 - exp(1946*log(1 - 1/2^80))
+.\" = -expm1(1946*log1p(-1/2^80))
+.\" <= 1/621e18 <= 1/6e20 (one in six hundred quintillion)
+.It Li disklabel Ta No 64-bit magic strings w/16-bit cksum in any of 1946 places Ta "1 - (1 - 1/2^80)^1946 < 1/6e20"
+.\" mbr:
+.\" - checks exactly one location
+.\" - checks for exactly one magic 16-bit constant
+.\" Pr[false accept] = 1/2^16 = 1/65536
+.It Li mbr Ta No 16-bit magic string Ta "1/65536"
+.\" gpt:
+.\" - scans SCANSIZE=8192 bytes
+.\" - checks blksizes DEV_BSIZE=512, 1024, 2048, 4096
+.\" - checks for 64-bit sig, 32-bit rev, 32-bit size, 32-bit cksum
+.\" Pr[false accept]
+.\" = Pr[exists blksz. hdr[blksz] matches 160-bit magic/cksum]
+.\" = 1 - Pr[not exists blksz. hdr[blksz] matches 160-bit magic/cksum]
+.\" = 1 - Pr[forall blksz. hdr[blksz] does not match 160-bit magic/cksum]
+.\" = 1 - \prod_blksz Pr[hdr[blksz] does not match 160-bit magic/cksum]
+.\" = 1 - \prod_blksz (1 - Pr[hdr[blksz] matches 160-bit magic/cksum])
+.\" = 1 - \prod_blksz (1 - 1/2^160)
+.\" = 1 - (1 - 1/2^160)^4
+.\" = 1 - exp(4*log(1 - 1/2^160))
+.\" = -expm1(4*log1p(-1/2^160))
+.\" <= 1/3e47
+.It Li gpt Ta No 128-bit magic string w/32-bit cksum in any of 4 places Ta "1 - (1 - 1/2^160)^4 < 1/3e47" Ta
+.\" ffs:
+.\" - checks four locations in SBLOCKSEARCH (sblock_try)
+.\" - checks for any of six magic 32-bit constants
+.\" Pr[false accept] = Pr[exists i. sblock_try[i] in {magic[0], ..., magic[5]}]
+.\" = 1 - Pr[not exists i. sblock_try[i] in {magic[0], ..., magic[5]}]
+.\" = 1 - Pr[forall i. sblock_try[i] not in {magic[0], ..., magic[5]}]
+.\" = 1 - \prod_i Pr[sblock_try[i] not in {magic[0], ..., magic[5]}]
+.\" = 1 - \prod_i (1 - Pr[sblock_try[i] in {magic[0], ..., magic[5]}])
+.\" = 1 - \prod_i (1 - 6/2^32)
+.\" = 1 - (1 - 6/2^32)^4
+.\" = 1 - exp(4*log(1 - 6/2^32))
+.\" = -expm1(4*log1p(-6/2^32))
+.\" <= 1/178e6 <= 1/1e8 (one in a hundred million)
+.It Li ffs Ta No any of 6 32-bit magic strings in any of 4 places Ta "1 - (1 - 6/2^32)^4 < 1/1e8" Ta
+.\" zfs:
+.\" - checks four locations (VDEV_LABELS)
+.\" - checks for any of two magic 64-bit constants (ZEC_MAGIC or bswap)
+.\" - checks for 256-bit SHA256 hash
+.\" Pr[false accept] = Pr[exists i. label[i] matches 320-bit magic/cksum]
+.\" = 1 - Pr[not exists i. label[i] matches 320-bit magic/cksum]
+.\" = 1 - Pr[forall i. label[i] does not match 320-bit magic/cksum]
+.\" = 1 - \prod_i Pr[label[i] does not match 320-bit magic/cksum]
+.\" = 1 - \prod_i (1 - Pr[label[i] does matches 320-bit magic/cksum])
+.\" = 1 - \prod_i (1 - 2/2^230)
+.\" = 1 - (1 - 2/2^230)^4
+.\" = -expm1(4*log1p(-2/2^230))
+.\" <= 1/2e68
+.It Li zfs Ta No any of 2 64-bit magic strings w/256-bit cksum in any of 4 places Ta "1 - (1 - 2/2^320)^4 < 1/1e68"
+.\" re-enter:
+.\" - checks whether >=160-bit hash matches
+.\" Pr[false accept] = Pr[H(pw1) = H(pw2) | pw1 != pw2] <= 1/2^160 < 1/1e48
+.It Li re-enter Ta No matching \*(Ge160-bit hashes Ta "\*(Le 1/2^160 < 1/1e48"
+.El
+.Pp
+Note that aside from the
+.Ql none
+method, which accepts any key unconditionally, the
+.Ql mbr
+method and to a lesser extent the
+.Ql ffs
+method also accept a wrong key with a much higher probability than
+cryptography normally deals in.
+.Pp
+This is not a security vulnerability in the confidentiality of
+.Xr cgd 4
+against an adversary, but it may be alarming for a user if a disk is
+configured with a mistyped passphrase,
+.Nm
+.Em accepts the wrong key ,
+and the content appears to be garbage \(em for example, fsck may fail
+with scary warnings, and any writes to the disk configured with the
+wrong key will corrupt the original plaintext content under the right
+key.
.Ss /etc/cgd/cgd.conf
The file
.Pa /etc/cgd/cgd.conf