1*8ff59090SHerbert Xu /* 2*8ff59090SHerbert Xu * algif_skcipher: User-space interface for skcipher algorithms 3*8ff59090SHerbert Xu * 4*8ff59090SHerbert Xu * This file provides the user-space API for symmetric key ciphers. 5*8ff59090SHerbert Xu * 6*8ff59090SHerbert Xu * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au> 7*8ff59090SHerbert Xu * 8*8ff59090SHerbert Xu * This program is free software; you can redistribute it and/or modify it 9*8ff59090SHerbert Xu * under the terms of the GNU General Public License as published by the Free 10*8ff59090SHerbert Xu * Software Foundation; either version 2 of the License, or (at your option) 11*8ff59090SHerbert Xu * any later version. 12*8ff59090SHerbert Xu * 13*8ff59090SHerbert Xu */ 14*8ff59090SHerbert Xu 15*8ff59090SHerbert Xu #include <crypto/scatterwalk.h> 16*8ff59090SHerbert Xu #include <crypto/skcipher.h> 17*8ff59090SHerbert Xu #include <crypto/if_alg.h> 18*8ff59090SHerbert Xu #include <linux/init.h> 19*8ff59090SHerbert Xu #include <linux/list.h> 20*8ff59090SHerbert Xu #include <linux/kernel.h> 21*8ff59090SHerbert Xu #include <linux/mm.h> 22*8ff59090SHerbert Xu #include <linux/module.h> 23*8ff59090SHerbert Xu #include <linux/net.h> 24*8ff59090SHerbert Xu #include <net/sock.h> 25*8ff59090SHerbert Xu 26*8ff59090SHerbert Xu struct skcipher_sg_list { 27*8ff59090SHerbert Xu struct list_head list; 28*8ff59090SHerbert Xu 29*8ff59090SHerbert Xu int cur; 30*8ff59090SHerbert Xu 31*8ff59090SHerbert Xu struct scatterlist sg[0]; 32*8ff59090SHerbert Xu }; 33*8ff59090SHerbert Xu 34*8ff59090SHerbert Xu struct skcipher_ctx { 35*8ff59090SHerbert Xu struct list_head tsgl; 36*8ff59090SHerbert Xu struct af_alg_sgl rsgl; 37*8ff59090SHerbert Xu 38*8ff59090SHerbert Xu void *iv; 39*8ff59090SHerbert Xu 40*8ff59090SHerbert Xu struct af_alg_completion completion; 41*8ff59090SHerbert Xu 42*8ff59090SHerbert Xu unsigned used; 43*8ff59090SHerbert Xu 44*8ff59090SHerbert Xu unsigned int len; 45*8ff59090SHerbert Xu bool more; 46*8ff59090SHerbert Xu bool merge; 47*8ff59090SHerbert Xu bool enc; 48*8ff59090SHerbert Xu 49*8ff59090SHerbert Xu struct ablkcipher_request req; 50*8ff59090SHerbert Xu }; 51*8ff59090SHerbert Xu 52*8ff59090SHerbert Xu #define MAX_SGL_ENTS ((PAGE_SIZE - sizeof(struct skcipher_sg_list)) / \ 53*8ff59090SHerbert Xu sizeof(struct scatterlist) - 1) 54*8ff59090SHerbert Xu 55*8ff59090SHerbert Xu static inline bool skcipher_writable(struct sock *sk) 56*8ff59090SHerbert Xu { 57*8ff59090SHerbert Xu struct alg_sock *ask = alg_sk(sk); 58*8ff59090SHerbert Xu struct skcipher_ctx *ctx = ask->private; 59*8ff59090SHerbert Xu 60*8ff59090SHerbert Xu return ctx->used + PAGE_SIZE <= max_t(int, sk->sk_sndbuf, PAGE_SIZE); 61*8ff59090SHerbert Xu } 62*8ff59090SHerbert Xu 63*8ff59090SHerbert Xu static int skcipher_alloc_sgl(struct sock *sk) 64*8ff59090SHerbert Xu { 65*8ff59090SHerbert Xu struct alg_sock *ask = alg_sk(sk); 66*8ff59090SHerbert Xu struct skcipher_ctx *ctx = ask->private; 67*8ff59090SHerbert Xu struct skcipher_sg_list *sgl; 68*8ff59090SHerbert Xu struct scatterlist *sg = NULL; 69*8ff59090SHerbert Xu 70*8ff59090SHerbert Xu sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list); 71*8ff59090SHerbert Xu if (!list_empty(&ctx->tsgl)) 72*8ff59090SHerbert Xu sg = sgl->sg; 73*8ff59090SHerbert Xu 74*8ff59090SHerbert Xu if (!sg || sgl->cur >= MAX_SGL_ENTS) { 75*8ff59090SHerbert Xu sgl = sock_kmalloc(sk, sizeof(*sgl) + 76*8ff59090SHerbert Xu sizeof(sgl->sg[0]) * (MAX_SGL_ENTS + 1), 77*8ff59090SHerbert Xu GFP_KERNEL); 78*8ff59090SHerbert Xu if (!sgl) 79*8ff59090SHerbert Xu return -ENOMEM; 80*8ff59090SHerbert Xu 81*8ff59090SHerbert Xu sg_init_table(sgl->sg, MAX_SGL_ENTS + 1); 82*8ff59090SHerbert Xu sgl->cur = 0; 83*8ff59090SHerbert Xu 84*8ff59090SHerbert Xu if (sg) 85*8ff59090SHerbert Xu scatterwalk_sg_chain(sg, MAX_SGL_ENTS + 1, sgl->sg); 86*8ff59090SHerbert Xu 87*8ff59090SHerbert Xu list_add_tail(&sgl->list, &ctx->tsgl); 88*8ff59090SHerbert Xu } 89*8ff59090SHerbert Xu 90*8ff59090SHerbert Xu return 0; 91*8ff59090SHerbert Xu } 92*8ff59090SHerbert Xu 93*8ff59090SHerbert Xu static void skcipher_pull_sgl(struct sock *sk, int used) 94*8ff59090SHerbert Xu { 95*8ff59090SHerbert Xu struct alg_sock *ask = alg_sk(sk); 96*8ff59090SHerbert Xu struct skcipher_ctx *ctx = ask->private; 97*8ff59090SHerbert Xu struct skcipher_sg_list *sgl; 98*8ff59090SHerbert Xu struct scatterlist *sg; 99*8ff59090SHerbert Xu int i; 100*8ff59090SHerbert Xu 101*8ff59090SHerbert Xu while (!list_empty(&ctx->tsgl)) { 102*8ff59090SHerbert Xu sgl = list_first_entry(&ctx->tsgl, struct skcipher_sg_list, 103*8ff59090SHerbert Xu list); 104*8ff59090SHerbert Xu sg = sgl->sg; 105*8ff59090SHerbert Xu 106*8ff59090SHerbert Xu for (i = 0; i < sgl->cur; i++) { 107*8ff59090SHerbert Xu int plen = min_t(int, used, sg[i].length); 108*8ff59090SHerbert Xu 109*8ff59090SHerbert Xu if (!sg_page(sg + i)) 110*8ff59090SHerbert Xu continue; 111*8ff59090SHerbert Xu 112*8ff59090SHerbert Xu sg[i].length -= plen; 113*8ff59090SHerbert Xu sg[i].offset += plen; 114*8ff59090SHerbert Xu 115*8ff59090SHerbert Xu used -= plen; 116*8ff59090SHerbert Xu ctx->used -= plen; 117*8ff59090SHerbert Xu 118*8ff59090SHerbert Xu if (sg[i].length) 119*8ff59090SHerbert Xu return; 120*8ff59090SHerbert Xu 121*8ff59090SHerbert Xu put_page(sg_page(sg + i)); 122*8ff59090SHerbert Xu sg_assign_page(sg + i, NULL); 123*8ff59090SHerbert Xu } 124*8ff59090SHerbert Xu 125*8ff59090SHerbert Xu list_del(&sgl->list); 126*8ff59090SHerbert Xu sock_kfree_s(sk, sgl, 127*8ff59090SHerbert Xu sizeof(*sgl) + sizeof(sgl->sg[0]) * 128*8ff59090SHerbert Xu (MAX_SGL_ENTS + 1)); 129*8ff59090SHerbert Xu } 130*8ff59090SHerbert Xu 131*8ff59090SHerbert Xu if (!ctx->used) 132*8ff59090SHerbert Xu ctx->merge = 0; 133*8ff59090SHerbert Xu } 134*8ff59090SHerbert Xu 135*8ff59090SHerbert Xu static void skcipher_free_sgl(struct sock *sk) 136*8ff59090SHerbert Xu { 137*8ff59090SHerbert Xu struct alg_sock *ask = alg_sk(sk); 138*8ff59090SHerbert Xu struct skcipher_ctx *ctx = ask->private; 139*8ff59090SHerbert Xu 140*8ff59090SHerbert Xu skcipher_pull_sgl(sk, ctx->used); 141*8ff59090SHerbert Xu } 142*8ff59090SHerbert Xu 143*8ff59090SHerbert Xu static int skcipher_wait_for_wmem(struct sock *sk, unsigned flags) 144*8ff59090SHerbert Xu { 145*8ff59090SHerbert Xu long timeout; 146*8ff59090SHerbert Xu DEFINE_WAIT(wait); 147*8ff59090SHerbert Xu int err = -ERESTARTSYS; 148*8ff59090SHerbert Xu 149*8ff59090SHerbert Xu if (flags & MSG_DONTWAIT) 150*8ff59090SHerbert Xu return -EAGAIN; 151*8ff59090SHerbert Xu 152*8ff59090SHerbert Xu set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); 153*8ff59090SHerbert Xu 154*8ff59090SHerbert Xu for (;;) { 155*8ff59090SHerbert Xu if (signal_pending(current)) 156*8ff59090SHerbert Xu break; 157*8ff59090SHerbert Xu prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); 158*8ff59090SHerbert Xu timeout = MAX_SCHEDULE_TIMEOUT; 159*8ff59090SHerbert Xu if (sk_wait_event(sk, &timeout, skcipher_writable(sk))) { 160*8ff59090SHerbert Xu err = 0; 161*8ff59090SHerbert Xu break; 162*8ff59090SHerbert Xu } 163*8ff59090SHerbert Xu } 164*8ff59090SHerbert Xu finish_wait(sk_sleep(sk), &wait); 165*8ff59090SHerbert Xu 166*8ff59090SHerbert Xu return err; 167*8ff59090SHerbert Xu } 168*8ff59090SHerbert Xu 169*8ff59090SHerbert Xu static void skcipher_wmem_wakeup(struct sock *sk) 170*8ff59090SHerbert Xu { 171*8ff59090SHerbert Xu struct socket_wq *wq; 172*8ff59090SHerbert Xu 173*8ff59090SHerbert Xu if (!skcipher_writable(sk)) 174*8ff59090SHerbert Xu return; 175*8ff59090SHerbert Xu 176*8ff59090SHerbert Xu rcu_read_lock(); 177*8ff59090SHerbert Xu wq = rcu_dereference(sk->sk_wq); 178*8ff59090SHerbert Xu if (wq_has_sleeper(wq)) 179*8ff59090SHerbert Xu wake_up_interruptible_sync_poll(&wq->wait, POLLIN | 180*8ff59090SHerbert Xu POLLRDNORM | 181*8ff59090SHerbert Xu POLLRDBAND); 182*8ff59090SHerbert Xu sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN); 183*8ff59090SHerbert Xu rcu_read_unlock(); 184*8ff59090SHerbert Xu } 185*8ff59090SHerbert Xu 186*8ff59090SHerbert Xu static int skcipher_wait_for_data(struct sock *sk, unsigned flags) 187*8ff59090SHerbert Xu { 188*8ff59090SHerbert Xu struct alg_sock *ask = alg_sk(sk); 189*8ff59090SHerbert Xu struct skcipher_ctx *ctx = ask->private; 190*8ff59090SHerbert Xu long timeout; 191*8ff59090SHerbert Xu DEFINE_WAIT(wait); 192*8ff59090SHerbert Xu int err = -ERESTARTSYS; 193*8ff59090SHerbert Xu 194*8ff59090SHerbert Xu if (flags & MSG_DONTWAIT) { 195*8ff59090SHerbert Xu return -EAGAIN; 196*8ff59090SHerbert Xu } 197*8ff59090SHerbert Xu 198*8ff59090SHerbert Xu set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); 199*8ff59090SHerbert Xu 200*8ff59090SHerbert Xu for (;;) { 201*8ff59090SHerbert Xu if (signal_pending(current)) 202*8ff59090SHerbert Xu break; 203*8ff59090SHerbert Xu prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); 204*8ff59090SHerbert Xu timeout = MAX_SCHEDULE_TIMEOUT; 205*8ff59090SHerbert Xu if (sk_wait_event(sk, &timeout, ctx->used)) { 206*8ff59090SHerbert Xu err = 0; 207*8ff59090SHerbert Xu break; 208*8ff59090SHerbert Xu } 209*8ff59090SHerbert Xu } 210*8ff59090SHerbert Xu finish_wait(sk_sleep(sk), &wait); 211*8ff59090SHerbert Xu 212*8ff59090SHerbert Xu clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); 213*8ff59090SHerbert Xu 214*8ff59090SHerbert Xu return err; 215*8ff59090SHerbert Xu } 216*8ff59090SHerbert Xu 217*8ff59090SHerbert Xu static void skcipher_data_wakeup(struct sock *sk) 218*8ff59090SHerbert Xu { 219*8ff59090SHerbert Xu struct alg_sock *ask = alg_sk(sk); 220*8ff59090SHerbert Xu struct skcipher_ctx *ctx = ask->private; 221*8ff59090SHerbert Xu struct socket_wq *wq; 222*8ff59090SHerbert Xu 223*8ff59090SHerbert Xu if (!ctx->used) 224*8ff59090SHerbert Xu return; 225*8ff59090SHerbert Xu 226*8ff59090SHerbert Xu rcu_read_lock(); 227*8ff59090SHerbert Xu wq = rcu_dereference(sk->sk_wq); 228*8ff59090SHerbert Xu if (wq_has_sleeper(wq)) 229*8ff59090SHerbert Xu wake_up_interruptible_sync_poll(&wq->wait, POLLOUT | 230*8ff59090SHerbert Xu POLLRDNORM | 231*8ff59090SHerbert Xu POLLRDBAND); 232*8ff59090SHerbert Xu sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); 233*8ff59090SHerbert Xu rcu_read_unlock(); 234*8ff59090SHerbert Xu } 235*8ff59090SHerbert Xu 236*8ff59090SHerbert Xu static int skcipher_sendmsg(struct kiocb *unused, struct socket *sock, 237*8ff59090SHerbert Xu struct msghdr *msg, size_t size) 238*8ff59090SHerbert Xu { 239*8ff59090SHerbert Xu struct sock *sk = sock->sk; 240*8ff59090SHerbert Xu struct alg_sock *ask = alg_sk(sk); 241*8ff59090SHerbert Xu struct skcipher_ctx *ctx = ask->private; 242*8ff59090SHerbert Xu struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(&ctx->req); 243*8ff59090SHerbert Xu unsigned ivsize = crypto_ablkcipher_ivsize(tfm); 244*8ff59090SHerbert Xu struct skcipher_sg_list *sgl; 245*8ff59090SHerbert Xu struct af_alg_control con = {}; 246*8ff59090SHerbert Xu long copied = 0; 247*8ff59090SHerbert Xu bool enc = 0; 248*8ff59090SHerbert Xu int limit; 249*8ff59090SHerbert Xu int err; 250*8ff59090SHerbert Xu int i; 251*8ff59090SHerbert Xu 252*8ff59090SHerbert Xu if (msg->msg_controllen) { 253*8ff59090SHerbert Xu err = af_alg_cmsg_send(msg, &con); 254*8ff59090SHerbert Xu if (err) 255*8ff59090SHerbert Xu return err; 256*8ff59090SHerbert Xu 257*8ff59090SHerbert Xu switch (con.op) { 258*8ff59090SHerbert Xu case ALG_OP_ENCRYPT: 259*8ff59090SHerbert Xu enc = 1; 260*8ff59090SHerbert Xu break; 261*8ff59090SHerbert Xu case ALG_OP_DECRYPT: 262*8ff59090SHerbert Xu enc = 0; 263*8ff59090SHerbert Xu break; 264*8ff59090SHerbert Xu default: 265*8ff59090SHerbert Xu return -EINVAL; 266*8ff59090SHerbert Xu } 267*8ff59090SHerbert Xu 268*8ff59090SHerbert Xu if (con.iv && con.iv->ivlen != ivsize) 269*8ff59090SHerbert Xu return -EINVAL; 270*8ff59090SHerbert Xu } 271*8ff59090SHerbert Xu 272*8ff59090SHerbert Xu err = -EINVAL; 273*8ff59090SHerbert Xu 274*8ff59090SHerbert Xu lock_sock(sk); 275*8ff59090SHerbert Xu if (!ctx->more && ctx->used) 276*8ff59090SHerbert Xu goto unlock; 277*8ff59090SHerbert Xu 278*8ff59090SHerbert Xu if (!ctx->used) { 279*8ff59090SHerbert Xu ctx->enc = enc; 280*8ff59090SHerbert Xu if (con.iv) 281*8ff59090SHerbert Xu memcpy(ctx->iv, con.iv->iv, ivsize); 282*8ff59090SHerbert Xu } 283*8ff59090SHerbert Xu 284*8ff59090SHerbert Xu limit = max_t(int, sk->sk_sndbuf, PAGE_SIZE); 285*8ff59090SHerbert Xu limit -= ctx->used; 286*8ff59090SHerbert Xu 287*8ff59090SHerbert Xu while (size) { 288*8ff59090SHerbert Xu struct scatterlist *sg; 289*8ff59090SHerbert Xu unsigned long len = size; 290*8ff59090SHerbert Xu int plen; 291*8ff59090SHerbert Xu 292*8ff59090SHerbert Xu if (ctx->merge) { 293*8ff59090SHerbert Xu sgl = list_entry(ctx->tsgl.prev, 294*8ff59090SHerbert Xu struct skcipher_sg_list, list); 295*8ff59090SHerbert Xu sg = sgl->sg + sgl->cur - 1; 296*8ff59090SHerbert Xu len = min_t(unsigned long, len, 297*8ff59090SHerbert Xu PAGE_SIZE - sg->offset - sg->length); 298*8ff59090SHerbert Xu 299*8ff59090SHerbert Xu err = memcpy_fromiovec(page_address(sg_page(sg)) + 300*8ff59090SHerbert Xu sg->offset + sg->length, 301*8ff59090SHerbert Xu msg->msg_iov, len); 302*8ff59090SHerbert Xu if (err) 303*8ff59090SHerbert Xu goto unlock; 304*8ff59090SHerbert Xu 305*8ff59090SHerbert Xu sg->length += len; 306*8ff59090SHerbert Xu ctx->merge = (sg->offset + sg->length) & 307*8ff59090SHerbert Xu (PAGE_SIZE - 1); 308*8ff59090SHerbert Xu 309*8ff59090SHerbert Xu ctx->used += len; 310*8ff59090SHerbert Xu copied += len; 311*8ff59090SHerbert Xu size -= len; 312*8ff59090SHerbert Xu limit -= len; 313*8ff59090SHerbert Xu continue; 314*8ff59090SHerbert Xu } 315*8ff59090SHerbert Xu 316*8ff59090SHerbert Xu if (limit < PAGE_SIZE) { 317*8ff59090SHerbert Xu err = skcipher_wait_for_wmem(sk, msg->msg_flags); 318*8ff59090SHerbert Xu if (err) 319*8ff59090SHerbert Xu goto unlock; 320*8ff59090SHerbert Xu 321*8ff59090SHerbert Xu limit = max_t(int, sk->sk_sndbuf, PAGE_SIZE); 322*8ff59090SHerbert Xu limit -= ctx->used; 323*8ff59090SHerbert Xu } 324*8ff59090SHerbert Xu 325*8ff59090SHerbert Xu len = min_t(unsigned long, len, limit); 326*8ff59090SHerbert Xu 327*8ff59090SHerbert Xu err = skcipher_alloc_sgl(sk); 328*8ff59090SHerbert Xu if (err) 329*8ff59090SHerbert Xu goto unlock; 330*8ff59090SHerbert Xu 331*8ff59090SHerbert Xu sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list); 332*8ff59090SHerbert Xu sg = sgl->sg; 333*8ff59090SHerbert Xu do { 334*8ff59090SHerbert Xu i = sgl->cur; 335*8ff59090SHerbert Xu plen = min_t(int, len, PAGE_SIZE); 336*8ff59090SHerbert Xu 337*8ff59090SHerbert Xu sg_assign_page(sg + i, alloc_page(GFP_KERNEL)); 338*8ff59090SHerbert Xu err = -ENOMEM; 339*8ff59090SHerbert Xu if (!sg_page(sg + i)) 340*8ff59090SHerbert Xu goto unlock; 341*8ff59090SHerbert Xu 342*8ff59090SHerbert Xu err = memcpy_fromiovec(page_address(sg_page(sg + i)), 343*8ff59090SHerbert Xu msg->msg_iov, plen); 344*8ff59090SHerbert Xu if (err) { 345*8ff59090SHerbert Xu __free_page(sg_page(sg + i)); 346*8ff59090SHerbert Xu sg_assign_page(sg + i, NULL); 347*8ff59090SHerbert Xu goto unlock; 348*8ff59090SHerbert Xu } 349*8ff59090SHerbert Xu 350*8ff59090SHerbert Xu sg[i].length = plen; 351*8ff59090SHerbert Xu len -= plen; 352*8ff59090SHerbert Xu ctx->used += plen; 353*8ff59090SHerbert Xu copied += plen; 354*8ff59090SHerbert Xu size -= plen; 355*8ff59090SHerbert Xu limit -= plen; 356*8ff59090SHerbert Xu sgl->cur++; 357*8ff59090SHerbert Xu } while (len && sgl->cur < MAX_SGL_ENTS); 358*8ff59090SHerbert Xu 359*8ff59090SHerbert Xu ctx->merge = plen & (PAGE_SIZE - 1); 360*8ff59090SHerbert Xu } 361*8ff59090SHerbert Xu 362*8ff59090SHerbert Xu err = 0; 363*8ff59090SHerbert Xu 364*8ff59090SHerbert Xu ctx->more = msg->msg_flags & MSG_MORE; 365*8ff59090SHerbert Xu if (!ctx->more && !list_empty(&ctx->tsgl)) 366*8ff59090SHerbert Xu sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list); 367*8ff59090SHerbert Xu 368*8ff59090SHerbert Xu unlock: 369*8ff59090SHerbert Xu skcipher_data_wakeup(sk); 370*8ff59090SHerbert Xu release_sock(sk); 371*8ff59090SHerbert Xu 372*8ff59090SHerbert Xu return copied ?: err; 373*8ff59090SHerbert Xu } 374*8ff59090SHerbert Xu 375*8ff59090SHerbert Xu static ssize_t skcipher_sendpage(struct socket *sock, struct page *page, 376*8ff59090SHerbert Xu int offset, size_t size, int flags) 377*8ff59090SHerbert Xu { 378*8ff59090SHerbert Xu struct sock *sk = sock->sk; 379*8ff59090SHerbert Xu struct alg_sock *ask = alg_sk(sk); 380*8ff59090SHerbert Xu struct skcipher_ctx *ctx = ask->private; 381*8ff59090SHerbert Xu struct skcipher_sg_list *sgl; 382*8ff59090SHerbert Xu int err = -EINVAL; 383*8ff59090SHerbert Xu int limit; 384*8ff59090SHerbert Xu 385*8ff59090SHerbert Xu lock_sock(sk); 386*8ff59090SHerbert Xu if (!ctx->more && ctx->used) 387*8ff59090SHerbert Xu goto unlock; 388*8ff59090SHerbert Xu 389*8ff59090SHerbert Xu if (!size) 390*8ff59090SHerbert Xu goto done; 391*8ff59090SHerbert Xu 392*8ff59090SHerbert Xu limit = max_t(int, sk->sk_sndbuf, PAGE_SIZE); 393*8ff59090SHerbert Xu limit -= ctx->used; 394*8ff59090SHerbert Xu 395*8ff59090SHerbert Xu if (limit < PAGE_SIZE) { 396*8ff59090SHerbert Xu err = skcipher_wait_for_wmem(sk, flags); 397*8ff59090SHerbert Xu if (err) 398*8ff59090SHerbert Xu goto unlock; 399*8ff59090SHerbert Xu 400*8ff59090SHerbert Xu limit = max_t(int, sk->sk_sndbuf, PAGE_SIZE); 401*8ff59090SHerbert Xu limit -= ctx->used; 402*8ff59090SHerbert Xu } 403*8ff59090SHerbert Xu 404*8ff59090SHerbert Xu err = skcipher_alloc_sgl(sk); 405*8ff59090SHerbert Xu if (err) 406*8ff59090SHerbert Xu goto unlock; 407*8ff59090SHerbert Xu 408*8ff59090SHerbert Xu ctx->merge = 0; 409*8ff59090SHerbert Xu sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list); 410*8ff59090SHerbert Xu 411*8ff59090SHerbert Xu get_page(page); 412*8ff59090SHerbert Xu sg_set_page(sgl->sg + sgl->cur, page, size, offset); 413*8ff59090SHerbert Xu sgl->cur++; 414*8ff59090SHerbert Xu ctx->used += size; 415*8ff59090SHerbert Xu 416*8ff59090SHerbert Xu done: 417*8ff59090SHerbert Xu ctx->more = flags & MSG_MORE; 418*8ff59090SHerbert Xu if (!ctx->more && !list_empty(&ctx->tsgl)) 419*8ff59090SHerbert Xu sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list); 420*8ff59090SHerbert Xu 421*8ff59090SHerbert Xu unlock: 422*8ff59090SHerbert Xu skcipher_data_wakeup(sk); 423*8ff59090SHerbert Xu release_sock(sk); 424*8ff59090SHerbert Xu 425*8ff59090SHerbert Xu return err ?: size; 426*8ff59090SHerbert Xu } 427*8ff59090SHerbert Xu 428*8ff59090SHerbert Xu static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock, 429*8ff59090SHerbert Xu struct msghdr *msg, size_t ignored, int flags) 430*8ff59090SHerbert Xu { 431*8ff59090SHerbert Xu struct sock *sk = sock->sk; 432*8ff59090SHerbert Xu struct alg_sock *ask = alg_sk(sk); 433*8ff59090SHerbert Xu struct skcipher_ctx *ctx = ask->private; 434*8ff59090SHerbert Xu unsigned bs = crypto_ablkcipher_blocksize(crypto_ablkcipher_reqtfm( 435*8ff59090SHerbert Xu &ctx->req)); 436*8ff59090SHerbert Xu struct skcipher_sg_list *sgl; 437*8ff59090SHerbert Xu struct scatterlist *sg; 438*8ff59090SHerbert Xu unsigned long iovlen; 439*8ff59090SHerbert Xu struct iovec *iov; 440*8ff59090SHerbert Xu int err = -EAGAIN; 441*8ff59090SHerbert Xu int used; 442*8ff59090SHerbert Xu long copied = 0; 443*8ff59090SHerbert Xu 444*8ff59090SHerbert Xu lock_sock(sk); 445*8ff59090SHerbert Xu for (iov = msg->msg_iov, iovlen = msg->msg_iovlen; iovlen > 0; 446*8ff59090SHerbert Xu iovlen--, iov++) { 447*8ff59090SHerbert Xu unsigned long seglen = iov->iov_len; 448*8ff59090SHerbert Xu char __user *from = iov->iov_base; 449*8ff59090SHerbert Xu 450*8ff59090SHerbert Xu while (seglen) { 451*8ff59090SHerbert Xu sgl = list_first_entry(&ctx->tsgl, 452*8ff59090SHerbert Xu struct skcipher_sg_list, list); 453*8ff59090SHerbert Xu sg = sgl->sg; 454*8ff59090SHerbert Xu 455*8ff59090SHerbert Xu while (!sg->length) 456*8ff59090SHerbert Xu sg++; 457*8ff59090SHerbert Xu 458*8ff59090SHerbert Xu used = ctx->used; 459*8ff59090SHerbert Xu if (!used) { 460*8ff59090SHerbert Xu err = skcipher_wait_for_data(sk, flags); 461*8ff59090SHerbert Xu if (err) 462*8ff59090SHerbert Xu goto unlock; 463*8ff59090SHerbert Xu } 464*8ff59090SHerbert Xu 465*8ff59090SHerbert Xu used = min_t(unsigned long, used, seglen); 466*8ff59090SHerbert Xu 467*8ff59090SHerbert Xu if (ctx->more || used < ctx->used) 468*8ff59090SHerbert Xu used -= used % bs; 469*8ff59090SHerbert Xu 470*8ff59090SHerbert Xu err = -EINVAL; 471*8ff59090SHerbert Xu if (!used) 472*8ff59090SHerbert Xu goto unlock; 473*8ff59090SHerbert Xu 474*8ff59090SHerbert Xu used = af_alg_make_sg(&ctx->rsgl, from, used, 1); 475*8ff59090SHerbert Xu if (used < 0) 476*8ff59090SHerbert Xu goto unlock; 477*8ff59090SHerbert Xu 478*8ff59090SHerbert Xu ablkcipher_request_set_crypt(&ctx->req, sg, 479*8ff59090SHerbert Xu ctx->rsgl.sg, used, 480*8ff59090SHerbert Xu ctx->iv); 481*8ff59090SHerbert Xu 482*8ff59090SHerbert Xu err = af_alg_wait_for_completion( 483*8ff59090SHerbert Xu ctx->enc ? 484*8ff59090SHerbert Xu crypto_ablkcipher_encrypt(&ctx->req) : 485*8ff59090SHerbert Xu crypto_ablkcipher_decrypt(&ctx->req), 486*8ff59090SHerbert Xu &ctx->completion); 487*8ff59090SHerbert Xu 488*8ff59090SHerbert Xu af_alg_free_sg(&ctx->rsgl); 489*8ff59090SHerbert Xu 490*8ff59090SHerbert Xu if (err) 491*8ff59090SHerbert Xu goto unlock; 492*8ff59090SHerbert Xu 493*8ff59090SHerbert Xu copied += used; 494*8ff59090SHerbert Xu from += used; 495*8ff59090SHerbert Xu seglen -= used; 496*8ff59090SHerbert Xu skcipher_pull_sgl(sk, used); 497*8ff59090SHerbert Xu } 498*8ff59090SHerbert Xu } 499*8ff59090SHerbert Xu 500*8ff59090SHerbert Xu err = 0; 501*8ff59090SHerbert Xu 502*8ff59090SHerbert Xu unlock: 503*8ff59090SHerbert Xu skcipher_wmem_wakeup(sk); 504*8ff59090SHerbert Xu release_sock(sk); 505*8ff59090SHerbert Xu 506*8ff59090SHerbert Xu return copied ?: err; 507*8ff59090SHerbert Xu } 508*8ff59090SHerbert Xu 509*8ff59090SHerbert Xu 510*8ff59090SHerbert Xu static unsigned int skcipher_poll(struct file *file, struct socket *sock, 511*8ff59090SHerbert Xu poll_table *wait) 512*8ff59090SHerbert Xu { 513*8ff59090SHerbert Xu struct sock *sk = sock->sk; 514*8ff59090SHerbert Xu struct alg_sock *ask = alg_sk(sk); 515*8ff59090SHerbert Xu struct skcipher_ctx *ctx = ask->private; 516*8ff59090SHerbert Xu unsigned int mask; 517*8ff59090SHerbert Xu 518*8ff59090SHerbert Xu sock_poll_wait(file, sk_sleep(sk), wait); 519*8ff59090SHerbert Xu mask = 0; 520*8ff59090SHerbert Xu 521*8ff59090SHerbert Xu if (ctx->used) 522*8ff59090SHerbert Xu mask |= POLLIN | POLLRDNORM; 523*8ff59090SHerbert Xu 524*8ff59090SHerbert Xu if (skcipher_writable(sk)) 525*8ff59090SHerbert Xu mask |= POLLOUT | POLLWRNORM | POLLWRBAND; 526*8ff59090SHerbert Xu 527*8ff59090SHerbert Xu return mask; 528*8ff59090SHerbert Xu } 529*8ff59090SHerbert Xu 530*8ff59090SHerbert Xu static struct proto_ops algif_skcipher_ops = { 531*8ff59090SHerbert Xu .family = PF_ALG, 532*8ff59090SHerbert Xu 533*8ff59090SHerbert Xu .connect = sock_no_connect, 534*8ff59090SHerbert Xu .socketpair = sock_no_socketpair, 535*8ff59090SHerbert Xu .getname = sock_no_getname, 536*8ff59090SHerbert Xu .ioctl = sock_no_ioctl, 537*8ff59090SHerbert Xu .listen = sock_no_listen, 538*8ff59090SHerbert Xu .shutdown = sock_no_shutdown, 539*8ff59090SHerbert Xu .getsockopt = sock_no_getsockopt, 540*8ff59090SHerbert Xu .mmap = sock_no_mmap, 541*8ff59090SHerbert Xu .bind = sock_no_bind, 542*8ff59090SHerbert Xu .accept = sock_no_accept, 543*8ff59090SHerbert Xu .setsockopt = sock_no_setsockopt, 544*8ff59090SHerbert Xu 545*8ff59090SHerbert Xu .release = af_alg_release, 546*8ff59090SHerbert Xu .sendmsg = skcipher_sendmsg, 547*8ff59090SHerbert Xu .sendpage = skcipher_sendpage, 548*8ff59090SHerbert Xu .recvmsg = skcipher_recvmsg, 549*8ff59090SHerbert Xu .poll = skcipher_poll, 550*8ff59090SHerbert Xu }; 551*8ff59090SHerbert Xu 552*8ff59090SHerbert Xu static void *skcipher_bind(const char *name, u32 type, u32 mask) 553*8ff59090SHerbert Xu { 554*8ff59090SHerbert Xu return crypto_alloc_ablkcipher(name, type, mask); 555*8ff59090SHerbert Xu } 556*8ff59090SHerbert Xu 557*8ff59090SHerbert Xu static void skcipher_release(void *private) 558*8ff59090SHerbert Xu { 559*8ff59090SHerbert Xu crypto_free_ablkcipher(private); 560*8ff59090SHerbert Xu } 561*8ff59090SHerbert Xu 562*8ff59090SHerbert Xu static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen) 563*8ff59090SHerbert Xu { 564*8ff59090SHerbert Xu return crypto_ablkcipher_setkey(private, key, keylen); 565*8ff59090SHerbert Xu } 566*8ff59090SHerbert Xu 567*8ff59090SHerbert Xu static void skcipher_sock_destruct(struct sock *sk) 568*8ff59090SHerbert Xu { 569*8ff59090SHerbert Xu struct alg_sock *ask = alg_sk(sk); 570*8ff59090SHerbert Xu struct skcipher_ctx *ctx = ask->private; 571*8ff59090SHerbert Xu struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(&ctx->req); 572*8ff59090SHerbert Xu 573*8ff59090SHerbert Xu skcipher_free_sgl(sk); 574*8ff59090SHerbert Xu sock_kfree_s(sk, ctx->iv, crypto_ablkcipher_ivsize(tfm)); 575*8ff59090SHerbert Xu sock_kfree_s(sk, ctx, ctx->len); 576*8ff59090SHerbert Xu af_alg_release_parent(sk); 577*8ff59090SHerbert Xu } 578*8ff59090SHerbert Xu 579*8ff59090SHerbert Xu static int skcipher_accept_parent(void *private, struct sock *sk) 580*8ff59090SHerbert Xu { 581*8ff59090SHerbert Xu struct skcipher_ctx *ctx; 582*8ff59090SHerbert Xu struct alg_sock *ask = alg_sk(sk); 583*8ff59090SHerbert Xu unsigned int len = sizeof(*ctx) + crypto_ablkcipher_reqsize(private); 584*8ff59090SHerbert Xu 585*8ff59090SHerbert Xu ctx = sock_kmalloc(sk, len, GFP_KERNEL); 586*8ff59090SHerbert Xu if (!ctx) 587*8ff59090SHerbert Xu return -ENOMEM; 588*8ff59090SHerbert Xu 589*8ff59090SHerbert Xu ctx->iv = sock_kmalloc(sk, crypto_ablkcipher_ivsize(private), 590*8ff59090SHerbert Xu GFP_KERNEL); 591*8ff59090SHerbert Xu if (!ctx->iv) { 592*8ff59090SHerbert Xu sock_kfree_s(sk, ctx, len); 593*8ff59090SHerbert Xu return -ENOMEM; 594*8ff59090SHerbert Xu } 595*8ff59090SHerbert Xu 596*8ff59090SHerbert Xu memset(ctx->iv, 0, crypto_ablkcipher_ivsize(private)); 597*8ff59090SHerbert Xu 598*8ff59090SHerbert Xu INIT_LIST_HEAD(&ctx->tsgl); 599*8ff59090SHerbert Xu ctx->len = len; 600*8ff59090SHerbert Xu ctx->used = 0; 601*8ff59090SHerbert Xu ctx->more = 0; 602*8ff59090SHerbert Xu ctx->merge = 0; 603*8ff59090SHerbert Xu ctx->enc = 0; 604*8ff59090SHerbert Xu af_alg_init_completion(&ctx->completion); 605*8ff59090SHerbert Xu 606*8ff59090SHerbert Xu ask->private = ctx; 607*8ff59090SHerbert Xu 608*8ff59090SHerbert Xu ablkcipher_request_set_tfm(&ctx->req, private); 609*8ff59090SHerbert Xu ablkcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG, 610*8ff59090SHerbert Xu af_alg_complete, &ctx->completion); 611*8ff59090SHerbert Xu 612*8ff59090SHerbert Xu sk->sk_destruct = skcipher_sock_destruct; 613*8ff59090SHerbert Xu 614*8ff59090SHerbert Xu return 0; 615*8ff59090SHerbert Xu } 616*8ff59090SHerbert Xu 617*8ff59090SHerbert Xu static const struct af_alg_type algif_type_skcipher = { 618*8ff59090SHerbert Xu .bind = skcipher_bind, 619*8ff59090SHerbert Xu .release = skcipher_release, 620*8ff59090SHerbert Xu .setkey = skcipher_setkey, 621*8ff59090SHerbert Xu .accept = skcipher_accept_parent, 622*8ff59090SHerbert Xu .ops = &algif_skcipher_ops, 623*8ff59090SHerbert Xu .name = "skcipher", 624*8ff59090SHerbert Xu .owner = THIS_MODULE 625*8ff59090SHerbert Xu }; 626*8ff59090SHerbert Xu 627*8ff59090SHerbert Xu static int __init algif_skcipher_init(void) 628*8ff59090SHerbert Xu { 629*8ff59090SHerbert Xu return af_alg_register_type(&algif_type_skcipher); 630*8ff59090SHerbert Xu } 631*8ff59090SHerbert Xu 632*8ff59090SHerbert Xu static void __exit algif_skcipher_exit(void) 633*8ff59090SHerbert Xu { 634*8ff59090SHerbert Xu int err = af_alg_unregister_type(&algif_type_skcipher); 635*8ff59090SHerbert Xu BUG_ON(err); 636*8ff59090SHerbert Xu } 637*8ff59090SHerbert Xu 638*8ff59090SHerbert Xu module_init(algif_skcipher_init); 639*8ff59090SHerbert Xu module_exit(algif_skcipher_exit); 640*8ff59090SHerbert Xu MODULE_LICENSE("GPL"); 641