2013-09-16 11:05:07

by dominik.d.paulus

[permalink] [raw]
Subject: crypto: GCM API usage

Hi,

We are currently trying to add encryption support to the usbip kernel
driver. Unfortunately, there is almost no documentation for the kernel
crypto API. So far, we couldn't figure out how to use the GCM encryption
mode in the kernel. There seems to be infrastructure for IV generation
in place (e.g. seqiv.c, the geniv stuff and the RFC 4106 implementation),
but no code directly using it.

What's the recommended way to use the IV generators with a "high-level"
API?

Regards,
Tobias Polzer and Dominik Paulus


2013-09-16 18:44:02

by Dominik Paulus

[permalink] [raw]
Subject: Re: crypto: GCM API usage

Hi,

On Mon, Sep 16, 2013 at 12:58:40PM +0200, [email protected] wrote:
> We are currently trying to add encryption support to the usbip kernel
> driver. Unfortunately, there is almost no documentation for the kernel
> crypto API. So far, we couldn't figure out how to use the GCM encryption
> mode in the kernel. There seems to be infrastructure for IV generation
> in place (e.g. seqiv.c, the geniv stuff and the RFC 4106 implementation),
> but no code directly using it.
>
> What's the recommended way to use the IV generators with a "high-level"
> API?

Sorry, that mail probably got a bit too short. To explain our problem a bit
more: We are currently using a 64-bit counter to generate IVs. As the
keys are randomly generated for each session and thus never reused,
that's probably a not too bad idea (if it is, please tell us why ;)),
assuming this counter is never going to overflow. We pass the IVs
directly to aead_request_set_crypt for each message. This currently
works quite fine.

However, we would expect that IV generation is at least partially handled
by the crypto API. As I said, there seems to be infrastructure for that,
that abstracts the sequence number quite nicely. The seqiv generator
seems to provide a high-level interface to the AEAD crypto, including an
abstraction for the sequence number generation. However, due to the lack
of documentation and/or reference code using the API, we couldn't find
out how to use it yet.

Any help on this would be appreciated. If we feel competent enough to do
so after finishing this project, we would also volunteer to extend the
introduction in Documentation/crypto/api-intro.txt a bit.

Regards,
Tobias Polzer and Dominik Paulus

2013-09-19 20:33:28

by Marcelo H. Cerri

[permalink] [raw]
Subject: Re: crypto: GCM API usage

On Mon, Sep 16, 2013 at 08:34:11PM +0200, Dominik Paulus wrote:
> Hi,
>
> On Mon, Sep 16, 2013 at 12:58:40PM +0200, [email protected] wrote:
> > We are currently trying to add encryption support to the usbip kernel
> > driver. Unfortunately, there is almost no documentation for the kernel
> > crypto API. So far, we couldn't figure out how to use the GCM encryption
> > mode in the kernel. There seems to be infrastructure for IV generation
> > in place (e.g. seqiv.c, the geniv stuff and the RFC 4106 implementation),
> > but no code directly using it.
> >
> > What's the recommended way to use the IV generators with a "high-level"
> > API?
>
> Sorry, that mail probably got a bit too short. To explain our problem a bit
> more: We are currently using a 64-bit counter to generate IVs. As the
> keys are randomly generated for each session and thus never reused,
> that's probably a not too bad idea (if it is, please tell us why ;)),
> assuming this counter is never going to overflow. We pass the IVs
> directly to aead_request_set_crypt for each message. This currently
> works quite fine.

It's usual the use of random IVs but I don't think that any known
pattern (as a counter) in the IV generation should cause any reduction
in the algorithm strength (and if it does, it's probably a weakness in
the algorithm itself). The only thing that should be avoided for sure is
the reuse of the same IV.

>
> However, we would expect that IV generation is at least partially handled
> by the crypto API. As I said, there seems to be infrastructure for that,
> that abstracts the sequence number quite nicely. The seqiv generator
> seems to provide a high-level interface to the AEAD crypto, including an
> abstraction for the sequence number generation. However, due to the lack
> of documentation and/or reference code using the API, we couldn't find
> out how to use it yet.

I haven't used the IV generation facility of the Crypto API, but it
seems to be very straightforward although there's no documentation
about that.

You should use aead_givcrypt_set_callback(), aead_givcrypt_set_assoc()
and aead_givcrypt_set_crypt() as you would use the regular aead
functions, that includes that you have to provide a buffer with length
equals to the algorithm block size for the IV. And then you should call
aead_givcrypt_set_giv() passing a counter and another IV buffer.

The difference between the two IV buffers that you have to provide to
aead_givcrypt_set_crypt() and aead_givcrypt_set_giv() is that the first
one will be updated by the algorithm during the encryption of each block
and the second one will contain the generated IV that you will have to
use to decrypt data.

The last step is to call crypto_aead_givencrypt() as you would call
crypto_aead_encrypt().

Under the cover the Crypto API will generate a random salt in the first
use of each request. This salt will be xor'd with the given counter to
create the new IV. That has an advantage over a simple count, that
usually will start with the same value every time the system is
rebooted.

>
> Any help on this would be appreciated. If we feel competent enough to do
> so after finishing this project, we would also volunteer to extend the
> introduction in Documentation/crypto/api-intro.txt a bit.
>

That is probably a very good idea! I also want to improve the
documentation as soon I have some time to do it :)

> Regards,
> Tobias Polzer and Dominik Paulus
> --
> To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>

2013-10-03 06:13:47

by Tobias Polzer

[permalink] [raw]
Subject: Re: crypto: GCM API usage

> I haven't used the IV generation facility of the Crypto API, but it
> seems to be very straightforward although there's no documentation
> about that.
>
> You should use aead_givcrypt_set_callback(), aead_givcrypt_set_assoc()
> and aead_givcrypt_set_crypt() as you would use the regular aead
> functions, that includes that you have to provide a buffer with length
> equals to the algorithm block size for the IV. And then you should call
> aead_givcrypt_set_giv() passing a counter and another IV buffer.
>
> The difference between the two IV buffers that you have to provide to
> aead_givcrypt_set_crypt() and aead_givcrypt_set_giv() is that the first
> one will be updated by the algorithm during the encryption of each block
> and the second one will contain the generated IV that you will have to
> use to decrypt data.
>
> The last step is to call crypto_aead_givencrypt() as you would call
> crypto_aead_encrypt().

We discovered those functions, yet the only way we found how to use them was
to use one of the ipsec modes, e.g.:
crypto_alloc_aead("rfc4106(gcm(aes))", 0, 0)

Is this the only way this API should be used, or is there some high level
interface to use iv generators like seqiv?

Thank you for your help,
Dominik Paulus and Tobias Polzer

2013-10-03 12:10:11

by Marcelo H. Cerri

[permalink] [raw]
Subject: Re: crypto: GCM API usage

On Thu, Oct 03, 2013 at 08:03:45AM +0200, [email protected] wrote:
> > I haven't used the IV generation facility of the Crypto API, but it
> > seems to be very straightforward although there's no documentation
> > about that.
> >
> > You should use aead_givcrypt_set_callback(), aead_givcrypt_set_assoc()
> > and aead_givcrypt_set_crypt() as you would use the regular aead
> > functions, that includes that you have to provide a buffer with length
> > equals to the algorithm block size for the IV. And then you should call
> > aead_givcrypt_set_giv() passing a counter and another IV buffer.
> >
> > The difference between the two IV buffers that you have to provide to
> > aead_givcrypt_set_crypt() and aead_givcrypt_set_giv() is that the first
> > one will be updated by the algorithm during the encryption of each block
> > and the second one will contain the generated IV that you will have to
> > use to decrypt data.
> >
> > The last step is to call crypto_aead_givencrypt() as you would call
> > crypto_aead_encrypt().
>
> We discovered those functions, yet the only way we found how to use them was
> to use one of the ipsec modes, e.g.:
> crypto_alloc_aead("rfc4106(gcm(aes))", 0, 0)
>
> Is this the only way this API should be used, or is there some high level
> interface to use iv generators like seqiv?

In order to use IV generation, the targeted algorithm must specify a
generation method and the "plain" GCM implementation actually doesn't do
it.

Both rfc4106 and rfc4543 (gmac) say that the implementation "can use any
IV generation method that meets the uniqueness requirement without
coordinating with the receiver". I think that is the reason that only
these two variations of GCM explicitly define an IV generation method.

If I'm not wrong the Crypto API was first designed to support ipsec
needs, so it makes sense that it simplify things for it. However, I
don't see any reason for GCM itself not have a default IV generation
method, since regular and giv interfaces can be used.

So you should keep explicitly handling the IV generation or maybe submit
a patch adding a default geniv for GCM. I think Herbert can give us more
information about the "history" behind the geniv support and correct me
if I said anything wrong.

>
> Thank you for your help,
> Dominik Paulus and Tobias Polzer
>