summaryrefslogtreecommitdiffstats
path: root/crypto/af_alg.c
diff options
context:
space:
mode:
authorStephan Mueller <smueller@chronox.de>2017-08-02 01:56:19 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2017-08-09 08:18:32 -0400
commit2d97591ef43d0587be22ad1b0d758d6df4999a0b (patch)
treee43adcbf67987557e3d1955f3496666b9799a486 /crypto/af_alg.c
parenta92f7af3854ce6b80a4cd7e3df6148663f15671b (diff)
crypto: af_alg - consolidation of duplicate code
Consolidate following data structures: skcipher_async_req, aead_async_req -> af_alg_async_req skcipher_rsgl, aead_rsql -> af_alg_rsgl skcipher_tsgl, aead_tsql -> af_alg_tsgl skcipher_ctx, aead_ctx -> af_alg_ctx Consolidate following functions: skcipher_sndbuf, aead_sndbuf -> af_alg_sndbuf skcipher_writable, aead_writable -> af_alg_writable skcipher_rcvbuf, aead_rcvbuf -> af_alg_rcvbuf skcipher_readable, aead_readable -> af_alg_readable aead_alloc_tsgl, skcipher_alloc_tsgl -> af_alg_alloc_tsgl aead_count_tsgl, skcipher_count_tsgl -> af_alg_count_tsgl aead_pull_tsgl, skcipher_pull_tsgl -> af_alg_pull_tsgl aead_free_areq_sgls, skcipher_free_areq_sgls -> af_alg_free_areq_sgls aead_wait_for_wmem, skcipher_wait_for_wmem -> af_alg_wait_for_wmem aead_wmem_wakeup, skcipher_wmem_wakeup -> af_alg_wmem_wakeup aead_wait_for_data, skcipher_wait_for_data -> af_alg_wait_for_data aead_data_wakeup, skcipher_data_wakeup -> af_alg_data_wakeup aead_sendmsg, skcipher_sendmsg -> af_alg_sendmsg aead_sendpage, skcipher_sendpage -> af_alg_sendpage aead_async_cb, skcipher_async_cb -> af_alg_async_cb aead_poll, skcipher_poll -> af_alg_poll Split out the following common code from recvmsg: af_alg_alloc_areq: allocation of the request data structure for the cipher operation af_alg_get_rsgl: creation of the RX SGL anchored in the request data structure The following changes to the implementation without affecting the functionality have been applied to synchronize slightly different code bases in algif_skcipher and algif_aead: The wakeup in af_alg_wait_for_data is triggered when either more data is received or the indicator that more data is to be expected is released. The first is triggered by user space, the second is triggered by the kernel upon finishing the processing of data (i.e. the kernel is ready for more). af_alg_sendmsg uses size_t in min_t calculation for obtaining len. Return code determination is consistent with algif_skcipher. The scope of the variable i is reduced to match algif_aead. The type of the variable i is switched from int to unsigned int to match algif_aead. af_alg_sendpage does not contain the superfluous err = 0 from aead_sendpage. af_alg_async_cb requires to store the number of output bytes in areq->outlen before the AIO callback is triggered. The POLLIN / POLLRDNORM is now set when either not more data is given or the kernel is supplied with data. This is consistent to the wakeup from sleep when the kernel waits for data. The request data structure is extended by the field last_rsgl which points to the last RX SGL list entry. This shall help recvmsg implementation to chain the RX SGL to other SG(L)s if needed. It is currently used by algif_aead which chains the tag SGL to the RX SGL during decryption. Signed-off-by: Stephan Mueller <smueller@chronox.de> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/af_alg.c')
-rw-r--r--crypto/af_alg.c693
1 files changed, 693 insertions, 0 deletions
diff --git a/crypto/af_alg.c b/crypto/af_alg.c
index 92a3d540d920..d6936c0e08d9 100644
--- a/crypto/af_alg.c
+++ b/crypto/af_alg.c
@@ -21,6 +21,7 @@
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/net.h> 22#include <linux/net.h>
23#include <linux/rwsem.h> 23#include <linux/rwsem.h>
24#include <linux/sched/signal.h>
24#include <linux/security.h> 25#include <linux/security.h>
25 26
26struct alg_type_list { 27struct alg_type_list {
@@ -507,6 +508,698 @@ void af_alg_complete(struct crypto_async_request *req, int err)
507} 508}
508EXPORT_SYMBOL_GPL(af_alg_complete); 509EXPORT_SYMBOL_GPL(af_alg_complete);
509 510
511/**
512 * af_alg_alloc_tsgl - allocate the TX SGL
513 *
514 * @sk socket of connection to user space
515 * @return: 0 upon success, < 0 upon error
516 */
517int af_alg_alloc_tsgl(struct sock *sk)
518{
519 struct alg_sock *ask = alg_sk(sk);
520 struct af_alg_ctx *ctx = ask->private;
521 struct af_alg_tsgl *sgl;
522 struct scatterlist *sg = NULL;
523
524 sgl = list_entry(ctx->tsgl_list.prev, struct af_alg_tsgl, list);
525 if (!list_empty(&ctx->tsgl_list))
526 sg = sgl->sg;
527
528 if (!sg || sgl->cur >= MAX_SGL_ENTS) {
529 sgl = sock_kmalloc(sk, sizeof(*sgl) +
530 sizeof(sgl->sg[0]) * (MAX_SGL_ENTS + 1),
531 GFP_KERNEL);
532 if (!sgl)
533 return -ENOMEM;
534
535 sg_init_table(sgl->sg, MAX_SGL_ENTS + 1);
536 sgl->cur = 0;
537
538 if (sg)
539 sg_chain(sg, MAX_SGL_ENTS + 1, sgl->sg);
540
541 list_add_tail(&sgl->list, &ctx->tsgl_list);
542 }
543
544 return 0;
545}
546EXPORT_SYMBOL_GPL(af_alg_alloc_tsgl);
547
548/**
549 * aead_count_tsgl - Count number of TX SG entries
550 *
551 * The counting starts from the beginning of the SGL to @bytes. If
552 * an offset is provided, the counting of the SG entries starts at the offset.
553 *
554 * @sk socket of connection to user space
555 * @bytes Count the number of SG entries holding given number of bytes.
556 * @offset Start the counting of SG entries from the given offset.
557 * @return Number of TX SG entries found given the constraints
558 */
559unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes, size_t offset)
560{
561 struct alg_sock *ask = alg_sk(sk);
562 struct af_alg_ctx *ctx = ask->private;
563 struct af_alg_tsgl *sgl, *tmp;
564 unsigned int i;
565 unsigned int sgl_count = 0;
566
567 if (!bytes)
568 return 0;
569
570 list_for_each_entry_safe(sgl, tmp, &ctx->tsgl_list, list) {
571 struct scatterlist *sg = sgl->sg;
572
573 for (i = 0; i < sgl->cur; i++) {
574 size_t bytes_count;
575
576 /* Skip offset */
577 if (offset >= sg[i].length) {
578 offset -= sg[i].length;
579 bytes -= sg[i].length;
580 continue;
581 }
582
583 bytes_count = sg[i].length - offset;
584
585 offset = 0;
586 sgl_count++;
587
588 /* If we have seen requested number of bytes, stop */
589 if (bytes_count >= bytes)
590 return sgl_count;
591
592 bytes -= bytes_count;
593 }
594 }
595
596 return sgl_count;
597}
598EXPORT_SYMBOL_GPL(af_alg_count_tsgl);
599
600/**
601 * aead_pull_tsgl - Release the specified buffers from TX SGL
602 *
603 * If @dst is non-null, reassign the pages to dst. The caller must release
604 * the pages. If @dst_offset is given only reassign the pages to @dst starting
605 * at the @dst_offset (byte). The caller must ensure that @dst is large
606 * enough (e.g. by using af_alg_count_tsgl with the same offset).
607 *
608 * @sk socket of connection to user space
609 * @used Number of bytes to pull from TX SGL
610 * @dst If non-NULL, buffer is reassigned to dst SGL instead of releasing. The
611 * caller must release the buffers in dst.
612 * @dst_offset Reassign the TX SGL from given offset. All buffers before
613 * reaching the offset is released.
614 */
615void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst,
616 size_t dst_offset)
617{
618 struct alg_sock *ask = alg_sk(sk);
619 struct af_alg_ctx *ctx = ask->private;
620 struct af_alg_tsgl *sgl;
621 struct scatterlist *sg;
622 unsigned int i, j;
623
624 while (!list_empty(&ctx->tsgl_list)) {
625 sgl = list_first_entry(&ctx->tsgl_list, struct af_alg_tsgl,
626 list);
627 sg = sgl->sg;
628
629 for (i = 0, j = 0; i < sgl->cur; i++) {
630 size_t plen = min_t(size_t, used, sg[i].length);
631 struct page *page = sg_page(sg + i);
632
633 if (!page)
634 continue;
635
636 /*
637 * Assumption: caller created af_alg_count_tsgl(len)
638 * SG entries in dst.
639 */
640 if (dst) {
641 if (dst_offset >= plen) {
642 /* discard page before offset */
643 dst_offset -= plen;
644 put_page(page);
645 } else {
646 /* reassign page to dst after offset */
647 sg_set_page(dst + j, page,
648 plen - dst_offset,
649 sg[i].offset + dst_offset);
650 dst_offset = 0;
651 j++;
652 }
653 }
654
655 sg[i].length -= plen;
656 sg[i].offset += plen;
657
658 used -= plen;
659 ctx->used -= plen;
660
661 if (sg[i].length)
662 return;
663
664 if (!dst)
665 put_page(page);
666
667 sg_assign_page(sg + i, NULL);
668 }
669
670 list_del(&sgl->list);
671 sock_kfree_s(sk, sgl, sizeof(*sgl) + sizeof(sgl->sg[0]) *
672 (MAX_SGL_ENTS + 1));
673 }
674
675 if (!ctx->used)
676 ctx->merge = 0;
677}
678EXPORT_SYMBOL_GPL(af_alg_pull_tsgl);
679
680/**
681 * af_alg_free_areq_sgls - Release TX and RX SGLs of the request
682 *
683 * @areq Request holding the TX and RX SGL
684 */
685void af_alg_free_areq_sgls(struct af_alg_async_req *areq)
686{
687 struct sock *sk = areq->sk;
688 struct alg_sock *ask = alg_sk(sk);
689 struct af_alg_ctx *ctx = ask->private;
690 struct af_alg_rsgl *rsgl, *tmp;
691 struct scatterlist *tsgl;
692 struct scatterlist *sg;
693 unsigned int i;
694
695 list_for_each_entry_safe(rsgl, tmp, &areq->rsgl_list, list) {
696 ctx->rcvused -= rsgl->sg_num_bytes;
697 af_alg_free_sg(&rsgl->sgl);
698 list_del(&rsgl->list);
699 if (rsgl != &areq->first_rsgl)
700 sock_kfree_s(sk, rsgl, sizeof(*rsgl));
701 }
702
703 tsgl = areq->tsgl;
704 for_each_sg(tsgl, sg, areq->tsgl_entries, i) {
705 if (!sg_page(sg))
706 continue;
707 put_page(sg_page(sg));
708 }
709
710 if (areq->tsgl && areq->tsgl_entries)
711 sock_kfree_s(sk, tsgl, areq->tsgl_entries * sizeof(*tsgl));
712}
713EXPORT_SYMBOL_GPL(af_alg_free_areq_sgls);
714
715/**
716 * af_alg_wait_for_wmem - wait for availability of writable memory
717 *
718 * @sk socket of connection to user space
719 * @flags If MSG_DONTWAIT is set, then only report if function would sleep
720 * @return 0 when writable memory is available, < 0 upon error
721 */
722int af_alg_wait_for_wmem(struct sock *sk, unsigned int flags)
723{
724 DEFINE_WAIT_FUNC(wait, woken_wake_function);
725 int err = -ERESTARTSYS;
726 long timeout;
727
728 if (flags & MSG_DONTWAIT)
729 return -EAGAIN;
730
731 sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
732
733 add_wait_queue(sk_sleep(sk), &wait);
734 for (;;) {
735 if (signal_pending(current))
736 break;
737 timeout = MAX_SCHEDULE_TIMEOUT;
738 if (sk_wait_event(sk, &timeout, af_alg_writable(sk), &wait)) {
739 err = 0;
740 break;
741 }
742 }
743 remove_wait_queue(sk_sleep(sk), &wait);
744
745 return err;
746}
747EXPORT_SYMBOL_GPL(af_alg_wait_for_wmem);
748
749/**
750 * af_alg_wmem_wakeup - wakeup caller when writable memory is available
751 *
752 * @sk socket of connection to user space
753 */
754void af_alg_wmem_wakeup(struct sock *sk)
755{
756 struct socket_wq *wq;
757
758 if (!af_alg_writable(sk))
759 return;
760
761 rcu_read_lock();
762 wq = rcu_dereference(sk->sk_wq);
763 if (skwq_has_sleeper(wq))
764 wake_up_interruptible_sync_poll(&wq->wait, POLLIN |
765 POLLRDNORM |
766 POLLRDBAND);
767 sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
768 rcu_read_unlock();
769}
770EXPORT_SYMBOL_GPL(af_alg_wmem_wakeup);
771
772/**
773 * af_alg_wait_for_data - wait for availability of TX data
774 *
775 * @sk socket of connection to user space
776 * @flags If MSG_DONTWAIT is set, then only report if function would sleep
777 * @return 0 when writable memory is available, < 0 upon error
778 */
779int af_alg_wait_for_data(struct sock *sk, unsigned flags)
780{
781 DEFINE_WAIT_FUNC(wait, woken_wake_function);
782 struct alg_sock *ask = alg_sk(sk);
783 struct af_alg_ctx *ctx = ask->private;
784 long timeout;
785 int err = -ERESTARTSYS;
786
787 if (flags & MSG_DONTWAIT)
788 return -EAGAIN;
789
790 sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
791
792 add_wait_queue(sk_sleep(sk), &wait);
793 for (;;) {
794 if (signal_pending(current))
795 break;
796 timeout = MAX_SCHEDULE_TIMEOUT;
797 if (sk_wait_event(sk, &timeout, (ctx->used || !ctx->more),
798 &wait)) {
799 err = 0;
800 break;
801 }
802 }
803 remove_wait_queue(sk_sleep(sk), &wait);
804
805 sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
806
807 return err;
808}
809EXPORT_SYMBOL_GPL(af_alg_wait_for_data);
810
811/**
812 * af_alg_data_wakeup - wakeup caller when new data can be sent to kernel
813 *
814 * @sk socket of connection to user space
815 */
816
817void af_alg_data_wakeup(struct sock *sk)
818{
819 struct alg_sock *ask = alg_sk(sk);
820 struct af_alg_ctx *ctx = ask->private;
821 struct socket_wq *wq;
822
823 if (!ctx->used)
824 return;
825
826 rcu_read_lock();
827 wq = rcu_dereference(sk->sk_wq);
828 if (skwq_has_sleeper(wq))
829 wake_up_interruptible_sync_poll(&wq->wait, POLLOUT |
830 POLLRDNORM |
831 POLLRDBAND);
832 sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
833 rcu_read_unlock();
834}
835EXPORT_SYMBOL_GPL(af_alg_data_wakeup);
836
837/**
838 * af_alg_sendmsg - implementation of sendmsg system call handler
839 *
840 * The sendmsg system call handler obtains the user data and stores it
841 * in ctx->tsgl_list. This implies allocation of the required numbers of
842 * struct af_alg_tsgl.
843 *
844 * In addition, the ctx is filled with the information sent via CMSG.
845 *
846 * @sock socket of connection to user space
847 * @msg message from user space
848 * @size size of message from user space
849 * @ivsize the size of the IV for the cipher operation to verify that the
850 * user-space-provided IV has the right size
851 * @return the number of copied data upon success, < 0 upon error
852 */
853int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
854 unsigned int ivsize)
855{
856 struct sock *sk = sock->sk;
857 struct alg_sock *ask = alg_sk(sk);
858 struct af_alg_ctx *ctx = ask->private;
859 struct af_alg_tsgl *sgl;
860 struct af_alg_control con = {};
861 long copied = 0;
862 bool enc = 0;
863 bool init = 0;
864 int err = 0;
865
866 if (msg->msg_controllen) {
867 err = af_alg_cmsg_send(msg, &con);
868 if (err)
869 return err;
870
871 init = 1;
872 switch (con.op) {
873 case ALG_OP_ENCRYPT:
874 enc = 1;
875 break;
876 case ALG_OP_DECRYPT:
877 enc = 0;
878 break;
879 default:
880 return -EINVAL;
881 }
882
883 if (con.iv && con.iv->ivlen != ivsize)
884 return -EINVAL;
885 }
886
887 lock_sock(sk);
888 if (!ctx->more && ctx->used) {
889 err = -EINVAL;
890 goto unlock;
891 }
892
893 if (init) {
894 ctx->enc = enc;
895 if (con.iv)
896 memcpy(ctx->iv, con.iv->iv, ivsize);
897
898 ctx->aead_assoclen = con.aead_assoclen;
899 }
900
901 while (size) {
902 struct scatterlist *sg;
903 size_t len = size;
904 size_t plen;
905
906 /* use the existing memory in an allocated page */
907 if (ctx->merge) {
908 sgl = list_entry(ctx->tsgl_list.prev,
909 struct af_alg_tsgl, list);
910 sg = sgl->sg + sgl->cur - 1;
911 len = min_t(size_t, len,
912 PAGE_SIZE - sg->offset - sg->length);
913
914 err = memcpy_from_msg(page_address(sg_page(sg)) +
915 sg->offset + sg->length,
916 msg, len);
917 if (err)
918 goto unlock;
919
920 sg->length += len;
921 ctx->merge = (sg->offset + sg->length) &
922 (PAGE_SIZE - 1);
923
924 ctx->used += len;
925 copied += len;
926 size -= len;
927 continue;
928 }
929
930 if (!af_alg_writable(sk)) {
931 err = af_alg_wait_for_wmem(sk, msg->msg_flags);
932 if (err)
933 goto unlock;
934 }
935
936 /* allocate a new page */
937 len = min_t(unsigned long, len, af_alg_sndbuf(sk));
938
939 err = af_alg_alloc_tsgl(sk);
940 if (err)
941 goto unlock;
942
943 sgl = list_entry(ctx->tsgl_list.prev, struct af_alg_tsgl,
944 list);
945 sg = sgl->sg;
946 if (sgl->cur)
947 sg_unmark_end(sg + sgl->cur - 1);
948
949 do {
950 unsigned int i = sgl->cur;
951
952 plen = min_t(size_t, len, PAGE_SIZE);
953
954 sg_assign_page(sg + i, alloc_page(GFP_KERNEL));
955 if (!sg_page(sg + i)) {
956 err = -ENOMEM;
957 goto unlock;
958 }
959
960 err = memcpy_from_msg(page_address(sg_page(sg + i)),
961 msg, plen);
962 if (err) {
963 __free_page(sg_page(sg + i));
964 sg_assign_page(sg + i, NULL);
965 goto unlock;
966 }
967
968 sg[i].length = plen;
969 len -= plen;
970 ctx->used += plen;
971 copied += plen;
972 size -= plen;
973 sgl->cur++;
974 } while (len && sgl->cur < MAX_SGL_ENTS);
975
976 if (!size)
977 sg_mark_end(sg + sgl->cur - 1);
978
979 ctx->merge = plen & (PAGE_SIZE - 1);
980 }
981
982 err = 0;
983
984 ctx->more = msg->msg_flags & MSG_MORE;
985
986unlock:
987 af_alg_data_wakeup(sk);
988 release_sock(sk);
989
990 return copied ?: err;
991}
992EXPORT_SYMBOL_GPL(af_alg_sendmsg);
993
994/**
995 * af_alg_sendpage - sendpage system call handler
996 *
997 * This is a generic implementation of sendpage to fill ctx->tsgl_list.
998 */
999ssize_t af_alg_sendpage(struct socket *sock, struct page *page,
1000 int offset, size_t size, int flags)
1001{
1002 struct sock *sk = sock->sk;
1003 struct alg_sock *ask = alg_sk(sk);
1004 struct af_alg_ctx *ctx = ask->private;
1005 struct af_alg_tsgl *sgl;
1006 int err = -EINVAL;
1007
1008 if (flags & MSG_SENDPAGE_NOTLAST)
1009 flags |= MSG_MORE;
1010
1011 lock_sock(sk);
1012 if (!ctx->more && ctx->used)
1013 goto unlock;
1014
1015 if (!size)
1016 goto done;
1017
1018 if (!af_alg_writable(sk)) {
1019 err = af_alg_wait_for_wmem(sk, flags);
1020 if (err)
1021 goto unlock;
1022 }
1023
1024 err = af_alg_alloc_tsgl(sk);
1025 if (err)
1026 goto unlock;
1027
1028 ctx->merge = 0;
1029 sgl = list_entry(ctx->tsgl_list.prev, struct af_alg_tsgl, list);
1030
1031 if (sgl->cur)
1032 sg_unmark_end(sgl->sg + sgl->cur - 1);
1033
1034 sg_mark_end(sgl->sg + sgl->cur);
1035
1036 get_page(page);
1037 sg_set_page(sgl->sg + sgl->cur, page, size, offset);
1038 sgl->cur++;
1039 ctx->used += size;
1040
1041done:
1042 ctx->more = flags & MSG_MORE;
1043
1044unlock:
1045 af_alg_data_wakeup(sk);
1046 release_sock(sk);
1047
1048 return err ?: size;
1049}
1050EXPORT_SYMBOL_GPL(af_alg_sendpage);
1051
1052/**
1053 * af_alg_async_cb - AIO callback handler
1054 *
1055 * This handler cleans up the struct af_alg_async_req upon completion of the
1056 * AIO operation.
1057 *
1058 * The number of bytes to be generated with the AIO operation must be set
1059 * in areq->outlen before the AIO callback handler is invoked.
1060 */
1061void af_alg_async_cb(struct crypto_async_request *_req, int err)
1062{
1063 struct af_alg_async_req *areq = _req->data;
1064 struct sock *sk = areq->sk;
1065 struct kiocb *iocb = areq->iocb;
1066 unsigned int resultlen;
1067
1068 lock_sock(sk);
1069
1070 /* Buffer size written by crypto operation. */
1071 resultlen = areq->outlen;
1072
1073 af_alg_free_areq_sgls(areq);
1074 sock_kfree_s(sk, areq, areq->areqlen);
1075 __sock_put(sk);
1076
1077 iocb->ki_complete(iocb, err ? err : resultlen, 0);
1078
1079 release_sock(sk);
1080}
1081EXPORT_SYMBOL_GPL(af_alg_async_cb);
1082
1083/**
1084 * af_alg_poll - poll system call handler
1085 */
1086unsigned int af_alg_poll(struct file *file, struct socket *sock,
1087 poll_table *wait)
1088{
1089 struct sock *sk = sock->sk;
1090 struct alg_sock *ask = alg_sk(sk);
1091 struct af_alg_ctx *ctx = ask->private;
1092 unsigned int mask;
1093
1094 sock_poll_wait(file, sk_sleep(sk), wait);
1095 mask = 0;
1096
1097 if (!ctx->more || ctx->used)
1098 mask |= POLLIN | POLLRDNORM;
1099
1100 if (af_alg_writable(sk))
1101 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
1102
1103 return mask;
1104}
1105EXPORT_SYMBOL_GPL(af_alg_poll);
1106
1107/**
1108 * af_alg_alloc_areq - allocate struct af_alg_async_req
1109 *
1110 * @sk socket of connection to user space
1111 * @areqlen size of struct af_alg_async_req + crypto_*_reqsize
1112 * @return allocated data structure or ERR_PTR upon error
1113 */
1114struct af_alg_async_req *af_alg_alloc_areq(struct sock *sk,
1115 unsigned int areqlen)
1116{
1117 struct af_alg_async_req *areq = sock_kmalloc(sk, areqlen, GFP_KERNEL);
1118
1119 if (unlikely(!areq))
1120 return ERR_PTR(-ENOMEM);
1121
1122 areq->areqlen = areqlen;
1123 areq->sk = sk;
1124 areq->last_rsgl = NULL;
1125 INIT_LIST_HEAD(&areq->rsgl_list);
1126 areq->tsgl = NULL;
1127 areq->tsgl_entries = 0;
1128
1129 return areq;
1130}
1131EXPORT_SYMBOL_GPL(af_alg_alloc_areq);
1132
1133/**
1134 * af_alg_get_rsgl - create the RX SGL for the output data from the crypto
1135 * operation
1136 *
1137 * @sk socket of connection to user space
1138 * @msg user space message
1139 * @flags flags used to invoke recvmsg with
1140 * @areq instance of the cryptographic request that will hold the RX SGL
1141 * @maxsize maximum number of bytes to be pulled from user space
1142 * @outlen number of bytes in the RX SGL
1143 * @return 0 on success, < 0 upon error
1144 */
1145int af_alg_get_rsgl(struct sock *sk, struct msghdr *msg, int flags,
1146 struct af_alg_async_req *areq, size_t maxsize,
1147 size_t *outlen)
1148{
1149 struct alg_sock *ask = alg_sk(sk);
1150 struct af_alg_ctx *ctx = ask->private;
1151 size_t len = 0;
1152
1153 while (maxsize > len && msg_data_left(msg)) {
1154 struct af_alg_rsgl *rsgl;
1155 size_t seglen;
1156 int err;
1157
1158 /* limit the amount of readable buffers */
1159 if (!af_alg_readable(sk))
1160 break;
1161
1162 if (!ctx->used) {
1163 err = af_alg_wait_for_data(sk, flags);
1164 if (err)
1165 return err;
1166 }
1167
1168 seglen = min_t(size_t, (maxsize - len),
1169 msg_data_left(msg));
1170
1171 if (list_empty(&areq->rsgl_list)) {
1172 rsgl = &areq->first_rsgl;
1173 } else {
1174 rsgl = sock_kmalloc(sk, sizeof(*rsgl), GFP_KERNEL);
1175 if (unlikely(!rsgl))
1176 return -ENOMEM;
1177 }
1178
1179 rsgl->sgl.npages = 0;
1180 list_add_tail(&rsgl->list, &areq->rsgl_list);
1181
1182 /* make one iovec available as scatterlist */
1183 err = af_alg_make_sg(&rsgl->sgl, &msg->msg_iter, seglen);
1184 if (err < 0)
1185 return err;
1186
1187 /* chain the new scatterlist with previous one */
1188 if (areq->last_rsgl)
1189 af_alg_link_sg(&areq->last_rsgl->sgl, &rsgl->sgl);
1190
1191 areq->last_rsgl = rsgl;
1192 len += err;
1193 ctx->rcvused += err;
1194 rsgl->sg_num_bytes = err;
1195 iov_iter_advance(&msg->msg_iter, err);
1196 }
1197
1198 *outlen = len;
1199 return 0;
1200}
1201EXPORT_SYMBOL_GPL(af_alg_get_rsgl);
1202
510static int __init af_alg_init(void) 1203static int __init af_alg_init(void)
511{ 1204{
512 int err = proto_register(&alg_proto, 0); 1205 int err = proto_register(&alg_proto, 0);