/* * CBC: Cipher Block Chaining mode * * Copyright (c) 2016 Herbert Xu <herbert@gondor.apana.org.au> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * */ #ifndef _CRYPTO_CBC_H #define _CRYPTO_CBC_H #include <crypto/internal/skcipher.h> #include <linux/string.h> #include <linux/types.h> static inline int crypto_cbc_encrypt_segment( struct skcipher_walk *walk, struct crypto_skcipher *tfm, void (*fn)(struct crypto_skcipher *, const u8 *, u8 *)) { unsigned int bsize = crypto_skcipher_blocksize(tfm); unsigned int nbytes = walk->nbytes; u8 *src = walk->src.virt.addr; u8 *dst = walk->dst.virt.addr; u8 *iv = walk->iv; do { crypto_xor(iv, src, bsize); fn(tfm, iv, dst); memcpy(iv, dst, bsize); src += bsize; dst += bsize; } while ((nbytes -= bsize) >= bsize); return nbytes; } static inline int crypto_cbc_encrypt_inplace( struct skcipher_walk *walk, struct crypto_skcipher *tfm, void (*fn)(struct crypto_skcipher *, const u8 *, u8 *)) { unsigned int bsize = crypto_skcipher_blocksize(tfm); unsigned int nbytes = walk->nbytes; u8 *src = walk->src.virt.addr; u8 *iv = walk->iv; do { crypto_xor(src, iv, bsize); fn(tfm, src, src); iv = src; src += bsize; } while ((nbytes -= bsize) >= bsize); memcpy(walk->iv, iv, bsize); return nbytes; } static inline int crypto_cbc_encrypt_walk(struct skcipher_request *req, void (*fn)(struct crypto_skcipher *, const u8 *, u8 *)) { struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); struct skcipher_walk walk; int err; err = skcipher_walk_virt(&walk, req, false); while (walk.nbytes) { if (walk.src.virt.addr == walk.dst.virt.addr) err = crypto_cbc_encrypt_inplace(&walk, tfm, fn); else err = crypto_cbc_encrypt_segment(&walk, tfm, fn); err = skcipher_walk_done(&walk, err); } return err; } static inline int crypto_cbc_decrypt_segment( struct skcipher_walk *walk, struct crypto_skcipher *tfm, void (*fn)(struct crypto_skcipher *, const u8 *, u8 *)) { unsigned int bsize = crypto_skcipher_blocksize(tfm); unsigned int nbytes = walk->nbytes; u8 *src = walk->src.virt.addr; u8 *dst = walk->dst.virt.addr; u8 *iv = walk->iv; do { fn(tfm, src, dst); crypto_xor(dst, iv, bsize); iv = src; src += bsize; dst += bsize; } while ((nbytes -= bsize) >= bsize); memcpy(walk->iv, iv, bsize); return nbytes; } static inline int crypto_cbc_decrypt_inplace( struct skcipher_walk *walk, struct crypto_skcipher *tfm, void (*fn)(struct crypto_skcipher *, const u8 *, u8 *)) { unsigned int bsize = crypto_skcipher_blocksize(tfm); unsigned int nbytes = walk->nbytes; u8 *src = walk->src.virt.addr; u8 last_iv[bsize]; /* Start of the last block. */ src += nbytes - (nbytes & (bsize - 1)) - bsize; memcpy(last_iv, src, bsize); for (;;) { fn(tfm, src, src); if ((nbytes -= bsize) < bsize) break; crypto_xor(src, src - bsize, bsize); src -= bsize; } crypto_xor(src, walk->iv, bsize); memcpy(walk->iv, last_iv, bsize); return nbytes; } static inline int crypto_cbc_decrypt_blocks( struct skcipher_walk *walk, struct crypto_skcipher *tfm, void (*fn)(struct crypto_skcipher *, const u8 *, u8 *)) { if (walk->src.virt.addr == walk->dst.virt.addr) return crypto_cbc_decrypt_inplace(walk, tfm, fn); else return crypto_cbc_decrypt_segment(walk, tfm, fn); } #endif /* _CRYPTO_CBC_H */
Name | Type | Size | Permission | Actions |
---|---|---|---|---|
internal | Folder | 0755 |
|
|
ablk_helper.h | File | 773 B | 0644 |
|
acompress.h | File | 7.89 KB | 0644 |
|
aead.h | File | 18.1 KB | 0644 |
|
aes.h | File | 1.03 KB | 0644 |
|
akcipher.h | File | 11.7 KB | 0644 |
|
algapi.h | File | 11.12 KB | 0644 |
|
authenc.h | File | 845 B | 0644 |
|
b128ops.h | File | 2.41 KB | 0644 |
|
blake2s.h | File | 2.37 KB | 0644 |
|
blowfish.h | File | 415 B | 0644 |
|
cast5.h | File | 590 B | 0644 |
|
cast6.h | File | 636 B | 0644 |
|
cast_common.h | File | 232 B | 0644 |
|
cbc.h | File | 3.48 KB | 0644 |
|
chacha20.h | File | 1.01 KB | 0644 |
|
cryptd.h | File | 2.5 KB | 0644 |
|
crypto_wq.h | File | 161 B | 0644 |
|
ctr.h | File | 524 B | 0644 |
|
des.h | File | 542 B | 0644 |
|
dh.h | File | 2.62 KB | 0644 |
|
drbg.h | File | 9.05 KB | 0644 |
|
ecdh.h | File | 2.67 KB | 0644 |
|
engine.h | File | 4 KB | 0644 |
|
gcm.h | File | 140 B | 0644 |
|
gf128mul.h | File | 9.41 KB | 0644 |
|
ghash.h | File | 381 B | 0644 |
|
hash.h | File | 31.48 KB | 0644 |
|
hash_info.h | File | 1.13 KB | 0644 |
|
hmac.h | File | 173 B | 0644 |
|
if_alg.h | File | 7 KB | 0644 |
|
kpp.h | File | 9.68 KB | 0644 |
|
lrw.h | File | 1.22 KB | 0644 |
|
mcryptd.h | File | 2.37 KB | 0644 |
|
md5.h | File | 497 B | 0644 |
|
null.h | File | 569 B | 0644 |
|
padlock.h | File | 649 B | 0644 |
|
pcrypt.h | File | 1.4 KB | 0644 |
|
pkcs7.h | File | 1.21 KB | 0644 |
|
poly1305.h | File | 920 B | 0644 |
|
public_key.h | File | 2.08 KB | 0644 |
|
rng.h | File | 6.66 KB | 0644 |
|
scatterwalk.h | File | 3.67 KB | 0644 |
|
serpent.h | File | 712 B | 0644 |
|
sha.h | File | 2.88 KB | 0644 |
|
sha1_base.h | File | 2.47 KB | 0644 |
|
sha256_base.h | File | 3.03 KB | 0644 |
|
sha3.h | File | 704 B | 0644 |
|
sha512_base.h | File | 3.19 KB | 0644 |
|
skcipher.h | File | 20.7 KB | 0644 |
|
sm3.h | File | 833 B | 0644 |
|
sm3_base.h | File | 2.95 KB | 0644 |
|
twofish.h | File | 755 B | 0644 |
|
xts.h | File | 1.81 KB | 0644 |
|