delete insecure scheme using HMAC

[Imported from Trac: page NewMutableEncodingDesign, version 8]
davidsarah 2010-01-05 19:40:22 +00:00
parent 937f77871f
commit 582d15aeb3

@ -188,66 +188,10 @@ doesn't even change the way the existing caps are used:
* verifycap = H(pubkey)
* storage-index = truncated verifycap
## Shorter readcaps
(oh, oops, ignore this part. HMACs using the readcap as key are vulnerable to
manipulation by a collusion between Rose-the-readcap-holder and the storage
servers, and could be used to cause another readcap-holder to see the wrong
data. Nevermind.)
To make the readcap shorter, we must give up something, like complete
server-side validation and complete offline attenuation.
* (1K) writecap = K-bit random string = privkey
* (1K) readcap = H(writecap)[:K]
* storage-index = H(readcap)
* verifycap = storage-index + pubkey
The readcap is used as an HMAC key, and the share contains (inside the signed
block) an HMAC of the pubkey. The readcap is also hashed with the per-publish
salt to form the AES key with which the actual data is encrypted.
The writecap begets the readcap, and the readcap begets the storage-index, so
both writers and readers will be able to find the shares, and writecaps can
be attenuated into readcaps offline. Wally the writecap-holder can generate
the pubkey himself and not use (or validate) the value stored in the share.
But Rose the readcap-holder must first retrieve the (pubkey,HMAC) pair and
validate them, then she can use the pubkey to validate the rest of the share.
Wally can generate the verifycap offline, but Rose cannot, since she has to
fetch the pubkey first.
The verifycap must contain a copy of the pubkey (or its hash), because the
storage-index is not usable to validate the pubkey (the HMAC doesn't help,
because it is keyed on the readcap, which is unavailable to the Val the
verifycap-holder). And it must contain a copy of the storage-index, because
the pubkey is insufficient to generate it.
The storage-index must be derived from the readcap, not the pubkey, because
the pubkey is too long to get into the readcap, and Rose the readcap-holder
must have some way of getting the storage-index.
The server can check the signature against the embedded pubkey, but has no
way to confirm that the embedded pubkey is correct, because the validatable
binding between pubkey and storage-index is only available to Rose. You could
copy the verifycap into the share, but there's no cryptographic binding
between it and the storage index. You could put a copy of the storage-index
in the signed block, but again that doesn't prove that the storage-index is
the right one. Only a scheme in which the storage-index is securely derived
from the pubkey will give the desired property.
Another possibility is to have a 2K-long readcap and put K bits of a pubkey
hash in it. That would look like:
* (1K) writecap = K-bit random string = privkey
* (1K) storage-index = H(pubkey)[:K]
* (2K) readcap = H(writecap)[:K] + storage-index
* verifycap = storage-index
This "half-verifycap" approach restores full offline attenuation, and gives
the server 1K bits of validation, but reduces Val the verifycap-holder's
validation bits in half (from 2K to 1K). A full verifycap, H(pubkey), could
be generated offline by Wally, or by Rose after fetching the pubkey. You
still need the HMAC on the pubkey to give Rose 2K confidence that she's got
the right pubkey: the storage-index only gives 1K.
## Shorter readcaps using MAC
This section used to describe a scheme using a MAC (with the read cap as key)
instead of signatures. However this was vulnerable to manipulation by a
collusion between Rose-the-readcap-holder and the storage servers, and
could be used to cause another readcap-holder to see the wrong data.
See the [history](http://allmydata.org/trac/tahoe/wiki/NewMutableEncodingDesign?version=7) if you're interested.