Thread: [Ocf-linux-users] question about a custom HW crypto driver
Brought to you by:
david-m
From: Amir T. <ami...@pe...> - 2009-08-04 22:30:11
|
Hello, I finished writing a Linux device driver for a custom crypto accelerator and after testing it am now in the process of adapting it to work with OCF Linux. I would greatly appreciate some pointers on some problems I encountered. 1. The driver uses DMA to fetch the input and then write the output after the crypto operation has completed. In my test version I put the call to sleep on a wait queue which then gets woken up by the DMA done ISR. I tried a similar approach with my OCF version but get scheduling panic messages from the kernel. What is the proper way to suspend the call until the DMA transfer has completed? 2. As a temporary hack until I figure out #1 I am currently polling to see when the operation has completed. Using openssl (with an OCF patch) I ran the following commands: openssl aes-128-cbc -a -salt -in test.txt -out test.txt.enc -pass pass:amir123 openssl aes-128-cbc -d -a -in test.txt.enc -out test.txt.dec -k amir123 where test.txt is: This is a test 123456789 line 1 This is a test 123456789 line 2 This is a test 123456789 line 3 …. This is a test 123456789 line 18 This is a test 123456789 line 19 This is a test 123456789 line 20 I get the following error: bad decrypt 1023:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:461: And the contents of the resulting test.txt.dec are: &£f64˜ uyVֳue23456789 line 1 This is a test 123456789 line 2 This is a test 123456789 line 3 ... This is a test 123456789 line 18 This is a test 123456789 line 19 This is a test 123456 So for some reason I am getting garbage in the beginning of the decrypted message and missing other data at the end of it? Thanks Amir |
From: David M. <Dav...@se...> - 2009-08-05 14:06:41
|
Jivin Amir Tsvitov lays it down ... > Hello, > > I finished writing a Linux device driver for a custom crypto accelerator > and after testing it am now in the process of adapting it to work with > OCF Linux. > > I would greatly appreciate some pointers on some problems I encountered. > > 1. The driver uses DMA to fetch the input and then write the output > after the crypto operation has completed. In my test version I put the call > to sleep on a wait queue which then gets woken up by the DMA done ISR. > I tried a similar approach with my OCF version but get scheduling panic > messages from the kernel. What is the proper way to suspend the call > until the DMA transfer has completed? You don't :-) Both the safei, hifn7751 and talitos drivers use DMA in much the same way. They are reasonable drivers to use as an example. Here is the basic idea for your driver: mydriver_process(..) ... set up DMA fetch to send data to HW signal chip to do it ... return OK mydriver_interrupt() ... request is complete do callback with status You don't need to wait anywhere as OCF is asynchronous, you just have your interrupt routine call back one the crypto processing is complete. Now a real drover will be much more complex and involved, but if you look at the other drivers you should be able to get the idea, > 2. As a temporary hack until I figure out #1 I am currently polling > to see when the operation has completed. Using openssl (with an OCF patch) > I ran the following commands: > > openssl aes-128-cbc -a -salt -in test.txt -out test.txt.enc -pass pass:amir123 > > openssl aes-128-cbc -d -a -in test.txt.enc -out test.txt.dec -k amir123 > > where test.txt is: > > This is a test 123456789 line 1 > > This is a test 123456789 line 2 > > This is a test 123456789 line 3 > > …. > > This is a test 123456789 line 18 > > This is a test 123456789 line 19 > > This is a test 123456789 line 20 > > > > I get the following error: > > bad decrypt > > 1023:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:461: > > > > And the contents of the resulting test.txt.dec are: > > &£f64˜ uyVֳue23456789 line 1 > > This is a test 123456789 line 2 > > This is a test 123456789 line 3 > > ... > > This is a test 123456789 line 18 > > This is a test 123456789 line 19 > > This is a test 123456 > > > > So for some reason I am getting garbage in the beginning of the > decrypted message and missing other data at the end of it? Hard to say really, use cryptotest to debug, it is much easier to follow than the SSL code, Cheers, Davidm -- David McCullough, dav...@se..., Ph:+61 734352815 McAfee - SnapGear http://www.snapgear.com http://www.uCdot.org |
From: Amir T. <ami...@pe...> - 2009-08-09 13:01:48
|
Hello David, .... > > Here is the basic idea for your driver: > > mydriver_process(..) > ... > set up DMA fetch to send data to HW > signal chip to do it > ... > return OK > > mydriver_interrupt() > ... > request is complete > do callback with status > > You don't need to wait anywhere as OCF is asynchronous, you just have > your > interrupt routine call back one the crypto processing is complete. > > Now a real drover will be much more complex and involved, but if you > look > at the other drivers you should be able to get the idea, > [>>] I looked at the reference drivers and think I got the basic idea. The only thing I'm not 100% sure about is the concept of a session. How does it fit in with the template you provide above? > > 2. As a temporary hack until I figure out #1 I am currently > polling > > to see when the operation has completed. Using openssl (with an OCF > patch) ..... > Hard to say really, use cryptotest to debug, it is much easier to > follow > than the SSL code, > [>>] I used cryptotest and quickly resolved the matter! Thanks it really is a much easier way to debug. According to the test results even with the inefficient way I've hooked the driver I still get 2 to 3 times better performance with the driver loaded then without it. [>>] I'm rewriting my driver to correctly hook into the OCF framework. However, I still would like to understand what my current implementation actually does in terms of its interaction with the OCF layer. The current driver: Registers an initialized crypto_alg by calling crypto_register_alg The relevant parts of the struct are: .cra_name = "cbc(aes)", .cra_driver_name = "cbc-aes-hw-driver", .cra_priority = 300, .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, In the blkcipher.encrpyt function I registered I more or less do (left out many details for clarity) blkcipher_walk_init(&walk, dst, src, nbytes); ret = blkcipher_walk_virt(desc, &walk); while ((nbytes = walk.nbytes)) { unsigned int n = nbytes & ~(AES_BLOCK_SIZE - 1); unsigned char *out = walk.dst.virt.addr; unsigned char *in = walk.src.virt.addr; in_dma = dma_map_single(NULL,(void*)in,n,DMA_TO_DEVICE); out_dma = dma_map_single(NULL,(void*)out,n,DMA_FROM_DEVICE); ret = hw_crypto_op(op,in_dma,out_dma,n); // POLLS on end of DMA interrupt before returning. if((ret < 0) || (ret != n)) goto cbc_aes_encrypt_out; dma_unmap_single(NULL,in_dma,n,DMA_TO_DEVICE); dma_unmap_single(NULL,out_dma,n,DMA_FROM_DEVICE); nbytes &= AES_BLOCK_SIZE - 1; ret = blkcipher_walk_done(desc, &walk, nbytes); } Is my driver just being called synchronously versus asynchronously? Is all this determined by calling crypto_register_alg versus crypto_register? Thanks a lot for taking the time to help me. Amir |
From: Amir T. <ami...@pe...> - 2009-09-08 10:45:00
Attachments:
proc_crypro.txt
|
Hello David, Thanks for your previous help and pointers. I modified my driver to register as a async block cipher. However, now it seems my driver functions are not getting called at all when I run cryptotest, even though it seems that the driver is registered correctly. I've included the relevant init code snippet and the output of /proc/crypto. Thanks, Amir Tsvitov Init code: ... static struct crypto_alg cbc_aes_alg = { .cra_name = "cbc(aes)", .cra_driver_name = "hw-cbc-aes-async", .cra_priority = 300, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct hw_aes_ctx), .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, .cra_init = cbc_aes_init, .cra_ablkcipher = { .setkey = cbc_aes_set_key, .encrypt = cbc_aes_encrypt, .decrypt = cbc_aes_decrypt, }, .cra_u = { .ablkcipher = { .min_keysize = AES_MIN_KEY_SIZE, .max_keysize = AES_MAX_KEY_SIZE, .ivsize = AES_BLOCK_SIZE, } } }; ... crypto_register_alg(&cbc_aes_alg); > -----Original Message----- > From: David McCullough [mailto:Dav...@se...] > Sent: Wednesday, August 05, 2009 4:51 PM > To: Amir Tsvitov > Cc: ocf...@li... > Subject: Re: [Ocf-linux-users] question about a custom HW crypto driver > > > Jivin Amir Tsvitov lays it down ... > > Hello, > > > > I finished writing a Linux device driver for a custom crypto > accelerator > > and after testing it am now in the process of adapting it to work > with > > OCF Linux. > > > > I would greatly appreciate some pointers on some problems I > encountered. > > > > 1. The driver uses DMA to fetch the input and then write the > output > > after the crypto operation has completed. In my test version I put > the call > > to sleep on a wait queue which then gets woken up by the DMA done > ISR. > > I tried a similar approach with my OCF version but get scheduling > panic > > messages from the kernel. What is the proper way to suspend the call > > until the DMA transfer has completed? > > You don't :-) > > Both the safei, hifn7751 and talitos drivers use DMA in much the same > way. > They are reasonable drivers to use as an example. > > Here is the basic idea for your driver: > > mydriver_process(..) > ... > set up DMA fetch to send data to HW > signal chip to do it > ... > return OK > > mydriver_interrupt() > ... > request is complete > do callback with status > > You don't need to wait anywhere as OCF is asynchronous, you just have > your > interrupt routine call back one the crypto processing is complete. > > Now a real drover will be much more complex and involved, but if you > look > at the other drivers you should be able to get the idea, > > > 2. As a temporary hack until I figure out #1 I am currently > polling > > to see when the operation has completed. Using openssl (with an OCF > patch) > > I ran the following commands: > > > > openssl aes-128-cbc -a -salt -in test.txt -out test.txt.enc -pass > pass:amir123 > > > > openssl aes-128-cbc -d -a -in test.txt.enc -out test.txt.dec -k > amir123 > > > > where test.txt is: > > > > This is a test 123456789 line 1 > > > > This is a test 123456789 line 2 > > > > This is a test 123456789 line 3 > > > > …. > > > > This is a test 123456789 line 18 > > > > This is a test 123456789 line 19 > > > > This is a test 123456789 line 20 > > > > > > > > I get the following error: > > > > bad decrypt > > > > 1023:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad > decrypt:evp_enc.c:461: > > > > > > > > And the contents of the resulting test.txt.dec are: > > > > &£f64˜ uyVֳue23456789 line 1 > > > > This is a test 123456789 line 2 > > > > This is a test 123456789 line 3 > > > > ... > > > > This is a test 123456789 line 18 > > > > This is a test 123456789 line 19 > > > > This is a test 123456 > > > > > > > > So for some reason I am getting garbage in the beginning of the > > decrypted message and missing other data at the end of it? > > Hard to say really, use cryptotest to debug, it is much easier to > follow > than the SSL code, > > Cheers, > Davidm > > -- > David McCullough, dav...@se..., Ph:+61 > 734352815 > McAfee - SnapGear http://www.snapgear.com > http://www.uCdot.org |
From: David M. <Dav...@se...> - 2009-09-08 23:18:56
|
Jivin Amir Tsvitov lays it down ... > Hello David, > > Thanks for your previous help and pointers. I modified my driver to register as a async block cipher. However, now it seems my driver functions are not getting called at all when I run cryptotest, even though it seems that the driver is registered correctly. > I've included the relevant init code snippet and the output of /proc/crypto. You have written a linux-native crypto driver. To interface to that using cryptotest you will need to have ocf+cryptosoft+cryptodev loaded. I am not sure how cryptosoft goes talking to async native drivers at the moment. Someone posted (here I think) that they got it to work but they needed to mod the code a little when looking for supported kernel algs. Cheers, Davidm > Init code: > ... > static struct crypto_alg cbc_aes_alg = { > .cra_name = "cbc(aes)", > .cra_driver_name = "hw-cbc-aes-async", > .cra_priority = 300, > .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, > .cra_blocksize = AES_BLOCK_SIZE, > .cra_ctxsize = sizeof(struct hw_aes_ctx), > .cra_type = &crypto_ablkcipher_type, > .cra_module = THIS_MODULE, > .cra_init = cbc_aes_init, > .cra_ablkcipher = { > .setkey = cbc_aes_set_key, > .encrypt = cbc_aes_encrypt, > .decrypt = cbc_aes_decrypt, > }, > .cra_u = { > .ablkcipher = { > .min_keysize = AES_MIN_KEY_SIZE, > .max_keysize = AES_MAX_KEY_SIZE, > .ivsize = AES_BLOCK_SIZE, > } > } > }; > ... > crypto_register_alg(&cbc_aes_alg); > > > > -----Original Message----- > > From: David McCullough [mailto:Dav...@se...] > > Sent: Wednesday, August 05, 2009 4:51 PM > > To: Amir Tsvitov > > Cc: ocf...@li... > > Subject: Re: [Ocf-linux-users] question about a custom HW crypto driver > > > > > > Jivin Amir Tsvitov lays it down ... > > > Hello, > > > > > > I finished writing a Linux device driver for a custom crypto > > accelerator > > > and after testing it am now in the process of adapting it to work > > with > > > OCF Linux. > > > > > > I would greatly appreciate some pointers on some problems I > > encountered. > > > > > > 1. The driver uses DMA to fetch the input and then write the > > output > > > after the crypto operation has completed. In my test version I put > > the call > > > to sleep on a wait queue which then gets woken up by the DMA done > > ISR. > > > I tried a similar approach with my OCF version but get scheduling > > panic > > > messages from the kernel. What is the proper way to suspend the call > > > until the DMA transfer has completed? > > > > You don't :-) > > > > Both the safei, hifn7751 and talitos drivers use DMA in much the same > > way. > > They are reasonable drivers to use as an example. > > > > Here is the basic idea for your driver: > > > > mydriver_process(..) > > ... > > set up DMA fetch to send data to HW > > signal chip to do it > > ... > > return OK > > > > mydriver_interrupt() > > ... > > request is complete > > do callback with status > > > > You don't need to wait anywhere as OCF is asynchronous, you just have > > your > > interrupt routine call back one the crypto processing is complete. > > > > Now a real drover will be much more complex and involved, but if you > > look > > at the other drivers you should be able to get the idea, > > > > > 2. As a temporary hack until I figure out #1 I am currently > > polling > > > to see when the operation has completed. Using openssl (with an OCF > > patch) > > > I ran the following commands: > > > > > > openssl aes-128-cbc -a -salt -in test.txt -out test.txt.enc -pass > > pass:amir123 > > > > > > openssl aes-128-cbc -d -a -in test.txt.enc -out test.txt.dec -k > > amir123 > > > > > > where test.txt is: > > > > > > This is a test 123456789 line 1 > > > > > > This is a test 123456789 line 2 > > > > > > This is a test 123456789 line 3 > > > > > > ??. > > > > > > This is a test 123456789 line 18 > > > > > > This is a test 123456789 line 19 > > > > > > This is a test 123456789 line 20 > > > > > > > > > > > > I get the following error: > > > > > > bad decrypt > > > > > > 1023:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad > > decrypt:evp_enc.c:461: > > > > > > > > > > > > And the contents of the resulting test.txt.dec are: > > > > > > &??f6?4?? uy?V?u?e23456789 line 1 > > > > > > This is a test 123456789 line 2 > > > > > > This is a test 123456789 line 3 > > > > > > ... > > > > > > This is a test 123456789 line 18 > > > > > > This is a test 123456789 line 19 > > > > > > This is a test 123456 > > > > > > > > > > > > So for some reason I am getting garbage in the beginning of the > > > decrypted message and missing other data at the end of it? > > > > Hard to say really, use cryptotest to debug, it is much easier to > > follow > > than the SSL code, > > > > Cheers, > > Davidm > > > > -- > > David McCullough, dav...@se..., Ph:+61 > > 734352815 > > McAfee - SnapGear http://www.snapgear.com > > http://www.uCdot.org > > name : cbc(aes) > driver : hw-cbc-aes-async > module : hw_AES > priority : 300 > refcnt : 1 > selftest : passed > type : blkcipher > blocksize : 16 > min keysize : 16 > max keysize : 32 > ivsize : 16 > geniv : <default> > > name : cbc(aes) > driver : cbc(aes-generic) > module : kernel > priority : 100 > refcnt : 1 > selftest : passed > type : blkcipher > blocksize : 16 > min keysize : 16 > max keysize : 32 > ivsize : 16 > geniv : <default> > > name : hmac(sha1) > driver : hmac(sha1-generic) > module : kernel > priority : 0 > refcnt : 2 > selftest : passed > type : hash > blocksize : 64 > digestsize : 20 > > name : cbc(des3_ede) > driver : cbc(des3_ede-generic) > module : kernel > priority : 0 > refcnt : 2 > selftest : passed > type : blkcipher > blocksize : 8 > min keysize : 24 > max keysize : 24 > ivsize : 8 > geniv : <default> > > name : cbc(des) > driver : cbc(des-generic) > module : kernel > priority : 0 > refcnt : 1 > selftest : passed > type : blkcipher > blocksize : 8 > min keysize : 8 > max keysize : 8 > ivsize : 8 > geniv : <default> > > name : stdrng > driver : ansi_cprng > module : kernel > priority : 100 > refcnt : 1 > selftest : passed > type : rng > seedsize : 32 > > name : stdrng > driver : krng > module : kernel > priority : 200 > refcnt : 1 > selftest : passed > type : rng > seedsize : 0 > > name : aes > driver : aes-generic > module : kernel > priority : 100 > refcnt : 1 > selftest : passed > type : cipher > blocksize : 16 > min keysize : 16 > max keysize : 32 > > name : des3_ede > driver : des3_ede-generic > module : kernel > priority : 0 > refcnt : 2 > selftest : passed > type : cipher > blocksize : 8 > min keysize : 24 > max keysize : 24 > > name : des > driver : des-generic > module : kernel > priority : 0 > refcnt : 1 > selftest : passed > type : cipher > blocksize : 8 > min keysize : 8 > max keysize : 8 > > name : sha1 > driver : sha1-generic > module : kernel > priority : 0 > refcnt : 2 > selftest : passed > type : digest > blocksize : 64 > digestsize : 20 > -- David McCullough, dav...@se..., Ph:+61 734352815 McAfee - SnapGear http://www.snapgear.com http://www.uCdot.org |