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

Reply via email to