struct crypto_spawn alg;
unsigned int noncesize;
unsigned int ivsize;
+ unsigned int countersize;
};
struct crypto_ctr_ctx {
unsigned long alignmask = crypto_cipher_alignmask(child);
u8 cblk[bsize + alignmask];
u8 *counterblk = (u8 *)ALIGN((unsigned long)cblk, alignmask + 1);
- unsigned int countersize;
int err;
blkcipher_walk_init(&walk, dst, src, nbytes);
memcpy(counterblk + ictx->noncesize, walk.iv, ictx->ivsize);
/* initialize counter portion of counter block */
- countersize = bsize - ictx->noncesize - ictx->ivsize;
- ctr_inc_quad(counterblk + (bsize - countersize), countersize);
+ ctr_inc_quad(counterblk + (bsize - ictx->countersize),
+ ictx->countersize);
while (walk.nbytes) {
if (walk.src.virt.addr == walk.dst.virt.addr)
nbytes = crypto_ctr_crypt_inplace(&walk, child,
counterblk,
- countersize);
+ ictx->countersize);
else
nbytes = crypto_ctr_crypt_segment(&walk, child,
counterblk,
- countersize);
+ ictx->countersize);
err = blkcipher_walk_done(desc, &walk, nbytes);
}
struct ctr_instance_ctx *ictx;
unsigned int noncesize;
unsigned int ivsize;
+ unsigned int countersize;
int err;
err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER);
if (err)
goto out_put_alg;
- /* verify size of nonce + iv + counter */
+ err = crypto_attr_u32(tb[4], &countersize);
+ if (err)
+ goto out_put_alg;
+
+ /* verify size of nonce + iv + counter
+ * counter must be >= 4 bytes.
+ */
err = -EINVAL;
- if ((noncesize + ivsize) >= alg->cra_blocksize)
+ if (((noncesize + ivsize + countersize) < alg->cra_blocksize) ||
+ ((noncesize + ivsize) > alg->cra_blocksize) ||
+ (countersize > alg->cra_blocksize) || (countersize < 4))
goto out_put_alg;
inst = kzalloc(sizeof(*inst) + sizeof(*ictx), GFP_KERNEL);
err = -ENAMETOOLONG;
if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME,
- "ctr(%s,%u,%u)", alg->cra_name, noncesize,
- ivsize) >= CRYPTO_MAX_ALG_NAME) {
+ "ctr(%s,%u,%u,%u)", alg->cra_name, noncesize,
+ ivsize, countersize) >= CRYPTO_MAX_ALG_NAME) {
goto err_free_inst;
}
if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME,
- "ctr(%s,%u,%u)", alg->cra_driver_name, noncesize,
- ivsize) >= CRYPTO_MAX_ALG_NAME) {
+ "ctr(%s,%u,%u,%u)", alg->cra_driver_name, noncesize,
+ ivsize, countersize) >= CRYPTO_MAX_ALG_NAME) {
goto err_free_inst;
}
ictx = crypto_instance_ctx(inst);
ictx->noncesize = noncesize;
ictx->ivsize = ivsize;
+ ictx->countersize = countersize;
err = crypto_init_spawn(&ictx->alg, alg, inst,
CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC);
AES_XTS_ENC_TEST_VECTORS);
test_cipher("xts(aes)", DECRYPT, aes_xts_dec_tv_template,
AES_XTS_DEC_TEST_VECTORS);
- test_cipher("ctr(aes,4,8)", ENCRYPT, aes_ctr_enc_tv_template,
+ test_cipher("ctr(aes,4,8,4)", ENCRYPT, aes_ctr_enc_tv_template,
AES_CTR_ENC_TEST_VECTORS);
- test_cipher("ctr(aes,4,8)", DECRYPT, aes_ctr_dec_tv_template,
+ test_cipher("ctr(aes,4,8,4)", DECRYPT, aes_ctr_dec_tv_template,
AES_CTR_DEC_TEST_VECTORS);
//CAST5
AES_XTS_ENC_TEST_VECTORS);
test_cipher("xts(aes)", DECRYPT, aes_xts_dec_tv_template,
AES_XTS_DEC_TEST_VECTORS);
- test_cipher("ctr(aes,4,8)", ENCRYPT, aes_ctr_enc_tv_template,
+ test_cipher("ctr(aes,4,8,4)", ENCRYPT, aes_ctr_enc_tv_template,
AES_CTR_ENC_TEST_VECTORS);
- test_cipher("ctr(aes,4,8)", DECRYPT, aes_ctr_dec_tv_template,
+ test_cipher("ctr(aes,4,8,4)", DECRYPT, aes_ctr_dec_tv_template,
AES_CTR_DEC_TEST_VECTORS);
break;