{
        int len = 0;
 
+       if (!IS_ALIGNED(total, AES_BLOCK_SIZE))
+               return -EINVAL;
+
        while (sg) {
                if (!IS_ALIGNED(sg->offset, 4))
                        return -1;
 static int omap_aes_copy_sgs(struct omap_aes_dev *dd)
 {
        void *buf_in, *buf_out;
-       int pages;
+       int pages, total;
 
-       pages = get_order(dd->total);
+       total = ALIGN(dd->total, AES_BLOCK_SIZE);
+       pages = get_order(total);
 
        buf_in = (void *)__get_free_pages(GFP_ATOMIC, pages);
        buf_out = (void *)__get_free_pages(GFP_ATOMIC, pages);
        sg_copy_buf(buf_in, dd->in_sg, 0, dd->total, 0);
 
        sg_init_table(&dd->in_sgl, 1);
-       sg_set_buf(&dd->in_sgl, buf_in, dd->total);
+       sg_set_buf(&dd->in_sgl, buf_in, total);
        dd->in_sg = &dd->in_sgl;
 
        sg_init_table(&dd->out_sgl, 1);
-       sg_set_buf(&dd->out_sgl, buf_out, dd->total);
+       sg_set_buf(&dd->out_sgl, buf_out, total);
        dd->out_sg = &dd->out_sgl;
 
        return 0;
        struct omap_aes_ctx *ctx;
        struct omap_aes_reqctx *rctx;
        unsigned long flags;
-       int err, ret = 0;
+       int err, ret = 0, len;
 
        spin_lock_irqsave(&dd->lock, flags);
        if (req)
                dd->sgs_copied = 0;
        }
 
-       dd->in_sg_len = scatterwalk_bytes_sglen(dd->in_sg, dd->total);
-       dd->out_sg_len = scatterwalk_bytes_sglen(dd->out_sg, dd->total);
+       len = ALIGN(dd->total, AES_BLOCK_SIZE);
+       dd->in_sg_len = scatterwalk_bytes_sglen(dd->in_sg, len);
+       dd->out_sg_len = scatterwalk_bytes_sglen(dd->out_sg, len);
        BUG_ON(dd->in_sg_len < 0 || dd->out_sg_len < 0);
 
        rctx = ablkcipher_request_ctx(req);
 {
        struct omap_aes_dev *dd = (struct omap_aes_dev *)data;
        void *buf_in, *buf_out;
-       int pages;
+       int pages, len;
 
        pr_debug("enter done_task\n");
 
 
                sg_copy_buf(buf_out, dd->orig_out, 0, dd->total_save, 1);
 
-               pages = get_order(dd->total_save);
+               len = ALIGN(dd->total_save, AES_BLOCK_SIZE);
+               pages = get_order(len);
                free_pages((unsigned long)buf_in, pages);
                free_pages((unsigned long)buf_out, pages);
        }
                  !!(mode & FLAGS_ENCRYPT),
                  !!(mode & FLAGS_CBC));
 
-       if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE)) {
-               pr_err("request size is not exact amount of AES blocks\n");
-               return -EINVAL;
-       }
-
        dd = omap_aes_find_dev(ctx);
        if (!dd)
                return -ENODEV;
                        }
                }
 
-               dd->total -= AES_BLOCK_SIZE;
-
-               BUG_ON(dd->total < 0);
+               dd->total -= min_t(size_t, AES_BLOCK_SIZE, dd->total);
 
                /* Clear IRQ status */
                status &= ~AES_REG_IRQ_DATA_OUT;