2
* An OCF module that uses Intels IXP CryptACC API to do the crypto.
3
* This driver requires the IXP400 Access Library that is available
4
* from Intel in order to operate (or compile).
6
* Written by David McCullough <david_mccullough@securecomputing.com>
7
* Copyright (C) 2006-2007 David McCullough
8
* Copyright (C) 2004-2005 Intel Corporation.
12
* The free distribution and use of this software in both source and binary
13
* form is allowed (with or without changes) provided that:
15
* 1. distributions of this source code include the above copyright
16
* notice, this list of conditions and the following disclaimer;
18
* 2. distributions in binary form include the above copyright
19
* notice, this list of conditions and the following disclaimer
20
* in the documentation and/or other associated materials;
22
* 3. the copyright holder's name is not used to endorse products
23
* built using this software without specific written permission.
25
* ALTERNATIVELY, provided that this notice is retained in full, this product
26
* may be distributed under the terms of the GNU General Public License (GPL),
27
* in which case the provisions of the GPL apply INSTEAD OF those given above.
31
* This software is provided 'as is' with no explicit or implied warranties
32
* in respect of its properties, including, but not limited to, correctness
33
* and/or fitness for purpose.
36
#ifndef AUTOCONF_INCLUDED
37
#include <linux/config.h>
39
#include <linux/module.h>
40
#include <linux/init.h>
41
#include <linux/list.h>
42
#include <linux/slab.h>
43
#include <linux/sched.h>
44
#include <linux/wait.h>
45
#include <linux/crypto.h>
46
#include <linux/interrupt.h>
47
#include <asm/scatterlist.h>
50
#include <IxOsBuffMgt.h>
52
#include <IxCryptoAcc.h>
54
#include <IxOsServices.h>
55
#include <IxOsCacheMMU.h>
57
#include <cryptodev.h>
61
#define IX_MBUF_PRIV(x) ((x)->priv)
67
struct list_head ixp_q_list;
68
struct ixp_data *ixp_q_data;
69
struct cryptop *ixp_q_crp;
70
struct cryptodesc *ixp_q_ccrd;
71
struct cryptodesc *ixp_q_acrd;
73
UINT8 *ixp_hash_dest; /* Location for hash in client buffer */
74
UINT8 *ixp_hash_src; /* Location of hash in internal buffer */
75
unsigned char ixp_q_iv_data[IX_CRYPTO_ACC_MAX_CIPHER_IV_LENGTH];
76
unsigned char *ixp_q_iv;
80
int ixp_registered; /* is the context registered */
81
int ixp_crd_flags; /* detect direction changes */
87
UINT32 ixp_hash_key_id; /* used when hashing */
88
IxCryptoAccCtx ixp_ctx;
92
struct work_struct ixp_pending_work;
93
struct work_struct ixp_registration_work;
94
struct list_head ixp_q; /* unprocessed requests */
99
#define MAX_IOP_SIZE 64 /* words */
100
#define MAX_OOP_SIZE 128
105
struct list_head pkq_list;
106
struct cryptkop *pkq_krp;
108
IxCryptoAccPkeEauInOperands pkq_op;
109
IxCryptoAccPkeEauOpResult pkq_result;
111
UINT32 pkq_ibuf0[MAX_IOP_SIZE];
112
UINT32 pkq_ibuf1[MAX_IOP_SIZE];
113
UINT32 pkq_ibuf2[MAX_IOP_SIZE];
114
UINT32 pkq_obuf[MAX_OOP_SIZE];
117
static LIST_HEAD(ixp_pkq); /* current PK wait list */
118
static struct ixp_pkq *ixp_pk_cur;
119
static spinlock_t ixp_pkq_lock;
121
#endif /* __ixp46X */
123
static int ixp_blocked = 0;
125
static int32_t ixp_id = -1;
126
static struct ixp_data **ixp_sessions = NULL;
127
static u_int32_t ixp_sesnum = 0;
129
static int ixp_process(device_t, struct cryptop *, int);
130
static int ixp_newsession(device_t, u_int32_t *, struct cryptoini *);
131
static int ixp_freesession(device_t, u_int64_t);
133
static int ixp_kprocess(device_t, struct cryptkop *krp, int hint);
136
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
137
static kmem_cache_t *qcache;
139
static struct kmem_cache *qcache;
142
#define debug ixp_debug
143
static int ixp_debug = 0;
144
module_param(ixp_debug, int, 0644);
145
MODULE_PARM_DESC(ixp_debug, "Enable debug");
147
static int ixp_init_crypto = 1;
148
module_param(ixp_init_crypto, int, 0444); /* RO after load/boot */
149
MODULE_PARM_DESC(ixp_init_crypto, "Call ixCryptoAccInit (default is 1)");
151
static void ixp_process_pending(void *arg);
152
static void ixp_registration(void *arg);
153
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
154
static void ixp_process_pending_wq(struct work_struct *work);
155
static void ixp_registration_wq(struct work_struct *work);
159
* dummy device structure
163
softc_device_decl sc_dev;
166
static device_method_t ixp_methods = {
167
/* crypto device methods */
168
DEVMETHOD(cryptodev_newsession, ixp_newsession),
169
DEVMETHOD(cryptodev_freesession,ixp_freesession),
170
DEVMETHOD(cryptodev_process, ixp_process),
172
DEVMETHOD(cryptodev_kprocess, ixp_kprocess),
177
* Generate a new software session.
180
ixp_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
182
struct ixp_data *ixp;
184
#define AUTH_LEN(cri, def) \
185
(cri->cri_mlen ? cri->cri_mlen : (def))
187
dprintk("%s():alg %d\n", __FUNCTION__,cri->cri_alg);
188
if (sid == NULL || cri == NULL) {
189
dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
194
for (i = 1; i < ixp_sesnum; i++)
195
if (ixp_sessions[i] == NULL)
198
i = 1; /* NB: to silence compiler warning */
200
if (ixp_sessions == NULL || i == ixp_sesnum) {
201
struct ixp_data **ixpd;
203
if (ixp_sessions == NULL) {
204
i = 1; /* We leave ixp_sessions[0] empty */
205
ixp_sesnum = CRYPTO_SW_SESSIONS;
209
ixpd = kmalloc(ixp_sesnum * sizeof(struct ixp_data *), SLAB_ATOMIC);
211
/* Reset session number */
212
if (ixp_sesnum == CRYPTO_SW_SESSIONS)
216
dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
219
memset(ixpd, 0, ixp_sesnum * sizeof(struct ixp_data *));
221
/* Copy existing sessions */
223
memcpy(ixpd, ixp_sessions,
224
(ixp_sesnum / 2) * sizeof(struct ixp_data *));
231
ixp_sessions[i] = (struct ixp_data *) kmalloc(sizeof(struct ixp_data),
233
if (ixp_sessions[i] == NULL) {
234
ixp_freesession(NULL, i);
235
dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
241
ixp = ixp_sessions[i];
242
memset(ixp, 0, sizeof(*ixp));
244
ixp->ixp_cipher_alg = -1;
245
ixp->ixp_auth_alg = -1;
246
ixp->ixp_ctx_id = -1;
247
INIT_LIST_HEAD(&ixp->ixp_q);
249
ixp->ixp_ctx.useDifferentSrcAndDestMbufs = 0;
252
switch (cri->cri_alg) {
254
ixp->ixp_cipher_alg = cri->cri_alg;
255
ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_DES;
256
ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
257
ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;
258
ixp->ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
259
ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen =
260
IX_CRYPTO_ACC_DES_IV_64;
261
memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,
262
cri->cri_key, (cri->cri_klen + 7) / 8);
265
case CRYPTO_3DES_CBC:
266
ixp->ixp_cipher_alg = cri->cri_alg;
267
ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_3DES;
268
ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
269
ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;
270
ixp->ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
271
ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen =
272
IX_CRYPTO_ACC_DES_IV_64;
273
memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,
274
cri->cri_key, (cri->cri_klen + 7) / 8);
277
case CRYPTO_RIJNDAEL128_CBC:
278
ixp->ixp_cipher_alg = cri->cri_alg;
279
ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_AES;
280
ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
281
ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;
282
ixp->ixp_ctx.cipherCtx.cipherBlockLen = 16;
283
ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen = 16;
284
memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,
285
cri->cri_key, (cri->cri_klen + 7) / 8);
289
case CRYPTO_MD5_HMAC:
290
ixp->ixp_auth_alg = cri->cri_alg;
291
ixp->ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_MD5;
292
ixp->ixp_ctx.authCtx.authDigestLen = AUTH_LEN(cri, MD5_HASH_LEN);
293
ixp->ixp_ctx.authCtx.aadLen = 0;
294
/* Only MD5_HMAC needs a key */
295
if (cri->cri_alg == CRYPTO_MD5_HMAC) {
296
ixp->ixp_ctx.authCtx.authKeyLen = (cri->cri_klen + 7) / 8;
297
if (ixp->ixp_ctx.authCtx.authKeyLen >
298
sizeof(ixp->ixp_ctx.authCtx.key.authKey)) {
300
"ixp4xx: Invalid key length for MD5_HMAC - %d bits\n",
302
ixp_freesession(NULL, i);
305
memcpy(ixp->ixp_ctx.authCtx.key.authKey,
306
cri->cri_key, (cri->cri_klen + 7) / 8);
311
case CRYPTO_SHA1_HMAC:
312
ixp->ixp_auth_alg = cri->cri_alg;
313
ixp->ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_SHA1;
314
ixp->ixp_ctx.authCtx.authDigestLen = AUTH_LEN(cri, SHA1_HASH_LEN);
315
ixp->ixp_ctx.authCtx.aadLen = 0;
316
/* Only SHA1_HMAC needs a key */
317
if (cri->cri_alg == CRYPTO_SHA1_HMAC) {
318
ixp->ixp_ctx.authCtx.authKeyLen = (cri->cri_klen + 7) / 8;
319
if (ixp->ixp_ctx.authCtx.authKeyLen >
320
sizeof(ixp->ixp_ctx.authCtx.key.authKey)) {
322
"ixp4xx: Invalid key length for SHA1_HMAC - %d bits\n",
324
ixp_freesession(NULL, i);
327
memcpy(ixp->ixp_ctx.authCtx.key.authKey,
328
cri->cri_key, (cri->cri_klen + 7) / 8);
333
printk("ixp: unknown algo 0x%x\n", cri->cri_alg);
334
ixp_freesession(NULL, i);
340
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
341
INIT_WORK(&ixp->ixp_pending_work, ixp_process_pending_wq);
342
INIT_WORK(&ixp->ixp_registration_work, ixp_registration_wq);
344
INIT_WORK(&ixp->ixp_pending_work, ixp_process_pending, ixp);
345
INIT_WORK(&ixp->ixp_registration_work, ixp_registration, ixp);
356
ixp_freesession(device_t dev, u_int64_t tid)
358
u_int32_t sid = CRYPTO_SESID2LID(tid);
360
dprintk("%s()\n", __FUNCTION__);
361
if (sid > ixp_sesnum || ixp_sessions == NULL ||
362
ixp_sessions[sid] == NULL) {
363
dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
367
/* Silently accept and return */
371
if (ixp_sessions[sid]) {
372
if (ixp_sessions[sid]->ixp_ctx_id != -1) {
373
ixCryptoAccCtxUnregister(ixp_sessions[sid]->ixp_ctx_id);
374
ixp_sessions[sid]->ixp_ctx_id = -1;
377
flush_scheduled_work();
379
kfree(ixp_sessions[sid]);
381
ixp_sessions[sid] = NULL;
384
crypto_unblock(ixp_id, CRYPTO_SYMQ);
391
* callback for when hash processing is complete
398
IxCryptoAccStatus status)
402
dprintk("%s(%u, %p, 0x%x)\n", __FUNCTION__, hash_key_id, bufp, status);
405
printk("ixp: NULL buf in %s\n", __FUNCTION__);
409
q = IX_MBUF_PRIV(bufp);
411
printk("ixp: NULL priv in %s\n", __FUNCTION__);
415
if (status == IX_CRYPTO_ACC_STATUS_SUCCESS) {
416
/* On success, need to copy hash back into original client buffer */
417
memcpy(q->ixp_hash_dest, q->ixp_hash_src,
418
(q->ixp_q_data->ixp_auth_alg == CRYPTO_SHA1) ?
419
SHA1_HASH_LEN : MD5_HASH_LEN);
422
printk("ixp: hash perform failed status=%d\n", status);
423
q->ixp_q_crp->crp_etype = EINVAL;
426
/* Free internal buffer used for hashing */
427
kfree(IX_MBUF_MDATA(&q->ixp_q_mbuf));
429
crypto_done(q->ixp_q_crp);
430
kmem_cache_free(qcache, q);
434
* setup a request and perform it
437
ixp_q_process(struct ixp_q *q)
439
IxCryptoAccStatus status;
440
struct ixp_data *ixp = q->ixp_q_data;
448
dprintk("%s(%p)\n", __FUNCTION__, q);
451
if (q->ixp_q_ccrd->crd_flags & CRD_F_IV_EXPLICIT) {
452
q->ixp_q_iv = q->ixp_q_ccrd->crd_iv;
454
q->ixp_q_iv = q->ixp_q_iv_data;
455
crypto_copydata(q->ixp_q_crp->crp_flags, q->ixp_q_crp->crp_buf,
456
q->ixp_q_ccrd->crd_inject,
457
ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen,
458
(caddr_t) q->ixp_q_iv);
462
auth_off = q->ixp_q_acrd->crd_skip;
463
auth_len = q->ixp_q_acrd->crd_len;
464
icv_off = q->ixp_q_acrd->crd_inject;
467
crypt_off = q->ixp_q_ccrd->crd_skip;
468
crypt_len = q->ixp_q_ccrd->crd_len;
469
} else { /* if (q->ixp_q_acrd) */
470
auth_off = q->ixp_q_acrd->crd_skip;
471
auth_len = q->ixp_q_acrd->crd_len;
472
icv_off = q->ixp_q_acrd->crd_inject;
475
if (q->ixp_q_crp->crp_flags & CRYPTO_F_SKBUF) {
476
struct sk_buff *skb = (struct sk_buff *) q->ixp_q_crp->crp_buf;
477
if (skb_shinfo(skb)->nr_frags) {
479
* DAVIDM fix this limitation one day by using
480
* a buffer pool and chaining, it is not currently
481
* needed for current user/kernel space acceleration
483
printk("ixp: Cannot handle fragmented skb's yet !\n");
484
q->ixp_q_crp->crp_etype = ENOENT;
487
IX_MBUF_MLEN(&q->ixp_q_mbuf) =
488
IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = skb->len;
489
IX_MBUF_MDATA(&q->ixp_q_mbuf) = skb->data;
490
} else if (q->ixp_q_crp->crp_flags & CRYPTO_F_IOV) {
491
struct uio *uiop = (struct uio *) q->ixp_q_crp->crp_buf;
492
if (uiop->uio_iovcnt != 1) {
494
* DAVIDM fix this limitation one day by using
495
* a buffer pool and chaining, it is not currently
496
* needed for current user/kernel space acceleration
498
printk("ixp: Cannot handle more than 1 iovec yet !\n");
499
q->ixp_q_crp->crp_etype = ENOENT;
502
IX_MBUF_MLEN(&q->ixp_q_mbuf) =
503
IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = uiop->uio_iov[0].iov_len;
504
IX_MBUF_MDATA(&q->ixp_q_mbuf) = uiop->uio_iov[0].iov_base;
505
} else /* contig buffer */ {
506
IX_MBUF_MLEN(&q->ixp_q_mbuf) =
507
IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = q->ixp_q_crp->crp_ilen;
508
IX_MBUF_MDATA(&q->ixp_q_mbuf) = q->ixp_q_crp->crp_buf;
511
IX_MBUF_PRIV(&q->ixp_q_mbuf) = q;
513
if (ixp->ixp_auth_alg == CRYPTO_SHA1 || ixp->ixp_auth_alg == CRYPTO_MD5) {
515
* For SHA1 and MD5 hash, need to create an internal buffer that is big
516
* enough to hold the original data + the appropriate padding for the
521
IX_MBUF_MLEN(&q->ixp_q_mbuf) = IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) =
522
((IX_MBUF_MLEN(&q->ixp_q_mbuf) * 8) + 72 + 511) / 8;
523
tbuf = kmalloc(IX_MBUF_MLEN(&q->ixp_q_mbuf), SLAB_ATOMIC);
525
if (IX_MBUF_MDATA(&q->ixp_q_mbuf) == NULL) {
526
printk("ixp: kmalloc(%u, SLAB_ATOMIC) failed\n",
527
IX_MBUF_MLEN(&q->ixp_q_mbuf));
528
q->ixp_q_crp->crp_etype = ENOMEM;
531
memcpy(tbuf, &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_off], auth_len);
533
/* Set location in client buffer to copy hash into */
535
&(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_off + auth_len];
537
IX_MBUF_MDATA(&q->ixp_q_mbuf) = tbuf;
539
/* Set location in internal buffer for where hash starts */
540
q->ixp_hash_src = &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_len];
542
crypt_func = "ixCryptoAccHashPerform";
543
status = ixCryptoAccHashPerform(ixp->ixp_ctx.authCtx.authAlgo,
544
&q->ixp_q_mbuf, ixp_hash_perform_cb, 0, auth_len, auth_len,
545
&ixp->ixp_hash_key_id);
548
crypt_func = "ixCryptoAccAuthCryptPerform";
549
status = ixCryptoAccAuthCryptPerform(ixp->ixp_ctx_id, &q->ixp_q_mbuf,
550
NULL, auth_off, auth_len, crypt_off, crypt_len, icv_off,
554
if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
557
if (IX_CRYPTO_ACC_STATUS_QUEUE_FULL == status) {
558
q->ixp_q_crp->crp_etype = ENOMEM;
562
printk("ixp: %s failed %u\n", crypt_func, status);
563
q->ixp_q_crp->crp_etype = EINVAL;
566
crypto_done(q->ixp_q_crp);
567
kmem_cache_free(qcache, q);
572
* because we cannot process the Q from the Register callback
573
* we do it here on a task Q.
577
ixp_process_pending(void *arg)
579
struct ixp_data *ixp = arg;
580
struct ixp_q *q = NULL;
582
dprintk("%s(%p)\n", __FUNCTION__, arg);
587
while (!list_empty(&ixp->ixp_q)) {
588
q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
589
list_del(&q->ixp_q_list);
594
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
596
ixp_process_pending_wq(struct work_struct *work)
598
struct ixp_data *ixp = container_of(work, struct ixp_data,
600
ixp_process_pending(ixp);
605
* callback for when context registration is complete
609
ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp, IxCryptoAccStatus status)
612
struct ixp_data *ixp;
615
dprintk("%s(%d, %p, %d)\n", __FUNCTION__, ctx_id, bufp, status);
618
* free any buffer passed in to this routine
621
IX_MBUF_MLEN(bufp) = IX_MBUF_PKT_LEN(bufp) = 0;
622
kfree(IX_MBUF_MDATA(bufp));
623
IX_MBUF_MDATA(bufp) = NULL;
626
for (i = 0; i < ixp_sesnum; i++) {
627
ixp = ixp_sessions[i];
628
if (ixp && ixp->ixp_ctx_id == ctx_id)
631
if (i >= ixp_sesnum) {
632
printk("ixp: invalid context id %d\n", ctx_id);
636
if (IX_CRYPTO_ACC_STATUS_WAIT == status) {
637
/* this is normal to free the first of two buffers */
638
dprintk("ixp: register not finished yet.\n");
642
if (IX_CRYPTO_ACC_STATUS_SUCCESS != status) {
643
printk("ixp: register failed 0x%x\n", status);
644
while (!list_empty(&ixp->ixp_q)) {
645
q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
646
list_del(&q->ixp_q_list);
647
q->ixp_q_crp->crp_etype = EINVAL;
648
crypto_done(q->ixp_q_crp);
649
kmem_cache_free(qcache, q);
655
* we are now registered, we cannot start processing the Q here
656
* or we get strange errors with AES (DES/3DES seem to be ok).
658
ixp->ixp_registered = 1;
659
schedule_work(&ixp->ixp_pending_work);
664
* callback for when data processing is complete
672
IxCryptoAccStatus status)
676
dprintk("%s(%d, %p, %p, 0x%x)\n", __FUNCTION__, ctx_id, sbufp,
680
printk("ixp: NULL sbuf in ixp_perform_cb\n");
684
q = IX_MBUF_PRIV(sbufp);
686
printk("ixp: NULL priv in ixp_perform_cb\n");
690
if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
691
printk("ixp: perform failed status=%d\n", status);
692
q->ixp_q_crp->crp_etype = EINVAL;
695
crypto_done(q->ixp_q_crp);
696
kmem_cache_free(qcache, q);
701
* registration is not callable at IRQ time, so we defer
702
* to a task queue, this routines completes the registration for us
703
* when the task queue runs
705
* Unfortunately this means we cannot tell OCF that the driver is blocked,
706
* we do that on the next request.
710
ixp_registration(void *arg)
712
struct ixp_data *ixp = arg;
713
struct ixp_q *q = NULL;
714
IX_MBUF *pri = NULL, *sec = NULL;
715
int status = IX_CRYPTO_ACC_STATUS_SUCCESS;
718
printk("ixp: ixp_registration with no arg\n");
722
if (ixp->ixp_ctx_id != -1) {
723
ixCryptoAccCtxUnregister(ixp->ixp_ctx_id);
724
ixp->ixp_ctx_id = -1;
727
if (list_empty(&ixp->ixp_q)) {
728
printk("ixp: ixp_registration with no Q\n");
733
* setup the primary and secondary buffers
735
q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
737
pri = &ixp->ixp_pri_mbuf;
738
sec = &ixp->ixp_sec_mbuf;
739
IX_MBUF_MLEN(pri) = IX_MBUF_PKT_LEN(pri) = 128;
740
IX_MBUF_MDATA(pri) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
741
IX_MBUF_MLEN(sec) = IX_MBUF_PKT_LEN(sec) = 128;
742
IX_MBUF_MDATA(sec) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
745
/* Only need to register if a crypt op or HMAC op */
746
if (!(ixp->ixp_auth_alg == CRYPTO_SHA1 ||
747
ixp->ixp_auth_alg == CRYPTO_MD5)) {
748
status = ixCryptoAccCtxRegister(
756
/* Otherwise we start processing pending q */
757
schedule_work(&ixp->ixp_pending_work);
760
if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
763
if (IX_CRYPTO_ACC_STATUS_EXCEED_MAX_TUNNELS == status) {
764
printk("ixp: ixCryptoAccCtxRegister failed (out of tunnels)\n");
766
/* perhaps we should return EGAIN on queued ops ? */
770
printk("ixp: ixCryptoAccCtxRegister failed %d\n", status);
771
ixp->ixp_ctx_id = -1;
774
* everything waiting is toasted
776
while (!list_empty(&ixp->ixp_q)) {
777
q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
778
list_del(&q->ixp_q_list);
779
q->ixp_q_crp->crp_etype = ENOENT;
780
crypto_done(q->ixp_q_crp);
781
kmem_cache_free(qcache, q);
785
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
787
ixp_registration_wq(struct work_struct *work)
789
struct ixp_data *ixp = container_of(work, struct ixp_data,
790
ixp_registration_work);
791
ixp_registration(ixp);
799
ixp_process(device_t dev, struct cryptop *crp, int hint)
801
struct ixp_data *ixp;
803
struct ixp_q *q = NULL;
806
dprintk("%s()\n", __FUNCTION__);
810
dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
819
if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
820
dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
821
crp->crp_etype = EINVAL;
826
* find the session we are using
829
lid = crp->crp_sid & 0xffffffff;
830
if (lid >= ixp_sesnum || lid == 0 || ixp_sessions == NULL ||
831
ixp_sessions[lid] == NULL) {
832
crp->crp_etype = ENOENT;
833
dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
836
ixp = ixp_sessions[lid];
839
* setup a new request ready for queuing
841
q = kmem_cache_alloc(qcache, SLAB_ATOMIC);
843
dprintk("%s,%d: ENOMEM\n", __FILE__, __LINE__);
844
crp->crp_etype = ENOMEM;
848
* save some cycles by only zeroing the important bits
850
memset(&q->ixp_q_mbuf, 0, sizeof(q->ixp_q_mbuf));
851
q->ixp_q_ccrd = NULL;
852
q->ixp_q_acrd = NULL;
857
* point the cipher and auth descriptors appropriately
858
* check that we have something to do
860
if (crp->crp_desc->crd_alg == ixp->ixp_cipher_alg)
861
q->ixp_q_ccrd = crp->crp_desc;
862
else if (crp->crp_desc->crd_alg == ixp->ixp_auth_alg)
863
q->ixp_q_acrd = crp->crp_desc;
865
crp->crp_etype = ENOENT;
866
dprintk("%s,%d: bad desc match: ENOENT\n", __FILE__, __LINE__);
869
if (crp->crp_desc->crd_next) {
870
if (crp->crp_desc->crd_next->crd_alg == ixp->ixp_cipher_alg)
871
q->ixp_q_ccrd = crp->crp_desc->crd_next;
872
else if (crp->crp_desc->crd_next->crd_alg == ixp->ixp_auth_alg)
873
q->ixp_q_acrd = crp->crp_desc->crd_next;
875
crp->crp_etype = ENOENT;
876
dprintk("%s,%d: bad desc match: ENOENT\n", __FILE__, __LINE__);
882
* If there is a direction change for this context then we mark it as
883
* unregistered and re-register is for the new direction. This is not
884
* a very expensive operation and currently only tends to happen when
885
* user-space application are doing benchmarks
887
* DM - we should be checking for pending requests before unregistering.
889
if (q->ixp_q_ccrd && ixp->ixp_registered &&
890
ixp->ixp_crd_flags != (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT)) {
891
dprintk("%s - detected direction change on session\n", __FUNCTION__);
892
ixp->ixp_registered = 0;
896
* if we are registered, call straight into the perform code
898
if (ixp->ixp_registered) {
904
* the only part of the context not set in newsession is the direction
908
ixp->ixp_crd_flags = (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT);
909
if (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT) {
910
ixp->ixp_ctx.operation = q->ixp_q_acrd ?
911
IX_CRYPTO_ACC_OP_ENCRYPT_AUTH : IX_CRYPTO_ACC_OP_ENCRYPT;
913
ixp->ixp_ctx.operation = q->ixp_q_acrd ?
914
IX_CRYPTO_ACC_OP_AUTH_DECRYPT : IX_CRYPTO_ACC_OP_DECRYPT;
917
/* q->ixp_q_acrd must be set if we are here */
918
ixp->ixp_ctx.operation = IX_CRYPTO_ACC_OP_AUTH_CALC;
921
status = list_empty(&ixp->ixp_q);
922
list_add_tail(&q->ixp_q_list, &ixp->ixp_q);
924
schedule_work(&ixp->ixp_registration_work);
929
kmem_cache_free(qcache, q);
937
* key processing support for the ixp465
942
* copy a BN (LE) into a buffer (BE) an fill out the op appropriately
943
* assume zeroed and only copy bits that are significant
947
ixp_copy_ibuf(struct crparam *p, IxCryptoAccPkeEauOperand *op, UINT32 *buf)
949
unsigned char *src = (unsigned char *) p->crp_p;
951
int len, bits = p->crp_nbits;
953
dprintk("%s()\n", __FUNCTION__);
955
if (bits > MAX_IOP_SIZE * sizeof(UINT32) * 8) {
956
dprintk("%s - ibuf too big (%d > %d)\n", __FUNCTION__,
957
bits, MAX_IOP_SIZE * sizeof(UINT32) * 8);
961
len = (bits + 31) / 32; /* the number UINT32's needed */
963
dst = (unsigned char *) &buf[len];
971
#if 0 /* no need to zero remaining bits as it is done during request alloc */
972
while (dst > (unsigned char *) buf)
982
* copy out the result, be as forgiving as we can about small output buffers
986
ixp_copy_obuf(struct crparam *p, IxCryptoAccPkeEauOpResult *op, UINT32 *buf)
988
unsigned char *dst = (unsigned char *) p->crp_p;
989
unsigned char *src = (unsigned char *) buf;
990
int len, z, bits = p->crp_nbits;
992
dprintk("%s()\n", __FUNCTION__);
994
len = op->dataLen * sizeof(UINT32);
996
/* skip leading zeroes to be small buffer friendly */
998
while (z < len && src[z] == '\0')
1005
while (len > 0 && bits > 0) {
1017
dprintk("%s - obuf is %d (z=%d, ob=%d) bytes too small\n",
1018
__FUNCTION__, len, z, p->crp_nbits / 8);
1027
* the parameter offsets for exp_mod
1030
#define IXP_PARAM_BASE 0
1031
#define IXP_PARAM_EXP 1
1032
#define IXP_PARAM_MOD 2
1033
#define IXP_PARAM_RES 3
1036
* key processing complete callback, is also used to start processing
1037
* by passing a NULL for pResult
1042
IxCryptoAccPkeEauOperation operation,
1043
IxCryptoAccPkeEauOpResult *pResult,
1045
IxCryptoAccStatus status)
1047
struct ixp_pkq *q, *tmp;
1048
unsigned long flags;
1050
dprintk("%s(0x%x, %p, %d, 0x%x)\n", __FUNCTION__, operation, pResult,
1051
carryOrBorrow, status);
1053
/* handle a completed request */
1055
if (ixp_pk_cur && &ixp_pk_cur->pkq_result == pResult) {
1057
if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
1058
dprintk("%s() - op failed 0x%x\n", __FUNCTION__, status);
1059
q->pkq_krp->krp_status = ERANGE; /* could do better */
1061
/* copy out the result */
1062
if (ixp_copy_obuf(&q->pkq_krp->krp_param[IXP_PARAM_RES],
1063
&q->pkq_result, q->pkq_obuf))
1064
q->pkq_krp->krp_status = ERANGE;
1066
crypto_kdone(q->pkq_krp);
1070
printk("%s - callback with invalid result pointer\n", __FUNCTION__);
1073
spin_lock_irqsave(&ixp_pkq_lock, flags);
1074
if (ixp_pk_cur || list_empty(&ixp_pkq)) {
1075
spin_unlock_irqrestore(&ixp_pkq_lock, flags);
1079
list_for_each_entry_safe(q, tmp, &ixp_pkq, pkq_list) {
1081
list_del(&q->pkq_list);
1084
spin_unlock_irqrestore(&ixp_pkq_lock, flags);
1086
status = ixCryptoAccPkeEauPerform(
1087
IX_CRYPTO_ACC_OP_EAU_MOD_EXP,
1092
if (status == IX_CRYPTO_ACC_STATUS_SUCCESS) {
1093
dprintk("%s() - ixCryptoAccPkeEauPerform SUCCESS\n", __FUNCTION__);
1094
return; /* callback will return here for callback */
1095
} else if (status == IX_CRYPTO_ACC_STATUS_RETRY) {
1096
printk("%s() - ixCryptoAccPkeEauPerform RETRY\n", __FUNCTION__);
1098
printk("%s() - ixCryptoAccPkeEauPerform failed %d\n",
1099
__FUNCTION__, status);
1101
q->pkq_krp->krp_status = ERANGE; /* could do better */
1102
crypto_kdone(q->pkq_krp);
1104
spin_lock_irqsave(&ixp_pkq_lock, flags);
1106
spin_unlock_irqrestore(&ixp_pkq_lock, flags);
1111
ixp_kprocess(device_t dev, struct cryptkop *krp, int hint)
1115
unsigned long flags;
1117
dprintk("%s l1=%d l2=%d l3=%d l4=%d\n", __FUNCTION__,
1118
krp->krp_param[IXP_PARAM_BASE].crp_nbits,
1119
krp->krp_param[IXP_PARAM_EXP].crp_nbits,
1120
krp->krp_param[IXP_PARAM_MOD].crp_nbits,
1121
krp->krp_param[IXP_PARAM_RES].crp_nbits);
1124
if (krp->krp_op != CRK_MOD_EXP) {
1125
krp->krp_status = EOPNOTSUPP;
1129
q = (struct ixp_pkq *) kmalloc(sizeof(*q), GFP_KERNEL);
1131
krp->krp_status = ENOMEM;
1136
* The PKE engine does not appear to zero the output buffer
1137
* appropriately, so we need to do it all here.
1139
memset(q, 0, sizeof(*q));
1142
INIT_LIST_HEAD(&q->pkq_list);
1144
if (ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_BASE], &q->pkq_op.modExpOpr.M,
1147
if (!rc && ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_EXP],
1148
&q->pkq_op.modExpOpr.e, q->pkq_ibuf1))
1150
if (!rc && ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_MOD],
1151
&q->pkq_op.modExpOpr.N, q->pkq_ibuf2))
1156
krp->krp_status = ERANGE;
1160
q->pkq_result.pData = q->pkq_obuf;
1161
q->pkq_result.dataLen =
1162
(krp->krp_param[IXP_PARAM_RES].crp_nbits + 31) / 32;
1164
spin_lock_irqsave(&ixp_pkq_lock, flags);
1165
list_add_tail(&q->pkq_list, &ixp_pkq);
1166
spin_unlock_irqrestore(&ixp_pkq_lock, flags);
1169
ixp_kperform_cb(0, NULL, 0, 0);
1179
#ifdef CONFIG_OCF_RANDOMHARVEST
1181
* We run the random number generator output through SHA so that it
1182
* is FIPS compliant.
1185
static volatile int sha_done = 0;
1186
static unsigned char sha_digest[20];
1189
ixp_hash_cb(UINT8 *digest, IxCryptoAccStatus status)
1191
dprintk("%s(%p, %d)\n", __FUNCTION__, digest, status);
1192
if (sha_digest != digest)
1193
printk("digest error\n");
1194
if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
1201
ixp_read_random(void *arg, u_int32_t *buf, int maxwords)
1203
IxCryptoAccStatus status;
1206
dprintk("%s(%p, %d)\n", __FUNCTION__, buf, maxwords);
1207
memset(buf, 0, maxwords * sizeof(*buf));
1208
status = ixCryptoAccPkePseudoRandomNumberGet(maxwords, buf);
1209
if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
1210
dprintk("%s: ixCryptoAccPkePseudoRandomNumberGet failed %d\n",
1211
__FUNCTION__, status);
1216
* run the random data through SHA to make it look more random
1219
n = sizeof(sha_digest); /* process digest bytes at a time */
1222
for (i = 0; i < maxwords; i += n / sizeof(*buf)) {
1223
if ((maxwords - i) * sizeof(*buf) < n)
1224
n = (maxwords - i) * sizeof(*buf);
1226
status = ixCryptoAccPkeHashPerform(IX_CRYPTO_ACC_AUTH_SHA1,
1227
(UINT8 *) &buf[i], n, ixp_hash_cb, sha_digest);
1228
if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
1229
dprintk("ixCryptoAccPkeHashPerform failed %d\n", status);
1235
dprintk("ixCryptoAccPkeHashPerform failed CB %d\n", -sha_done);
1238
memcpy(&buf[i], sha_digest, n);
1239
rc += n / sizeof(*buf);;
1244
#endif /* CONFIG_OCF_RANDOMHARVEST */
1246
#endif /* __ixp46X */
1251
* our driver startup and shutdown routines
1257
dprintk("%s(%p)\n", __FUNCTION__, ixp_init);
1259
if (ixp_init_crypto && ixCryptoAccInit() != IX_CRYPTO_ACC_STATUS_SUCCESS)
1260
printk("ixCryptoAccInit failed, assuming already initialised!\n");
1262
qcache = kmem_cache_create("ixp4xx_q", sizeof(struct ixp_q), 0,
1263
SLAB_HWCACHE_ALIGN, NULL
1264
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
1269
printk("failed to create Qcache\n");
1273
memset(&ixpdev, 0, sizeof(ixpdev));
1274
softc_device_init(&ixpdev, "ixp4xx", 0, ixp_methods);
1276
ixp_id = crypto_get_driverid(softc_get_device(&ixpdev),
1277
CRYPTOCAP_F_HARDWARE);
1279
panic("IXP/OCF crypto device cannot initialize!");
1281
#define REGISTER(alg) \
1282
crypto_register(ixp_id,alg,0,0)
1284
REGISTER(CRYPTO_DES_CBC);
1285
REGISTER(CRYPTO_3DES_CBC);
1286
REGISTER(CRYPTO_RIJNDAEL128_CBC);
1287
#ifdef CONFIG_OCF_IXP4XX_SHA1_MD5
1288
REGISTER(CRYPTO_MD5);
1289
REGISTER(CRYPTO_SHA1);
1291
REGISTER(CRYPTO_MD5_HMAC);
1292
REGISTER(CRYPTO_SHA1_HMAC);
1296
spin_lock_init(&ixp_pkq_lock);
1298
* we do not enable the go fast options here as they can potentially
1299
* allow timing based attacks
1301
* http://www.openssl.org/news/secadv_20030219.txt
1303
ixCryptoAccPkeEauExpConfig(0, 0);
1304
crypto_kregister(ixp_id, CRK_MOD_EXP, 0);
1305
#ifdef CONFIG_OCF_RANDOMHARVEST
1306
crypto_rregister(ixp_id, ixp_read_random, NULL);
1316
dprintk("%s()\n", __FUNCTION__);
1317
crypto_unregister_all(ixp_id);
1319
kmem_cache_destroy(qcache);
1323
module_init(ixp_init);
1324
module_exit(ixp_exit);
1326
MODULE_LICENSE("Dual BSD/GPL");
1327
MODULE_AUTHOR("David McCullough <dmccullough@cyberguard.com>");
1328
MODULE_DESCRIPTION("ixp (OCF module for IXP4xx crypto)");