0001
0002
0003
0004
0005
0006
0007
0008 #ifndef _CRYPTO_CTR_H
0009 #define _CRYPTO_CTR_H
0010
0011 #include <crypto/algapi.h>
0012 #include <crypto/internal/skcipher.h>
0013 #include <linux/string.h>
0014 #include <linux/types.h>
0015
0016 #define CTR_RFC3686_NONCE_SIZE 4
0017 #define CTR_RFC3686_IV_SIZE 8
0018 #define CTR_RFC3686_BLOCK_SIZE 16
0019
0020 static inline int crypto_ctr_encrypt_walk(struct skcipher_request *req,
0021 void (*fn)(struct crypto_skcipher *,
0022 const u8 *, u8 *))
0023 {
0024 struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
0025 int blocksize = crypto_skcipher_chunksize(tfm);
0026 u8 buf[MAX_CIPHER_BLOCKSIZE];
0027 struct skcipher_walk walk;
0028 int err;
0029
0030
0031 if (WARN_ON_ONCE(!is_power_of_2(blocksize)))
0032 return -EINVAL;
0033
0034 err = skcipher_walk_virt(&walk, req, false);
0035
0036 while (walk.nbytes > 0) {
0037 u8 *dst = walk.dst.virt.addr;
0038 u8 *src = walk.src.virt.addr;
0039 int nbytes = walk.nbytes;
0040 int tail = 0;
0041
0042 if (nbytes < walk.total) {
0043 tail = walk.nbytes & (blocksize - 1);
0044 nbytes -= tail;
0045 }
0046
0047 do {
0048 int bsize = min(nbytes, blocksize);
0049
0050 fn(tfm, walk.iv, buf);
0051
0052 crypto_xor_cpy(dst, src, buf, bsize);
0053 crypto_inc(walk.iv, blocksize);
0054
0055 dst += bsize;
0056 src += bsize;
0057 nbytes -= bsize;
0058 } while (nbytes > 0);
0059
0060 err = skcipher_walk_done(&walk, tail);
0061 }
0062 return err;
0063 }
0064
0065 #endif