This patch forbids the use of 2-key 3DES (K1 == K3) in FIPS mode.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Reviewed-by: Horia Geantă <horia.geanta@nxp.com>
Tested-by: Iuliana Prodan <iuliana.prodan@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
        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)
 {
                                                   "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,
                                                   "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,
                                                   "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,
                                                   "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,
                                                   "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,
                                                   "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,
                                                   "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,
                                                   "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,
                                                   "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,
                                                   "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,
                                                   "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,
                                                   "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,
 
        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_set_sh_desc(struct crypto_aead *aead)
 {
        struct caam_ctx *ctx = crypto_aead_ctx(aead);
        return -EINVAL;
 }
 
+static int des3_skcipher_setkey(struct crypto_skcipher *skcipher,
+                               const u8 *key, unsigned int keylen)
+{
+       return unlikely(des3_verify_key(skcipher, key)) ?:
+              skcipher_setkey(skcipher, key, keylen);
+}
+
 static int xts_skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
                               unsigned int keylen)
 {
                                .cra_driver_name = "cbc-3des-caam-qi",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = skcipher_setkey,
+                       .setkey = des3_skcipher_setkey,
                        .encrypt = skcipher_encrypt,
                        .decrypt = skcipher_decrypt,
                        .min_keysize = DES3_EDE_KEY_SIZE,
                                                   "cbc-des3_ede-caam-qi",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
                                                   "cbc-des3_ede-caam-qi",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
                                                   "cbc-des3_ede-caam-qi",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
                                                   "cbc-des3_ede-caam-qi",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
                                                   "cbc-des3_ede-caam-qi",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
                                                   "cbc-des3_ede-caam-qi",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
                                                   "cbc-des3_ede-caam-qi",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
                                                   "cbc-des3_ede-caam-qi",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
                                                   "cbc-des3_ede-caam-qi",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
                                                   "cbc-des3_ede-caam-qi",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
                                                   "cbc-des3_ede-caam-qi",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
                                                   "cbc-des3_ede-caam-qi",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
 
        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 struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
                                           bool encrypt)
 {
        return 0;
 }
 
+static int des3_skcipher_setkey(struct crypto_skcipher *skcipher,
+                               const u8 *key, unsigned int keylen)
+{
+       return unlikely(des3_verify_key(skcipher, key)) ?:
+              skcipher_setkey(skcipher, key, keylen);
+}
+
 static int xts_skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
                               unsigned int keylen)
 {
                                .cra_driver_name = "cbc-3des-caam-qi2",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = skcipher_setkey,
+                       .setkey = des3_skcipher_setkey,
                        .encrypt = skcipher_encrypt,
                        .decrypt = skcipher_decrypt,
                        .min_keysize = DES3_EDE_KEY_SIZE,
                                                   "cbc-des3_ede-caam-qi2",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
                                                   "cbc-des3_ede-caam-qi2",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
                                                   "cbc-des3_ede-caam-qi2",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
                                                   "cbc-des3_ede-caam-qi2",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
                                                   "cbc-des3_ede-caam-qi2",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
                                                   "cbc-des3_ede-caam-qi2",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
                                                   "cbc-des3_ede-caam-qi2",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
                                                   "cbc-des3_ede-caam-qi2",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
                                                   "cbc-des3_ede-caam-qi2",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
                                                   "cbc-des3_ede-caam-qi2",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
                                                   "cbc-des3_ede-caam-qi2",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,
                                                   "cbc-des3_ede-caam-qi2",
                                .cra_blocksize = DES3_EDE_BLOCK_SIZE,
                        },
-                       .setkey = aead_setkey,
+                       .setkey = des3_aead_setkey,
                        .setauthsize = aead_setauthsize,
                        .encrypt = aead_encrypt,
                        .decrypt = aead_decrypt,