Skip to content
  • Daniel Rosenberg's avatar
    fscrypt: improve format of no-key names · edc440e3
    Daniel Rosenberg authored
    
    
    When an encrypted directory is listed without the key, the filesystem
    must show "no-key names" that uniquely identify directory entries, are
    at most 255 (NAME_MAX) bytes long, and don't contain '/' or '\0'.
    Currently, for short names the no-key name is the base64 encoding of the
    ciphertext filename, while for long names it's the base64 encoding of
    the ciphertext filename's dirhash and second-to-last 16-byte block.
    
    This format has the following problems:
    
    - Since it doesn't always include the dirhash, it's incompatible with
      directories that will use a secret-keyed dirhash over the plaintext
      filenames.  In this case, the dirhash won't be computable from the
      ciphertext name without the key, so it instead must be retrieved from
      the directory entry and always included in the no-key name.
      Casefolded encrypted directories will use this type of dirhash.
    
    - It's ambiguous: it's possible to craft two filenames that map to the
      same no-key name, since the method used to abbreviate long filenames
      doesn't use a proper cryptographic hash function.
    
    Solve both these problems by switching to a new no-key name format that
    is the base64 encoding of a variable-length structure that contains the
    dirhash, up to 149 bytes of the ciphertext filename, and (if any bytes
    remain) the SHA-256 of the remaining bytes of the ciphertext filename.
    
    This ensures that each no-key name contains everything needed to find
    the directory entry again, contains only legal characters, doesn't
    exceed NAME_MAX, is unambiguous unless there's a SHA-256 collision, and
    that we only take the performance hit of SHA-256 on very long filenames.
    
    Note: this change does *not* address the existing issue where users can
    modify the 'dirhash' part of a no-key name and the filesystem may still
    accept the name.
    
    Signed-off-by: default avatarDaniel Rosenberg <drosen@google.com>
    [EB: improved comments and commit message, fixed checking return value
     of base64_decode(), check for SHA-256 error, continue to set disk_name
     for short names to keep matching simpler, and many other cleanups]
    Link: https://lore.kernel.org/r/20200120223201.241390-7-ebiggers@kernel.org
    
    
    Signed-off-by: default avatarEric Biggers <ebiggers@google.com>
    edc440e3