diff options
author | James Morris <jmorris@intercode.com.au> | 2003-03-07 19:44:09 -0800 |
---|---|---|
committer | David S. Miller <davem@nuts.ninka.net> | 2003-03-07 19:44:09 -0800 |
commit | c7870e139556aa404578b575927d87fbc7148ab2 (patch) | |
tree | 75397184c6b234d901019c23bcef7f872978e097 /crypto | |
parent | 1e031531d3348aa7462ce7404c178cce1ef0d38c (diff) | |
download | history-c7870e139556aa404578b575927d87fbc7148ab2.tar.gz |
[CRYPTO]: Add encrypt_iv() and decrypt_iv() methods.
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/cipher.c | 74 |
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: |