Commit 3b8b12cd authored by Jacek Kalwas's avatar Jacek Kalwas Committed by Jim Harris
Browse files

accel: add tweak mode support



It was already done on SMA layer before, that is just an alignment.

Signed-off-by: default avatarJacek Kalwas <jacek.kalwas@intel.com>
Change-Id: I247b7973335745153a2371680d5d405068880426
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/17528


Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@nvidia.com>
Community-CI: Mellanox Build Bot
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent d20ae7ff
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ struct spdk_accel_crypto_key_create_param {
	char *cipher;	/**< Cipher to be used for crypto operations */
	char *hex_key;	/**< Hexlified key */
	char *hex_key2;	/**< Hexlified key2 */
	char *tweak_mode;	/**< Tweak mode */
	char *key_name;	/**< Key name */
};

+25 −0
Original line number Diff line number Diff line
@@ -21,12 +21,32 @@ void spdk_accel_task_complete(struct spdk_accel_task *task, int status);
/** Some reasonable key length used with strnlen() */
#define SPDK_ACCEL_CRYPTO_KEY_MAX_HEX_LENGTH (256 + 1)

enum spdk_accel_crypto_tweak_mode {
	/* Tweak[127:0] = {64'b0, LBA[63:0]} */
	SPDK_ACCEL_CRYPTO_TWEAK_MODE_SIMPLE_LBA,

	/* Tweak[127:0] = {1’b0, ~LBA[62:0], LBA[63:0]} */
	SPDK_ACCEL_CRYPTO_TWEAK_MODE_JOIN_NEG_LBA_WITH_LBA,

	/* Tweak is derived from LBA that is internally incremented by 1 for every 512 bytes processed
	 * so initial lba = (BLOCK_SIZE_IN_BYTES / 512) * LBA
	 * Tweak[127:0] = {lba[127:0]} */
	SPDK_ACCEL_CRYPTO_TWEAK_MODE_INCR_512_FULL_LBA,

	/* Tweak is derived from LBA that is internally incremented by 1 for every 512 bytes processed
	 * so initial lba = (BLOCK_SIZE_IN_BYTES / 512) * LBA
	 * Tweak[127:0] = {lba[63:0], 64'b0} */
	SPDK_ACCEL_CRYPTO_TWEAK_MODE_INCR_512_UPPER_LBA,
	SPDK_ACCEL_CRYPTO_TWEAK_MODE_MAX,
};

struct spdk_accel_crypto_key {
	void *priv;					/**< Module private data */
	char *key;					/**< Key in binary form */
	size_t key_size;				/**< Key size in bytes */
	char *key2;					/**< Key2 in binary form */
	size_t key2_size;				/**< Key2 size in bytes */
	enum spdk_accel_crypto_tweak_mode tweak_mode;
	struct spdk_accel_module_if *module_if;			/**< Accel module the key belongs to */
	struct spdk_accel_crypto_key_create_param param;	/**< User input parameters */
	TAILQ_ENTRY(spdk_accel_crypto_key) link;
@@ -150,6 +170,11 @@ struct spdk_accel_module_if {
	int (*crypto_key_init)(struct spdk_accel_crypto_key *key);
	void (*crypto_key_deinit)(struct spdk_accel_crypto_key *key);

	/**
	 * Returns true if given tweak mode is supported. If module doesn't implement that function it shall support SIMPLE LBA mode.
	 */
	bool (*crypto_supports_tweak_mode)(enum spdk_accel_crypto_tweak_mode tweak_mode);

	/**
	 * Returns memory domains supported by the module.  If NULL, the module does not support
	 * memory domains.  The `domains` array can be NULL, in which case this function only
+51 −0
Original line number Diff line number Diff line
@@ -35,6 +35,9 @@
#define ACCEL_BUFFER_BASE		((void *)(1ull << 63))
#define ACCEL_BUFFER_OFFSET_MASK	((uintptr_t)ACCEL_BUFFER_BASE - 1)

#define ACCEL_CRYPTO_TWEAK_MODE_DEFAULT	SPDK_ACCEL_CRYPTO_TWEAK_MODE_SIMPLE_LBA
#define ACCEL_CRYPTO_TWEAK_MODE_CHAR_MAX	32

struct accel_module {
	struct spdk_accel_module_if	*module;
	bool				supports_memory_domains;
@@ -1987,6 +1990,7 @@ accel_crypto_key_free_mem(struct spdk_accel_crypto_key *key)
		spdk_memset_s(key->param.hex_key2, key->key2_size * 2, 0, key->key2_size * 2);
		free(key->param.hex_key2);
	}
	free(key->param.tweak_mode);
	free(key->param.key_name);
	free(key->param.cipher);
	if (key->key) {
@@ -2029,6 +2033,13 @@ accel_aes_xts_keys_equal(const char *k1, size_t k1_len, const char *k2, size_t k
	return x == 0;
}

static const char *g_tweak_modes[SPDK_ACCEL_CRYPTO_TWEAK_MODE_MAX] = {
	[SPDK_ACCEL_CRYPTO_TWEAK_MODE_SIMPLE_LBA] = "SIMPLE_LBA",
	[SPDK_ACCEL_CRYPTO_TWEAK_MODE_JOIN_NEG_LBA_WITH_LBA] = "JOIN_NEG_LBA_WITH_LBA",
	[SPDK_ACCEL_CRYPTO_TWEAK_MODE_INCR_512_FULL_LBA] = "INCR_512_FULL_LBA",
	[SPDK_ACCEL_CRYPTO_TWEAK_MODE_INCR_512_UPPER_LBA] = "INCR_512_UPPER_LBA",
};

int
spdk_accel_crypto_key_create(const struct spdk_accel_crypto_key_create_param *param)
{
@@ -2121,6 +2132,42 @@ spdk_accel_crypto_key_create(const struct spdk_accel_crypto_key_create_param *pa
		}
	}


	key->tweak_mode = ACCEL_CRYPTO_TWEAK_MODE_DEFAULT;
	if (param->tweak_mode) {
		bool found = false;

		key->param.tweak_mode = strdup(param->tweak_mode);
		if (!key->param.tweak_mode) {
			rc = -ENOMEM;
			goto error;
		}

		for (uint32_t i = 0; i < SPDK_COUNTOF(g_tweak_modes); ++i) {
			assert(strlen(g_tweak_modes[i]) < ACCEL_CRYPTO_TWEAK_MODE_CHAR_MAX);

			if (strncmp(param->tweak_mode, g_tweak_modes[i], ACCEL_CRYPTO_TWEAK_MODE_CHAR_MAX) == 0) {
				key->tweak_mode = i;
				found = true;
				break;
			}
		}

		if (!found) {
			SPDK_ERRLOG("Failed to parse tweak mode\n");
			rc = -EINVAL;
			goto error;
		}
	}

	if ((!module->crypto_supports_tweak_mode && key->tweak_mode != ACCEL_CRYPTO_TWEAK_MODE_DEFAULT) ||
	    (module->crypto_supports_tweak_mode && !module->crypto_supports_tweak_mode(key->tweak_mode))) {
		SPDK_ERRLOG("Module %s doesn't support %s tweak mode\n", module->name,
			    g_tweak_modes[key->tweak_mode]);
		rc = -EINVAL;
		goto error;
	}

	key->module_if = module;

	spdk_spin_lock(&g_keyring_spin);
@@ -2460,6 +2507,10 @@ __accel_crypto_key_dump_param(struct spdk_json_write_ctx *w, struct spdk_accel_c
	if (key->param.hex_key2) {
		spdk_json_write_named_string(w, "key2", key->param.hex_key2);
	}

	if (key->param.tweak_mode) {
		spdk_json_write_named_string(w, "tweak_mode", key->param.tweak_mode);
	}
}

void
+2 −0
Original line number Diff line number Diff line
@@ -183,6 +183,7 @@ static const struct spdk_json_object_decoder rpc_accel_dek_create_decoders[] = {
	{"cipher", offsetof(struct rpc_accel_crypto_key_create, param.cipher), spdk_json_decode_string},
	{"key", offsetof(struct rpc_accel_crypto_key_create, param.hex_key),   spdk_json_decode_string},
	{"key2", offsetof(struct rpc_accel_crypto_key_create, param.hex_key2), spdk_json_decode_string, true},
	{"tweak_mode", offsetof(struct rpc_accel_crypto_key_create, param.tweak_mode), spdk_json_decode_string, true},
	{"name", offsetof(struct rpc_accel_crypto_key_create, param.key_name), spdk_json_decode_string},
};

@@ -222,6 +223,7 @@ cleanup:
		spdk_memset_s(req.param.hex_key2, key_size, 0, key_size);
		free(req.param.hex_key2);
	}
	free(req.param.tweak_mode);
	free(req.param.key_name);
}
SPDK_RPC_REGISTER("accel_crypto_key_create", rpc_accel_crypto_key_create, SPDK_RPC_RUNTIME)
+8 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ static struct spdk_accel_module_if g_sw_module;

static void sw_accel_crypto_key_deinit(struct spdk_accel_crypto_key *_key);
static int sw_accel_crypto_key_init(struct spdk_accel_crypto_key *key);
static bool sw_accel_crypto_supports_tweak_mode(enum spdk_accel_crypto_tweak_mode tweak_mode);

/* Post SW completions to a list and complete in a poller as we don't want to
 * complete them on the caller's stack as they'll likely submit another. */
@@ -523,6 +524,7 @@ static struct spdk_accel_module_if g_sw_module = {
	.submit_tasks		= sw_accel_submit_tasks,
	.crypto_key_init	= sw_accel_crypto_key_init,
	.crypto_key_deinit	= sw_accel_crypto_key_deinit,
	.crypto_supports_tweak_mode	= sw_accel_crypto_supports_tweak_mode,
};

static int
@@ -682,4 +684,10 @@ sw_accel_crypto_key_deinit(struct spdk_accel_crypto_key *key)
	free(key->priv);
}

static bool
sw_accel_crypto_supports_tweak_mode(enum spdk_accel_crypto_tweak_mode tweak_mode)
{
	return tweak_mode == SPDK_ACCEL_CRYPTO_TWEAK_MODE_SIMPLE_LBA;
}

SPDK_ACCEL_MODULE_REGISTER(sw, &g_sw_module)
Loading