aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorJames Morris <jmorris@intercode.com.au>2003-03-07 19:44:09 -0800
committerDavid S. Miller <davem@nuts.ninka.net>2003-03-07 19:44:09 -0800
commitc7870e139556aa404578b575927d87fbc7148ab2 (patch)
tree75397184c6b234d901019c23bcef7f872978e097 /crypto
parent1e031531d3348aa7462ce7404c178cce1ef0d38c (diff)
downloadhistory-c7870e139556aa404578b575927d87fbc7148ab2.tar.gz
[CRYPTO]: Add encrypt_iv() and decrypt_iv() methods.
Diffstat (limited to 'crypto')
-rw-r--r--crypto/cipher.c74
1 files changed, 57 insertions, 17 deletions
diff --git a/crypto/cipher.c b/crypto/cipher.c
index ae45fe344c91ee..335ff51a3d4762 100644
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -23,7 +23,8 @@
#include "internal.h"
typedef void (cryptfn_t)(void *, u8 *, const u8 *);
-typedef void (procfn_t)(struct crypto_tfm *, u8 *, u8*, cryptfn_t, int enc);
+typedef void (procfn_t)(struct crypto_tfm *, u8 *,
+ u8*, cryptfn_t, int enc, void *);
struct scatter_walk {
struct scatterlist *sg;
@@ -166,7 +167,8 @@ static int copy_chunks(void *buf, struct scatter_walk *walk,
static int crypt(struct crypto_tfm *tfm,
struct scatterlist *dst,
struct scatterlist *src,
- unsigned int nbytes, cryptfn_t crfn, procfn_t prfn, int enc)
+ unsigned int nbytes, cryptfn_t crfn,
+ procfn_t prfn, int enc, void *info)
{
struct scatter_walk walk_in, walk_out;
const unsigned int bsize = crypto_tfm_alg_blocksize(tfm);
@@ -196,7 +198,7 @@ static int crypt(struct crypto_tfm *tfm,
copy_chunks(src_p, &walk_in, bsize, 0);
- prfn(tfm, dst_p, src_p, crfn, enc);
+ prfn(tfm, dst_p, src_p, crfn, enc, info);
scatter_done(&walk_in, 0, nbytes);
@@ -211,33 +213,33 @@ static int crypt(struct crypto_tfm *tfm,
}
static void cbc_process(struct crypto_tfm *tfm,
- u8 *dst, u8 *src, cryptfn_t fn, int enc)
+ u8 *dst, u8 *src, cryptfn_t fn, int enc, void *info)
{
+ u8 *iv = info;
+
/* Null encryption */
- if (!tfm->crt_cipher.cit_iv)
+ if (!iv)
return;
if (enc) {
- tfm->crt_u.cipher.cit_xor_block(tfm->crt_cipher.cit_iv, src);
- fn(tfm->crt_ctx, dst, tfm->crt_cipher.cit_iv);
- memcpy(tfm->crt_cipher.cit_iv, dst,
- crypto_tfm_alg_blocksize(tfm));
+ tfm->crt_u.cipher.cit_xor_block(iv, src);
+ fn(tfm->crt_ctx, dst, iv);
+ memcpy(iv, dst, crypto_tfm_alg_blocksize(tfm));
} else {
const int need_stack = (src == dst);
u8 stack[need_stack ? crypto_tfm_alg_blocksize(tfm) : 0];
u8 *buf = need_stack ? stack : dst;
fn(tfm->crt_ctx, buf, src);
- tfm->crt_u.cipher.cit_xor_block(buf, tfm->crt_cipher.cit_iv);
- memcpy(tfm->crt_cipher.cit_iv, src,
- crypto_tfm_alg_blocksize(tfm));
+ tfm->crt_u.cipher.cit_xor_block(buf, iv);
+ memcpy(iv, src, crypto_tfm_alg_blocksize(tfm));
if (buf != dst)
memcpy(dst, buf, crypto_tfm_alg_blocksize(tfm));
}
}
static void ecb_process(struct crypto_tfm *tfm, u8 *dst, u8 *src,
- cryptfn_t fn, int enc)
+ cryptfn_t fn, int enc, void *info)
{
fn(tfm->crt_ctx, dst, src);
}
@@ -259,7 +261,8 @@ static int ecb_encrypt(struct crypto_tfm *tfm,
struct scatterlist *src, unsigned int nbytes)
{
return crypt(tfm, dst, src, nbytes,
- tfm->__crt_alg->cra_cipher.cia_encrypt, ecb_process, 1);
+ tfm->__crt_alg->cra_cipher.cia_encrypt,
+ ecb_process, 1, NULL);
}
static int ecb_decrypt(struct crypto_tfm *tfm,
@@ -268,7 +271,8 @@ static int ecb_decrypt(struct crypto_tfm *tfm,
unsigned int nbytes)
{
return crypt(tfm, dst, src, nbytes,
- tfm->__crt_alg->cra_cipher.cia_decrypt, ecb_process, 1);
+ tfm->__crt_alg->cra_cipher.cia_decrypt,
+ ecb_process, 1, NULL);
}
static int cbc_encrypt(struct crypto_tfm *tfm,
@@ -277,7 +281,18 @@ static int cbc_encrypt(struct crypto_tfm *tfm,
unsigned int nbytes)
{
return crypt(tfm, dst, src, nbytes,
- tfm->__crt_alg->cra_cipher.cia_encrypt, cbc_process, 1);
+ tfm->__crt_alg->cra_cipher.cia_encrypt,
+ cbc_process, 1, tfm->crt_cipher.cit_iv);
+}
+
+static int cbc_encrypt_iv(struct crypto_tfm *tfm,
+ struct scatterlist *dst,
+ struct scatterlist *src,
+ unsigned int nbytes, u8 *iv)
+{
+ return crypt(tfm, dst, src, nbytes,
+ tfm->__crt_alg->cra_cipher.cia_encrypt,
+ cbc_process, 1, iv);
}
static int cbc_decrypt(struct crypto_tfm *tfm,
@@ -286,7 +301,18 @@ static int cbc_decrypt(struct crypto_tfm *tfm,
unsigned int nbytes)
{
return crypt(tfm, dst, src, nbytes,
- tfm->__crt_alg->cra_cipher.cia_decrypt, cbc_process, 0);
+ tfm->__crt_alg->cra_cipher.cia_decrypt,
+ cbc_process, 0, tfm->crt_cipher.cit_iv);
+}
+
+static int cbc_decrypt_iv(struct crypto_tfm *tfm,
+ struct scatterlist *dst,
+ struct scatterlist *src,
+ unsigned int nbytes, u8 *iv)
+{
+ return crypt(tfm, dst, src, nbytes,
+ tfm->__crt_alg->cra_cipher.cia_decrypt,
+ cbc_process, 0, iv);
}
static int nocrypt(struct crypto_tfm *tfm,
@@ -297,6 +323,14 @@ static int nocrypt(struct crypto_tfm *tfm,
return -ENOSYS;
}
+static int nocrypt_iv(struct crypto_tfm *tfm,
+ struct scatterlist *dst,
+ struct scatterlist *src,
+ unsigned int nbytes, u8 *iv)
+{
+ return -ENOSYS;
+}
+
int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags)
{
u32 mode = flags & CRYPTO_TFM_MODE_MASK;
@@ -325,16 +359,22 @@ int crypto_init_cipher_ops(struct crypto_tfm *tfm)
case CRYPTO_TFM_MODE_CBC:
ops->cit_encrypt = cbc_encrypt;
ops->cit_decrypt = cbc_decrypt;
+ ops->cit_encrypt_iv = cbc_encrypt_iv;
+ ops->cit_decrypt_iv = cbc_decrypt_iv;
break;
case CRYPTO_TFM_MODE_CFB:
ops->cit_encrypt = nocrypt;
ops->cit_decrypt = nocrypt;
+ ops->cit_encrypt_iv = nocrypt_iv;
+ ops->cit_decrypt_iv = nocrypt_iv;
break;
case CRYPTO_TFM_MODE_CTR:
ops->cit_encrypt = nocrypt;
ops->cit_decrypt = nocrypt;
+ ops->cit_encrypt_iv = nocrypt_iv;
+ ops->cit_decrypt_iv = nocrypt_iv;
break;
default: