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


  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 ||
                                                   >> 140             (err == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
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[bsize * 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 ||
                                                   >> 233             (err == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
231                 return;                           234                 return;
232                                                   235 
233 out:                                              236 out:
234         skcipher_request_complete(req, err);      237         skcipher_request_complete(req, err);
235 }                                                 238 }
236                                                   239 
237 static int crypto_cts_decrypt(struct skcipher_    240 static int crypto_cts_decrypt(struct skcipher_request *req)
238 {                                                 241 {
239         struct crypto_skcipher *tfm = crypto_s    242         struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
240         struct crypto_cts_reqctx *rctx = skcip    243         struct crypto_cts_reqctx *rctx = skcipher_request_ctx(req);
241         struct crypto_cts_ctx *ctx = crypto_sk    244         struct crypto_cts_ctx *ctx = crypto_skcipher_ctx(tfm);
242         struct skcipher_request *subreq = &rct    245         struct skcipher_request *subreq = &rctx->subreq;
243         int bsize = crypto_skcipher_blocksize(    246         int bsize = crypto_skcipher_blocksize(tfm);
244         unsigned int nbytes = req->cryptlen;      247         unsigned int nbytes = req->cryptlen;
                                                   >> 248         int cbc_blocks = (nbytes + bsize - 1) / bsize - 1;
245         unsigned int offset;                      249         unsigned int offset;
246         u8 *space;                                250         u8 *space;
247                                                   251 
248         skcipher_request_set_tfm(subreq, ctx->    252         skcipher_request_set_tfm(subreq, ctx->child);
249                                                   253 
250         if (nbytes < bsize)                    !! 254         if (cbc_blocks <= 0) {
251                 return -EINVAL;                << 
252                                                << 
253         if (nbytes == bsize) {                 << 
254                 skcipher_request_set_callback(    255                 skcipher_request_set_callback(subreq, req->base.flags,
255                                                   256                                               req->base.complete,
256                                                   257                                               req->base.data);
257                 skcipher_request_set_crypt(sub    258                 skcipher_request_set_crypt(subreq, req->src, req->dst, nbytes,
258                                            req    259                                            req->iv);
259                 return crypto_skcipher_decrypt    260                 return crypto_skcipher_decrypt(subreq);
260         }                                         261         }
261                                                   262 
262         skcipher_request_set_callback(subreq,     263         skcipher_request_set_callback(subreq, req->base.flags,
263                                       crypto_c    264                                       crypto_cts_decrypt_done, req);
264                                                   265 
265         space = crypto_cts_reqctx_space(req);     266         space = crypto_cts_reqctx_space(req);
266                                                   267 
267         offset = rounddown(nbytes - 1, bsize); !! 268         offset = cbc_blocks * bsize;
268         rctx->offset = offset;                    269         rctx->offset = offset;
269                                                   270 
270         if (offset <= bsize)                   !! 271         if (cbc_blocks <= 1)
271                 memcpy(space, req->iv, bsize);    272                 memcpy(space, req->iv, bsize);
272         else                                      273         else
273                 scatterwalk_map_and_copy(space    274                 scatterwalk_map_and_copy(space, req->src, offset - 2 * bsize,
274                                          bsize    275                                          bsize, 0);
275                                                   276 
276         skcipher_request_set_crypt(subreq, req    277         skcipher_request_set_crypt(subreq, req->src, req->dst,
277                                    offset, req    278                                    offset, req->iv);
278                                                   279 
279         return crypto_skcipher_decrypt(subreq)    280         return crypto_skcipher_decrypt(subreq) ?:
280                cts_cbc_decrypt(req);              281                cts_cbc_decrypt(req);
281 }                                                 282 }
282                                                   283 
283 static int crypto_cts_init_tfm(struct crypto_s    284 static int crypto_cts_init_tfm(struct crypto_skcipher *tfm)
284 {                                                 285 {
285         struct skcipher_instance *inst = skcip    286         struct skcipher_instance *inst = skcipher_alg_instance(tfm);
286         struct crypto_skcipher_spawn *spawn =     287         struct crypto_skcipher_spawn *spawn = skcipher_instance_ctx(inst);
287         struct crypto_cts_ctx *ctx = crypto_sk    288         struct crypto_cts_ctx *ctx = crypto_skcipher_ctx(tfm);
288         struct crypto_skcipher *cipher;           289         struct crypto_skcipher *cipher;
289         unsigned reqsize;                         290         unsigned reqsize;
290         unsigned bsize;                           291         unsigned bsize;
291         unsigned align;                           292         unsigned align;
292                                                   293 
293         cipher = crypto_spawn_skcipher(spawn);    294         cipher = crypto_spawn_skcipher(spawn);
294         if (IS_ERR(cipher))                       295         if (IS_ERR(cipher))
295                 return PTR_ERR(cipher);           296                 return PTR_ERR(cipher);
296                                                   297 
297         ctx->child = cipher;                      298         ctx->child = cipher;
298                                                   299 
299         align = crypto_skcipher_alignmask(tfm)    300         align = crypto_skcipher_alignmask(tfm);
300         bsize = crypto_skcipher_blocksize(ciph    301         bsize = crypto_skcipher_blocksize(cipher);
301         reqsize = ALIGN(sizeof(struct crypto_c    302         reqsize = ALIGN(sizeof(struct crypto_cts_reqctx) +
302                         crypto_skcipher_reqsiz    303                         crypto_skcipher_reqsize(cipher),
303                         crypto_tfm_ctx_alignme    304                         crypto_tfm_ctx_alignment()) +
304                   (align & ~(crypto_tfm_ctx_al    305                   (align & ~(crypto_tfm_ctx_alignment() - 1)) + bsize;
305                                                   306 
306         crypto_skcipher_set_reqsize(tfm, reqsi    307         crypto_skcipher_set_reqsize(tfm, reqsize);
307                                                   308 
308         return 0;                                 309         return 0;
309 }                                                 310 }
310                                                   311 
311 static void crypto_cts_exit_tfm(struct crypto_    312 static void crypto_cts_exit_tfm(struct crypto_skcipher *tfm)
312 {                                                 313 {
313         struct crypto_cts_ctx *ctx = crypto_sk    314         struct crypto_cts_ctx *ctx = crypto_skcipher_ctx(tfm);
314                                                   315 
315         crypto_free_skcipher(ctx->child);         316         crypto_free_skcipher(ctx->child);
316 }                                                 317 }
317                                                   318 
318 static void crypto_cts_free(struct skcipher_in    319 static void crypto_cts_free(struct skcipher_instance *inst)
319 {                                                 320 {
320         crypto_drop_skcipher(skcipher_instance    321         crypto_drop_skcipher(skcipher_instance_ctx(inst));
321         kfree(inst);                              322         kfree(inst);
322 }                                                 323 }
323                                                   324 
324 static int crypto_cts_create(struct crypto_tem    325 static int crypto_cts_create(struct crypto_template *tmpl, struct rtattr **tb)
325 {                                                 326 {
326         struct crypto_skcipher_spawn *spawn;      327         struct crypto_skcipher_spawn *spawn;
327         struct skcipher_alg_common *alg;       << 
328         struct skcipher_instance *inst;           328         struct skcipher_instance *inst;
329         u32 mask;                              !! 329         struct crypto_attr_type *algt;
                                                   >> 330         struct skcipher_alg *alg;
                                                   >> 331         const char *cipher_name;
330         int err;                                  332         int err;
331                                                   333 
332         err = crypto_check_attr_type(tb, CRYPT !! 334         algt = crypto_get_attr_type(tb);
333         if (err)                               !! 335         if (IS_ERR(algt))
334                 return err;                    !! 336                 return PTR_ERR(algt);
                                                   >> 337 
                                                   >> 338         if ((algt->type ^ CRYPTO_ALG_TYPE_SKCIPHER) & algt->mask)
                                                   >> 339                 return -EINVAL;
                                                   >> 340 
                                                   >> 341         cipher_name = crypto_attr_alg_name(tb[1]);
                                                   >> 342         if (IS_ERR(cipher_name))
                                                   >> 343                 return PTR_ERR(cipher_name);
335                                                   344 
336         inst = kzalloc(sizeof(*inst) + sizeof(    345         inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
337         if (!inst)                                346         if (!inst)
338                 return -ENOMEM;                   347                 return -ENOMEM;
339                                                   348 
340         spawn = skcipher_instance_ctx(inst);      349         spawn = skcipher_instance_ctx(inst);
341                                                   350 
342         err = crypto_grab_skcipher(spawn, skci !! 351         crypto_set_skcipher_spawn(spawn, skcipher_crypto_instance(inst));
343                                    crypto_attr !! 352         err = crypto_grab_skcipher(spawn, cipher_name, 0,
                                                   >> 353                                    crypto_requires_sync(algt->type,
                                                   >> 354                                                         algt->mask));
344         if (err)                                  355         if (err)
345                 goto err_free_inst;               356                 goto err_free_inst;
346                                                   357 
347         alg = crypto_spawn_skcipher_alg_common !! 358         alg = crypto_spawn_skcipher_alg(spawn);
348                                                   359 
349         err = -EINVAL;                            360         err = -EINVAL;
350         if (alg->ivsize != alg->base.cra_block !! 361         if (crypto_skcipher_alg_ivsize(alg) != alg->base.cra_blocksize)
351                 goto err_free_inst;            !! 362                 goto err_drop_spawn;
352                                                   363 
353         if (strncmp(alg->base.cra_name, "cbc("    364         if (strncmp(alg->base.cra_name, "cbc(", 4))
354                 goto err_free_inst;            !! 365                 goto err_drop_spawn;
355                                                   366 
356         err = crypto_inst_setname(skcipher_cry    367         err = crypto_inst_setname(skcipher_crypto_instance(inst), "cts",
357                                   &alg->base);    368                                   &alg->base);
358         if (err)                                  369         if (err)
359                 goto err_free_inst;            !! 370                 goto err_drop_spawn;
360                                                   371 
                                                   >> 372         inst->alg.base.cra_flags = alg->base.cra_flags & CRYPTO_ALG_ASYNC;
361         inst->alg.base.cra_priority = alg->bas    373         inst->alg.base.cra_priority = alg->base.cra_priority;
362         inst->alg.base.cra_blocksize = alg->ba    374         inst->alg.base.cra_blocksize = alg->base.cra_blocksize;
363         inst->alg.base.cra_alignmask = alg->ba    375         inst->alg.base.cra_alignmask = alg->base.cra_alignmask;
364                                                   376 
365         inst->alg.ivsize = alg->base.cra_block    377         inst->alg.ivsize = alg->base.cra_blocksize;
366         inst->alg.chunksize = alg->chunksize;  !! 378         inst->alg.chunksize = crypto_skcipher_alg_chunksize(alg);
367         inst->alg.min_keysize = alg->min_keysi !! 379         inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(alg);
368         inst->alg.max_keysize = alg->max_keysi !! 380         inst->alg.max_keysize = crypto_skcipher_alg_max_keysize(alg);
369                                                   381 
370         inst->alg.base.cra_ctxsize = sizeof(st    382         inst->alg.base.cra_ctxsize = sizeof(struct crypto_cts_ctx);
371                                                   383 
372         inst->alg.init = crypto_cts_init_tfm;     384         inst->alg.init = crypto_cts_init_tfm;
373         inst->alg.exit = crypto_cts_exit_tfm;     385         inst->alg.exit = crypto_cts_exit_tfm;
374                                                   386 
375         inst->alg.setkey = crypto_cts_setkey;     387         inst->alg.setkey = crypto_cts_setkey;
376         inst->alg.encrypt = crypto_cts_encrypt    388         inst->alg.encrypt = crypto_cts_encrypt;
377         inst->alg.decrypt = crypto_cts_decrypt    389         inst->alg.decrypt = crypto_cts_decrypt;
378                                                   390 
379         inst->free = crypto_cts_free;             391         inst->free = crypto_cts_free;
380                                                   392 
381         err = skcipher_register_instance(tmpl,    393         err = skcipher_register_instance(tmpl, inst);
382         if (err) {                             !! 394         if (err)
383 err_free_inst:                                 !! 395                 goto err_drop_spawn;
384                 crypto_cts_free(inst);         !! 396 
385         }                                      !! 397 out:
386         return err;                               398         return err;
                                                   >> 399 
                                                   >> 400 err_drop_spawn:
                                                   >> 401         crypto_drop_skcipher(spawn);
                                                   >> 402 err_free_inst:
                                                   >> 403         kfree(inst);
                                                   >> 404         goto out;
387 }                                                 405 }
388                                                   406 
389 static struct crypto_template crypto_cts_tmpl     407 static struct crypto_template crypto_cts_tmpl = {
390         .name = "cts",                            408         .name = "cts",
391         .create = crypto_cts_create,              409         .create = crypto_cts_create,
392         .module = THIS_MODULE,                    410         .module = THIS_MODULE,
393 };                                                411 };
394                                                   412 
395 static int __init crypto_cts_module_init(void)    413 static int __init crypto_cts_module_init(void)
396 {                                                 414 {
397         return crypto_register_template(&crypt    415         return crypto_register_template(&crypto_cts_tmpl);
398 }                                                 416 }
399                                                   417 
400 static void __exit crypto_cts_module_exit(void    418 static void __exit crypto_cts_module_exit(void)
401 {                                                 419 {
402         crypto_unregister_template(&crypto_cts    420         crypto_unregister_template(&crypto_cts_tmpl);
403 }                                                 421 }
404                                                   422 
405 subsys_initcall(crypto_cts_module_init);       !! 423 module_init(crypto_cts_module_init);
406 module_exit(crypto_cts_module_exit);              424 module_exit(crypto_cts_module_exit);
407                                                   425 
408 MODULE_LICENSE("Dual BSD/GPL");                   426 MODULE_LICENSE("Dual BSD/GPL");
409 MODULE_DESCRIPTION("CTS-CBC CipherText Stealin    427 MODULE_DESCRIPTION("CTS-CBC CipherText Stealing for CBC");
410 MODULE_ALIAS_CRYPTO("cts");                       428 MODULE_ALIAS_CRYPTO("cts");
411                                                   429 

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