Giter Club home page Giter Club logo

Comments (16)

DurandA avatar DurandA commented on June 15, 2024 1

Here are some useful resources:

@martindisch and me are attempting to do an implementation of AES-CCM in Rust using TinyCrypt as a reference implementation. Among other notable implementations there is aes-ccm from wpa_supplicant. @marcovr is also interested in OSCORE with libcose.

from libcose.

bergzand avatar bergzand commented on June 15, 2024

As discussed on IRC, I'd like to start restricting the crypto to algorithms to ciphers that allow some sort of incremental API. This to reduce the memory requirements for COSE (not needing a message twice in different structures). In practice, this restricts libcose to 'on-line' stream ciphers.

With AES-CCM, the message size and the length of the authenticated data needs to be known up front. For this reason, most crypto libraries don't implement it with an incremental API. If there is a library implementing CCM with an API where the authenticated data can be supplied with an incremental API, I can add support for it.

from libcose.

bergzand avatar bergzand commented on June 15, 2024

If there is a library implementing CCM with an API where the authenticated data can be supplied with an incremental API, I can add support for it.

Of course the library should be somewhat suitable for embedded applications (no malloc and such :) )

from libcose.

chrysn avatar chrysn commented on June 15, 2024

So far I've looked at

  • libsodium: no streaming AEAD (and no AES-CCM, for that matter)
  • wolfCrypt: no steraming AEAD (but given their interest in embedded applications, maybe they can be persuaded to add it)
  • openssl: streaming AEAD (see example, esp. "zero or more calls" part) but not particularly embedded friendly
    and thus did not find a suitable candidate.
    That's by no means comprehensive, but if the trend continues it may mean that a libcose backend just can't implement the OSCORE mandatory-to-implement AES-CCM. Not too much of an issue IMO as that'll affect other crypto backends just as well -- and when one turns up to be usable, it can still be added to libcose.

from libcose.

chrysn avatar chrysn commented on June 15, 2024

Apologies, I mixed things up: AES-CCM is not available in OpenSSL in a streaming manner, only AES-GCM is. At least the payload length (possibly also the AAD length; wikipedia claims that, I don't quite see why from the tinycrypt implementation -- edit: readingccm_cbc_mac with flag=1 which is set for AAD, now I do) needs to be known in advance for AES-CCM before the first AAD data is fed.

That, to me, begs the question of what the precise incremental API would be: Should it be

  • the strong incremental form, where the length of the AAD and payload does not need to be known in advance (ruling out AES-CCM altogether), or
  • the weak incremental form, where the caller needs to provide AAD and plaintext lengths, but can then feed the AAD and plaintext / ciphertext in chunk by chunk?

For OSCORE, I require only the weak version (because the AAD's length is effectively encoded inside itself somewhere in the first few bytes, and by the time I know the AAD's full length I also know the payload length, and only then can actually start feeding in AAD data). Are there cases in COSE where the implementation would profit from the strong form?

from libcose.

chrysn avatar chrysn commented on June 15, 2024

In case that helps with the incremental API part, here's the backend interface I'm currently describing: oscore_crypto_aead_encrypt_start and friends (the decrypt part is still in the nonincremental form). It's tailored towards what OSCORE needs (ie. knows payload and AAD lengths in advance, does AEAD in place and wants the tag after the ciphertext).

from libcose.

bergzand avatar bergzand commented on June 15, 2024

For OSCORE, I require only the weak version (because the AAD's length is effectively encoded inside itself somewhere in the first few bytes, and by the time I know the AAD's full length I also know the payload length, and only then can actually start feeding in AAD data).

This should be the same for COSE.

Are there cases in COSE where the implementation would profit from the strong form?

From the top of my head: no, don't think so.

The practical issue here is that for a crypto backend library, supporting this weak incremental form allows for easy misuse of the library by having a mismatch between the claimed AAD length (supplied with the first initialization call) and the actual supplied number of bytes for the AAD. I think COSE (and with that OSCORE) is more an exception where it is almost a hard requirement to use this weak incremental form.

To be honest, I don't mind wrapping the basic CBC-MAC and AES-CTR calls if that would allow libcose to support AES-CCM using the weak incremental form.

from libcose.

DurandA avatar DurandA commented on June 15, 2024

To be honest, I don't mind wrapping the basic CBC-MAC and AES-CTR calls if that would allow libcose to support AES-CCM using the weak incremental form.

Be careful as AES-CCM uses its own version of CBC-MAC and AES-CTR.

from libcose.

bergzand avatar bergzand commented on June 15, 2024

Be careful as AES-CCM uses its own version of CBC-MAC and AES-CTR.

I'm aware that I should carefully read the spec before attempting to implement this. I'd also like to have some tests against a known working AES-CCM implementation in the CI to validate the wrapping.

from libcose.

bergzand avatar bergzand commented on June 15, 2024

Here are some useful resources:

Thanks!

from libcose.

chrysn avatar chrysn commented on June 15, 2024

@martindisch and me are attempting to do an implementation of AES-CCM in Rust

I think that would make quite an interesting additional backend to libcose, and could be a practical example of the Rust backends libraries useful in RIOT which I'm looking for in RIOT-OS/RIOT#9799.

from libcose.

chrysn avatar chrysn commented on June 15, 2024

To propose a concrete way forward here, would this work for you?

  • Add an API that reflects the weak incremental form, with roughly init(*struct, algorithm, AEAD length), feed_aad(*struct, AAD bytes), {encrypt,decrypt}(*struct, source area, destination area, tag area)
  • Backends are changed to the incremental API
  • The old API can still be served by a three-line compatibility implementation if it was public
  • Change internal users to the new API
  • Some backends will initially not support incremental API well (ie. require contiguous memory input); they would need to resort to dynamic memory management (yikes I know, but it's only for the low-quality backends…) to build a scratch buffer into which the fed AAD parts are placed. If that's done in a clever fashion, it can be possible to avoid memory allocation if all the AAD happens to be fed in at a single feed call – but being clever here may not be worth it, as we're aiming for high-quality streamable backends anyway, and the dynamic memory part is more of a migration helper.

Having this library as a showcase may help making the case for AAD streaming at backend libraries (@danielinux, would wolfCrypt be able to accomodate this?).

from libcose.

bergzand avatar bergzand commented on June 15, 2024
* Add an API that reflects the weak incremental form, with roughly `init(*struct, algorithm, AEAD length)`, `feed_aad(*struct, AAD bytes)`, `{encrypt,decrypt}(*struct, source area, destination area, tag area)`

For the signing/verification I have something along these lines 80% ready somewhere. The main issue I had is that the context struct required for the crypto algorithm is not constant in size among the different algorithm. This resulted in a fairly complex structure where the crypto_sign function 1. initializes the crypto alg, 2. calls a cose sign specific function, 3. the cose sign function calls a passed update() call a number of times, 4. the crypto_sign function finalizes the crypto alg and generates the signature.

Backends are changed to the incremental API

👍

The old API can still be served by a three-line compatibility implementation if it was public

Also 👍

Change internal users to the new API

Still good here. I do have to make an explicit choice here whether I want to consider the crypto API as public. On a related note, it might make sense to move the crypto multiplexing code to a separate project/library and reuse that for both libcose and your OSCORE work.

  • Some backends will initially not support incremental API well (ie. require contiguous memory input); they would need to resort to dynamic memory management (yikes I know, but it's only for the low-quality backends…) to build a scratch buffer into which the fed AAD parts are placed. If that's done in a clever fashion, it can be possible to avoid memory allocation if all the AAD happens to be fed in at a single feed call – but being clever here may not be worth it, as we're aiming for high-quality streamable backends anyway, and the dynamic memory part is more of a migration helper.

Yeah, this is also what I concluded a while ago. I think some compile time setting to enable malloc()/free() usage is not necessarily a bad thing. This way more generic (non-embedded) crypto libs could also be supported.

from libcose.

chrysn avatar chrysn commented on June 15, 2024

from libcose.

chrysn avatar chrysn commented on June 15, 2024

Small detail on the API details: We may need to give the plain- and ciphertext locations at the initialization already – at least judging from the wolfSSL source of ChaCha20Poly1305 where those are processed before the AAD is processed. It's asking a bit more of the application (having the pointers ready and keeping them exclusive to the operation for the time feeding the AAD), but if it helps having more algorithms usable that way…

(I don't know ChaCha20Poly1305 well enough to know whether that's inherent to the algorithm or just an implementation choice of WolfCrypt, but either way, given that AEAD algorithm authors seem to rarely think of those concerns, the more defensive API seems appropriate).

from libcose.

chrysn avatar chrysn commented on June 15, 2024

With the #103 merged this can be closed. We may want to revisit the discussions had here when refactoring the interfaces to allow streaming AAD, and I might still update my tinydtls branch to add an alternative AES-CCM implementation (primarily depending on how to easiest get HKDF again), but the core of the issue is closed.

from libcose.

Related Issues (14)

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.