Giter VIP home page Giter VIP logo

Comments (17)

AKushWarrior avatar AKushWarrior commented on May 28, 2024 1

@Archprogrammer Woah sorry it's been a while. I was wrapped up in this test suite I've been creating.

I'll try to have it out by the end of this week.

from steel_crypt.

AKushWarrior avatar AKushWarrior commented on May 28, 2024 1

Alright, this feature is actually complete and ready to publish. I'm working on a CMac bug right now; once that's done I'll publish this.

from steel_crypt.

AKushWarrior avatar AKushWarrior commented on May 28, 2024 1

Yes, that is a property of the tag - a shorter tag is a prefix of a longer tag. You can always truncate the tag to the wanted length if you have a longer one and the resulting, shorter tag, will be correct. At least that is how I understand it.

Cool. I'll publish a hotfix for this in a few hours.

from steel_crypt.

AKushWarrior avatar AKushWarrior commented on May 28, 2024

I'll investigate this.

I think that using PaddedBlockCipher for AES-GCM is messing up the encryption. I'm not as sure about the tag length, but my guess is that that can be fixed as well.

PaddingAES.none is something I wanted to avoid (runtime-errors are more frequent; lib harder to use) but, as you said, not having it appears to be causing more trouble.

from steel_crypt.

AKushWarrior avatar AKushWarrior commented on May 28, 2024

Okay, I mostly figured this out:

Internally, in our fork of PointyCastle, tagSize is represented as macSize:

This code is fine.

To conform with the unified BlockCipher interface, we do some things internally:

@override
Uint8List process(Uint8List data) {
var out = Uint8List(_getOutputSize(data.length));
var len = processBytes(data, 0, data.length, out, 0);
len += doFinal(out, len);
return Uint8List.view(out.buffer, 0, len);
}
@override
int processBytes(
Uint8List inp, int inpOff, int len, Uint8List out, int outOff) {
if (len == 0) return 0;
if (forEncryption) {
// all bytes are plain text bytes
return _processCipherBytes(inp, inpOff, len, out, outOff);
}
// last macSize bytes are possibly mac bytes and not cipher text bytes
// -> keep them in buffer
var cipherLen = _lastMacSizeBytesOff + len - macSize;
var resultLen = 0;
if (cipherLen > 0 && _lastMacSizeBytesOff > 0) {
// at least part of the buffer are actually cipher text bytes
// process them and update the buffer
var l = min(_lastMacSizeBytesOff, cipherLen);
resultLen += _processCipherBytes(_lastMacSizeBytes, 0,
min(_lastMacSizeBytesOff, cipherLen), out, outOff);
outOff += resultLen;
cipherLen -= l;
_lastMacSizeBytes.setRange(0, macSize - l, _lastMacSizeBytes.skip(l));
_lastMacSizeBytesOff -= l;
}
if (cipherLen > 0) {
// part of the input are cipher text bytes
resultLen += _processCipherBytes(inp, inpOff, cipherLen, out, outOff);
}
_lastMacSizeBytes.setRange(_lastMacSizeBytesOff,
_lastMacSizeBytesOff + len - cipherLen, inp.skip(inpOff + cipherLen));
_lastMacSizeBytesOff += len - cipherLen;
return resultLen;
}
This code is also fine.

And then, the actual issue resides here:

AEADParameters(KeyParameter(key), 128, ivLocal, aadLocal);
While this is mainly to ensure ease of use (auto-setting the tag to 128 bits, the most secure length), it also screws up anyone who needs the flexibility.

I'm thinking that some serious rearchitecture of AesCrypt is necessary. It just doesn't make sense to abstract GCM and CBC and CTR and ECB in the same method. It creates classes of bugs like this one (which are mostly avoidable).

A better way to do this would be:

var aes = AesCrypt(key); //Usable for literally anything at this point.
print(aes.gcm.encrypt(inp: 'words', iv: iv, tagLength: tl, aad: aad)); //GCM encrypt.
print(aes.ecb.encrypt(inp: 'words')); //ECB encrypt

This bug will be fixed and the new architecture will be implemented in the next commit.

from steel_crypt.

Archprogrammer avatar Archprogrammer commented on May 28, 2024

This sounds excellent - thank you for the quick reply as well!

Will this result in a 2.0.4 (beta) release?

from steel_crypt.

AKushWarrior avatar AKushWarrior commented on May 28, 2024

It will, yeah. I can probably have it done by mid-week.

from steel_crypt.

Archprogrammer avatar Archprogrammer commented on May 28, 2024

Sorry to bug you, but any update on this or a timeframe for an initial attempt?

from steel_crypt.

Archprogrammer avatar Archprogrammer commented on May 28, 2024

Just me nagging again. :)

Any progress on this issue? Is there anything I can do to help out?

from steel_crypt.

AKushWarrior avatar AKushWarrior commented on May 28, 2024

Ugh. I'm really sorry about this. I've been wrapped up in some other things professionally which are kind of a time sink.

Regardless, I'll try to get this update out today.

from steel_crypt.

AKushWarrior avatar AKushWarrior commented on May 28, 2024

@Archprogrammer done with the latest commit and published to pub. See example/example.dart to see the new syntax. You can put in tagLength and aad as named parameters (e.g. the syntax shown above.)

from steel_crypt.

Archprogrammer avatar Archprogrammer commented on May 28, 2024

I'm afraid this doesn't work quite as intended. Testing the new version runs into this problem:

https://github.com/bcgit/pc-dart/blob/52ef0aea5303466c015463a61d8b193994490d78/lib/block/modes/gcm.dart#L37

macSize is required to be 16 in pointycastle.

However - the resulting output looks correct, so it's possible to set the tagSize to 128 bits and just chop off the last 4 bytes to get a 96-bit tag even if this is a bit cumbersome.

Without examining the code further, I'd hazard a guess that the easiest way to support a tagLength argument would be to implement it in steel_crypt as a post-encryption step?

from steel_crypt.

AKushWarrior avatar AKushWarrior commented on May 28, 2024

macSize is required to be 16 in pointycastle.

However - the resulting output looks correct, so it's possible to set the tagSize to 128 bits and just chop off the last 4 bytes to get a 96-bit tag even if this is a bit cumbersome.

Does the output come out to the correct thing if you truncate the last 32 bits? This is pretty minimal overhead for me to implement, so I think I could probably do this.

from steel_crypt.

Archprogrammer avatar Archprogrammer commented on May 28, 2024

Yes, that is a property of the tag - a shorter tag is a prefix of a longer tag. You can always truncate the tag to the wanted length if you have a longer one and the resulting, shorter tag, will be correct. At least that is how I understand it.

from steel_crypt.

AKushWarrior avatar AKushWarrior commented on May 28, 2024

@Archprogrammer I tried to implement this, but decryption doesn't work:

Uint8List encrypt({@required Uint8List inp, @required Uint8List iv, Uint8List aad, int tagLength = 128}) {
    dynamic params = (padding == PaddingAES.none)
        ? AEADParameters(KeyParameter(key), 128, iv, aad)
        : PaddedBlockCipherParameters(
            AEADParameters(KeyParameter(key), 128, iv, aad), null);
    var cipher = (padding == PaddingAES.none)
        ? GCMBlockCipher(AESFastEngine())
        : PaddedBlockCipher('AES/GCM/' + parsePadding(padding));
    cipher.init(true, params);
    return cipher.process(inp).sublist(0, tagLength ~/ 8);
  }

  Uint8List decrypt({@required Uint8List enc, @required Uint8List iv, Uint8List aad, int tagLength = 128}) {
    dynamic params = (padding == PaddingAES.none)
        ? AEADParameters(KeyParameter(key), 128, iv, aad)
        : PaddedBlockCipherParameters(
            AEADParameters(KeyParameter(key), 128, iv, aad), null);
    var cipher = (padding == PaddingAES.none)
        ? GCMBlockCipher(AESFastEngine())
        : BlockCipher('AES/GCM/' + parsePadding(padding));
    cipher.init(false, params);

    return cipher.process(enc);
  }

This is some code that I'm testing (from GcmSatelliteRaw). It fails during decryption because PointyCastle expects an input length that is a multiple of the block size; I may have to "re-pad" the input, but I'm not sure how to go about that.

from steel_crypt.

AKushWarrior avatar AKushWarrior commented on May 28, 2024

I think it's easier to file this as an issue upstream than to try and deal with it here. It's clear that this is a pointycastle issue, not really one with this library. I'll leave this open as a marker for the upstream issue (which I will file when I get around to it).

from steel_crypt.

Archprogrammer avatar Archprogrammer commented on May 28, 2024

Sounds like a good plan - I can adjust the tag outside of steel_crypt for now since I only need to encrypt at the moment, so this works for me right now. Hopefully this can be solved in PointyCastle soon.

Thanks for the help!

from steel_crypt.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.