• David Davidović's avatar
    [sync::nigori] Read/write key derivation method from/to NigoriSpecifics · c1cfff1e
    David Davidović authored
    Add support for the key derivation method field in the NigoriSpecifics
    proto in SyncEncryptionHandlerImpl. Persist the key derivation method
    chosen for new passphrases in NigoriSpecifics. If updating from a remote
    NigoriSpecifics, respect the key derivation method stored there. The
    change is limited to cases when the passphrase type is
    CUSTOM_PASSPHRASE.
    
    A rationale for the change follows.
    
    Prerequisite: if the custom passphrase key derivation method is set to
    PBKDF2 (or UNSPECIFIED), the behavior of all decryption is exactly the
    same as in previous versions.
    
    Let "happy paths" be the encryption and decryption code paths which a
    keystore-enabled client (referring to a client released after the
    support for keystore migrations was introduced) will be able to hit
    starting from a fresh account, if only other keystore-enabled clients
    are syncing to that account.  Since legacy encryption methods are out of
    scope for the change, we need to change the behavior only in these
    "happy paths", and keep the behavior identical in others.
    
    In ApplyNigoriUpdateImpl, we will read the key derivation method from
    Nigori and save it in the class member.
    
    In "happy paths", we will always know what key derivation method will be
    used, and we will always know when we'll end up in a CUSTOM_PASSPHRASE
    state. We will remember the key derivation method in the class as a
    member when applicable. In particular, there are two such paths. Both
    are short-circuits that are much easier to follow than the alternative,
    legacy code paths:
    
    1. |IsNigoriMigratedToKeystore() == true| case in
    SetEncryptionPassphrase(), which calls SetCustomPassphrase() (only call
    site). Here, it is us who are making the decision, so this is obvious.
    
    2. |IsNigoriMigratedToKeystore() == true && ...| case in
    SetDecryptionPassphrase(), which calls
    DecryptPendingKeysWithExplicitPassphrase() (only call site). Here, we
    will use the key derivation method from the member. Since we can't reach
    this path in SetDecryptionPassphrase() without a valid Nigori node, we
    assume that ApplyNigoriUpdateImpl() was called and has saved the key
    derivation method from Nigori in the member.
    
    Since we write the passphrase type to Nigori *only* in
    AttemptToMigrateNigoriToKeystore, we will also write the custom
    passphrase key derivation method *only* there. If the key derivation
    method member is not set at that point (but the passphrase type we are
    writing is CUSTOM_PASSPHRASE), that means we have reached the
    CUSTOM_PASSPHRASE state through some other, non-"happy" path. In this
    case, we will write PBKDF2 as the key derivation method. This will
    ensure that decryption for these cases works the same way as in older
    versions, no matter what.
    
    The only thing that remains is converting an UNSPECIFIED key derivation
    method in Nigori to PBKDF2. We will also do this in
    ApplyNigoriUpdateImpl(), which is called when we receive a remote
    Nigori. Because we expect to set the key derivation method explicitly
    whenever we decide what it is, this will ensure that we use every chance
    we can to set an explicit (rather than UNSPECIFIED) key derivation
    method in Nigori.
    
    Bug: 876408
    Change-Id: Ia793f53f8777ed61af5edda9d8fa21090ad6da43
    Reviewed-on: https://chromium-review.googlesource.com/1187148
    Commit-Queue: David Davidović <davidovic@google.com>
    Reviewed-by: default avatarMarc Treib <treib@chromium.org>
    Reviewed-by: default avatarvitaliii <vitaliii@chromium.org>
    Cr-Commit-Position: refs/heads/master@{#587611}
    c1cfff1e
passphrase_enums.h 2.19 KB