Merge branch 'next-general' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris...
[sfrench/cifs-2.6.git] / drivers / crypto / caam / caamalg.c
index 579578498debba63f5bbe9efa54b872fc1da1c18..3e23d4b2cce2a5017c088405334ef2f25c124ff0 100644 (file)
@@ -638,6 +638,39 @@ badkey:
        return -EINVAL;
 }
 
+static int des3_aead_setkey(struct crypto_aead *aead, const u8 *key,
+                           unsigned int keylen)
+{
+       struct crypto_authenc_keys keys;
+       u32 flags;
+       int err;
+
+       err = crypto_authenc_extractkeys(&keys, key, keylen);
+       if (unlikely(err))
+               goto badkey;
+
+       err = -EINVAL;
+       if (keys.enckeylen != DES3_EDE_KEY_SIZE)
+               goto badkey;
+
+       flags = crypto_aead_get_flags(aead);
+       err = __des3_verify_key(&flags, keys.enckey);
+       if (unlikely(err)) {
+               crypto_aead_set_flags(aead, flags);
+               goto out;
+       }
+
+       err = aead_setkey(aead, key, keylen);
+
+out:
+       memzero_explicit(&keys, sizeof(keys));
+       return err;
+
+badkey:
+       crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
+       goto out;
+}
+
 static int gcm_setkey(struct crypto_aead *aead,
                      const u8 *key, unsigned int keylen)
 {
@@ -2457,7 +2490,7 @@ static struct caam_aead_alg driver_aeads[] = {
                                                   "cbc-des3_ede-caam",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
@@ -2479,7 +2512,7 @@ static struct caam_aead_alg driver_aeads[] = {
                                                   "cbc-des3_ede-caam",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
@@ -2502,7 +2535,7 @@ static struct caam_aead_alg driver_aeads[] = {
                                                   "cbc-des3_ede-caam",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
@@ -2525,7 +2558,7 @@ static struct caam_aead_alg driver_aeads[] = {
                                                   "cbc-des3_ede-caam",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
@@ -2548,7 +2581,7 @@ static struct caam_aead_alg driver_aeads[] = {
                                                   "cbc-des3_ede-caam",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
@@ -2571,7 +2604,7 @@ static struct caam_aead_alg driver_aeads[] = {
                                                   "cbc-des3_ede-caam",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
@@ -2594,7 +2627,7 @@ static struct caam_aead_alg driver_aeads[] = {
                                                   "cbc-des3_ede-caam",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
@@ -2617,7 +2650,7 @@ static struct caam_aead_alg driver_aeads[] = {
                                                   "cbc-des3_ede-caam",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
@@ -2640,7 +2673,7 @@ static struct caam_aead_alg driver_aeads[] = {
                                                   "cbc-des3_ede-caam",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
@@ -2663,7 +2696,7 @@ static struct caam_aead_alg driver_aeads[] = {
                                                   "cbc-des3_ede-caam",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
@@ -2686,7 +2719,7 @@ static struct caam_aead_alg driver_aeads[] = {
                                                   "cbc-des3_ede-caam",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
@@ -2709,7 +2742,7 @@ static struct caam_aead_alg driver_aeads[] = {
                                                   "cbc-des3_ede-caam",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
@@ -3460,7 +3493,7 @@ static int __init caam_algapi_init(void)
        u32 aes_vid, aes_inst, des_inst, md_vid, md_inst, ccha_inst, ptha_inst;
        u32 arc4_inst;
        unsigned int md_limit = SHA512_DIGEST_SIZE;
-       bool registered = false;
+       bool registered = false, gcm_support;
 
        dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
        if (!dev_node) {
@@ -3493,7 +3526,7 @@ static int __init caam_algapi_init(void)
         * First, detect presence and attributes of DES, AES, and MD blocks.
         */
        if (priv->era < 10) {
-               u32 cha_vid, cha_inst;
+               u32 cha_vid, cha_inst, aes_rn;
 
                cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
                aes_vid = cha_vid & CHA_ID_LS_AES_MASK;
@@ -3508,6 +3541,10 @@ static int __init caam_algapi_init(void)
                            CHA_ID_LS_ARC4_SHIFT;
                ccha_inst = 0;
                ptha_inst = 0;
+
+               aes_rn = rd_reg32(&priv->ctrl->perfmon.cha_rev_ls) &
+                        CHA_ID_LS_AES_MASK;
+               gcm_support = !(aes_vid == CHA_VER_VID_AES_LP && aes_rn < 8);
        } else {
                u32 aesa, mdha;
 
@@ -3523,6 +3560,8 @@ static int __init caam_algapi_init(void)
                ccha_inst = rd_reg32(&priv->ctrl->vreg.ccha) & CHA_VER_NUM_MASK;
                ptha_inst = rd_reg32(&priv->ctrl->vreg.ptha) & CHA_VER_NUM_MASK;
                arc4_inst = rd_reg32(&priv->ctrl->vreg.afha) & CHA_VER_NUM_MASK;
+
+               gcm_support = aesa & CHA_VER_MISC_AES_GCM;
        }
 
        /* If MD is present, limit digest size based on LP256 */
@@ -3595,11 +3634,9 @@ static int __init caam_algapi_init(void)
                if (c2_alg_sel == OP_ALG_ALGSEL_POLY1305 && !ptha_inst)
                        continue;
 
-               /*
-                * Check support for AES algorithms not available
-                * on LP devices.
-                */
-               if (aes_vid  == CHA_VER_VID_AES_LP && alg_aai == OP_ALG_AAI_GCM)
+               /* Skip GCM algorithms if not supported by device */
+               if (c1_alg_sel == OP_ALG_ALGSEL_AES &&
+                   alg_aai == OP_ALG_AAI_GCM && !gcm_support)
                        continue;
 
                /*