forked from mirrors/linux
		
	crypto: ccree - add skcipher support
Add CryptoCell skcipher support Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
		
							parent
							
								
									4c3f97276e
								
							
						
					
					
						commit
						63ee04c8b4
					
				
					 7 changed files with 1339 additions and 2 deletions
				
			
		|  | @ -1,6 +1,6 @@ | ||||||
| # SPDX-License-Identifier: GPL-2.0
 | # SPDX-License-Identifier: GPL-2.0
 | ||||||
| 
 | 
 | ||||||
| obj-$(CONFIG_CRYPTO_DEV_CCREE) := ccree.o | obj-$(CONFIG_CRYPTO_DEV_CCREE) := ccree.o | ||||||
| ccree-y := cc_driver.o cc_buffer_mgr.o cc_request_mgr.o cc_ivgen.o cc_sram_mgr.o | ccree-y := cc_driver.o cc_buffer_mgr.o cc_request_mgr.o cc_cipher.o cc_ivgen.o cc_sram_mgr.o | ||||||
| ccree-$(CONFIG_DEBUG_FS) += cc_debugfs.o | ccree-$(CONFIG_DEBUG_FS) += cc_debugfs.o | ||||||
| ccree-$(CONFIG_PM) += cc_pm.o | ccree-$(CONFIG_PM) += cc_pm.o | ||||||
|  |  | ||||||
|  | @ -8,6 +8,7 @@ | ||||||
| 
 | 
 | ||||||
| #include "cc_buffer_mgr.h" | #include "cc_buffer_mgr.h" | ||||||
| #include "cc_lli_defs.h" | #include "cc_lli_defs.h" | ||||||
|  | #include "cc_cipher.h" | ||||||
| 
 | 
 | ||||||
| enum dma_buffer_type { | enum dma_buffer_type { | ||||||
| 	DMA_NULL_TYPE = -1, | 	DMA_NULL_TYPE = -1, | ||||||
|  | @ -347,6 +348,130 @@ static int cc_map_sg(struct device *dev, struct scatterlist *sg, | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void cc_unmap_cipher_request(struct device *dev, void *ctx, | ||||||
|  | 			     unsigned int ivsize, struct scatterlist *src, | ||||||
|  | 			     struct scatterlist *dst) | ||||||
|  | { | ||||||
|  | 	struct cipher_req_ctx *req_ctx = (struct cipher_req_ctx *)ctx; | ||||||
|  | 
 | ||||||
|  | 	if (req_ctx->gen_ctx.iv_dma_addr) { | ||||||
|  | 		dev_dbg(dev, "Unmapped iv: iv_dma_addr=%pad iv_size=%u\n", | ||||||
|  | 			&req_ctx->gen_ctx.iv_dma_addr, ivsize); | ||||||
|  | 		dma_unmap_single(dev, req_ctx->gen_ctx.iv_dma_addr, | ||||||
|  | 				 ivsize, | ||||||
|  | 				 req_ctx->is_giv ? DMA_BIDIRECTIONAL : | ||||||
|  | 				 DMA_TO_DEVICE); | ||||||
|  | 	} | ||||||
|  | 	/* Release pool */ | ||||||
|  | 	if (req_ctx->dma_buf_type == CC_DMA_BUF_MLLI && | ||||||
|  | 	    req_ctx->mlli_params.mlli_virt_addr) { | ||||||
|  | 		dma_pool_free(req_ctx->mlli_params.curr_pool, | ||||||
|  | 			      req_ctx->mlli_params.mlli_virt_addr, | ||||||
|  | 			      req_ctx->mlli_params.mlli_dma_addr); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	dma_unmap_sg(dev, src, req_ctx->in_nents, DMA_BIDIRECTIONAL); | ||||||
|  | 	dev_dbg(dev, "Unmapped req->src=%pK\n", sg_virt(src)); | ||||||
|  | 
 | ||||||
|  | 	if (src != dst) { | ||||||
|  | 		dma_unmap_sg(dev, dst, req_ctx->out_nents, DMA_BIDIRECTIONAL); | ||||||
|  | 		dev_dbg(dev, "Unmapped req->dst=%pK\n", sg_virt(dst)); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int cc_map_cipher_request(struct cc_drvdata *drvdata, void *ctx, | ||||||
|  | 			  unsigned int ivsize, unsigned int nbytes, | ||||||
|  | 			  void *info, struct scatterlist *src, | ||||||
|  | 			  struct scatterlist *dst, gfp_t flags) | ||||||
|  | { | ||||||
|  | 	struct cipher_req_ctx *req_ctx = (struct cipher_req_ctx *)ctx; | ||||||
|  | 	struct mlli_params *mlli_params = &req_ctx->mlli_params; | ||||||
|  | 	struct buff_mgr_handle *buff_mgr = drvdata->buff_mgr_handle; | ||||||
|  | 	struct device *dev = drvdata_to_dev(drvdata); | ||||||
|  | 	struct buffer_array sg_data; | ||||||
|  | 	u32 dummy = 0; | ||||||
|  | 	int rc = 0; | ||||||
|  | 	u32 mapped_nents = 0; | ||||||
|  | 
 | ||||||
|  | 	req_ctx->dma_buf_type = CC_DMA_BUF_DLLI; | ||||||
|  | 	mlli_params->curr_pool = NULL; | ||||||
|  | 	sg_data.num_of_buffers = 0; | ||||||
|  | 
 | ||||||
|  | 	/* Map IV buffer */ | ||||||
|  | 	if (ivsize) { | ||||||
|  | 		dump_byte_array("iv", (u8 *)info, ivsize); | ||||||
|  | 		req_ctx->gen_ctx.iv_dma_addr = | ||||||
|  | 			dma_map_single(dev, (void *)info, | ||||||
|  | 				       ivsize, | ||||||
|  | 				       req_ctx->is_giv ? DMA_BIDIRECTIONAL : | ||||||
|  | 				       DMA_TO_DEVICE); | ||||||
|  | 		if (dma_mapping_error(dev, req_ctx->gen_ctx.iv_dma_addr)) { | ||||||
|  | 			dev_err(dev, "Mapping iv %u B at va=%pK for DMA failed\n", | ||||||
|  | 				ivsize, info); | ||||||
|  | 			return -ENOMEM; | ||||||
|  | 		} | ||||||
|  | 		dev_dbg(dev, "Mapped iv %u B at va=%pK to dma=%pad\n", | ||||||
|  | 			ivsize, info, &req_ctx->gen_ctx.iv_dma_addr); | ||||||
|  | 	} else { | ||||||
|  | 		req_ctx->gen_ctx.iv_dma_addr = 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* Map the src SGL */ | ||||||
|  | 	rc = cc_map_sg(dev, src, nbytes, DMA_BIDIRECTIONAL, &req_ctx->in_nents, | ||||||
|  | 		       LLI_MAX_NUM_OF_DATA_ENTRIES, &dummy, &mapped_nents); | ||||||
|  | 	if (rc) { | ||||||
|  | 		rc = -ENOMEM; | ||||||
|  | 		goto cipher_exit; | ||||||
|  | 	} | ||||||
|  | 	if (mapped_nents > 1) | ||||||
|  | 		req_ctx->dma_buf_type = CC_DMA_BUF_MLLI; | ||||||
|  | 
 | ||||||
|  | 	if (src == dst) { | ||||||
|  | 		/* Handle inplace operation */ | ||||||
|  | 		if (req_ctx->dma_buf_type == CC_DMA_BUF_MLLI) { | ||||||
|  | 			req_ctx->out_nents = 0; | ||||||
|  | 			cc_add_sg_entry(dev, &sg_data, req_ctx->in_nents, src, | ||||||
|  | 					nbytes, 0, true, | ||||||
|  | 					&req_ctx->in_mlli_nents); | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		/* Map the dst sg */ | ||||||
|  | 		if (cc_map_sg(dev, dst, nbytes, DMA_BIDIRECTIONAL, | ||||||
|  | 			      &req_ctx->out_nents, LLI_MAX_NUM_OF_DATA_ENTRIES, | ||||||
|  | 			      &dummy, &mapped_nents)) { | ||||||
|  | 			rc = -ENOMEM; | ||||||
|  | 			goto cipher_exit; | ||||||
|  | 		} | ||||||
|  | 		if (mapped_nents > 1) | ||||||
|  | 			req_ctx->dma_buf_type = CC_DMA_BUF_MLLI; | ||||||
|  | 
 | ||||||
|  | 		if (req_ctx->dma_buf_type == CC_DMA_BUF_MLLI) { | ||||||
|  | 			cc_add_sg_entry(dev, &sg_data, req_ctx->in_nents, src, | ||||||
|  | 					nbytes, 0, true, | ||||||
|  | 					&req_ctx->in_mlli_nents); | ||||||
|  | 			cc_add_sg_entry(dev, &sg_data, req_ctx->out_nents, dst, | ||||||
|  | 					nbytes, 0, true, | ||||||
|  | 					&req_ctx->out_mlli_nents); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (req_ctx->dma_buf_type == CC_DMA_BUF_MLLI) { | ||||||
|  | 		mlli_params->curr_pool = buff_mgr->mlli_buffs_pool; | ||||||
|  | 		rc = cc_generate_mlli(dev, &sg_data, mlli_params, flags); | ||||||
|  | 		if (rc) | ||||||
|  | 			goto cipher_exit; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	dev_dbg(dev, "areq_ctx->dma_buf_type = %s\n", | ||||||
|  | 		cc_dma_buf_type(req_ctx->dma_buf_type)); | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | 
 | ||||||
|  | cipher_exit: | ||||||
|  | 	cc_unmap_cipher_request(dev, req_ctx, ivsize, src, dst); | ||||||
|  | 	return rc; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| int cc_buffer_mgr_init(struct cc_drvdata *drvdata) | int cc_buffer_mgr_init(struct cc_drvdata *drvdata) | ||||||
| { | { | ||||||
| 	struct buff_mgr_handle *buff_mgr_handle; | 	struct buff_mgr_handle *buff_mgr_handle; | ||||||
|  |  | ||||||
|  | @ -40,6 +40,14 @@ int cc_buffer_mgr_init(struct cc_drvdata *drvdata); | ||||||
| 
 | 
 | ||||||
| int cc_buffer_mgr_fini(struct cc_drvdata *drvdata); | int cc_buffer_mgr_fini(struct cc_drvdata *drvdata); | ||||||
| 
 | 
 | ||||||
|  | int cc_map_cipher_request(struct cc_drvdata *drvdata, void *ctx, | ||||||
|  | 			  unsigned int ivsize, unsigned int nbytes, | ||||||
|  | 			  void *info, struct scatterlist *src, | ||||||
|  | 			  struct scatterlist *dst, gfp_t flags); | ||||||
|  | 
 | ||||||
|  | void cc_unmap_cipher_request(struct device *dev, void *ctx, unsigned int ivsize, | ||||||
|  | 			     struct scatterlist *src, struct scatterlist *dst); | ||||||
|  | 
 | ||||||
| int cc_map_hash_request_final(struct cc_drvdata *drvdata, void *ctx, | int cc_map_hash_request_final(struct cc_drvdata *drvdata, void *ctx, | ||||||
| 			      struct scatterlist *src, unsigned int nbytes, | 			      struct scatterlist *src, unsigned int nbytes, | ||||||
| 			      bool do_update, gfp_t flags); | 			      bool do_update, gfp_t flags); | ||||||
|  |  | ||||||
							
								
								
									
										1130
									
								
								drivers/crypto/ccree/cc_cipher.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1130
									
								
								drivers/crypto/ccree/cc_cipher.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										59
									
								
								drivers/crypto/ccree/cc_cipher.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								drivers/crypto/ccree/cc_cipher.h
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,59 @@ | ||||||
|  | /* SPDX-License-Identifier: GPL-2.0 */ | ||||||
|  | /* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ | ||||||
|  | 
 | ||||||
|  | /* \file cc_cipher.h
 | ||||||
|  |  * ARM CryptoCell Cipher Crypto API | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef __CC_CIPHER_H__ | ||||||
|  | #define __CC_CIPHER_H__ | ||||||
|  | 
 | ||||||
|  | #include <linux/kernel.h> | ||||||
|  | #include <crypto/algapi.h> | ||||||
|  | #include "cc_driver.h" | ||||||
|  | #include "cc_buffer_mgr.h" | ||||||
|  | 
 | ||||||
|  | /* Crypto cipher flags */ | ||||||
|  | #define CC_CRYPTO_CIPHER_KEY_KFDE0	BIT(0) | ||||||
|  | #define CC_CRYPTO_CIPHER_KEY_KFDE1	BIT(1) | ||||||
|  | #define CC_CRYPTO_CIPHER_KEY_KFDE2	BIT(2) | ||||||
|  | #define CC_CRYPTO_CIPHER_KEY_KFDE3	BIT(3) | ||||||
|  | #define CC_CRYPTO_CIPHER_DU_SIZE_512B	BIT(4) | ||||||
|  | 
 | ||||||
|  | #define CC_CRYPTO_CIPHER_KEY_KFDE_MASK (CC_CRYPTO_CIPHER_KEY_KFDE0 | \ | ||||||
|  | 					CC_CRYPTO_CIPHER_KEY_KFDE1 | \ | ||||||
|  | 					CC_CRYPTO_CIPHER_KEY_KFDE2 | \ | ||||||
|  | 					CC_CRYPTO_CIPHER_KEY_KFDE3) | ||||||
|  | 
 | ||||||
|  | struct cipher_req_ctx { | ||||||
|  | 	struct async_gen_req_ctx gen_ctx; | ||||||
|  | 	enum cc_req_dma_buf_type dma_buf_type; | ||||||
|  | 	u32 in_nents; | ||||||
|  | 	u32 in_mlli_nents; | ||||||
|  | 	u32 out_nents; | ||||||
|  | 	u32 out_mlli_nents; | ||||||
|  | 	u8 *backup_info; /*store iv for generated IV flow*/ | ||||||
|  | 	u8 *iv; | ||||||
|  | 	bool is_giv; | ||||||
|  | 	struct mlli_params mlli_params; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | int cc_cipher_alloc(struct cc_drvdata *drvdata); | ||||||
|  | 
 | ||||||
|  | int cc_cipher_free(struct cc_drvdata *drvdata); | ||||||
|  | 
 | ||||||
|  | struct arm_hw_key_info { | ||||||
|  | 	int hw_key1; | ||||||
|  | 	int hw_key2; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * This is a stub function that will replaced when we | ||||||
|  |  * implement secure keys | ||||||
|  |  */ | ||||||
|  | static inline bool cc_is_hw_key(struct crypto_tfm *tfm) | ||||||
|  | { | ||||||
|  | 	return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif /*__CC_CIPHER_H__*/ | ||||||
|  | @ -19,6 +19,7 @@ | ||||||
| #include "cc_request_mgr.h" | #include "cc_request_mgr.h" | ||||||
| #include "cc_buffer_mgr.h" | #include "cc_buffer_mgr.h" | ||||||
| #include "cc_debugfs.h" | #include "cc_debugfs.h" | ||||||
|  | #include "cc_cipher.h" | ||||||
| #include "cc_ivgen.h" | #include "cc_ivgen.h" | ||||||
| #include "cc_sram_mgr.h" | #include "cc_sram_mgr.h" | ||||||
| #include "cc_pm.h" | #include "cc_pm.h" | ||||||
|  | @ -278,8 +279,17 @@ static int init_cc_resources(struct platform_device *plat_dev) | ||||||
| 		goto post_power_mgr_err; | 		goto post_power_mgr_err; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	/* Allocate crypto algs */ | ||||||
|  | 	rc = cc_cipher_alloc(new_drvdata); | ||||||
|  | 	if (rc) { | ||||||
|  | 		dev_err(dev, "cc_cipher_alloc failed\n"); | ||||||
|  | 		goto post_ivgen_err; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| 
 | 
 | ||||||
|  | post_ivgen_err: | ||||||
|  | 	cc_ivgen_fini(new_drvdata); | ||||||
| post_power_mgr_err: | post_power_mgr_err: | ||||||
| 	cc_pm_fini(new_drvdata); | 	cc_pm_fini(new_drvdata); | ||||||
| post_buf_mgr_err: | post_buf_mgr_err: | ||||||
|  | @ -308,6 +318,7 @@ static void cleanup_cc_resources(struct platform_device *plat_dev) | ||||||
| 	struct cc_drvdata *drvdata = | 	struct cc_drvdata *drvdata = | ||||||
| 		(struct cc_drvdata *)platform_get_drvdata(plat_dev); | 		(struct cc_drvdata *)platform_get_drvdata(plat_dev); | ||||||
| 
 | 
 | ||||||
|  | 	cc_cipher_free(drvdata); | ||||||
| 	cc_ivgen_fini(drvdata); | 	cc_ivgen_fini(drvdata); | ||||||
| 	cc_pm_fini(drvdata); | 	cc_pm_fini(drvdata); | ||||||
| 	cc_buffer_mgr_fini(drvdata); | 	cc_buffer_mgr_fini(drvdata); | ||||||
|  |  | ||||||
|  | @ -15,6 +15,7 @@ | ||||||
| #endif | #endif | ||||||
| #include <linux/dma-mapping.h> | #include <linux/dma-mapping.h> | ||||||
| #include <crypto/algapi.h> | #include <crypto/algapi.h> | ||||||
|  | #include <crypto/internal/skcipher.h> | ||||||
| #include <crypto/aes.h> | #include <crypto/aes.h> | ||||||
| #include <crypto/sha.h> | #include <crypto/sha.h> | ||||||
| #include <crypto/aead.h> | #include <crypto/aead.h> | ||||||
|  | @ -111,6 +112,7 @@ struct cc_drvdata { | ||||||
| 	struct platform_device *plat_dev; | 	struct platform_device *plat_dev; | ||||||
| 	cc_sram_addr_t mlli_sram_addr; | 	cc_sram_addr_t mlli_sram_addr; | ||||||
| 	void *buff_mgr_handle; | 	void *buff_mgr_handle; | ||||||
|  | 	void *cipher_handle; | ||||||
| 	void *request_mgr_handle; | 	void *request_mgr_handle; | ||||||
| 	void *ivgen_handle; | 	void *ivgen_handle; | ||||||
| 	void *sram_mgr_handle; | 	void *sram_mgr_handle; | ||||||
|  | @ -124,8 +126,9 @@ struct cc_crypto_alg { | ||||||
| 	int cipher_mode; | 	int cipher_mode; | ||||||
| 	int flow_mode; /* Note: currently, refers to the cipher mode only. */ | 	int flow_mode; /* Note: currently, refers to the cipher mode only. */ | ||||||
| 	int auth_mode; | 	int auth_mode; | ||||||
|  | 	unsigned int data_unit; | ||||||
| 	struct cc_drvdata *drvdata; | 	struct cc_drvdata *drvdata; | ||||||
| 	struct crypto_alg crypto_alg; | 	struct skcipher_alg skcipher_alg; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct cc_alg_template { | struct cc_alg_template { | ||||||
|  | @ -140,6 +143,7 @@ struct cc_alg_template { | ||||||
| 	int cipher_mode; | 	int cipher_mode; | ||||||
| 	int flow_mode; /* Note: currently, refers to the cipher mode only. */ | 	int flow_mode; /* Note: currently, refers to the cipher mode only. */ | ||||||
| 	int auth_mode; | 	int auth_mode; | ||||||
|  | 	unsigned int data_unit; | ||||||
| 	struct cc_drvdata *drvdata; | 	struct cc_drvdata *drvdata; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Gilad Ben-Yossef
						Gilad Ben-Yossef