Re: [Design] some comments on Linux CryptoAPI - this "atomic" cipherbusiness

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Michael Richardson wrote:
|
|   In the case of FreeSWAN with hardware, we do *not* want to sleep. We
want a
| callback. I am looking at doing this.

Agreed.

|
|   Some more comments:
|
| Naming of ciphers
| =================
|
|   I think that there should be a hierarchy of names with longest matching
| wins. Transforms should provide relative weights for binding to the less
| specific names.
|
|   Specifically:
| 	aes-cbc
| 	aes-cbc/software	(or aes/atomic if you prefer)
| 	aes-cbc/hardware
| 	aes-cbc/hardware/hifn/pci/01/00/0
	[PCI bus/device/function]
| 	aes-cbc/hardware/chrysalis/pci/04/06/0
| 	aes-cbc/hardware/broadcom/csix/5/7/8	[to make something up]
|
|   This permits one to VERY specifically attach to the implementation
that one
| wants, while still permitting "aes-cbc" to get something useful. This all
| would occur at registration and lookup of cipher_implementation time.

How about a in-between application that want to use hardware, but in an
atomic fashion? This is how I started doing things before using a callback.
In some occasions, it might be good to be able to wait for the hardware
to finish encrypting by busy-looping. It is still more efficient to do
that then to wait for 3DES to finish in S/W.

I therefore suggest to leave the hardware specification to the library.
You want to say " I want this done ASAP, with those limitation (SYNC or
ASYN)". That way, the library chooses the best available hardware (or
software) to execute the request, according to specified limitations.


|
| The operation queue
| ===================
|
| I would propose that all fucntions take a "struct transform_command *" as
| an argument, defined essentially like this:
|
| struct transform_command {
|   struct list_head           tc_cmdqueue;
|   struct cipher_context     *tc_context;
|   transform_unit_callback    tc_callback;
|   cipher_usercontext         tc_user;    /* whatever the user callback
wants */
|   unsigned int               tc_flags;
|   const u8                   tc_iv[MAX_IV_SIZE];
|   const u8                  *tc_in;
|   u8                        *tc_out;     /* if NULL, use cc_in */
|   u8                        *tc_mac;     /* must point to space of
tc_macsize */
|   size_t                     tc_insize;  /* size of input buffer */
|   size_t                     tc_outsize; /* size of output buffer */
|   size_t                     tc_macsize; /* size of MAC output buffer */
|   size_t                     tc_resultsize;  /* amount of output
buffer used */
| };
|
| #define TC_FLAGS_GENERATE_IV   (1<<0)    /* if set, then IV must be
generated */
|
| Unfortunately, this is too big. It is 52 bytes + MAX_IV_SIZE.
|
| Making all of the sizes 16 bit integers, and putting the IV outline (a
| pointer) would get us down to 44 bytes.
|
| To be memory efficient, we need to fit this into the 48 bytes in the
skb->cb,
| which avoids having to allocate another control structure for each
| packet. The result is therefore:
|
| struct transform_command {
|   struct list_head           tc_cmdqueue;
|   struct cipher_context     *tc_context;
|   transform_unit_callback    tc_callback;
|   cipher_usercontext         tc_user;    /* whatever the user callback
wants */
|   unsigned int               tc_flags;
|   const u8                  *tc_iv;
|   const u8                  *tc_in;
|   const u8                  *tc_out;
|   u8                        *tc_mac;     /* must point to space of
tc_macsize */
|   u16                        tc_insize;  /* size of input buffer */
|   union {
|     u16	                     tc_buffersize;    /* size of output buffer */
|     u16                      tc_resultsize; /* number of bytes in
output */
|   } tc_output;			
| };
|
| yes, it is necessary to provide outsize as well as insize somehow.
| De-Compression could expand the output, and it must bounds check the
| output. We re-use the tc_outsize as the tc_resultsize. The tc_macsize
| is also dropped, as I believe that the MAC result will always be the
same for
| a given digest.
|
| Note that the operation is implied by the cipher_context now, or we
can steal
| some bits from tc_flags for it.

Something is missing: the start of the operation, and size of the
operation. Is that included in tc_cmdqueue?
Example: on packet pointer at tc_in, do HMAC from in+4 for size1, and
then do 3DES from in+16 for size2.

We also need some kind of open_session()/close_session(). H/W can
remember keys (no need to transfer them with every command) but we need
to manage that either explicitly, on implicitly (use a LRU algo). On the
Hifn 7811 and 7901, there is a limited number of H/W session available,
due to memory constrains.


My 2 cents,

- --
==============
Martin Gadbois
S/W Developper
Colubris Networks Inc.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.4 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAj04dkgACgkQ9Y3/iTTCEDnWQwCeLYdPVjBmRuWngeLyNWCMcydZ
MiwAniUJsJNN+2Q+XmAGEfCVCWR+k3th
=5WaJ
-----END PGP SIGNATURE-----

-
Linux-crypto:  cryptography in and on the Linux system
Archive:       http://mail.nl.linux.org/linux-crypto/


[Index of Archives]     [Kernel]     [Linux Crypto]     [Gnu Crypto]     [Gnu Classpath]     [Netfilter]     [Bugtraq]
  Powered by Linux