[PATCH] s390: des crypto code speedup
authorJan Glauber <jan.glauber@de.ibm.com>
Sat, 14 Jan 2006 21:20:53 +0000 (13:20 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Sun, 15 Jan 2006 02:27:08 +0000 (18:27 -0800)
Provide ECB and CBC encrypt / decrypt functions to crypto API to speed up our
hardware accelerated DES implementation.  This new functions allow the crypto
API to call ECB / CBC directly with large blocks in difference to the old
functions that were calles with algorithm block size (8 bytes for DES).

This is up to factor 10 faster than our old hardware implementation :)

Signed-off-by: Jan Glauber <jan.glauber@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/s390/crypto/des_s390.c

index f090c3c2745bf17ddac07652a97b2e02b2336265..e3c37aa0a19936b33be3e4a2b13a067129d29e7d 100644 (file)
@@ -57,18 +57,79 @@ static int des_setkey(void *ctx, const u8 *key, unsigned int keylen,
        return ret;
 }
 
-static void des_encrypt(void *ctx, u8 *dst, const u8 *src)
+static void des_encrypt(void *ctx, u8 *out, const u8 *in)
 {
        struct crypt_s390_des_ctx *dctx = ctx;
 
-       crypt_s390_km(KM_DEA_ENCRYPT, dctx->key, dst, src, DES_BLOCK_SIZE);
+       crypt_s390_km(KM_DEA_ENCRYPT, dctx->key, out, in, DES_BLOCK_SIZE);
 }
 
-static void des_decrypt(void *ctx, u8 *dst, const u8 *src)
+static void des_decrypt(void *ctx, u8 *out, const u8 *in)
 {
        struct crypt_s390_des_ctx *dctx = ctx;
 
-       crypt_s390_km(KM_DEA_DECRYPT, dctx->key, dst, src, DES_BLOCK_SIZE);
+       crypt_s390_km(KM_DEA_DECRYPT, dctx->key, out, in, DES_BLOCK_SIZE);
+}
+
+static unsigned int des_encrypt_ecb(const struct cipher_desc *desc, u8 *out,
+                                   const u8 *in, unsigned int nbytes)
+{
+       struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+       int ret;
+
+       /* only use complete blocks */
+       nbytes &= ~(DES_BLOCK_SIZE - 1);
+       ret = crypt_s390_km(KM_DEA_ENCRYPT, sctx->key, out, in, nbytes);
+       BUG_ON((ret < 0) || (ret != nbytes));
+
+       return nbytes;
+}
+
+static unsigned int des_decrypt_ecb(const struct cipher_desc *desc, u8 *out,
+                                   const u8 *in, unsigned int nbytes)
+{
+       struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+       int ret;
+
+       /* only use complete blocks */
+       nbytes &= ~(DES_BLOCK_SIZE - 1);
+       ret = crypt_s390_km(KM_DEA_DECRYPT, sctx->key, out, in, nbytes);
+       BUG_ON((ret < 0) || (ret != nbytes));
+
+       return nbytes;
+}
+
+static unsigned int des_encrypt_cbc(const struct cipher_desc *desc, u8 *out,
+                                   const u8 *in, unsigned int nbytes)
+{
+       struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+       int ret;
+
+       /* only use complete blocks */
+       nbytes &= ~(DES_BLOCK_SIZE - 1);
+
+       memcpy(sctx->iv, desc->info, DES_BLOCK_SIZE);
+       ret = crypt_s390_kmc(KMC_DEA_ENCRYPT, &sctx->iv, out, in, nbytes);
+       BUG_ON((ret < 0) || (ret != nbytes));
+
+       memcpy(desc->info, sctx->iv, DES_BLOCK_SIZE);
+       return nbytes;
+}
+
+static unsigned int des_decrypt_cbc(const struct cipher_desc *desc, u8 *out,
+                                   const u8 *in, unsigned int nbytes)
+{
+       struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+       int ret;
+
+       /* only use complete blocks */
+       nbytes &= ~(DES_BLOCK_SIZE - 1);
+
+       memcpy(&sctx->iv, desc->info, DES_BLOCK_SIZE);
+       ret = crypt_s390_kmc(KMC_DEA_DECRYPT, &sctx->iv, out, in, nbytes);
+       BUG_ON((ret < 0) || (ret != nbytes));
+
+       return nbytes;
 }
 
 static struct crypto_alg des_alg = {
@@ -84,7 +145,11 @@ static struct crypto_alg des_alg = {
                        .cia_max_keysize        =       DES_KEY_SIZE,
                        .cia_setkey             =       des_setkey,
                        .cia_encrypt            =       des_encrypt,
-                       .cia_decrypt            =       des_decrypt
+                       .cia_decrypt            =       des_decrypt,
+                       .cia_encrypt_ecb        =       des_encrypt_ecb,
+                       .cia_decrypt_ecb        =       des_decrypt_ecb,
+                       .cia_encrypt_cbc        =       des_encrypt_cbc,
+                       .cia_decrypt_cbc        =       des_decrypt_cbc,
                }
        }
 };
@@ -137,6 +202,71 @@ static void des3_128_decrypt(void *ctx, u8 *dst, const u8 *src)
                      DES3_128_BLOCK_SIZE);
 }
 
+static unsigned int des3_128_encrypt_ecb(const struct cipher_desc *desc,
+                                        u8 *out, const u8 *in,
+                                        unsigned int nbytes)
+{
+       struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+       int ret;
+
+       /* only use complete blocks */
+       nbytes &= ~(DES3_128_BLOCK_SIZE - 1);
+       ret = crypt_s390_km(KM_TDEA_128_ENCRYPT, sctx->key, out, in, nbytes);
+       BUG_ON((ret < 0) || (ret != nbytes));
+
+       return nbytes;
+}
+
+static unsigned int des3_128_decrypt_ecb(const struct cipher_desc *desc,
+                                        u8 *out, const u8 *in,
+                                        unsigned int nbytes)
+{
+       struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+       int ret;
+
+       /* only use complete blocks */
+       nbytes &= ~(DES3_128_BLOCK_SIZE - 1);
+       ret = crypt_s390_km(KM_TDEA_128_DECRYPT, sctx->key, out, in, nbytes);
+       BUG_ON((ret < 0) || (ret != nbytes));
+
+       return nbytes;
+}
+
+static unsigned int des3_128_encrypt_cbc(const struct cipher_desc *desc,
+                                        u8 *out, const u8 *in,
+                                        unsigned int nbytes)
+{
+       struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+       int ret;
+
+       /* only use complete blocks */
+       nbytes &= ~(DES3_128_BLOCK_SIZE - 1);
+
+       memcpy(sctx->iv, desc->info, DES3_128_BLOCK_SIZE);
+       ret = crypt_s390_kmc(KMC_TDEA_128_ENCRYPT, &sctx->iv, out, in, nbytes);
+       BUG_ON((ret < 0) || (ret != nbytes));
+
+       memcpy(desc->info, sctx->iv, DES3_128_BLOCK_SIZE);
+       return nbytes;
+}
+
+static unsigned int des3_128_decrypt_cbc(const struct cipher_desc *desc,
+                                        u8 *out, const u8 *in,
+                                        unsigned int nbytes)
+{
+       struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+       int ret;
+
+       /* only use complete blocks */
+       nbytes &= ~(DES3_128_BLOCK_SIZE - 1);
+
+       memcpy(&sctx->iv, desc->info, DES3_128_BLOCK_SIZE);
+       ret = crypt_s390_kmc(KMC_TDEA_128_DECRYPT, &sctx->iv, out, in, nbytes);
+       BUG_ON((ret < 0) || (ret != nbytes));
+
+       return nbytes;
+}
+
 static struct crypto_alg des3_128_alg = {
        .cra_name               =       "des3_ede128",
        .cra_flags              =       CRYPTO_ALG_TYPE_CIPHER,
@@ -150,7 +280,11 @@ static struct crypto_alg des3_128_alg = {
                        .cia_max_keysize        =       DES3_128_KEY_SIZE,
                        .cia_setkey             =       des3_128_setkey,
                        .cia_encrypt            =       des3_128_encrypt,
-                       .cia_decrypt            =       des3_128_decrypt
+                       .cia_decrypt            =       des3_128_decrypt,
+                       .cia_encrypt_ecb        =       des3_128_encrypt_ecb,
+                       .cia_decrypt_ecb        =       des3_128_decrypt_ecb,
+                       .cia_encrypt_cbc        =       des3_128_encrypt_cbc,
+                       .cia_decrypt_cbc        =       des3_128_decrypt_cbc,
                }
        }
 };
@@ -207,6 +341,71 @@ static void des3_192_decrypt(void *ctx, u8 *dst, const u8 *src)
                      DES3_192_BLOCK_SIZE);
 }
 
+static unsigned int des3_192_encrypt_ecb(const struct cipher_desc *desc,
+                                        u8 *out, const u8 *in,
+                                        unsigned int nbytes)
+{
+       struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+       int ret;
+
+       /* only use complete blocks */
+       nbytes &= ~(DES3_192_BLOCK_SIZE - 1);
+       ret = crypt_s390_km(KM_TDEA_192_ENCRYPT, sctx->key, out, in, nbytes);
+       BUG_ON((ret < 0) || (ret != nbytes));
+
+       return nbytes;
+}
+
+static unsigned int des3_192_decrypt_ecb(const struct cipher_desc *desc,
+                                        u8 *out, const u8 *in,
+                                        unsigned int nbytes)
+{
+       struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+       int ret;
+
+       /* only use complete blocks */
+       nbytes &= ~(DES3_192_BLOCK_SIZE - 1);
+       ret = crypt_s390_km(KM_TDEA_192_DECRYPT, sctx->key, out, in, nbytes);
+       BUG_ON((ret < 0) || (ret != nbytes));
+
+       return nbytes;
+}
+
+static unsigned int des3_192_encrypt_cbc(const struct cipher_desc *desc,
+                                        u8 *out, const u8 *in,
+                                        unsigned int nbytes)
+{
+       struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+       int ret;
+
+       /* only use complete blocks */
+       nbytes &= ~(DES3_192_BLOCK_SIZE - 1);
+
+       memcpy(sctx->iv, desc->info, DES3_192_BLOCK_SIZE);
+       ret = crypt_s390_kmc(KMC_TDEA_192_ENCRYPT, &sctx->iv, out, in, nbytes);
+       BUG_ON((ret < 0) || (ret != nbytes));
+
+       memcpy(desc->info, sctx->iv, DES3_192_BLOCK_SIZE);
+       return nbytes;
+}
+
+static unsigned int des3_192_decrypt_cbc(const struct cipher_desc *desc,
+                                        u8 *out, const u8 *in,
+                                        unsigned int nbytes)
+{
+       struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+       int ret;
+
+       /* only use complete blocks */
+       nbytes &= ~(DES3_192_BLOCK_SIZE - 1);
+
+       memcpy(&sctx->iv, desc->info, DES3_192_BLOCK_SIZE);
+       ret = crypt_s390_kmc(KMC_TDEA_192_DECRYPT, &sctx->iv, out, in, nbytes);
+       BUG_ON((ret < 0) || (ret != nbytes));
+
+       return nbytes;
+}
+
 static struct crypto_alg des3_192_alg = {
        .cra_name               =       "des3_ede",
        .cra_flags              =       CRYPTO_ALG_TYPE_CIPHER,
@@ -220,7 +419,11 @@ static struct crypto_alg des3_192_alg = {
                        .cia_max_keysize        =       DES3_192_KEY_SIZE,
                        .cia_setkey             =       des3_192_setkey,
                        .cia_encrypt            =       des3_192_encrypt,
-                       .cia_decrypt            =       des3_192_decrypt
+                       .cia_decrypt            =       des3_192_decrypt,
+                       .cia_encrypt_ecb        =       des3_192_encrypt_ecb,
+                       .cia_decrypt_ecb        =       des3_192_decrypt_ecb,
+                       .cia_encrypt_cbc        =       des3_192_encrypt_cbc,
+                       .cia_decrypt_cbc        =       des3_192_decrypt_cbc,
                }
        }
 };