~ [ 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.15.18)


  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>                     << 
 44 #include <crypto/internal/skcipher.h>              43 #include <crypto/internal/skcipher.h>
 45 #include <linux/err.h>                             44 #include <linux/err.h>
 46 #include <linux/init.h>                            45 #include <linux/init.h>
 47 #include <linux/kernel.h>                          46 #include <linux/kernel.h>
 48 #include <linux/log2.h>                            47 #include <linux/log2.h>
 49 #include <linux/module.h>                          48 #include <linux/module.h>
 50 #include <linux/scatterlist.h>                     49 #include <linux/scatterlist.h>
 51 #include <crypto/scatterwalk.h>                    50 #include <crypto/scatterwalk.h>
 52 #include <linux/slab.h>                            51 #include <linux/slab.h>
 53 #include <linux/compiler.h>                        52 #include <linux/compiler.h>
 54                                                    53 
 55 struct crypto_cts_ctx {                            54 struct crypto_cts_ctx {
 56         struct crypto_skcipher *child;             55         struct crypto_skcipher *child;
 57 };                                                 56 };
 58                                                    57 
 59 struct crypto_cts_reqctx {                         58 struct crypto_cts_reqctx {
 60         struct scatterlist sg[2];                  59         struct scatterlist sg[2];
 61         unsigned offset;                           60         unsigned offset;
 62         struct skcipher_request subreq;            61         struct skcipher_request subreq;
 63 };                                                 62 };
 64                                                    63 
 65 static inline u8 *crypto_cts_reqctx_space(stru     64 static inline u8 *crypto_cts_reqctx_space(struct skcipher_request *req)
 66 {                                                  65 {
 67         struct crypto_cts_reqctx *rctx = skcip     66         struct crypto_cts_reqctx *rctx = skcipher_request_ctx(req);
 68         struct crypto_skcipher *tfm = crypto_s     67         struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
 69         struct crypto_cts_ctx *ctx = crypto_sk     68         struct crypto_cts_ctx *ctx = crypto_skcipher_ctx(tfm);
 70         struct crypto_skcipher *child = ctx->c     69         struct crypto_skcipher *child = ctx->child;
 71                                                    70 
 72         return PTR_ALIGN((u8 *)(rctx + 1) + cr     71         return PTR_ALIGN((u8 *)(rctx + 1) + crypto_skcipher_reqsize(child),
 73                          crypto_skcipher_align     72                          crypto_skcipher_alignmask(tfm) + 1);
 74 }                                                  73 }
 75                                                    74 
 76 static int crypto_cts_setkey(struct crypto_skc     75 static int crypto_cts_setkey(struct crypto_skcipher *parent, const u8 *key,
 77                              unsigned int keyl     76                              unsigned int keylen)
 78 {                                                  77 {
 79         struct crypto_cts_ctx *ctx = crypto_sk     78         struct crypto_cts_ctx *ctx = crypto_skcipher_ctx(parent);
 80         struct crypto_skcipher *child = ctx->c     79         struct crypto_skcipher *child = ctx->child;
                                                   >>  80         int err;
 81                                                    81 
 82         crypto_skcipher_clear_flags(child, CRY     82         crypto_skcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
 83         crypto_skcipher_set_flags(child, crypt     83         crypto_skcipher_set_flags(child, crypto_skcipher_get_flags(parent) &
 84                                          CRYPT     84                                          CRYPTO_TFM_REQ_MASK);
 85         return crypto_skcipher_setkey(child, k !!  85         err = crypto_skcipher_setkey(child, key, keylen);
                                                   >>  86         crypto_skcipher_set_flags(parent, crypto_skcipher_get_flags(child) &
                                                   >>  87                                           CRYPTO_TFM_RES_MASK);
                                                   >>  88         return err;
 86 }                                                  89 }
 87                                                    90 
 88 static void cts_cbc_crypt_done(void *data, int !!  91 static void cts_cbc_crypt_done(struct crypto_async_request *areq, int err)
 89 {                                                  92 {
 90         struct skcipher_request *req = data;   !!  93         struct skcipher_request *req = areq->data;
 91                                                    94 
 92         if (err == -EINPROGRESS)                   95         if (err == -EINPROGRESS)
 93                 return;                            96                 return;
 94                                                    97 
 95         skcipher_request_complete(req, err);       98         skcipher_request_complete(req, err);
 96 }                                                  99 }
 97                                                   100 
 98 static int cts_cbc_encrypt(struct skcipher_req    101 static int cts_cbc_encrypt(struct skcipher_request *req)
 99 {                                                 102 {
100         struct crypto_cts_reqctx *rctx = skcip    103         struct crypto_cts_reqctx *rctx = skcipher_request_ctx(req);
101         struct crypto_skcipher *tfm = crypto_s    104         struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
102         struct skcipher_request *subreq = &rct    105         struct skcipher_request *subreq = &rctx->subreq;
103         int bsize = crypto_skcipher_blocksize(    106         int bsize = crypto_skcipher_blocksize(tfm);
104         u8 d[MAX_CIPHER_BLOCKSIZE * 2] __align !! 107         u8 d[bsize * 2] __aligned(__alignof__(u32));
105         struct scatterlist *sg;                   108         struct scatterlist *sg;
106         unsigned int offset;                      109         unsigned int offset;
107         int lastn;                                110         int lastn;
108                                                   111 
109         offset = rctx->offset;                    112         offset = rctx->offset;
110         lastn = req->cryptlen - offset;           113         lastn = req->cryptlen - offset;
111                                                   114 
112         sg = scatterwalk_ffwd(rctx->sg, req->d    115         sg = scatterwalk_ffwd(rctx->sg, req->dst, offset - bsize);
113         scatterwalk_map_and_copy(d + bsize, sg    116         scatterwalk_map_and_copy(d + bsize, sg, 0, bsize, 0);
114                                                   117 
115         memset(d, 0, bsize);                      118         memset(d, 0, bsize);
116         scatterwalk_map_and_copy(d, req->src,     119         scatterwalk_map_and_copy(d, req->src, offset, lastn, 0);
117                                                   120 
118         scatterwalk_map_and_copy(d, sg, 0, bsi    121         scatterwalk_map_and_copy(d, sg, 0, bsize + lastn, 1);
119         memzero_explicit(d, sizeof(d));           122         memzero_explicit(d, sizeof(d));
120                                                   123 
121         skcipher_request_set_callback(subreq,     124         skcipher_request_set_callback(subreq, req->base.flags &
122                                                   125                                               CRYPTO_TFM_REQ_MAY_BACKLOG,
123                                       cts_cbc_    126                                       cts_cbc_crypt_done, req);
124         skcipher_request_set_crypt(subreq, sg,    127         skcipher_request_set_crypt(subreq, sg, sg, bsize, req->iv);
125         return crypto_skcipher_encrypt(subreq)    128         return crypto_skcipher_encrypt(subreq);
126 }                                                 129 }
127                                                   130 
128 static void crypto_cts_encrypt_done(void *data !! 131 static void crypto_cts_encrypt_done(struct crypto_async_request *areq, int err)
129 {                                                 132 {
130         struct skcipher_request *req = data;   !! 133         struct skcipher_request *req = areq->data;
131                                                   134 
132         if (err)                                  135         if (err)
133                 goto out;                         136                 goto out;
134                                                   137 
135         err = cts_cbc_encrypt(req);               138         err = cts_cbc_encrypt(req);
136         if (err == -EINPROGRESS || err == -EBU    139         if (err == -EINPROGRESS || err == -EBUSY)
137                 return;                           140                 return;
138                                                   141 
139 out:                                              142 out:
140         skcipher_request_complete(req, err);      143         skcipher_request_complete(req, err);
141 }                                                 144 }
142                                                   145 
143 static int crypto_cts_encrypt(struct skcipher_    146 static int crypto_cts_encrypt(struct skcipher_request *req)
144 {                                                 147 {
145         struct crypto_skcipher *tfm = crypto_s    148         struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
146         struct crypto_cts_reqctx *rctx = skcip    149         struct crypto_cts_reqctx *rctx = skcipher_request_ctx(req);
147         struct crypto_cts_ctx *ctx = crypto_sk    150         struct crypto_cts_ctx *ctx = crypto_skcipher_ctx(tfm);
148         struct skcipher_request *subreq = &rct    151         struct skcipher_request *subreq = &rctx->subreq;
149         int bsize = crypto_skcipher_blocksize(    152         int bsize = crypto_skcipher_blocksize(tfm);
150         unsigned int nbytes = req->cryptlen;      153         unsigned int nbytes = req->cryptlen;
                                                   >> 154         int cbc_blocks = (nbytes + bsize - 1) / bsize - 1;
151         unsigned int offset;                      155         unsigned int offset;
152                                                   156 
153         skcipher_request_set_tfm(subreq, ctx->    157         skcipher_request_set_tfm(subreq, ctx->child);
154                                                   158 
155         if (nbytes < bsize)                    !! 159         if (cbc_blocks <= 0) {
156                 return -EINVAL;                << 
157                                                << 
158         if (nbytes == bsize) {                 << 
159                 skcipher_request_set_callback(    160                 skcipher_request_set_callback(subreq, req->base.flags,
160                                                   161                                               req->base.complete,
161                                                   162                                               req->base.data);
162                 skcipher_request_set_crypt(sub    163                 skcipher_request_set_crypt(subreq, req->src, req->dst, nbytes,
163                                            req    164                                            req->iv);
164                 return crypto_skcipher_encrypt    165                 return crypto_skcipher_encrypt(subreq);
165         }                                         166         }
166                                                   167 
167         offset = rounddown(nbytes - 1, bsize); !! 168         offset = cbc_blocks * bsize;
168         rctx->offset = offset;                    169         rctx->offset = offset;
169                                                   170 
170         skcipher_request_set_callback(subreq,     171         skcipher_request_set_callback(subreq, req->base.flags,
171                                       crypto_c    172                                       crypto_cts_encrypt_done, req);
172         skcipher_request_set_crypt(subreq, req    173         skcipher_request_set_crypt(subreq, req->src, req->dst,
173                                    offset, req    174                                    offset, req->iv);
174                                                   175 
175         return crypto_skcipher_encrypt(subreq)    176         return crypto_skcipher_encrypt(subreq) ?:
176                cts_cbc_encrypt(req);              177                cts_cbc_encrypt(req);
177 }                                                 178 }
178                                                   179 
179 static int cts_cbc_decrypt(struct skcipher_req    180 static int cts_cbc_decrypt(struct skcipher_request *req)
180 {                                                 181 {
181         struct crypto_cts_reqctx *rctx = skcip    182         struct crypto_cts_reqctx *rctx = skcipher_request_ctx(req);
182         struct crypto_skcipher *tfm = crypto_s    183         struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
183         struct skcipher_request *subreq = &rct    184         struct skcipher_request *subreq = &rctx->subreq;
184         int bsize = crypto_skcipher_blocksize(    185         int bsize = crypto_skcipher_blocksize(tfm);
185         u8 d[MAX_CIPHER_BLOCKSIZE * 2] __align !! 186         u8 d[bsize * 2] __aligned(__alignof__(u32));
186         struct scatterlist *sg;                   187         struct scatterlist *sg;
187         unsigned int offset;                      188         unsigned int offset;
188         u8 *space;                                189         u8 *space;
189         int lastn;                                190         int lastn;
190                                                   191 
191         offset = rctx->offset;                    192         offset = rctx->offset;
192         lastn = req->cryptlen - offset;           193         lastn = req->cryptlen - offset;
193                                                   194 
194         sg = scatterwalk_ffwd(rctx->sg, req->d    195         sg = scatterwalk_ffwd(rctx->sg, req->dst, offset - bsize);
195                                                   196 
196         /* 1. Decrypt Cn-1 (s) to create Dn */    197         /* 1. Decrypt Cn-1 (s) to create Dn */
197         scatterwalk_map_and_copy(d + bsize, sg    198         scatterwalk_map_and_copy(d + bsize, sg, 0, bsize, 0);
198         space = crypto_cts_reqctx_space(req);     199         space = crypto_cts_reqctx_space(req);
199         crypto_xor(d + bsize, space, bsize);      200         crypto_xor(d + bsize, space, bsize);
200         /* 2. Pad Cn with zeros at the end to     201         /* 2. Pad Cn with zeros at the end to create C of length BB */
201         memset(d, 0, bsize);                      202         memset(d, 0, bsize);
202         scatterwalk_map_and_copy(d, req->src,     203         scatterwalk_map_and_copy(d, req->src, offset, lastn, 0);
203         /* 3. Exclusive-or Dn with C to create    204         /* 3. Exclusive-or Dn with C to create Xn */
204         /* 4. Select the first Ln bytes of Xn     205         /* 4. Select the first Ln bytes of Xn to create Pn */
205         crypto_xor(d + bsize, d, lastn);          206         crypto_xor(d + bsize, d, lastn);
206                                                   207 
207         /* 5. Append the tail (BB - Ln) bytes     208         /* 5. Append the tail (BB - Ln) bytes of Xn to Cn to create En */
208         memcpy(d + lastn, d + bsize + lastn, b    209         memcpy(d + lastn, d + bsize + lastn, bsize - lastn);
209         /* 6. Decrypt En to create Pn-1 */        210         /* 6. Decrypt En to create Pn-1 */
210                                                   211 
211         scatterwalk_map_and_copy(d, sg, 0, bsi    212         scatterwalk_map_and_copy(d, sg, 0, bsize + lastn, 1);
212         memzero_explicit(d, sizeof(d));           213         memzero_explicit(d, sizeof(d));
213                                                   214 
214         skcipher_request_set_callback(subreq,     215         skcipher_request_set_callback(subreq, req->base.flags &
215                                                   216                                               CRYPTO_TFM_REQ_MAY_BACKLOG,
216                                       cts_cbc_    217                                       cts_cbc_crypt_done, req);
217                                                   218 
218         skcipher_request_set_crypt(subreq, sg,    219         skcipher_request_set_crypt(subreq, sg, sg, bsize, space);
219         return crypto_skcipher_decrypt(subreq)    220         return crypto_skcipher_decrypt(subreq);
220 }                                                 221 }
221                                                   222 
222 static void crypto_cts_decrypt_done(void *data !! 223 static void crypto_cts_decrypt_done(struct crypto_async_request *areq, int err)
223 {                                                 224 {
224         struct skcipher_request *req = data;   !! 225         struct skcipher_request *req = areq->data;
225                                                   226 
226         if (err)                                  227         if (err)
227                 goto out;                         228                 goto out;
228                                                   229 
229         err = cts_cbc_decrypt(req);               230         err = cts_cbc_decrypt(req);
230         if (err == -EINPROGRESS || err == -EBU    231         if (err == -EINPROGRESS || err == -EBUSY)
231                 return;                           232                 return;
232                                                   233 
233 out:                                              234 out:
234         skcipher_request_complete(req, err);      235         skcipher_request_complete(req, err);
235 }                                                 236 }
236                                                   237 
237 static int crypto_cts_decrypt(struct skcipher_    238 static int crypto_cts_decrypt(struct skcipher_request *req)
238 {                                                 239 {
239         struct crypto_skcipher *tfm = crypto_s    240         struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
240         struct crypto_cts_reqctx *rctx = skcip    241         struct crypto_cts_reqctx *rctx = skcipher_request_ctx(req);
241         struct crypto_cts_ctx *ctx = crypto_sk    242         struct crypto_cts_ctx *ctx = crypto_skcipher_ctx(tfm);
242         struct skcipher_request *subreq = &rct    243         struct skcipher_request *subreq = &rctx->subreq;
243         int bsize = crypto_skcipher_blocksize(    244         int bsize = crypto_skcipher_blocksize(tfm);
244         unsigned int nbytes = req->cryptlen;      245         unsigned int nbytes = req->cryptlen;
                                                   >> 246         int cbc_blocks = (nbytes + bsize - 1) / bsize - 1;
245         unsigned int offset;                      247         unsigned int offset;
246         u8 *space;                                248         u8 *space;
247                                                   249 
248         skcipher_request_set_tfm(subreq, ctx->    250         skcipher_request_set_tfm(subreq, ctx->child);
249                                                   251 
250         if (nbytes < bsize)                    !! 252         if (cbc_blocks <= 0) {
251                 return -EINVAL;                << 
252                                                << 
253         if (nbytes == bsize) {                 << 
254                 skcipher_request_set_callback(    253                 skcipher_request_set_callback(subreq, req->base.flags,
255                                                   254                                               req->base.complete,
256                                                   255                                               req->base.data);
257                 skcipher_request_set_crypt(sub    256                 skcipher_request_set_crypt(subreq, req->src, req->dst, nbytes,
258                                            req    257                                            req->iv);
259                 return crypto_skcipher_decrypt    258                 return crypto_skcipher_decrypt(subreq);
260         }                                         259         }
261                                                   260 
262         skcipher_request_set_callback(subreq,     261         skcipher_request_set_callback(subreq, req->base.flags,
263                                       crypto_c    262                                       crypto_cts_decrypt_done, req);
264                                                   263 
265         space = crypto_cts_reqctx_space(req);     264         space = crypto_cts_reqctx_space(req);
266                                                   265 
267         offset = rounddown(nbytes - 1, bsize); !! 266         offset = cbc_blocks * bsize;
268         rctx->offset = offset;                    267         rctx->offset = offset;
269                                                   268 
270         if (offset <= bsize)                   !! 269         if (cbc_blocks <= 1)
271                 memcpy(space, req->iv, bsize);    270                 memcpy(space, req->iv, bsize);
272         else                                      271         else
273                 scatterwalk_map_and_copy(space    272                 scatterwalk_map_and_copy(space, req->src, offset - 2 * bsize,
274                                          bsize    273                                          bsize, 0);
275                                                   274 
276         skcipher_request_set_crypt(subreq, req    275         skcipher_request_set_crypt(subreq, req->src, req->dst,
277                                    offset, req    276                                    offset, req->iv);
278                                                   277 
279         return crypto_skcipher_decrypt(subreq)    278         return crypto_skcipher_decrypt(subreq) ?:
280                cts_cbc_decrypt(req);              279                cts_cbc_decrypt(req);
281 }                                                 280 }
282                                                   281 
283 static int crypto_cts_init_tfm(struct crypto_s    282 static int crypto_cts_init_tfm(struct crypto_skcipher *tfm)
284 {                                                 283 {
285         struct skcipher_instance *inst = skcip    284         struct skcipher_instance *inst = skcipher_alg_instance(tfm);
286         struct crypto_skcipher_spawn *spawn =     285         struct crypto_skcipher_spawn *spawn = skcipher_instance_ctx(inst);
287         struct crypto_cts_ctx *ctx = crypto_sk    286         struct crypto_cts_ctx *ctx = crypto_skcipher_ctx(tfm);
288         struct crypto_skcipher *cipher;           287         struct crypto_skcipher *cipher;
289         unsigned reqsize;                         288         unsigned reqsize;
290         unsigned bsize;                           289         unsigned bsize;
291         unsigned align;                           290         unsigned align;
292                                                   291 
293         cipher = crypto_spawn_skcipher(spawn);    292         cipher = crypto_spawn_skcipher(spawn);
294         if (IS_ERR(cipher))                       293         if (IS_ERR(cipher))
295                 return PTR_ERR(cipher);           294                 return PTR_ERR(cipher);
296                                                   295 
297         ctx->child = cipher;                      296         ctx->child = cipher;
298                                                   297 
299         align = crypto_skcipher_alignmask(tfm)    298         align = crypto_skcipher_alignmask(tfm);
300         bsize = crypto_skcipher_blocksize(ciph    299         bsize = crypto_skcipher_blocksize(cipher);
301         reqsize = ALIGN(sizeof(struct crypto_c    300         reqsize = ALIGN(sizeof(struct crypto_cts_reqctx) +
302                         crypto_skcipher_reqsiz    301                         crypto_skcipher_reqsize(cipher),
303                         crypto_tfm_ctx_alignme    302                         crypto_tfm_ctx_alignment()) +
304                   (align & ~(crypto_tfm_ctx_al    303                   (align & ~(crypto_tfm_ctx_alignment() - 1)) + bsize;
305                                                   304 
306         crypto_skcipher_set_reqsize(tfm, reqsi    305         crypto_skcipher_set_reqsize(tfm, reqsize);
307                                                   306 
308         return 0;                                 307         return 0;
309 }                                                 308 }
310                                                   309 
311 static void crypto_cts_exit_tfm(struct crypto_    310 static void crypto_cts_exit_tfm(struct crypto_skcipher *tfm)
312 {                                                 311 {
313         struct crypto_cts_ctx *ctx = crypto_sk    312         struct crypto_cts_ctx *ctx = crypto_skcipher_ctx(tfm);
314                                                   313 
315         crypto_free_skcipher(ctx->child);         314         crypto_free_skcipher(ctx->child);
316 }                                                 315 }
317                                                   316 
318 static void crypto_cts_free(struct skcipher_in    317 static void crypto_cts_free(struct skcipher_instance *inst)
319 {                                                 318 {
320         crypto_drop_skcipher(skcipher_instance    319         crypto_drop_skcipher(skcipher_instance_ctx(inst));
321         kfree(inst);                              320         kfree(inst);
322 }                                                 321 }
323                                                   322 
324 static int crypto_cts_create(struct crypto_tem    323 static int crypto_cts_create(struct crypto_template *tmpl, struct rtattr **tb)
325 {                                                 324 {
326         struct crypto_skcipher_spawn *spawn;      325         struct crypto_skcipher_spawn *spawn;
327         struct skcipher_alg_common *alg;       << 
328         struct skcipher_instance *inst;           326         struct skcipher_instance *inst;
329         u32 mask;                              !! 327         struct crypto_attr_type *algt;
                                                   >> 328         struct skcipher_alg *alg;
                                                   >> 329         const char *cipher_name;
330         int err;                                  330         int err;
331                                                   331 
332         err = crypto_check_attr_type(tb, CRYPT !! 332         algt = crypto_get_attr_type(tb);
333         if (err)                               !! 333         if (IS_ERR(algt))
334                 return err;                    !! 334                 return PTR_ERR(algt);
                                                   >> 335 
                                                   >> 336         if ((algt->type ^ CRYPTO_ALG_TYPE_SKCIPHER) & algt->mask)
                                                   >> 337                 return -EINVAL;
                                                   >> 338 
                                                   >> 339         cipher_name = crypto_attr_alg_name(tb[1]);
                                                   >> 340         if (IS_ERR(cipher_name))
                                                   >> 341                 return PTR_ERR(cipher_name);
335                                                   342 
336         inst = kzalloc(sizeof(*inst) + sizeof(    343         inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
337         if (!inst)                                344         if (!inst)
338                 return -ENOMEM;                   345                 return -ENOMEM;
339                                                   346 
340         spawn = skcipher_instance_ctx(inst);      347         spawn = skcipher_instance_ctx(inst);
341                                                   348 
342         err = crypto_grab_skcipher(spawn, skci !! 349         crypto_set_skcipher_spawn(spawn, skcipher_crypto_instance(inst));
343                                    crypto_attr !! 350         err = crypto_grab_skcipher(spawn, cipher_name, 0,
                                                   >> 351                                    crypto_requires_sync(algt->type,
                                                   >> 352                                                         algt->mask));
344         if (err)                                  353         if (err)
345                 goto err_free_inst;               354                 goto err_free_inst;
346                                                   355 
347         alg = crypto_spawn_skcipher_alg_common !! 356         alg = crypto_spawn_skcipher_alg(spawn);
348                                                   357 
349         err = -EINVAL;                            358         err = -EINVAL;
350         if (alg->ivsize != alg->base.cra_block !! 359         if (crypto_skcipher_alg_ivsize(alg) != alg->base.cra_blocksize)
351                 goto err_free_inst;            !! 360                 goto err_drop_spawn;
352                                                   361 
353         if (strncmp(alg->base.cra_name, "cbc("    362         if (strncmp(alg->base.cra_name, "cbc(", 4))
354                 goto err_free_inst;            !! 363                 goto err_drop_spawn;
355                                                   364 
356         err = crypto_inst_setname(skcipher_cry    365         err = crypto_inst_setname(skcipher_crypto_instance(inst), "cts",
357                                   &alg->base);    366                                   &alg->base);
358         if (err)                                  367         if (err)
359                 goto err_free_inst;            !! 368                 goto err_drop_spawn;
360                                                   369 
                                                   >> 370         inst->alg.base.cra_flags = alg->base.cra_flags & CRYPTO_ALG_ASYNC;
361         inst->alg.base.cra_priority = alg->bas    371         inst->alg.base.cra_priority = alg->base.cra_priority;
362         inst->alg.base.cra_blocksize = alg->ba    372         inst->alg.base.cra_blocksize = alg->base.cra_blocksize;
363         inst->alg.base.cra_alignmask = alg->ba    373         inst->alg.base.cra_alignmask = alg->base.cra_alignmask;
364                                                   374 
365         inst->alg.ivsize = alg->base.cra_block    375         inst->alg.ivsize = alg->base.cra_blocksize;
366         inst->alg.chunksize = alg->chunksize;  !! 376         inst->alg.chunksize = crypto_skcipher_alg_chunksize(alg);
367         inst->alg.min_keysize = alg->min_keysi !! 377         inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(alg);
368         inst->alg.max_keysize = alg->max_keysi !! 378         inst->alg.max_keysize = crypto_skcipher_alg_max_keysize(alg);
369                                                   379 
370         inst->alg.base.cra_ctxsize = sizeof(st    380         inst->alg.base.cra_ctxsize = sizeof(struct crypto_cts_ctx);
371                                                   381 
372         inst->alg.init = crypto_cts_init_tfm;     382         inst->alg.init = crypto_cts_init_tfm;
373         inst->alg.exit = crypto_cts_exit_tfm;     383         inst->alg.exit = crypto_cts_exit_tfm;
374                                                   384 
375         inst->alg.setkey = crypto_cts_setkey;     385         inst->alg.setkey = crypto_cts_setkey;
376         inst->alg.encrypt = crypto_cts_encrypt    386         inst->alg.encrypt = crypto_cts_encrypt;
377         inst->alg.decrypt = crypto_cts_decrypt    387         inst->alg.decrypt = crypto_cts_decrypt;
378                                                   388 
379         inst->free = crypto_cts_free;             389         inst->free = crypto_cts_free;
380                                                   390 
381         err = skcipher_register_instance(tmpl,    391         err = skcipher_register_instance(tmpl, inst);
382         if (err) {                             !! 392         if (err)
383 err_free_inst:                                 !! 393                 goto err_drop_spawn;
384                 crypto_cts_free(inst);         !! 394 
385         }                                      !! 395 out:
386         return err;                               396         return err;
                                                   >> 397 
                                                   >> 398 err_drop_spawn:
                                                   >> 399         crypto_drop_skcipher(spawn);
                                                   >> 400 err_free_inst:
                                                   >> 401         kfree(inst);
                                                   >> 402         goto out;
387 }                                                 403 }
388                                                   404 
389 static struct crypto_template crypto_cts_tmpl     405 static struct crypto_template crypto_cts_tmpl = {
390         .name = "cts",                            406         .name = "cts",
391         .create = crypto_cts_create,              407         .create = crypto_cts_create,
392         .module = THIS_MODULE,                    408         .module = THIS_MODULE,
393 };                                                409 };
394                                                   410 
395 static int __init crypto_cts_module_init(void)    411 static int __init crypto_cts_module_init(void)
396 {                                                 412 {
397         return crypto_register_template(&crypt    413         return crypto_register_template(&crypto_cts_tmpl);
398 }                                                 414 }
399                                                   415 
400 static void __exit crypto_cts_module_exit(void    416 static void __exit crypto_cts_module_exit(void)
401 {                                                 417 {
402         crypto_unregister_template(&crypto_cts    418         crypto_unregister_template(&crypto_cts_tmpl);
403 }                                                 419 }
404                                                   420 
405 subsys_initcall(crypto_cts_module_init);       !! 421 module_init(crypto_cts_module_init);
406 module_exit(crypto_cts_module_exit);              422 module_exit(crypto_cts_module_exit);
407                                                   423 
408 MODULE_LICENSE("Dual BSD/GPL");                   424 MODULE_LICENSE("Dual BSD/GPL");
409 MODULE_DESCRIPTION("CTS-CBC CipherText Stealin    425 MODULE_DESCRIPTION("CTS-CBC CipherText Stealing for CBC");
410 MODULE_ALIAS_CRYPTO("cts");                       426 MODULE_ALIAS_CRYPTO("cts");
411                                                   427 

~ [ 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