doFinal method

  1. @override
int doFinal(
  1. Uint8List out,
  2. int outOff
)
override

Implementation

@override
int doFinal(Uint8List out, int outOff) {
  if (outOff < 0) {
    throw ArgumentError('\'outOff\' cannot be negative');
  }

  checkData();

  for (var i = 0; i < _mac.length; i++) {
    _mac[i] = 0x00;
  }

  var resultLen = 0;

  switch (_state) {
    case State.DEC_DATA:
      {
        if (_bufPos < MAC_SIZE) {
          throw ArgumentError('data too short');
        }

        resultLen = _bufPos - MAC_SIZE;

        if (outOff > (out.length - resultLen)) {
          throw ArgumentError('Output buffer too short');
        }

        if (resultLen > 0) {
          poly1305.update(_buf, 0, resultLen);
          processData(_buf, 0, resultLen, out, outOff);
        }

        finishData(State.DEC_FINAL);

        if (!utils.constantTimeAreEqualOffset(
            MAC_SIZE, _mac, 0, _buf, resultLen)) {
          throw ArgumentError('mac check in ChaCha20Poly1305 failed');
        }

        break;
      }
    case State.ENC_DATA:
      {
        resultLen = _bufPos + MAC_SIZE;

        // ignore: invariant_booleans
        if (outOff > (out.length - resultLen)) {
          throw ArgumentError('Output buffer too short');
        }

        if (_bufPos > 0) {
          processData(_buf, 0, _bufPos, out, outOff);
          poly1305.update(out, outOff, _bufPos);
        }

        finishData(State.ENC_FINAL);

        utils.arrayCopy(_mac, 0, out, outOff + _bufPos, MAC_SIZE);
        break;
      }
    default:
      throw StateError('');
  }

  resetBool(false, true);

  return resultLen;
}