crypto: qce - handle AES-XTS cases that qce fails
authorEneas U de Queiroz <cotequeiroz@gmail.com>
Fri, 7 Feb 2020 15:02:27 +0000 (12:02 -0300)
committerHerbert Xu <herbert@gondor.apana.org.au>
Thu, 13 Feb 2020 09:05:27 +0000 (17:05 +0800)
QCE hangs when presented with an AES-XTS request whose length is larger
than QCE_SECTOR_SIZE (512-bytes), and is not a multiple of it.  Let the
fallback cipher handle them.

Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/qce/common.c
drivers/crypto/qce/common.h
drivers/crypto/qce/skcipher.c

index 629e7f34dc0962a67d09c1a67d891a0f1053148f..5006e74c40cd0efced53fb8c9923a6db31ed0ec7 100644 (file)
@@ -15,8 +15,6 @@
 #include "regs-v5.h"
 #include "sha.h"
 
-#define QCE_SECTOR_SIZE                512
-
 static inline u32 qce_read(struct qce_device *qce, u32 offset)
 {
        return readl(qce->base + offset);
index 282d4317470d3abaf953b24abec906899a13e98c..9f989cba0f1b56bd086dd79bde7c738b60e31ff8 100644 (file)
@@ -12,6 +12,9 @@
 #include <crypto/hash.h>
 #include <crypto/internal/skcipher.h>
 
+/* xts du size */
+#define QCE_SECTOR_SIZE                        512
+
 /* key size in bytes */
 #define QCE_SHA_HMAC_KEY_SIZE          64
 #define QCE_MAX_CIPHER_KEY_SIZE                AES_KEYSIZE_256
index fc7c940b5a43ee68cab58c2551df084b577dcc63..a4f6ec1b64c72b6cd23daf18e560cfbe20e99dde 100644 (file)
@@ -227,9 +227,14 @@ static int qce_skcipher_crypt(struct skcipher_request *req, int encrypt)
        rctx->flags |= encrypt ? QCE_ENCRYPT : QCE_DECRYPT;
        keylen = IS_XTS(rctx->flags) ? ctx->enc_keylen >> 1 : ctx->enc_keylen;
 
+       /* qce is hanging when AES-XTS request len > QCE_SECTOR_SIZE and
+        * is not a multiple of it; pass such requests to the fallback
+        */
        if (IS_AES(rctx->flags) &&
-           ((keylen != AES_KEYSIZE_128 && keylen != AES_KEYSIZE_256) ||
-            req->cryptlen <= aes_sw_max_len)) {
+           (((keylen != AES_KEYSIZE_128 && keylen != AES_KEYSIZE_256) ||
+             req->cryptlen <= aes_sw_max_len) ||
+            (IS_XTS(rctx->flags) && req->cryptlen > QCE_SECTOR_SIZE &&
+             req->cryptlen % QCE_SECTOR_SIZE))) {
                SYNC_SKCIPHER_REQUEST_ON_STACK(subreq, ctx->fallback);
 
                skcipher_request_set_sync_tfm(subreq, ctx->fallback);