⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 padlock-aes.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	ctx->cword.decrypt.ksize = ctx->cword.encrypt.ksize;	/* Don't generate extended keys if the hardware can do it. */	if (aes_hw_extkey_available(key_len))		return 0;	ctx->D = ctx->d_data;	ctx->cword.encrypt.keygen = 1;	ctx->cword.decrypt.keygen = 1;	switch (key_len) {	case 16:		t = E_KEY[3];		for (i = 0; i < 10; ++i)			loop4 (i);		break;	case 24:		E_KEY[4] = le32_to_cpu(key[4]);		t = E_KEY[5] = le32_to_cpu(key[5]);		for (i = 0; i < 8; ++i)			loop6 (i);		break;	case 32:		E_KEY[4] = le32_to_cpu(key[4]);		E_KEY[5] = le32_to_cpu(key[5]);		E_KEY[6] = le32_to_cpu(key[6]);		t = E_KEY[7] = le32_to_cpu(key[7]);		for (i = 0; i < 7; ++i)			loop8 (i);		break;	}	D_KEY[0] = E_KEY[0];	D_KEY[1] = E_KEY[1];	D_KEY[2] = E_KEY[2];	D_KEY[3] = E_KEY[3];	for (i = 4; i < key_len + 24; ++i) {		imix_col (D_KEY[i], E_KEY[i]);	}	/* PadLock needs a different format of the decryption key. */	rounds = 10 + (key_len - 16) / 4;	for (i = 0; i < rounds; i++) {		P[((i + 1) * 4) + 0] = D_KEY[((rounds - i - 1) * 4) + 0];		P[((i + 1) * 4) + 1] = D_KEY[((rounds - i - 1) * 4) + 1];		P[((i + 1) * 4) + 2] = D_KEY[((rounds - i - 1) * 4) + 2];		P[((i + 1) * 4) + 3] = D_KEY[((rounds - i - 1) * 4) + 3];	}	P[0] = E_KEY[(rounds * 4) + 0];	P[1] = E_KEY[(rounds * 4) + 1];	P[2] = E_KEY[(rounds * 4) + 2];	P[3] = E_KEY[(rounds * 4) + 3];	memcpy(D_KEY, P, AES_EXTENDED_KEY_SIZE_B);	return 0;}/* ====== Encryption/decryption routines ====== *//* These are the real call to PadLock. */static inline void padlock_xcrypt(const u8 *input, u8 *output, void *key,				  void *control_word){	asm volatile (".byte 0xf3,0x0f,0xa7,0xc8"	/* rep xcryptecb */		      : "+S"(input), "+D"(output)		      : "d"(control_word), "b"(key), "c"(1));}static void aes_crypt_copy(const u8 *in, u8 *out, u32 *key, struct cword *cword){	u8 buf[AES_BLOCK_SIZE * 2 + PADLOCK_ALIGNMENT - 1];	u8 *tmp = PTR_ALIGN(&buf[0], PADLOCK_ALIGNMENT);	memcpy(tmp, in, AES_BLOCK_SIZE);	padlock_xcrypt(tmp, out, key, cword);}static inline void aes_crypt(const u8 *in, u8 *out, u32 *key,			     struct cword *cword){	asm volatile ("pushfl; popfl");	/* padlock_xcrypt requires at least two blocks of data. */	if (unlikely(!(((unsigned long)in ^ (PAGE_SIZE - AES_BLOCK_SIZE)) &		       (PAGE_SIZE - 1)))) {		aes_crypt_copy(in, out, key, cword);		return;	}	padlock_xcrypt(in, out, key, cword);}static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key,				      void *control_word, u32 count){	if (count == 1) {		aes_crypt(input, output, key, control_word);		return;	}	asm volatile ("pushfl; popfl");		/* enforce key reload. */	asm volatile ("test $1, %%cl;"		      "je 1f;"		      "lea -1(%%ecx), %%eax;"		      "mov $1, %%ecx;"		      ".byte 0xf3,0x0f,0xa7,0xc8;"	/* rep xcryptecb */		      "mov %%eax, %%ecx;"		      "1:"		      ".byte 0xf3,0x0f,0xa7,0xc8"	/* rep xcryptecb */		      : "+S"(input), "+D"(output)		      : "d"(control_word), "b"(key), "c"(count)		      : "ax");}static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key,				     u8 *iv, void *control_word, u32 count){	/* Enforce key reload. */	asm volatile ("pushfl; popfl");	/* rep xcryptcbc */	asm volatile (".byte 0xf3,0x0f,0xa7,0xd0"		      : "+S" (input), "+D" (output), "+a" (iv)		      : "d" (control_word), "b" (key), "c" (count));	return iv;}static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in){	struct aes_ctx *ctx = aes_ctx(tfm);	aes_crypt(in, out, ctx->E, &ctx->cword.encrypt);}static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in){	struct aes_ctx *ctx = aes_ctx(tfm);	aes_crypt(in, out, ctx->D, &ctx->cword.decrypt);}static struct crypto_alg aes_alg = {	.cra_name		=	"aes",	.cra_driver_name	=	"aes-padlock",	.cra_priority		=	PADLOCK_CRA_PRIORITY,	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,	.cra_blocksize		=	AES_BLOCK_SIZE,	.cra_ctxsize		=	sizeof(struct aes_ctx),	.cra_alignmask		=	PADLOCK_ALIGNMENT - 1,	.cra_module		=	THIS_MODULE,	.cra_list		=	LIST_HEAD_INIT(aes_alg.cra_list),	.cra_u			=	{		.cipher = {			.cia_min_keysize	=	AES_MIN_KEY_SIZE,			.cia_max_keysize	=	AES_MAX_KEY_SIZE,			.cia_setkey	   	= 	aes_set_key,			.cia_encrypt	 	=	aes_encrypt,			.cia_decrypt	  	=	aes_decrypt,		}	}};static int ecb_aes_encrypt(struct blkcipher_desc *desc,			   struct scatterlist *dst, struct scatterlist *src,			   unsigned int nbytes){	struct aes_ctx *ctx = blk_aes_ctx(desc->tfm);	struct blkcipher_walk walk;	int err;	blkcipher_walk_init(&walk, dst, src, nbytes);	err = blkcipher_walk_virt(desc, &walk);	while ((nbytes = walk.nbytes)) {		padlock_xcrypt_ecb(walk.src.virt.addr, walk.dst.virt.addr,				   ctx->E, &ctx->cword.encrypt,				   nbytes / AES_BLOCK_SIZE);		nbytes &= AES_BLOCK_SIZE - 1;		err = blkcipher_walk_done(desc, &walk, nbytes);	}	return err;}static int ecb_aes_decrypt(struct blkcipher_desc *desc,			   struct scatterlist *dst, struct scatterlist *src,			   unsigned int nbytes){	struct aes_ctx *ctx = blk_aes_ctx(desc->tfm);	struct blkcipher_walk walk;	int err;	blkcipher_walk_init(&walk, dst, src, nbytes);	err = blkcipher_walk_virt(desc, &walk);	while ((nbytes = walk.nbytes)) {		padlock_xcrypt_ecb(walk.src.virt.addr, walk.dst.virt.addr,				   ctx->D, &ctx->cword.decrypt,				   nbytes / AES_BLOCK_SIZE);		nbytes &= AES_BLOCK_SIZE - 1;		err = blkcipher_walk_done(desc, &walk, nbytes);	}	return err;}static struct crypto_alg ecb_aes_alg = {	.cra_name		=	"ecb(aes)",	.cra_driver_name	=	"ecb-aes-padlock",	.cra_priority		=	PADLOCK_COMPOSITE_PRIORITY,	.cra_flags		=	CRYPTO_ALG_TYPE_BLKCIPHER,	.cra_blocksize		=	AES_BLOCK_SIZE,	.cra_ctxsize		=	sizeof(struct aes_ctx),	.cra_alignmask		=	PADLOCK_ALIGNMENT - 1,	.cra_type		=	&crypto_blkcipher_type,	.cra_module		=	THIS_MODULE,	.cra_list		=	LIST_HEAD_INIT(ecb_aes_alg.cra_list),	.cra_u			=	{		.blkcipher = {			.min_keysize		=	AES_MIN_KEY_SIZE,			.max_keysize		=	AES_MAX_KEY_SIZE,			.setkey	   		= 	aes_set_key,			.encrypt		=	ecb_aes_encrypt,			.decrypt		=	ecb_aes_decrypt,		}	}};static int cbc_aes_encrypt(struct blkcipher_desc *desc,			   struct scatterlist *dst, struct scatterlist *src,			   unsigned int nbytes){	struct aes_ctx *ctx = blk_aes_ctx(desc->tfm);	struct blkcipher_walk walk;	int err;	blkcipher_walk_init(&walk, dst, src, nbytes);	err = blkcipher_walk_virt(desc, &walk);	while ((nbytes = walk.nbytes)) {		u8 *iv = padlock_xcrypt_cbc(walk.src.virt.addr,					    walk.dst.virt.addr, ctx->E,					    walk.iv, &ctx->cword.encrypt,					    nbytes / AES_BLOCK_SIZE);		memcpy(walk.iv, iv, AES_BLOCK_SIZE);		nbytes &= AES_BLOCK_SIZE - 1;		err = blkcipher_walk_done(desc, &walk, nbytes);	}	return err;}static int cbc_aes_decrypt(struct blkcipher_desc *desc,			   struct scatterlist *dst, struct scatterlist *src,			   unsigned int nbytes){	struct aes_ctx *ctx = blk_aes_ctx(desc->tfm);	struct blkcipher_walk walk;	int err;	blkcipher_walk_init(&walk, dst, src, nbytes);	err = blkcipher_walk_virt(desc, &walk);	while ((nbytes = walk.nbytes)) {		padlock_xcrypt_cbc(walk.src.virt.addr, walk.dst.virt.addr,				   ctx->D, walk.iv, &ctx->cword.decrypt,				   nbytes / AES_BLOCK_SIZE);		nbytes &= AES_BLOCK_SIZE - 1;		err = blkcipher_walk_done(desc, &walk, nbytes);	}	return err;}static struct crypto_alg cbc_aes_alg = {	.cra_name		=	"cbc(aes)",	.cra_driver_name	=	"cbc-aes-padlock",	.cra_priority		=	PADLOCK_COMPOSITE_PRIORITY,	.cra_flags		=	CRYPTO_ALG_TYPE_BLKCIPHER,	.cra_blocksize		=	AES_BLOCK_SIZE,	.cra_ctxsize		=	sizeof(struct aes_ctx),	.cra_alignmask		=	PADLOCK_ALIGNMENT - 1,	.cra_type		=	&crypto_blkcipher_type,	.cra_module		=	THIS_MODULE,	.cra_list		=	LIST_HEAD_INIT(cbc_aes_alg.cra_list),	.cra_u			=	{		.blkcipher = {			.min_keysize		=	AES_MIN_KEY_SIZE,			.max_keysize		=	AES_MAX_KEY_SIZE,			.ivsize			=	AES_BLOCK_SIZE,			.setkey	   		= 	aes_set_key,			.encrypt		=	cbc_aes_encrypt,			.decrypt		=	cbc_aes_decrypt,		}	}};static int __init padlock_init(void){	int ret;	if (!cpu_has_xcrypt) {		printk(KERN_ERR PFX "VIA PadLock not detected.\n");		return -ENODEV;	}	if (!cpu_has_xcrypt_enabled) {		printk(KERN_ERR PFX "VIA PadLock detected, but not enabled. Hmm, strange...\n");		return -ENODEV;	}	gen_tabs();	if ((ret = crypto_register_alg(&aes_alg)))		goto aes_err;	if ((ret = crypto_register_alg(&ecb_aes_alg)))		goto ecb_aes_err;	if ((ret = crypto_register_alg(&cbc_aes_alg)))		goto cbc_aes_err;	printk(KERN_NOTICE PFX "Using VIA PadLock ACE for AES algorithm.\n");out:	return ret;cbc_aes_err:	crypto_unregister_alg(&ecb_aes_alg);ecb_aes_err:	crypto_unregister_alg(&aes_alg);aes_err:	printk(KERN_ERR PFX "VIA PadLock AES initialization failed.\n");	goto out;}static void __exit padlock_fini(void){	crypto_unregister_alg(&cbc_aes_alg);	crypto_unregister_alg(&ecb_aes_alg);	crypto_unregister_alg(&aes_alg);}module_init(padlock_init);module_exit(padlock_fini);MODULE_DESCRIPTION("VIA PadLock AES algorithm support");MODULE_LICENSE("GPL");MODULE_AUTHOR("Michal Ludvig");MODULE_ALIAS("aes");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -