hc
2024-01-31 f9004dbfff8a3fbbd7e2a88c8a4327c7f2f8e5b2
kernel/include/crypto/ctr.h
....@@ -1,20 +1,65 @@
1
+/* SPDX-License-Identifier: GPL-2.0-or-later */
12 /*
23 * CTR: Counter mode
34 *
45 * Copyright (c) 2007 Herbert Xu <herbert@gondor.apana.org.au>
5
- *
6
- * This program is free software; you can redistribute it and/or modify it
7
- * under the terms of the GNU General Public License as published by the Free
8
- * Software Foundation; either version 2 of the License, or (at your option)
9
- * any later version.
10
- *
116 */
127
138 #ifndef _CRYPTO_CTR_H
149 #define _CRYPTO_CTR_H
1510
11
+#include <crypto/algapi.h>
12
+#include <crypto/internal/skcipher.h>
13
+#include <linux/string.h>
14
+#include <linux/types.h>
15
+
1616 #define CTR_RFC3686_NONCE_SIZE 4
1717 #define CTR_RFC3686_IV_SIZE 8
1818 #define CTR_RFC3686_BLOCK_SIZE 16
1919
20
+static inline int crypto_ctr_encrypt_walk(struct skcipher_request *req,
21
+ void (*fn)(struct crypto_skcipher *,
22
+ const u8 *, u8 *))
23
+{
24
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
25
+ int blocksize = crypto_skcipher_chunksize(tfm);
26
+ u8 buf[MAX_CIPHER_BLOCKSIZE];
27
+ struct skcipher_walk walk;
28
+ int err;
29
+
30
+ /* avoid integer division due to variable blocksize parameter */
31
+ if (WARN_ON_ONCE(!is_power_of_2(blocksize)))
32
+ return -EINVAL;
33
+
34
+ err = skcipher_walk_virt(&walk, req, false);
35
+
36
+ while (walk.nbytes > 0) {
37
+ u8 *dst = walk.dst.virt.addr;
38
+ u8 *src = walk.src.virt.addr;
39
+ int nbytes = walk.nbytes;
40
+ int tail = 0;
41
+
42
+ if (nbytes < walk.total) {
43
+ tail = walk.nbytes & (blocksize - 1);
44
+ nbytes -= tail;
45
+ }
46
+
47
+ do {
48
+ int bsize = min(nbytes, blocksize);
49
+
50
+ fn(tfm, walk.iv, buf);
51
+
52
+ crypto_xor_cpy(dst, src, buf, bsize);
53
+ crypto_inc(walk.iv, blocksize);
54
+
55
+ dst += bsize;
56
+ src += bsize;
57
+ nbytes -= bsize;
58
+ } while (nbytes > 0);
59
+
60
+ err = skcipher_walk_done(&walk, tail);
61
+ }
62
+ return err;
63
+}
64
+
2065 #endif /* _CRYPTO_CTR_H */