crypto: keywrap - simplify code
The code is simplified by using two __be64 values for the operation instead of using two arrays of u8. This allows to get rid of the memory alignment code. In addition, the crypto_xor can be replaced with a native XOR operation. Finally, the definition of the variables is re-arranged such that the data structures come before simple variables to potentially reduce memory space. Signed-off-by: Stephan Mueller <smueller@chronox.de> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
		
							parent
							
								
									5b3f3a8bed
								
							
						
					
					
						commit
						9e49451d7a
					
				| @ -93,18 +93,10 @@ struct crypto_kw_ctx { | ||||
| 
 | ||||
| struct crypto_kw_block { | ||||
| #define SEMIBSIZE 8 | ||||
| 	u8 A[SEMIBSIZE]; | ||||
| 	u8 R[SEMIBSIZE]; | ||||
| 	__be64 A; | ||||
| 	__be64 R; | ||||
| }; | ||||
| 
 | ||||
| /* convert 64 bit integer into its string representation */ | ||||
| static inline void crypto_kw_cpu_to_be64(u64 val, u8 *buf) | ||||
| { | ||||
| 	__be64 *a = (__be64 *)buf; | ||||
| 
 | ||||
| 	*a = cpu_to_be64(val); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Fast forward the SGL to the "end" length minus SEMIBSIZE. | ||||
|  * The start in the SGL defined by the fast-forward is returned with | ||||
| @ -139,17 +131,10 @@ static int crypto_kw_decrypt(struct blkcipher_desc *desc, | ||||
| 	struct crypto_blkcipher *tfm = desc->tfm; | ||||
| 	struct crypto_kw_ctx *ctx = crypto_blkcipher_ctx(tfm); | ||||
| 	struct crypto_cipher *child = ctx->child; | ||||
| 
 | ||||
| 	unsigned long alignmask = max_t(unsigned long, SEMIBSIZE, | ||||
| 					crypto_cipher_alignmask(child)); | ||||
| 	unsigned int i; | ||||
| 
 | ||||
| 	u8 blockbuf[sizeof(struct crypto_kw_block) + alignmask]; | ||||
| 	struct crypto_kw_block *block = (struct crypto_kw_block *) | ||||
| 					PTR_ALIGN(blockbuf + 0, alignmask + 1); | ||||
| 
 | ||||
| 	u64 t = 6 * ((nbytes) >> 3); | ||||
| 	struct crypto_kw_block block; | ||||
| 	struct scatterlist *lsrc, *ldst; | ||||
| 	u64 t = 6 * ((nbytes) >> 3); | ||||
| 	unsigned int i; | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 	/*
 | ||||
| @ -160,7 +145,7 @@ static int crypto_kw_decrypt(struct blkcipher_desc *desc, | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	/* Place the IV into block A */ | ||||
| 	memcpy(block->A, desc->info, SEMIBSIZE); | ||||
| 	memcpy(&block.A, desc->info, SEMIBSIZE); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * src scatterlist is read-only. dst scatterlist is r/w. During the | ||||
| @ -171,32 +156,27 @@ static int crypto_kw_decrypt(struct blkcipher_desc *desc, | ||||
| 	ldst = dst; | ||||
| 
 | ||||
| 	for (i = 0; i < 6; i++) { | ||||
| 		u8 tbe_buffer[SEMIBSIZE + alignmask]; | ||||
| 		/* alignment for the crypto_xor and the _to_be64 operation */ | ||||
| 		u8 *tbe = PTR_ALIGN(tbe_buffer + 0, alignmask + 1); | ||||
| 		unsigned int tmp_nbytes = nbytes; | ||||
| 		struct scatter_walk src_walk, dst_walk; | ||||
| 		unsigned int tmp_nbytes = nbytes; | ||||
| 
 | ||||
| 		while (tmp_nbytes) { | ||||
| 			/* move pointer by tmp_nbytes in the SGL */ | ||||
| 			crypto_kw_scatterlist_ff(&src_walk, lsrc, tmp_nbytes); | ||||
| 			/* get the source block */ | ||||
| 			scatterwalk_copychunks(block->R, &src_walk, SEMIBSIZE, | ||||
| 			scatterwalk_copychunks(&block.R, &src_walk, SEMIBSIZE, | ||||
| 					       false); | ||||
| 
 | ||||
| 			/* perform KW operation: get counter as byte string */ | ||||
| 			crypto_kw_cpu_to_be64(t, tbe); | ||||
| 			/* perform KW operation: modify IV with counter */ | ||||
| 			crypto_xor(block->A, tbe, SEMIBSIZE); | ||||
| 			block.A ^= cpu_to_be64(t); | ||||
| 			t--; | ||||
| 			/* perform KW operation: decrypt block */ | ||||
| 			crypto_cipher_decrypt_one(child, (u8*)block, | ||||
| 						  (u8*)block); | ||||
| 			crypto_cipher_decrypt_one(child, (u8*)&block, | ||||
| 						  (u8*)&block); | ||||
| 
 | ||||
| 			/* move pointer by tmp_nbytes in the SGL */ | ||||
| 			crypto_kw_scatterlist_ff(&dst_walk, ldst, tmp_nbytes); | ||||
| 			/* Copy block->R into place */ | ||||
| 			scatterwalk_copychunks(block->R, &dst_walk, SEMIBSIZE, | ||||
| 			scatterwalk_copychunks(&block.R, &dst_walk, SEMIBSIZE, | ||||
| 					       true); | ||||
| 
 | ||||
| 			tmp_nbytes -= SEMIBSIZE; | ||||
| @ -208,11 +188,10 @@ static int crypto_kw_decrypt(struct blkcipher_desc *desc, | ||||
| 	} | ||||
| 
 | ||||
| 	/* Perform authentication check */ | ||||
| 	if (crypto_memneq("\xA6\xA6\xA6\xA6\xA6\xA6\xA6\xA6", block->A, | ||||
| 			  SEMIBSIZE)) | ||||
| 	if (block.A != cpu_to_be64(0xa6a6a6a6a6a6a6a6)) | ||||
| 		ret = -EBADMSG; | ||||
| 
 | ||||
| 	memzero_explicit(block, sizeof(struct crypto_kw_block)); | ||||
| 	memzero_explicit(&block, sizeof(struct crypto_kw_block)); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| @ -224,17 +203,10 @@ static int crypto_kw_encrypt(struct blkcipher_desc *desc, | ||||
| 	struct crypto_blkcipher *tfm = desc->tfm; | ||||
| 	struct crypto_kw_ctx *ctx = crypto_blkcipher_ctx(tfm); | ||||
| 	struct crypto_cipher *child = ctx->child; | ||||
| 
 | ||||
| 	unsigned long alignmask = max_t(unsigned long, SEMIBSIZE, | ||||
| 					crypto_cipher_alignmask(child)); | ||||
| 	unsigned int i; | ||||
| 
 | ||||
| 	u8 blockbuf[sizeof(struct crypto_kw_block) + alignmask]; | ||||
| 	struct crypto_kw_block *block = (struct crypto_kw_block *) | ||||
| 					PTR_ALIGN(blockbuf + 0, alignmask + 1); | ||||
| 
 | ||||
| 	u64 t = 1; | ||||
| 	struct crypto_kw_block block; | ||||
| 	struct scatterlist *lsrc, *ldst; | ||||
| 	u64 t = 1; | ||||
| 	unsigned int i; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Require at least 2 semiblocks (note, the 3rd semiblock that is | ||||
| @ -249,7 +221,7 @@ static int crypto_kw_encrypt(struct blkcipher_desc *desc, | ||||
| 	 * Place the predefined IV into block A -- for encrypt, the caller | ||||
| 	 * does not need to provide an IV, but he needs to fetch the final IV. | ||||
| 	 */ | ||||
| 	memcpy(block->A, "\xA6\xA6\xA6\xA6\xA6\xA6\xA6\xA6", SEMIBSIZE); | ||||
| 	block.A = cpu_to_be64(0xa6a6a6a6a6a6a6a6); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * src scatterlist is read-only. dst scatterlist is r/w. During the | ||||
| @ -260,30 +232,26 @@ static int crypto_kw_encrypt(struct blkcipher_desc *desc, | ||||
| 	ldst = dst; | ||||
| 
 | ||||
| 	for (i = 0; i < 6; i++) { | ||||
| 		u8 tbe_buffer[SEMIBSIZE + alignmask]; | ||||
| 		u8 *tbe = PTR_ALIGN(tbe_buffer + 0, alignmask + 1); | ||||
| 		unsigned int tmp_nbytes = nbytes; | ||||
| 		struct scatter_walk src_walk, dst_walk; | ||||
| 		unsigned int tmp_nbytes = nbytes; | ||||
| 
 | ||||
| 		scatterwalk_start(&src_walk, lsrc); | ||||
| 		scatterwalk_start(&dst_walk, ldst); | ||||
| 
 | ||||
| 		while (tmp_nbytes) { | ||||
| 			/* get the source block */ | ||||
| 			scatterwalk_copychunks(block->R, &src_walk, SEMIBSIZE, | ||||
| 			scatterwalk_copychunks(&block.R, &src_walk, SEMIBSIZE, | ||||
| 					       false); | ||||
| 
 | ||||
| 			/* perform KW operation: encrypt block */ | ||||
| 			crypto_cipher_encrypt_one(child, (u8 *)block, | ||||
| 						  (u8 *)block); | ||||
| 			/* perform KW operation: get counter as byte string */ | ||||
| 			crypto_kw_cpu_to_be64(t, tbe); | ||||
| 			crypto_cipher_encrypt_one(child, (u8 *)&block, | ||||
| 						  (u8 *)&block); | ||||
| 			/* perform KW operation: modify IV with counter */ | ||||
| 			crypto_xor(block->A, tbe, SEMIBSIZE); | ||||
| 			block.A ^= cpu_to_be64(t); | ||||
| 			t++; | ||||
| 
 | ||||
| 			/* Copy block->R into place */ | ||||
| 			scatterwalk_copychunks(block->R, &dst_walk, SEMIBSIZE, | ||||
| 			scatterwalk_copychunks(&block.R, &dst_walk, SEMIBSIZE, | ||||
| 					       true); | ||||
| 
 | ||||
| 			tmp_nbytes -= SEMIBSIZE; | ||||
| @ -295,9 +263,9 @@ static int crypto_kw_encrypt(struct blkcipher_desc *desc, | ||||
| 	} | ||||
| 
 | ||||
| 	/* establish the IV for the caller to pick up */ | ||||
| 	memcpy(desc->info, block->A, SEMIBSIZE); | ||||
| 	memcpy(desc->info, &block.A, SEMIBSIZE); | ||||
| 
 | ||||
| 	memzero_explicit(block, sizeof(struct crypto_kw_block)); | ||||
| 	memzero_explicit(&block, sizeof(struct crypto_kw_block)); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user