[QUESTION] blkcipher_walk_phys and memory

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Dear all, I have a couple of questions about crypto internals, please
help me to understand some concepts. My drivers implements
CRYPTO_ALG_TYPE_BLKCIPHER algorithm and has to perform encryption via
DMA transfers.
I decided to use blkcipher_walk_phys() and blkcipher_walk_done()
functions. These functions take scatterlist and return one or more
struct page's and offsets. Then i pass those to dma_map_page() which
returns  dma_addr_t  to send to my device's DMA engine.
Everything seems to work (on ARM) but i have several questions:

1. Is it generally correct to do this? (see *_encrypt() handler below)
2. Article at http://linux-mm.org/DeviceDriverMmap
says "You may be tempted to call virt_to_page(addr) to get a struct
page pointer for a kmalloced address, but this is a violation of the
abstraction: kmalloc does not return pages, it returns another type of
memory object."
And blkcipher_walk_init() internally calls virt_to_page() on a pointer
allocated from unknown location (for example, in tcrypt.c there is
statically allocated buffer, but it is just one case of many). Is it
correct and how to think about it?


static int mcrypto_3des_ecb_encrypt(struct blkcipher_desc *desc,
    struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
{
    struct mcrypto_device *device = &g_mcrypto_device;
    struct mcrypto_3des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
    struct blkcipher_walk walk;
    int err;

    blkcipher_walk_init(&walk, dst, src, nbytes);
    err = blkcipher_walk_phys(desc, &walk);
    ctx->mode = mcrypto_encrypt;

    while((nbytes = walk.nbytes)) {
        dma_addr_t src_dma, dst_dma;
        size_t size = nbytes - (nbytes % DES3_EDE_MIN_BLOCK_SIZE);

        src_dma = dma_map_page(device->dev, walk.src.phys.page,
            walk.src.phys.offset, size, DMA_TO_DEVICE);
        dst_dma = dma_map_page(device->dev, walk.dst.phys.page,
            walk.dst.phys.offset, size, DMA_FROM_DEVICE);

        /* Performs actual DMA transfers and waits for completion */
        mcrypto_3des_dmacrypt(device, ctx, src_dma, dst_dma, size);

        dma_unmap_page(device->dev, dst_dma, size, DMA_FROM_DEVICE);
        dma_unmap_page(device->dev, src_dma, size, DMA_TO_DEVICE);

        err = blkcipher_walk_done(desc, &walk, nbytes-size);
    }
    return err;
}


-- 
Thanks,
Sergey
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel]     [Gnu Classpath]     [Gnu Crypto]     [DM Crypt]     [Netfilter]     [Bugtraq]

  Powered by Linux