Dear Mr. Goff,

(Adding linux-crypto in Cc, please always do so for this kind of
correspondence.)

On Tue, Mar 13, 2012 at 06:29:31PM +0000, Michael Goff wrote:
> I am running into an issue with mv_cesa.  We are working with QNAP network 
> attached storage devices that run a marvell arm chip that has crypto support 
> via the mv_cesa module that you maintain.  We are using the cryptodev module 
> to run cryptography through the kernel from userspace.  QNAP is running the 
> linux kernel version 2.6.33.2.  This version of mv_cesa seems to have a 
> problem when hashing blocks larger than 1920 bytes.  I noticed a commit 
> (274252862f386b7868f35bf5ceaa5391a8ccfdf3) that says it fixes a 1920 byte 
> limit and we also want to use the hardware offloading of sha1 provided by 
> newer mv_cesa code.  What we did is grab mv_cesa.c and mv_cesa.h (from 
> 274252862f386b7868f35bf5ceaa5391a8ccfdf3) and built the mv_cesa module in the 
> 2.6.33.2 tree.  This seemed to have successfully added sha1 hardware 
> offloading but rather than fixing the 1920 byte limit it made things worse.

I don't fully understand your description here. With vanilla 2.6.33.2
you say there is a problem with hashing blocks larger than 1920 bytes
although in vanilla 2.6.33.2 there was no support for sha1 in mv_cesa.c
yet?

> I am going to attach a simple c program that runs aes128 cbc through 
> cryptodev and dumps the unencrypted and encrypted data in files.  Then I run 
> the unencrypted file through openssl to verify the results.  Without the 
> mv_cesa module insmoded the results of cryptodev and openssl are the same.  
> With the mv_cesa module from 2.6.33.2, the results are the same up until 
> after the 1920 byte limit.  With the mv_cesa module built from 
> 274252862f386b7868f35bf5ceaa5391a8ccfdf3 if the source data is all zeros the 
> results are the same up until 1920, however if input data is anything other 
> than all zeros (random or all 1's for instance) they differ completely.

Can you reproduce this with a current kernel? Just to make sure this is
not a heisenbug resulting from the combination of current mv_cesa.c with
your kernel version.

What hardware are you running this on exactly? Which implementation of
cryptodev are you using?

> The program I'm attaching to test this takes 3 parameters: the name of a file 
> to place the data that will be encrypted, the name of a file to put the 
> resulting encrypted data, the number of bytes of data to generate/encrypt.  
> Here is a sample use of the program and comparing it to openssl:
> > gcc repro.c
> > ./a.out toencrypt cryptoenc 2000
> > openssl enc -in toencrypt -iv 0 -K 0 -out opensslenc -nopad -aes-128-cbc
> > hexdump -x cryptoenc > cryptoenc.hex
> > hexdump -x opensslenc > opensslenc.hex
> > diff cryptoenc.hex opensslenc.hex
> 
> Here are the results of my tests again for reference:
> Setup
> 
> Result
> 
> Plain cryptodev without mv_cesa
> 
> Works: same as openssl for tested values
> 
> Mv_cesa from 2.6.33.2
> 
> Works up to 1920 but after that different than openssl
> 
> Mv_cesa from 274252862f386b7868f35bf5ceaa5391a8ccfdf3
> 
> Works for all zeros input until 1920 then different but for all other input 
> values differs from openssl output completely.
> 
> 
> 
> Thank you for your help,
> Michael Goff
> Symform Inc.
> http://symform.com
> 

> #include <stdio.h>
> #include <fcntl.h>
> #include <cryptodev.h>
> #include <string.h>
> #include <sys/ioctl.h>
> 
> #define KEY_SIZE        16
> #define BLOCK_SIZE      16
> 
> static int test_crypto(int fd, char *to_encrypt_file, char *encrypted_file, 
> int data_size)
> {
>         struct {
>                 char    in[data_size],
>                         encrypted[data_size],
>                         iv[BLOCK_SIZE],
>                         key[KEY_SIZE];
>         } data;
> 
>         struct session_op sess;
>         struct crypt_op cryp;
> 
>         /* Set iv and key to 0's */
>         memset(data.iv, 0, BLOCK_SIZE);
>         memset(data.key, 0, KEY_SIZE);
> 
>         /* We'll leave data.in alone to pick up junk from the stack for 
> "random" data */
> 
>         /* Get crypto session for AES128 */
>         sess.cipher = CRYPTO_AES_CBC;
>         sess.keylen = KEY_SIZE;
>         sess.key = data.key;
>         if (ioctl(fd, CIOCGSESSION, &sess)) {
>                 perror("ioctl(CIOCGSESSION)");
>                 return 1;
>         }
> 
>         /* Encrypt data.in to data.encrypted */
>         cryp.ses = sess.ses;
>         cryp.len = sizeof(data.in);
>         cryp.src = data.in;
>         cryp.dst = data.encrypted;
>         cryp.iv = data.iv;
>         cryp.op = COP_ENCRYPT;
>         if (ioctl(fd, CIOCCRYPT, &cryp)) {
>                 perror("ioctl(CIOCCRYPT)");
>                 return 1;
>         }
> 
>         /* Output input and output of encryption */
>         FILE *file = fopen(to_encrypt_file, "w+");
>         fwrite(data.in, sizeof(char), data_size, file);
>         fclose(file);
> 
>         file = fopen(encrypted_file, "w+");
>         fwrite(data.encrypted, sizeof(char), data_size, file);
>         fclose(file);
> 
>         /* Finish crypto session */
>         if (ioctl(fd, CIOCFSESSION, &sess.ses)) {
>                 perror("ioctl(CIOCFSESSION)");
>                 return 1;
>         }
> 
>         return 0;
> }
> 
> int main(int argc, char *argv[])
> {
>         if (argc != 4) {
>                 printf("Usage: %s UNENCRYPTED_FILE ENCRYPTED_FILE 
> NUMBER_OF_BYTES", argv[0]);
>                 printf("\n\tUNENCRYPTED_FILE: Filename to write the input 
> data used to");
>                 printf("\n\tENCRYPTED_FILE: File to write the encrypted input 
> data to");
>                 printf("\n\tNUMBER_OF_BYTES: The number of bytes of data to 
> encrypt");
>                 printf("\n\n\tThis program will take some data from stack 
> garbage and encrypte it\n");
>                 printf("\n\toutputting the unencrypted and encrypted data to 
> files.\n");
>                 printf("\n\tThen invoke openssl like the follow to 
> verify:\n");
>                 printf("\n\topenssl enc -in UNENCRYPTED_FILE -iv 0 -K 0 
> \\\n");
>                 printf("\t\t-out OPENSSL_ENCRYPTED_FILE -nopad 
> -aes-128-cbc\n");
>                 return 1;
>         }
> 
>         int number_of_bytes = atoi(argv[3]);
> 
>         int fd = -1;
>         fd = open("/dev/crypto", O_RDWR, 0);
>         if (fd < 0)
>         {
>                 perror("open(/dev/crypto)");
>                 return 1;
>         }
> 
>         /* Set close-on-exec (not really neede here) */
>         if (fcntl(fd, F_SETFD, 1) == -1) {
>                 perror("fcntl(F_SETFD)");
>                 return 1;
>         }
> 
>         test_crypto(fd, argv[1], argv[2], number_of_bytes);
> 
>         if(close(fd))
>         {
>                 perror("close(fd)");
>                 return 1;
>         }
> 
>         return 0;
> }



Phil Sutter
Software Engineer

-- 
Viprinet – Never be offline again!

************************************************
Viprinet auf der CeBIT 2012 – 6.-10. März:
Besuchen Sie uns in Halle 13, Stand D27!
Alle gezeigten Produkte im Livebetrieb,
zahlreiche Beispielapplikationen. Gerne
schicken wir Ihnen kostenlose Eintrittskarten.
************************************************
Viprinet at CeBIT 2012, March 6 to 10
in Hannover, Germany. Come and visit us
at Hall 13, Booth D27! All exhibits shown
live, many sample applications. We’ll be
happy to send you free admission tickets.
************************************************


Viprinet GmbH
Mainzer Str. 43
55411 Bingen am Rhein
Germany

Phone/Zentrale:         +49-6721-49030-0
Direct line/Durchwahl:  +49-6721-49030-134
Fax:                    +49-6721-49030-209

phil.sut...@viprinet.com
http://www.viprinet.com

Registered office/Sitz der Gesellschaft: Bingen am Rhein
Commercial register/Handelsregister: Amtsgericht Mainz HRB40380
CEO/Geschäftsführer: Simon Kissel
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to