From nobody Tue Feb 10 10:19:21 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1598634708; cv=none; d=zohomail.com; s=zohoarc; b=VM+yciv4zgDykWoKhQnV/9kBzW2mGheRh7/BTlwNdLcXH0+NkfXzf3nygLpkh+G8x6o1RPlbEkOixer+4hjJbqO5RpbYuRyydZ83VcXVGh5MCuc0EtoTf2yFpuYHghO3Eadq/Nty+SzyKkZYXV/TZOS1i25SNptFO7OKm+dFpzw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1598634708; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=xjAvkiOCc/NtSfmsWN0x73KFFAEhwgsUyYE/lGgma1M=; b=CkLseB3d70j/Rm9g5jek26/dyZjLfSinhv0LP+sj1H1OHvA9Aqzd2NwZ0eTt9U0cALhawdmzJhgtp7ruKkAH2pxom8xwDFhTMxDuzxOQDD4P3Cfx+xJ85sDo7ievYNYdC1vBIxLsUXvlGWn3ITm2jMY1jMLfWM8jxNVK8umev8s= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1598634708208297.21091760760964; Fri, 28 Aug 2020 10:11:48 -0700 (PDT) Received: from localhost ([::1]:60194 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kBhuk-0007P6-Q2 for importer@patchew.org; Fri, 28 Aug 2020 13:11:46 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36852) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kBhp2-0004OU-NH for qemu-devel@nongnu.org; Fri, 28 Aug 2020 13:05:52 -0400 Received: from mail-pg1-x532.google.com ([2607:f8b0:4864:20::532]:35370) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kBhoy-00037u-19 for qemu-devel@nongnu.org; Fri, 28 Aug 2020 13:05:52 -0400 Received: by mail-pg1-x532.google.com with SMTP id g29so733645pgl.2 for ; Fri, 28 Aug 2020 10:05:47 -0700 (PDT) Received: from localhost.localdomain ([71.212.141.89]) by smtp.gmail.com with ESMTPSA id q12sm2277495pff.196.2020.08.28.10.05.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 Aug 2020 10:05:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=xjAvkiOCc/NtSfmsWN0x73KFFAEhwgsUyYE/lGgma1M=; b=RjfWO9ty3XE62f7nFHgLRJ8ft8Hrf8LoapgMwFEkzEiZ7I0hQ/V/1EHtnFs4szsjf6 MpYSlBhyYCoREPqzUAWc2yt+jq1imwUOMxrXfeCehZ1BV5MQfYbV0NiS1+04LXkD4OVl fPjaRET9SGnUCSeXr9j7m+C2mIuOzQBZvC4mZJKiwGilLoh1d/8voyrsAV9TQh88fR6H T2UvdlYIkWZNzBmjajdc0Yz72z8MtqfW2ajBRLIWmP77NfkSxYwdsIJP9LoLjNO5d/VA +J1vJLach3MRxi3usakX0RVOWLkVlkj9wPhapcs/hlpRkXlKHED8Tx6koNBtrfRUS6/N MPCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=xjAvkiOCc/NtSfmsWN0x73KFFAEhwgsUyYE/lGgma1M=; b=WVvswYimtlNRJ7qY5YwivbE2VAz2xF0n8PrifVPQyt3MEMLV7blwJpfhwPqHbDY5qS nywsrZwOy00lPoUvo5PSGxQ8qb1F+rVNkTYsZgg6nE7sU3Lrqs3d5Oa6hadShdn9JG4m 9Gwz7FMfxMolyuFjh6HMt4E2fNEtk4UvNEI/HKemBKFjYZ9+hZpjFbjWqiDAgztMUUzY QaZ8QWY9n45FBxyMdc+9tznMPSM8cDp9Pak8wLaPlPy22UxYCDCmezOGEpyFB8KOupDG 5I04kuIphP2R4ZvDevSsl4EJNdXhfRTA2SaepjkZNkAheSHTOGR1GsSoRKe7yx+QzHEM H3qg== X-Gm-Message-State: AOAM533W6gvrNaGzznKUu16Z0dnRZu+P2VwLFudb7xqu4GWV3t6dkjdg MtSwmOnIeknjEihBwmLo8iAlVP4DkoJ3jQ== X-Google-Smtp-Source: ABdhPJyyBrha3cGi8oLqOhEWJVhWvxIp2Qcg6U7Sc0Q++48d7uJ0nBojFOg5gx4ZVwUDBhq7nn1GYQ== X-Received: by 2002:aa7:96cf:: with SMTP id h15mr2087694pfq.294.1598634345521; Fri, 28 Aug 2020 10:05:45 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 15/16] crypto/nettle: Split QCryptoCipherNettle into subclasses Date: Fri, 28 Aug 2020 10:05:22 -0700 Message-Id: <20200828170523.418603-16-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200828170523.418603-1-richard.henderson@linaro.org> References: <20200828170523.418603-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::532; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x532.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: berrange@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Use separate classes for each cipher entry point: des_rfb, des3, aes128, aes192, aes256, cast128, serpent, and twofish. Generate wrappers for XTS only for CONFIG_QEMU_PRIVATE_XTS. This eliminates unreachable wrappers for DES_RFB, DES3 and CAST128, which have blocksizes that do not allow XTS mode. Reviewed-by: Daniel P. Berrang=C3=A9 Signed-off-by: Richard Henderson --- crypto/cipher-nettle.c.inc | 993 +++++++++++++++++++------------------ 1 file changed, 508 insertions(+), 485 deletions(-) diff --git a/crypto/cipher-nettle.c.inc b/crypto/cipher-nettle.c.inc index 36d57ef430..cac771e4ff 100644 --- a/crypto/cipher-nettle.c.inc +++ b/crypto/cipher-nettle.c.inc @@ -34,8 +34,6 @@ #include #endif =20 -static const struct QCryptoCipherDriver qcrypto_cipher_lib_driver; - typedef void (*QCryptoCipherNettleFuncWrapper)(const void *ctx, size_t length, uint8_t *dst, @@ -45,6 +43,7 @@ typedef void (*QCryptoCipherNettleFuncWrapper)(const void= *ctx, typedef nettle_crypt_func * QCryptoCipherNettleFuncNative; typedef void * cipher_ctx_t; typedef unsigned cipher_length_t; +#define CONST_CTX =20 #define cast5_set_key cast128_set_key =20 @@ -73,64 +72,215 @@ typedef unsigned cipher_length_t; typedef nettle_cipher_func * QCryptoCipherNettleFuncNative; typedef const void * cipher_ctx_t; typedef size_t cipher_length_t; +#define CONST_CTX const #endif =20 -typedef struct QCryptoNettleAES128 { - struct aes128_ctx enc; - struct aes128_ctx dec; -} QCryptoNettleAES128; - -typedef struct QCryptoNettleAES192 { - struct aes192_ctx enc; - struct aes192_ctx dec; -} QCryptoNettleAES192; - -typedef struct QCryptoNettleAES256 { - struct aes256_ctx enc; - struct aes256_ctx dec; -} QCryptoNettleAES256; - -static void aes128_encrypt_native(cipher_ctx_t ctx, cipher_length_t length, - uint8_t *dst, const uint8_t *src) +static inline bool qcrypto_length_check(size_t len, size_t blocksize, + Error **errp) { - const QCryptoNettleAES128 *aesctx =3D ctx; - aes128_encrypt(&aesctx->enc, length, dst, src); + if (unlikely(len & (blocksize - 1))) { + error_setg(errp, "Length %zu must be a multiple of block size %zu", + len, blocksize); + return false; + } + return true; } =20 -static void aes128_decrypt_native(cipher_ctx_t ctx, cipher_length_t length, - uint8_t *dst, const uint8_t *src) + +static void qcrypto_cipher_ctx_free(QCryptoCipher *ctx) { - const QCryptoNettleAES128 *aesctx =3D ctx; - aes128_decrypt(&aesctx->dec, length, dst, src); + g_free(ctx); } =20 -static void aes192_encrypt_native(cipher_ctx_t ctx, cipher_length_t length, - uint8_t *dst, const uint8_t *src) +static int qcrypto_cipher_no_setiv(QCryptoCipher *cipher, + const uint8_t *iv, size_t niv, + Error **errp) { - const QCryptoNettleAES192 *aesctx =3D ctx; - aes192_encrypt(&aesctx->enc, length, dst, src); + error_setg(errp, "Setting IV is not supported"); + return -1; } =20 -static void aes192_decrypt_native(cipher_ctx_t ctx, cipher_length_t length, - uint8_t *dst, const uint8_t *src) -{ - const QCryptoNettleAES192 *aesctx =3D ctx; - aes192_decrypt(&aesctx->dec, length, dst, src); + +#define DEFINE_SETIV(NAME, TYPE, BLEN) \ +static int NAME##_setiv(QCryptoCipher *cipher, const uint8_t *iv, \ + size_t niv, Error **errp) \ +{ \ + TYPE *ctx =3D container_of(cipher, TYPE, base); \ + if (niv !=3D BLEN) { \ + error_setg(errp, "Expected IV size %d not %zu", BLEN, niv); \ + return -1; \ + } \ + memcpy(ctx->iv, iv, niv); \ + return 0; \ } =20 -static void aes256_encrypt_native(cipher_ctx_t ctx, cipher_length_t length, - uint8_t *dst, const uint8_t *src) -{ - const QCryptoNettleAES256 *aesctx =3D ctx; - aes256_encrypt(&aesctx->enc, length, dst, src); -} =20 -static void aes256_decrypt_native(cipher_ctx_t ctx, cipher_length_t length, - uint8_t *dst, const uint8_t *src) -{ - const QCryptoNettleAES256 *aesctx =3D ctx; - aes256_decrypt(&aesctx->dec, length, dst, src); +#define DEFINE_ECB(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \ +static int NAME##_encrypt_ecb(QCryptoCipher *cipher, const void *in, \ + void *out, size_t len, Error **errp) \ +{ \ + TYPE *ctx =3D container_of(cipher, TYPE, base); \ + if (!qcrypto_length_check(len, BLEN, errp)) { \ + return -1; \ + } \ + ENCRYPT(&ctx->key, len, out, in); \ + return 0; \ +} \ +static int NAME##_decrypt_ecb(QCryptoCipher *cipher, const void *in, \ + void *out, size_t len, Error **errp) \ +{ \ + TYPE *ctx =3D container_of(cipher, TYPE, base); \ + if (!qcrypto_length_check(len, BLEN, errp)) { \ + return -1; \ + } \ + DECRYPT(&ctx->key, len, out, in); \ + return 0; \ +} \ +static const struct QCryptoCipherDriver NAME##_driver_ecb =3D { \ + .cipher_encrypt =3D NAME##_encrypt_ecb, \ + .cipher_decrypt =3D NAME##_decrypt_ecb, \ + .cipher_setiv =3D qcrypto_cipher_no_setiv, \ + .cipher_free =3D qcrypto_cipher_ctx_free, \ +}; + + +#define DEFINE_CBC(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \ +static int NAME##_encrypt_cbc(QCryptoCipher *cipher, const void *in, \ + void *out, size_t len, Error **errp) \ +{ \ + TYPE *ctx =3D container_of(cipher, TYPE, base); \ + if (!qcrypto_length_check(len, BLEN, errp)) { \ + return -1; \ + } \ + cbc_encrypt(&ctx->key, ENCRYPT, BLEN, ctx->iv, len, out, in); \ + return 0; \ +} \ +static int NAME##_decrypt_cbc(QCryptoCipher *cipher, const void *in, \ + void *out, size_t len, Error **errp) \ +{ \ + TYPE *ctx =3D container_of(cipher, TYPE, base); \ + if (!qcrypto_length_check(len, BLEN, errp)) { \ + return -1; \ + } \ + cbc_decrypt(&ctx->key, DECRYPT, BLEN, ctx->iv, len, out, in); \ + return 0; \ +} \ +static const struct QCryptoCipherDriver NAME##_driver_cbc =3D { \ + .cipher_encrypt =3D NAME##_encrypt_cbc, \ + .cipher_decrypt =3D NAME##_decrypt_cbc, \ + .cipher_setiv =3D NAME##_setiv, \ + .cipher_free =3D qcrypto_cipher_ctx_free, \ +}; + + +#define DEFINE_CTR(NAME, TYPE, BLEN, ENCRYPT) \ +static int NAME##_encrypt_ctr(QCryptoCipher *cipher, const void *in, \ + void *out, size_t len, Error **errp) \ +{ \ + TYPE *ctx =3D container_of(cipher, TYPE, base); \ + if (!qcrypto_length_check(len, BLEN, errp)) { \ + return -1; \ + } \ + ctr_crypt(&ctx->key, ENCRYPT, BLEN, ctx->iv, len, out, in); \ + return 0; \ +} \ +static const struct QCryptoCipherDriver NAME##_driver_ctr =3D { \ + .cipher_encrypt =3D NAME##_encrypt_ctr, \ + .cipher_decrypt =3D NAME##_encrypt_ctr, \ + .cipher_setiv =3D NAME##_setiv, \ + .cipher_free =3D qcrypto_cipher_ctx_free, \ +}; + + +#ifdef CONFIG_QEMU_PRIVATE_XTS +#define DEFINE__XTS(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \ +static void NAME##_xts_wrape(const void *ctx, size_t length, \ + uint8_t *dst, const uint8_t *src) \ +{ \ + ENCRYPT((cipher_ctx_t)ctx, length, dst, src); \ +} \ +static void NAME##_xts_wrapd(const void *ctx, size_t length, \ + uint8_t *dst, const uint8_t *src) \ +{ \ + DECRYPT((cipher_ctx_t)ctx, length, dst, src); \ +} \ +static int NAME##_encrypt_xts(QCryptoCipher *cipher, const void *in, \ + void *out, size_t len, Error **errp) \ +{ \ + TYPE *ctx =3D container_of(cipher, TYPE, base); \ + if (!qcrypto_length_check(len, BLEN, errp)) { \ + return -1; \ + } \ + xts_encrypt(&ctx->key, &ctx->key_xts, \ + NAME##_xts_wrape, NAME##_xts_wrapd, \ + ctx->iv, len, out, in); \ + return 0; \ +} \ +static int NAME##_decrypt_xts(QCryptoCipher *cipher, const void *in, \ + void *out, size_t len, Error **errp) \ +{ \ + TYPE *ctx =3D container_of(cipher, TYPE, base); \ + if (!qcrypto_length_check(len, BLEN, errp)) { \ + return -1; \ + } \ + xts_decrypt(&ctx->key, &ctx->key_xts, \ + NAME##_xts_wrape, NAME##_xts_wrapd, \ + ctx->iv, len, out, in); \ + return 0; \ } +#else +#define DEFINE__XTS(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \ +static int NAME##_encrypt_xts(QCryptoCipher *cipher, const void *in, \ + void *out, size_t len, Error **errp) \ +{ \ + TYPE *ctx =3D container_of(cipher, TYPE, base); \ + if (!qcrypto_length_check(len, BLEN, errp)) { \ + return -1; \ + } \ + xts_encrypt_message(&ctx->key, &ctx->key_xts, ENCRYPT, \ + ctx->iv, len, out, in); \ + return 0; \ +} \ +static int NAME##_decrypt_xts(QCryptoCipher *cipher, const void *in, \ + void *out, size_t len, Error **errp) \ +{ \ + TYPE *ctx =3D container_of(cipher, TYPE, base); \ + if (!qcrypto_length_check(len, BLEN, errp)) { \ + return -1; \ + } \ + xts_decrypt_message(&ctx->key, &ctx->key_xts, DECRYPT, ENCRYPT, \ + ctx->iv, len, out, in); \ + return 0; \ +} +#endif + +#define DEFINE_XTS(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \ + QEMU_BUILD_BUG_ON(BLEN !=3D XTS_BLOCK_SIZE); \ + DEFINE__XTS(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \ +static const struct QCryptoCipherDriver NAME##_driver_xts =3D { \ + .cipher_encrypt =3D NAME##_encrypt_xts, \ + .cipher_decrypt =3D NAME##_decrypt_xts, \ + .cipher_setiv =3D NAME##_setiv, \ + .cipher_free =3D qcrypto_cipher_ctx_free, \ +}; + + +#define DEFINE_ECB_CBC_CTR(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \ + DEFINE_SETIV(NAME, TYPE, BLEN) \ + DEFINE_ECB(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \ + DEFINE_CBC(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \ + DEFINE_CTR(NAME, TYPE, BLEN, ENCRYPT) + +#define DEFINE_ECB_CBC_CTR_XTS(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \ + DEFINE_ECB_CBC_CTR(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \ + DEFINE_XTS(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) + + +typedef struct QCryptoNettleDESRFB { + QCryptoCipher base; + struct des_ctx key; + uint8_t iv[DES_BLOCK_SIZE]; +} QCryptoNettleDESRFB; =20 static void des_encrypt_native(cipher_ctx_t ctx, cipher_length_t length, uint8_t *dst, const uint8_t *src) @@ -144,6 +294,16 @@ static void des_decrypt_native(cipher_ctx_t ctx, ciphe= r_length_t length, des_decrypt(ctx, length, dst, src); } =20 +DEFINE_ECB_CBC_CTR(qcrypto_nettle_des_rfb, QCryptoNettleDESRFB, + DES_BLOCK_SIZE, des_encrypt_native, des_decrypt_native) + + +typedef struct QCryptoNettleDES3 { + QCryptoCipher base; + struct des3_ctx key; + uint8_t iv[DES3_BLOCK_SIZE]; +} QCryptoNettleDES3; + static void des3_encrypt_native(cipher_ctx_t ctx, cipher_length_t length, uint8_t *dst, const uint8_t *src) { @@ -156,6 +316,94 @@ static void des3_decrypt_native(cipher_ctx_t ctx, ciph= er_length_t length, des3_decrypt(ctx, length, dst, src); } =20 +DEFINE_ECB_CBC_CTR(qcrypto_nettle_des3, QCryptoNettleDES3, DES3_BLOCK_SIZE, + des3_encrypt_native, des3_decrypt_native) + + +typedef struct QCryptoNettleAES128 { + QCryptoCipher base; + uint8_t iv[AES_BLOCK_SIZE]; + /* First key from pair is encode, second key is decode. */ + struct aes128_ctx key[2], key_xts[2]; +} QCryptoNettleAES128; + +static void aes128_encrypt_native(cipher_ctx_t ctx, cipher_length_t length, + uint8_t *dst, const uint8_t *src) +{ + CONST_CTX struct aes128_ctx *keys =3D ctx; + aes128_encrypt(&keys[0], length, dst, src); +} + +static void aes128_decrypt_native(cipher_ctx_t ctx, cipher_length_t length, + uint8_t *dst, const uint8_t *src) +{ + CONST_CTX struct aes128_ctx *keys =3D ctx; + aes128_decrypt(&keys[1], length, dst, src); +} + +DEFINE_ECB_CBC_CTR_XTS(qcrypto_nettle_aes128, + QCryptoNettleAES128, AES_BLOCK_SIZE, + aes128_encrypt_native, aes128_decrypt_native) + + +typedef struct QCryptoNettleAES192 { + QCryptoCipher base; + uint8_t iv[AES_BLOCK_SIZE]; + /* First key from pair is encode, second key is decode. */ + struct aes192_ctx key[2], key_xts[2]; +} QCryptoNettleAES192; + +static void aes192_encrypt_native(cipher_ctx_t ctx, cipher_length_t length, + uint8_t *dst, const uint8_t *src) +{ + CONST_CTX struct aes192_ctx *keys =3D ctx; + aes192_encrypt(&keys[0], length, dst, src); +} + +static void aes192_decrypt_native(cipher_ctx_t ctx, cipher_length_t length, + uint8_t *dst, const uint8_t *src) +{ + CONST_CTX struct aes192_ctx *keys =3D ctx; + aes192_decrypt(&keys[1], length, dst, src); +} + +DEFINE_ECB_CBC_CTR_XTS(qcrypto_nettle_aes192, + QCryptoNettleAES192, AES_BLOCK_SIZE, + aes192_encrypt_native, aes192_decrypt_native) + + +typedef struct QCryptoNettleAES256 { + QCryptoCipher base; + uint8_t iv[AES_BLOCK_SIZE]; + /* First key from pair is encode, second key is decode. */ + struct aes256_ctx key[2], key_xts[2]; +} QCryptoNettleAES256; + +static void aes256_encrypt_native(cipher_ctx_t ctx, cipher_length_t length, + uint8_t *dst, const uint8_t *src) +{ + CONST_CTX struct aes256_ctx *keys =3D ctx; + aes256_encrypt(&keys[0], length, dst, src); +} + +static void aes256_decrypt_native(cipher_ctx_t ctx, cipher_length_t length, + uint8_t *dst, const uint8_t *src) +{ + CONST_CTX struct aes256_ctx *keys =3D ctx; + aes256_decrypt(&keys[1], length, dst, src); +} + +DEFINE_ECB_CBC_CTR_XTS(qcrypto_nettle_aes256, + QCryptoNettleAES256, AES_BLOCK_SIZE, + aes256_encrypt_native, aes256_decrypt_native) + + +typedef struct QCryptoNettleCAST128 { + QCryptoCipher base; + uint8_t iv[CAST128_BLOCK_SIZE]; + struct cast128_ctx key, key_xts; +} QCryptoNettleCAST128; + static void cast128_encrypt_native(cipher_ctx_t ctx, cipher_length_t lengt= h, uint8_t *dst, const uint8_t *src) { @@ -168,6 +416,18 @@ static void cast128_decrypt_native(cipher_ctx_t ctx, c= ipher_length_t length, cast128_decrypt(ctx, length, dst, src); } =20 +DEFINE_ECB_CBC_CTR(qcrypto_nettle_cast128, + QCryptoNettleCAST128, CAST128_BLOCK_SIZE, + cast128_encrypt_native, cast128_decrypt_native) + + +typedef struct QCryptoNettleSerpent { + QCryptoCipher base; + uint8_t iv[SERPENT_BLOCK_SIZE]; + struct serpent_ctx key, key_xts; +} QCryptoNettleSerpent; + + static void serpent_encrypt_native(cipher_ctx_t ctx, cipher_length_t lengt= h, uint8_t *dst, const uint8_t *src) { @@ -180,6 +440,17 @@ static void serpent_decrypt_native(cipher_ctx_t ctx, c= ipher_length_t length, serpent_decrypt(ctx, length, dst, src); } =20 +DEFINE_ECB_CBC_CTR_XTS(qcrypto_nettle_serpent, + QCryptoNettleSerpent, SERPENT_BLOCK_SIZE, + serpent_encrypt_native, serpent_decrypt_native) + + +typedef struct QCryptoNettleTwofish { + QCryptoCipher base; + uint8_t iv[TWOFISH_BLOCK_SIZE]; + struct twofish_ctx key, key_xts; +} QCryptoNettleTwofish; + static void twofish_encrypt_native(cipher_ctx_t ctx, cipher_length_t lengt= h, uint8_t *dst, const uint8_t *src) { @@ -192,125 +463,10 @@ static void twofish_decrypt_native(cipher_ctx_t ctx,= cipher_length_t length, twofish_decrypt(ctx, length, dst, src); } =20 -static void aes128_encrypt_wrapper(const void *ctx, size_t length, - uint8_t *dst, const uint8_t *src) -{ - const QCryptoNettleAES128 *aesctx =3D ctx; - aes128_encrypt(&aesctx->enc, length, dst, src); -} +DEFINE_ECB_CBC_CTR_XTS(qcrypto_nettle_twofish, + QCryptoNettleTwofish, TWOFISH_BLOCK_SIZE, + twofish_encrypt_native, twofish_decrypt_native) =20 -static void aes128_decrypt_wrapper(const void *ctx, size_t length, - uint8_t *dst, const uint8_t *src) -{ - const QCryptoNettleAES128 *aesctx =3D ctx; - aes128_decrypt(&aesctx->dec, length, dst, src); -} - -static void aes192_encrypt_wrapper(const void *ctx, size_t length, - uint8_t *dst, const uint8_t *src) -{ - const QCryptoNettleAES192 *aesctx =3D ctx; - aes192_encrypt(&aesctx->enc, length, dst, src); -} - -static void aes192_decrypt_wrapper(const void *ctx, size_t length, - uint8_t *dst, const uint8_t *src) -{ - const QCryptoNettleAES192 *aesctx =3D ctx; - aes192_decrypt(&aesctx->dec, length, dst, src); -} - -static void aes256_encrypt_wrapper(const void *ctx, size_t length, - uint8_t *dst, const uint8_t *src) -{ - const QCryptoNettleAES256 *aesctx =3D ctx; - aes256_encrypt(&aesctx->enc, length, dst, src); -} - -static void aes256_decrypt_wrapper(const void *ctx, size_t length, - uint8_t *dst, const uint8_t *src) -{ - const QCryptoNettleAES256 *aesctx =3D ctx; - aes256_decrypt(&aesctx->dec, length, dst, src); -} - -static void des_encrypt_wrapper(const void *ctx, size_t length, - uint8_t *dst, const uint8_t *src) -{ - des_encrypt(ctx, length, dst, src); -} - -static void des_decrypt_wrapper(const void *ctx, size_t length, - uint8_t *dst, const uint8_t *src) -{ - des_decrypt(ctx, length, dst, src); -} - -static void des3_encrypt_wrapper(const void *ctx, size_t length, - uint8_t *dst, const uint8_t *src) -{ - des3_encrypt(ctx, length, dst, src); -} - -static void des3_decrypt_wrapper(const void *ctx, size_t length, - uint8_t *dst, const uint8_t *src) -{ - des3_decrypt(ctx, length, dst, src); -} - -static void cast128_encrypt_wrapper(const void *ctx, size_t length, - uint8_t *dst, const uint8_t *src) -{ - cast128_encrypt(ctx, length, dst, src); -} - -static void cast128_decrypt_wrapper(const void *ctx, size_t length, - uint8_t *dst, const uint8_t *src) -{ - cast128_decrypt(ctx, length, dst, src); -} - -static void serpent_encrypt_wrapper(const void *ctx, size_t length, - uint8_t *dst, const uint8_t *src) -{ - serpent_encrypt(ctx, length, dst, src); -} - -static void serpent_decrypt_wrapper(const void *ctx, size_t length, - uint8_t *dst, const uint8_t *src) -{ - serpent_decrypt(ctx, length, dst, src); -} - -static void twofish_encrypt_wrapper(const void *ctx, size_t length, - uint8_t *dst, const uint8_t *src) -{ - twofish_encrypt(ctx, length, dst, src); -} - -static void twofish_decrypt_wrapper(const void *ctx, size_t length, - uint8_t *dst, const uint8_t *src) -{ - twofish_decrypt(ctx, length, dst, src); -} - -typedef struct QCryptoCipherNettle QCryptoCipherNettle; -struct QCryptoCipherNettle { - QCryptoCipher base; - - /* Primary cipher context for all modes */ - void *ctx; - /* Second cipher context for XTS mode only */ - void *ctx_tweak; - /* Cipher callbacks for both contexts */ - QCryptoCipherNettleFuncNative alg_encrypt_native; - QCryptoCipherNettleFuncNative alg_decrypt_native; - QCryptoCipherNettleFuncWrapper alg_encrypt_wrapper; - QCryptoCipherNettleFuncWrapper alg_decrypt_wrapper; - /* Initialization vector or Counter */ - uint8_t *iv; - size_t blocksize; -}; =20 bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg, QCryptoCipherMode mode) @@ -344,30 +500,12 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm a= lg, } } =20 - -static void -qcrypto_nettle_cipher_free_ctx(QCryptoCipherNettle *ctx) -{ - if (!ctx) { - return; - } - - g_free(ctx->iv); - g_free(ctx->ctx); - g_free(ctx->ctx_tweak); - g_free(ctx); -} - - static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, QCryptoCipherMode mode, const uint8_t *key, size_t nkey, Error **errp) { - QCryptoCipherNettle *ctx; - uint8_t *rfbkey; - switch (mode) { case QCRYPTO_CIPHER_MODE_ECB: case QCRYPTO_CIPHER_MODE_CBC: @@ -375,363 +513,248 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCrypt= oCipherAlgorithm alg, case QCRYPTO_CIPHER_MODE_CTR: break; default: - error_setg(errp, "Unsupported cipher mode %s", - QCryptoCipherMode_str(mode)); - return NULL; + goto bad_cipher_mode; } =20 if (!qcrypto_cipher_validate_key_length(alg, mode, nkey, errp)) { return NULL; } =20 - ctx =3D g_new0(QCryptoCipherNettle, 1); - switch (alg) { case QCRYPTO_CIPHER_ALG_DES_RFB: - ctx->ctx =3D g_new0(struct des_ctx, 1); - rfbkey =3D qcrypto_cipher_munge_des_rfb_key(key, nkey); - des_set_key(ctx->ctx, rfbkey); - g_free(rfbkey); + { + QCryptoNettleDESRFB *ctx; + const QCryptoCipherDriver *drv; + uint8_t *rfbkey; =20 - ctx->alg_encrypt_native =3D des_encrypt_native; - ctx->alg_decrypt_native =3D des_decrypt_native; - ctx->alg_encrypt_wrapper =3D des_encrypt_wrapper; - ctx->alg_decrypt_wrapper =3D des_decrypt_wrapper; + switch (mode) { + case QCRYPTO_CIPHER_MODE_ECB: + drv =3D &qcrypto_nettle_des_rfb_driver_ecb; + break; + case QCRYPTO_CIPHER_MODE_CBC: + drv =3D &qcrypto_nettle_des_rfb_driver_cbc; + break; + case QCRYPTO_CIPHER_MODE_CTR: + drv =3D &qcrypto_nettle_des_rfb_driver_ctr; + break; + default: + goto bad_cipher_mode; + } =20 - ctx->blocksize =3D DES_BLOCK_SIZE; - break; + ctx =3D g_new0(QCryptoNettleDESRFB, 1); + ctx->base.driver =3D drv; + + rfbkey =3D qcrypto_cipher_munge_des_rfb_key(key, nkey); + des_set_key(&ctx->key, rfbkey); + g_free(rfbkey); + + return &ctx->base; + } =20 case QCRYPTO_CIPHER_ALG_3DES: - ctx->ctx =3D g_new0(struct des3_ctx, 1); - des3_set_key(ctx->ctx, key); + { + QCryptoNettleDES3 *ctx; + const QCryptoCipherDriver *drv; =20 - ctx->alg_encrypt_native =3D des3_encrypt_native; - ctx->alg_decrypt_native =3D des3_decrypt_native; - ctx->alg_encrypt_wrapper =3D des3_encrypt_wrapper; - ctx->alg_decrypt_wrapper =3D des3_decrypt_wrapper; + switch (mode) { + case QCRYPTO_CIPHER_MODE_ECB: + drv =3D &qcrypto_nettle_des3_driver_ecb; + break; + case QCRYPTO_CIPHER_MODE_CBC: + drv =3D &qcrypto_nettle_des3_driver_cbc; + break; + case QCRYPTO_CIPHER_MODE_CTR: + drv =3D &qcrypto_nettle_des3_driver_ctr; + break; + default: + goto bad_cipher_mode; + } =20 - ctx->blocksize =3D DES3_BLOCK_SIZE; - break; + ctx =3D g_new0(QCryptoNettleDES3, 1); + ctx->base.driver =3D drv; + des3_set_key(&ctx->key, key); + return &ctx->base; + } =20 case QCRYPTO_CIPHER_ALG_AES_128: - ctx->ctx =3D g_new0(QCryptoNettleAES128, 1); + { + QCryptoNettleAES128 *ctx =3D g_new0(QCryptoNettleAES128, 1); =20 - if (mode =3D=3D QCRYPTO_CIPHER_MODE_XTS) { - ctx->ctx_tweak =3D g_new0(QCryptoNettleAES128, 1); + switch (mode) { + case QCRYPTO_CIPHER_MODE_ECB: + ctx->base.driver =3D &qcrypto_nettle_aes128_driver_ecb; + break; + case QCRYPTO_CIPHER_MODE_CBC: + ctx->base.driver =3D &qcrypto_nettle_aes128_driver_cbc; + break; + case QCRYPTO_CIPHER_MODE_CTR: + ctx->base.driver =3D &qcrypto_nettle_aes128_driver_ctr; + break; + case QCRYPTO_CIPHER_MODE_XTS: + ctx->base.driver =3D &qcrypto_nettle_aes128_driver_xts; + nkey /=3D 2; + aes128_set_encrypt_key(&ctx->key_xts[0], key + nkey); + aes128_set_decrypt_key(&ctx->key_xts[1], key + nkey); + break; + default: + g_assert_not_reached(); + } + aes128_set_encrypt_key(&ctx->key[0], key); + aes128_set_decrypt_key(&ctx->key[1], key); =20 - nkey /=3D 2; - aes128_set_encrypt_key(&((QCryptoNettleAES128 *)ctx->ctx)->enc, - key); - aes128_set_decrypt_key(&((QCryptoNettleAES128 *)ctx->ctx)->dec, - key); - - aes128_set_encrypt_key(&((QCryptoNettleAES128 *)ctx->ctx_tweak= )-> - enc, key + nkey); - aes128_set_decrypt_key(&((QCryptoNettleAES128 *)ctx->ctx_tweak= )-> - dec, key + nkey); - } else { - aes128_set_encrypt_key(&((QCryptoNettleAES128 *)ctx->ctx)->enc, - key); - aes128_set_decrypt_key(&((QCryptoNettleAES128 *)ctx->ctx)->dec, - key); + return &ctx->base; } =20 - ctx->alg_encrypt_native =3D aes128_encrypt_native; - ctx->alg_decrypt_native =3D aes128_decrypt_native; - ctx->alg_encrypt_wrapper =3D aes128_encrypt_wrapper; - ctx->alg_decrypt_wrapper =3D aes128_decrypt_wrapper; - - ctx->blocksize =3D AES_BLOCK_SIZE; - break; - case QCRYPTO_CIPHER_ALG_AES_192: - ctx->ctx =3D g_new0(QCryptoNettleAES192, 1); + { + QCryptoNettleAES192 *ctx =3D g_new0(QCryptoNettleAES192, 1); =20 - if (mode =3D=3D QCRYPTO_CIPHER_MODE_XTS) { - ctx->ctx_tweak =3D g_new0(QCryptoNettleAES192, 1); + switch (mode) { + case QCRYPTO_CIPHER_MODE_ECB: + ctx->base.driver =3D &qcrypto_nettle_aes192_driver_ecb; + break; + case QCRYPTO_CIPHER_MODE_CBC: + ctx->base.driver =3D &qcrypto_nettle_aes192_driver_cbc; + break; + case QCRYPTO_CIPHER_MODE_CTR: + ctx->base.driver =3D &qcrypto_nettle_aes192_driver_ctr; + break; + case QCRYPTO_CIPHER_MODE_XTS: + ctx->base.driver =3D &qcrypto_nettle_aes192_driver_xts; + nkey /=3D 2; + aes192_set_encrypt_key(&ctx->key_xts[0], key + nkey); + aes192_set_decrypt_key(&ctx->key_xts[1], key + nkey); + break; + default: + g_assert_not_reached(); + } + aes192_set_encrypt_key(&ctx->key[0], key); + aes192_set_decrypt_key(&ctx->key[1], key); =20 - nkey /=3D 2; - aes192_set_encrypt_key(&((QCryptoNettleAES192 *)ctx->ctx)->enc, - key); - aes192_set_decrypt_key(&((QCryptoNettleAES192 *)ctx->ctx)->dec, - key); - - aes192_set_encrypt_key(&((QCryptoNettleAES192 *)ctx->ctx_tweak= )-> - enc, key + nkey); - aes192_set_decrypt_key(&((QCryptoNettleAES192 *)ctx->ctx_tweak= )-> - dec, key + nkey); - } else { - aes192_set_encrypt_key(&((QCryptoNettleAES192 *)ctx->ctx)->enc, - key); - aes192_set_decrypt_key(&((QCryptoNettleAES192 *)ctx->ctx)->dec, - key); + return &ctx->base; } =20 - ctx->alg_encrypt_native =3D aes192_encrypt_native; - ctx->alg_decrypt_native =3D aes192_decrypt_native; - ctx->alg_encrypt_wrapper =3D aes192_encrypt_wrapper; - ctx->alg_decrypt_wrapper =3D aes192_decrypt_wrapper; - - ctx->blocksize =3D AES_BLOCK_SIZE; - break; - case QCRYPTO_CIPHER_ALG_AES_256: - ctx->ctx =3D g_new0(QCryptoNettleAES256, 1); + { + QCryptoNettleAES256 *ctx =3D g_new0(QCryptoNettleAES256, 1); =20 - if (mode =3D=3D QCRYPTO_CIPHER_MODE_XTS) { - ctx->ctx_tweak =3D g_new0(QCryptoNettleAES256, 1); + switch (mode) { + case QCRYPTO_CIPHER_MODE_ECB: + ctx->base.driver =3D &qcrypto_nettle_aes256_driver_ecb; + break; + case QCRYPTO_CIPHER_MODE_CBC: + ctx->base.driver =3D &qcrypto_nettle_aes256_driver_cbc; + break; + case QCRYPTO_CIPHER_MODE_CTR: + ctx->base.driver =3D &qcrypto_nettle_aes256_driver_ctr; + break; + case QCRYPTO_CIPHER_MODE_XTS: + ctx->base.driver =3D &qcrypto_nettle_aes256_driver_xts; + nkey /=3D 2; + aes256_set_encrypt_key(&ctx->key_xts[0], key + nkey); + aes256_set_decrypt_key(&ctx->key_xts[1], key + nkey); + break; + default: + g_assert_not_reached(); + } + aes256_set_encrypt_key(&ctx->key[0], key); + aes256_set_decrypt_key(&ctx->key[1], key); =20 - nkey /=3D 2; - aes256_set_encrypt_key(&((QCryptoNettleAES256 *)ctx->ctx)->enc, - key); - aes256_set_decrypt_key(&((QCryptoNettleAES256 *)ctx->ctx)->dec, - key); - - aes256_set_encrypt_key(&((QCryptoNettleAES256 *)ctx->ctx_tweak= )-> - enc, key + nkey); - aes256_set_decrypt_key(&((QCryptoNettleAES256 *)ctx->ctx_tweak= )-> - dec, key + nkey); - } else { - aes256_set_encrypt_key(&((QCryptoNettleAES256 *)ctx->ctx)->enc, - key); - aes256_set_decrypt_key(&((QCryptoNettleAES256 *)ctx->ctx)->dec, - key); + return &ctx->base; } =20 - ctx->alg_encrypt_native =3D aes256_encrypt_native; - ctx->alg_decrypt_native =3D aes256_decrypt_native; - ctx->alg_encrypt_wrapper =3D aes256_encrypt_wrapper; - ctx->alg_decrypt_wrapper =3D aes256_decrypt_wrapper; - - ctx->blocksize =3D AES_BLOCK_SIZE; - break; - case QCRYPTO_CIPHER_ALG_CAST5_128: - ctx->ctx =3D g_new0(struct cast128_ctx, 1); + { + QCryptoNettleCAST128 *ctx; + const QCryptoCipherDriver *drv; =20 - if (mode =3D=3D QCRYPTO_CIPHER_MODE_XTS) { - ctx->ctx_tweak =3D g_new0(struct cast128_ctx, 1); + switch (mode) { + case QCRYPTO_CIPHER_MODE_ECB: + drv =3D &qcrypto_nettle_cast128_driver_ecb; + break; + case QCRYPTO_CIPHER_MODE_CBC: + drv =3D &qcrypto_nettle_cast128_driver_cbc; + break; + case QCRYPTO_CIPHER_MODE_CTR: + drv =3D &qcrypto_nettle_cast128_driver_ctr; + break; + default: + goto bad_cipher_mode; + } =20 - nkey /=3D 2; - cast5_set_key(ctx->ctx, nkey, key); - cast5_set_key(ctx->ctx_tweak, nkey, key + nkey); - } else { - cast5_set_key(ctx->ctx, nkey, key); + ctx =3D g_new0(QCryptoNettleCAST128, 1); + ctx->base.driver =3D drv; + cast5_set_key(&ctx->key, nkey, key); + + return &ctx->base; } =20 - ctx->alg_encrypt_native =3D cast128_encrypt_native; - ctx->alg_decrypt_native =3D cast128_decrypt_native; - ctx->alg_encrypt_wrapper =3D cast128_encrypt_wrapper; - ctx->alg_decrypt_wrapper =3D cast128_decrypt_wrapper; - - ctx->blocksize =3D CAST128_BLOCK_SIZE; - break; - case QCRYPTO_CIPHER_ALG_SERPENT_128: case QCRYPTO_CIPHER_ALG_SERPENT_192: case QCRYPTO_CIPHER_ALG_SERPENT_256: - ctx->ctx =3D g_new0(struct serpent_ctx, 1); + { + QCryptoNettleSerpent *ctx =3D g_new0(QCryptoNettleSerpent, 1); =20 - if (mode =3D=3D QCRYPTO_CIPHER_MODE_XTS) { - ctx->ctx_tweak =3D g_new0(struct serpent_ctx, 1); + switch (mode) { + case QCRYPTO_CIPHER_MODE_ECB: + ctx->base.driver =3D &qcrypto_nettle_serpent_driver_ecb; + break; + case QCRYPTO_CIPHER_MODE_CBC: + ctx->base.driver =3D &qcrypto_nettle_serpent_driver_cbc; + break; + case QCRYPTO_CIPHER_MODE_CTR: + ctx->base.driver =3D &qcrypto_nettle_serpent_driver_ctr; + break; + case QCRYPTO_CIPHER_MODE_XTS: + ctx->base.driver =3D &qcrypto_nettle_serpent_driver_xts; + nkey /=3D 2; + serpent_set_key(&ctx->key_xts, nkey, key + nkey); + break; + default: + g_assert_not_reached(); + } + serpent_set_key(&ctx->key, nkey, key); =20 - nkey /=3D 2; - serpent_set_key(ctx->ctx, nkey, key); - serpent_set_key(ctx->ctx_tweak, nkey, key + nkey); - } else { - serpent_set_key(ctx->ctx, nkey, key); + return &ctx->base; } =20 - ctx->alg_encrypt_native =3D serpent_encrypt_native; - ctx->alg_decrypt_native =3D serpent_decrypt_native; - ctx->alg_encrypt_wrapper =3D serpent_encrypt_wrapper; - ctx->alg_decrypt_wrapper =3D serpent_decrypt_wrapper; - - ctx->blocksize =3D SERPENT_BLOCK_SIZE; - break; - case QCRYPTO_CIPHER_ALG_TWOFISH_128: case QCRYPTO_CIPHER_ALG_TWOFISH_192: case QCRYPTO_CIPHER_ALG_TWOFISH_256: - ctx->ctx =3D g_new0(struct twofish_ctx, 1); + { + QCryptoNettleTwofish *ctx =3D g_new0(QCryptoNettleTwofish, 1); =20 - if (mode =3D=3D QCRYPTO_CIPHER_MODE_XTS) { - ctx->ctx_tweak =3D g_new0(struct twofish_ctx, 1); + switch (mode) { + case QCRYPTO_CIPHER_MODE_ECB: + ctx->base.driver =3D &qcrypto_nettle_twofish_driver_ecb; + break; + case QCRYPTO_CIPHER_MODE_CBC: + ctx->base.driver =3D &qcrypto_nettle_twofish_driver_cbc; + break; + case QCRYPTO_CIPHER_MODE_CTR: + ctx->base.driver =3D &qcrypto_nettle_twofish_driver_ctr; + break; + case QCRYPTO_CIPHER_MODE_XTS: + ctx->base.driver =3D &qcrypto_nettle_twofish_driver_xts; + nkey /=3D 2; + twofish_set_key(&ctx->key_xts, nkey, key + nkey); + break; + default: + g_assert_not_reached(); + } + twofish_set_key(&ctx->key, nkey, key); =20 - nkey /=3D 2; - twofish_set_key(ctx->ctx, nkey, key); - twofish_set_key(ctx->ctx_tweak, nkey, key + nkey); - } else { - twofish_set_key(ctx->ctx, nkey, key); + return &ctx->base; } =20 - ctx->alg_encrypt_native =3D twofish_encrypt_native; - ctx->alg_decrypt_native =3D twofish_decrypt_native; - ctx->alg_encrypt_wrapper =3D twofish_encrypt_wrapper; - ctx->alg_decrypt_wrapper =3D twofish_decrypt_wrapper; - - ctx->blocksize =3D TWOFISH_BLOCK_SIZE; - break; - default: error_setg(errp, "Unsupported cipher algorithm %s", QCryptoCipherAlgorithm_str(alg)); - goto error; - } - g_assert(is_power_of_2(ctx->blocksize)); - - if (mode =3D=3D QCRYPTO_CIPHER_MODE_XTS && - ctx->blocksize !=3D XTS_BLOCK_SIZE) { - error_setg(errp, "Cipher block size %zu must equal XTS block size = %d", - ctx->blocksize, XTS_BLOCK_SIZE); - goto error; + return NULL; } =20 - ctx->iv =3D g_new0(uint8_t, ctx->blocksize); - - ctx->base.driver =3D &qcrypto_cipher_lib_driver; - return &ctx->base; - - error: - qcrypto_nettle_cipher_free_ctx(ctx); + bad_cipher_mode: + error_setg(errp, "Unsupported cipher mode %s", + QCryptoCipherMode_str(mode)); return NULL; } - - -static void -qcrypto_nettle_cipher_ctx_free(QCryptoCipher *cipher) -{ - QCryptoCipherNettle *ctx =3D container_of(cipher, QCryptoCipherNettle,= base); - - qcrypto_nettle_cipher_free_ctx(ctx); -} - - -static int -qcrypto_nettle_cipher_encrypt(QCryptoCipher *cipher, - const void *in, - void *out, - size_t len, - Error **errp) -{ - QCryptoCipherNettle *ctx =3D container_of(cipher, QCryptoCipherNettle,= base); - - if (len & (ctx->blocksize - 1)) { - error_setg(errp, "Length %zu must be a multiple of block size %zu", - len, ctx->blocksize); - return -1; - } - - switch (cipher->mode) { - case QCRYPTO_CIPHER_MODE_ECB: - ctx->alg_encrypt_wrapper(ctx->ctx, len, out, in); - break; - - case QCRYPTO_CIPHER_MODE_CBC: - cbc_encrypt(ctx->ctx, ctx->alg_encrypt_native, - ctx->blocksize, ctx->iv, - len, out, in); - break; - - case QCRYPTO_CIPHER_MODE_XTS: -#ifdef CONFIG_QEMU_PRIVATE_XTS - xts_encrypt(ctx->ctx, ctx->ctx_tweak, - ctx->alg_encrypt_wrapper, ctx->alg_decrypt_wrapper, - ctx->iv, len, out, in); -#else - xts_encrypt_message(ctx->ctx, ctx->ctx_tweak, - ctx->alg_encrypt_native, - ctx->iv, len, out, in); -#endif - break; - - case QCRYPTO_CIPHER_MODE_CTR: - ctr_crypt(ctx->ctx, ctx->alg_encrypt_native, - ctx->blocksize, ctx->iv, - len, out, in); - break; - - default: - error_setg(errp, "Unsupported cipher mode %s", - QCryptoCipherMode_str(cipher->mode)); - return -1; - } - return 0; -} - - -static int -qcrypto_nettle_cipher_decrypt(QCryptoCipher *cipher, - const void *in, - void *out, - size_t len, - Error **errp) -{ - QCryptoCipherNettle *ctx =3D container_of(cipher, QCryptoCipherNettle,= base); - - if (len & (ctx->blocksize - 1)) { - error_setg(errp, "Length %zu must be a multiple of block size %zu", - len, ctx->blocksize); - return -1; - } - - switch (cipher->mode) { - case QCRYPTO_CIPHER_MODE_ECB: - ctx->alg_decrypt_wrapper(ctx->ctx, len, out, in); - break; - - case QCRYPTO_CIPHER_MODE_CBC: - cbc_decrypt(ctx->ctx, ctx->alg_decrypt_native, - ctx->blocksize, ctx->iv, - len, out, in); - break; - - case QCRYPTO_CIPHER_MODE_XTS: -#ifdef CONFIG_QEMU_PRIVATE_XTS - xts_decrypt(ctx->ctx, ctx->ctx_tweak, - ctx->alg_encrypt_wrapper, ctx->alg_decrypt_wrapper, - ctx->iv, len, out, in); -#else - xts_decrypt_message(ctx->ctx, ctx->ctx_tweak, - ctx->alg_decrypt_native, - ctx->alg_encrypt_native, - ctx->iv, len, out, in); -#endif - break; - case QCRYPTO_CIPHER_MODE_CTR: - ctr_crypt(ctx->ctx, ctx->alg_encrypt_native, - ctx->blocksize, ctx->iv, - len, out, in); - break; - - default: - error_setg(errp, "Unsupported cipher mode %s", - QCryptoCipherMode_str(cipher->mode)); - return -1; - } - return 0; -} - -static int -qcrypto_nettle_cipher_setiv(QCryptoCipher *cipher, - const uint8_t *iv, size_t niv, - Error **errp) -{ - QCryptoCipherNettle *ctx =3D container_of(cipher, QCryptoCipherNettle,= base); - - if (niv !=3D ctx->blocksize) { - error_setg(errp, "Expected IV size %zu not %zu", - ctx->blocksize, niv); - return -1; - } - memcpy(ctx->iv, iv, niv); - return 0; -} - - -static const struct QCryptoCipherDriver qcrypto_cipher_lib_driver =3D { - .cipher_encrypt =3D qcrypto_nettle_cipher_encrypt, - .cipher_decrypt =3D qcrypto_nettle_cipher_decrypt, - .cipher_setiv =3D qcrypto_nettle_cipher_setiv, - .cipher_free =3D qcrypto_nettle_cipher_ctx_free, -}; --=20 2.25.1