crypto/skcipher.c
Source file repositories/reference/linux-study-clean/crypto/skcipher.c
File Facts
- System
- Linux kernel
- Corpus path
crypto/skcipher.c- Extension
.c- Size
- 24424 bytes
- Lines
- 887
- Domain
- Kernel Services
- Bucket
- crypto
- Inferred role
- Kernel Services: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.
- Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
crypto/internal/aead.hcrypto/internal/cipher.hcrypto/internal/skcipher.hcrypto/scatterwalk.hlinux/bug.hlinux/cryptouser.hlinux/err.hlinux/kernel.hlinux/mm.hlinux/module.hlinux/seq_file.hlinux/slab.hlinux/string.hlinux/string_choices.hnet/netlink.hskcipher.h
Detected Declarations
function skcipher_walk_gfpfunction skcipher_walk_donefunction skcipher_next_slowfunction skcipher_next_copyfunction skcipher_next_fastfunction skcipher_walk_nextfunction skcipher_copy_ivfunction skcipher_walk_firstfunction skcipher_walk_virtfunction skcipher_walk_aead_commonfunction skcipher_walk_aead_encryptfunction skcipher_walk_aead_decryptfunction skcipher_set_needkeyfunction skcipher_setkey_unalignedfunction crypto_skcipher_setkeyfunction crypto_skcipher_encryptfunction crypto_skcipher_decryptfunction crypto_lskcipher_exportfunction crypto_lskcipher_importfunction skcipher_noexportfunction skcipher_noimportfunction crypto_skcipher_exportfunction crypto_skcipher_importfunction crypto_skcipher_exit_tfmfunction crypto_skcipher_init_tfmfunction crypto_skcipher_extsizefunction crypto_skcipher_free_instancefunction crypto_skcipher_showfunction crypto_skcipher_reportfunction crypto_grab_skcipherfunction crypto_has_skcipherfunction skcipher_prepare_alg_commonfunction skcipher_prepare_algfunction crypto_register_skcipherfunction crypto_unregister_skcipherfunction crypto_register_skciphersfunction crypto_unregister_skciphersfunction skcipher_register_instancefunction skcipher_setkey_simplefunction skcipher_init_tfm_simplefunction skcipher_exit_tfm_simplefunction skcipher_free_instance_simpleexport skcipher_walk_doneexport skcipher_walk_virtexport skcipher_walk_aead_encryptexport skcipher_walk_aead_decryptexport crypto_skcipher_setkeyexport crypto_skcipher_encrypt
Annotated Snippet
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 (!((unsigned long)walk->buffer | (unsigned long)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((unsigned long)walk->page);
out:
return res;
}
EXPORT_SYMBOL_GPL(skcipher_walk_done);
static int skcipher_next_slow(struct skcipher_walk *walk, unsigned int bsize)
{
unsigned alignmask = walk->alignmask;
unsigned n;
void *buffer;
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));
buffer = kzalloc(n, skcipher_walk_gfp(walk));
if (!buffer)
return skcipher_walk_done(walk, -ENOMEM);
walk->buffer = buffer;
}
buffer = PTR_ALIGN(buffer, alignmask + 1);
memcpy_from_scatterwalk(buffer, &walk->in, bsize);
walk->out.__addr = buffer;
walk->in.__addr = walk->out.addr;
walk->nbytes = bsize;
walk->flags |= SKCIPHER_WALK_SLOW;
return 0;
}
static int skcipher_next_copy(struct skcipher_walk *walk)
{
void *tmp = walk->page;
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.
*/
Annotation
- Immediate include surface: `crypto/internal/aead.h`, `crypto/internal/cipher.h`, `crypto/internal/skcipher.h`, `crypto/scatterwalk.h`, `linux/bug.h`, `linux/cryptouser.h`, `linux/err.h`, `linux/kernel.h`.
- Detected declarations: `function skcipher_walk_gfp`, `function skcipher_walk_done`, `function skcipher_next_slow`, `function skcipher_next_copy`, `function skcipher_next_fast`, `function skcipher_walk_next`, `function skcipher_copy_iv`, `function skcipher_walk_first`, `function skcipher_walk_virt`, `function skcipher_walk_aead_common`.
- Atlas domain: Kernel Services / crypto.
- Implementation status: integration implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.