Skip to content

bug: browser AES-CTR exposes inconsistent errors for invalid counter bit lengths #392

Description

@harrshita123

Summary

The browser implementation of AesCtrSecretKey.encryptBytes and decryptBytes forwards length to SubtleCrypto without validating the AES-CTR counter length range first.

The native backend validates that length is between 1 and 128 and throws ArgumentError. In browsers, invalid values are instead handled at the Web IDL or Web Crypto boundary. Values outside the Web IDL octet range can expose a raw JavaScript TypeError, while other invalid AES-CTR lengths produce OperationError.

This makes the public API behavior dependent on the selected backend.

Reproduction

import 'package:webcrypto/webcrypto.dart';

Future<void> main() async {
  final key = await AesCtrSecretKey.importRawKey(List.filled(16, 0));
  final counter = List.filled(16, 0);

  await key.encryptBytes([1, 2, 3], counter, -1);
}

Native result

Invalid argument (length): must be between 1 and 128: -1

Chrome result

TypeError: Failed to execute 'encrypt' on 'SubtleCrypto':
AesCtrParams: length: Outside of numeric range

The browser result occurs under both dart2js and dart2wasm.

Expected behavior

AES-CTR length values outside 1..128 should be rejected consistently with ArgumentError before entering browser interop, matching the native backend.

Both encryption and decryption should have the same behavior.

Cause

Web Crypto defines AesCtrParams.length as an [EnforceRange] octet. The browser backend currently passes the Dart integer directly to SubtleCrypto, while the native backend performs an explicit 1..128 validation.

Suggested fix

  • Validate 1 <= length <= 128 in the browser AES-CTR implementation before calling SubtleCrypto.
  • Apply the validation to encryption and decryption.
  • Add shared regression coverage for -1, 0, 129, and 256.
  • Run the regression on native, Chrome/dart2js, and Chrome/dart2wasm.

Activity

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions