• Ard Biesheuvel's avatar
    SUNRPC: Avoid relying on crypto API to derive CBC-CTS output IV · af97b7df
    Ard Biesheuvel authored
    Scott reports SUNRPC self-test failures regarding the output IV on arm64
    when using the SIMD accelerated implementation of AES in CBC mode with
    ciphertext stealing ("cts(cbc(aes))" in crypto API speak).
    
    These failures are the result of the fact that, while RFC 3962 does
    specify what the output IV should be and includes test vectors for it,
    the general concept of an output IV is poorly defined, and generally,
    not specified by the various algorithms implemented by the crypto API.
    Only algorithms that support transparent chaining (e.g., CBC mode on a
    block boundary) have requirements on the output IV, but ciphertext
    stealing (CTS) is fundamentally about how to encapsulate CBC in a way
    where the length of the entire message may not be an integral multiple
    of the cipher block size, and the concept of an output IV does not exist
    here because it has no defined purpose past the end of the message.
    
    The generic CTS template takes advantage of this chaining capability of
    the CBC implementations, and as a result, happens to return an output
    IV, simply because it passes its IV buffer directly to the encapsulated
    CBC implementation, which operates on full blocks only, and always
    returns an IV. This output IV happens to match how RFC 3962 defines it,
    even though the CTS template itself does not contain any output IV logic
    whatsoever, and, for this reason, lacks any test vectors that exercise
    this accidental output IV generation.
    
    The arm64 SIMD implementation of cts(cbc(aes)) does not use the generic
    CTS template at all, but instead, implements the CBC mode and ciphertext
    stealing directly, and therefore does not encapsule a CBC implementation
    that returns an output IV in the same way. The arm64 SIMD implementation
    complies with the specification and passes all internal tests, but when
    invoked by the SUNRPC code, fails to produce the expected output IV and
    causes its selftests to fail.
    
    Given that the output IV is defined as the penultimate block (where the
    final block may smaller than the block size), we can quite easily derive
    it in the caller by copying the appropriate slice of ciphertext after
    encryption.
    
    Cc: Trond Myklebust <trond.myklebust@hammerspace.com>
    Cc: Anna Schumaker <anna@kernel.org>
    Cc: Chuck Lever <chuck.lever@oracle.com>
    Cc: Jeff Layton <jlayton@kernel.org>
    Reported-by: default avatarScott Mayhew <smayhew@redhat.com>
    Tested-by: default avatarScott Mayhew <smayhew@redhat.com>
    Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
    Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
    af97b7df
gss_krb5_crypto.c 31.1 KB