Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decrypting a zero-length array with SubtleCrypto triggers Assertion failures #38883

Closed
TheSpyder opened this issue Jun 1, 2021 · 1 comment
Closed
Labels
confirmed-bug Issues with confirmed bugs. crypto Issues and PRs related to the crypto subsystem. webcrypto

Comments

@TheSpyder
Copy link

TheSpyder commented Jun 1, 2021

  • Version: v16.2.0
  • Platform: Darwin shinji 20.6.0 Darwin Kernel Version 20.6.0: Mon May 10 03:15:35 PDT 2021; root:xnu-7195.140.13.0.1~20/RELEASE_X86_64 x86_64 i386 MacBookPro16,2 Darwin
  • Subsystem: webcrypto (specifically SubtleCrypto)

What steps will reproduce the bug?

Attempting to decrypt a zero-length array crashes node completely. There are two ways to trigger this.

The first encrypts a zero length array and then attempts to decrypt that same data:

const crypto = require('crypto').webcrypto;
crypto.subtle.importKey('raw', new Uint8Array(32), {name: 'AES-GCM'}, false, ['encrypt','decrypt'])
  .then(k =>
    crypto.subtle.encrypt({name: 'AES-GCM', iv: new Uint8Array(12)}, k, new Uint8Array(0))
    .then(e =>
      crypto.subtle.decrypt({name: 'AES-GCM', iv: new Uint8Array(12)}, k, e)
    )
  )
  .then(v => console.log(v));

The second simply decrypts a zero length data array:

const crypto = require('crypto').webcrypto;
crypto.subtle.importKey('raw', new Uint8Array(32), {name: 'AES-GCM'}, false, ['encrypt','decrypt'])
  .then(k => crypto.subtle.decrypt({name: 'AES-GCM', iv: new Uint8Array(12)}, k, new Uint8Array(0)))
  .then(v => console.log(v));

How often does it reproduce? Is there a required condition?

Every time.

What is the expected behavior?

The decrypt call should produce a zero-length array in the first case, and fail in the second (chrome rejects with The provided data is too small).

What do you see instead?

Node crashes. The two snippets trigger different errors.

First:

node[51088]: ../src/crypto/crypto_cipher.h:261:virtual v8::Maybe<bool> node::crypto::CipherJob<node::crypto::AESCipherTraits>::ToResult(v8::Local<v8::Value> *, v8::Local<v8::Value> *) [CipherTraits = node::crypto::AESCipherTraits]: Assertion `!errors->Empty()' failed.
 1: 0x105ac3832 node::Abort() [/usr/local/bin/node]
 2: 0x105ac36be node::AppendExceptionLine(node::Environment*, v8::Local<v8::Value>, v8::Local<v8::Message>, node::ErrorHandlingMode) [/usr/local/bin/node]
 3: 0x105b93582 node::crypto::CipherJob<node::crypto::AESCipherTraits>::DoThreadPoolWork() [/usr/local/bin/node]
 4: 0x105b93309 node::crypto::CryptoJob<node::crypto::AESCipherTraits>::AfterThreadPoolWork(int) [/usr/local/bin/node]
 5: 0x106345d74 uv__work_done [/usr/local/bin/node]
 6: 0x106349528 uv__async_io [/usr/local/bin/node]
 7: 0x106359662 uv__io_poll [/usr/local/bin/node]
 8: 0x10634995e uv_run [/usr/local/bin/node]
 9: 0x105a12624 node::SpinEventLoop(node::Environment*) [/usr/local/bin/node]
10: 0x105afbd35 node::NodeMainInstance::Run(node::EnvSerializeInfo const*) [/usr/local/bin/node]
11: 0x105a9ab72 node::Start(int, char**) [/usr/local/bin/node]
12: 0x7fff20348f5d start [/usr/lib/system/libdyld.dylib]
13: 0x1
Abort trap: 6

Second:

node[51123]: ../src/crypto/crypto_aes.cc:92:node::crypto::WebCryptoCipherStatus node::crypto::(anonymous namespace)::AES_Cipher(node::Environment *, node::crypto::KeyObjectData *, node::crypto::WebCryptoCipherMode, const node::crypto::AESCipherConfig &, const node::crypto::ByteSource &, node::crypto::ByteSource *): Assertion `params.tag' failed.
 1: 0x10d74e832 node::Abort() [/usr/local/bin/node]
 2: 0x10d74e6be node::AppendExceptionLine(node::Environment*, v8::Local<v8::Value>, v8::Local<v8::Message>, node::ErrorHandlingMode) [/usr/local/bin/node]
 3: 0x10d81ccf3 node::crypto::AES::Initialize(node::Environment*, v8::Local<v8::Object>) [/usr/local/bin/node]
 4: 0x10d81e5d6 node::crypto::CipherJob<node::crypto::AESCipherTraits>::DoThreadPoolWork() [/usr/local/bin/node]
 5: 0x10dfd1128 worker [/usr/local/bin/node]
 6: 0x7fff2032d8fc _pthread_start [/usr/lib/system/libsystem_pthread.dylib]
 7: 0x7fff20329443 thread_start [/usr/lib/system/libsystem_pthread.dylib]
Abort trap: 6

Additional information

These inputs are far from normal, but I figure node should never crash.

The project I work on has property tests involving webcrypto. We've been using node-webcrypto-ossl to run these tests for months; we thought it might be nice to switch to the new built-in webcrypto instead. Our property tests are designed to throw all sorts of invalid values at our own code - but it turns out they throw invalid values at the webcrypto API as well.

@Ayase-252
Copy link
Member

cc @nodejs/crypto

@panva panva added confirmed-bug Issues with confirmed bugs. crypto Issues and PRs related to the crypto subsystem. labels Jun 1, 2021
XadillaX added a commit to XadillaX/node that referenced this issue Jun 3, 2021
XadillaX added a commit to XadillaX/node that referenced this issue Jun 3, 2021
XadillaX added a commit to XadillaX/node that referenced this issue Jun 3, 2021
@XadillaX XadillaX reopened this Jun 16, 2021
danielleadams pushed a commit that referenced this issue Jun 21, 2021
Fixes: #38883

PR-URL: #38914
Reviewed-By: Tobias Nießen <[email protected]>
Reviewed-By: James M Snell <[email protected]>
XadillaX added a commit to XadillaX/node that referenced this issue Jun 22, 2021
XadillaX added a commit to XadillaX/node that referenced this issue Jun 24, 2021
XadillaX added a commit to XadillaX/node that referenced this issue Jun 25, 2021
targos pushed a commit that referenced this issue Jul 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed-bug Issues with confirmed bugs. crypto Issues and PRs related to the crypto subsystem. webcrypto
Projects
None yet
4 participants