summaryrefslogtreecommitdiff
path: root/crypto/algif_aead.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-06-22 21:04:48 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2015-06-22 21:04:48 -0700
commit44d21c3f3a2ef2f58b18bda64c52c99e723f3f4a (patch)
tree5146cf96cb0dbd7121176d484417ab942c92dcd4 /crypto/algif_aead.c
parentefdfce2b7ff3205ba0fba10270b92b80bbc6187d (diff)
parentfe55dfdcdfabf160ab0c14617725c57c7a1facfc (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto update from Herbert Xu: "Here is the crypto update for 4.2: API: - Convert RNG interface to new style. - New AEAD interface with one SG list for AD and plain/cipher text. All external AEAD users have been converted. - New asymmetric key interface (akcipher). Algorithms: - Chacha20, Poly1305 and RFC7539 support. - New RSA implementation. - Jitter RNG. - DRBG is now seeded with both /dev/random and Jitter RNG. If kernel pool isn't ready then DRBG will be reseeded when it is. - DRBG is now the default crypto API RNG, replacing krng. - 842 compression (previously part of powerpc nx driver). Drivers: - Accelerated SHA-512 for arm64. - New Marvell CESA driver that supports DMA and more algorithms. - Updated powerpc nx 842 support. - Added support for SEC1 hardware to talitos" * git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (292 commits) crypto: marvell/cesa - remove COMPILE_TEST dependency crypto: algif_aead - Temporarily disable all AEAD algorithms crypto: af_alg - Forbid the use internal algorithms crypto: echainiv - Only hold RNG during initialisation crypto: seqiv - Add compatibility support without RNG crypto: eseqiv - Offer normal cipher functionality without RNG crypto: chainiv - Offer normal cipher functionality without RNG crypto: user - Add CRYPTO_MSG_DELRNG crypto: user - Move cryptouser.h to uapi crypto: rng - Do not free default RNG when it becomes unused crypto: skcipher - Allow givencrypt to be NULL crypto: sahara - propagate the error on clk_disable_unprepare() failure crypto: rsa - fix invalid select for AKCIPHER crypto: picoxcell - Update to the current clk API crypto: nx - Check for bogus firmware properties crypto: marvell/cesa - add DT bindings documentation crypto: marvell/cesa - add support for Kirkwood and Dove SoCs crypto: marvell/cesa - add support for Orion SoCs crypto: marvell/cesa - add allhwsupport module parameter crypto: marvell/cesa - add support for all armada SoCs ...
Diffstat (limited to 'crypto/algif_aead.c')
-rw-r--r--crypto/algif_aead.c70
1 files changed, 11 insertions, 59 deletions
diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
index 69abada22373..e0408a480d2f 100644
--- a/crypto/algif_aead.c
+++ b/crypto/algif_aead.c
@@ -13,6 +13,7 @@
* any later version.
*/
+#include <crypto/aead.h>
#include <crypto/scatterwalk.h>
#include <crypto/if_alg.h>
#include <linux/init.h>
@@ -71,7 +72,7 @@ static inline bool aead_sufficient_data(struct aead_ctx *ctx)
{
unsigned as = crypto_aead_authsize(crypto_aead_reqtfm(&ctx->aead_req));
- return (ctx->used >= (ctx->aead_assoclen + (ctx->enc ? 0 : as)));
+ return ctx->used >= ctx->aead_assoclen + as;
}
static void aead_put_sgl(struct sock *sk)
@@ -352,12 +353,8 @@ static int aead_recvmsg(struct socket *sock, struct msghdr *msg, size_t ignored,
struct sock *sk = sock->sk;
struct alg_sock *ask = alg_sk(sk);
struct aead_ctx *ctx = ask->private;
- unsigned bs = crypto_aead_blocksize(crypto_aead_reqtfm(&ctx->aead_req));
unsigned as = crypto_aead_authsize(crypto_aead_reqtfm(&ctx->aead_req));
struct aead_sg_list *sgl = &ctx->tsgl;
- struct scatterlist *sg = NULL;
- struct scatterlist assoc[ALG_MAX_PAGES];
- size_t assoclen = 0;
unsigned int i = 0;
int err = -EINVAL;
unsigned long used = 0;
@@ -406,23 +403,13 @@ static int aead_recvmsg(struct socket *sock, struct msghdr *msg, size_t ignored,
if (!aead_sufficient_data(ctx))
goto unlock;
+ outlen = used;
+
/*
* The cipher operation input data is reduced by the associated data
* length as this data is processed separately later on.
*/
- used -= ctx->aead_assoclen;
-
- if (ctx->enc) {
- /* round up output buffer to multiple of block size */
- outlen = ((used + bs - 1) / bs * bs);
- /* add the size needed for the auth tag to be created */
- outlen += as;
- } else {
- /* output data size is input without the authentication tag */
- outlen = used - as;
- /* round up output buffer to multiple of block size */
- outlen = ((outlen + bs - 1) / bs * bs);
- }
+ used -= ctx->aead_assoclen + (ctx->enc ? as : 0);
/* convert iovecs of output buffers into scatterlists */
while (iov_iter_count(&msg->msg_iter)) {
@@ -451,47 +438,11 @@ static int aead_recvmsg(struct socket *sock, struct msghdr *msg, size_t ignored,
if (usedpages < outlen)
goto unlock;
- sg_init_table(assoc, ALG_MAX_PAGES);
- assoclen = ctx->aead_assoclen;
- /*
- * Split scatterlist into two: first part becomes AD, second part
- * is plaintext / ciphertext. The first part is assigned to assoc
- * scatterlist. When this loop finishes, sg points to the start of the
- * plaintext / ciphertext.
- */
- for (i = 0; i < ctx->tsgl.cur; i++) {
- sg = sgl->sg + i;
- if (sg->length <= assoclen) {
- /* AD is larger than one page */
- sg_set_page(assoc + i, sg_page(sg),
- sg->length, sg->offset);
- assoclen -= sg->length;
- if (i >= ctx->tsgl.cur)
- goto unlock;
- } else if (!assoclen) {
- /* current page is to start of plaintext / ciphertext */
- if (i)
- /* AD terminates at page boundary */
- sg_mark_end(assoc + i - 1);
- else
- /* AD size is zero */
- sg_mark_end(assoc);
- break;
- } else {
- /* AD does not terminate at page boundary */
- sg_set_page(assoc + i, sg_page(sg),
- assoclen, sg->offset);
- sg_mark_end(assoc + i);
- /* plaintext / ciphertext starts after AD */
- sg->length -= assoclen;
- sg->offset += assoclen;
- break;
- }
- }
+ sg_mark_end(sgl->sg + sgl->cur - 1);
- aead_request_set_assoc(&ctx->aead_req, assoc, ctx->aead_assoclen);
- aead_request_set_crypt(&ctx->aead_req, sg, ctx->rsgl[0].sg, used,
- ctx->iv);
+ aead_request_set_crypt(&ctx->aead_req, sgl->sg, ctx->rsgl[0].sg,
+ used, ctx->iv);
+ aead_request_set_ad(&ctx->aead_req, ctx->aead_assoclen);
err = af_alg_wait_for_completion(ctx->enc ?
crypto_aead_encrypt(&ctx->aead_req) :
@@ -563,7 +514,8 @@ static struct proto_ops algif_aead_ops = {
static void *aead_bind(const char *name, u32 type, u32 mask)
{
- return crypto_alloc_aead(name, type, mask);
+ return crypto_alloc_aead(name, type | CRYPTO_ALG_AEAD_NEW,
+ mask | CRYPTO_ALG_AEAD_NEW);
}
static void aead_release(void *private)