Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ff5b299a authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "crypto: msm: Support SHA384 & SHA512"

parents 857969df 4931e540
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -26,6 +26,10 @@

#define AES_CE_BLOCK_SIZE		16

/* SHA1/256 supports 2 AUTH_BYTECNT REGISTER */
/* SHA384/512 supports 4 AUTH_BYTECNT REGISTER */
#define	AUTH_BYTECNT_REG_NUMBER		4

/* key size in bytes */
#define HMAC_KEY_SIZE			(SHA1_DIGESTSIZE)    /* hmac-sha1 */
#define SHA_HMAC_KEY_SIZE		64
@@ -71,6 +75,10 @@ enum qce_hash_alg_enum {
	QCE_HASH_SHA1_HMAC   = 2,
	QCE_HASH_SHA256_HMAC = 3,
	QCE_HASH_AES_CMAC = 4,
	QCE_HASH_SHA384 = 5,
	QCE_HASH_SHA512 = 6,
	QCE_HASH_SHA384_HMAC = 7,
	QCE_HASH_SHA512_HMAC = 8,
	QCE_HASH_LAST
};

+224 −30
Original line number Diff line number Diff line
@@ -176,6 +176,22 @@ static uint32_t _std_init_vector_sha256[] = {
	0x510E527F, 0x9B05688C,	0x1F83D9AB, 0x5BE0CD19
};

/* Standard initialization vector for SHA-384, source: FIPS 180-2 */
static uint32_t _std_init_vector_sha384[] = {
	0xCBBB9D5D, 0xC1059ED8, 0x629A292A, 0x367CD507,
	0x9159015A, 0x3070DD17, 0x152FECD8, 0xF70E5939,
	0x67332667, 0xFFC00B31, 0x8EB44A87, 0x68581511,
	0xDB0C2E0D, 0x64F98FA7, 0x47B5481D, 0xBEFA4FA4
};

/* Standard initialization vector for SHA-512, source: FIPS 180-2 */
static uint32_t _std_init_vector_sha512[] = {
	0x6A09E667, 0xF3BCC908, 0xBB67AE85, 0x84CAA73B,
	0x3C6EF372, 0xFE94F82B, 0xA54FF53A, 0x5F1D36F1,
	0x510E527F, 0xADE682D1, 0x9B05688C, 0x2B3E6C1F,
	0x1F83D9AB, 0xFB41BD6B, 0x5BE0CD19, 0x137E2179
};

static void _byte_stream_to_net_words(uint32_t *iv, unsigned char *b,
		unsigned int len)
{
@@ -225,6 +241,23 @@ static int count_sg(struct scatterlist *sg, int nbytes)
	return i;
}

static uint32_t qce_get_block_size(enum qce_hash_alg_enum alg)
{
	switch (alg) {
	case QCE_HASH_SHA1:
	case QCE_HASH_SHA1_HMAC:
		return SHA1_BLOCK_SIZE;
	case QCE_HASH_SHA256:
	case QCE_HASH_SHA256_HMAC:
		return SHA256_BLOCK_SIZE;
	case QCE_HASH_SHA384:
	case QCE_HASH_SHA384_HMAC:
		return SHA384_BLOCK_SIZE;
	default:
		return SHA512_BLOCK_SIZE;
	}
}

static int qce_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
	enum dma_data_direction direction)
{
@@ -323,10 +356,18 @@ static struct qce_cmdlist_info *_ce_get_hash_cmdlistinfo(
		return &cmdlistptr->auth_sha1;
	case QCE_HASH_SHA256:
		return &cmdlistptr->auth_sha256;
	case QCE_HASH_SHA384:
		return &cmdlistptr->auth_sha384;
	case QCE_HASH_SHA512:
		return &cmdlistptr->auth_sha512;
	case QCE_HASH_SHA1_HMAC:
		return &cmdlistptr->auth_sha1_hmac;
	case QCE_HASH_SHA256_HMAC:
		return &cmdlistptr->auth_sha256_hmac;
	case QCE_HASH_SHA384_HMAC:
		return &cmdlistptr->auth_sha384_hmac;
	case QCE_HASH_SHA512_HMAC:
		return &cmdlistptr->auth_sha512_hmac;
	case QCE_HASH_AES_CMAC:
		if (sreq->authklen == AES128_KEY_SIZE)
			return &cmdlistptr->auth_aes_128_cmac;
@@ -341,12 +382,11 @@ static int _ce_setup_hash(struct qce_device *pce_dev,
				struct qce_sha_req *sreq,
				struct qce_cmdlist_info *cmdlistinfo)
{
	uint32_t auth32[SHA256_DIGEST_SIZE / sizeof(uint32_t)];
	uint32_t auth32[SHA512_DIGEST_SIZE / sizeof(uint32_t)];
	uint32_t diglen;
	int i;
	uint32_t mackey32[SHA_HMAC_KEY_SIZE/sizeof(uint32_t)] = {
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
	bool sha1 = false;
	uint32_t mackey32[SHA_HMAC_KEY_SIZE/sizeof(uint32_t)] = {0};
	bool sha1 = false, sha256 = false, sha384 = false, sha512 = false;
	struct sps_command_element *pce = NULL;
	bool use_hw_key = false;
	bool use_pipe_key = false;
@@ -355,6 +395,8 @@ static int _ce_setup_hash(struct qce_device *pce_dev,

	if ((sreq->alg == QCE_HASH_SHA1_HMAC) ||
			(sreq->alg == QCE_HASH_SHA256_HMAC) ||
			(sreq->alg == QCE_HASH_SHA384_HMAC) ||
			(sreq->alg == QCE_HASH_SHA512_HMAC) ||
			(sreq->alg ==  QCE_HASH_AES_CMAC)) {


@@ -387,7 +429,7 @@ static int _ce_setup_hash(struct qce_device *pce_dev,
		goto go_proc;

	/* if not the last, the size has to be on the block boundary */
	if (!sreq->last_blk && (sreq->size % SHA256_BLOCK_SIZE))
	if (!sreq->last_blk && (sreq->size % qce_get_block_size(sreq->alg)))
		return -EIO;

	switch (sreq->alg) {
@@ -399,6 +441,17 @@ static int _ce_setup_hash(struct qce_device *pce_dev,
	case QCE_HASH_SHA256:
	case QCE_HASH_SHA256_HMAC:
		diglen = SHA256_DIGEST_SIZE;
		sha256 = true;
		break;
	case QCE_HASH_SHA384:
	case QCE_HASH_SHA384_HMAC:
		diglen = SHA512_DIGEST_SIZE;
		sha384 = true;
		break;
	case QCE_HASH_SHA512:
	case QCE_HASH_SHA512_HMAC:
		diglen = SHA512_DIGEST_SIZE;
		sha512 = true;
		break;
	default:
		return -EINVAL;
@@ -406,13 +459,18 @@ static int _ce_setup_hash(struct qce_device *pce_dev,

	/* write 20/32 bytes, 5/8 words into auth_iv for SHA1/SHA256 */
	if (sreq->first_blk) {
		if (sha1) {
		if (sha1)
			for (i = 0; i < 5; i++)
				auth32[i] = _std_init_vector_sha1[i];
		} else {
		if (sha256)
			for (i = 0; i < 8; i++)
				auth32[i] = _std_init_vector_sha256[i];
		}
		if (sha384)
			for (i = 0; i < 16; i++)
				auth32[i] = _std_init_vector_sha384[i];
		if (sha512)
			for (i = 0; i < 16; i++)
				auth32[i] = _std_init_vector_sha512[i];
	} else {
		_byte_stream_to_net_words(auth32, sreq->digest, diglen);
	}
@@ -421,15 +479,18 @@ static int _ce_setup_hash(struct qce_device *pce_dev,
	for (i = 0; i < 5; i++, pce++)
		pce->data = auth32[i];

	if ((sreq->alg == QCE_HASH_SHA256) ||
			(sreq->alg == QCE_HASH_SHA256_HMAC)) {
	if (sha256)
		for (i = 5; i < 8; i++, pce++)
			pce->data = auth32[i];
	}

	if (sha384 || sha512)
		for (i = 5; i < 16; i++, pce++)
			pce->data = auth32[i];


	/* write auth_bytecnt 0/1, start with 0 */
	pce = cmdlistinfo->auth_bytecount;
	for (i = 0; i < 2; i++, pce++)
	for (i = 0; i < 4; i++, pce++)
		pce->data = sreq->auth_data[i];

	/* Set/reset  last bit in CFG register  */
@@ -1173,15 +1234,14 @@ static void _qce_dump_descr_fifos_dbg(struct qce_device *pce_dev, int req_info)
static int _ce_setup_hash_direct(struct qce_device *pce_dev,
				struct qce_sha_req *sreq)
{
	uint32_t auth32[SHA256_DIGEST_SIZE / sizeof(uint32_t)];
	uint32_t auth32[SHA512_DIGEST_SIZE / sizeof(uint32_t)];
	uint32_t diglen;
	bool use_hw_key = false;
	bool use_pipe_key = false;
	int i;
	uint32_t mackey32[SHA_HMAC_KEY_SIZE/sizeof(uint32_t)] = {
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
	uint32_t mackey32[SHA_HMAC_KEY_SIZE / sizeof(uint32_t)] = {0};
	uint32_t authk_size_in_word = sreq->authklen/sizeof(uint32_t);
	bool sha1 = false;
	bool sha1 = false, sha256 = false, sha384 = false, sha512 = false;
	uint32_t auth_cfg = 0;

	/* clear status */
@@ -1226,6 +1286,8 @@ static int _ce_setup_hash_direct(struct qce_device *pce_dev,

	if ((sreq->alg == QCE_HASH_SHA1_HMAC) ||
			(sreq->alg == QCE_HASH_SHA256_HMAC) ||
			(sreq->alg == QCE_HASH_SHA384_HMAC) ||
			(sreq->alg == QCE_HASH_SHA512_HMAC) ||
			(sreq->alg ==  QCE_HASH_AES_CMAC)) {

		_byte_stream_to_net_words(mackey32, sreq->authkey,
@@ -1252,7 +1314,7 @@ static int _ce_setup_hash_direct(struct qce_device *pce_dev,
		goto go_proc;

	/* if not the last, the size has to be on the block boundary */
	if (!sreq->last_blk && (sreq->size % SHA256_BLOCK_SIZE))
	if (!sreq->last_blk && (sreq->size % qce_get_block_size(sreq->alg)))
		return -EIO;

	switch (sreq->alg) {
@@ -1269,10 +1331,32 @@ static int _ce_setup_hash_direct(struct qce_device *pce_dev,
	case QCE_HASH_SHA256:
		auth_cfg = pce_dev->reg.auth_cfg_sha256;
		diglen = SHA256_DIGEST_SIZE;
		sha256 = true;
		break;
	case QCE_HASH_SHA256_HMAC:
		auth_cfg = pce_dev->reg.auth_cfg_hmac_sha256;
		diglen = SHA256_DIGEST_SIZE;
		sha256 = true;
		break;
	case QCE_HASH_SHA384:
		auth_cfg = pce_dev->reg.auth_cfg_sha384;
		diglen = SHA512_DIGEST_SIZE;
		sha384 = true;
		break;
	case QCE_HASH_SHA384_HMAC:
		auth_cfg = pce_dev->reg.auth_cfg_hmac_sha384;
		diglen = SHA512_DIGEST_SIZE;
		sha384 = true;
		break;
	case QCE_HASH_SHA512:
		auth_cfg = pce_dev->reg.auth_cfg_sha512;
		diglen = SHA512_DIGEST_SIZE;
		sha512 = true;
		break;
	case QCE_HASH_SHA512_HMAC:
		auth_cfg = pce_dev->reg.auth_cfg_hmac_sha512;
		diglen = SHA512_DIGEST_SIZE;
		sha512 = true;
		break;
	default:
		return -EINVAL;
@@ -1280,13 +1364,18 @@ static int _ce_setup_hash_direct(struct qce_device *pce_dev,

	/* write 20/32 bytes, 5/8 words into auth_iv for SHA1/SHA256 */
	if (sreq->first_blk) {
		if (sha1) {
		if (sha1)
			for (i = 0; i < 5; i++)
				auth32[i] = _std_init_vector_sha1[i];
		} else {
		if (sha256)
			for (i = 0; i < 8; i++)
				auth32[i] = _std_init_vector_sha256[i];
		}
		if (sha384)
			for (i = 0; i < 16; i++)
				auth32[i] = _std_init_vector_sha384[i];
		if (sha512)
			for (i = 0; i < 16; i++)
				auth32[i] = _std_init_vector_sha512[i];
	} else {
		_byte_stream_to_net_words(auth32, sreq->digest, diglen);
	}
@@ -1296,16 +1385,17 @@ static int _ce_setup_hash_direct(struct qce_device *pce_dev,
		QCE_WRITE_REG(auth32[i], (pce_dev->iobase +
			(CRYPTO_AUTH_IV0_REG + i*sizeof(uint32_t))));

	if ((sreq->alg == QCE_HASH_SHA256) ||
			(sreq->alg == QCE_HASH_SHA256_HMAC)) {
	if (sha256)
		for (i = 5; i < 8; i++)
			QCE_WRITE_REG(auth32[i], (pce_dev->iobase +
				(CRYPTO_AUTH_IV0_REG + i*sizeof(uint32_t))));
	}

	if (sha384 || sha512)
		for (i = 5; i < 16; i++)
			QCE_WRITE_REG(auth32[i], (pce_dev->iobase +
				(CRYPTO_AUTH_IV0_REG + i*sizeof(uint32_t))));

	/* write auth_bytecnt 0/1/2/3, start with 0 */
	for (i = 0; i < 2; i++)
	for (i = 0; i < 4; i++)
		QCE_WRITE_REG(sreq->auth_data[i], pce_dev->iobase +
					CRYPTO_AUTH_BYTECNT0_REG +
						i * sizeof(uint32_t));
@@ -2139,8 +2229,8 @@ static int _aead_complete(struct qce_device *pce_dev, int req_info)
static int _sha_complete(struct qce_device *pce_dev, int req_info)
{
	struct ahash_request *areq;
	unsigned char digest[SHA256_DIGEST_SIZE];
	uint32_t bytecount32[2];
	unsigned char digest[SHA512_DIGEST_SIZE];
	uint32_t bytecount32[AUTH_BYTECNT_REG_NUMBER];
	int32_t result_status = 0;
	uint32_t result_dump_status;
	struct ce_request_info *preq_info;
@@ -2158,10 +2248,10 @@ static int _sha_complete(struct qce_device *pce_dev, int req_info)
	qce_dma_unmap_sg(pce_dev->pdev, areq->src, preq_info->src_nents,
				DMA_TO_DEVICE);
	memcpy(digest, (char *)(&pce_sps_data->result->auth_iv[0]),
						SHA256_DIGEST_SIZE);
						SHA512_DIGEST_SIZE);
	_byte_stream_to_net_words(bytecount32,
		(unsigned char *)pce_sps_data->result->auth_byte_count,
					2 * CRYPTO_REG_SIZE);
				AUTH_BYTECNT_REG_NUMBER * CRYPTO_REG_SIZE);

	if (_qce_unlock_other_pipes(pce_dev, req_info)) {
		qce_free_req_info(pce_dev, req_info, true);
@@ -3574,6 +3664,40 @@ static int _setup_auth_cmdlistptrs(struct qce_device *pdev, int cri_index,
		qce_add_cmd_element(pdev, &ce_vaddr, CRYPTO_ENCR_SEG_SIZE_REG,
								0, NULL);
	break;
	case QCE_HASH_SHA384:
		cmdlistptr->auth_sha384.cmdlist = (uintptr_t)ce_vaddr;
		pcl_info = &(cmdlistptr->auth_sha384);

		auth_cfg = pdev->reg.auth_cfg_sha384;
		iv_reg = 16;

		/* clear status register */
		qce_add_cmd_element(pdev, &ce_vaddr, CRYPTO_STATUS_REG,
					0, NULL);

		qce_add_cmd_element(pdev, &ce_vaddr, CRYPTO_CONFIG_REG,
			pdev->reg.crypto_cfg_be, &pcl_info->crypto_cfg);
		/* 1 dummy write */
		qce_add_cmd_element(pdev, &ce_vaddr, CRYPTO_ENCR_SEG_SIZE_REG,
								0, NULL);
	break;
	case QCE_HASH_SHA512:
		cmdlistptr->auth_sha512.cmdlist = (uintptr_t)ce_vaddr;
		pcl_info = &(cmdlistptr->auth_sha512);

		auth_cfg = pdev->reg.auth_cfg_sha512;
		iv_reg = 16;

		/* clear status register */
		qce_add_cmd_element(pdev, &ce_vaddr, CRYPTO_STATUS_REG,
					0, NULL);

		qce_add_cmd_element(pdev, &ce_vaddr, CRYPTO_CONFIG_REG,
			pdev->reg.crypto_cfg_be, &pcl_info->crypto_cfg);
		/* 1 dummy write */
		qce_add_cmd_element(pdev, &ce_vaddr, CRYPTO_ENCR_SEG_SIZE_REG,
								0, NULL);
	break;
	case QCE_HASH_SHA1_HMAC:
		cmdlistptr->auth_sha1_hmac.cmdlist = (uintptr_t)ce_vaddr;
		pcl_info = &(cmdlistptr->auth_sha1_hmac);
@@ -3607,6 +3731,42 @@ static int _setup_auth_cmdlistptrs(struct qce_device *pdev, int cri_index,
		qce_add_cmd_element(pdev, &ce_vaddr, CRYPTO_ENCR_SEG_SIZE_REG,
								0, NULL);
	break;
	case QCE_HASH_SHA384_HMAC:
		cmdlistptr->auth_sha384_hmac.cmdlist = (uintptr_t)ce_vaddr;
		pcl_info = &(cmdlistptr->auth_sha384_hmac);

		auth_cfg = pdev->reg.auth_cfg_hmac_sha384;
		key_reg = 32;
		iv_reg = 16;

		/* clear status register */
		qce_add_cmd_element(pdev, &ce_vaddr, CRYPTO_STATUS_REG, 0,
					NULL);

		qce_add_cmd_element(pdev, &ce_vaddr, CRYPTO_CONFIG_REG,
			pdev->reg.crypto_cfg_be, &pcl_info->crypto_cfg);
		/* 1 dummy write */
		qce_add_cmd_element(pdev, &ce_vaddr, CRYPTO_ENCR_SEG_SIZE_REG,
								0, NULL);
	break;
	case QCE_HASH_SHA512_HMAC:
		cmdlistptr->auth_sha512_hmac.cmdlist = (uintptr_t)ce_vaddr;
		pcl_info = &(cmdlistptr->auth_sha512_hmac);

		auth_cfg = pdev->reg.auth_cfg_hmac_sha512;
		key_reg = 32;
		iv_reg = 16;

		/* clear status register */
		qce_add_cmd_element(pdev, &ce_vaddr, CRYPTO_STATUS_REG, 0,
					NULL);

		qce_add_cmd_element(pdev, &ce_vaddr, CRYPTO_CONFIG_REG,
			pdev->reg.crypto_cfg_be, &pcl_info->crypto_cfg);
		/* 1 dummy write */
		qce_add_cmd_element(pdev, &ce_vaddr, CRYPTO_ENCR_SEG_SIZE_REG,
								0, NULL);
	break;
	case QCE_HASH_AES_CMAC:
		if (key_128) {
			cmdlistptr->auth_aes_128_cmac.cmdlist =
@@ -3674,6 +3834,8 @@ static int _setup_auth_cmdlistptrs(struct qce_device *pdev, int cri_index,
						0, &pcl_info->auth_bytecount);
	}
	qce_add_cmd_element(pdev, &ce_vaddr, CRYPTO_AUTH_BYTECNT1_REG, 0, NULL);
	qce_add_cmd_element(pdev, &ce_vaddr, CRYPTO_AUTH_BYTECNT2_REG, 0, NULL);
	qce_add_cmd_element(pdev, &ce_vaddr, CRYPTO_AUTH_BYTECNT3_REG, 0, NULL);

	if (key_reg) {
		qce_add_cmd_element(pdev, &ce_vaddr,
@@ -4282,11 +4444,19 @@ static int qce_setup_cmdlistptrs(struct qce_device *pdev, int cri_index,
								false);
	_setup_auth_cmdlistptrs(pdev, cri_index, pvaddr, QCE_HASH_SHA256,
								false);
	_setup_auth_cmdlistptrs(pdev, cri_index, pvaddr, QCE_HASH_SHA384,
								false);
	_setup_auth_cmdlistptrs(pdev, cri_index, pvaddr, QCE_HASH_SHA512,
								false);

	_setup_auth_cmdlistptrs(pdev, cri_index, pvaddr, QCE_HASH_SHA1_HMAC,
								false);
	_setup_auth_cmdlistptrs(pdev, cri_index, pvaddr, QCE_HASH_SHA256_HMAC,
								false);
	_setup_auth_cmdlistptrs(pdev, cri_index, pvaddr, QCE_HASH_SHA384_HMAC,
								false);
	_setup_auth_cmdlistptrs(pdev, cri_index, pvaddr, QCE_HASH_SHA512_HMAC,
								false);

	_setup_auth_cmdlistptrs(pdev, cri_index, pvaddr, QCE_HASH_AES_CMAC,
								true);
@@ -4505,6 +4675,18 @@ static int qce_init_ce_cfg_val(struct qce_device *pce_dev)
		(CRYPTO_AUTH_ALG_SHA << CRYPTO_AUTH_ALG) |
		(CRYPTO_AUTH_POS_BEFORE << CRYPTO_AUTH_POS);

	pce_dev->reg.auth_cfg_hmac_sha384 =
		(CRYPTO_AUTH_MODE_HMAC << CRYPTO_AUTH_MODE)|
		(CRYPTO_AUTH_SIZE_SHA384 << CRYPTO_AUTH_SIZE) |
		(CRYPTO_AUTH_ALG_SHA << CRYPTO_AUTH_ALG) |
		(CRYPTO_AUTH_POS_BEFORE << CRYPTO_AUTH_POS);

	pce_dev->reg.auth_cfg_hmac_sha512 =
		(CRYPTO_AUTH_MODE_HMAC << CRYPTO_AUTH_MODE)|
		(CRYPTO_AUTH_SIZE_SHA512 << CRYPTO_AUTH_SIZE) |
		(CRYPTO_AUTH_ALG_SHA << CRYPTO_AUTH_ALG) |
		(CRYPTO_AUTH_POS_BEFORE << CRYPTO_AUTH_POS);

	/* Initialize auth_cfg register for SHA1/256 alg */
	pce_dev->reg.auth_cfg_sha1 =
		(CRYPTO_AUTH_MODE_HASH << CRYPTO_AUTH_MODE)|
@@ -4518,6 +4700,18 @@ static int qce_init_ce_cfg_val(struct qce_device *pce_dev)
		(CRYPTO_AUTH_ALG_SHA << CRYPTO_AUTH_ALG) |
		(CRYPTO_AUTH_POS_BEFORE << CRYPTO_AUTH_POS);

	pce_dev->reg.auth_cfg_sha384 =
		(CRYPTO_AUTH_MODE_HASH << CRYPTO_AUTH_MODE)|
		(CRYPTO_AUTH_SIZE_SHA384 << CRYPTO_AUTH_SIZE) |
		(CRYPTO_AUTH_ALG_SHA << CRYPTO_AUTH_ALG) |
		(CRYPTO_AUTH_POS_BEFORE << CRYPTO_AUTH_POS);

	pce_dev->reg.auth_cfg_sha512 =
		(CRYPTO_AUTH_MODE_HASH << CRYPTO_AUTH_MODE)|
		(CRYPTO_AUTH_SIZE_SHA512 << CRYPTO_AUTH_SIZE) |
		(CRYPTO_AUTH_ALG_SHA << CRYPTO_AUTH_ALG) |
		(CRYPTO_AUTH_POS_BEFORE << CRYPTO_AUTH_POS);

	/* Initialize auth_cfg register for AEAD alg */
	pce_dev->reg.auth_cfg_aead_sha1_hmac =
		(CRYPTO_AUTH_MODE_HMAC << CRYPTO_AUTH_MODE)|
+9 −0
Original line number Diff line number Diff line
@@ -126,6 +126,10 @@ struct qce_cmdlistptr_ops {
	struct qce_cmdlist_info f9_kasumi;
	struct qce_cmdlist_info f9_snow3g;
	struct qce_cmdlist_info unlock_all_pipes;
	struct qce_cmdlist_info auth_sha384;
	struct qce_cmdlist_info auth_sha512;
	struct qce_cmdlist_info auth_sha384_hmac;
	struct qce_cmdlist_info auth_sha512_hmac;
};

struct qce_ce_cfg_reg_setting {
@@ -170,6 +174,11 @@ struct qce_ce_cfg_reg_setting {
	uint32_t auth_cfg_aead_sha256_hmac;
	uint32_t auth_cfg_kasumi;
	uint32_t auth_cfg_snow3g;

	uint32_t auth_cfg_sha384;
	uint32_t auth_cfg_sha512;
	uint32_t auth_cfg_hmac_sha384;
	uint32_t auth_cfg_hmac_sha512;
};

struct ce_bam_info {
+136 −36
Original line number Diff line number Diff line
@@ -50,6 +50,28 @@ static uint8_t _std_init_vector_sha256_uint8[] = {
	0x1F, 0x83, 0xD9, 0xAB, 0x5B, 0xE0, 0xCD, 0x19
};

static uint8_t _std_init_vector_sha384_uint8[] = {
	0xCB, 0xBB, 0x9D, 0x5D, 0xC1, 0x05, 0x9E, 0xD8,
	0x62, 0x9A, 0x29, 0x2A, 0x36, 0x7C, 0xD5, 0x07,
	0x91, 0x59, 0x01, 0x5A, 0x30, 0x70, 0xDD, 0x17,
	0x15, 0x2F, 0xEC, 0xD8, 0xF7, 0x0E, 0x59, 0x39,
	0x67, 0x33, 0x26, 0x67, 0xFF, 0xC0, 0x0B, 0x31,
	0x8E, 0xB4, 0x4A, 0x87, 0x68, 0x58, 0x15, 0x11,
	0xDB, 0x0C, 0x2E, 0x0D, 0x64, 0xF9, 0x8F, 0xA7,
	0x47, 0xB5, 0x48, 0x1D, 0xBE, 0xFA, 0x4F, 0xA4
};

static uint8_t _std_init_vector_sha512_uint8[] = {
	0x6A, 0x09, 0xE6, 0x67, 0xF3, 0xBC, 0xC9, 0x08,
	0xBB, 0x67, 0xAE, 0x85, 0x84, 0xCA, 0xA7, 0x3B,
	0x3C, 0x6E, 0xF3, 0x72, 0xFE, 0x94, 0xF8, 0x2B,
	0xA5, 0x4F, 0xF5, 0x3A, 0x5F, 0x1D, 0x36, 0xF1,
	0x51, 0x0E, 0x52, 0x7F, 0xAD, 0xE6, 0x82, 0xD1,
	0x9B, 0x05, 0x68, 0x8C, 0x2B, 0x3E, 0x6C, 0x1F,
	0x1F, 0x83, 0xD9, 0xAB, 0xFB, 0x41, 0xBD, 0x6B,
	0x5B, 0xE0, 0xCD, 0x19, 0x13, 0x7E, 0x21, 0x79
};

static DEFINE_MUTEX(send_cmd_lock);
static DEFINE_MUTEX(qcedev_sent_bw_req);
static DEFINE_MUTEX(hash_access_lock);
@@ -66,6 +88,23 @@ static const struct of_device_id qcedev_match[] = {
	{}
};

static uint32_t qcedev_get_block_size(enum qcedev_sha_alg_enum alg)
{
	switch (alg) {
	case QCEDEV_ALG_SHA1:
	case QCEDEV_ALG_SHA1_HMAC:
		return SHA1_BLOCK_SIZE;
	case QCEDEV_ALG_SHA256:
	case QCEDEV_ALG_SHA256_HMAC:
		return SHA256_BLOCK_SIZE;
	case QCEDEV_ALG_SHA384:
	case QCEDEV_ALG_SHA384_HMAC:
		return SHA384_BLOCK_SIZE;
	default:
		return SHA512_BLOCK_SIZE;
	}
}

static int qcedev_control_clocks(struct qcedev_control *podev, bool enable)
{
	unsigned int control_flag;
@@ -340,11 +379,14 @@ void qcedev_sha_req_cb(void *cookie, unsigned char *digest,
	pdev = handle->cntl;

	if (digest)
		memcpy(&handle->sha_ctxt.digest[0], digest, 32);
		memcpy(&handle->sha_ctxt.digest[0], digest,
			QCEDEV_MAX_SHA_DIGEST);

	if (authdata) {
		handle->sha_ctxt.auth_data[0] = auth32[0];
		handle->sha_ctxt.auth_data[1] = auth32[1];
		handle->sha_ctxt.auth_data[2] = auth32[2];
		handle->sha_ctxt.auth_data[3] = auth32[3];
	}

	tasklet_schedule(&pdev->done_tasklet);
@@ -490,12 +532,17 @@ static int start_sha_req(struct qcedev_control *podev)
	case QCEDEV_ALG_SHA256:
		sreq.alg = QCE_HASH_SHA256;
		break;
	case QCEDEV_ALG_SHA384:
		sreq.alg = QCE_HASH_SHA384;
		break;
	case QCEDEV_ALG_SHA512:
		sreq.alg = QCE_HASH_SHA512;
		break;
	case QCEDEV_ALG_SHA1_HMAC:
		if (podev->ce_support.sha_hmac) {
			sreq.alg = QCE_HASH_SHA1_HMAC;
			sreq.authkey = &handle->sha_ctxt.authkey[0];
			sreq.authklen = QCEDEV_MAX_SHA_BLOCK_SIZE;

			sreq.authklen = SHA1_BLOCK_SIZE;
		} else {
			sreq.alg = QCE_HASH_SHA1;
			sreq.authkey = NULL;
@@ -505,12 +552,32 @@ static int start_sha_req(struct qcedev_control *podev)
		if (podev->ce_support.sha_hmac) {
			sreq.alg = QCE_HASH_SHA256_HMAC;
			sreq.authkey = &handle->sha_ctxt.authkey[0];
			sreq.authklen = QCEDEV_MAX_SHA_BLOCK_SIZE;
			sreq.authklen = SHA256_BLOCK_SIZE;
		} else {
			sreq.alg = QCE_HASH_SHA256;
			sreq.authkey = NULL;
		}
		break;
	case QCEDEV_ALG_SHA384_HMAC:
		if (podev->ce_support.sha_hmac) {
			sreq.alg = QCE_HASH_SHA384_HMAC;
			sreq.authkey = &handle->sha_ctxt.authkey[0];
			sreq.authklen = SHA384_BLOCK_SIZE;
		} else {
			sreq.alg = QCE_HASH_SHA384;
			sreq.authkey = NULL;
		}
		break;
	case QCEDEV_ALG_SHA512_HMAC:
		if (podev->ce_support.sha_hmac) {
			sreq.alg = QCE_HASH_SHA512_HMAC;
			sreq.authkey = &handle->sha_ctxt.authkey[0];
			sreq.authklen = SHA512_BLOCK_SIZE;
		} else {
			sreq.alg = QCE_HASH_SHA512;
			sreq.authkey = NULL;
		}
		break;
	case QCEDEV_ALG_AES_CMAC:
		sreq.alg = QCE_HASH_AES_CMAC;
		sreq.authkey = &handle->sha_ctxt.authkey[0];
@@ -623,7 +690,7 @@ static int qcedev_sha_init(struct qcedev_async_req *areq,
		memcpy(&sha_ctxt->digest[0],
			&_std_init_vector_sha1_uint8[0], SHA1_DIGEST_SIZE);
		sha_ctxt->diglen = SHA1_DIGEST_SIZE;
	} else {
	}
	if ((areq->sha_op_req.alg == QCEDEV_ALG_SHA256) ||
			(areq->sha_op_req.alg == QCEDEV_ALG_SHA256_HMAC)) {
		memcpy(&sha_ctxt->digest[0],
@@ -631,6 +698,19 @@ static int qcedev_sha_init(struct qcedev_async_req *areq,
			SHA256_DIGEST_SIZE);
		sha_ctxt->diglen = SHA256_DIGEST_SIZE;
	}
	if ((areq->sha_op_req.alg == QCEDEV_ALG_SHA384) ||
			(areq->sha_op_req.alg == QCEDEV_ALG_SHA384_HMAC)) {
		memcpy(&sha_ctxt->digest[0],
			&_std_init_vector_sha384_uint8[0],
			SHA512_DIGEST_SIZE);
		sha_ctxt->diglen = SHA384_DIGEST_SIZE;
	}
	if ((areq->sha_op_req.alg == QCEDEV_ALG_SHA512) ||
			(areq->sha_op_req.alg == QCEDEV_ALG_SHA512_HMAC)) {
		memcpy(&sha_ctxt->digest[0],
			&_std_init_vector_sha512_uint8[0],
			SHA512_DIGEST_SIZE);
		sha_ctxt->diglen = SHA512_DIGEST_SIZE;
	}
	sha_ctxt->init_done = true;
	return 0;
@@ -657,10 +737,7 @@ static int qcedev_sha_update_max_xfer(struct qcedev_async_req *qcedev_areq,

	total = qcedev_areq->sha_op_req.data_len + t_buf;

	if (qcedev_areq->sha_op_req.alg == QCEDEV_ALG_SHA1)
		sha_block_size = SHA1_BLOCK_SIZE;
	else
		sha_block_size = SHA256_BLOCK_SIZE;
	sha_block_size = qcedev_get_block_size(qcedev_areq->sha_op_req.alg);

	if (total <= sha_block_size) {
		uint32_t len =  qcedev_areq->sha_op_req.data_len;
@@ -687,7 +764,6 @@ static int qcedev_sha_update_max_xfer(struct qcedev_async_req *qcedev_areq,
		return 0;
	}


	k_buf_src = kmalloc(total + CACHE_LINE_SIZE * 2,
				GFP_KERNEL);
	if (k_buf_src == NULL)
@@ -727,8 +803,8 @@ static int qcedev_sha_update_max_xfer(struct qcedev_async_req *qcedev_areq,
	}

	/*  get new trailing buffer */
	sha_pad_len = ALIGN(total, CE_SHA_BLOCK_SIZE) - total;
	trailing_buf_len =  CE_SHA_BLOCK_SIZE - sha_pad_len;
	sha_pad_len = ALIGN(total, sha_block_size) - total;
	trailing_buf_len =  sha_block_size - sha_pad_len;

	qcedev_areq->sha_req.sreq.src = sg_src;
	sg_init_one(qcedev_areq->sha_req.sreq.src, k_align_src,
@@ -738,7 +814,8 @@ static int qcedev_sha_update_max_xfer(struct qcedev_async_req *qcedev_areq,

	/*  update sha_ctxt trailing buf content to new trailing buf */
	if (trailing_buf_len > 0) {
		memset(&handle->sha_ctxt.trailing_buf[0], 0, 64);
		memset(&handle->sha_ctxt.trailing_buf[0], 0,
			QCEDEV_MAX_SHA_BLOCK_SIZE);
		memcpy(&handle->sha_ctxt.trailing_buf[0],
			(k_src - trailing_buf_len),
			trailing_buf_len);
@@ -905,9 +982,11 @@ static int qcedev_sha_final(struct qcedev_async_req *qcedev_areq,
	handle->sha_ctxt.last_blk = 0;
	handle->sha_ctxt.auth_data[0] = 0;
	handle->sha_ctxt.auth_data[1] = 0;
	handle->sha_ctxt.auth_data[2] = 0;
	handle->sha_ctxt.auth_data[3] = 0;
	handle->sha_ctxt.trailing_buf_len = 0;
	handle->sha_ctxt.init_done = false;
	memset(&handle->sha_ctxt.trailing_buf[0], 0, 64);
	memset(&handle->sha_ctxt.trailing_buf[0], 0, QCEDEV_MAX_SHA_BLOCK_SIZE);
	memset(k_buf_src, 0, ksize((void *)k_buf_src));
	kfree(k_buf_src);
	qcedev_areq->sha_req.sreq.src = NULL;
@@ -979,8 +1058,9 @@ static int qcedev_set_hmac_auth_key(struct qcedev_async_req *areq,
					struct scatterlist *sg_src)
{
	int err = 0;
	int qcedev_max_key = qcedev_get_block_size(areq->sha_op_req.alg);

	if (areq->sha_op_req.authklen <= QCEDEV_MAX_KEY_SIZE) {
	if (areq->sha_op_req.authklen <= qcedev_max_key) {
		qcedev_sha_init(areq, handle);
		if (copy_from_user(&handle->sha_ctxt.authkey[0],
				(void __user *)areq->sha_op_req.authkey,
@@ -1006,6 +1086,10 @@ static int qcedev_set_hmac_auth_key(struct qcedev_async_req *areq,
			authkey_areq.sha_op_req.alg = QCEDEV_ALG_SHA1;
		if (areq->sha_op_req.alg == QCEDEV_ALG_SHA256_HMAC)
			authkey_areq.sha_op_req.alg = QCEDEV_ALG_SHA256;
		if (areq->sha_op_req.alg == QCEDEV_ALG_SHA384_HMAC)
			authkey_areq.sha_op_req.alg = QCEDEV_ALG_SHA384;
		if (areq->sha_op_req.alg == QCEDEV_ALG_SHA512_HMAC)
			authkey_areq.sha_op_req.alg = QCEDEV_ALG_SHA512;

		authkey_areq.op_type = QCEDEV_CRYPTO_OPER_SHA;

@@ -1034,15 +1118,16 @@ static int qcedev_hmac_get_ohash(struct qcedev_async_req *qcedev_areq,
	uint32_t sha_block_size = 0;
	uint32_t sha_digest_size = 0;

	if (qcedev_areq->sha_op_req.alg == QCEDEV_ALG_SHA1_HMAC) {
	sha_block_size = qcedev_get_block_size(qcedev_areq->sha_op_req.alg);
	if (qcedev_areq->sha_op_req.alg == QCEDEV_ALG_SHA1_HMAC)
		sha_digest_size = SHA1_DIGEST_SIZE;
		sha_block_size = SHA1_BLOCK_SIZE;
	} else {
		if (qcedev_areq->sha_op_req.alg == QCEDEV_ALG_SHA256_HMAC) {
	if (qcedev_areq->sha_op_req.alg == QCEDEV_ALG_SHA256_HMAC)
		sha_digest_size = SHA256_DIGEST_SIZE;
			sha_block_size = SHA256_BLOCK_SIZE;
		}
	}
	if (qcedev_areq->sha_op_req.alg == QCEDEV_ALG_SHA384_HMAC)
		sha_digest_size = SHA384_DIGEST_SIZE;
	if (qcedev_areq->sha_op_req.alg == QCEDEV_ALG_SHA512_HMAC)
		sha_digest_size = SHA512_DIGEST_SIZE;

	k_src = kmalloc(sha_block_size, GFP_KERNEL);
	if (k_src == NULL)
		return -ENOMEM;
@@ -1076,6 +1161,18 @@ static int qcedev_hmac_get_ohash(struct qcedev_async_req *qcedev_areq,
			&_std_init_vector_sha256_uint8[0], SHA256_DIGEST_SIZE);
		handle->sha_ctxt.diglen = SHA256_DIGEST_SIZE;
	}

	if (qcedev_areq->sha_op_req.alg == QCEDEV_ALG_SHA384_HMAC) {
		memcpy(&handle->sha_ctxt.digest[0],
			&_std_init_vector_sha384_uint8[0], SHA512_DIGEST_SIZE);
		handle->sha_ctxt.diglen = SHA384_DIGEST_SIZE;
	}

	if (qcedev_areq->sha_op_req.alg == QCEDEV_ALG_SHA512_HMAC) {
		memcpy(&handle->sha_ctxt.digest[0],
			&_std_init_vector_sha512_uint8[0], SHA512_DIGEST_SIZE);
		handle->sha_ctxt.diglen = SHA512_DIGEST_SIZE;
	}
	err = submit_req(qcedev_areq, handle);

	handle->sha_ctxt.last_blk = 0;
@@ -1098,10 +1195,7 @@ static int qcedev_hmac_update_iokey(struct qcedev_async_req *areq,
	else
		constant = 0x5c;

	if (areq->sha_op_req.alg == QCEDEV_ALG_SHA1_HMAC)
		sha_block_size = SHA1_BLOCK_SIZE;
	else
		sha_block_size = SHA256_BLOCK_SIZE;
	sha_block_size = qcedev_get_block_size(areq->sha_op_req.alg);

	memset(&handle->sha_ctxt.trailing_buf[0], 0, sha_block_size);
	for (i = 0; i < sha_block_size; i++)
@@ -1151,7 +1245,9 @@ static int qcedev_hash_init(struct qcedev_async_req *areq,
				struct scatterlist *sg_src)
{
	if ((areq->sha_op_req.alg == QCEDEV_ALG_SHA1) ||
			(areq->sha_op_req.alg == QCEDEV_ALG_SHA256))
			(areq->sha_op_req.alg == QCEDEV_ALG_SHA256) ||
			(areq->sha_op_req.alg == QCEDEV_ALG_SHA384) ||
			(areq->sha_op_req.alg == QCEDEV_ALG_SHA512))
		return qcedev_sha_init(areq, handle);
	else
		return qcedev_hmac_init(areq, handle, sg_src);
@@ -1168,7 +1264,9 @@ static int qcedev_hash_final(struct qcedev_async_req *areq,
				struct qcedev_handle *handle)
{
	if ((areq->sha_op_req.alg == QCEDEV_ALG_SHA1) ||
			(areq->sha_op_req.alg == QCEDEV_ALG_SHA256))
			(areq->sha_op_req.alg == QCEDEV_ALG_SHA256) ||
			(areq->sha_op_req.alg == QCEDEV_ALG_SHA384) ||
			(areq->sha_op_req.alg == QCEDEV_ALG_SHA512))
		return qcedev_sha_final(areq, handle);
	else
		return qcedev_hmac_final(areq, handle);
@@ -1635,7 +1733,9 @@ static int qcedev_check_sha_params(struct qcedev_sha_op_req *req,
		goto sha_error;
	}
	if ((req->alg == QCEDEV_ALG_SHA1_HMAC) ||
			(req->alg == QCEDEV_ALG_SHA256_HMAC)) {
			(req->alg == QCEDEV_ALG_SHA256_HMAC) ||
			(req->alg == QCEDEV_ALG_SHA384_HMAC) ||
			(req->alg == QCEDEV_ALG_SHA512_HMAC)) {
		if (req->authkey == NULL) {
			pr_err("%s: Invalid authkey pointer\n", __func__);
			goto sha_error;
+1 −1
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ struct qcedev_sha_ctxt {
	uint32_t	auth_data[4];
	uint8_t	digest[QCEDEV_MAX_SHA_DIGEST];
	uint32_t	diglen;
	uint8_t	trailing_buf[64];
	uint8_t	trailing_buf[QCEDEV_MAX_SHA_BLOCK_SIZE];
	uint32_t	trailing_buf_len;
	uint8_t	first_blk;
	uint8_t	last_blk;
Loading