crypto: inside-secure - improve error reporting
authorAntoine Tenart <antoine.tenart@bootlin.com>
Mon, 14 May 2018 13:11:01 +0000 (15:11 +0200)
committerHerbert Xu <herbert@gondor.apana.org.au>
Sat, 26 May 2018 16:11:40 +0000 (00:11 +0800)
This patch improves the error reporting from the Inside Secure driver to
the upper layers and crypto consumers. All errors reported by the engine
aren't fatal, and some may be genuine.

Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/inside-secure/safexcel.c
drivers/crypto/inside-secure/safexcel.h
drivers/crypto/inside-secure/safexcel_cipher.c
drivers/crypto/inside-secure/safexcel_hash.c

index d4a81be0d7d2e9cd5e088b2c5801afb6f963055d..87e6d1a63886e3c27e02833a89d55a407dfadee7 100644 (file)
@@ -537,6 +537,27 @@ finalize:
               EIP197_HIA_CDR(priv, ring) + EIP197_HIA_xDR_PREP_COUNT);
 }
 
+inline int safexcel_rdesc_check_errors(struct safexcel_crypto_priv *priv,
+                                      struct safexcel_result_desc *rdesc)
+{
+       if (likely(!rdesc->result_data.error_code))
+               return 0;
+
+       if (rdesc->result_data.error_code & 0x407f) {
+               /* Fatal error (bits 0-7, 14) */
+               dev_err(priv->dev,
+                       "cipher: result: result descriptor error (%d)\n",
+                       rdesc->result_data.error_code);
+               return -EIO;
+       } else if (rdesc->result_data.error_code == BIT(9)) {
+               /* Authentication failed */
+               return -EBADMSG;
+       }
+
+       /* All other non-fatal errors */
+       return -EINVAL;
+}
+
 void safexcel_complete(struct safexcel_crypto_priv *priv, int ring)
 {
        struct safexcel_command_desc *cdesc;
index eec75dfcdad7c9e2ce0df83d7f710bf8fe6e5b78..dce02bf92dff5f45b9aa7b9ec929c4f78f66f240 100644 (file)
@@ -610,6 +610,8 @@ struct safexcel_inv_result {
 };
 
 void safexcel_dequeue(struct safexcel_crypto_priv *priv, int ring);
+int safexcel_rdesc_check_errors(struct safexcel_crypto_priv *priv,
+                               struct safexcel_result_desc *rdesc);
 void safexcel_complete(struct safexcel_crypto_priv *priv, int ring);
 int safexcel_invalidate_cache(struct crypto_async_request *async,
                              struct safexcel_crypto_priv *priv,
index 1f4787ea272541131c13f180cb5c08ac4dae9786..2452fce64fb7315f6e7085d4e855e82b85b00b03 100644 (file)
@@ -160,12 +160,8 @@ static int safexcel_handle_req_result(struct safexcel_crypto_priv *priv, int rin
                        break;
                }
 
-               if (rdesc->result_data.error_code) {
-                       dev_err(priv->dev,
-                               "cipher: result: result descriptor error (%d)\n",
-                               rdesc->result_data.error_code);
-                       *ret = -EIO;
-               }
+               if (likely(!*ret))
+                       *ret = safexcel_rdesc_check_errors(priv, rdesc);
 
                ndesc++;
        } while (!rdesc->last_seg);
index 00d2cad0ff1c704b54b810d0e7c475d77639b519..6cbd879e8fb52def513250f87ee40627a62586aa 100644 (file)
@@ -146,11 +146,8 @@ static int safexcel_handle_req_result(struct safexcel_crypto_priv *priv, int rin
                dev_err(priv->dev,
                        "hash: result: could not retrieve the result descriptor\n");
                *ret = PTR_ERR(rdesc);
-       } else if (rdesc->result_data.error_code) {
-               dev_err(priv->dev,
-                       "hash: result: result descriptor error (%d)\n",
-                       rdesc->result_data.error_code);
-               *ret = -EINVAL;
+       } else {
+               *ret = safexcel_rdesc_check_errors(priv, rdesc);
        }
 
        safexcel_complete(priv, ring);