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

Commit e652399e authored by Gary R Hook's avatar Gary R Hook Committed by Herbert Xu
Browse files

crypto: ccp - Fix XTS-AES-128 support on v5 CCPs



Version 5 CCPs have some new requirements for XTS-AES: the type field
must be specified, and the key requires 512 bits, with each part
occupying 256 bits and padded with zeroes.

cc: <stable@vger.kernel.org> # 4.9.x+

Signed-off-by: default avatarGary R Hook <ghook@amd.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 7c83d689
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
/*
 * AMD Cryptographic Coprocessor (CCP) AES XTS crypto API support
 *
 * Copyright (C) 2013 Advanced Micro Devices, Inc.
 * Copyright (C) 2013,2017 Advanced Micro Devices, Inc.
 *
 * Author: Gary R Hook <gary.hook@amd.com>
 * Author: Tom Lendacky <thomas.lendacky@amd.com>
 *
 * This program is free software; you can redistribute it and/or modify
@@ -164,6 +165,7 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request *req,
	memset(&rctx->cmd, 0, sizeof(rctx->cmd));
	INIT_LIST_HEAD(&rctx->cmd.entry);
	rctx->cmd.engine = CCP_ENGINE_XTS_AES_128;
	rctx->cmd.u.xts.type = CCP_AES_TYPE_128;
	rctx->cmd.u.xts.action = (encrypt) ? CCP_AES_ACTION_ENCRYPT
					   : CCP_AES_ACTION_DECRYPT;
	rctx->cmd.u.xts.unit_size = unit_size;
+2 −0
Original line number Diff line number Diff line
@@ -145,6 +145,7 @@ union ccp_function {
#define	CCP_AES_MODE(p)		((p)->aes.mode)
#define	CCP_AES_TYPE(p)		((p)->aes.type)
#define	CCP_XTS_SIZE(p)		((p)->aes_xts.size)
#define	CCP_XTS_TYPE(p)		((p)->aes_xts.type)
#define	CCP_XTS_ENCRYPT(p)	((p)->aes_xts.encrypt)
#define	CCP_DES3_SIZE(p)	((p)->des3.size)
#define	CCP_DES3_ENCRYPT(p)	((p)->des3.encrypt)
@@ -344,6 +345,7 @@ static int ccp5_perform_xts_aes(struct ccp_op *op)
	CCP5_CMD_PROT(&desc) = 0;

	function.raw = 0;
	CCP_XTS_TYPE(&function) = op->u.xts.type;
	CCP_XTS_ENCRYPT(&function) = op->u.xts.action;
	CCP_XTS_SIZE(&function) = op->u.xts.unit_size;
	CCP5_CMD_FUNCTION(&desc) = function.raw;
+2 −0
Original line number Diff line number Diff line
@@ -194,6 +194,7 @@
#define CCP_AES_CTX_SB_COUNT		1

#define CCP_XTS_AES_KEY_SB_COUNT	1
#define CCP5_XTS_AES_KEY_SB_COUNT	2
#define CCP_XTS_AES_CTX_SB_COUNT	1

#define CCP_DES3_KEY_SB_COUNT		1
@@ -498,6 +499,7 @@ struct ccp_aes_op {
};

struct ccp_xts_aes_op {
	enum ccp_aes_type type;
	enum ccp_aes_action action;
	enum ccp_xts_aes_unit_size unit_size;
};
+34 −9
Original line number Diff line number Diff line
@@ -1038,6 +1038,8 @@ static int ccp_run_xts_aes_cmd(struct ccp_cmd_queue *cmd_q,
	struct ccp_op op;
	unsigned int unit_size, dm_offset;
	bool in_place = false;
	unsigned int sb_count;
	enum ccp_aes_type aestype;
	int ret;

	switch (xts->unit_size) {
@@ -1061,7 +1063,9 @@ static int ccp_run_xts_aes_cmd(struct ccp_cmd_queue *cmd_q,
		return -EINVAL;
	}

	if (xts->key_len != AES_KEYSIZE_128)
	if (xts->key_len == AES_KEYSIZE_128)
		aestype = CCP_AES_TYPE_128;
	else
		return -EINVAL;

	if (!xts->final && (xts->src_len & (AES_BLOCK_SIZE - 1)))
@@ -1083,23 +1087,44 @@ static int ccp_run_xts_aes_cmd(struct ccp_cmd_queue *cmd_q,
	op.sb_key = cmd_q->sb_key;
	op.sb_ctx = cmd_q->sb_ctx;
	op.init = 1;
	op.u.xts.type = aestype;
	op.u.xts.action = xts->action;
	op.u.xts.unit_size = xts->unit_size;

	/* All supported key sizes fit in a single (32-byte) SB entry
	 * and must be in little endian format. Use the 256-bit byte
	 * swap passthru option to convert from big endian to little
	 * endian.
	/* A version 3 device only supports 128-bit keys, which fits into a
	 * single SB entry. A version 5 device uses a 512-bit vector, so two
	 * SB entries.
	 */
	if (cmd_q->ccp->vdata->version == CCP_VERSION(3, 0))
		sb_count = CCP_XTS_AES_KEY_SB_COUNT;
	else
		sb_count = CCP5_XTS_AES_KEY_SB_COUNT;
	ret = ccp_init_dm_workarea(&key, cmd_q,
				   CCP_XTS_AES_KEY_SB_COUNT * CCP_SB_BYTES,
				   sb_count * CCP_SB_BYTES,
				   DMA_TO_DEVICE);
	if (ret)
		return ret;

	if (cmd_q->ccp->vdata->version == CCP_VERSION(3, 0)) {
		/* All supported key sizes must be in little endian format.
		 * Use the 256-bit byte swap passthru option to convert from
		 * big endian to little endian.
		 */
		dm_offset = CCP_SB_BYTES - AES_KEYSIZE_128;
		ccp_set_dm_area(&key, dm_offset, xts->key, 0, xts->key_len);
	ccp_set_dm_area(&key, 0, xts->key, dm_offset, xts->key_len);
		ccp_set_dm_area(&key, 0, xts->key, xts->key_len, xts->key_len);
	} else {
		/* Version 5 CCPs use a 512-bit space for the key: each portion
		 * occupies 256 bits, or one entire slot, and is zero-padded.
		 */
		unsigned int pad;

		dm_offset = CCP_SB_BYTES;
		pad = dm_offset - xts->key_len;
		ccp_set_dm_area(&key, pad, xts->key, 0, xts->key_len);
		ccp_set_dm_area(&key, dm_offset + pad, xts->key, xts->key_len,
				xts->key_len);
	}
	ret = ccp_copy_to_sb(cmd_q, &key, op.jobid, op.sb_key,
			     CCP_PASSTHRU_BYTESWAP_256BIT);
	if (ret) {
+2 −1
Original line number Diff line number Diff line
/*
 * AMD Cryptographic Coprocessor (CCP) driver
 *
 * Copyright (C) 2013,2016 Advanced Micro Devices, Inc.
 * Copyright (C) 2013,2017 Advanced Micro Devices, Inc.
 *
 * Author: Tom Lendacky <thomas.lendacky@amd.com>
 * Author: Gary R Hook <gary.hook@amd.com>
@@ -229,6 +229,7 @@ enum ccp_xts_aes_unit_size {
 * AES operation the new IV overwrites the old IV.
 */
struct ccp_xts_aes_engine {
	enum ccp_aes_type type;
	enum ccp_aes_action action;
	enum ccp_xts_aes_unit_size unit_size;