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

crypto: nx - Fixing NX data alignment with nx_sg list

In NX we need to pass always a 16 multiple size nx_sg_list to
co processor. Trim function handle with this assuring all nx_sg_lists
are 16 multiple size, although data was not being considerated when
crop was done. It was causing an unalignment between size of the list
and data, corrupting csbcpb fields returning a -23 H_ST_PARM error, or
invalid operation.

This patch fix this recalculating how much data should be put back
in to_process variable what assures the size of sg_list will be
correct with size of the data.

Signed-off-by: Leonidas S. Barbosa <leosilva@linux.vnet.ibm.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Leonidas Da Silva Barbosa and committed by
Herbert Xu
c3365ce1 21a6dd5b

+24 -4
+24 -4
drivers/crypto/nx/nx.c
··· 215 215 * @delta: is the amount we need to crop in order to bound the list. 216 216 * 217 217 */ 218 - static long int trim_sg_list(struct nx_sg *sg, struct nx_sg *end, unsigned int delta) 218 + static long int trim_sg_list(struct nx_sg *sg, 219 + struct nx_sg *end, 220 + unsigned int delta, 221 + unsigned int *nbytes) 219 222 { 223 + long int oplen; 224 + long int data_back; 225 + unsigned int is_delta = delta; 226 + 220 227 while (delta && end > sg) { 221 228 struct nx_sg *last = end - 1; 222 229 ··· 235 228 delta -= last->len; 236 229 } 237 230 } 238 - return (sg - end) * sizeof(struct nx_sg); 231 + 232 + /* There are cases where we need to crop list in order to make it 233 + * a block size multiple, but we also need to align data. In order to 234 + * that we need to calculate how much we need to put back to be 235 + * processed 236 + */ 237 + oplen = (sg - end) * sizeof(struct nx_sg); 238 + if (is_delta) { 239 + data_back = (abs(oplen) / AES_BLOCK_SIZE) * sg->len; 240 + data_back = *nbytes - (data_back & ~(AES_BLOCK_SIZE - 1)); 241 + *nbytes -= data_back; 242 + } 243 + 244 + return oplen; 239 245 } 240 246 241 247 /** ··· 350 330 /* these lengths should be negative, which will indicate to phyp that 351 331 * the input and output parameters are scatterlists, not linear 352 332 * buffers */ 353 - nx_ctx->op.inlen = trim_sg_list(nx_ctx->in_sg, nx_insg, delta); 354 - nx_ctx->op.outlen = trim_sg_list(nx_ctx->out_sg, nx_outsg, delta); 333 + nx_ctx->op.inlen = trim_sg_list(nx_ctx->in_sg, nx_insg, delta, nbytes); 334 + nx_ctx->op.outlen = trim_sg_list(nx_ctx->out_sg, nx_outsg, delta, nbytes); 355 335 356 336 return 0; 357 337 }