| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * algif_skcipher: User-space interface for skcipher algorithms |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * This file provides the user-space API for symmetric key ciphers. |
|---|
| 5 | 6 | * |
|---|
| 6 | 7 | * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au> |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 9 | | - * under the terms of the GNU General Public License as published by the Free |
|---|
| 10 | | - * Software Foundation; either version 2 of the License, or (at your option) |
|---|
| 11 | | - * any later version. |
|---|
| 12 | 8 | * |
|---|
| 13 | 9 | * The following concept of the memory management is used: |
|---|
| 14 | 10 | * |
|---|
| .. | .. |
|---|
| 60 | 56 | struct alg_sock *pask = alg_sk(psk); |
|---|
| 61 | 57 | struct af_alg_ctx *ctx = ask->private; |
|---|
| 62 | 58 | struct crypto_skcipher *tfm = pask->private; |
|---|
| 63 | | - unsigned int bs = crypto_skcipher_blocksize(tfm); |
|---|
| 59 | + unsigned int bs = crypto_skcipher_chunksize(tfm); |
|---|
| 64 | 60 | struct af_alg_async_req *areq; |
|---|
| 65 | 61 | int err = 0; |
|---|
| 66 | 62 | size_t len = 0; |
|---|
| 67 | 63 | |
|---|
| 68 | | - if (!ctx->used) { |
|---|
| 69 | | - err = af_alg_wait_for_data(sk, flags); |
|---|
| 64 | + if (!ctx->init || (ctx->more && ctx->used < bs)) { |
|---|
| 65 | + err = af_alg_wait_for_data(sk, flags, bs); |
|---|
| 70 | 66 | if (err) |
|---|
| 71 | 67 | return err; |
|---|
| 72 | 68 | } |
|---|
| .. | .. |
|---|
| 192 | 188 | .ioctl = sock_no_ioctl, |
|---|
| 193 | 189 | .listen = sock_no_listen, |
|---|
| 194 | 190 | .shutdown = sock_no_shutdown, |
|---|
| 195 | | - .getsockopt = sock_no_getsockopt, |
|---|
| 196 | 191 | .mmap = sock_no_mmap, |
|---|
| 197 | 192 | .bind = sock_no_bind, |
|---|
| 198 | 193 | .accept = sock_no_accept, |
|---|
| 199 | | - .setsockopt = sock_no_setsockopt, |
|---|
| 200 | 194 | |
|---|
| 201 | 195 | .release = af_alg_release, |
|---|
| 202 | 196 | .sendmsg = skcipher_sendmsg, |
|---|
| .. | .. |
|---|
| 285 | 279 | .ioctl = sock_no_ioctl, |
|---|
| 286 | 280 | .listen = sock_no_listen, |
|---|
| 287 | 281 | .shutdown = sock_no_shutdown, |
|---|
| 288 | | - .getsockopt = sock_no_getsockopt, |
|---|
| 289 | 282 | .mmap = sock_no_mmap, |
|---|
| 290 | 283 | .bind = sock_no_bind, |
|---|
| 291 | 284 | .accept = sock_no_accept, |
|---|
| 292 | | - .setsockopt = sock_no_setsockopt, |
|---|
| 293 | 285 | |
|---|
| 294 | 286 | .release = af_alg_release, |
|---|
| 295 | 287 | .sendmsg = skcipher_sendmsg_nokey, |
|---|
| .. | .. |
|---|
| 337 | 329 | ctx = sock_kmalloc(sk, len, GFP_KERNEL); |
|---|
| 338 | 330 | if (!ctx) |
|---|
| 339 | 331 | return -ENOMEM; |
|---|
| 332 | + memset(ctx, 0, len); |
|---|
| 340 | 333 | |
|---|
| 341 | 334 | ctx->iv = sock_kmalloc(sk, crypto_skcipher_ivsize(tfm), |
|---|
| 342 | 335 | GFP_KERNEL); |
|---|
| .. | .. |
|---|
| 344 | 337 | sock_kfree_s(sk, ctx, len); |
|---|
| 345 | 338 | return -ENOMEM; |
|---|
| 346 | 339 | } |
|---|
| 347 | | - |
|---|
| 348 | 340 | memset(ctx->iv, 0, crypto_skcipher_ivsize(tfm)); |
|---|
| 349 | 341 | |
|---|
| 350 | 342 | INIT_LIST_HEAD(&ctx->tsgl_list); |
|---|
| 351 | 343 | ctx->len = len; |
|---|
| 352 | | - ctx->used = 0; |
|---|
| 353 | | - atomic_set(&ctx->rcvused, 0); |
|---|
| 354 | | - ctx->more = 0; |
|---|
| 355 | | - ctx->merge = 0; |
|---|
| 356 | | - ctx->enc = 0; |
|---|
| 357 | 344 | crypto_init_wait(&ctx->wait); |
|---|
| 358 | 345 | |
|---|
| 359 | 346 | ask->private = ctx; |
|---|