diff -u original/omap-aes.c ecb/omap-aes.c --- original/omap-aes.c 2017-05-04 11:55:41.607498930 +0200 +++ ecb/omap-aes.c 2017-05-05 14:16:59.405794002 +0200 @@ -46,6 +46,144 @@ static DEFINE_SPINLOCK(list_lock); static int aes_fallback_sz = 200; +static unsigned long number_of_error =0; + +void omap_crypto_dump_sg(const char *name, struct scatterlist *sg, int len) +{ + void *buf; + struct scatterlist *tmp; + int i = 0; + int calc_len = 0; + + if (len > 0) + buf = kzalloc(len, GFP_KERNEL); + else + buf = kzalloc(2048, GFP_KERNEL); + if (!buf) + return; + + tmp = sg; + + pr_info("%s: name=%s, sg=%p, len=%d\n", __func__, name, sg, len); + + while (tmp) { + pr_info("%s: i=%d, page=%p, len=%d, offset=%d\n", __func__, + i, sg_page(tmp), tmp->length, tmp->offset); + if (!len) + calc_len += tmp->length; + tmp = sg_next(tmp); + i++; + } + + if (!len) + len = calc_len; + + scatterwalk_map_and_copy(buf, sg, 0, len, 0); + print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET, 16, 1, + buf, len, false); + + kfree(buf); +} + + +static void xor_buffer_32 (unsigned char * buf_io, unsigned char * buf_to_xor, unsigned len) +{ + uint32_t *ptr_io_32; + uint32_t *ptr_to_xor_32; + unsigned len_32 = len >> 2; + unsigned i; + + ptr_io_32 = (uint32_t*) buf_io; + ptr_to_xor_32 = (uint32_t*) buf_to_xor; + + for (i = 0; i < len_32; ++i, ++ptr_io_32, ++ptr_to_xor_32) + { + *ptr_io_32 ^= *ptr_to_xor_32; + } +} + + +static void xor_sg(struct scatterlist * sg_io, unsigned char * buf_to_xor, unsigned len) +{ + struct sg_mapping_iter miter; + unsigned int sg_flags = SG_MITER_ATOMIC | SG_MITER_FROM_SG; + unsigned int nents = sg_nents(sg_io); + unsigned long flags; + unsigned int actual_len; + unsigned int offset = 0; + + sg_miter_start(&miter, sg_io, nents, sg_flags); + + local_irq_save(flags); + + while(sg_miter_next(&miter) && offset < len) + { + actual_len = min(miter.length, (unsigned int)buf_to_xor - offset); + + xor_buffer_32(miter.addr, &buf_to_xor[offset], actual_len); + + offset += actual_len; + } + + sg_miter_stop(&miter); + local_irq_restore(flags); +} + + +unsigned long comp_checksum (unsigned char * buf, int len) +{ + u32 * ptr_32; + unsigned len_32 = len >> 2; + unsigned i; + u32 sum = 0; // because its an uint32_t, the modulo will be automatic + + ptr_32 = (u32 *) buf; + + for (i = 0; i < len_32; ++i, ++ptr_32) + { + sum += *ptr_32; + } + + return sum; +} + +unsigned char tweak_buf[512]={ + 0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x05,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x07,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x09,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x05,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x07,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x09,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + 0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00, + }; + + + #ifdef DEBUG #define omap_aes_read(dd, offset) \ @@ -446,7 +584,10 @@ static int omap_aes_copy_sgs(struct omap_aes_dev *dd) { void *buf_in, *buf_out; - int pages, total; + int pages, total,j,i; + unsigned char ecb_soft[512]; + struct omap_aes_ctx *ctx = crypto_ablkcipher_ctx( + crypto_ablkcipher_reqtfm(dd->req)); total = ALIGN(dd->total, AES_BLOCK_SIZE); pages = get_order(total); @@ -458,10 +599,21 @@ pr_err("Couldn't allocated pages for unaligned cases.\n"); return -1; } - dd->orig_out = dd->out_sg; sg_copy_buf(buf_in, dd->in_sg, 0, dd->total, 0); + if(dd->total !=512) + printk("dd->total = %d \n",dd->total); + + /* + * We compute the checksum of buf_in + * */ + ctx->check_buf_before_ecb = comp_checksum(buf_in,dd->total); + + /* + * We store this buf_in inside the ctx + * */ + memcpy(ctx->c_buf_in,buf_in,dd->total); sg_init_table(dd->in_sgl, 1); sg_set_buf(dd->in_sgl, buf_in, total); @@ -511,25 +663,25 @@ dd->in_sg = req->src; dd->out_sg = req->dst; - if (omap_aes_copy_needed(dd->in_sg, dd->total) || - omap_aes_copy_needed(dd->out_sg, dd->total)) { - if (omap_aes_copy_sgs(dd)) - pr_err("Failed to copy SGs for unaligned cases\n"); - dd->sgs_copied = 1; - } else { - dd->sgs_copied = 0; - } - 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); ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(req)); rctx->mode &= FLAGS_MODE_MASK; dd->flags = (dd->flags & ~FLAGS_MODE_MASK) | rctx->mode; + + if (omap_aes_copy_sgs(dd)) + pr_err("Failed to copy SGs for unaligned cases\n"); + dd->sgs_copied = 1; + + 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); + + dd->ctx = ctx; rctx->dd = dd; @@ -550,7 +702,7 @@ { struct omap_aes_dev *dd = (struct omap_aes_dev *)data; void *buf_in, *buf_out; - int pages, len; + int pages, len,j; pr_debug("enter done_task\n"); @@ -559,7 +711,7 @@ DMA_FROM_DEVICE); dma_unmap_sg(dd->dev, dd->in_sg, dd->in_sg_len, DMA_TO_DEVICE); dma_unmap_sg(dd->dev, dd->out_sg, dd->out_sg_len, - DMA_FROM_DEVICE); + DMA_FROM_DEVICE); omap_aes_crypt_dma_stop(dd); } @@ -567,8 +719,27 @@ buf_in = sg_virt(dd->in_sgl); buf_out = sg_virt(&dd->out_sgl); - sg_copy_buf(buf_out, dd->orig_out, 0, dd->total_save, 1); + if(number_of_error < 5){ + /* + * We compute the checksum of : + * buf_in (to compare if it has changed) + * */ + dd->ctx->check_buf_after_ecb = comp_checksum(buf_in,dd->total); + + if(dd->ctx->check_buf_before_ecb != dd->ctx->check_buf_after_ecb ){ + number_of_error++; + printk("buf_in before ecb with co-pro: %lu and buf_in after : %lu \n",dd->ctx->check_buf_before_ecb,dd->ctx->check_buf_after_ecb ); + print_hex_dump(KERN_CONT, "buf_in_after_ecb", DUMP_PREFIX_OFFSET, 16, 1, + buf_in, dd->total, false); + print_hex_dump(KERN_CONT, "buf_in_in_ctx", DUMP_PREFIX_OFFSET, 16, 1, + dd->ctx->c_buf_in, dd->total, false); + omap_crypto_dump_sg("sg_in_after_ecb",dd->in_sgl,dd->total); + print_hex_dump(KERN_CONT, "buf_out", DUMP_PREFIX_OFFSET, 16, 1, + buf_out, dd->total, false); + } + } + sg_copy_buf(buf_out, dd->orig_out, 0, dd->total_save, 1); len = ALIGN(dd->total_save, AES_BLOCK_SIZE); pages = get_order(len); free_pages((unsigned long)buf_in, pages); diff -u original/omap-aes.h ecb/omap-aes.h --- original/omap-aes.h 2017-05-04 11:55:45.060446780 +0200 +++ ecb/omap-aes.h 2017-05-05 14:12:04.757987534 +0200 @@ -93,6 +93,9 @@ u32 key[AES_KEYSIZE_256 / sizeof(u32)]; u8 nonce[4]; unsigned long flags; + unsigned char c_buf_in[512]; /* buf to check buf_in */ + unsigned long check_buf_before_ecb; + unsigned long check_buf_after_ecb; struct crypto_skcipher *ctr; struct crypto_ablkcipher *fallback; };