misc: tegra-cryptodev: Fix error check for return value
[linux-2.6.git] / drivers / misc / tegra-cryptodev.c
1 /*
2  * drivers/misc/tegra-cryptodev.c
3  *
4  * crypto dev node for NVIDIA tegra aes hardware
5  *
6  * Copyright (c) 2010, NVIDIA Corporation.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  * more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21  */
22
23 #include <linux/module.h>
24 #include <linux/init.h>
25 #include <linux/errno.h>
26 #include <linux/kernel.h>
27 #include <linux/slab.h>
28 #include <linux/fs.h>
29 #include <linux/miscdevice.h>
30 #include <linux/crypto.h>
31 #include <linux/scatterlist.h>
32 #include <linux/uaccess.h>
33 #include <crypto/rng.h>
34 #include <crypto/hash.h>
35 #include <mach/hardware.h>
36
37 #include "tegra-cryptodev.h"
38
39 #define NBUFS 2
40 #define XBUFSIZE 8
41 #define RNG_DRBG 1
42 #define RNG 0
43
44 struct tegra_crypto_ctx {
45         struct crypto_ablkcipher *ecb_tfm;
46         struct crypto_ablkcipher *cbc_tfm;
47         struct crypto_ablkcipher *ofb_tfm;
48         struct crypto_ablkcipher *ctr_tfm;
49         struct crypto_ablkcipher *cmac_tfm;
50         struct crypto_rng *rng;
51         struct crypto_rng *rng_drbg;
52         u8 seed[TEGRA_CRYPTO_RNG_SEED_SIZE];
53         int use_ssk;
54 };
55
56 struct tegra_crypto_completion {
57         struct completion restart;
58         int req_err;
59 };
60
61 static int alloc_bufs(unsigned long *buf[NBUFS])
62 {
63         int i;
64
65         for (i = 0; i < NBUFS; i++) {
66                 buf[i] = (void *)__get_free_page(GFP_KERNEL);
67                 if (!buf[i])
68                         goto err_free_buf;
69         }
70
71         return 0;
72
73 err_free_buf:
74         while (i-- > 0)
75                 free_page((unsigned long)buf[i]);
76
77         return -ENOMEM;
78 }
79
80 static void free_bufs(unsigned long *buf[NBUFS])
81 {
82         int i;
83
84         for (i = 0; i < NBUFS; i++)
85                 free_page((unsigned long)buf[i]);
86 }
87
88 static int tegra_crypto_dev_open(struct inode *inode, struct file *filp)
89 {
90         struct tegra_crypto_ctx *ctx;
91         int ret = 0;
92
93         ctx = kzalloc(sizeof(struct tegra_crypto_ctx), GFP_KERNEL);
94         if (!ctx) {
95                 pr_err("no memory for context\n");
96                 return -ENOMEM;
97         }
98
99         ctx->ecb_tfm = crypto_alloc_ablkcipher("ecb-aes-tegra",
100                 CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 0);
101         if (IS_ERR(ctx->ecb_tfm)) {
102                 pr_err("Failed to load transform for ecb-aes-tegra: %ld\n",
103                         PTR_ERR(ctx->ecb_tfm));
104                 ret = PTR_ERR(ctx->ecb_tfm);
105                 goto fail_ecb;
106         }
107
108         ctx->cbc_tfm = crypto_alloc_ablkcipher("cbc-aes-tegra",
109                 CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 0);
110         if (IS_ERR(ctx->cbc_tfm)) {
111                 pr_err("Failed to load transform for cbc-aes-tegra: %ld\n",
112                         PTR_ERR(ctx->cbc_tfm));
113                 ret = PTR_ERR(ctx->cbc_tfm);
114                 goto fail_cbc;
115         }
116
117         if (tegra_get_chipid() != TEGRA_CHIPID_TEGRA2) {
118                 ctx->ofb_tfm = crypto_alloc_ablkcipher("ofb-aes-tegra",
119                         CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 0);
120                 if (IS_ERR(ctx->ofb_tfm)) {
121                         pr_err("Failed to load transform for ofb-aes-tegra: %ld\n",
122                                 PTR_ERR(ctx->ofb_tfm));
123                         ret = PTR_ERR(ctx->ofb_tfm);
124                         goto fail_ofb;
125                 }
126
127                 ctx->ctr_tfm = crypto_alloc_ablkcipher("ctr-aes-tegra",
128                         CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 0);
129                 if (IS_ERR(ctx->ctr_tfm)) {
130                         pr_err("Failed to load transform for ctr-aes-tegra: %ld\n",
131                                 PTR_ERR(ctx->ctr_tfm));
132                         ret = PTR_ERR(ctx->ctr_tfm);
133                         goto fail_ctr;
134                 }
135         }
136
137         if (tegra_get_chipid() == TEGRA_CHIPID_TEGRA11) {
138                 ctx->rng_drbg = crypto_alloc_rng("rng_drbg-aes-tegra",
139                         CRYPTO_ALG_TYPE_RNG, 0);
140                 if (IS_ERR(ctx->rng_drbg)) {
141                         pr_err("Failed to load transform for rng_drbg tegra: %ld\n",
142                                 PTR_ERR(ctx->rng_drbg));
143                         ret = PTR_ERR(ctx->rng_drbg);
144                         goto fail_rng;
145                 }
146         } else {
147                 ctx->rng = crypto_alloc_rng("rng-aes-tegra",
148                         CRYPTO_ALG_TYPE_RNG, 0);
149                 if (IS_ERR(ctx->rng)) {
150                         pr_err("Failed to load transform for tegra rng: %ld\n",
151                                 PTR_ERR(ctx->rng));
152                         ret = PTR_ERR(ctx->rng);
153                         goto fail_rng;
154                 }
155         }
156
157         filp->private_data = ctx;
158         return ret;
159
160 fail_rng:
161         if (tegra_get_chipid() != TEGRA_CHIPID_TEGRA2)
162                 crypto_free_ablkcipher(ctx->ctr_tfm);
163 fail_ctr:
164         if (tegra_get_chipid() != TEGRA_CHIPID_TEGRA2)
165                 crypto_free_ablkcipher(ctx->ofb_tfm);
166 fail_ofb:
167         crypto_free_ablkcipher(ctx->cbc_tfm);
168
169 fail_cbc:
170         crypto_free_ablkcipher(ctx->ecb_tfm);
171
172 fail_ecb:
173         kfree(ctx);
174         return ret;
175 }
176
177 static int tegra_crypto_dev_release(struct inode *inode, struct file *filp)
178 {
179         struct tegra_crypto_ctx *ctx = filp->private_data;
180
181         crypto_free_ablkcipher(ctx->ecb_tfm);
182         crypto_free_ablkcipher(ctx->cbc_tfm);
183
184         if (tegra_get_chipid() != TEGRA_CHIPID_TEGRA2) {
185                 crypto_free_ablkcipher(ctx->ofb_tfm);
186                 crypto_free_ablkcipher(ctx->ctr_tfm);
187         }
188
189         if (tegra_get_chipid() == TEGRA_CHIPID_TEGRA11)
190                 crypto_free_rng(ctx->rng_drbg);
191         else
192                 crypto_free_rng(ctx->rng);
193         kfree(ctx);
194         filp->private_data = NULL;
195         return 0;
196 }
197
198 static void tegra_crypt_complete(struct crypto_async_request *req, int err)
199 {
200         struct tegra_crypto_completion *done = req->data;
201
202         if (err != -EINPROGRESS) {
203                 done->req_err = err;
204                 complete(&done->restart);
205         }
206 }
207
208 static int process_crypt_req(struct tegra_crypto_ctx *ctx, struct tegra_crypt_req *crypt_req)
209 {
210         struct crypto_ablkcipher *tfm;
211         struct ablkcipher_request *req = NULL;
212         struct scatterlist in_sg;
213         struct scatterlist out_sg;
214         unsigned long *xbuf[NBUFS];
215         int ret = 0, size = 0;
216         unsigned long total = 0;
217         const u8 *key = NULL;
218         struct tegra_crypto_completion tcrypt_complete;
219
220         if (crypt_req->op & TEGRA_CRYPTO_ECB) {
221                 req = ablkcipher_request_alloc(ctx->ecb_tfm, GFP_KERNEL);
222                 tfm = ctx->ecb_tfm;
223         } else if (crypt_req->op & TEGRA_CRYPTO_CBC) {
224                 req = ablkcipher_request_alloc(ctx->cbc_tfm, GFP_KERNEL);
225                 tfm = ctx->cbc_tfm;
226         } else if ((crypt_req->op & TEGRA_CRYPTO_OFB) &&
227                         (tegra_get_chipid() != TEGRA_CHIPID_TEGRA2)) {
228
229                 req = ablkcipher_request_alloc(ctx->ofb_tfm, GFP_KERNEL);
230                 tfm = ctx->ofb_tfm;
231         } else if ((crypt_req->op & TEGRA_CRYPTO_CTR) &&
232                         (tegra_get_chipid() != TEGRA_CHIPID_TEGRA2)) {
233
234                 req = ablkcipher_request_alloc(ctx->ctr_tfm, GFP_KERNEL);
235                 tfm = ctx->ctr_tfm;
236         }
237
238         if (!req) {
239                 pr_err("%s: Failed to allocate request\n", __func__);
240                 return -ENOMEM;
241         }
242
243         if ((crypt_req->keylen < 0) || (crypt_req->keylen > AES_MAX_KEY_SIZE)) {
244                 ret = -EINVAL;
245                 pr_err("crypt_req keylen invalid");
246                 goto process_req_out;
247         }
248
249         crypto_ablkcipher_clear_flags(tfm, ~0);
250
251         if (!ctx->use_ssk)
252                 key = crypt_req->key;
253
254         ret = crypto_ablkcipher_setkey(tfm, key, crypt_req->keylen);
255         if (ret < 0) {
256                 pr_err("setkey failed");
257                 goto process_req_out;
258         }
259
260         ret = alloc_bufs(xbuf);
261         if (ret < 0) {
262                 pr_err("alloc_bufs failed");
263                 goto process_req_out;
264         }
265
266         init_completion(&tcrypt_complete.restart);
267
268         ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
269                 tegra_crypt_complete, &tcrypt_complete);
270
271         total = crypt_req->plaintext_sz;
272         while (total > 0) {
273                 size = min(total, PAGE_SIZE);
274                 ret = copy_from_user((void *)xbuf[0],
275                         (void __user *)crypt_req->plaintext, size);
276                 if (ret) {
277                         ret = -EFAULT;
278                         pr_debug("%s: copy_from_user failed (%d)\n", __func__, ret);
279                         goto process_req_buf_out;
280                 }
281                 sg_init_one(&in_sg, xbuf[0], size);
282                 sg_init_one(&out_sg, xbuf[1], size);
283
284                 ablkcipher_request_set_crypt(req, &in_sg,
285                         &out_sg, size, crypt_req->iv);
286
287                 INIT_COMPLETION(tcrypt_complete.restart);
288                 tcrypt_complete.req_err = 0;
289                 ret = crypt_req->encrypt ?
290                         crypto_ablkcipher_encrypt(req) :
291                         crypto_ablkcipher_decrypt(req);
292
293                 if ((ret == -EINPROGRESS) || (ret == -EBUSY)) {
294                         /* crypto driver is asynchronous */
295                         ret = wait_for_completion_interruptible(&tcrypt_complete.restart);
296
297                         if (ret < 0)
298                                 goto process_req_buf_out;
299
300                         if (tcrypt_complete.req_err < 0) {
301                                 ret = tcrypt_complete.req_err;
302                                 goto process_req_buf_out;
303                         }
304                 } else if (ret < 0) {
305                         pr_debug("%scrypt failed (%d)\n",
306                                 crypt_req->encrypt ? "en" : "de", ret);
307                         goto process_req_buf_out;
308                 }
309
310                 ret = copy_to_user((void __user *)crypt_req->result,
311                         (const void *)xbuf[1], size);
312                 if (ret) {
313                         ret = -EFAULT;
314                         pr_debug("%s: copy_to_user failed (%d)\n", __func__,
315                                         ret);
316                         goto process_req_buf_out;
317                 }
318
319                 total -= size;
320                 crypt_req->result += size;
321                 crypt_req->plaintext += size;
322         }
323
324 process_req_buf_out:
325         free_bufs(xbuf);
326 process_req_out:
327         ablkcipher_request_free(req);
328
329         return ret;
330 }
331
332 static int sha_async_hash_op(struct ahash_request *req,
333                                 struct tegra_crypto_completion *tr,
334                                 int ret)
335 {
336         if (ret == -EINPROGRESS || ret == -EBUSY) {
337                 ret = wait_for_completion_interruptible(&tr->restart);
338                 if (!ret)
339                         ret = tr->req_err;
340                 INIT_COMPLETION(tr->restart);
341         }
342         return ret;
343 }
344
345 static int tegra_crypt_rsa(struct tegra_rsa_req *rsa_req)
346 {
347         struct crypto_ahash *tfm;
348         struct ahash_request *req;
349         struct scatterlist sg[1];
350         char *result = NULL;
351         void *hash_buff;
352         int ret = 0;
353         unsigned long *xbuf[XBUFSIZE];
354         struct tegra_crypto_completion rsa_complete;
355
356         tfm = crypto_alloc_ahash(rsa_req->algo, 0, 0);
357         if (IS_ERR(tfm)) {
358                 printk(KERN_ERR "alg: hash: Failed to load transform for %s: %ld\n",
359                         rsa_req->algo, PTR_ERR(tfm));
360                 goto alloc_fail;
361         }
362
363         req = ahash_request_alloc(tfm, GFP_KERNEL);
364         if (!req) {
365                 printk(KERN_ERR "alg: hash: Failed to allocate request for %s\n",
366                         rsa_req->algo);
367                 goto req_fail;
368         }
369
370         ret = alloc_bufs(xbuf);
371          if (ret < 0) {
372                 pr_err("alloc_bufs failed");
373                 goto buf_fail;
374         }
375
376         init_completion(&rsa_complete.restart);
377
378         result = kzalloc(rsa_req->keylen >> 16, GFP_KERNEL);
379         if (!result) {
380                 pr_err("\nresult alloc fail\n");
381                 goto result_fail;
382         }
383
384         hash_buff = xbuf[0];
385
386         memcpy(hash_buff, rsa_req->message, rsa_req->msg_len);
387
388         sg_init_one(&sg[0], hash_buff, rsa_req->msg_len);
389
390         if (!(rsa_req->keylen))
391                 goto rsa_fail;
392
393         ret = crypto_ahash_setkey(tfm, rsa_req->key, rsa_req->keylen);
394
395         if (ret) {
396                 printk(KERN_ERR "alg: hash: setkey failed on: %s\n",
397                         rsa_req->algo);
398                 goto rsa_fail;
399         }
400
401         ahash_request_set_crypt(req, sg, result, rsa_req->msg_len);
402
403         ret = crypto_ahash_digest(req);
404
405         if (ret == -EINPROGRESS || ret == -EBUSY) {
406                 ret = wait_for_completion_interruptible(&rsa_complete.restart);
407                 if (!ret)
408                         ret = rsa_complete.req_err;
409                 INIT_COMPLETION(rsa_complete.restart);
410         }
411
412         if (ret) {
413                 pr_err("alg: hash: digest failed for %s\n", rsa_req->algo);
414                 goto rsa_fail;
415         }
416
417         ret = copy_to_user((void __user *)rsa_req->result, (const void *)result,
418                 crypto_ahash_digestsize(tfm));
419         if (ret) {
420                 ret = -EFAULT;
421                 pr_err("alg: hash: copy_to_user failed (%d) for %s\n",
422                                 ret, rsa_req->algo);
423         }
424
425 rsa_fail:
426         kfree(result);
427 result_fail:
428         free_bufs(xbuf);
429 buf_fail:
430         ahash_request_free(req);
431 req_fail:
432         crypto_free_ahash(tfm);
433 alloc_fail:
434         return ret;
435 }
436
437 static int tegra_crypto_sha(struct tegra_sha_req *sha_req)
438 {
439
440         struct crypto_ahash *tfm;
441         struct scatterlist sg[1];
442         char result[64];
443         struct ahash_request *req;
444         struct tegra_crypto_completion sha_complete;
445         void *hash_buff;
446         unsigned long *xbuf[XBUFSIZE];
447         int ret = -ENOMEM;
448
449         tfm = crypto_alloc_ahash(sha_req->algo, 0, 0);
450         if (IS_ERR(tfm)) {
451                 printk(KERN_ERR "alg: hash: Failed to load transform for %s: "
452                        "%ld\n", sha_req->algo, PTR_ERR(tfm));
453                 goto out_alloc;
454         }
455
456         req = ahash_request_alloc(tfm, GFP_KERNEL);
457         if (!req) {
458                 printk(KERN_ERR "alg: hash: Failed to allocate request for "
459                        "%s\n", sha_req->algo);
460                 goto out_noreq;
461         }
462
463         ret = alloc_bufs(xbuf);
464         if (ret < 0) {
465                 pr_err("alloc_bufs failed");
466                 goto out_buf;
467         }
468
469         init_completion(&sha_complete.restart);
470
471         memset(result, 0, 64);
472
473         hash_buff = xbuf[0];
474
475         memcpy(hash_buff, sha_req->plaintext, sha_req->plaintext_sz);
476         sg_init_one(&sg[0], hash_buff, sha_req->plaintext_sz);
477
478         if (sha_req->keylen) {
479                 crypto_ahash_clear_flags(tfm, ~0);
480                 ret = crypto_ahash_setkey(tfm, sha_req->key,
481                                           sha_req->keylen);
482                 if (ret) {
483                         printk(KERN_ERR "alg: hash: setkey failed on "
484                                " %s: ret=%d\n", sha_req->algo,
485                                -ret);
486                         goto out;
487                 }
488         }
489
490         ahash_request_set_crypt(req, sg, result, sha_req->plaintext_sz);
491
492         ret = sha_async_hash_op(req, &sha_complete, crypto_ahash_init(req));
493         if (ret) {
494                 pr_err("alg: hash: init failed on "
495                        "for %s: ret=%d\n", sha_req->algo, -ret);
496                 goto out;
497         }
498
499         ret = sha_async_hash_op(req, &sha_complete, crypto_ahash_update(req));
500         if (ret) {
501                 pr_err("alg: hash: update failed on "
502                        "for %s: ret=%d\n", sha_req->algo, -ret);
503                 goto out;
504         }
505
506         ret = sha_async_hash_op(req, &sha_complete, crypto_ahash_final(req));
507         if (ret) {
508                 pr_err("alg: hash: final failed on "
509                        "for %s: ret=%d\n", sha_req->algo, -ret);
510                 goto out;
511         }
512
513         ret = copy_to_user((void __user *)sha_req->result,
514                 (const void *)result, crypto_ahash_digestsize(tfm));
515         if (ret) {
516                 ret = -EFAULT;
517                 pr_err("alg: hash: copy_to_user failed (%d) for %s\n",
518                                 ret, sha_req->algo);
519         }
520
521 out:
522         free_bufs(xbuf);
523
524 out_buf:
525         ahash_request_free(req);
526
527 out_noreq:
528         crypto_free_ahash(tfm);
529
530 out_alloc:
531         return ret;
532 }
533
534 static long tegra_crypto_dev_ioctl(struct file *filp,
535         unsigned int ioctl_num, unsigned long arg)
536 {
537         struct tegra_crypto_ctx *ctx = filp->private_data;
538         struct tegra_crypt_req crypt_req;
539         struct tegra_rng_req rng_req;
540         struct tegra_sha_req sha_req;
541         struct tegra_rsa_req rsa_req;
542         char *rng;
543         int ret = 0;
544
545         switch (ioctl_num) {
546
547         case TEGRA_CRYPTO_IOCTL_NEED_SSK:
548                 ctx->use_ssk = (int)arg;
549                 break;
550
551         case TEGRA_CRYPTO_IOCTL_PROCESS_REQ:
552                 ret = copy_from_user(&crypt_req, (void __user *)arg,
553                         sizeof(crypt_req));
554                 if (ret) {
555                         ret = -EFAULT;
556                         pr_err("%s: copy_from_user fail(%d)\n", __func__, ret);
557                         break;
558                 }
559
560                 ret = process_crypt_req(ctx, &crypt_req);
561                 break;
562
563         case TEGRA_CRYPTO_IOCTL_SET_SEED:
564                 if (copy_from_user(&rng_req, (void __user *)arg,
565                         sizeof(rng_req))) {
566                         ret = -EFAULT;
567                         pr_err("%s: copy_from_user fail(%d)\n", __func__, ret);
568                         return ret;
569                 }
570
571                 memcpy(ctx->seed, rng_req.seed, TEGRA_CRYPTO_RNG_SEED_SIZE);
572
573                 if (rng_req.type == RNG_DRBG)
574                         ret = crypto_rng_reset(ctx->rng_drbg, ctx->seed,
575                                 crypto_rng_seedsize(ctx->rng_drbg));
576                 else
577                         ret = crypto_rng_reset(ctx->rng, ctx->seed,
578                                 crypto_rng_seedsize(ctx->rng));
579                 break;
580
581         case TEGRA_CRYPTO_IOCTL_GET_RANDOM:
582                 if (copy_from_user(&rng_req, (void __user *)arg,
583                         sizeof(rng_req))) {
584                         ret = -EFAULT;
585                         pr_err("%s: copy_from_user fail(%d)\n", __func__, ret);
586                         return ret;
587                 }
588
589                 rng = kzalloc(rng_req.nbytes, GFP_KERNEL);
590                 if (!rng) {
591                         if (rng_req.type == RNG_DRBG)
592                                 pr_err("mem alloc for rng_drbg fail");
593                         else
594                                 pr_err("mem alloc for rng fail");
595
596                         ret = -ENODATA;
597                         goto rng_out;
598                 }
599
600                 if (rng_req.type == RNG_DRBG)
601                         ret = crypto_rng_get_bytes(ctx->rng_drbg, rng,
602                                 rng_req.nbytes);
603                 else
604                         ret = crypto_rng_get_bytes(ctx->rng, rng,
605                                 rng_req.nbytes);
606
607                 if (ret != rng_req.nbytes) {
608                         if (rng_req.type == RNG_DRBG)
609                                 pr_err("rng_drbg failed");
610                         else
611                                 pr_err("rng failed");
612                         ret = -ENODATA;
613                         goto rng_out;
614                 }
615
616                 ret = copy_to_user((void __user *)rng_req.rdata,
617                         (const void *)rng, rng_req.nbytes);
618                 if (ret) {
619                         ret = -EFAULT;
620                         pr_err("%s: copy_to_user fail(%d)\n", __func__, ret);
621                         return ret;
622                 }
623
624 rng_out:
625                 if (rng)
626                         kfree(rng);
627                 break;
628
629         case TEGRA_CRYPTO_IOCTL_GET_SHA:
630                 if (tegra_get_chipid() != TEGRA_CHIPID_TEGRA2) {
631                         if (copy_from_user(&sha_req, (void __user *)arg,
632                                 sizeof(sha_req))) {
633                                 ret = -EFAULT;
634                                 pr_err("%s: copy_from_user fail(%d)\n",
635                                                 __func__, ret);
636                                 return ret;
637                         }
638
639                         ret = tegra_crypto_sha(&sha_req);
640                 } else {
641                         ret = -EINVAL;
642                 }
643                 break;
644
645         case TEGRA_CRYPTO_IOCTL_RSA_REQ:
646                 if (copy_from_user(&rsa_req, (void __user *)arg,
647                         sizeof(rsa_req))) {
648                         ret = -EFAULT;
649                         pr_err("%s: copy_from_user fail(%d)\n", __func__, ret);
650                         return ret;
651                 }
652
653                 ret = tegra_crypt_rsa(&rsa_req);
654                 break;
655
656         default:
657                 pr_debug("invalid ioctl code(%d)", ioctl_num);
658                 ret = -EINVAL;
659         }
660
661         return ret;
662 }
663
664 const struct file_operations tegra_crypto_fops = {
665         .owner = THIS_MODULE,
666         .open = tegra_crypto_dev_open,
667         .release = tegra_crypto_dev_release,
668         .unlocked_ioctl = tegra_crypto_dev_ioctl,
669 };
670
671 struct miscdevice tegra_crypto_device = {
672         .minor = MISC_DYNAMIC_MINOR,
673         .name = "tegra-crypto",
674         .fops = &tegra_crypto_fops,
675 };
676
677 static int __init tegra_crypto_dev_init(void)
678 {
679         return misc_register(&tegra_crypto_device);
680 }
681
682 late_initcall(tegra_crypto_dev_init);
683
684 MODULE_DESCRIPTION("Tegra AES hw device node.");
685 MODULE_AUTHOR("NVIDIA Corporation");
686 MODULE_LICENSE("GPLv2");