aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto
diff options
context:
space:
mode:
authorLars Persson <lars.persson@axis.com>2019-01-23 06:59:44 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2019-02-01 01:42:04 -0500
commit48ef0908b81cc6b92ec8b157bb78ce2c4eddd7c7 (patch)
tree5909d9af246ada3db109deb517caaed0532948af /drivers/crypto
parent0d1d482416002791a705e7acef55edcd989facd2 (diff)
crypto: axis - support variable AEAD tag length
The implementation assumed that the client always wants the whole 16 byte AES-GCM tag. Now we respect the requested authentication tag size fetched using crypto_aead_authsize(). Signed-off-by: Lars Persson <larper@axis.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto')
-rw-r--r--drivers/crypto/axis/artpec6_crypto.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/drivers/crypto/axis/artpec6_crypto.c b/drivers/crypto/axis/artpec6_crypto.c
index e8a57b9e1c7a..5089ad2c49f9 100644
--- a/drivers/crypto/axis/artpec6_crypto.c
+++ b/drivers/crypto/axis/artpec6_crypto.c
@@ -1907,7 +1907,7 @@ static int artpec6_crypto_prepare_aead(struct aead_request *areq)
1907 /* For the decryption, cryptlen includes the tag. */ 1907 /* For the decryption, cryptlen includes the tag. */
1908 input_length = areq->cryptlen; 1908 input_length = areq->cryptlen;
1909 if (req_ctx->decrypt) 1909 if (req_ctx->decrypt)
1910 input_length -= AES_BLOCK_SIZE; 1910 input_length -= crypto_aead_authsize(cipher);
1911 1911
1912 /* Prepare the context buffer */ 1912 /* Prepare the context buffer */
1913 req_ctx->hw_ctx.aad_length_bits = 1913 req_ctx->hw_ctx.aad_length_bits =
@@ -1972,7 +1972,7 @@ static int artpec6_crypto_prepare_aead(struct aead_request *areq)
1972 size_t output_len = areq->cryptlen; 1972 size_t output_len = areq->cryptlen;
1973 1973
1974 if (req_ctx->decrypt) 1974 if (req_ctx->decrypt)
1975 output_len -= AES_BLOCK_SIZE; 1975 output_len -= crypto_aead_authsize(cipher);
1976 1976
1977 artpec6_crypto_walk_init(&walk, areq->dst); 1977 artpec6_crypto_walk_init(&walk, areq->dst);
1978 1978
@@ -2001,19 +2001,32 @@ static int artpec6_crypto_prepare_aead(struct aead_request *areq)
2001 * the output ciphertext. For decryption it is put in a context 2001 * the output ciphertext. For decryption it is put in a context
2002 * buffer for later compare against the input tag. 2002 * buffer for later compare against the input tag.
2003 */ 2003 */
2004 count = AES_BLOCK_SIZE;
2005 2004
2006 if (req_ctx->decrypt) { 2005 if (req_ctx->decrypt) {
2007 ret = artpec6_crypto_setup_in_descr(common, 2006 ret = artpec6_crypto_setup_in_descr(common,
2008 req_ctx->decryption_tag, count, false); 2007 req_ctx->decryption_tag, AES_BLOCK_SIZE, false);
2009 if (ret) 2008 if (ret)
2010 return ret; 2009 return ret;
2011 2010
2012 } else { 2011 } else {
2012 /* For encryption the requested tag size may be smaller
2013 * than the hardware's generated tag.
2014 */
2015 size_t authsize = crypto_aead_authsize(cipher);
2016
2013 ret = artpec6_crypto_setup_sg_descrs_in(common, &walk, 2017 ret = artpec6_crypto_setup_sg_descrs_in(common, &walk,
2014 count); 2018 authsize);
2015 if (ret) 2019 if (ret)
2016 return ret; 2020 return ret;
2021
2022 if (authsize < AES_BLOCK_SIZE) {
2023 count = AES_BLOCK_SIZE - authsize;
2024 ret = artpec6_crypto_setup_in_descr(common,
2025 ac->pad_buffer,
2026 count, false);
2027 if (ret)
2028 return ret;
2029 }
2017 } 2030 }
2018 2031
2019 } 2032 }
@@ -2174,27 +2187,29 @@ static void artpec6_crypto_complete_aead(struct crypto_async_request *req)
2174 /* Verify GCM hashtag. */ 2187 /* Verify GCM hashtag. */
2175 struct aead_request *areq = container_of(req, 2188 struct aead_request *areq = container_of(req,
2176 struct aead_request, base); 2189 struct aead_request, base);
2190 struct crypto_aead *aead = crypto_aead_reqtfm(areq);
2177 struct artpec6_crypto_aead_req_ctx *req_ctx = aead_request_ctx(areq); 2191 struct artpec6_crypto_aead_req_ctx *req_ctx = aead_request_ctx(areq);
2178 2192
2179 if (req_ctx->decrypt) { 2193 if (req_ctx->decrypt) {
2180 u8 input_tag[AES_BLOCK_SIZE]; 2194 u8 input_tag[AES_BLOCK_SIZE];
2195 unsigned int authsize = crypto_aead_authsize(aead);
2181 2196
2182 sg_pcopy_to_buffer(areq->src, 2197 sg_pcopy_to_buffer(areq->src,
2183 sg_nents(areq->src), 2198 sg_nents(areq->src),
2184 input_tag, 2199 input_tag,
2185 AES_BLOCK_SIZE, 2200 authsize,
2186 areq->assoclen + areq->cryptlen - 2201 areq->assoclen + areq->cryptlen -
2187 AES_BLOCK_SIZE); 2202 authsize);
2188 2203
2189 if (memcmp(req_ctx->decryption_tag, 2204 if (memcmp(req_ctx->decryption_tag,
2190 input_tag, 2205 input_tag,
2191 AES_BLOCK_SIZE)) { 2206 authsize)) {
2192 pr_debug("***EBADMSG:\n"); 2207 pr_debug("***EBADMSG:\n");
2193 print_hex_dump_debug("ref:", DUMP_PREFIX_ADDRESS, 32, 1, 2208 print_hex_dump_debug("ref:", DUMP_PREFIX_ADDRESS, 32, 1,
2194 input_tag, AES_BLOCK_SIZE, true); 2209 input_tag, authsize, true);
2195 print_hex_dump_debug("out:", DUMP_PREFIX_ADDRESS, 32, 1, 2210 print_hex_dump_debug("out:", DUMP_PREFIX_ADDRESS, 32, 1,
2196 req_ctx->decryption_tag, 2211 req_ctx->decryption_tag,
2197 AES_BLOCK_SIZE, true); 2212 authsize, true);
2198 2213
2199 result = -EBADMSG; 2214 result = -EBADMSG;
2200 } 2215 }