1198157Srrs/*-
2198157Srrs * Copyright (c) 2003-2009 RMI Corporation
3198157Srrs * All rights reserved.
4198157Srrs *
5198157Srrs * Redistribution and use in source and binary forms, with or without
6198157Srrs * modification, are permitted provided that the following conditions
7198157Srrs * are met:
8198157Srrs * 1. Redistributions of source code must retain the above copyright
9198157Srrs *    notice, this list of conditions and the following disclaimer.
10198157Srrs * 2. Redistributions in binary form must reproduce the above copyright
11198157Srrs *    notice, this list of conditions and the following disclaimer in the
12198157Srrs *    documentation and/or other materials provided with the distribution.
13198157Srrs * 3. Neither the name of RMI Corporation, nor the names of its contributors,
14198157Srrs *    may be used to endorse or promote products derived from this software
15198157Srrs *    without specific prior written permission.
16198157Srrs *
17198157Srrs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18198157Srrs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19198157Srrs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20198157Srrs * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21198157Srrs * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22198157Srrs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23198157Srrs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24198157Srrs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25198157Srrs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26198157Srrs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27198157Srrs * SUCH DAMAGE.
28198157Srrs *
29202066Simp * RMI_BSD
30202066Simp */
31198157Srrs
32202066Simp#include <sys/cdefs.h>
33202066Simp__FBSDID("$FreeBSD: releng/11.0/sys/mips/rmi/dev/sec/rmisec.c 275732 2014-12-12 19:56:36Z jmg $");
34198157Srrs
35198157Srrs#include <sys/param.h>
36198157Srrs#include <sys/systm.h>
37198157Srrs#include <sys/proc.h>
38198157Srrs#include <sys/errno.h>
39198157Srrs#include <sys/malloc.h>
40198157Srrs#include <sys/kernel.h>
41198157Srrs#include <sys/module.h>
42198157Srrs#include <sys/mbuf.h>
43198157Srrs#include <sys/lock.h>
44198157Srrs#include <sys/mutex.h>
45198157Srrs#include <sys/sysctl.h>
46212763Sjchandra#include <sys/bus.h>
47212763Sjchandra#include <sys/random.h>
48212763Sjchandra#include <sys/rman.h>
49212763Sjchandra#include <sys/uio.h>
50212763Sjchandra#include <sys/kobj.h>
51212763Sjchandra#include <opencrypto/cryptodev.h>
52198157Srrs
53212763Sjchandra#include "cryptodev_if.h"
54212763Sjchandra
55198157Srrs#include <vm/vm.h>
56198157Srrs#include <vm/pmap.h>
57198157Srrs
58202066Simp#include <mips/rmi/dev/sec/rmilib.h>
59198157Srrs
60212763Sjchandra/* #define RMI_SEC_DEBUG  */
61198157Srrs
62198157Srrsvoid xlr_sec_print_data(struct cryptop *crp);
63198157Srrs
64212763Sjchandrastatic int xlr_sec_newsession(device_t dev, uint32_t * sidp, struct cryptoini *cri);
65212763Sjchandrastatic int xlr_sec_freesession(device_t dev, uint64_t tid);
66212763Sjchandrastatic int xlr_sec_process(device_t dev, struct cryptop *crp, int hint);
67198157Srrs
68198627Srrsstatic int xlr_sec_probe(device_t);
69198627Srrsstatic int xlr_sec_attach(device_t);
70198627Srrsstatic int xlr_sec_detach(device_t);
71198157Srrs
72198157Srrs
73198157Srrsstatic device_method_t xlr_sec_methods[] = {
74198627Srrs	/* device interface */
75198627Srrs	DEVMETHOD(device_probe, xlr_sec_probe),
76198627Srrs	DEVMETHOD(device_attach, xlr_sec_attach),
77198627Srrs	DEVMETHOD(device_detach, xlr_sec_detach),
78198157Srrs
79212763Sjchandra	/* crypto device methods */
80212763Sjchandra	DEVMETHOD(cryptodev_newsession, xlr_sec_newsession),
81212763Sjchandra	DEVMETHOD(cryptodev_freesession,xlr_sec_freesession),
82212763Sjchandra	DEVMETHOD(cryptodev_process,    xlr_sec_process),
83212763Sjchandra
84227843Smarius	DEVMETHOD_END
85198157Srrs};
86198157Srrs
87198157Srrsstatic driver_t xlr_sec_driver = {
88198627Srrs	"rmisec",
89198627Srrs	xlr_sec_methods,
90198627Srrs	sizeof(struct xlr_sec_softc)
91198157Srrs};
92198157Srrsstatic devclass_t xlr_sec_devclass;
93198157Srrs
94198157SrrsDRIVER_MODULE(rmisec, iodi, xlr_sec_driver, xlr_sec_devclass, 0, 0);
95198157SrrsMODULE_DEPEND(rmisec, crypto, 1, 1, 1);
96198157Srrs
97198157Srrsstatic int
98198157Srrsxlr_sec_probe(device_t dev)
99198157Srrs{
100212763Sjchandra
101212763Sjchandra	device_set_desc(dev, "XLR Security Accelerator");
102198627Srrs	return (BUS_PROBE_DEFAULT);
103198157Srrs}
104198157Srrs
105198157Srrs/*
106198157Srrs * Attach an interface that successfully probed.
107198157Srrs */
108198157Srrsstatic int
109198157Srrsxlr_sec_attach(device_t dev)
110198157Srrs{
111198627Srrs	struct xlr_sec_softc *sc = device_get_softc(dev);
112198157Srrs
113198627Srrs	sc->sc_dev = dev;
114212763Sjchandra	mtx_init(&sc->sc_mtx, device_get_nameunit(dev), "rmi crypto driver",
115212763Sjchandra	    MTX_DEF);
116212763Sjchandra	sc->sc_cid = crypto_get_driverid(dev, CRYPTOCAP_F_HARDWARE);
117198627Srrs	if (sc->sc_cid < 0) {
118198627Srrs		printf("xlr_sec - error : could not get the driver id\n");
119198627Srrs		goto error_exit;
120198627Srrs	}
121212763Sjchandra	if (crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0) != 0)
122198627Srrs		printf("register failed for CRYPTO_DES_CBC\n");
123198157Srrs
124212763Sjchandra	if (crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0) != 0)
125198627Srrs		printf("register failed for CRYPTO_3DES_CBC\n");
126198157Srrs
127212763Sjchandra	if (crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0) != 0)
128198627Srrs		printf("register failed for CRYPTO_AES_CBC\n");
129198157Srrs
130212763Sjchandra	if (crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0) != 0)
131198627Srrs		printf("register failed for CRYPTO_ARC4\n");
132198157Srrs
133212763Sjchandra	if (crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0) != 0)
134198627Srrs		printf("register failed for CRYPTO_MD5\n");
135198157Srrs
136212763Sjchandra	if (crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0) != 0)
137198627Srrs		printf("register failed for CRYPTO_SHA1\n");
138198157Srrs
139212763Sjchandra	if (crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0) != 0)
140198627Srrs		printf("register failed for CRYPTO_MD5_HMAC\n");
141198157Srrs
142212763Sjchandra	if (crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0) != 0)
143198627Srrs		printf("register failed for CRYPTO_SHA1_HMAC\n");
144198157Srrs
145198627Srrs	xlr_sec_init(sc);
146212763Sjchandra	device_printf(dev, "Initialization complete!\n");
147198627Srrs	return (0);
148198157Srrs
149198157Srrserror_exit:
150198627Srrs	return (ENXIO);
151198157Srrs
152198157Srrs}
153198157Srrs
154198157Srrs/*
155198157Srrs * Detach an interface that successfully probed.
156198157Srrs */
157198157Srrsstatic int
158198157Srrsxlr_sec_detach(device_t dev)
159198157Srrs{
160198627Srrs	int sesn;
161198627Srrs	struct xlr_sec_softc *sc = device_get_softc(dev);
162198627Srrs	struct xlr_sec_session *ses = NULL;
163198627Srrs	symkey_desc_pt desc;
164198157Srrs
165198627Srrs	for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
166198627Srrs		ses = &sc->sc_sessions[sesn];
167198627Srrs		desc = (symkey_desc_pt) ses->desc_ptr;
168198627Srrs		free(desc->user.kern_src, M_DEVBUF);
169198627Srrs		free(desc->user.kern_dest, M_DEVBUF);
170198627Srrs		free(desc->next_src_buf, M_DEVBUF);
171198627Srrs		free(desc->next_dest_buf, M_DEVBUF);
172198627Srrs		free(ses->desc_ptr, M_DEVBUF);
173198627Srrs	}
174198157Srrs
175198627Srrs	return (0);
176198157Srrs}
177198157Srrs
178198157Srrs/*
179198157Srrs * Allocate a new 'session' and return an encoded session id.  'sidp'
180198157Srrs * contains our registration id, and should contain an encoded session
181198157Srrs * id on successful allocation.
182198157Srrs */
183198157Srrsstatic int
184212763Sjchandraxlr_sec_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
185198157Srrs{
186198627Srrs	struct cryptoini *c;
187212763Sjchandra	struct xlr_sec_softc *sc = device_get_softc(dev);
188198627Srrs	int mac = 0, cry = 0, sesn;
189198627Srrs	struct xlr_sec_session *ses = NULL;
190198157Srrs
191198627Srrs	if (sidp == NULL || cri == NULL || sc == NULL)
192198627Srrs		return (EINVAL);
193198157Srrs
194198627Srrs	if (sc->sc_sessions == NULL) {
195198627Srrs		ses = sc->sc_sessions = (struct xlr_sec_session *)malloc(
196198627Srrs		    sizeof(struct xlr_sec_session), M_DEVBUF, M_NOWAIT);
197198627Srrs		if (ses == NULL)
198198627Srrs			return (ENOMEM);
199198627Srrs		sesn = 0;
200198627Srrs		sc->sc_nsessions = 1;
201198627Srrs	} else {
202198627Srrs		for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
203198627Srrs			if (!sc->sc_sessions[sesn].hs_used) {
204198627Srrs				ses = &sc->sc_sessions[sesn];
205198627Srrs				break;
206198627Srrs			}
207198627Srrs		}
208198157Srrs
209198627Srrs		if (ses == NULL) {
210198627Srrs			sesn = sc->sc_nsessions;
211198627Srrs			ses = (struct xlr_sec_session *)malloc((sesn + 1) *
212198627Srrs			    sizeof(struct xlr_sec_session), M_DEVBUF, M_NOWAIT);
213198627Srrs			if (ses == NULL)
214198627Srrs				return (ENOMEM);
215212763Sjchandra			bcopy(sc->sc_sessions, ses, sesn * sizeof(*ses));
216212763Sjchandra			bzero(sc->sc_sessions, sesn * sizeof(*ses));
217198627Srrs			free(sc->sc_sessions, M_DEVBUF);
218198627Srrs			sc->sc_sessions = ses;
219198627Srrs			ses = &sc->sc_sessions[sesn];
220198627Srrs			sc->sc_nsessions++;
221198627Srrs		}
222198627Srrs	}
223212763Sjchandra	bzero(ses, sizeof(*ses));
224212763Sjchandra	ses->sessionid = sesn;
225212763Sjchandra	ses->desc_ptr = xlr_sec_allocate_desc(ses);
226212763Sjchandra	if (ses->desc_ptr == NULL)
227212763Sjchandra		return (ENOMEM);
228198627Srrs	ses->hs_used = 1;
229198157Srrs
230198627Srrs	for (c = cri; c != NULL; c = c->cri_next) {
231198627Srrs		switch (c->cri_alg) {
232198627Srrs		case CRYPTO_MD5:
233198627Srrs		case CRYPTO_SHA1:
234198627Srrs		case CRYPTO_MD5_HMAC:
235198627Srrs		case CRYPTO_SHA1_HMAC:
236198627Srrs			if (mac)
237198627Srrs				return (EINVAL);
238198627Srrs			mac = 1;
239198627Srrs			ses->hs_mlen = c->cri_mlen;
240198627Srrs			if (ses->hs_mlen == 0) {
241198627Srrs				switch (c->cri_alg) {
242198627Srrs				case CRYPTO_MD5:
243198627Srrs				case CRYPTO_MD5_HMAC:
244198627Srrs					ses->hs_mlen = 16;
245198627Srrs					break;
246198627Srrs				case CRYPTO_SHA1:
247198627Srrs				case CRYPTO_SHA1_HMAC:
248198627Srrs					ses->hs_mlen = 20;
249198627Srrs					break;
250198627Srrs				}
251198627Srrs			}
252198627Srrs			break;
253198627Srrs		case CRYPTO_DES_CBC:
254198627Srrs		case CRYPTO_3DES_CBC:
255198627Srrs		case CRYPTO_AES_CBC:
256198627Srrs			/* XXX this may read fewer, does it matter? */
257198627Srrs			/*
258198627Srrs			 * read_random(ses->hs_iv, c->cri_alg ==
259198627Srrs			 * CRYPTO_AES_CBC ? XLR_SEC_AES_IV_LENGTH :
260198627Srrs			 * XLR_SEC_IV_LENGTH);
261198627Srrs			 */
262198627Srrs			/* FALLTHROUGH */
263198627Srrs		case CRYPTO_ARC4:
264198627Srrs			if (cry)
265198627Srrs				return (EINVAL);
266198627Srrs			cry = 1;
267198627Srrs			break;
268198627Srrs		default:
269198627Srrs			return (EINVAL);
270198627Srrs		}
271198627Srrs	}
272198627Srrs	if (mac == 0 && cry == 0)
273198627Srrs		return (EINVAL);
274198157Srrs
275198627Srrs	*sidp = XLR_SEC_SID(device_get_unit(sc->sc_dev), sesn);
276198627Srrs	return (0);
277198157Srrs}
278198157Srrs
279198157Srrs/*
280198157Srrs * Deallocate a session.
281198157Srrs * XXX this routine should run a zero'd mac/encrypt key into context ram.
282198157Srrs * XXX to blow away any keys already stored there.
283198157Srrs */
284198157Srrsstatic int
285212763Sjchandraxlr_sec_freesession(device_t dev, u_int64_t tid)
286198157Srrs{
287212763Sjchandra	struct xlr_sec_softc *sc = device_get_softc(dev);
288198627Srrs	int session;
289198627Srrs	u_int32_t sid = CRYPTO_SESID2LID(tid);
290198157Srrs
291198627Srrs	if (sc == NULL)
292198627Srrs		return (EINVAL);
293198157Srrs
294198627Srrs	session = XLR_SEC_SESSION(sid);
295198627Srrs	if (session >= sc->sc_nsessions)
296198627Srrs		return (EINVAL);
297198157Srrs
298198627Srrs	sc->sc_sessions[session].hs_used = 0;
299198627Srrs	return (0);
300198157Srrs}
301198157Srrs
302198157Srrs#ifdef RMI_SEC_DEBUG
303198157Srrs
304198627Srrsvoid
305198627Srrsxlr_sec_print_data(struct cryptop *crp)
306198157Srrs{
307198627Srrs	int i, key_len;
308198627Srrs	struct cryptodesc *crp_desc;
309198157Srrs
310198627Srrs	printf("session id = 0x%llx, crp_ilen = %d, crp_olen=%d \n",
311198627Srrs	    crp->crp_sid, crp->crp_ilen, crp->crp_olen);
312198157Srrs
313198627Srrs	printf("crp_flags = 0x%x\n", crp->crp_flags);
314198157Srrs
315198157Srrs
316198627Srrs	printf("crp buf:\n");
317198627Srrs	for (i = 0; i < crp->crp_ilen; i++) {
318198627Srrs		printf("%c  ", crp->crp_buf[i]);
319198627Srrs		if (i % 10 == 0)
320198627Srrs			printf("\n");
321198627Srrs	}
322198157Srrs
323198627Srrs	printf("\n");
324198627Srrs	printf("****************** desc ****************\n");
325198627Srrs	crp_desc = crp->crp_desc;
326198627Srrs	printf("crd_skip=%d, crd_len=%d, crd_flags=0x%x, crd_alg=%d\n",
327198627Srrs	    crp_desc->crd_skip, crp_desc->crd_len, crp_desc->crd_flags, crp_desc->crd_alg);
328198157Srrs
329198627Srrs	key_len = crp_desc->crd_klen / 8;
330198627Srrs	printf("key(%d) :\n", key_len);
331198627Srrs	for (i = 0; i < key_len; i++)
332198627Srrs		printf("%d", crp_desc->crd_key[i]);
333198627Srrs	printf("\n");
334198157Srrs
335198627Srrs	printf(" IV : \n");
336198627Srrs	for (i = 0; i < EALG_MAX_BLOCK_LEN; i++)
337198627Srrs		printf("%d", crp_desc->crd_iv[i]);
338198627Srrs	printf("\n");
339198157Srrs
340198627Srrs	printf("crd_next=%p\n", crp_desc->crd_next);
341198627Srrs	return;
342198157Srrs}
343198157Srrs
344198157Srrs#endif
345198157Srrs
346198157Srrsstatic int
347212763Sjchandraxlr_sec_process(device_t dev, struct cryptop *crp, int hint)
348198157Srrs{
349212763Sjchandra	struct xlr_sec_softc *sc = device_get_softc(dev);
350198627Srrs	struct xlr_sec_command *cmd = NULL;
351198627Srrs	int session, err;
352198627Srrs	struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
353198627Srrs	struct xlr_sec_session *ses;
354198157Srrs
355198627Srrs	if (crp == NULL || crp->crp_callback == NULL) {
356198627Srrs		return (EINVAL);
357198627Srrs	}
358198627Srrs	session = XLR_SEC_SESSION(crp->crp_sid);
359198627Srrs	if (sc == NULL || session >= sc->sc_nsessions) {
360198627Srrs		err = EINVAL;
361198627Srrs		goto errout;
362198627Srrs	}
363198627Srrs	ses = &sc->sc_sessions[session];
364198157Srrs
365198627Srrs	cmd = &ses->cmd;
366198627Srrs	if (cmd == NULL) {
367198627Srrs		err = ENOMEM;
368198627Srrs		goto errout;
369198627Srrs	}
370198627Srrs	crd1 = crp->crp_desc;
371198627Srrs	if (crd1 == NULL) {
372198627Srrs		err = EINVAL;
373198627Srrs		goto errout;
374198627Srrs	}
375198627Srrs	crd2 = crd1->crd_next;
376198157Srrs
377198627Srrs	if (crd2 == NULL) {
378198627Srrs		if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
379198627Srrs		    crd1->crd_alg == CRYPTO_SHA1_HMAC ||
380198627Srrs		    crd1->crd_alg == CRYPTO_SHA1 ||
381198627Srrs		    crd1->crd_alg == CRYPTO_MD5) {
382198627Srrs			maccrd = crd1;
383198627Srrs			enccrd = NULL;
384198627Srrs		} else if (crd1->crd_alg == CRYPTO_DES_CBC ||
385198627Srrs			    crd1->crd_alg == CRYPTO_3DES_CBC ||
386198627Srrs			    crd1->crd_alg == CRYPTO_AES_CBC ||
387198627Srrs		    crd1->crd_alg == CRYPTO_ARC4) {
388198627Srrs			maccrd = NULL;
389198627Srrs			enccrd = crd1;
390198627Srrs		} else {
391198627Srrs			err = EINVAL;
392198627Srrs			goto errout;
393198627Srrs		}
394198627Srrs	} else {
395198627Srrs		if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
396198627Srrs		    crd1->crd_alg == CRYPTO_SHA1_HMAC ||
397198627Srrs		    crd1->crd_alg == CRYPTO_MD5 ||
398198627Srrs		    crd1->crd_alg == CRYPTO_SHA1) &&
399198627Srrs		    (crd2->crd_alg == CRYPTO_DES_CBC ||
400198627Srrs		    crd2->crd_alg == CRYPTO_3DES_CBC ||
401198627Srrs		    crd2->crd_alg == CRYPTO_AES_CBC ||
402198627Srrs		    crd2->crd_alg == CRYPTO_ARC4)) {
403198627Srrs			maccrd = crd1;
404198627Srrs			enccrd = crd2;
405198627Srrs		} else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
406198627Srrs			    crd1->crd_alg == CRYPTO_ARC4 ||
407198627Srrs			    crd1->crd_alg == CRYPTO_3DES_CBC ||
408198627Srrs			    crd1->crd_alg == CRYPTO_AES_CBC) &&
409198627Srrs			    (crd2->crd_alg == CRYPTO_MD5_HMAC ||
410198627Srrs			    crd2->crd_alg == CRYPTO_SHA1_HMAC ||
411198627Srrs			    crd2->crd_alg == CRYPTO_MD5 ||
412198627Srrs			    crd2->crd_alg == CRYPTO_SHA1) &&
413198627Srrs		    (crd1->crd_flags & CRD_F_ENCRYPT)) {
414198627Srrs			enccrd = crd1;
415198627Srrs			maccrd = crd2;
416198627Srrs		} else {
417198627Srrs			err = EINVAL;
418198627Srrs			goto errout;
419198627Srrs		}
420198627Srrs	}
421198157Srrs
422198627Srrs	bzero(&cmd->op, sizeof(xlr_sec_io_t));
423198157Srrs
424198627Srrs	cmd->op.source_buf = (uint64_t) (unsigned long)crp->crp_buf;
425198627Srrs	cmd->op.source_buf_size = crp->crp_ilen;
426275732Sjmg	cmd->op.dest_buf = (uint64_t) (unsigned long)crp->crp_buf;
427275732Sjmg	cmd->op.dest_buf_size = crp->crp_ilen;
428198627Srrs	cmd->op.num_packets = 1;
429198627Srrs	cmd->op.num_fragments = 1;
430198157Srrs
431198627Srrs	if (cmd->op.source_buf_size > SEC_MAX_FRAG_LEN) {
432198627Srrs		ses->multi_frag_flag = 1;
433198627Srrs	} else {
434198627Srrs		ses->multi_frag_flag = 0;
435198627Srrs	}
436198157Srrs
437198627Srrs	if (maccrd) {
438198627Srrs		cmd->maccrd = maccrd;
439198627Srrs		cmd->op.cipher_op = XLR_SEC_CIPHER_MODE_PASS;
440198627Srrs		cmd->op.cipher_mode = XLR_SEC_CIPHER_MODE_NONE;
441198627Srrs		cmd->op.cipher_type = XLR_SEC_CIPHER_TYPE_NONE;
442198627Srrs		cmd->op.cipher_init = 0;
443198627Srrs		cmd->op.cipher_offset = 0;
444198157Srrs
445198627Srrs		switch (maccrd->crd_alg) {
446198627Srrs		case CRYPTO_MD5:
447198627Srrs			cmd->op.digest_type = XLR_SEC_DIGEST_TYPE_MD5;
448198627Srrs			cmd->op.digest_init = XLR_SEC_DIGEST_INIT_NEWKEY;
449198627Srrs			cmd->op.digest_src = XLR_SEC_DIGEST_SRC_DMA;
450198627Srrs			cmd->op.digest_offset = 0;
451198157Srrs
452198627Srrs			cmd->op.cksum_type = XLR_SEC_CKSUM_TYPE_NOP;
453198627Srrs			cmd->op.cksum_src = XLR_SEC_CKSUM_SRC_CIPHER;
454198627Srrs			cmd->op.cksum_offset = 0;
455198157Srrs
456198627Srrs			cmd->op.pkt_hmac = XLR_SEC_LOADHMACKEY_MODE_OLD;
457198627Srrs			cmd->op.pkt_hash = XLR_SEC_PADHASH_PAD;
458198627Srrs			cmd->op.pkt_hashbytes = XLR_SEC_HASHBYTES_ALL8;
459198627Srrs			cmd->op.pkt_next = XLR_SEC_NEXT_FINISH;
460198627Srrs			cmd->op.pkt_iv = XLR_SEC_PKT_IV_OLD;
461198627Srrs			cmd->op.pkt_lastword = XLR_SEC_LASTWORD_128;
462198157Srrs
463198627Srrs		default:
464198627Srrs			printf("currently not handled\n");
465198627Srrs		}
466198627Srrs	}
467198627Srrs	if (enccrd) {
468198627Srrs		cmd->enccrd = enccrd;
469198157Srrs
470198157Srrs#ifdef RMI_SEC_DEBUG
471198627Srrs		xlr_sec_print_data(crp);
472198157Srrs#endif
473198157Srrs
474198627Srrs		if (enccrd->crd_flags & CRD_F_ENCRYPT) {
475198627Srrs			cmd->op.cipher_op = XLR_SEC_CIPHER_OP_ENCRYPT;
476198627Srrs		} else
477198627Srrs			cmd->op.cipher_op = XLR_SEC_CIPHER_OP_DECRYPT;
478198157Srrs
479198627Srrs		switch (enccrd->crd_alg) {
480198627Srrs		case CRYPTO_DES_CBC:
481198627Srrs		case CRYPTO_3DES_CBC:
482198627Srrs			if (enccrd->crd_alg == CRYPTO_DES_CBC) {
483198627Srrs				cmd->op.cipher_type = XLR_SEC_CIPHER_TYPE_DES;
484198627Srrs				memcpy(&cmd->op.crypt_key[0], enccrd->crd_key, XLR_SEC_DES_KEY_LENGTH);
485198627Srrs			} else {
486198627Srrs				cmd->op.cipher_type = XLR_SEC_CIPHER_TYPE_3DES;
487212763Sjchandra				//if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT)
488212763Sjchandra				{
489212763Sjchandra					memcpy(&cmd->op.crypt_key[0], enccrd->crd_key,
490212763Sjchandra					    XLR_SEC_3DES_KEY_LENGTH);
491198627Srrs				}
492198627Srrs			}
493198157Srrs
494198627Srrs			cmd->op.cipher_mode = XLR_SEC_CIPHER_MODE_CBC;
495198627Srrs			cmd->op.cipher_init = XLR_SEC_CIPHER_INIT_NK;
496198627Srrs			cmd->op.cipher_offset = XLR_SEC_DES_IV_LENGTH;
497198157Srrs
498198627Srrs			cmd->op.digest_type = XLR_SEC_DIGEST_TYPE_NONE;
499198627Srrs			cmd->op.digest_init = XLR_SEC_DIGEST_INIT_OLDKEY;
500198627Srrs			cmd->op.digest_src = XLR_SEC_DIGEST_SRC_DMA;
501198627Srrs			cmd->op.digest_offset = 0;
502198157Srrs
503198627Srrs			cmd->op.cksum_type = XLR_SEC_CKSUM_TYPE_NOP;
504198627Srrs			cmd->op.cksum_src = XLR_SEC_CKSUM_SRC_CIPHER;
505198627Srrs			cmd->op.cksum_offset = 0;
506198157Srrs
507198627Srrs			cmd->op.pkt_hmac = XLR_SEC_LOADHMACKEY_MODE_OLD;
508198627Srrs			cmd->op.pkt_hash = XLR_SEC_PADHASH_PAD;
509198627Srrs			cmd->op.pkt_hashbytes = XLR_SEC_HASHBYTES_ALL8;
510198627Srrs			cmd->op.pkt_next = XLR_SEC_NEXT_FINISH;
511198627Srrs			cmd->op.pkt_iv = XLR_SEC_PKT_IV_NEW;
512198627Srrs			cmd->op.pkt_lastword = XLR_SEC_LASTWORD_128;
513198157Srrs
514198627Srrs			//if ((!(enccrd->crd_flags & CRD_F_IV_PRESENT)) &&
515212763Sjchandra			if ((enccrd->crd_flags & CRD_F_IV_EXPLICIT)) {
516212763Sjchandra				memcpy(&cmd->op.initial_vector[0], enccrd->crd_iv,
517212763Sjchandra				    XLR_SEC_DES_IV_LENGTH);
518212763Sjchandra			}
519198627Srrs			break;
520198157Srrs
521198627Srrs		case CRYPTO_AES_CBC:
522198627Srrs			if (enccrd->crd_alg == CRYPTO_AES_CBC) {
523198627Srrs				cmd->op.cipher_type = XLR_SEC_CIPHER_TYPE_AES128;
524212763Sjchandra				//if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT)
525212763Sjchandra				{
526212763Sjchandra					memcpy(&cmd->op.crypt_key[0], enccrd->crd_key,
527212763Sjchandra					    XLR_SEC_AES128_KEY_LENGTH);
528198627Srrs				}
529198627Srrs			}
530198627Srrs			cmd->op.cipher_mode = XLR_SEC_CIPHER_MODE_CBC;
531198627Srrs			cmd->op.cipher_init = XLR_SEC_CIPHER_INIT_NK;
532198627Srrs			cmd->op.cipher_offset = XLR_SEC_AES_BLOCK_SIZE;
533198157Srrs
534198627Srrs			cmd->op.digest_type = XLR_SEC_DIGEST_TYPE_NONE;
535198627Srrs			cmd->op.digest_init = XLR_SEC_DIGEST_INIT_OLDKEY;
536198627Srrs			cmd->op.digest_src = XLR_SEC_DIGEST_SRC_DMA;
537198627Srrs			cmd->op.digest_offset = 0;
538198157Srrs
539198627Srrs			cmd->op.cksum_type = XLR_SEC_CKSUM_TYPE_NOP;
540198627Srrs			cmd->op.cksum_src = XLR_SEC_CKSUM_SRC_CIPHER;
541198627Srrs			cmd->op.cksum_offset = 0;
542198157Srrs
543198627Srrs			cmd->op.pkt_hmac = XLR_SEC_LOADHMACKEY_MODE_OLD;
544198627Srrs			cmd->op.pkt_hash = XLR_SEC_PADHASH_PAD;
545198627Srrs			cmd->op.pkt_hashbytes = XLR_SEC_HASHBYTES_ALL8;
546198627Srrs			cmd->op.pkt_next = XLR_SEC_NEXT_FINISH;
547198627Srrs			cmd->op.pkt_iv = XLR_SEC_PKT_IV_NEW;
548198627Srrs			cmd->op.pkt_lastword = XLR_SEC_LASTWORD_128;
549198157Srrs
550198627Srrs			//if (!(enccrd->crd_flags & CRD_F_IV_PRESENT)) {
551212763Sjchandra			if ((enccrd->crd_flags & CRD_F_IV_EXPLICIT)) {
552212763Sjchandra				memcpy(&cmd->op.initial_vector[0], enccrd->crd_iv,
553212763Sjchandra				    XLR_SEC_AES_BLOCK_SIZE);
554198627Srrs			}
555212763Sjchandra			//}
556198627Srrs			break;
557198627Srrs		}
558198627Srrs	}
559198627Srrs	cmd->crp = crp;
560198627Srrs	cmd->session_num = session;
561198627Srrs	xlr_sec_setup(ses, cmd, (symkey_desc_pt) ses->desc_ptr);
562198157Srrs
563198627Srrs	return (0);
564198157Srrs
565198157Srrserrout:
566198627Srrs	if (cmd != NULL)
567198627Srrs		free(cmd, M_DEVBUF);
568198627Srrs	crp->crp_etype = err;
569198627Srrs	crypto_done(crp);
570198627Srrs	return (err);
571198157Srrs}
572