Commit b8dc6038 authored by Jan Glauber's avatar Jan Glauber Committed by Linus Torvalds

[PATCH] s390: des crypto code speedup

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: default avatarJan Glauber <jan.glauber@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent c1357833
...@@ -57,18 +57,79 @@ static int des_setkey(void *ctx, const u8 *key, unsigned int keylen, ...@@ -57,18 +57,79 @@ static int des_setkey(void *ctx, const u8 *key, unsigned int keylen,
return ret; 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; 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; 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 = { static struct crypto_alg des_alg = {
...@@ -84,7 +145,11 @@ static struct crypto_alg des_alg = { ...@@ -84,7 +145,11 @@ static struct crypto_alg des_alg = {
.cia_max_keysize = DES_KEY_SIZE, .cia_max_keysize = DES_KEY_SIZE,
.cia_setkey = des_setkey, .cia_setkey = des_setkey,
.cia_encrypt = des_encrypt, .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) ...@@ -137,6 +202,71 @@ static void des3_128_decrypt(void *ctx, u8 *dst, const u8 *src)
DES3_128_BLOCK_SIZE); 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 = { static struct crypto_alg des3_128_alg = {
.cra_name = "des3_ede128", .cra_name = "des3_ede128",
.cra_flags = CRYPTO_ALG_TYPE_CIPHER, .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
...@@ -150,7 +280,11 @@ static struct crypto_alg des3_128_alg = { ...@@ -150,7 +280,11 @@ static struct crypto_alg des3_128_alg = {
.cia_max_keysize = DES3_128_KEY_SIZE, .cia_max_keysize = DES3_128_KEY_SIZE,
.cia_setkey = des3_128_setkey, .cia_setkey = des3_128_setkey,
.cia_encrypt = des3_128_encrypt, .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) ...@@ -207,6 +341,71 @@ static void des3_192_decrypt(void *ctx, u8 *dst, const u8 *src)
DES3_192_BLOCK_SIZE); 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 = { static struct crypto_alg des3_192_alg = {
.cra_name = "des3_ede", .cra_name = "des3_ede",
.cra_flags = CRYPTO_ALG_TYPE_CIPHER, .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
...@@ -220,7 +419,11 @@ static struct crypto_alg des3_192_alg = { ...@@ -220,7 +419,11 @@ static struct crypto_alg des3_192_alg = {
.cia_max_keysize = DES3_192_KEY_SIZE, .cia_max_keysize = DES3_192_KEY_SIZE,
.cia_setkey = des3_192_setkey, .cia_setkey = des3_192_setkey,
.cia_encrypt = des3_192_encrypt, .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,
} }
} }
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment