diff options
| author | Lars Persson <lars.persson@axis.com> | 2019-01-23 06:59:44 -0500 |
|---|---|---|
| committer | Herbert Xu <herbert@gondor.apana.org.au> | 2019-02-01 01:42:04 -0500 |
| commit | 48ef0908b81cc6b92ec8b157bb78ce2c4eddd7c7 (patch) | |
| tree | 5909d9af246ada3db109deb517caaed0532948af /drivers/crypto | |
| parent | 0d1d482416002791a705e7acef55edcd989facd2 (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.c | 35 |
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 | } |
