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