2 * Driver for /dev/crypto device (aka CryptoDev)
4 * Copyright (c) 2004 Michal Ludvig <mludvig@logix.net.nz>, SuSE Labs
5 * Copyright (c) 2009,2010 Nikos Mavrogiannopoulos <nmav@gnutls.org>
7 * This file is part of linux cryptodev.
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26 * Device /dev/crypto provides an interface for
27 * accessing kernel CryptoAPI algorithms (ciphers,
28 * hashes) from userspace programs.
30 * /dev/crypto interface was originally introduced in
31 * OpenBSD and this module attempts to keep the API.
35 #include <linux/crypto.h>
37 #include <linux/highmem.h>
38 #include <linux/ioctl.h>
39 #include <linux/random.h>
40 #include <linux/syscalls.h>
41 #include <linux/pagemap.h>
42 #include <linux/uaccess.h>
43 #include "cryptodev.h"
44 #include <linux/scatterlist.h>
45 #include "cryptodev_int.h"
48 MODULE_AUTHOR("Nikos Mavrogiannopoulos <nmav@gnutls.org>");
49 MODULE_DESCRIPTION("CryptoDev driver");
50 MODULE_LICENSE("GPL");
52 /* ====== Compile-time config ====== */
54 #define CRYPTODEV_STATS
56 /* ====== Module parameters ====== */
58 int cryptodev_verbosity
;
59 module_param(cryptodev_verbosity
, int, 0644);
60 MODULE_PARM_DESC(cryptodev_verbosity
, "0: normal, 1: verbose, 2: debug");
62 #ifdef CRYPTODEV_STATS
63 static int enable_stats
;
64 module_param(enable_stats
, int, 0644);
65 MODULE_PARM_DESC(enable_stats
, "collect statictics about cryptodev usage");
68 /* ====== CryptoAPI ====== */
70 struct list_head list
;
78 #define FILL_SG(sg, ptr, len) \
80 (sg)->page = virt_to_page(ptr); \
81 (sg)->offset = offset_in_page(ptr); \
83 (sg)->dma_address = 0; \
87 struct list_head entry
;
89 struct cipher_data cdata
;
90 struct hash_data hdata
;
92 #ifdef CRYPTODEV_STATS
93 #if !((COP_ENCRYPT < 2) && (COP_DECRYPT < 2))
94 #error Struct csession.stat uses COP_{ENCRYPT,DECRYPT} as indices. Do something!
96 unsigned long long stat
[2];
97 size_t stat_max_size
, stat_count
;
101 struct scatterlist
*sg
;
104 /* Prepare session for future use. */
106 crypto_create_session(struct fcrypt
*fcr
, struct session_op
*sop
)
108 struct csession
*ses_new
= NULL
, *ses_ptr
;
110 const char *alg_name
= NULL
;
111 const char *hash_name
= NULL
;
114 /* Does the request make sense? */
115 if (unlikely(!sop
->cipher
&& !sop
->mac
)) {
116 dprintk(1, KERN_DEBUG
, "Both 'cipher' and 'mac' unset.\n");
120 switch (sop
->cipher
) {
124 alg_name
= "cbc(des)";
126 case CRYPTO_3DES_CBC
:
127 alg_name
= "cbc(des3_ede)";
130 alg_name
= "cbc(blowfish)";
133 alg_name
= "cbc(aes)";
135 case CRYPTO_CAMELLIA_CBC
:
136 alg_name
= "cbc(camelia)";
139 alg_name
= "ctr(aes)";
142 alg_name
= "ecb(cipher_null)";
145 dprintk(1, KERN_DEBUG
, "%s: bad cipher: %d\n", __func__
,
153 case CRYPTO_MD5_HMAC
:
154 hash_name
= "hmac(md5)";
156 case CRYPTO_RIPEMD160_HMAC
:
157 hash_name
= "hmac(rmd160)";
159 case CRYPTO_SHA1_HMAC
:
160 hash_name
= "hmac(sha1)";
162 case CRYPTO_SHA2_256_HMAC
:
163 hash_name
= "hmac(sha256)";
165 case CRYPTO_SHA2_384_HMAC
:
166 hash_name
= "hmac(sha384)";
168 case CRYPTO_SHA2_512_HMAC
:
169 hash_name
= "hmac(sha512)";
177 case CRYPTO_RIPEMD160
:
178 hash_name
= "rmd160";
185 case CRYPTO_SHA2_256
:
186 hash_name
= "sha256";
189 case CRYPTO_SHA2_384
:
190 hash_name
= "sha384";
193 case CRYPTO_SHA2_512
:
194 hash_name
= "sha512";
199 dprintk(1, KERN_DEBUG
, "%s: bad mac: %d\n", __func__
,
204 /* Create a session and put it to the list. */
205 ses_new
= kzalloc(sizeof(*ses_new
), GFP_KERNEL
);
209 /* Set-up crypto transform. */
211 uint8_t keyp
[CRYPTO_CIPHER_MAX_KEY_LEN
];
213 if (unlikely(sop
->keylen
> CRYPTO_CIPHER_MAX_KEY_LEN
)) {
214 dprintk(1, KERN_DEBUG
,
215 "Setting key failed for %s-%zu.\n",
216 alg_name
, (size_t)sop
->keylen
*8);
221 if (unlikely(copy_from_user(keyp
, sop
->key
, sop
->keylen
))) {
226 ret
= cryptodev_cipher_init(&ses_new
->cdata
, alg_name
, keyp
,
229 dprintk(1, KERN_DEBUG
,
230 "%s: Failed to load cipher for %s\n",
238 uint8_t keyp
[CRYPTO_HMAC_MAX_KEY_LEN
];
240 if (unlikely(sop
->mackeylen
> CRYPTO_HMAC_MAX_KEY_LEN
)) {
241 dprintk(1, KERN_DEBUG
,
242 "Setting key failed for %s-%zu.\n",
243 alg_name
, (size_t)sop
->mackeylen
*8);
248 if (unlikely(copy_from_user(keyp
, sop
->mackey
,
254 ret
= cryptodev_hash_init(&ses_new
->hdata
, hash_name
, hmac_mode
,
255 keyp
, sop
->mackeylen
);
257 dprintk(1, KERN_DEBUG
,
258 "%s: Failed to load hash for %s\n",
259 __func__
, hash_name
);
265 ses_new
->array_size
= DEFAULT_PREALLOC_PAGES
;
266 dprintk(2, KERN_DEBUG
, "%s: preallocating for %d user pages\n",
267 __func__
, ses_new
->array_size
);
268 ses_new
->pages
= kzalloc(ses_new
->array_size
*
269 sizeof(struct page
*), GFP_KERNEL
);
270 ses_new
->sg
= kzalloc(ses_new
->array_size
*
271 sizeof(struct scatterlist
), GFP_KERNEL
);
272 if (ses_new
->sg
== NULL
|| ses_new
->pages
== NULL
) {
273 dprintk(0, KERN_DEBUG
, "Memory error\n");
278 /* put the new session to the list */
279 get_random_bytes(&ses_new
->sid
, sizeof(ses_new
->sid
));
280 mutex_init(&ses_new
->sem
);
282 mutex_lock(&fcr
->sem
);
284 list_for_each_entry(ses_ptr
, &fcr
->list
, entry
) {
285 /* Check for duplicate SID */
286 if (unlikely(ses_new
->sid
== ses_ptr
->sid
)) {
287 get_random_bytes(&ses_new
->sid
, sizeof(ses_new
->sid
));
288 /* Unless we have a broken RNG this
289 shouldn't loop forever... ;-) */
294 list_add(&ses_new
->entry
, &fcr
->list
);
295 mutex_unlock(&fcr
->sem
);
297 /* Fill in some values for the user. */
298 sop
->ses
= ses_new
->sid
;
303 cryptodev_cipher_deinit(&ses_new
->cdata
);
305 kfree(ses_new
->pages
);
313 /* Everything that needs to be done when remowing a session. */
315 crypto_destroy_session(struct csession
*ses_ptr
)
317 if (!mutex_trylock(&ses_ptr
->sem
)) {
318 dprintk(2, KERN_DEBUG
, "Waiting for semaphore of sid=0x%08X\n",
320 mutex_lock(&ses_ptr
->sem
);
322 dprintk(2, KERN_DEBUG
, "Removed session 0x%08X\n", ses_ptr
->sid
);
323 #if defined(CRYPTODEV_STATS)
325 dprintk(2, KERN_DEBUG
,
326 "Usage in Bytes: enc=%llu, dec=%llu, \
327 max=%zu, avg=%lu, cnt=%zu\n",
328 ses_ptr
->stat
[COP_ENCRYPT
], ses_ptr
->stat
[COP_DECRYPT
],
329 ses_ptr
->stat_max_size
, ses_ptr
->stat_count
> 0
330 ? ((unsigned long)(ses_ptr
->stat
[COP_ENCRYPT
]+
331 ses_ptr
->stat
[COP_DECRYPT
]) /
332 ses_ptr
->stat_count
) : 0,
333 ses_ptr
->stat_count
);
335 cryptodev_cipher_deinit(&ses_ptr
->cdata
);
336 cryptodev_hash_deinit(&ses_ptr
->hdata
);
337 dprintk(2, KERN_DEBUG
, "%s: freeing space for %d user pages\n",
338 __func__
, ses_ptr
->array_size
);
339 kfree(ses_ptr
->pages
);
341 mutex_unlock(&ses_ptr
->sem
);
345 /* Look up a session by ID and remove. */
347 crypto_finish_session(struct fcrypt
*fcr
, uint32_t sid
)
349 struct csession
*tmp
, *ses_ptr
;
350 struct list_head
*head
;
353 mutex_lock(&fcr
->sem
);
355 list_for_each_entry_safe(ses_ptr
, tmp
, head
, entry
) {
356 if (ses_ptr
->sid
== sid
) {
357 list_del(&ses_ptr
->entry
);
358 crypto_destroy_session(ses_ptr
);
363 if (unlikely(!ses_ptr
)) {
364 dprintk(1, KERN_ERR
, "Session with sid=0x%08X not found!\n",
368 mutex_unlock(&fcr
->sem
);
373 /* Remove all sessions when closing the file */
375 crypto_finish_all_sessions(struct fcrypt
*fcr
)
377 struct csession
*tmp
, *ses_ptr
;
378 struct list_head
*head
;
380 mutex_lock(&fcr
->sem
);
383 list_for_each_entry_safe(ses_ptr
, tmp
, head
, entry
) {
384 list_del(&ses_ptr
->entry
);
385 crypto_destroy_session(ses_ptr
);
387 mutex_unlock(&fcr
->sem
);
392 /* Look up session by session ID. The returned session is locked. */
393 static struct csession
*
394 crypto_get_session_by_sid(struct fcrypt
*fcr
, uint32_t sid
)
396 struct csession
*ses_ptr
;
398 mutex_lock(&fcr
->sem
);
399 list_for_each_entry(ses_ptr
, &fcr
->list
, entry
) {
400 if (ses_ptr
->sid
== sid
) {
401 mutex_lock(&ses_ptr
->sem
);
405 mutex_unlock(&fcr
->sem
);
411 hash_n_crypt(struct csession
*ses_ptr
, struct crypt_op
*cop
,
412 struct scatterlist
*src_sg
, struct scatterlist
*dst_sg
,
417 /* Always hash before encryption and after decryption. Maybe
418 * we should introduce a flag to switch... TBD later on.
420 if (cop
->op
== COP_ENCRYPT
) {
421 if (ses_ptr
->hdata
.init
!= 0) {
422 ret
= cryptodev_hash_update(&ses_ptr
->hdata
,
427 if (ses_ptr
->cdata
.init
!= 0) {
428 ret
= cryptodev_cipher_encrypt(&ses_ptr
->cdata
,
429 src_sg
, dst_sg
, len
);
435 if (ses_ptr
->cdata
.init
!= 0) {
436 ret
= cryptodev_cipher_decrypt(&ses_ptr
->cdata
,
437 src_sg
, dst_sg
, len
);
443 if (ses_ptr
->hdata
.init
!= 0) {
444 ret
= cryptodev_hash_update(&ses_ptr
->hdata
,
452 dprintk(0, KERN_ERR
, "CryptoAPI failure: %d\n", ret
);
457 /* This is the main crypto function - feed it with plaintext
458 and get a ciphertext (or vice versa :-) */
460 __crypto_run_std(struct csession
*ses_ptr
, struct crypt_op
*cop
)
463 char __user
*src
, *dst
;
464 struct scatterlist sg
;
465 size_t nbytes
, bufsize
;
469 data
= (char *)__get_free_page(GFP_KERNEL
);
474 bufsize
= PAGE_SIZE
< nbytes
? PAGE_SIZE
: nbytes
;
480 size_t current_len
= nbytes
> bufsize
? bufsize
: nbytes
;
482 if (unlikely(copy_from_user(data
, src
, current_len
))) {
487 sg_init_one(&sg
, data
, current_len
);
489 ret
= hash_n_crypt(ses_ptr
, cop
, &sg
, &sg
, current_len
);
494 if (ses_ptr
->cdata
.init
!= 0) {
495 if (unlikely(copy_to_user(dst
, data
, current_len
))) {
502 nbytes
-= current_len
;
506 free_page((unsigned long)data
);
510 void release_user_pages(struct page
**pg
, int pagecount
)
512 while (pagecount
--) {
513 if (!PageReserved(pg
[pagecount
]))
514 SetPageDirty(pg
[pagecount
]);
515 page_cache_release(pg
[pagecount
]);
519 /* offset of buf in it's first page */
520 #define PAGEOFFSET(buf) ((unsigned long)buf & ~PAGE_MASK)
522 /* fetch the pages addr resides in into pg and initialise sg with them */
523 int __get_userbuf(uint8_t __user
*addr
, uint32_t len
, int write
,
524 int pgcount
, struct page
**pg
, struct scatterlist
*sg
)
526 int ret
, pglen
, i
= 0;
527 struct scatterlist
*sgp
;
529 down_write(¤t
->mm
->mmap_sem
);
530 ret
= get_user_pages(current
, current
->mm
,
531 (unsigned long)addr
, pgcount
, write
, 0, pg
, NULL
);
532 up_write(¤t
->mm
->mmap_sem
);
536 sg_init_table(sg
, pgcount
);
538 pglen
= min((ptrdiff_t)(PAGE_SIZE
- PAGEOFFSET(addr
)), (ptrdiff_t)len
);
539 sg_set_page(sg
, pg
[i
++], pglen
, PAGEOFFSET(addr
));
542 for (sgp
= sg_next(sg
); len
; sgp
= sg_next(sgp
)) {
543 pglen
= min((uint32_t)PAGE_SIZE
, len
);
544 sg_set_page(sgp
, pg
[i
++], pglen
, 0);
547 sg_mark_end(sg_last(sg
, pgcount
));
551 /* make cop->src and cop->dst available in scatterlists */
552 static int get_userbuf(struct csession
*ses
, struct kernel_crypt_op
*kcop
,
553 struct scatterlist
**src_sg
, struct scatterlist
**dst_sg
,
556 int src_pagecount
, dst_pagecount
= 0, pagecount
, write_src
= 1;
557 struct crypt_op
*cop
= &kcop
->cop
;
559 if (cop
->src
== NULL
)
562 src_pagecount
= PAGECOUNT(cop
->src
, cop
->len
);
563 if (!ses
->cdata
.init
) { /* hashing only */
565 } else if (cop
->src
!= cop
->dst
) { /* non-in-situ transformation */
566 if (cop
->dst
== NULL
)
569 dst_pagecount
= PAGECOUNT(cop
->dst
, cop
->len
);
572 (*tot_pages
) = pagecount
= src_pagecount
+ dst_pagecount
;
574 if (pagecount
> ses
->array_size
) {
575 struct scatterlist
*sg
;
579 for (array_size
= ses
->array_size
; array_size
< pagecount
;
583 dprintk(2, KERN_DEBUG
, "%s: reallocating to %d elements\n",
584 __func__
, array_size
);
585 pages
= krealloc(ses
->pages
, array_size
* sizeof(struct page
*),
587 if (unlikely(!pages
))
590 sg
= krealloc(ses
->sg
, array_size
* sizeof(struct scatterlist
),
595 ses
->array_size
= array_size
;
598 if (__get_userbuf(cop
->src
, cop
->len
, write_src
,
599 src_pagecount
, ses
->pages
, ses
->sg
)) {
601 "failed to get user pages for data input\n");
604 (*src_sg
) = (*dst_sg
) = ses
->sg
;
607 (*dst_sg
) = ses
->sg
+ src_pagecount
;
609 if (__get_userbuf(cop
->dst
, cop
->len
, 1, dst_pagecount
,
610 ses
->pages
+ src_pagecount
, *dst_sg
)) {
612 "failed to get user pages for data output\n");
613 release_user_pages(ses
->pages
, src_pagecount
);
620 /* This is the main crypto function - zero-copy edition */
622 __crypto_run_zc(struct csession
*ses_ptr
, struct kernel_crypt_op
*kcop
)
624 struct scatterlist
*src_sg
, *dst_sg
;
625 struct crypt_op
*cop
= &kcop
->cop
;
626 int ret
= 0, pagecount
;
628 ret
= get_userbuf(ses_ptr
, kcop
, &src_sg
, &dst_sg
, &pagecount
);
630 dprintk(1, KERN_ERR
, "Error getting user pages. \
631 Falling back to non zero copy.\n");
632 return __crypto_run_std(ses_ptr
, cop
);
635 ret
= hash_n_crypt(ses_ptr
, cop
, src_sg
, dst_sg
, cop
->len
);
637 release_user_pages(ses_ptr
->pages
, pagecount
);
641 static int crypto_run(struct fcrypt
*fcr
, struct kernel_crypt_op
*kcop
)
643 struct csession
*ses_ptr
;
644 struct crypt_op
*cop
= &kcop
->cop
;
647 if (unlikely(cop
->op
!= COP_ENCRYPT
&& cop
->op
!= COP_DECRYPT
)) {
648 dprintk(1, KERN_DEBUG
, "invalid operation op=%u\n", cop
->op
);
652 /* this also enters ses_ptr->sem */
653 ses_ptr
= crypto_get_session_by_sid(fcr
, cop
->ses
);
654 if (unlikely(!ses_ptr
)) {
655 dprintk(1, KERN_ERR
, "invalid session ID=0x%08X\n", cop
->ses
);
659 if (ses_ptr
->hdata
.init
!= 0 && !(cop
->flags
& COP_FLAG_UPDATE
) &&
660 !(cop
->flags
& COP_FLAG_FINAL
)) {
661 ret
= cryptodev_hash_reset(&ses_ptr
->hdata
);
664 "error in cryptodev_hash_reset()\n");
669 if (ses_ptr
->cdata
.init
!= 0) {
670 int blocksize
= ses_ptr
->cdata
.blocksize
;
672 if (unlikely(cop
->len
% blocksize
)) {
674 "data size (%u) isn't a multiple \
675 of block size (%u)\n",
676 cop
->len
, blocksize
);
681 cryptodev_cipher_set_iv(&ses_ptr
->cdata
, kcop
->iv
,
682 min(ses_ptr
->cdata
.ivsize
, kcop
->ivlen
));
686 ret
= __crypto_run_zc(ses_ptr
, kcop
);
691 if (ses_ptr
->hdata
.init
!= 0 &&
692 ((cop
->flags
& COP_FLAG_FINAL
) ||
693 (!(cop
->flags
& COP_FLAG_UPDATE
) || cop
->len
== 0))) {
695 ret
= cryptodev_hash_final(&ses_ptr
->hdata
, kcop
->hash_output
);
697 dprintk(0, KERN_ERR
, "CryptoAPI failure: %d\n", ret
);
702 #if defined(CRYPTODEV_STATS)
704 /* this is safe - we check cop->op at the function entry */
705 ses_ptr
->stat
[cop
->op
] += cop
->len
;
706 if (ses_ptr
->stat_max_size
< cop
->len
)
707 ses_ptr
->stat_max_size
= cop
->len
;
708 ses_ptr
->stat_count
++;
713 mutex_unlock(&ses_ptr
->sem
);
717 /* ====== /dev/crypto ====== */
720 cryptodev_open(struct inode
*inode
, struct file
*filp
)
722 struct crypt_priv
*pcr
;
724 pcr
= kmalloc(sizeof(*pcr
), GFP_KERNEL
);
728 memset(pcr
, 0, sizeof(*pcr
));
729 mutex_init(&pcr
->fcrypt
.sem
);
730 INIT_LIST_HEAD(&pcr
->fcrypt
.list
);
732 filp
->private_data
= pcr
;
737 cryptodev_release(struct inode
*inode
, struct file
*filp
)
739 struct crypt_priv
*pcr
= filp
->private_data
;
742 crypto_finish_all_sessions(&pcr
->fcrypt
);
744 filp
->private_data
= NULL
;
751 clonefd(struct file
*filp
)
754 ret
= get_unused_fd();
757 fd_install(ret
, filp
);
763 /* this function has to be called from process context */
764 static int fill_kcop_from_cop(struct kernel_crypt_op
*kcop
, struct fcrypt
*fcr
)
766 struct crypt_op
*cop
= &kcop
->cop
;
767 struct csession
*ses_ptr
;
770 /* this also enters ses_ptr->sem */
771 ses_ptr
= crypto_get_session_by_sid(fcr
, cop
->ses
);
772 if (unlikely(!ses_ptr
)) {
773 dprintk(1, KERN_ERR
, "invalid session ID=0x%08X\n", cop
->ses
);
776 kcop
->ivlen
= cop
->iv
? ses_ptr
->cdata
.ivsize
: 0;
777 kcop
->digestsize
= ses_ptr
->hdata
.digestsize
;
778 mutex_unlock(&ses_ptr
->sem
);
780 if (unlikely(rc
= copy_from_user(kcop
->iv
, cop
->iv
, kcop
->ivlen
))) {
782 "error copying IV (%d bytes), copy_from_user returned %d for address %lx\n",
783 kcop
->ivlen
, rc
, (unsigned long)cop
->iv
);
790 static int kcop_from_user(struct kernel_crypt_op
*kcop
,
791 struct fcrypt
*fcr
, void __user
*arg
)
793 if (unlikely(copy_from_user(&kcop
->cop
, arg
, sizeof(kcop
->cop
))))
796 return fill_kcop_from_cop(kcop
, fcr
);
800 cryptodev_ioctl(struct file
*filp
, unsigned int cmd
, unsigned long arg_
)
802 void __user
*arg
= (void __user
*)arg_
;
804 struct session_op sop
;
805 struct kernel_crypt_op kcop
;
806 struct crypt_priv
*pcr
= filp
->private_data
;
818 return put_user(0, p
);
821 ret
= put_user(fd
, p
);
828 if (unlikely(copy_from_user(&sop
, arg
, sizeof(sop
))))
831 ret
= crypto_create_session(fcr
, &sop
);
834 ret
= copy_to_user(arg
, &sop
, sizeof(sop
));
836 crypto_finish_session(fcr
, sop
.ses
);
841 ret
= get_user(ses
, (uint32_t __user
*)arg
);
844 ret
= crypto_finish_session(fcr
, ses
);
847 if (unlikely(ret
= kcop_from_user(&kcop
, fcr
, arg
)))
850 ret
= crypto_run(fcr
, &kcop
);
853 ret
= copy_to_user(kcop
.cop
.mac
, kcop
.hash_output
, kcop
.digestsize
);
856 if (unlikely(copy_to_user(arg
, &kcop
.cop
, sizeof(kcop
.cop
))))
865 /* compatibility code for 32bit userlands */
869 compat_to_session_op(struct compat_session_op
*compat
, struct session_op
*sop
)
871 sop
->cipher
= compat
->cipher
;
872 sop
->mac
= compat
->mac
;
873 sop
->keylen
= compat
->keylen
;
875 sop
->key
= compat_ptr(compat
->key
);
876 sop
->mackeylen
= compat
->mackeylen
;
877 sop
->mackey
= compat_ptr(compat
->mackey
);
878 sop
->ses
= compat
->ses
;
882 session_op_to_compat(struct session_op
*sop
, struct compat_session_op
*compat
)
884 compat
->cipher
= sop
->cipher
;
885 compat
->mac
= sop
->mac
;
886 compat
->keylen
= sop
->keylen
;
888 compat
->key
= ptr_to_compat(sop
->key
);
889 compat
->mackeylen
= sop
->mackeylen
;
890 compat
->mackey
= ptr_to_compat(sop
->mackey
);
891 compat
->ses
= sop
->ses
;
895 compat_to_crypt_op(struct compat_crypt_op
*compat
, struct crypt_op
*cop
)
897 cop
->ses
= compat
->ses
;
898 cop
->op
= compat
->op
;
899 cop
->flags
= compat
->flags
;
900 cop
->len
= compat
->len
;
902 cop
->src
= compat_ptr(compat
->src
);
903 cop
->dst
= compat_ptr(compat
->dst
);
904 cop
->mac
= compat_ptr(compat
->mac
);
905 cop
->iv
= compat_ptr(compat
->iv
);
909 crypt_op_to_compat(struct crypt_op
*cop
, struct compat_crypt_op
*compat
)
911 compat
->ses
= cop
->ses
;
912 compat
->op
= cop
->op
;
913 compat
->flags
= cop
->flags
;
914 compat
->len
= cop
->len
;
916 compat
->src
= ptr_to_compat(cop
->src
);
917 compat
->dst
= ptr_to_compat(cop
->dst
);
918 compat
->mac
= ptr_to_compat(cop
->mac
);
919 compat
->iv
= ptr_to_compat(cop
->iv
);
922 static int compat_kcop_from_user(struct kernel_crypt_op
*kcop
,
923 struct fcrypt
*fcr
, void __user
*arg
)
925 struct compat_crypt_op compat_cop
;
927 if (unlikely(copy_from_user(&compat_cop
, arg
, sizeof(compat_cop
))))
929 compat_to_crypt_op(&compat_cop
, &kcop
->cop
);
931 return fill_kcop_from_cop(kcop
, fcr
);
935 cryptodev_compat_ioctl(struct file
*file
, unsigned int cmd
, unsigned long arg_
)
937 void __user
*arg
= (void __user
*)arg_
;
938 struct fcrypt
*fcr
= file
->private_data
;
939 struct session_op sop
;
940 struct compat_session_op compat_sop
;
941 struct kernel_crypt_op kcop
;
942 struct compat_crypt_op compat_cop
;
952 return cryptodev_ioctl(file
, cmd
, arg_
);
954 case COMPAT_CIOCGSESSION
:
955 if (unlikely(copy_from_user(&compat_sop
, arg
,
956 sizeof(compat_sop
))))
958 compat_to_session_op(&compat_sop
, &sop
);
960 ret
= crypto_create_session(fcr
, &sop
);
964 session_op_to_compat(&sop
, &compat_sop
);
965 ret
= copy_to_user(arg
, &compat_sop
, sizeof(compat_sop
));
967 crypto_finish_session(fcr
, sop
.ses
);
972 case COMPAT_CIOCCRYPT
:
973 ret
= compat_kcop_from_user(&kcop
, fcr
, arg
);
977 ret
= crypto_run(fcr
, &kcop
);
981 ret
= copy_to_user(kcop
.cop
.mac
,
982 kcop
.hash_output
, kcop
.digestsize
);
986 crypt_op_to_compat(&kcop
.cop
, &compat_cop
);
987 if (unlikely(copy_to_user(arg
, &compat_cop
,
988 sizeof(compat_cop
))))
997 #endif /* CONFIG_COMPAT */
999 static const struct file_operations cryptodev_fops
= {
1000 .owner
= THIS_MODULE
,
1001 .open
= cryptodev_open
,
1002 .release
= cryptodev_release
,
1003 .unlocked_ioctl
= cryptodev_ioctl
,
1004 #ifdef CONFIG_COMPAT
1005 .compat_ioctl
= cryptodev_compat_ioctl
,
1006 #endif /* CONFIG_COMPAT */
1009 static struct miscdevice cryptodev
= {
1010 .minor
= MISC_DYNAMIC_MINOR
,
1012 .fops
= &cryptodev_fops
,
1016 cryptodev_register(void)
1020 rc
= misc_register(&cryptodev
);
1022 printk(KERN_ERR PFX
"registration of /dev/crypto failed\n");
1030 cryptodev_deregister(void)
1032 misc_deregister(&cryptodev
);
1035 /* ====== Module init/exit ====== */
1036 static int __init
init_cryptodev(void)
1040 rc
= cryptodev_register();
1044 printk(KERN_INFO PFX
"driver %s loaded.\n", VERSION
);
1049 static void __exit
exit_cryptodev(void)
1051 cryptodev_deregister();
1052 printk(KERN_INFO PFX
"driver unloaded.\n");
1055 module_init(init_cryptodev
);
1056 module_exit(exit_cryptodev
);