crypto: talitos - use devm_kmalloc()
[linux-2.6-block.git] / drivers / crypto / talitos.c
index 1e799886c57dc42d7883ec1b5c7e3ea213eff95f..2a53d0f2a869b5d6cd21179c700c21ed23454bae 100644 (file)
@@ -75,7 +75,6 @@ static void to_talitos_ptr_len(struct talitos_ptr *ptr, unsigned int len,
                               bool is_sec1)
 {
        if (is_sec1) {
-               ptr->res = 0;
                ptr->len1 = cpu_to_be16(len);
        } else {
                ptr->len = cpu_to_be16(len);
@@ -118,7 +117,6 @@ static void map_single_talitos_ptr(struct device *dev,
 
        to_talitos_ptr_len(ptr, len, is_sec1);
        to_talitos_ptr(ptr, dma_addr, is_sec1);
-       to_talitos_ptr_ext_set(ptr, 0, is_sec1);
 }
 
 /*
@@ -287,7 +285,6 @@ int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,
        /* map descriptor and save caller data */
        if (is_sec1) {
                desc->hdr1 = desc->hdr;
-               desc->next_desc = 0;
                request->dma_desc = dma_map_single(dev, &desc->hdr1,
                                                   TALITOS_DESC_SIZE,
                                                   DMA_BIDIRECTIONAL);
@@ -1116,7 +1113,7 @@ next:
        return count;
 }
 
-int talitos_sg_map(struct device *dev, struct scatterlist *src,
+static int talitos_sg_map(struct device *dev, struct scatterlist *src,
                   unsigned int len, struct talitos_edesc *edesc,
                   struct talitos_ptr *ptr,
                   int sg_count, unsigned int offset, int tbl_off)
@@ -1125,7 +1122,6 @@ int talitos_sg_map(struct device *dev, struct scatterlist *src,
        bool is_sec1 = has_ftr_sec1(priv);
 
        to_talitos_ptr_len(ptr, len, is_sec1);
-       to_talitos_ptr_ext_set(ptr, 0, is_sec1);
 
        if (sg_count == 1) {
                to_talitos_ptr(ptr, sg_dma_address(src) + offset, is_sec1);
@@ -1197,11 +1193,9 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
        if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP) {
                to_talitos_ptr(&desc->ptr[2], edesc->iv_dma, is_sec1);
                to_talitos_ptr_len(&desc->ptr[2], ivsize, is_sec1);
-               to_talitos_ptr_ext_set(&desc->ptr[2], 0, is_sec1);
        } else {
                to_talitos_ptr(&desc->ptr[3], edesc->iv_dma, is_sec1);
                to_talitos_ptr_len(&desc->ptr[3], ivsize, is_sec1);
-               to_talitos_ptr_ext_set(&desc->ptr[3], 0, is_sec1);
        }
 
        /* cipher key */
@@ -1221,7 +1215,6 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
         * typically 12 for ipsec
         */
        to_talitos_ptr_len(&desc->ptr[4], cryptlen, is_sec1);
-       to_talitos_ptr_ext_set(&desc->ptr[4], 0, is_sec1);
 
        sg_link_tbl_len = cryptlen;
 
@@ -1232,8 +1225,8 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
                        sg_link_tbl_len += authsize;
        }
 
-       ret = talitos_sg_map(dev, areq->src, cryptlen, edesc, &desc->ptr[4],
-                            sg_count, areq->assoclen, tbl_off);
+       ret = talitos_sg_map(dev, areq->src, sg_link_tbl_len, edesc,
+                            &desc->ptr[4], sg_count, areq->assoclen, tbl_off);
 
        if (ret > 1) {
                tbl_off += ret;
@@ -1406,6 +1399,7 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
                err = ERR_PTR(-ENOMEM);
                goto error_sg;
        }
+       memset(&edesc->desc, 0, sizeof(edesc->desc));
 
        edesc->src_nents = src_nents;
        edesc->dst_nents = dst_nents;
@@ -1481,7 +1475,6 @@ static int aead_decrypt(struct aead_request *req)
                                  DESC_HDR_MODE1_MDEU_CICV;
 
                /* reset integrity check result bits */
-               edesc->desc.hdr_lo = 0;
 
                return ipsec_esp(edesc, req, ipsec_esp_decrypt_hwauth_done);
        }
@@ -1507,12 +1500,20 @@ static int ablkcipher_setkey(struct crypto_ablkcipher *cipher,
                             const u8 *key, unsigned int keylen)
 {
        struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+       u32 tmp[DES_EXPKEY_WORDS];
 
        if (keylen > TALITOS_MAX_KEY_SIZE) {
                crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
                return -EINVAL;
        }
 
+       if (unlikely(crypto_ablkcipher_get_flags(cipher) &
+                    CRYPTO_TFM_REQ_WEAK_KEY) &&
+           !des_ekey(tmp, key)) {
+               crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_WEAK_KEY);
+               return -EINVAL;
+       }
+
        memcpy(&ctx->key, key, keylen);
        ctx->keylen = keylen;
 
@@ -1568,12 +1569,10 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
        bool is_sec1 = has_ftr_sec1(priv);
 
        /* first DWORD empty */
-       desc->ptr[0] = zero_entry;
 
        /* cipher iv */
        to_talitos_ptr(&desc->ptr[1], edesc->iv_dma, is_sec1);
        to_talitos_ptr_len(&desc->ptr[1], ivsize, is_sec1);
-       to_talitos_ptr_ext_set(&desc->ptr[1], 0, is_sec1);
 
        /* cipher key */
        map_single_talitos_ptr(dev, &desc->ptr[2], ctx->keylen,
@@ -1612,7 +1611,6 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
                               DMA_FROM_DEVICE);
 
        /* last DWORD empty */
-       desc->ptr[6] = zero_entry;
 
        if (sync_needed)
                dma_sync_single_for_device(dev, edesc->dma_link_tbl,
@@ -1723,7 +1721,7 @@ static void ahash_done(struct device *dev,
  * SEC1 doesn't like hashing of 0 sized message, so we do the padding
  * ourself and submit a padded block
  */
-void talitos_handle_buggy_hash(struct talitos_ctx *ctx,
+static void talitos_handle_buggy_hash(struct talitos_ctx *ctx,
                               struct talitos_edesc *edesc,
                               struct talitos_ptr *ptr)
 {
@@ -1758,7 +1756,6 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc,
        int sg_count;
 
        /* first DWORD empty */
-       desc->ptr[0] = zero_entry;
 
        /* hash context in */
        if (!req_ctx->first || req_ctx->swinit) {
@@ -1767,8 +1764,6 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc,
                                       (char *)req_ctx->hw_context,
                                       DMA_TO_DEVICE);
                req_ctx->swinit = 0;
-       } else {
-               desc->ptr[1] = zero_entry;
        }
        /* Indicate next op is not the first. */
        req_ctx->first = 0;
@@ -1777,8 +1772,6 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc,
        if (ctx->keylen)
                map_single_talitos_ptr(dev, &desc->ptr[2], ctx->keylen,
                                       (char *)&ctx->key, DMA_TO_DEVICE);
-       else
-               desc->ptr[2] = zero_entry;
 
        sg_count = edesc->src_nents ?: 1;
        if (is_sec1 && sg_count > 1)
@@ -1795,7 +1788,6 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc,
                sync_needed = true;
 
        /* fifth DWORD empty */
-       desc->ptr[4] = zero_entry;
 
        /* hash/HMAC out -or- hash context out */
        if (req_ctx->last)
@@ -1808,7 +1800,6 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc,
                                       req_ctx->hw_context, DMA_FROM_DEVICE);
 
        /* last DWORD empty */
-       desc->ptr[6] = zero_entry;
 
        if (is_sec1 && from_talitos_ptr_len(&desc->ptr[3], true) == 0)
                talitos_handle_buggy_hash(ctx, edesc, &desc->ptr[3]);
@@ -2627,7 +2618,7 @@ static struct talitos_alg_template driver_algs[] = {
                                .ivsize = AES_BLOCK_SIZE,
                        }
                },
-               .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+               .desc_hdr_template = DESC_HDR_TYPE_AESU_CTR_NONSNOOP |
                                     DESC_HDR_SEL0_AESU |
                                     DESC_HDR_MODE0_AESU_CTR,
        },
@@ -3002,17 +2993,11 @@ static int talitos_remove(struct platform_device *ofdev)
                        break;
                }
                list_del(&t_alg->entry);
-               kfree(t_alg);
        }
 
        if (hw_supports(dev, DESC_HDR_SEL0_RNG))
                talitos_unregister_rng(dev);
 
-       for (i = 0; priv->chan && i < priv->num_channels; i++)
-               kfree(priv->chan[i].fifo);
-
-       kfree(priv->chan);
-
        for (i = 0; i < 2; i++)
                if (priv->irq[i]) {
                        free_irq(priv->irq[i], dev);
@@ -3025,8 +3010,6 @@ static int talitos_remove(struct platform_device *ofdev)
 
        iounmap(priv->reg);
 
-       kfree(priv);
-
        return 0;
 }
 
@@ -3038,7 +3021,8 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
        struct talitos_crypto_alg *t_alg;
        struct crypto_alg *alg;
 
-       t_alg = kzalloc(sizeof(struct talitos_crypto_alg), GFP_KERNEL);
+       t_alg = devm_kzalloc(dev, sizeof(struct talitos_crypto_alg),
+                            GFP_KERNEL);
        if (!t_alg)
                return ERR_PTR(-ENOMEM);
 
@@ -3060,6 +3044,11 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
                t_alg->algt.alg.aead.setkey = aead_setkey;
                t_alg->algt.alg.aead.encrypt = aead_encrypt;
                t_alg->algt.alg.aead.decrypt = aead_decrypt;
+               if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
+                   !strncmp(alg->cra_name, "authenc(hmac(sha224)", 20)) {
+                       devm_kfree(dev, t_alg);
+                       return ERR_PTR(-ENOTSUPP);
+               }
                break;
        case CRYPTO_ALG_TYPE_AHASH:
                alg = &t_alg->algt.alg.hash.halg.base;
@@ -3077,7 +3066,7 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
 
                if (!(priv->features & TALITOS_FTR_HMAC_OK) &&
                    !strncmp(alg->cra_name, "hmac", 4)) {
-                       kfree(t_alg);
+                       devm_kfree(dev, t_alg);
                        return ERR_PTR(-ENOTSUPP);
                }
                if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
@@ -3092,7 +3081,7 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
                break;
        default:
                dev_err(dev, "unknown algorithm type %d\n", t_alg->algt.type);
-               kfree(t_alg);
+               devm_kfree(dev, t_alg);
                return ERR_PTR(-EINVAL);
        }
 
@@ -3173,7 +3162,7 @@ static int talitos_probe(struct platform_device *ofdev)
        int i, err;
        int stride;
 
-       priv = kzalloc(sizeof(struct talitos_private), GFP_KERNEL);
+       priv = devm_kzalloc(dev, sizeof(struct talitos_private), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
 
@@ -3271,8 +3260,8 @@ static int talitos_probe(struct platform_device *ofdev)
                }
        }
 
-       priv->chan = kzalloc(sizeof(struct talitos_channel) *
-                            priv->num_channels, GFP_KERNEL);
+       priv->chan = devm_kzalloc(dev, sizeof(struct talitos_channel) *
+                                      priv->num_channels, GFP_KERNEL);
        if (!priv->chan) {
                dev_err(dev, "failed to allocate channel management space\n");
                err = -ENOMEM;
@@ -3289,8 +3278,9 @@ static int talitos_probe(struct platform_device *ofdev)
                spin_lock_init(&priv->chan[i].head_lock);
                spin_lock_init(&priv->chan[i].tail_lock);
 
-               priv->chan[i].fifo = kzalloc(sizeof(struct talitos_request) *
-                                            priv->fifo_len, GFP_KERNEL);
+               priv->chan[i].fifo = devm_kzalloc(dev,
+                                               sizeof(struct talitos_request) *
+                                               priv->fifo_len, GFP_KERNEL);
                if (!priv->chan[i].fifo) {
                        dev_err(dev, "failed to allocate request fifo %d\n", i);
                        err = -ENOMEM;
@@ -3356,7 +3346,7 @@ static int talitos_probe(struct platform_device *ofdev)
                        if (err) {
                                dev_err(dev, "%s alg registration failed\n",
                                        alg->cra_driver_name);
-                               kfree(t_alg);
+                               devm_kfree(dev, t_alg);
                        } else
                                list_add_tail(&t_alg->entry, &priv->alg_list);
                }