On Thu, Dec 14, 2000 at 05:03:57PM +0100, Olaf Titz wrote: > > In the current implementation, getting a version that doesn't sleep > > simply requires disabling the if (current->need_reshed) test. This > > Is this enough? Sleeping can be achieved e.g. by sleep_on() which is a > common way for drivers, and calling this in an interrupt context > already causes a kernel panic. If we want to use the cipher in this > way we must have some means to either tell the cipher to never ever > sleep, or to have the cipher tell us whether it _can_ sleep (and then > reject to use it; to the user this behaviour is nonobvious and it does > not look good to have a cipher work or not depending on how it's > implemented). > > > However, in the future this means we always have to have a > > software-version of any hardware-accellerated cipher, or _only_ > > provide hardware-accelleration using a work-queue interface where we > > invoke a callback when the job is done. > > Hm, didn't think about that. One easy possibility would be to put the > output packets in the (existing) input queue and handle them in the > ciped process context. However, this could increase packet output > latency by a degree I just don't want to bear, and it will definitely > interfere with any packet queuing mechanism the kernel employs itself. > A kernel thread would have the same problems. > Actually there are three possible interfaces. 1) A software-based non-sleeping one. You want this to encrypt atomically. However, encrypting 512 bytes in cbc-mode is something you don't _want_ to do atomically because it takes too long, so you have: 2) A software-based sleeping one. You want this to encrypt large amounts of data with a simple interface. This interface can support hardware accelleration. You want this when you don't want to loose sight of a user-level process (for instance loopback block device). This _might_ be due to a broken design though. 3) A work-queue w/callback one. You want this when dealing with the network stack. You don't care about processes. > A callback solution looks cleaner to me. A non sleeping software-only > solution could do that too, to avoid dealing with a double API. > For atomic operation we need special atomic software implementations, and the current interface is a natural interface for this, so I don't see the need for any change except making the rescheduling in the ciphers optional. Currently I feel that all three interfaces should be supported. Off the top of my head - something like: struct cipher_implementation { ... int (*encrypt)(struct cipher_context *cx, const u8 *in, u8 *out, int size); int (*decrypt)(struct cipher_context *cx, const u8 *in, u8 *out, int size); int (*set_key)(struct cipher_context *cx, unsigned char *key, int key_len); int (*encrypt_atomic)(struct cipher_context *cx, const u8 *in, u8 *out, int size); int (*decrypt_atomic)(struct cipher_context *cx, const u8 *in, u8 *out, int size); int (*set_key_atomic)(struct cipher_context *cx, unsigned char *key, int key_len); int (*wq_encrypt)(struct cipher_context *cx, const u8 *in, u8 *out, int size, void *cookie, void (*callback)(void *)); int (*wq_decrypt)(struct cipher_context *cx, const u8 *in, u8 *out, int size, void *cookie, void (*callback)(void *)); int (*wq_set_key)(struct cipher_context *cx, unsigned char *key, int key_len, void *cookie, void (*callback)(void *)); }; Most of these functions can point to defaults. However, the *_encrypt functions could be NULL, so find_cipher_by_name would have to take an additional parameter indicating whether the cipher should support atomic encryption. static inline struct cipher_implementation * find_cipher_by_name(const char *name, int atomic); astor -- Alexander Kjeldaas Mail: astor@xxxxxxx finger astor@xxxxxxxxxxxxxxxxx for OpenPGP key. Linux-crypto: cryptography in and on the Linux system Archive: http://mail.nl.linux.org/linux-crypto/