@@ -265,6 +265,12 @@ static int cryptodev_builtin_sym_operation(
return -VIRTIO_CRYPTO_INVSESS;
}
+ if (op_info->op_type == VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) {
+ error_setg(errp,
+ "Algorithm chain is unsupported for cryptdoev-builtin");
+ return -VIRTIO_CRYPTO_NOTSUPP;
+ }
+
sess = builtin->sessions[op_info->session_id];
ret = qcrypto_cipher_setiv(sess->cipher, op_info->iv,
@@ -390,21 +390,42 @@ virtio_crypto_get_request(VirtIOCrypto *s, VirtQueue *vq)
static CryptoDevBackendSymOpInfo *
virtio_crypto_sym_op_helper(VirtIODevice *vdev,
- struct virtio_crypto_cipher_para *para,
- uint32_t aad_len,
- struct iovec *iov, unsigned int out_num,
- uint32_t hash_result_len,
- uint32_t hash_start_src_offset)
+ struct virtio_crypto_cipher_para *cipher_para,
+ struct virtio_crypto_alg_chain_data_para *alg_chain_para,
+ struct iovec *iov, unsigned int out_num)
{
CryptoDevBackendSymOpInfo *op_info;
- uint32_t src_len, dst_len;
- uint32_t iv_len;
+ uint32_t src_len = 0, dst_len = 0;
+ uint32_t iv_len = 0;
+ uint32_t aad_len = 0, hash_result_len = 0;
+ uint32_t hash_start_src_offset = 0, len_to_hash = 0;
+ uint32_t cipher_start_src_offset = 0, len_to_cipher = 0;
+
size_t max_len, curr_size = 0;
size_t s;
- iv_len = virtio_ldl_p(vdev, ¶->iv_len);
- src_len = virtio_ldl_p(vdev, ¶->src_data_len);
- dst_len = virtio_ldl_p(vdev, ¶->dst_data_len);
+ /* Plain cipher */
+ if (cipher_para) {
+ iv_len = virtio_ldl_p(vdev, &cipher_para->iv_len);
+ src_len = virtio_ldl_p(vdev, &cipher_para->src_data_len);
+ dst_len = virtio_ldl_p(vdev, &cipher_para->dst_data_len);
+ } else if (alg_chain_para) { /* Algorithm chain */
+ iv_len = virtio_ldl_p(vdev, &alg_chain_para->iv_len);
+ src_len = virtio_ldl_p(vdev, &alg_chain_para->src_data_len);
+ dst_len = virtio_ldl_p(vdev, &alg_chain_para->dst_data_len);
+
+ aad_len = virtio_ldl_p(vdev, &alg_chain_para->aad_len);
+ hash_result_len = virtio_ldl_p(vdev,
+ &alg_chain_para->hash_result_len);
+ hash_start_src_offset = virtio_ldl_p(vdev,
+ &alg_chain_para->hash_start_src_offset);
+ cipher_start_src_offset = virtio_ldl_p(vdev,
+ &alg_chain_para->cipher_start_src_offset);
+ len_to_cipher = virtio_ldl_p(vdev, &alg_chain_para->len_to_cipher);
+ len_to_hash = virtio_ldl_p(vdev, &alg_chain_para->len_to_hash);
+ } else {
+ return NULL;
+ }
max_len = iv_len + aad_len + src_len + dst_len + hash_result_len;
op_info = g_malloc0(sizeof(CryptoDevBackendSymOpInfo) + max_len);
@@ -414,6 +435,9 @@ virtio_crypto_sym_op_helper(VirtIODevice *vdev,
op_info->aad_len = aad_len;
op_info->digest_result_len = hash_result_len;
op_info->hash_start_src_offset = hash_start_src_offset;
+ op_info->len_to_hash = len_to_hash;
+ op_info->cipher_start_src_offset = cipher_start_src_offset;
+ op_info->len_to_cipher = len_to_cipher;
/* Handle the initilization vector */
if (op_info->iv_len > 0) {
DPRINTF("iv_len=%" PRIu32 "\n", op_info->iv_len);
@@ -491,25 +515,15 @@ virtio_crypto_handle_sym_req(VirtIOCrypto *vcrypto,
if (op_type == VIRTIO_CRYPTO_SYM_OP_CIPHER) {
op_info = virtio_crypto_sym_op_helper(vdev, &req->u.cipher.para,
- 0, iov, out_num, 0, 0);
+ NULL, iov, out_num);
if (!op_info) {
return -EFAULT;
}
op_info->op_type = op_type;
} else if (op_type == VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) {
- uint32_t aad_len, hash_result_len;
- uint32_t hash_start_src_offset;
-
- aad_len = virtio_ldl_p(vdev, &req->u.chain.para.aad_len);
- hash_result_len = virtio_ldl_p(vdev,
- &req->u.chain.para.hash_result_len);
- hash_start_src_offset = virtio_ldl_p(vdev,
- &req->u.chain.para.hash_start_src_offset);
- /* cipher part */
- op_info = virtio_crypto_sym_op_helper(vdev, &req->u.chain.para.cipher,
- aad_len, iov, out_num,
- hash_result_len,
- hash_start_src_offset);
+ op_info = virtio_crypto_sym_op_helper(vdev, NULL,
+ &req->u.chain.para,
+ iov, out_num);
if (!op_info) {
return -EFAULT;
}
@@ -301,7 +301,15 @@ struct virtio_crypto_mac_data_req {
};
struct virtio_crypto_alg_chain_data_para {
- struct virtio_crypto_cipher_para cipher;
+ __virtio32 iv_len;
+ /* Length of source data */
+ __virtio32 src_data_len;
+ /* Length of destination data */
+ __virtio32 dst_data_len;
+ /* Starting point for cipher processing in source data */
+ __virtio32 cipher_start_src_offset;
+ /* Length of the source data that the cipher will be computed on */
+ __virtio32 len_to_cipher;
/* Starting point for hash processing in source data */
__virtio32 hash_start_src_offset;
/* Length of the source data that the hash will be computed on */
@@ -310,6 +318,7 @@ struct virtio_crypto_alg_chain_data_para {
__virtio32 aad_len;
/* Length of the hash result */
__virtio32 hash_result_len;
+ __virtio32 reserved;
};
struct virtio_crypto_alg_chain_data_req {
@@ -108,7 +108,15 @@ typedef struct CryptoDevBackendSymSessionInfo {
* @dst_len: byte length of destination data
* @digest_result_len: byte length of hash digest result
* @hash_start_src_offset: Starting point for hash processing, specified
- * as number of bytes from start of packet in source data
+ * as number of bytes from start of packet in source data, only used for
+ * algorithm chain
+ * @cipher_start_src_offset: Starting point for cipher processing, specified
+ * as number of bytes from start of packet in source data, only used for
+ * algorithm chain
+ * @len_to_hash: byte length of source data on which the hash
+ * operation will be computed, only used for algorithm chain
+ * @len_to_cipher: byte length of source data on which the cipher
+ * operation will be computed, only used for algorithm chain
* @op_type: operation type (refer to virtio_crypto.h)
* @iv: point to the initialization vector or counter
* @src: point to the source data
@@ -126,6 +134,9 @@ typedef struct CryptoDevBackendSymOpInfo {
uint32_t dst_len;
uint32_t digest_result_len;
uint32_t hash_start_src_offset;
+ uint32_t cipher_start_src_offset;
+ uint32_t len_to_hash;
+ uint32_t len_to_cipher;
uint8_t op_type;
uint8_t *iv;
uint8_t *src;
For one source buffer, we can do cipher and hash operations partly in algorithms chainning mode. We updated the corresponding part in virtio crypto specification firstly. The cryptodev-builtin backend doesn't support algorithm chainning, so let's add a check for it. Signed-off-by: Gonglei <arei.gonglei@huawei.com> --- backends/cryptodev-builtin.c | 6 +++ hw/virtio/virtio-crypto.c | 62 ++++++++++++++++---------- include/standard-headers/linux/virtio_crypto.h | 11 ++++- include/sysemu/cryptodev.h | 13 +++++- 4 files changed, 66 insertions(+), 26 deletions(-)