镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Support GMAC and multiple AAD chunks for AEAD #48314

Description

@tniessen

What is the problem this feature will solve?

Node.js only allows a single call to setAAD() for AEAD algorithms. AAD that consists of multiple chunks must be concatenated in memory before it can be passed to setAAD(), which is highly inefficient.

GMAC is a MAC algorithm based on AES-GCM that consumes the entire input data as AAD and leaves the plaintext/ciphertext empty. The AES-GCM authentication tag is the MAC produced by GMAC. Implementing GMAC on top of Node.js again requires concatenating all input data in memory before calling setAAD().

What is the feature you are proposing to solve the problem?

Extend the API to allow appending multiple chunks of AAD. This is common practice and supported by various cryptographic libraries, including OpenSSL.

We should consider carefully if such an extension should be a separate WritableStream or if a simpler API makes more sense.

What alternatives have you considered?

Concatenating all data in memory before passing it to setAAD().

My primary use case for multiple calls to setAAD() is GMAC, so a separate GMAC API (similar to the existing HMAC API) would also be sufficient for my purposes. However, it would leave a gap between AES-GCM and GMAC for those rare use cases that have multiple chunks of AAD and a non-empty plaintext/ciphertext.

On a side note, I preliminarily decided against adding streaming support for AAD in https://github.com/wintercg/proposal-webcrypto-streams, see this section of the explainer. However, that is mostly due to the API constraints of the Web Crypto API.

Activity

  1. added
    cryptoIssues and PRs related to the crypto subsystem.
    feature requestIssues requesting new Node.js features.
    on Jun 3, 2023
  2. bnoordhuis commented on Jun 5, 2023

    @bnoordhuis
    Member

    Relaxing the rule that setAAD() is only called once would fix that, right?

    We may want to relax it only for GMAC but I don't know how you distinguish between GMAC and regular GCM mode. By checking for non-AAD input?

  3. tniessen commented on Jun 5, 2023

    @tniessen
    MemberAuthor

    Relaxing the rule that setAAD() is only called once would fix that, right?

    Yes, that is the simplest solution I believe. Only the function's name might be misleading. Other libraries typically use "update" or "append".

    We may want to relax it only for GMAC but I don't know how you distinguish between GMAC and regular GCM mode. By checking for non-AAD input?

    Yes, GMAC is defined to be GCM with empty plaintext/ciphertext. If we go that route, I think we might as well avoid the Cipher/Decipher classes altogether and add a Hmac-like API for GMAC. A few crypto libraries have done that (e.g., libgcrypt). However, the vast majority of libraries that I have worked with support multiple AAD chunks even with regular AES-GCM. This includes OpenSSL, Mbed TLS, Nettle, CMOX, and Crypto++ if I remember correctly.

  4. github-actions commented on Dec 3, 2023

    @github-actions
  5. added
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on Dec 3, 2023
  6. tniessen commented on Dec 3, 2023

    @tniessen
    MemberAuthor

    @bnoordhuis Do you have a strong preference among those options? :)

  7. removed
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on Dec 4, 2023
  8. added
    never-staleIssues and PRs exempt from automated stale handling.
    on May 21, 2024
  9. moved this from Awaiting Triage to In Progress in Node.js feature requestson Aug 26, 2026
  10. added a commit that references this issue on Aug 29, 2026
  11. panva commented on Aug 29, 2026

    @panva
    Member

    This seems to have always worked?

    const gmac = createCipheriv(cipher, key, iv);
    gmac.setAAD(chunk1);
    gmac.setAAD(chunk2);
    gmac.final();
    const tag = gmac.getAuthTag();

    And this is now on main slated for the next v26.x release from #65553

    const gmac = createMac('GMAC', key, { cipher, iv });
    gmac.update(chunk1);
    gmac.update(chunk2);
    const tag = gmac.final();

    @tniessen am I right to assume this fully resolved?

  12. removed
    never-staleIssues and PRs exempt from automated stale handling.
    on Aug 29, 2026
  13. added a commit that references this issue on Sep 3, 2026
  14. added a commit that references this issue on Sep 15, 2026
  15. added a commit that references this issue on Sep 21, 2026
  16. panva commented on Sep 23, 2026

    @panva
    Member

    Resolved in #65553

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

    cryptoIssues and PRs related to the crypto subsystem.feature requestIssues requesting new Node.js features.

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions