Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[CRYPTO] aead: Add givcrypt operations

This patch adds the underlying givcrypt operations for aead and associated
support elements. The rationale is identical to that of the skcipher
givcrypt operations, i.e., sometimes only the algorithm knows how the
IV should be generated.

A new request type aead_givcrypt_request is added which contains an
embedded aead_request structure with two new elements to support this
operation. The new elements are seq and giv. The seq field should
contain a strictly increasing 64-bit integer which may be used by
certain IV generators as an input value. The giv field will be used
to store the generated IV. It does not need to obey the alignment
requirements of the algorithm because it's not used during the operation.

The existing iv field must still be available as it will be used to store
intermediate IVs and the output IV if chaining is desired.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

+50
+7
crypto/aead.c
··· 77 77 return alg->cra_ctxsize; 78 78 } 79 79 80 + static int no_givdecrypt(struct aead_givcrypt_request *req) 81 + { 82 + return -ENOSYS; 83 + } 84 + 80 85 static int crypto_init_aead_ops(struct crypto_tfm *tfm, u32 type, u32 mask) 81 86 { 82 87 struct aead_alg *alg = &tfm->__crt_alg->cra_aead; ··· 93 88 crt->setkey = setkey; 94 89 crt->encrypt = alg->encrypt; 95 90 crt->decrypt = alg->decrypt; 91 + crt->givencrypt = alg->givencrypt; 92 + crt->givdecrypt = alg->givdecrypt ?: no_givdecrypt; 96 93 crt->ivsize = alg->ivsize; 97 94 crt->authsize = alg->maxauthsize; 98 95
+38
include/crypto/aead.h
··· 1 + /* 2 + * AEAD: Authenticated Encryption with Associated Data 3 + * 4 + * Copyright (c) 2007 Herbert Xu <herbert@gondor.apana.org.au> 5 + * 6 + * This program is free software; you can redistribute it and/or modify it 7 + * under the terms of the GNU General Public License as published by the Free 8 + * Software Foundation; either version 2 of the License, or (at your option) 9 + * any later version. 10 + * 11 + */ 12 + 13 + #ifndef _CRYPTO_AEAD_H 14 + #define _CRYPTO_AEAD_H 15 + 16 + #include <linux/crypto.h> 17 + #include <linux/kernel.h> 18 + 19 + /** 20 + * struct aead_givcrypt_request - AEAD request with IV generation 21 + * @seq: Sequence number for IV generation 22 + * @giv: Space for generated IV 23 + * @areq: The AEAD request itself 24 + */ 25 + struct aead_givcrypt_request { 26 + u64 seq; 27 + u8 *giv; 28 + 29 + struct aead_request areq; 30 + }; 31 + 32 + static inline struct crypto_aead *aead_givcrypt_reqtfm( 33 + struct aead_givcrypt_request *req) 34 + { 35 + return crypto_aead_reqtfm(&req->areq); 36 + } 37 + 38 + #endif /* _CRYPTO_AEAD_H */
+5
include/linux/crypto.h
··· 106 106 struct crypto_hash; 107 107 struct crypto_tfm; 108 108 struct crypto_type; 109 + struct aead_givcrypt_request; 109 110 struct skcipher_givcrypt_request; 110 111 111 112 typedef void (*crypto_completion_t)(struct crypto_async_request *req, int err); ··· 203 202 int (*setauthsize)(struct crypto_aead *tfm, unsigned int authsize); 204 203 int (*encrypt)(struct aead_request *req); 205 204 int (*decrypt)(struct aead_request *req); 205 + int (*givencrypt)(struct aead_givcrypt_request *req); 206 + int (*givdecrypt)(struct aead_givcrypt_request *req); 206 207 207 208 unsigned int ivsize; 208 209 unsigned int maxauthsize; ··· 351 348 unsigned int keylen); 352 349 int (*encrypt)(struct aead_request *req); 353 350 int (*decrypt)(struct aead_request *req); 351 + int (*givencrypt)(struct aead_givcrypt_request *req); 352 + int (*givdecrypt)(struct aead_givcrypt_request *req); 354 353 unsigned int ivsize; 355 354 unsigned int authsize; 356 355 unsigned int reqsize;