~ [ 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-5.19.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                                                    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         return crypto_skcipher_setkey(child, key, keylen);
 86 }                                                  86 }
 87                                                    87 
 88 static void cts_cbc_crypt_done(void *data, int !!  88 static void cts_cbc_crypt_done(struct crypto_async_request *areq, int err)
 89 {                                                  89 {
 90         struct skcipher_request *req = data;   !!  90         struct skcipher_request *req = areq->data;
 91                                                    91 
 92         if (err == -EINPROGRESS)                   92         if (err == -EINPROGRESS)
 93                 return;                            93                 return;
 94                                                    94 
 95         skcipher_request_complete(req, err);       95         skcipher_request_complete(req, err);
 96 }                                                  96 }
 97                                                    97 
 98 static int cts_cbc_encrypt(struct skcipher_req     98 static int cts_cbc_encrypt(struct skcipher_request *req)
 99 {                                                  99 {
100         struct crypto_cts_reqctx *rctx = skcip    100         struct crypto_cts_reqctx *rctx = skcipher_request_ctx(req);
101         struct crypto_skcipher *tfm = crypto_s    101         struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
102         struct skcipher_request *subreq = &rct    102         struct skcipher_request *subreq = &rctx->subreq;
103         int bsize = crypto_skcipher_blocksize(    103         int bsize = crypto_skcipher_blocksize(tfm);
104         u8 d[MAX_CIPHER_BLOCKSIZE * 2] __align    104         u8 d[MAX_CIPHER_BLOCKSIZE * 2] __aligned(__alignof__(u32));
105         struct scatterlist *sg;                   105         struct scatterlist *sg;
106         unsigned int offset;                      106         unsigned int offset;
107         int lastn;                                107         int lastn;
108                                                   108 
109         offset = rctx->offset;                    109         offset = rctx->offset;
110         lastn = req->cryptlen - offset;           110         lastn = req->cryptlen - offset;
111                                                   111 
112         sg = scatterwalk_ffwd(rctx->sg, req->d    112         sg = scatterwalk_ffwd(rctx->sg, req->dst, offset - bsize);
113         scatterwalk_map_and_copy(d + bsize, sg    113         scatterwalk_map_and_copy(d + bsize, sg, 0, bsize, 0);
114                                                   114 
115         memset(d, 0, bsize);                      115         memset(d, 0, bsize);
116         scatterwalk_map_and_copy(d, req->src,     116         scatterwalk_map_and_copy(d, req->src, offset, lastn, 0);
117                                                   117 
118         scatterwalk_map_and_copy(d, sg, 0, bsi    118         scatterwalk_map_and_copy(d, sg, 0, bsize + lastn, 1);
119         memzero_explicit(d, sizeof(d));           119         memzero_explicit(d, sizeof(d));
120                                                   120 
121         skcipher_request_set_callback(subreq,     121         skcipher_request_set_callback(subreq, req->base.flags &
122                                                   122                                               CRYPTO_TFM_REQ_MAY_BACKLOG,
123                                       cts_cbc_    123                                       cts_cbc_crypt_done, req);
124         skcipher_request_set_crypt(subreq, sg,    124         skcipher_request_set_crypt(subreq, sg, sg, bsize, req->iv);
125         return crypto_skcipher_encrypt(subreq)    125         return crypto_skcipher_encrypt(subreq);
126 }                                                 126 }
127                                                   127 
128 static void crypto_cts_encrypt_done(void *data !! 128 static void crypto_cts_encrypt_done(struct crypto_async_request *areq, int err)
129 {                                                 129 {
130         struct skcipher_request *req = data;   !! 130         struct skcipher_request *req = areq->data;
131                                                   131 
132         if (err)                                  132         if (err)
133                 goto out;                         133                 goto out;
134                                                   134 
135         err = cts_cbc_encrypt(req);               135         err = cts_cbc_encrypt(req);
136         if (err == -EINPROGRESS || err == -EBU    136         if (err == -EINPROGRESS || err == -EBUSY)
137                 return;                           137                 return;
138                                                   138 
139 out:                                              139 out:
140         skcipher_request_complete(req, err);      140         skcipher_request_complete(req, err);
141 }                                                 141 }
142                                                   142 
143 static int crypto_cts_encrypt(struct skcipher_    143 static int crypto_cts_encrypt(struct skcipher_request *req)
144 {                                                 144 {
145         struct crypto_skcipher *tfm = crypto_s    145         struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
146         struct crypto_cts_reqctx *rctx = skcip    146         struct crypto_cts_reqctx *rctx = skcipher_request_ctx(req);
147         struct crypto_cts_ctx *ctx = crypto_sk    147         struct crypto_cts_ctx *ctx = crypto_skcipher_ctx(tfm);
148         struct skcipher_request *subreq = &rct    148         struct skcipher_request *subreq = &rctx->subreq;
149         int bsize = crypto_skcipher_blocksize(    149         int bsize = crypto_skcipher_blocksize(tfm);
150         unsigned int nbytes = req->cryptlen;      150         unsigned int nbytes = req->cryptlen;
151         unsigned int offset;                      151         unsigned int offset;
152                                                   152 
153         skcipher_request_set_tfm(subreq, ctx->    153         skcipher_request_set_tfm(subreq, ctx->child);
154                                                   154 
155         if (nbytes < bsize)                       155         if (nbytes < bsize)
156                 return -EINVAL;                   156                 return -EINVAL;
157                                                   157 
158         if (nbytes == bsize) {                    158         if (nbytes == bsize) {
159                 skcipher_request_set_callback(    159                 skcipher_request_set_callback(subreq, req->base.flags,
160                                                   160                                               req->base.complete,
161                                                   161                                               req->base.data);
162                 skcipher_request_set_crypt(sub    162                 skcipher_request_set_crypt(subreq, req->src, req->dst, nbytes,
163                                            req    163                                            req->iv);
164                 return crypto_skcipher_encrypt    164                 return crypto_skcipher_encrypt(subreq);
165         }                                         165         }
166                                                   166 
167         offset = rounddown(nbytes - 1, bsize);    167         offset = rounddown(nbytes - 1, bsize);
168         rctx->offset = offset;                    168         rctx->offset = offset;
169                                                   169 
170         skcipher_request_set_callback(subreq,     170         skcipher_request_set_callback(subreq, req->base.flags,
171                                       crypto_c    171                                       crypto_cts_encrypt_done, req);
172         skcipher_request_set_crypt(subreq, req    172         skcipher_request_set_crypt(subreq, req->src, req->dst,
173                                    offset, req    173                                    offset, req->iv);
174                                                   174 
175         return crypto_skcipher_encrypt(subreq)    175         return crypto_skcipher_encrypt(subreq) ?:
176                cts_cbc_encrypt(req);              176                cts_cbc_encrypt(req);
177 }                                                 177 }
178                                                   178 
179 static int cts_cbc_decrypt(struct skcipher_req    179 static int cts_cbc_decrypt(struct skcipher_request *req)
180 {                                                 180 {
181         struct crypto_cts_reqctx *rctx = skcip    181         struct crypto_cts_reqctx *rctx = skcipher_request_ctx(req);
182         struct crypto_skcipher *tfm = crypto_s    182         struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
183         struct skcipher_request *subreq = &rct    183         struct skcipher_request *subreq = &rctx->subreq;
184         int bsize = crypto_skcipher_blocksize(    184         int bsize = crypto_skcipher_blocksize(tfm);
185         u8 d[MAX_CIPHER_BLOCKSIZE * 2] __align    185         u8 d[MAX_CIPHER_BLOCKSIZE * 2] __aligned(__alignof__(u32));
186         struct scatterlist *sg;                   186         struct scatterlist *sg;
187         unsigned int offset;                      187         unsigned int offset;
188         u8 *space;                                188         u8 *space;
189         int lastn;                                189         int lastn;
190                                                   190 
191         offset = rctx->offset;                    191         offset = rctx->offset;
192         lastn = req->cryptlen - offset;           192         lastn = req->cryptlen - offset;
193                                                   193 
194         sg = scatterwalk_ffwd(rctx->sg, req->d    194         sg = scatterwalk_ffwd(rctx->sg, req->dst, offset - bsize);
195                                                   195 
196         /* 1. Decrypt Cn-1 (s) to create Dn */    196         /* 1. Decrypt Cn-1 (s) to create Dn */
197         scatterwalk_map_and_copy(d + bsize, sg    197         scatterwalk_map_and_copy(d + bsize, sg, 0, bsize, 0);
198         space = crypto_cts_reqctx_space(req);     198         space = crypto_cts_reqctx_space(req);
199         crypto_xor(d + bsize, space, bsize);      199         crypto_xor(d + bsize, space, bsize);
200         /* 2. Pad Cn with zeros at the end to     200         /* 2. Pad Cn with zeros at the end to create C of length BB */
201         memset(d, 0, bsize);                      201         memset(d, 0, bsize);
202         scatterwalk_map_and_copy(d, req->src,     202         scatterwalk_map_and_copy(d, req->src, offset, lastn, 0);
203         /* 3. Exclusive-or Dn with C to create    203         /* 3. Exclusive-or Dn with C to create Xn */
204         /* 4. Select the first Ln bytes of Xn     204         /* 4. Select the first Ln bytes of Xn to create Pn */
205         crypto_xor(d + bsize, d, lastn);          205         crypto_xor(d + bsize, d, lastn);
206                                                   206 
207         /* 5. Append the tail (BB - Ln) bytes     207         /* 5. Append the tail (BB - Ln) bytes of Xn to Cn to create En */
208         memcpy(d + lastn, d + bsize + lastn, b    208         memcpy(d + lastn, d + bsize + lastn, bsize - lastn);
209         /* 6. Decrypt En to create Pn-1 */        209         /* 6. Decrypt En to create Pn-1 */
210                                                   210 
211         scatterwalk_map_and_copy(d, sg, 0, bsi    211         scatterwalk_map_and_copy(d, sg, 0, bsize + lastn, 1);
212         memzero_explicit(d, sizeof(d));           212         memzero_explicit(d, sizeof(d));
213                                                   213 
214         skcipher_request_set_callback(subreq,     214         skcipher_request_set_callback(subreq, req->base.flags &
215                                                   215                                               CRYPTO_TFM_REQ_MAY_BACKLOG,
216                                       cts_cbc_    216                                       cts_cbc_crypt_done, req);
217                                                   217 
218         skcipher_request_set_crypt(subreq, sg,    218         skcipher_request_set_crypt(subreq, sg, sg, bsize, space);
219         return crypto_skcipher_decrypt(subreq)    219         return crypto_skcipher_decrypt(subreq);
220 }                                                 220 }
221                                                   221 
222 static void crypto_cts_decrypt_done(void *data !! 222 static void crypto_cts_decrypt_done(struct crypto_async_request *areq, int err)
223 {                                                 223 {
224         struct skcipher_request *req = data;   !! 224         struct skcipher_request *req = areq->data;
225                                                   225 
226         if (err)                                  226         if (err)
227                 goto out;                         227                 goto out;
228                                                   228 
229         err = cts_cbc_decrypt(req);               229         err = cts_cbc_decrypt(req);
230         if (err == -EINPROGRESS || err == -EBU    230         if (err == -EINPROGRESS || err == -EBUSY)
231                 return;                           231                 return;
232                                                   232 
233 out:                                              233 out:
234         skcipher_request_complete(req, err);      234         skcipher_request_complete(req, err);
235 }                                                 235 }
236                                                   236 
237 static int crypto_cts_decrypt(struct skcipher_    237 static int crypto_cts_decrypt(struct skcipher_request *req)
238 {                                                 238 {
239         struct crypto_skcipher *tfm = crypto_s    239         struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
240         struct crypto_cts_reqctx *rctx = skcip    240         struct crypto_cts_reqctx *rctx = skcipher_request_ctx(req);
241         struct crypto_cts_ctx *ctx = crypto_sk    241         struct crypto_cts_ctx *ctx = crypto_skcipher_ctx(tfm);
242         struct skcipher_request *subreq = &rct    242         struct skcipher_request *subreq = &rctx->subreq;
243         int bsize = crypto_skcipher_blocksize(    243         int bsize = crypto_skcipher_blocksize(tfm);
244         unsigned int nbytes = req->cryptlen;      244         unsigned int nbytes = req->cryptlen;
245         unsigned int offset;                      245         unsigned int offset;
246         u8 *space;                                246         u8 *space;
247                                                   247 
248         skcipher_request_set_tfm(subreq, ctx->    248         skcipher_request_set_tfm(subreq, ctx->child);
249                                                   249 
250         if (nbytes < bsize)                       250         if (nbytes < bsize)
251                 return -EINVAL;                   251                 return -EINVAL;
252                                                   252 
253         if (nbytes == bsize) {                    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 = rounddown(nbytes - 1, bsize);
268         rctx->offset = offset;                    268         rctx->offset = offset;
269                                                   269 
270         if (offset <= bsize)                      270         if (offset <= bsize)
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;
                                                   >> 328         struct skcipher_alg *alg;
329         u32 mask;                                 329         u32 mask;
330         int err;                                  330         int err;
331                                                   331 
332         err = crypto_check_attr_type(tb, CRYPT    332         err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SKCIPHER, &mask);
333         if (err)                                  333         if (err)
334                 return err;                       334                 return err;
335                                                   335 
336         inst = kzalloc(sizeof(*inst) + sizeof(    336         inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
337         if (!inst)                                337         if (!inst)
338                 return -ENOMEM;                   338                 return -ENOMEM;
339                                                   339 
340         spawn = skcipher_instance_ctx(inst);      340         spawn = skcipher_instance_ctx(inst);
341                                                   341 
342         err = crypto_grab_skcipher(spawn, skci    342         err = crypto_grab_skcipher(spawn, skcipher_crypto_instance(inst),
343                                    crypto_attr    343                                    crypto_attr_alg_name(tb[1]), 0, mask);
344         if (err)                                  344         if (err)
345                 goto err_free_inst;               345                 goto err_free_inst;
346                                                   346 
347         alg = crypto_spawn_skcipher_alg_common !! 347         alg = crypto_spawn_skcipher_alg(spawn);
348                                                   348 
349         err = -EINVAL;                            349         err = -EINVAL;
350         if (alg->ivsize != alg->base.cra_block !! 350         if (crypto_skcipher_alg_ivsize(alg) != alg->base.cra_blocksize)
351                 goto err_free_inst;               351                 goto err_free_inst;
352                                                   352 
353         if (strncmp(alg->base.cra_name, "cbc("    353         if (strncmp(alg->base.cra_name, "cbc(", 4))
354                 goto err_free_inst;               354                 goto err_free_inst;
355                                                   355 
356         err = crypto_inst_setname(skcipher_cry    356         err = crypto_inst_setname(skcipher_crypto_instance(inst), "cts",
357                                   &alg->base);    357                                   &alg->base);
358         if (err)                                  358         if (err)
359                 goto err_free_inst;               359                 goto err_free_inst;
360                                                   360 
361         inst->alg.base.cra_priority = alg->bas    361         inst->alg.base.cra_priority = alg->base.cra_priority;
362         inst->alg.base.cra_blocksize = alg->ba    362         inst->alg.base.cra_blocksize = alg->base.cra_blocksize;
363         inst->alg.base.cra_alignmask = alg->ba    363         inst->alg.base.cra_alignmask = alg->base.cra_alignmask;
364                                                   364 
365         inst->alg.ivsize = alg->base.cra_block    365         inst->alg.ivsize = alg->base.cra_blocksize;
366         inst->alg.chunksize = alg->chunksize;  !! 366         inst->alg.chunksize = crypto_skcipher_alg_chunksize(alg);
367         inst->alg.min_keysize = alg->min_keysi !! 367         inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(alg);
368         inst->alg.max_keysize = alg->max_keysi !! 368         inst->alg.max_keysize = crypto_skcipher_alg_max_keysize(alg);
369                                                   369 
370         inst->alg.base.cra_ctxsize = sizeof(st    370         inst->alg.base.cra_ctxsize = sizeof(struct crypto_cts_ctx);
371                                                   371 
372         inst->alg.init = crypto_cts_init_tfm;     372         inst->alg.init = crypto_cts_init_tfm;
373         inst->alg.exit = crypto_cts_exit_tfm;     373         inst->alg.exit = crypto_cts_exit_tfm;
374                                                   374 
375         inst->alg.setkey = crypto_cts_setkey;     375         inst->alg.setkey = crypto_cts_setkey;
376         inst->alg.encrypt = crypto_cts_encrypt    376         inst->alg.encrypt = crypto_cts_encrypt;
377         inst->alg.decrypt = crypto_cts_decrypt    377         inst->alg.decrypt = crypto_cts_decrypt;
378                                                   378 
379         inst->free = crypto_cts_free;             379         inst->free = crypto_cts_free;
380                                                   380 
381         err = skcipher_register_instance(tmpl,    381         err = skcipher_register_instance(tmpl, inst);
382         if (err) {                                382         if (err) {
383 err_free_inst:                                    383 err_free_inst:
384                 crypto_cts_free(inst);            384                 crypto_cts_free(inst);
385         }                                         385         }
386         return err;                               386         return err;
387 }                                                 387 }
388                                                   388 
389 static struct crypto_template crypto_cts_tmpl     389 static struct crypto_template crypto_cts_tmpl = {
390         .name = "cts",                            390         .name = "cts",
391         .create = crypto_cts_create,              391         .create = crypto_cts_create,
392         .module = THIS_MODULE,                    392         .module = THIS_MODULE,
393 };                                                393 };
394                                                   394 
395 static int __init crypto_cts_module_init(void)    395 static int __init crypto_cts_module_init(void)
396 {                                                 396 {
397         return crypto_register_template(&crypt    397         return crypto_register_template(&crypto_cts_tmpl);
398 }                                                 398 }
399                                                   399 
400 static void __exit crypto_cts_module_exit(void    400 static void __exit crypto_cts_module_exit(void)
401 {                                                 401 {
402         crypto_unregister_template(&crypto_cts    402         crypto_unregister_template(&crypto_cts_tmpl);
403 }                                                 403 }
404                                                   404 
405 subsys_initcall(crypto_cts_module_init);          405 subsys_initcall(crypto_cts_module_init);
406 module_exit(crypto_cts_module_exit);              406 module_exit(crypto_cts_module_exit);
407                                                   407 
408 MODULE_LICENSE("Dual BSD/GPL");                   408 MODULE_LICENSE("Dual BSD/GPL");
409 MODULE_DESCRIPTION("CTS-CBC CipherText Stealin    409 MODULE_DESCRIPTION("CTS-CBC CipherText Stealing for CBC");
410 MODULE_ALIAS_CRYPTO("cts");                       410 MODULE_ALIAS_CRYPTO("cts");
411                                                   411 

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