Skip to content

fs,crypto: AAD decryption of fs stream > 32768 bytes fails #31733

Description

@fenying
  • Node.js Version: v12.15.0
  • OS: Linux 5.5.2-arch1-1
  • Scope (install, code, runtime, meta, other?): code
  • Module (and version) (if relevant): crypto (openssl: '1.1.1d')

With a 32768 bytes message, the AES-128-CCM cipher and decipher both work well.
With a 32769 bytes message, the AES-128-CCM cipher works well, but the decipher failed with a message:

Error: Unsupported state or unable to authenticate data
    at Decipheriv._flush (internal/crypto/cipher.js:139:29)
    at Decipheriv.prefinish (_stream_transform.js:140:10)
    at Decipheriv.emit (events.js:223:5)
    at prefinish (_stream_writable.js:670:14)
    at finishMaybe (_stream_writable.js:678:5)
    at endWritable (_stream_writable.js:698:3)
    at Decipheriv.Writable.end (_stream_writable.js:627:5)
    at ReadStream.onend (_stream_readable.js:693:10)
    at Object.onceWrapper (events.js:312:28)
    at ReadStream.emit (events.js:228:7)

I can't understand why. Whatever I change the AAD/IV/authTagLength, it can‘t work.

Here is my code:

// execute after: dd if=/dev/random of=random.bin count=1 bs=32769
const $Crypto = require("crypto");
const $fs = require("fs");

const key = $Crypto.randomBytes(16);

const iv = $Crypto.randomBytes(8);

const aad = $Crypto.randomBytes(1);

const stream = $Crypto.createCipheriv("aes-128-ccm", key, iv, {
    authTagLength: 16
});

stream.setAAD(aad, {
    plaintextLength: 32769
});

$fs.createReadStream("./random.bin").pipe(stream).pipe(
    $fs.createWriteStream("./random.bin.ciphertext")
).on("finish", function() {

    console.info("encrypted");

    const destream = $Crypto.createDecipheriv("aes-128-ccm", key, iv, {
        authTagLength: 16
    });
    
    destream.setAAD(aad, {
        plaintextLength: 32769
    });

    destream.setAuthTag(stream.getAuthTag());
    
    $fs.createReadStream("./random.bin.ciphertext").pipe(destream).pipe(
        $fs.createWriteStream("./random.bin.plaintext")
    );
});

Activity

  1. bnoordhuis commented on Feb 10, 2020

    @bnoordhuis
    Member

    See here - the maximum message size is a function of the IV size. Make it bigger and it'll work.

  2. fenying commented on Feb 11, 2020

    @fenying
    Author

    @bnoordhuis Thx guy, but I have read this article and tried it before. And It doesn't work even if I increase the length of IV to 13 bytes, which is the maximum length of CCM IV.

    const iv = $Crypto.randomBytes(13);
  3. transferred this issue fromnodejs/helpon Feb 11, 2020
  4. added
    cryptoIssues and PRs related to the crypto subsystem.
    fsIssues and PRs related to file-system APIs and the fs module.
    streamIssues and PRs related to Node.js streams.
    on Feb 11, 2020
  5. bnoordhuis commented on Feb 11, 2020

    @bnoordhuis
    Member

    I'm moving this to nodejs/node because this looks like a timing related bug with fs streams. I can reproduce what you're describing but also observe that AAD decryption works with other stream types.

  6. bnoordhuis commented on Feb 11, 2020

    @bnoordhuis
    Member

    I don't have time to investigate right now but I've opened #31734 with a known issues test as a starting point for others.

  7. changed the title [-]Why AES-128-CCM decipher failed when message larger than 32768 bytes[/-] [+]fs,crypto: AAD decryption of fs stream > 32768 bytes fails[/+] on Feb 11, 2020
  8. fenying commented on Feb 11, 2020

    @fenying
    Author

    @bnoordhuis Okay, Thanks.

  9. added a commit that references this issue on Apr 2, 2020
  10. added a commit that references this issue on Apr 12, 2020
  11. added a commit that references this issue on Apr 22, 2020
  12. ronag commented on Jun 20, 2020

    @ronag
    Member

    This might be fixed through #33981

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    confirmed-bugIssues and PRs for confirmed bugs.cryptoIssues and PRs related to the crypto subsystem.fsIssues and PRs related to file-system APIs and the fs module.streamIssues and PRs related to Node.js streams.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions