Hi! I've noticed that quite a lot of stuff in crypto.h is unneeded. In particular, all the encrypt/decrypt/set_key declarations don't need to be there, since the symbols aren't exported anyway and placing them in the crypto.h file might make people do the wrong thing and calling them directly. I have also added a little description of the meaning of the CIPHER_KEYSIZE_* constants, and a CIPHER_ECB and CIPHER_CTR to accopany CIPHER_CBC, which should rather be CIPHER_MODE_CBC. This patch does not touch anything except crypto.h. This is the reason that *_KEY_SCHEULE_SIZE is still alive. After all, it is exported via the cipher_implementation structure of each cipher and only used in the module implementing the cipher. It was best to create a struct CIPHERNAME_context for each cipher and use sizeof(CIPHERNAME_context) to determine CIPHERNAME_KEY_SCHEDULE_SIZE. Also, the size parameter can be dropped from the vanilla encrypt/decrypt routines, now that we have *_ecb_encrypt. After all, those functions were supposed to only encrypt one block at a time. All this would be confined 'below the surface', i.e. would require no change to the user-side API. The following changes would affect the user-side API: In the next step, we could get rid of exporting that number entirely and make set_key or the constuct() method below allocate the required memory and fill in the keyinfo pointer into struct cipher_context. Then we could move the lock() and unlock() methods into constuct() and destruct() methods, resp. where the keyinfo memory could be freed in destruct(). This makes for a nice object-oriented API. The current version is almost there, but the caller needs too much information about the cipher, IMO. For all implementations of digests/ciphers in the current kerneli, the constructors and destructors would be no-ops except for calling lock(), unlock() and kfree(). For future hw crypto accelerators, however, the use of constructors and destructors would enable them to set up quite complicated data structures, such as wait queues, to handle concurrent accesses or to wake the hw from a powersave mode. The constructors could be loaded with all the things that need to be (re-)defined only seldomly, if at all: o block size (for ciphers that support variable block sizes, e.g. AES) o key length (dto.) o mode (either ECB or CBC or Counter or...) o encryption/keysetup speed tradeoffs. (??) etc. set_key() would then only accept a pointer to the key. This could also speed up implementations where re-keying can be done faster than an initial key-setup (e.g. twofish's 'compiled' option). Comments? Marc -- Marc Mutz <Marc@xxxxxxxx> http://EncryptionHOWTO.sourceforge.net/ University of Bielefeld, Dep. of Mathematics / Dep. of Physics PGP-keyID's: 0xd46ce9ab (RSA), 0x7ae55b9e (DSS/DH)
--- linux/include/linux/crypto.h~ Sat Oct 14 10:41:43 2000 +++ linux/include/linux/crypto.h Tue Oct 17 16:56:38 2000 @@ -44,8 +44,21 @@ #define CIPHER_RC5 17 #define CIPHER_AES 18 #define MAX_CIPHER 20 +#define CIPHER_ECB 0x00000000 #define CIPHER_CBC 0x00010000 +#define CIPHER_CTR 0x00020000 /* not implemented yet */ +/* Allowed keysizes: This is just a set of commonly found values. If + * you need additional ones, you can place them here. Note that + * CIPHER_KEY_ANY really means _any_ key length (that is a multiple of + * 8 bits, just limited by MAX_KEY_SIZE*32. This is not important now, + * but might become so if we choose to support keylengths greater than + * 256 bits. There are many ciphers that can take keys that are longer + * (e.g. blowfish: 448 bits). If you want to say all key lengths up to + * 256, play safe and use 0xFFFFFFFF-1 as keysize_mask. + * CIPHER_KEYSIZE_NONE means that the cipher does not expect a key. It + * is only used for 'none' encryption. + */ #define CIPHER_KEYSIZE_ANY 0xFFFFFFFF #define CIPHER_KEYSIZE_NONE 0x00000000 @@ -247,136 +260,51 @@ extern int init_cast256(void); #define CAST256_KEY_SCHEDULE_SIZE (96*sizeof(u32)) -extern int cast256_set_key(struct cipher_context *cx, unsigned char *key, - int key_len); -extern int cast256_encrypt(struct cipher_context *cx, - const u8 *in, u8 *out, int size); -extern int cast256_decrypt(struct cipher_context *cx, - const u8 *in, u8 *out, int size); extern int init_crypton(void); #define CRYPTON_KEY_SCHEDULE_SIZE (104*sizeof(u32)) -extern int crypton_set_key(struct cipher_context *cx, unsigned char *key, - int key_len); -extern int crypton_encrypt(struct cipher_context *cx, - const u8 *in, u8 *out, int size); -extern int crypton_decrypt(struct cipher_context *cx, - const u8 *in, u8 *out, int size); extern int init_serpent(void); #define SERPENT_KEY_SCHEDULE_SIZE (140*sizeof(u32)) -extern int serpent_set_key(struct cipher_context *cx, unsigned char *key, - int key_len); -extern int serpent_encrypt(struct cipher_context *cx, - const u8 *in, u8 *out, int size); -extern int serpent_decrypt(struct cipher_context *cx, - const u8 *in, u8 *out, int size); extern int init_mars(void); #define MARS_KEY_SCHEDULE_SIZE (40*sizeof(u32)) -extern int mars_set_key(struct cipher_context *cx, unsigned char *key, - int key_len); -extern int mars_encrypt(struct cipher_context *cx, - const u8 *in, u8 *out, int size); -extern int mars_decrypt(struct cipher_context *cx, - const u8 *in, u8 *out, int size); extern int init_rc5(void); #define RC5_KEY_SCHEDULE_SIZE (34*sizeof(u32)) -extern int rc5_set_key(struct cipher_context *cx, unsigned char *key, - int key_len); -extern int rc5_encrypt(struct cipher_context *cx, - const u8 *in, u8 *out, int size); -extern int rc5_decrypt(struct cipher_context *cx, - const u8 *in, u8 *out, int size); extern int init_rc6(void); #define RC6_KEY_SCHEDULE_SIZE (44*sizeof(u32)) -extern int rc6_set_key(struct cipher_context *cx, unsigned char *key, - int key_len); -extern int rc6_encrypt(struct cipher_context *cx, - const u8 *in, u8 *out, int size); -extern int rc6_decrypt(struct cipher_context *cx, - const u8 *in, u8 *out, int size); extern int init_dfc(void); #define DFC_KEY_SCHEDULE_SIZE (32*sizeof(u32)) -extern int dfc_set_key(struct cipher_context *cx, unsigned char *key, - int key_len); -extern int dfc_encrypt(struct cipher_context *cx, - const u8 *in, u8 *out, int size); -extern int dfc_decrypt(struct cipher_context *cx, - const u8 *in, u8 *out, int size); extern int init_rijndael(void); #define RIJNDAEL_KEY_SCHEDULE_SIZE ((60+60)*sizeof(u32)) -extern int rijndael_set_key(struct cipher_context *cx, unsigned char *key, - int key_len); -extern int rijndael_encrypt(struct cipher_context *cx, - const u8 *in, u8 *out, int size); -extern int rijndael_decrypt(struct cipher_context *cx, - const u8 *in, u8 *out, int size); extern int init_blowfish(void); #define BLOWFISH_KEY_SCHEDULE_SIZE ((18+1024)*sizeof(u32)) -extern int blowfish_set_key(struct cipher_context *cx, - unsigned char *key, int key_len); -extern int blowfish_encrypt(struct cipher_context *cx, - const u8 *in, u8 *out, int size); -extern int blowfish_decrypt(struct cipher_context *cx, - const u8 *in, u8 *out, int size); extern int init_twofish(void); #define TWOFISH_KEY_SCHEDULE_SIZE ((4*256+8+32)*sizeof(u32)) -extern int twofish_set_key(struct cipher_context *cx, - unsigned char *key, int key_len); -extern int twofish_encrypt(struct cipher_context *cx, - const u8 *in, u8 *out, int size); -extern int twofish_decrypt(struct cipher_context *cx, - const u8 *in, u8 *out, int size); extern int init_idea(void); #define IDEA_KEY_SCHEDULE_SIZE (104*2) -extern int idea_set_key(struct cipher_context *cx, unsigned char *key, - int key_len); -extern int idea_encrypt(struct cipher_context *cx, - const u8 *in, u8 *out, int size); -extern int idea_decrypt(struct cipher_context *cx, - const u8 *in, u8 *out, int size); extern int init_des(void); #define DES_KEY_SCHEDULE_SIZE (32*sizeof(u32)) -extern int des_set_key(struct cipher_context *cx, unsigned char *key, - int key_len); -extern int des_encrypt(struct cipher_context *cx, - const u8 *in, u8 *out, int size); -extern int des_decrypt(struct cipher_context *cx, - const u8 *in, u8 *out, int size); extern int init_des_ede3(void); #define DES_EDE3_KEY_SCHEDULE_SIZE (3*32*sizeof(u32)) -extern int des_ede3_set_key(struct cipher_context *cx, unsigned char *key, - int key_len); -extern int des_ede3_encrypt(struct cipher_context *cx, - const u8 *in, u8 *out, int size); -extern int des_ede3_decrypt(struct cipher_context *cx, - const u8 *in, u8 *out, int size); + /* Digest implementations */ extern int init_md5(void); #define MD5_WORKING_SIZE ((4+2+16)*sizeof(u32)) -extern int md5_open(struct digest_context *cx); -extern int md5_update(struct digest_context *cx, u8 *in, int size); -extern int md5_current(struct digest_context *cx, u8 *out); -extern int md5_close(struct digest_context *cx, u8 *out); extern int init_sha1(void); #define SHA1_WORKING_SIZE ((5+2+16)*sizeof(u32)) -extern int sha1_open(struct digest_context *cx); -extern int sha1_update(struct digest_context *cx, u8 *in, int size); -extern int sha1_current(struct digest_context *cx, u8 *out); -extern int sha1_close(struct digest_context *cx, u8 *out); /* Utility macros */