Commit c972fa12 authored by Vladimir Sementsov-Ogievskiy's avatar Vladimir Sementsov-Ogievskiy Committed by Daniel P. Berrangé
Browse files

crypto: support multiple threads accessing one QCryptoBlock



The two thing that should be handled are cipher and ivgen. For ivgen
the solution is just mutex, as iv calculations should not be long in
comparison with encryption/decryption. And for cipher let's just keep
per-thread ciphers.

Signed-off-by: default avatarVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: default avatarAlberto Garcia <berto@igalia.com>
Signed-off-by: default avatarDaniel P. Berrangé <berrange@redhat.com>
parent 0f0d596c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -229,6 +229,7 @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
                                       block_crypto_read_func,
                                       bs,
                                       cflags,
                                       1,
                                       errp);

    if (!crypto->block) {
+1 −1
Original line number Diff line number Diff line
@@ -213,7 +213,7 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
                cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
            }
            s->crypto = qcrypto_block_open(crypto_opts, "encrypt.",
                                           NULL, NULL, cflags, errp);
                                           NULL, NULL, cflags, 1, errp);
            if (!s->crypto) {
                ret = -EINVAL;
                goto fail;
+2 −2
Original line number Diff line number Diff line
@@ -294,7 +294,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
            }
            s->crypto = qcrypto_block_open(s->crypto_opts, "encrypt.",
                                           qcow2_crypto_hdr_read_func,
                                           bs, cflags, errp);
                                           bs, cflags, 1, errp);
            if (!s->crypto) {
                return -EINVAL;
            }
@@ -1445,7 +1445,7 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
                cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
            }
            s->crypto = qcrypto_block_open(s->crypto_opts, "encrypt.",
                                           NULL, NULL, cflags, errp);
                                           NULL, NULL, cflags, 1, errp);
            if (!s->crypto) {
                ret = -EINVAL;
                goto fail;
+10 −12
Original line number Diff line number Diff line
@@ -636,6 +636,7 @@ qcrypto_block_luks_open(QCryptoBlock *block,
                        QCryptoBlockReadFunc readfunc,
                        void *opaque,
                        unsigned int flags,
                        size_t n_threads,
                        Error **errp)
{
    QCryptoBlockLUKS *luks;
@@ -836,11 +837,10 @@ qcrypto_block_luks_open(QCryptoBlock *block,
            goto fail;
        }

        block->cipher = qcrypto_cipher_new(cipheralg,
                                           ciphermode,
                                           masterkey, masterkeylen,
        ret = qcrypto_block_init_cipher(block, cipheralg, ciphermode,
                                        masterkey, masterkeylen, n_threads,
                                        errp);
        if (!block->cipher) {
        if (ret < 0) {
            ret = -ENOTSUP;
            goto fail;
        }
@@ -863,7 +863,7 @@ qcrypto_block_luks_open(QCryptoBlock *block,

 fail:
    g_free(masterkey);
    qcrypto_cipher_free(block->cipher);
    qcrypto_block_free_cipher(block);
    qcrypto_ivgen_free(block->ivgen);
    g_free(luks);
    g_free(password);
@@ -1030,11 +1030,9 @@ qcrypto_block_luks_create(QCryptoBlock *block,


    /* Setup the block device payload encryption objects */
    block->cipher = qcrypto_cipher_new(luks_opts.cipher_alg,
                                       luks_opts.cipher_mode,
                                       masterkey, luks->header.key_bytes,
                                       errp);
    if (!block->cipher) {
    if (qcrypto_block_init_cipher(block, luks_opts.cipher_alg,
                                  luks_opts.cipher_mode, masterkey,
                                  luks->header.key_bytes, 1, errp) < 0) {
        goto error;
    }

@@ -1341,7 +1339,7 @@ qcrypto_block_luks_create(QCryptoBlock *block,
    qcrypto_ivgen_free(ivgen);
    qcrypto_cipher_free(cipher);

    qcrypto_cipher_free(block->cipher);
    qcrypto_block_free_cipher(block);
    qcrypto_ivgen_free(block->ivgen);

    g_free(luks);
+11 −9
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ qcrypto_block_qcow_has_format(const uint8_t *buf G_GNUC_UNUSED,
static int
qcrypto_block_qcow_init(QCryptoBlock *block,
                        const char *keysecret,
                        size_t n_threads,
                        Error **errp)
{
    char *password;
@@ -71,11 +72,11 @@ qcrypto_block_qcow_init(QCryptoBlock *block,
        goto fail;
    }

    block->cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_128,
    ret = qcrypto_block_init_cipher(block, QCRYPTO_CIPHER_ALG_AES_128,
                                    QCRYPTO_CIPHER_MODE_CBC,
                                    keybuf, G_N_ELEMENTS(keybuf),
                                       errp);
    if (!block->cipher) {
                                    n_threads, errp);
    if (ret < 0) {
        ret = -ENOTSUP;
        goto fail;
    }
@@ -86,7 +87,7 @@ qcrypto_block_qcow_init(QCryptoBlock *block,
    return 0;

 fail:
    qcrypto_cipher_free(block->cipher);
    qcrypto_block_free_cipher(block);
    qcrypto_ivgen_free(block->ivgen);
    return ret;
}
@@ -99,6 +100,7 @@ qcrypto_block_qcow_open(QCryptoBlock *block,
                        QCryptoBlockReadFunc readfunc G_GNUC_UNUSED,
                        void *opaque G_GNUC_UNUSED,
                        unsigned int flags,
                        size_t n_threads,
                        Error **errp)
{
    if (flags & QCRYPTO_BLOCK_OPEN_NO_IO) {
@@ -112,8 +114,8 @@ qcrypto_block_qcow_open(QCryptoBlock *block,
                       optprefix ? optprefix : "");
            return -1;
        }
        return qcrypto_block_qcow_init(block,
                                       options->u.qcow.key_secret, errp);
        return qcrypto_block_qcow_init(block, options->u.qcow.key_secret,
                                       n_threads, errp);
    }
}

@@ -133,7 +135,7 @@ qcrypto_block_qcow_create(QCryptoBlock *block,
        return -1;
    }
    /* QCow2 has no special header, since everything is hardwired */
    return qcrypto_block_qcow_init(block, options->u.qcow.key_secret, errp);
    return qcrypto_block_qcow_init(block, options->u.qcow.key_secret, 1, errp);
}


Loading