2626#include <crypto/internal/aead.h>
2727#include <crypto/scatterwalk.h>
2828#include <crypto/if_alg.h>
29- #include <crypto/skcipher.h>
3029#include <crypto/null.h>
3130#include <linux/init.h>
3231#include <linux/list.h>
@@ -96,9 +95,8 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
9695 struct aead_tfm * aeadc = pask -> private ;
9796 struct crypto_aead * tfm = aeadc -> aead ;
9897 struct crypto_sync_skcipher * null_tfm = aeadc -> null_tfm ;
99- unsigned int i , as = crypto_aead_authsize (tfm );
98+ unsigned int as = crypto_aead_authsize (tfm );
10099 struct af_alg_async_req * areq ;
101- struct af_alg_tsgl * tsgl , * tmp ;
102100 struct scatterlist * rsgl_src , * tsgl_src = NULL ;
103101 int err = 0 ;
104102 size_t used = 0 ; /* [in] TX bufs to be en/decrypted */
@@ -178,23 +176,24 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
178176 outlen -= less ;
179177 }
180178
179+ /*
180+ * Create a per request TX SGL for this request which tracks the
181+ * SG entries from the global TX SGL.
182+ */
181183 processed = used + ctx -> aead_assoclen ;
182- list_for_each_entry_safe (tsgl , tmp , & ctx -> tsgl_list , list ) {
183- for (i = 0 ; i < tsgl -> cur ; i ++ ) {
184- struct scatterlist * process_sg = tsgl -> sg + i ;
185-
186- if (!(process_sg -> length ) || !sg_page (process_sg ))
187- continue ;
188- tsgl_src = process_sg ;
189- break ;
190- }
191- if (tsgl_src )
192- break ;
193- }
194- if (processed && !tsgl_src ) {
195- err = - EFAULT ;
184+ areq -> tsgl_entries = af_alg_count_tsgl (sk , processed );
185+ if (!areq -> tsgl_entries )
186+ areq -> tsgl_entries = 1 ;
187+ areq -> tsgl = sock_kmalloc (sk , array_size (sizeof (* areq -> tsgl ),
188+ areq -> tsgl_entries ),
189+ GFP_KERNEL );
190+ if (!areq -> tsgl ) {
191+ err = - ENOMEM ;
196192 goto free ;
197193 }
194+ sg_init_table (areq -> tsgl , areq -> tsgl_entries );
195+ af_alg_pull_tsgl (sk , processed , areq -> tsgl );
196+ tsgl_src = areq -> tsgl ;
198197
199198 /*
200199 * Copy of AAD from source to destination
@@ -209,75 +208,16 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
209208 * is achieved by memory management specified as follows.
210209 */
211210
212- /* Use the RX SGL as source (and destination) for crypto op . */
211+ /* Use the RX SGL as destination; TX SGL as crypto source . */
213212 rsgl_src = areq -> first_rsgl .sgl .sg ;
214213
215- if (ctx -> enc ) {
216- /*
217- * Encryption operation - The in-place cipher operation is
218- * achieved by the following operation:
219- *
220- * TX SGL: AAD || PT
221- * | |
222- * | copy |
223- * v v
224- * RX SGL: AAD || PT || Tag
225- */
226- err = crypto_aead_copy_sgl (null_tfm , tsgl_src ,
227- areq -> first_rsgl .sgl .sg , processed );
228- if (err )
229- goto free ;
230- af_alg_pull_tsgl (sk , processed , NULL , 0 );
231- } else {
232- /*
233- * Decryption operation - To achieve an in-place cipher
234- * operation, the following SGL structure is used:
235- *
236- * TX SGL: AAD || CT || Tag
237- * | | ^
238- * | copy | | Create SGL link.
239- * v v |
240- * RX SGL: AAD || CT ----+
241- */
242-
243- /* Copy AAD || CT to RX SGL buffer for in-place operation. */
244- err = crypto_aead_copy_sgl (null_tfm , tsgl_src ,
245- areq -> first_rsgl .sgl .sg , outlen );
246- if (err )
247- goto free ;
248-
249- /* Create TX SGL for tag and chain it to RX SGL. */
250- areq -> tsgl_entries = af_alg_count_tsgl (sk , processed ,
251- processed - as );
252- if (!areq -> tsgl_entries )
253- areq -> tsgl_entries = 1 ;
254- areq -> tsgl = sock_kmalloc (sk , array_size (sizeof (* areq -> tsgl ),
255- areq -> tsgl_entries ),
256- GFP_KERNEL );
257- if (!areq -> tsgl ) {
258- err = - ENOMEM ;
259- goto free ;
260- }
261- sg_init_table (areq -> tsgl , areq -> tsgl_entries );
262-
263- /* Release TX SGL, except for tag data and reassign tag data. */
264- af_alg_pull_tsgl (sk , processed , areq -> tsgl , processed - as );
265-
266- /* chain the areq TX SGL holding the tag with RX SGL */
267- if (usedpages ) {
268- /* RX SGL present */
269- struct af_alg_sgl * sgl_prev = & areq -> last_rsgl -> sgl ;
270-
271- sg_unmark_end (sgl_prev -> sg + sgl_prev -> npages - 1 );
272- sg_chain (sgl_prev -> sg , sgl_prev -> npages + 1 ,
273- areq -> tsgl );
274- } else
275- /* no RX SGL present (e.g. authentication only) */
276- rsgl_src = areq -> tsgl ;
277- }
214+ err = crypto_aead_copy_sgl (null_tfm , tsgl_src , rsgl_src ,
215+ ctx -> aead_assoclen );
216+ if (err )
217+ goto free ;
278218
279219 /* Initialize the crypto operation */
280- aead_request_set_crypt (& areq -> cra_u .aead_req , rsgl_src ,
220+ aead_request_set_crypt (& areq -> cra_u .aead_req , tsgl_src ,
281221 areq -> first_rsgl .sgl .sg , used , ctx -> iv );
282222 aead_request_set_ad (& areq -> cra_u .aead_req , ctx -> aead_assoclen );
283223 aead_request_set_tfm (& areq -> cra_u .aead_req , tfm );
@@ -526,7 +466,7 @@ static void aead_sock_destruct(struct sock *sk)
526466 struct crypto_aead * tfm = aeadc -> aead ;
527467 unsigned int ivlen = crypto_aead_ivsize (tfm );
528468
529- af_alg_pull_tsgl (sk , ctx -> used , NULL , 0 );
469+ af_alg_pull_tsgl (sk , ctx -> used , NULL );
530470 sock_kzfree_s (sk , ctx -> iv , ivlen );
531471 sock_kfree_s (sk , ctx , ctx -> len );
532472 af_alg_release_parent (sk );
0 commit comments