if (!walk->buffer)
walk->buffer = walk->page;
buffer = walk->buffer; if (!buffer) { /* Min size for a buffer of bsize bytes aligned to alignmask */
n = bsize + (alignmask & ~(crypto_tfm_ctx_alignment() - 1));
scatterwalk_map(&walk->in);
memcpy(tmp, walk->in.addr, walk->nbytes);
scatterwalk_unmap(&walk->in); /* * walk->in is advanced later when the number of bytes actually * processed (which might be less than walk->nbytes) is known.
*/
/** * skcipher_walk_done() - finish one step of a skcipher_walk * @walk: the skcipher_walk * @res: number of bytes *not* processed (>= 0) from walk->nbytes, * or a -errno value to terminate the walk due to an error * * This function cleans up after one step of walking through the source and * destination scatterlists, and advances to the next step if applicable. * walk->nbytes is set to the number of bytes available in the next step, * walk->total is set to the new total number of bytes remaining, and * walk->{src,dst}.virt.addr is set to the next pair of data pointers. If there * is no more data, or if an error occurred (i.e. -errno return), then * walk->nbytes and walk->total are set to 0 and all resources owned by the * skcipher_walk are freed. * * Return: 0 or a -errno value. If @res was a -errno value then it will be * returned, but other errors may occur too.
*/ int skcipher_walk_done(struct skcipher_walk *walk, int res)
{ unsignedint n = walk->nbytes; /* num bytes processed this step */ unsignedint total = 0; /* new total remaining */
if (!n) goto finish;
if (likely(res >= 0)) {
n -= res; /* subtract num bytes *not* processed */
total = walk->total - n;
}
if (likely(!(walk->flags & (SKCIPHER_WALK_SLOW |
SKCIPHER_WALK_COPY |
SKCIPHER_WALK_DIFF)))) {
scatterwalk_advance(&walk->in, n);
} elseif (walk->flags & SKCIPHER_WALK_DIFF) {
scatterwalk_done_src(&walk->in, n);
} elseif (walk->flags & SKCIPHER_WALK_COPY) {
scatterwalk_advance(&walk->in, n);
scatterwalk_map(&walk->out);
memcpy(walk->out.addr, walk->page, n);
} else { /* SKCIPHER_WALK_SLOW */ if (res > 0) { /* * Didn't process all bytes. Either the algorithm is * broken, or this was the last step and it turned out * the message wasn't evenly divisible into blocks but * the algorithm requires it.
*/
res = -EINVAL;
total = 0;
} else
memcpy_to_scatterwalk(&walk->out, walk->out.addr, n); goto dst_done;
}
scatterwalk_done_dst(&walk->out, n);
dst_done:
if (res > 0)
res = 0;
walk->total = total;
walk->nbytes = 0;
if (total) { if (walk->flags & SKCIPHER_WALK_SLEEP)
cond_resched();
walk->flags &= ~(SKCIPHER_WALK_SLOW | SKCIPHER_WALK_COPY |
SKCIPHER_WALK_DIFF); return skcipher_walk_next(walk);
}
finish: /* Short-circuit for the common/fast path. */ if (!((unsignedlong)walk->buffer | (unsignedlong)walk->page)) goto out;
if (walk->iv != walk->oiv)
memcpy(walk->oiv, walk->iv, walk->ivsize); if (walk->buffer != walk->page)
kfree(walk->buffer); if (walk->page)
free_page((unsignedlong)walk->page);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.