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 * cryptodev is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
14 * cryptodev 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, see <http://www.gnu.org/licenses/>.
24 * Device /dev/crypto provides an interface for
25 * accessing kernel CryptoAPI algorithms (ciphers,
26 * hashes) from userspace programs.
28 * /dev/crypto interface was originally introduced in
29 * OpenBSD and this module attempts to keep the API.
33 #include <linux/crypto.h>
35 #include <linux/highmem.h>
36 #include <linux/random.h>
37 #include "cryptodev.h"
38 #include <asm/uaccess.h>
39 #include <asm/ioctl.h>
40 #include <linux/scatterlist.h>
41 #include "cryptodev_int.h"
43 MODULE_AUTHOR("Nikos Mavrogiannopoulos <nmav@gnutls.org>");
44 MODULE_DESCRIPTION("CryptoDev driver");
45 MODULE_LICENSE("GPL");
47 /* ====== Compile-time config ====== */
49 #define CRYPTODEV_STATS
51 /* ====== Module parameters ====== */
53 int cryptodev_verbosity
= 0;
54 module_param(cryptodev_verbosity
, int, 0644);
55 MODULE_PARM_DESC(cryptodev_verbosity
, "0: normal, 1: verbose, 2: debug");
57 #ifdef CRYPTODEV_STATS
58 static int enable_stats
= 0;
59 module_param(enable_stats
, int, 0644);
60 MODULE_PARM_DESC(enable_stats
, "collect statictics about cryptodev usage");
63 /* ====== CryptoAPI ====== */
65 #define FILL_SG(sg,ptr,len) \
67 (sg)->page = virt_to_page(ptr); \
68 (sg)->offset = offset_in_page(ptr); \
70 (sg)->dma_address = 0; \
74 struct list_head entry
;
76 struct cipher_data cdata
;
77 struct hash_data hdata
;
79 #ifdef CRYPTODEV_STATS
80 #if ! ((COP_ENCRYPT < 2) && (COP_DECRYPT < 2))
81 #error Struct csession.stat uses COP_{ENCRYPT,DECRYPT} as indices. Do something!
83 unsigned long long stat
[2];
84 size_t stat_max_size
, stat_count
;
89 struct list_head list
;
93 /* Prepare session for future use. */
95 crypto_create_session(struct fcrypt
*fcr
, struct session_op
*sop
)
97 struct csession
*ses_new
= NULL
, *ses_ptr
;
99 const char *alg_name
=NULL
;
100 const char *hash_name
=NULL
;
103 /* Does the request make sense? */
104 if (unlikely(!sop
->cipher
&& !sop
->mac
)) {
105 dprintk(1,KERN_DEBUG
,"Both 'cipher' and 'mac' unset.\n");
109 switch (sop
->cipher
) {
113 alg_name
= "cbc(des)";
115 case CRYPTO_3DES_CBC
:
116 alg_name
= "cbc(des3_ede)";
119 alg_name
= "cbc(blowfish)";
122 alg_name
= "cbc(aes)";
124 case CRYPTO_CAMELLIA_CBC
:
125 alg_name
= "cbc(camelia)";
128 dprintk(1,KERN_DEBUG
,"%s: bad cipher: %d\n", __func__
, sop
->cipher
);
135 case CRYPTO_MD5_HMAC
:
136 hash_name
= "hmac(md5)";
138 case CRYPTO_RIPEMD160_HMAC
:
139 hash_name
= "hmac(rmd160)";
141 case CRYPTO_SHA1_HMAC
:
142 hash_name
= "hmac(sha1)";
144 case CRYPTO_SHA2_256_HMAC
:
145 hash_name
= "hmac(sha256)";
147 case CRYPTO_SHA2_384_HMAC
:
148 hash_name
= "hmac(sha384)";
150 case CRYPTO_SHA2_512_HMAC
:
151 hash_name
= "hmac(sha512)";
159 case CRYPTO_RIPEMD160
:
160 hash_name
= "rmd160";
167 case CRYPTO_SHA2_256
:
168 hash_name
= "sha256";
171 case CRYPTO_SHA2_384
:
172 hash_name
= "sha384";
175 case CRYPTO_SHA2_512
:
176 hash_name
= "sha512";
181 dprintk(1,KERN_DEBUG
,"%s: bad mac: %d\n", __func__
, sop
->mac
);
185 /* Create a session and put it to the list. */
186 ses_new
= kmalloc(sizeof(*ses_new
), GFP_KERNEL
);
191 memset(ses_new
, 0, sizeof(*ses_new
));
193 /* Set-up crypto transform. */
195 ret
= cryptodev_cipher_init(&ses_new
->cdata
, alg_name
, sop
->key
, sop
->keylen
);
197 dprintk(1,KERN_DEBUG
,"%s: Failed to load cipher for %s\n", __func__
,
205 ret
= cryptodev_hash_init(&ses_new
->hdata
, hash_name
, hmac_mode
, sop
->mackey
, sop
->mackeylen
);
207 dprintk(1,KERN_DEBUG
,"%s: Failed to load hash for %s\n", __func__
,
214 /* put the new session to the list */
215 get_random_bytes(&ses_new
->sid
, sizeof(ses_new
->sid
));
216 init_MUTEX(&ses_new
->sem
);
220 list_for_each_entry(ses_ptr
, &fcr
->list
, entry
) {
221 /* Check for duplicate SID */
222 if (unlikely(ses_new
->sid
== ses_ptr
->sid
)) {
223 get_random_bytes(&ses_new
->sid
, sizeof(ses_new
->sid
));
224 /* Unless we have a broken RNG this
225 shouldn't loop forever... ;-) */
230 list_add(&ses_new
->entry
, &fcr
->list
);
233 /* Fill in some values for the user. */
234 sop
->ses
= ses_new
->sid
;
239 cryptodev_cipher_deinit( &ses_new
->cdata
);
240 cryptodev_hash_deinit( &ses_new
->hdata
);
241 if (ses_new
) kfree(ses_new
);
247 /* Everything that needs to be done when remowing a session. */
249 crypto_destroy_session(struct csession
*ses_ptr
)
251 if(down_trylock(&ses_ptr
->sem
)) {
252 dprintk(2, KERN_DEBUG
, "Waiting for semaphore of sid=0x%08X\n",
256 dprintk(2, KERN_DEBUG
, "Removed session 0x%08X\n", ses_ptr
->sid
);
257 #if defined(CRYPTODEV_STATS)
259 dprintk(2, KERN_DEBUG
,
260 "Usage in Bytes: enc=%llu, dec=%llu, max=%zu, avg=%lu, cnt=%zu\n",
261 ses_ptr
->stat
[COP_ENCRYPT
], ses_ptr
->stat
[COP_DECRYPT
],
262 ses_ptr
->stat_max_size
, ses_ptr
->stat_count
> 0
263 ? ((unsigned long)(ses_ptr
->stat
[COP_ENCRYPT
]+
264 ses_ptr
->stat
[COP_DECRYPT
]) /
265 ses_ptr
->stat_count
) : 0,
266 ses_ptr
->stat_count
);
268 cryptodev_cipher_deinit(&ses_ptr
->cdata
);
269 cryptodev_hash_deinit(&ses_ptr
->hdata
);
274 /* Look up a session by ID and remove. */
276 crypto_finish_session(struct fcrypt
*fcr
, uint32_t sid
)
278 struct csession
*tmp
, *ses_ptr
;
279 struct list_head
*head
;
284 list_for_each_entry_safe(ses_ptr
, tmp
, head
, entry
) {
285 if(ses_ptr
->sid
== sid
) {
286 list_del(&ses_ptr
->entry
);
287 crypto_destroy_session(ses_ptr
);
292 if (unlikely(!ses_ptr
)) {
293 dprintk(1, KERN_ERR
, "Session with sid=0x%08X not found!\n", sid
);
301 /* Remove all sessions when closing the file */
303 crypto_finish_all_sessions(struct fcrypt
*fcr
)
305 struct csession
*tmp
, *ses_ptr
;
306 struct list_head
*head
;
311 list_for_each_entry_safe(ses_ptr
, tmp
, head
, entry
) {
312 list_del(&ses_ptr
->entry
);
313 crypto_destroy_session(ses_ptr
);
320 /* Look up session by session ID. The returned session is locked. */
321 static struct csession
*
322 crypto_get_session_by_sid(struct fcrypt
*fcr
, uint32_t sid
)
324 struct csession
*ses_ptr
;
327 list_for_each_entry(ses_ptr
, &fcr
->list
, entry
) {
328 if(ses_ptr
->sid
== sid
) {
338 /* This is the main crypto function - feed it with plaintext
339 and get a ciphertext (or vice versa :-) */
341 crypto_run(struct fcrypt
*fcr
, struct crypt_op
*cop
)
344 char __user
*src
, __user
*dst
;
345 struct scatterlist sg
;
346 struct csession
*ses_ptr
;
347 unsigned int ivsize
=0;
348 size_t nbytes
, bufsize
;
350 uint8_t hash_output
[AALG_MAX_RESULT_LEN
];
352 if (unlikely(cop
->op
!= COP_ENCRYPT
&& cop
->op
!= COP_DECRYPT
)) {
353 dprintk(1, KERN_DEBUG
, "invalid operation op=%u\n", cop
->op
);
357 ses_ptr
= crypto_get_session_by_sid(fcr
, cop
->ses
);
358 if (unlikely(!ses_ptr
)) {
359 dprintk(1, KERN_ERR
, "invalid session ID=0x%08X\n", cop
->ses
);
364 data
= (char*)__get_free_page(GFP_KERNEL
);
366 if (unlikely(!data
)) {
370 bufsize
= PAGE_SIZE
< nbytes
? PAGE_SIZE
: nbytes
;
374 if (ses_ptr
->hdata
.init
!= 0) {
375 ret
= cryptodev_hash_reset(&ses_ptr
->hdata
);
378 "error in cryptodev_hash_reset()\n");
383 if (ses_ptr
->cdata
.init
!= 0) {
384 int blocksize
= ses_ptr
->cdata
.blocksize
;
386 if (unlikely(nbytes
% blocksize
)) {
388 "data size (%zu) isn't a multiple of block size (%u)\n",
394 ivsize
= ses_ptr
->cdata
.ivsize
;
397 cryptodev_cipher_set_iv(&ses_ptr
->cdata
, cop
->iv
, ivsize
);
406 size_t current_len
= nbytes
> bufsize
? bufsize
: nbytes
;
408 copy_from_user(data
, src
, current_len
);
410 sg_init_one(&sg
, data
, current_len
);
412 /* Always hash before encryption and after decryption. Maybe
413 * we should introduce a flag to switch... TBD later on.
415 if (cop
->op
== COP_ENCRYPT
) {
416 if (ses_ptr
->hdata
.init
!= 0) {
417 ret
= cryptodev_hash_update(&ses_ptr
->hdata
, &sg
, current_len
);
419 dprintk(0, KERN_ERR
, "CryptoAPI failure: %d\n",ret
);
423 if (ses_ptr
->cdata
.init
!= 0) {
424 ret
= cryptodev_cipher_encrypt( &ses_ptr
->cdata
, &sg
, &sg
, current_len
);
427 dprintk(0, KERN_ERR
, "CryptoAPI failure: %d\n",ret
);
430 copy_to_user(dst
, data
, current_len
);
434 if (ses_ptr
->cdata
.init
!= 0) {
435 ret
= cryptodev_cipher_decrypt( &ses_ptr
->cdata
, &sg
, &sg
, current_len
);
438 dprintk(0, KERN_ERR
, "CryptoAPI failure: %d\n",ret
);
441 copy_to_user(dst
, data
, current_len
);
446 if (ses_ptr
->hdata
.init
!= 0) {
447 ret
= cryptodev_hash_update(&ses_ptr
->hdata
, &sg
, current_len
);
449 dprintk(0, KERN_ERR
, "CryptoAPI failure: %d\n",ret
);
455 nbytes
-= current_len
;
459 if (ses_ptr
->hdata
.init
!= 0) {
460 ret
= cryptodev_hash_final(&ses_ptr
->hdata
, hash_output
);
462 dprintk(0, KERN_ERR
, "CryptoAPI failure: %d\n",ret
);
466 copy_to_user(cop
->mac
, hash_output
, ses_ptr
->hdata
.digestsize
);
469 #if defined(CRYPTODEV_STATS)
471 /* this is safe - we check cop->op at the function entry */
472 ses_ptr
->stat
[cop
->op
] += cop
->len
;
473 if (ses_ptr
->stat_max_size
< cop
->len
)
474 ses_ptr
->stat_max_size
= cop
->len
;
475 ses_ptr
->stat_count
++;
480 free_page((unsigned long)data
);
488 /* ====== /dev/crypto ====== */
491 cryptodev_open(struct inode
*inode
, struct file
*filp
)
495 fcr
= kmalloc(sizeof(*fcr
), GFP_KERNEL
);
499 memset(fcr
, 0, sizeof(*fcr
));
500 init_MUTEX(&fcr
->sem
);
501 INIT_LIST_HEAD(&fcr
->list
);
502 filp
->private_data
= fcr
;
508 cryptodev_release(struct inode
*inode
, struct file
*filp
)
510 struct fcrypt
*fcr
= filp
->private_data
;
513 crypto_finish_all_sessions(fcr
);
515 filp
->private_data
= NULL
;
522 clonefd(struct file
*filp
)
524 struct fdtable
*fdt
= files_fdtable(current
->files
);
526 ret
= get_unused_fd();
529 FD_SET(ret
, fdt
->open_fds
);
530 fd_install(ret
, filp
);
537 cryptodev_ioctl(struct inode
*inode
, struct file
*filp
,
538 unsigned int cmd
, unsigned long arg
)
540 int __user
*p
= (void __user
*)arg
;
541 struct session_op sop
;
543 struct fcrypt
*fcr
= filp
->private_data
;
560 copy_from_user(&sop
, (void*)arg
, sizeof(sop
));
561 ret
= crypto_create_session(fcr
, &sop
);
564 copy_to_user((void*)arg
, &sop
, sizeof(sop
));
568 get_user(ses
, (uint32_t*)arg
);
569 ret
= crypto_finish_session(fcr
, ses
);
573 copy_from_user(&cop
, (void*)arg
, sizeof(cop
));
574 ret
= crypto_run(fcr
, &cop
);
577 copy_to_user((void*)arg
, &cop
, sizeof(cop
));
586 compat_to_session_op(struct compat_session_op
*compat
, struct session_op
*sop
)
588 memcpy(sop
, compat
, sizeof(uint32_t) * 3);
589 sop
->key
= (uint8_t *)(unsigned long)compat
->key
;
590 sop
->mackeylen
= compat
->mackeylen
;
591 sop
->mackey
= (uint8_t *)(unsigned long)compat
->mackey
;
592 sop
->ses
= compat
->ses
;
596 session_op_to_compat(struct session_op
*sop
, struct compat_session_op
*compat
)
598 memcpy(compat
, sop
, sizeof(uint32_t) * 3);
599 compat
->key
= (unsigned long)sop
->key
;
600 compat
->mackeylen
= sop
->mackeylen
;
601 compat
->mackey
= (unsigned long)sop
->mackey
;
602 compat
->ses
= sop
->ses
;
606 compat_to_crypt_op(struct compat_crypt_op
*compat
, struct crypt_op
*cop
)
608 memcpy(cop
, compat
, sizeof(uint32_t) * 2 + sizeof(uint16_t) * 2);
609 cop
->src
= (uint8_t *)(unsigned long)compat
->src
;
610 cop
->dst
= (uint8_t *)(unsigned long)compat
->dst
;
611 cop
->mac
= (uint8_t *)(unsigned long)compat
->mac
;
612 cop
->iv
= (uint8_t *)(unsigned long)compat
->iv
;
616 crypt_op_to_compat(struct crypt_op
*cop
, struct compat_crypt_op
*compat
)
618 memcpy(compat
, cop
, sizeof(uint32_t) * 2 + sizeof(uint16_t) * 2);
619 compat
->src
= (unsigned long)cop
->src
;
620 compat
->dst
= (unsigned long)cop
->dst
;
621 compat
->mac
= (unsigned long)cop
->mac
;
622 compat
->iv
= (unsigned long)cop
->iv
;
626 cryptodev_compat_ioctl(struct file
*file
, unsigned int cmd
, unsigned long arg
)
628 struct fcrypt
*fcr
= file
->private_data
;
629 struct session_op sop
;
630 struct compat_session_op compat_sop
;
632 struct compat_crypt_op compat_cop
;
642 return cryptodev_ioctl(NULL
, file
, cmd
, arg
);
644 case COMPAT_CIOCGSESSION
:
645 copy_from_user(&compat_sop
, (void *)arg
,
647 compat_to_session_op(&compat_sop
, &sop
);
649 ret
= crypto_create_session(fcr
, &sop
);
653 session_op_to_compat(&sop
, &compat_sop
);
654 copy_to_user((void*)arg
, &compat_sop
,
658 case COMPAT_CIOCCRYPT
:
659 copy_from_user(&compat_cop
, (void*)arg
,
661 compat_to_crypt_op(&compat_cop
, &cop
);
663 ret
= crypto_run(fcr
, &cop
);
667 crypt_op_to_compat(&cop
, &compat_cop
);
668 copy_to_user((void*)arg
, &compat_cop
,
677 struct file_operations cryptodev_fops
= {
678 .owner
= THIS_MODULE
,
679 .open
= cryptodev_open
,
680 .release
= cryptodev_release
,
681 .ioctl
= cryptodev_ioctl
,
682 .compat_ioctl
= cryptodev_compat_ioctl
,
685 struct miscdevice cryptodev
= {
686 .minor
= MISC_DYNAMIC_MINOR
,
688 .fops
= &cryptodev_fops
,
692 cryptodev_register(void)
696 rc
= misc_register (&cryptodev
);
698 printk(KERN_ERR PFX
"registeration of /dev/crypto failed\n");
706 cryptodev_deregister(void)
708 misc_deregister(&cryptodev
);
711 /* ====== Module init/exit ====== */
713 int __init
init_cryptodev(void)
717 rc
= cryptodev_register();
721 printk(KERN_INFO PFX
"driver loaded.\n");
726 void __exit
exit_cryptodev(void)
728 cryptodev_deregister();
729 printk(KERN_INFO PFX
"driver unloaded.\n");
732 module_init(init_cryptodev
);
733 module_exit(exit_cryptodev
);