staticint riscv64_aes_setkey(struct crypto_aes_ctx *ctx, const u8 *key, unsignedint keylen)
{ /* * For now we just use the generic key expansion, for these reasons: * * - zvkned's key expansion instructions don't support AES-192. * So, non-zvkned fallback code would be needed anyway. * * - Users of AES in Linux usually don't change keys frequently. * So, key expansion isn't performance-critical. * * - For single-block AES exposed as a "cipher" algorithm, it's * necessary to use struct crypto_aes_ctx and initialize its 'key_dec' * field with the round keys for the Equivalent Inverse Cipher. This * is because with "cipher", decryption can be requested from a * context where the vector unit isn't usable, necessitating a * fallback to aes_decrypt(). But, zvkned can only generate and use * the normal round keys. Of course, it's preferable to not have * special code just for "cipher", as e.g. XTS also uses a * single-block AES encryption. It's simplest to just use * struct crypto_aes_ctx and aes_expandkey() everywhere.
*/ return aes_expandkey(ctx, key, keylen);
}
if (req->cryptlen < AES_BLOCK_SIZE) return -EINVAL;
err = skcipher_walk_virt(&walk, req, false); if (err) return err; /* * If the full message is available in one step, decrypt it in one call * to the CBC-CTS assembly function. This reduces overhead, especially * on short messages. Otherwise, fall back to doing CBC up to the last * two blocks, then invoke CTS just for the ciphertext stealing.
*/ if (unlikely(walk.nbytes != req->cryptlen)) {
cbc_len = round_down(req->cryptlen - AES_BLOCK_SIZE - 1,
AES_BLOCK_SIZE);
skcipher_walk_abort(&walk);
skcipher_request_set_tfm(&subreq, tfm);
skcipher_request_set_callback(&subreq,
skcipher_request_flags(req),
NULL, NULL);
skcipher_request_set_crypt(&subreq, req->src, req->dst,
cbc_len, req->iv);
err = riscv64_aes_cbc_crypt(&subreq, enc); if (err) return err;
dst = src = scatterwalk_ffwd(sg_src, req->src, cbc_len); if (req->dst != req->src)
dst = scatterwalk_ffwd(sg_dst, req->dst, cbc_len);
skcipher_request_set_crypt(&subreq, src, dst,
req->cryptlen - cbc_len, req->iv);
err = skcipher_walk_virt(&walk, &subreq, false); if (err) return err;
}
kernel_vector_begin();
aes_cbc_cts_crypt_zvkned(ctx, walk.src.virt.addr, walk.dst.virt.addr,
walk.nbytes, req->iv, enc);
kernel_vector_end(); return skcipher_walk_done(&walk, 0);
}
/* Get the low 32-bit word of the 128-bit big endian counter. */
ctr32 = get_unaligned_be32(req->iv + 12);
err = skcipher_walk_virt(&walk, req, false); while ((nbytes = walk.nbytes) != 0) { if (nbytes < walk.total) { /* Not the end yet, so keep the length block-aligned. */
nbytes = round_down(nbytes, AES_BLOCK_SIZE);
nblocks = nbytes / AES_BLOCK_SIZE;
} else { /* It's the end, so include any final partial block. */
nblocks = DIV_ROUND_UP(nbytes, AES_BLOCK_SIZE);
}
ctr32 += nblocks;
kernel_vector_begin(); if (ctr32 >= nblocks) { /* The low 32-bit word of the counter won't overflow. */
aes_ctr32_crypt_zvkned_zvkb(ctx, walk.src.virt.addr,
walk.dst.virt.addr, nbytes,
req->iv);
} else { /* * The low 32-bit word of the counter will overflow. * The assembly doesn't handle this case, so split the * operation into two at the point where the overflow * will occur. After the first part, add the carry bit.
*/
p1_nbytes = min_t(unsignedint, nbytes,
(nblocks - ctr32) * AES_BLOCK_SIZE);
aes_ctr32_crypt_zvkned_zvkb(ctx, walk.src.virt.addr,
walk.dst.virt.addr,
p1_nbytes, req->iv);
crypto_inc(req->iv, 12);
if (req->cryptlen < AES_BLOCK_SIZE) return -EINVAL;
/* Encrypt the IV with the tweak key to get the first tweak. */
kernel_vector_begin();
aes_encrypt_zvkned(&ctx->ctx2, req->iv, req->iv);
kernel_vector_end();
err = skcipher_walk_virt(&walk, req, false);
/* * If the message length isn't divisible by the AES block size and the * full message isn't available in one step of the scatterlist walk, * then separate off the last full block and the partial block. This * ensures that they are processed in the same call to the assembly * function, which is required for ciphertext stealing.
*/ if (unlikely(tail > 0 && walk.nbytes < walk.total)) {
skcipher_walk_abort(&walk);
¤ 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.0.15Bemerkung:
(vorverarbeitet am 2026-04-26)
¤
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.