~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/crypto/cts.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /crypto/cts.c (Version linux-6.11.5) and /crypto/cts.c (Version linux-4.20.17)


  1 /*                                                  1 /*
  2  * CTS: Cipher Text Stealing mode                   2  * CTS: Cipher Text Stealing mode
  3  *                                                  3  *
  4  * COPYRIGHT (c) 2008                               4  * COPYRIGHT (c) 2008
  5  * The Regents of the University of Michigan        5  * The Regents of the University of Michigan
  6  * ALL RIGHTS RESERVED                              6  * ALL RIGHTS RESERVED
  7  *                                                  7  *
  8  * Permission is granted to use, copy, create       8  * Permission is granted to use, copy, create derivative works
  9  * and redistribute this software and such der      9  * and redistribute this software and such derivative works
 10  * for any purpose, so long as the name of The     10  * for any purpose, so long as the name of The University of
 11  * Michigan is not used in any advertising or      11  * Michigan is not used in any advertising or publicity
 12  * pertaining to the use of distribution of th     12  * pertaining to the use of distribution of this software
 13  * without specific, written prior authorizati     13  * without specific, written prior authorization.  If the
 14  * above copyright notice or any other identif     14  * above copyright notice or any other identification of the
 15  * University of Michigan is included in any c     15  * University of Michigan is included in any copy of any
 16  * portion of this software, then the disclaim     16  * portion of this software, then the disclaimer below must
 17  * also be included.                               17  * also be included.
 18  *                                                 18  *
 19  * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT RE     19  * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
 20  * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS F     20  * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
 21  * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVER     21  * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
 22  * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMP     22  * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
 23  * WITHOUT LIMITATION THE IMPLIED WARRANTIES O     23  * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
 24  * MERCHANTABILITY AND FITNESS FOR A PARTICULA     24  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
 25  * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL     25  * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
 26  * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIREC     26  * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
 27  * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY      27  * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
 28  * OUT OF OR IN CONNECTION WITH THE USE OF THE     28  * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
 29  * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF T     29  * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
 30  * SUCH DAMAGES.                                   30  * SUCH DAMAGES.
 31  */                                                31  */
 32                                                    32 
 33 /* Derived from various:                           33 /* Derived from various:
 34  *      Copyright (c) 2006 Herbert Xu <herbert     34  *      Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
 35  */                                                35  */
 36                                                    36 
 37 /*                                                 37 /*
 38  * This is the Cipher Text Stealing mode as de     38  * This is the Cipher Text Stealing mode as described by
 39  * Section 8 of rfc2040 and referenced by rfc3     39  * Section 8 of rfc2040 and referenced by rfc3962.
 40  * rfc3962 includes errata information in its      40  * rfc3962 includes errata information in its Appendix A.
 41  */                                                41  */
 42                                                    42 
 43 #include <crypto/algapi.h>                         43 #include <crypto/algapi.h>
 44 #include <crypto/internal/skcipher.h>              44 #include <crypto/internal/skcipher.h>
 45 #include <linux/err.h>                             45 #include <linux/err.h>
 46 #include <linux/init.h>                            46 #include <linux/init.h>
 47 #include <linux/kernel.h>                          47 #include <linux/kernel.h>
 48 #include <linux/log2.h>                            48 #include <linux/log2.h>
 49 #include <linux/module.h>                          49 #include <linux/module.h>
 50 #include <linux/scatterlist.h>                     50 #include <linux/scatterlist.h>
 51 #include <crypto/scatterwalk.h>                    51 #include <crypto/scatterwalk.h>
 52 #include <linux/slab.h>                            52 #include <linux/slab.h>
 53 #include <linux/compiler.h>                        53 #include <linux/compiler.h>
 54                                                    54 
 55 struct crypto_cts_ctx {                            55 struct crypto_cts_ctx {
 56         struct crypto_skcipher *child;             56         struct crypto_skcipher *child;
 57 };                                                 57 };
 58                                                    58 
 59 struct crypto_cts_reqctx {                         59 struct crypto_cts_reqctx {
 60         struct scatterlist sg[2];                  60         struct scatterlist sg[2];
 61         unsigned offset;                           61         unsigned offset;
 62         struct skcipher_request subreq;            62         struct skcipher_request subreq;
 63 };                                                 63 };
 64                                                    64 
 65 static inline u8 *crypto_cts_reqctx_space(stru     65 static inline u8 *crypto_cts_reqctx_space(struct skcipher_request *req)
 66 {                                                  66 {
 67         struct crypto_cts_reqctx *rctx = skcip     67         struct crypto_cts_reqctx *rctx = skcipher_request_ctx(req);
 68         struct crypto_skcipher *tfm = crypto_s     68         struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
 69         struct crypto_cts_ctx *ctx = crypto_sk     69         struct crypto_cts_ctx *ctx = crypto_skcipher_ctx(tfm);
 70         struct crypto_skcipher *child = ctx->c     70         struct crypto_skcipher *child = ctx->child;
 71                                                    71 
 72         return PTR_ALIGN((u8 *)(rctx + 1) + cr     72         return PTR_ALIGN((u8 *)(rctx + 1) + crypto_skcipher_reqsize(child),
 73                          crypto_skcipher_align     73                          crypto_skcipher_alignmask(tfm) + 1);
 74 }                                                  74 }
 75                                                    75 
 76 static int crypto_cts_setkey(struct crypto_skc     76 static int crypto_cts_setkey(struct crypto_skcipher *parent, const u8 *key,
 77                              unsigned int keyl     77                              unsigned int keylen)
 78 {                                                  78 {
 79         struct crypto_cts_ctx *ctx = crypto_sk     79         struct crypto_cts_ctx *ctx = crypto_skcipher_ctx(parent);
 80         struct crypto_skcipher *child = ctx->c     80         struct crypto_skcipher *child = ctx->child;
                                                   >>  81         int err;
 81                                                    82 
 82         crypto_skcipher_clear_flags(child, CRY     83         crypto_skcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
 83         crypto_skcipher_set_flags(child, crypt     84         crypto_skcipher_set_flags(child, crypto_skcipher_get_flags(parent) &
 84                                          CRYPT     85                                          CRYPTO_TFM_REQ_MASK);
 85         return crypto_skcipher_setkey(child, k !!  86         err = crypto_skcipher_setkey(child, key, keylen);
                                                   >>  87         crypto_skcipher_set_flags(parent, crypto_skcipher_get_flags(child) &
                                                   >>  88                                           CRYPTO_TFM_RES_MASK);
                                                   >>  89         return err;
 86 }                                                  90 }
 87                                                    91 
 88 static void cts_cbc_crypt_done(void *data, int !!  92 static void cts_cbc_crypt_done(struct crypto_async_request *areq, int err)
 89 {                                                  93 {
 90         struct skcipher_request *req = data;   !!  94         struct skcipher_request *req = areq->data;
 91                                                    95 
 92         if (err == -EINPROGRESS)                   96         if (err == -EINPROGRESS)
 93                 return;                            97                 return;
 94                                                    98 
 95         skcipher_request_complete(req, err);       99         skcipher_request_complete(req, err);
 96 }                                                 100 }
 97                                                   101 
 98 static int cts_cbc_encrypt(struct skcipher_req    102 static int cts_cbc_encrypt(struct skcipher_request *req)
 99 {                                                 103 {
100         struct crypto_cts_reqctx *rctx = skcip    104         struct crypto_cts_reqctx *rctx = skcipher_request_ctx(req);
101         struct crypto_skcipher *tfm = crypto_s    105         struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
102         struct skcipher_request *subreq = &rct    106         struct skcipher_request *subreq = &rctx->subreq;
103         int bsize = crypto_skcipher_blocksize(    107         int bsize = crypto_skcipher_blocksize(tfm);
104         u8 d[MAX_CIPHER_BLOCKSIZE * 2] __align    108         u8 d[MAX_CIPHER_BLOCKSIZE * 2] __aligned(__alignof__(u32));
105         struct scatterlist *sg;                   109         struct scatterlist *sg;
106         unsigned int offset;                      110         unsigned int offset;
107         int lastn;                                111         int lastn;
108                                                   112 
109         offset = rctx->offset;                    113         offset = rctx->offset;
110         lastn = req->cryptlen - offset;           114         lastn = req->cryptlen - offset;
111                                                   115 
112         sg = scatterwalk_ffwd(rctx->sg, req->d    116         sg = scatterwalk_ffwd(rctx->sg, req->dst, offset - bsize);
113         scatterwalk_map_and_copy(d + bsize, sg    117         scatterwalk_map_and_copy(d + bsize, sg, 0, bsize, 0);
114                                                   118 
115         memset(d, 0, bsize);                      119         memset(d, 0, bsize);
116         scatterwalk_map_and_copy(d, req->src,     120         scatterwalk_map_and_copy(d, req->src, offset, lastn, 0);
117                                                   121 
118         scatterwalk_map_and_copy(d, sg, 0, bsi    122         scatterwalk_map_and_copy(d, sg, 0, bsize + lastn, 1);
119         memzero_explicit(d, sizeof(d));           123         memzero_explicit(d, sizeof(d));
120                                                   124 
121         skcipher_request_set_callback(subreq,     125         skcipher_request_set_callback(subreq, req->base.flags &
122                                                   126                                               CRYPTO_TFM_REQ_MAY_BACKLOG,
123                                       cts_cbc_    127                                       cts_cbc_crypt_done, req);
124         skcipher_request_set_crypt(subreq, sg,    128         skcipher_request_set_crypt(subreq, sg, sg, bsize, req->iv);
125         return crypto_skcipher_encrypt(subreq)    129         return crypto_skcipher_encrypt(subreq);
126 }                                                 130 }
127                                                   131 
128 static void crypto_cts_encrypt_done(void *data !! 132 static void crypto_cts_encrypt_done(struct crypto_async_request *areq, int err)
129 {                                                 133 {
130         struct skcipher_request *req = data;   !! 134         struct skcipher_request *req = areq->data;
131                                                   135 
132         if (err)                                  136         if (err)
133                 goto out;                         137                 goto out;
134                                                   138 
135         err = cts_cbc_encrypt(req);               139         err = cts_cbc_encrypt(req);
136         if (err == -EINPROGRESS || err == -EBU    140         if (err == -EINPROGRESS || err == -EBUSY)
137                 return;                           141                 return;
138                                                   142 
139 out:                                              143 out:
140         skcipher_request_complete(req, err);      144         skcipher_request_complete(req, err);
141 }                                                 145 }
142                                                   146 
143 static int crypto_cts_encrypt(struct skcipher_    147 static int crypto_cts_encrypt(struct skcipher_request *req)
144 {                                                 148 {
145         struct crypto_skcipher *tfm = crypto_s    149         struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
146         struct crypto_cts_reqctx *rctx = skcip    150         struct crypto_cts_reqctx *rctx = skcipher_request_ctx(req);
147         struct crypto_cts_ctx *ctx = crypto_sk    151         struct crypto_cts_ctx *ctx = crypto_skcipher_ctx(tfm);
148         struct skcipher_request *subreq = &rct    152         struct skcipher_request *subreq = &rctx->subreq;
149         int bsize = crypto_skcipher_blocksize(    153         int bsize = crypto_skcipher_blocksize(tfm);
150         unsigned int nbytes = req->cryptlen;      154         unsigned int nbytes = req->cryptlen;
                                                   >> 155         int cbc_blocks = (nbytes + bsize - 1) / bsize - 1;
151         unsigned int offset;                      156         unsigned int offset;
152                                                   157 
153         skcipher_request_set_tfm(subreq, ctx->    158         skcipher_request_set_tfm(subreq, ctx->child);
154                                                   159 
155         if (nbytes < bsize)                    !! 160         if (cbc_blocks <= 0) {
156                 return -EINVAL;                << 
157                                                << 
158         if (nbytes == bsize) {                 << 
159                 skcipher_request_set_callback(    161                 skcipher_request_set_callback(subreq, req->base.flags,
160                                                   162                                               req->base.complete,
161                                                   163                                               req->base.data);
162                 skcipher_request_set_crypt(sub    164                 skcipher_request_set_crypt(subreq, req->src, req->dst, nbytes,
163                                            req    165                                            req->iv);
164                 return crypto_skcipher_encrypt    166                 return crypto_skcipher_encrypt(subreq);
165         }                                         167         }
166                                                   168 
167         offset = rounddown(nbytes - 1, bsize); !! 169         offset = cbc_blocks * bsize;
168         rctx->offset = offset;                    170         rctx->offset = offset;
169                                                   171 
170         skcipher_request_set_callback(subreq,     172         skcipher_request_set_callback(subreq, req->base.flags,
171                                       crypto_c    173                                       crypto_cts_encrypt_done, req);
172         skcipher_request_set_crypt(subreq, req    174         skcipher_request_set_crypt(subreq, req->src, req->dst,
173                                    offset, req    175                                    offset, req->iv);
174                                                   176 
175         return crypto_skcipher_encrypt(subreq)    177         return crypto_skcipher_encrypt(subreq) ?:
176                cts_cbc_encrypt(req);              178                cts_cbc_encrypt(req);
177 }                                                 179 }
178                                                   180 
179 static int cts_cbc_decrypt(struct skcipher_req    181 static int cts_cbc_decrypt(struct skcipher_request *req)
180 {                                                 182 {
181         struct crypto_cts_reqctx *rctx = skcip    183         struct crypto_cts_reqctx *rctx = skcipher_request_ctx(req);
182         struct crypto_skcipher *tfm = crypto_s    184         struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
183         struct skcipher_request *subreq = &rct    185         struct skcipher_request *subreq = &rctx->subreq;
184         int bsize = crypto_skcipher_blocksize(    186         int bsize = crypto_skcipher_blocksize(tfm);
185         u8 d[MAX_CIPHER_BLOCKSIZE * 2] __align    187         u8 d[MAX_CIPHER_BLOCKSIZE * 2] __aligned(__alignof__(u32));
186         struct scatterlist *sg;                   188         struct scatterlist *sg;
187         unsigned int offset;                      189         unsigned int offset;
188         u8 *space;                                190         u8 *space;
189         int lastn;                                191         int lastn;
190                                                   192 
191         offset = rctx->offset;                    193         offset = rctx->offset;
192         lastn = req->cryptlen - offset;           194         lastn = req->cryptlen - offset;
193                                                   195 
194         sg = scatterwalk_ffwd(rctx->sg, req->d    196         sg = scatterwalk_ffwd(rctx->sg, req->dst, offset - bsize);
195                                                   197 
196         /* 1. Decrypt Cn-1 (s) to create Dn */    198         /* 1. Decrypt Cn-1 (s) to create Dn */
197         scatterwalk_map_and_copy(d + bsize, sg    199         scatterwalk_map_and_copy(d + bsize, sg, 0, bsize, 0);
198         space = crypto_cts_reqctx_space(req);     200         space = crypto_cts_reqctx_space(req);
199         crypto_xor(d + bsize, space, bsize);      201         crypto_xor(d + bsize, space, bsize);
200         /* 2. Pad Cn with zeros at the end to     202         /* 2. Pad Cn with zeros at the end to create C of length BB */
201         memset(d, 0, bsize);                      203         memset(d, 0, bsize);
202         scatterwalk_map_and_copy(d, req->src,     204         scatterwalk_map_and_copy(d, req->src, offset, lastn, 0);
203         /* 3. Exclusive-or Dn with C to create    205         /* 3. Exclusive-or Dn with C to create Xn */
204         /* 4. Select the first Ln bytes of Xn     206         /* 4. Select the first Ln bytes of Xn to create Pn */
205         crypto_xor(d + bsize, d, lastn);          207         crypto_xor(d + bsize, d, lastn);
206                                                   208 
207         /* 5. Append the tail (BB - Ln) bytes     209         /* 5. Append the tail (BB - Ln) bytes of Xn to Cn to create En */
208         memcpy(d + lastn, d + bsize + lastn, b    210         memcpy(d + lastn, d + bsize + lastn, bsize - lastn);
209         /* 6. Decrypt En to create Pn-1 */        211         /* 6. Decrypt En to create Pn-1 */
210                                                   212 
211         scatterwalk_map_and_copy(d, sg, 0, bsi    213         scatterwalk_map_and_copy(d, sg, 0, bsize + lastn, 1);
212         memzero_explicit(d, sizeof(d));           214         memzero_explicit(d, sizeof(d));
213                                                   215 
214         skcipher_request_set_callback(subreq,     216         skcipher_request_set_callback(subreq, req->base.flags &
215                                                   217                                               CRYPTO_TFM_REQ_MAY_BACKLOG,
216                                       cts_cbc_    218                                       cts_cbc_crypt_done, req);
217                                                   219 
218         skcipher_request_set_crypt(subreq, sg,    220         skcipher_request_set_crypt(subreq, sg, sg, bsize, space);
219         return crypto_skcipher_decrypt(subreq)    221         return crypto_skcipher_decrypt(subreq);
220 }                                                 222 }
221                                                   223 
222 static void crypto_cts_decrypt_done(void *data !! 224 static void crypto_cts_decrypt_done(struct crypto_async_request *areq, int err)
223 {                                                 225 {
224         struct skcipher_request *req = data;   !! 226         struct skcipher_request *req = areq->data;
225                                                   227 
226         if (err)                                  228         if (err)
227                 goto out;                         229                 goto out;
228                                                   230 
229         err = cts_cbc_decrypt(req);               231         err = cts_cbc_decrypt(req);
230         if (err == -EINPROGRESS || err == -EBU    232         if (err == -EINPROGRESS || err == -EBUSY)
231                 return;                           233                 return;
232                                                   234 
233 out:                                              235 out:
234         skcipher_request_complete(req, err);      236         skcipher_request_complete(req, err);
235 }                                                 237 }
236                                                   238 
237 static int crypto_cts_decrypt(struct skcipher_    239 static int crypto_cts_decrypt(struct skcipher_request *req)
238 {                                                 240 {
239         struct crypto_skcipher *tfm = crypto_s    241         struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
240         struct crypto_cts_reqctx *rctx = skcip    242         struct crypto_cts_reqctx *rctx = skcipher_request_ctx(req);
241         struct crypto_cts_ctx *ctx = crypto_sk    243         struct crypto_cts_ctx *ctx = crypto_skcipher_ctx(tfm);
242         struct skcipher_request *subreq = &rct    244         struct skcipher_request *subreq = &rctx->subreq;
243         int bsize = crypto_skcipher_blocksize(    245         int bsize = crypto_skcipher_blocksize(tfm);
244         unsigned int nbytes = req->cryptlen;      246         unsigned int nbytes = req->cryptlen;
                                                   >> 247         int cbc_blocks = (nbytes + bsize - 1) / bsize - 1;
245         unsigned int offset;                      248         unsigned int offset;
246         u8 *space;                                249         u8 *space;
247                                                   250 
248         skcipher_request_set_tfm(subreq, ctx->    251         skcipher_request_set_tfm(subreq, ctx->child);
249                                                   252 
250         if (nbytes < bsize)                    !! 253         if (cbc_blocks <= 0) {
251                 return -EINVAL;                << 
252                                                << 
253         if (nbytes == bsize) {                 << 
254                 skcipher_request_set_callback(    254                 skcipher_request_set_callback(subreq, req->base.flags,
255                                                   255                                               req->base.complete,
256                                                   256                                               req->base.data);
257                 skcipher_request_set_crypt(sub    257                 skcipher_request_set_crypt(subreq, req->src, req->dst, nbytes,
258                                            req    258                                            req->iv);
259                 return crypto_skcipher_decrypt    259                 return crypto_skcipher_decrypt(subreq);
260         }                                         260         }
261                                                   261 
262         skcipher_request_set_callback(subreq,     262         skcipher_request_set_callback(subreq, req->base.flags,
263                                       crypto_c    263                                       crypto_cts_decrypt_done, req);
264                                                   264 
265         space = crypto_cts_reqctx_space(req);     265         space = crypto_cts_reqctx_space(req);
266                                                   266 
267         offset = rounddown(nbytes - 1, bsize); !! 267         offset = cbc_blocks * bsize;
268         rctx->offset = offset;                    268         rctx->offset = offset;
269                                                   269 
270         if (offset <= bsize)                   !! 270         if (cbc_blocks <= 1)
271                 memcpy(space, req->iv, bsize);    271                 memcpy(space, req->iv, bsize);
272         else                                      272         else
273                 scatterwalk_map_and_copy(space    273                 scatterwalk_map_and_copy(space, req->src, offset - 2 * bsize,
274                                          bsize    274                                          bsize, 0);
275                                                   275 
276         skcipher_request_set_crypt(subreq, req    276         skcipher_request_set_crypt(subreq, req->src, req->dst,
277                                    offset, req    277                                    offset, req->iv);
278                                                   278 
279         return crypto_skcipher_decrypt(subreq)    279         return crypto_skcipher_decrypt(subreq) ?:
280                cts_cbc_decrypt(req);              280                cts_cbc_decrypt(req);
281 }                                                 281 }
282                                                   282 
283 static int crypto_cts_init_tfm(struct crypto_s    283 static int crypto_cts_init_tfm(struct crypto_skcipher *tfm)
284 {                                                 284 {
285         struct skcipher_instance *inst = skcip    285         struct skcipher_instance *inst = skcipher_alg_instance(tfm);
286         struct crypto_skcipher_spawn *spawn =     286         struct crypto_skcipher_spawn *spawn = skcipher_instance_ctx(inst);
287         struct crypto_cts_ctx *ctx = crypto_sk    287         struct crypto_cts_ctx *ctx = crypto_skcipher_ctx(tfm);
288         struct crypto_skcipher *cipher;           288         struct crypto_skcipher *cipher;
289         unsigned reqsize;                         289         unsigned reqsize;
290         unsigned bsize;                           290         unsigned bsize;
291         unsigned align;                           291         unsigned align;
292                                                   292 
293         cipher = crypto_spawn_skcipher(spawn);    293         cipher = crypto_spawn_skcipher(spawn);
294         if (IS_ERR(cipher))                       294         if (IS_ERR(cipher))
295                 return PTR_ERR(cipher);           295                 return PTR_ERR(cipher);
296                                                   296 
297         ctx->child = cipher;                      297         ctx->child = cipher;
298                                                   298 
299         align = crypto_skcipher_alignmask(tfm)    299         align = crypto_skcipher_alignmask(tfm);
300         bsize = crypto_skcipher_blocksize(ciph    300         bsize = crypto_skcipher_blocksize(cipher);
301         reqsize = ALIGN(sizeof(struct crypto_c    301         reqsize = ALIGN(sizeof(struct crypto_cts_reqctx) +
302                         crypto_skcipher_reqsiz    302                         crypto_skcipher_reqsize(cipher),
303                         crypto_tfm_ctx_alignme    303                         crypto_tfm_ctx_alignment()) +
304                   (align & ~(crypto_tfm_ctx_al    304                   (align & ~(crypto_tfm_ctx_alignment() - 1)) + bsize;
305                                                   305 
306         crypto_skcipher_set_reqsize(tfm, reqsi    306         crypto_skcipher_set_reqsize(tfm, reqsize);
307                                                   307 
308         return 0;                                 308         return 0;
309 }                                                 309 }
310                                                   310 
311 static void crypto_cts_exit_tfm(struct crypto_    311 static void crypto_cts_exit_tfm(struct crypto_skcipher *tfm)
312 {                                                 312 {
313         struct crypto_cts_ctx *ctx = crypto_sk    313         struct crypto_cts_ctx *ctx = crypto_skcipher_ctx(tfm);
314                                                   314 
315         crypto_free_skcipher(ctx->child);         315         crypto_free_skcipher(ctx->child);
316 }                                                 316 }
317                                                   317 
318 static void crypto_cts_free(struct skcipher_in    318 static void crypto_cts_free(struct skcipher_instance *inst)
319 {                                                 319 {
320         crypto_drop_skcipher(skcipher_instance    320         crypto_drop_skcipher(skcipher_instance_ctx(inst));
321         kfree(inst);                              321         kfree(inst);
322 }                                                 322 }
323                                                   323 
324 static int crypto_cts_create(struct crypto_tem    324 static int crypto_cts_create(struct crypto_template *tmpl, struct rtattr **tb)
325 {                                                 325 {
326         struct crypto_skcipher_spawn *spawn;      326         struct crypto_skcipher_spawn *spawn;
327         struct skcipher_alg_common *alg;       << 
328         struct skcipher_instance *inst;           327         struct skcipher_instance *inst;
329         u32 mask;                              !! 328         struct crypto_attr_type *algt;
                                                   >> 329         struct skcipher_alg *alg;
                                                   >> 330         const char *cipher_name;
330         int err;                                  331         int err;
331                                                   332 
332         err = crypto_check_attr_type(tb, CRYPT !! 333         algt = crypto_get_attr_type(tb);
333         if (err)                               !! 334         if (IS_ERR(algt))
334                 return err;                    !! 335                 return PTR_ERR(algt);
                                                   >> 336 
                                                   >> 337         if ((algt->type ^ CRYPTO_ALG_TYPE_SKCIPHER) & algt->mask)
                                                   >> 338                 return -EINVAL;
                                                   >> 339 
                                                   >> 340         cipher_name = crypto_attr_alg_name(tb[1]);
                                                   >> 341         if (IS_ERR(cipher_name))
                                                   >> 342                 return PTR_ERR(cipher_name);
335                                                   343 
336         inst = kzalloc(sizeof(*inst) + sizeof(    344         inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
337         if (!inst)                                345         if (!inst)
338                 return -ENOMEM;                   346                 return -ENOMEM;
339                                                   347 
340         spawn = skcipher_instance_ctx(inst);      348         spawn = skcipher_instance_ctx(inst);
341                                                   349 
342         err = crypto_grab_skcipher(spawn, skci !! 350         crypto_set_skcipher_spawn(spawn, skcipher_crypto_instance(inst));
343                                    crypto_attr !! 351         err = crypto_grab_skcipher(spawn, cipher_name, 0,
                                                   >> 352                                    crypto_requires_sync(algt->type,
                                                   >> 353                                                         algt->mask));
344         if (err)                                  354         if (err)
345                 goto err_free_inst;               355                 goto err_free_inst;
346                                                   356 
347         alg = crypto_spawn_skcipher_alg_common !! 357         alg = crypto_spawn_skcipher_alg(spawn);
348                                                   358 
349         err = -EINVAL;                            359         err = -EINVAL;
350         if (alg->ivsize != alg->base.cra_block !! 360         if (crypto_skcipher_alg_ivsize(alg) != alg->base.cra_blocksize)
351                 goto err_free_inst;            !! 361                 goto err_drop_spawn;
352                                                   362 
353         if (strncmp(alg->base.cra_name, "cbc("    363         if (strncmp(alg->base.cra_name, "cbc(", 4))
354                 goto err_free_inst;            !! 364                 goto err_drop_spawn;
355                                                   365 
356         err = crypto_inst_setname(skcipher_cry    366         err = crypto_inst_setname(skcipher_crypto_instance(inst), "cts",
357                                   &alg->base);    367                                   &alg->base);
358         if (err)                                  368         if (err)
359                 goto err_free_inst;            !! 369                 goto err_drop_spawn;
360                                                   370 
                                                   >> 371         inst->alg.base.cra_flags = alg->base.cra_flags & CRYPTO_ALG_ASYNC;
361         inst->alg.base.cra_priority = alg->bas    372         inst->alg.base.cra_priority = alg->base.cra_priority;
362         inst->alg.base.cra_blocksize = alg->ba    373         inst->alg.base.cra_blocksize = alg->base.cra_blocksize;
363         inst->alg.base.cra_alignmask = alg->ba    374         inst->alg.base.cra_alignmask = alg->base.cra_alignmask;
364                                                   375 
365         inst->alg.ivsize = alg->base.cra_block    376         inst->alg.ivsize = alg->base.cra_blocksize;
366         inst->alg.chunksize = alg->chunksize;  !! 377         inst->alg.chunksize = crypto_skcipher_alg_chunksize(alg);
367         inst->alg.min_keysize = alg->min_keysi !! 378         inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(alg);
368         inst->alg.max_keysize = alg->max_keysi !! 379         inst->alg.max_keysize = crypto_skcipher_alg_max_keysize(alg);
369                                                   380 
370         inst->alg.base.cra_ctxsize = sizeof(st    381         inst->alg.base.cra_ctxsize = sizeof(struct crypto_cts_ctx);
371                                                   382 
372         inst->alg.init = crypto_cts_init_tfm;     383         inst->alg.init = crypto_cts_init_tfm;
373         inst->alg.exit = crypto_cts_exit_tfm;     384         inst->alg.exit = crypto_cts_exit_tfm;
374                                                   385 
375         inst->alg.setkey = crypto_cts_setkey;     386         inst->alg.setkey = crypto_cts_setkey;
376         inst->alg.encrypt = crypto_cts_encrypt    387         inst->alg.encrypt = crypto_cts_encrypt;
377         inst->alg.decrypt = crypto_cts_decrypt    388         inst->alg.decrypt = crypto_cts_decrypt;
378                                                   389 
379         inst->free = crypto_cts_free;             390         inst->free = crypto_cts_free;
380                                                   391 
381         err = skcipher_register_instance(tmpl,    392         err = skcipher_register_instance(tmpl, inst);
382         if (err) {                             !! 393         if (err)
383 err_free_inst:                                 !! 394                 goto err_drop_spawn;
384                 crypto_cts_free(inst);         !! 395 
385         }                                      !! 396 out:
386         return err;                               397         return err;
                                                   >> 398 
                                                   >> 399 err_drop_spawn:
                                                   >> 400         crypto_drop_skcipher(spawn);
                                                   >> 401 err_free_inst:
                                                   >> 402         kfree(inst);
                                                   >> 403         goto out;
387 }                                                 404 }
388                                                   405 
389 static struct crypto_template crypto_cts_tmpl     406 static struct crypto_template crypto_cts_tmpl = {
390         .name = "cts",                            407         .name = "cts",
391         .create = crypto_cts_create,              408         .create = crypto_cts_create,
392         .module = THIS_MODULE,                    409         .module = THIS_MODULE,
393 };                                                410 };
394                                                   411 
395 static int __init crypto_cts_module_init(void)    412 static int __init crypto_cts_module_init(void)
396 {                                                 413 {
397         return crypto_register_template(&crypt    414         return crypto_register_template(&crypto_cts_tmpl);
398 }                                                 415 }
399                                                   416 
400 static void __exit crypto_cts_module_exit(void    417 static void __exit crypto_cts_module_exit(void)
401 {                                                 418 {
402         crypto_unregister_template(&crypto_cts    419         crypto_unregister_template(&crypto_cts_tmpl);
403 }                                                 420 }
404                                                   421 
405 subsys_initcall(crypto_cts_module_init);       !! 422 module_init(crypto_cts_module_init);
406 module_exit(crypto_cts_module_exit);              423 module_exit(crypto_cts_module_exit);
407                                                   424 
408 MODULE_LICENSE("Dual BSD/GPL");                   425 MODULE_LICENSE("Dual BSD/GPL");
409 MODULE_DESCRIPTION("CTS-CBC CipherText Stealin    426 MODULE_DESCRIPTION("CTS-CBC CipherText Stealing for CBC");
410 MODULE_ALIAS_CRYPTO("cts");                       427 MODULE_ALIAS_CRYPTO("cts");
411                                                   428 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php