aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLEROY Christophe <christophe.leroy@c-s.fr>2018-03-22 05:57:01 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2018-03-30 13:33:10 -0400
commit2b1227301a8e4729409694e323b72c064c47cb6b (patch)
treeee36a0f3a2a8bc2962a831f57ac7a226edc091ca
parent9def051018c08e65c532822749e857eb4b2e12e7 (diff)
crypto: talitos - fix IPsec cipher in length
For SEC 2.x+, cipher in length must contain only the ciphertext length. In case of using hardware ICV checking, the ICV length is provided via the "extent" field of the descriptor pointer. Cc: <stable@vger.kernel.org> # 4.8+ Fixes: 549bd8bc5987 ("crypto: talitos - Implement AEAD for SEC1 using HMAC_SNOOP_NO_AFEU") Reported-by: Horia Geantă <horia.geanta@nxp.com> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr> Tested-by: Horia Geantă <horia.geanta@nxp.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--drivers/crypto/talitos.c36
1 files changed, 20 insertions, 16 deletions
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 9a9788d7d5a8..3cfd53a00dc1 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1146,10 +1146,10 @@ next:
1146 return count; 1146 return count;
1147} 1147}
1148 1148
1149static int talitos_sg_map(struct device *dev, struct scatterlist *src, 1149static int talitos_sg_map_ext(struct device *dev, struct scatterlist *src,
1150 unsigned int len, struct talitos_edesc *edesc, 1150 unsigned int len, struct talitos_edesc *edesc,
1151 struct talitos_ptr *ptr, 1151 struct talitos_ptr *ptr, int sg_count,
1152 int sg_count, unsigned int offset, int tbl_off) 1152 unsigned int offset, int tbl_off, int elen)
1153{ 1153{
1154 struct talitos_private *priv = dev_get_drvdata(dev); 1154 struct talitos_private *priv = dev_get_drvdata(dev);
1155 bool is_sec1 = has_ftr_sec1(priv); 1155 bool is_sec1 = has_ftr_sec1(priv);
@@ -1158,6 +1158,7 @@ static int talitos_sg_map(struct device *dev, struct scatterlist *src,
1158 to_talitos_ptr(ptr, 0, 0, is_sec1); 1158 to_talitos_ptr(ptr, 0, 0, is_sec1);
1159 return 1; 1159 return 1;
1160 } 1160 }
1161 to_talitos_ptr_ext_set(ptr, elen, is_sec1);
1161 if (sg_count == 1) { 1162 if (sg_count == 1) {
1162 to_talitos_ptr(ptr, sg_dma_address(src) + offset, len, is_sec1); 1163 to_talitos_ptr(ptr, sg_dma_address(src) + offset, len, is_sec1);
1163 return sg_count; 1164 return sg_count;
@@ -1166,7 +1167,7 @@ static int talitos_sg_map(struct device *dev, struct scatterlist *src,
1166 to_talitos_ptr(ptr, edesc->dma_link_tbl + offset, len, is_sec1); 1167 to_talitos_ptr(ptr, edesc->dma_link_tbl + offset, len, is_sec1);
1167 return sg_count; 1168 return sg_count;
1168 } 1169 }
1169 sg_count = sg_to_link_tbl_offset(src, sg_count, offset, len, 1170 sg_count = sg_to_link_tbl_offset(src, sg_count, offset, len + elen,
1170 &edesc->link_tbl[tbl_off]); 1171 &edesc->link_tbl[tbl_off]);
1171 if (sg_count == 1) { 1172 if (sg_count == 1) {
1172 /* Only one segment now, so no link tbl needed*/ 1173 /* Only one segment now, so no link tbl needed*/
@@ -1180,6 +1181,15 @@ static int talitos_sg_map(struct device *dev, struct scatterlist *src,
1180 return sg_count; 1181 return sg_count;
1181} 1182}
1182 1183
1184static int talitos_sg_map(struct device *dev, struct scatterlist *src,
1185 unsigned int len, struct talitos_edesc *edesc,
1186 struct talitos_ptr *ptr, int sg_count,
1187 unsigned int offset, int tbl_off)
1188{
1189 return talitos_sg_map_ext(dev, src, len, edesc, ptr, sg_count, offset,
1190 tbl_off, 0);
1191}
1192
1183/* 1193/*
1184 * fill in and submit ipsec_esp descriptor 1194 * fill in and submit ipsec_esp descriptor
1185 */ 1195 */
@@ -1197,7 +1207,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
1197 unsigned int ivsize = crypto_aead_ivsize(aead); 1207 unsigned int ivsize = crypto_aead_ivsize(aead);
1198 int tbl_off = 0; 1208 int tbl_off = 0;
1199 int sg_count, ret; 1209 int sg_count, ret;
1200 int sg_link_tbl_len; 1210 int elen = 0;
1201 bool sync_needed = false; 1211 bool sync_needed = false;
1202 struct talitos_private *priv = dev_get_drvdata(dev); 1212 struct talitos_private *priv = dev_get_drvdata(dev);
1203 bool is_sec1 = has_ftr_sec1(priv); 1213 bool is_sec1 = has_ftr_sec1(priv);
@@ -1239,17 +1249,11 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
1239 * extent is bytes of HMAC postpended to ciphertext, 1249 * extent is bytes of HMAC postpended to ciphertext,
1240 * typically 12 for ipsec 1250 * typically 12 for ipsec
1241 */ 1251 */
1242 sg_link_tbl_len = cryptlen; 1252 if (is_ipsec_esp && (desc->hdr & DESC_HDR_MODE1_MDEU_CICV))
1243 1253 elen = authsize;
1244 if (is_ipsec_esp) {
1245 to_talitos_ptr_ext_set(&desc->ptr[4], authsize, is_sec1);
1246
1247 if (desc->hdr & DESC_HDR_MODE1_MDEU_CICV)
1248 sg_link_tbl_len += authsize;
1249 }
1250 1254
1251 ret = talitos_sg_map(dev, areq->src, sg_link_tbl_len, edesc, 1255 ret = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, &desc->ptr[4],
1252 &desc->ptr[4], sg_count, areq->assoclen, tbl_off); 1256 sg_count, areq->assoclen, tbl_off, elen);
1253 1257
1254 if (ret > 1) { 1258 if (ret > 1) {
1255 tbl_off += ret; 1259 tbl_off += ret;