2626#include <crypto/internal/aead.h>
2727#include <crypto/scatterwalk.h>
2828#include <crypto/if_alg.h>
29- #include <crypto/skcipher.h>
3029#include <linux/init.h>
3130#include <linux/list.h>
3231#include <linux/kernel.h>
@@ -72,9 +71,8 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
7271 struct alg_sock * pask = alg_sk (psk );
7372 struct af_alg_ctx * ctx = ask -> private ;
7473 struct crypto_aead * tfm = pask -> private ;
75- unsigned int i , as = crypto_aead_authsize (tfm );
74+ unsigned int as = crypto_aead_authsize (tfm );
7675 struct af_alg_async_req * areq ;
77- struct af_alg_tsgl * tsgl , * tmp ;
7876 struct scatterlist * rsgl_src , * tsgl_src = NULL ;
7977 int err = 0 ;
8078 size_t used = 0 ; /* [in] TX bufs to be en/decrypted */
@@ -154,23 +152,24 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
154152 outlen -= less ;
155153 }
156154
155+ /*
156+ * Create a per request TX SGL for this request which tracks the
157+ * SG entries from the global TX SGL.
158+ */
157159 processed = used + ctx -> aead_assoclen ;
158- list_for_each_entry_safe (tsgl , tmp , & ctx -> tsgl_list , list ) {
159- for (i = 0 ; i < tsgl -> cur ; i ++ ) {
160- struct scatterlist * process_sg = tsgl -> sg + i ;
161-
162- if (!(process_sg -> length ) || !sg_page (process_sg ))
163- continue ;
164- tsgl_src = process_sg ;
165- break ;
166- }
167- if (tsgl_src )
168- break ;
169- }
170- if (processed && !tsgl_src ) {
171- err = - EFAULT ;
160+ areq -> tsgl_entries = af_alg_count_tsgl (sk , processed );
161+ if (!areq -> tsgl_entries )
162+ areq -> tsgl_entries = 1 ;
163+ areq -> tsgl = sock_kmalloc (sk , array_size (sizeof (* areq -> tsgl ),
164+ areq -> tsgl_entries ),
165+ GFP_KERNEL );
166+ if (!areq -> tsgl ) {
167+ err = - ENOMEM ;
172168 goto free ;
173169 }
170+ sg_init_table (areq -> tsgl , areq -> tsgl_entries );
171+ af_alg_pull_tsgl (sk , processed , areq -> tsgl );
172+ tsgl_src = areq -> tsgl ;
174173
175174 /*
176175 * Copy of AAD from source to destination
@@ -179,76 +178,15 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
179178 * when user space uses an in-place cipher operation, the kernel
180179 * will copy the data as it does not see whether such in-place operation
181180 * is initiated.
182- *
183- * To ensure efficiency, the following implementation ensure that the
184- * ciphers are invoked to perform a crypto operation in-place. This
185- * is achieved by memory management specified as follows.
186181 */
187182
188183 /* Use the RX SGL as source (and destination) for crypto op. */
189184 rsgl_src = areq -> first_rsgl .sgl .sgt .sgl ;
190185
191- if (ctx -> enc ) {
192- /*
193- * Encryption operation - The in-place cipher operation is
194- * achieved by the following operation:
195- *
196- * TX SGL: AAD || PT
197- * | |
198- * | copy |
199- * v v
200- * RX SGL: AAD || PT || Tag
201- */
202- memcpy_sglist (areq -> first_rsgl .sgl .sgt .sgl , tsgl_src ,
203- processed );
204- af_alg_pull_tsgl (sk , processed , NULL , 0 );
205- } else {
206- /*
207- * Decryption operation - To achieve an in-place cipher
208- * operation, the following SGL structure is used:
209- *
210- * TX SGL: AAD || CT || Tag
211- * | | ^
212- * | copy | | Create SGL link.
213- * v v |
214- * RX SGL: AAD || CT ----+
215- */
216-
217- /* Copy AAD || CT to RX SGL buffer for in-place operation. */
218- memcpy_sglist (areq -> first_rsgl .sgl .sgt .sgl , tsgl_src , outlen );
219-
220- /* Create TX SGL for tag and chain it to RX SGL. */
221- areq -> tsgl_entries = af_alg_count_tsgl (sk , processed ,
222- processed - as );
223- if (!areq -> tsgl_entries )
224- areq -> tsgl_entries = 1 ;
225- areq -> tsgl = sock_kmalloc (sk , array_size (sizeof (* areq -> tsgl ),
226- areq -> tsgl_entries ),
227- GFP_KERNEL );
228- if (!areq -> tsgl ) {
229- err = - ENOMEM ;
230- goto free ;
231- }
232- sg_init_table (areq -> tsgl , areq -> tsgl_entries );
233-
234- /* Release TX SGL, except for tag data and reassign tag data. */
235- af_alg_pull_tsgl (sk , processed , areq -> tsgl , processed - as );
236-
237- /* chain the areq TX SGL holding the tag with RX SGL */
238- if (usedpages ) {
239- /* RX SGL present */
240- struct af_alg_sgl * sgl_prev = & areq -> last_rsgl -> sgl ;
241- struct scatterlist * sg = sgl_prev -> sgt .sgl ;
242-
243- sg_unmark_end (sg + sgl_prev -> sgt .nents - 1 );
244- sg_chain (sg , sgl_prev -> sgt .nents + 1 , areq -> tsgl );
245- } else
246- /* no RX SGL present (e.g. authentication only) */
247- rsgl_src = areq -> tsgl ;
248- }
186+ memcpy_sglist (rsgl_src , tsgl_src , ctx -> aead_assoclen );
249187
250188 /* Initialize the crypto operation */
251- aead_request_set_crypt (& areq -> cra_u .aead_req , rsgl_src ,
189+ aead_request_set_crypt (& areq -> cra_u .aead_req , tsgl_src ,
252190 areq -> first_rsgl .sgl .sgt .sgl , used , ctx -> iv );
253191 aead_request_set_ad (& areq -> cra_u .aead_req , ctx -> aead_assoclen );
254192 aead_request_set_tfm (& areq -> cra_u .aead_req , tfm );
@@ -450,7 +388,7 @@ static void aead_sock_destruct(struct sock *sk)
450388 struct crypto_aead * tfm = pask -> private ;
451389 unsigned int ivlen = crypto_aead_ivsize (tfm );
452390
453- af_alg_pull_tsgl (sk , ctx -> used , NULL , 0 );
391+ af_alg_pull_tsgl (sk , ctx -> used , NULL );
454392 sock_kzfree_s (sk , ctx -> iv , ivlen );
455393 sock_kfree_s (sk , ctx , ctx -> len );
456394 af_alg_release_parent (sk );
0 commit comments