This source file includes following definitions.
- glxsb_match
- glxsb_attach
- glxsb_rnd
- glxsb_crypto_setup
- glxsb_crypto_newsession
- glxsb_crypto_freesession
- glxsb_aes
- glxsb_crypto_swauth
- glxsb_crypto_encdec
- glxsb_crypto_process
- glxsb_dma_alloc
- glxsb_dma_pre_op
- glxsb_dma_post_op
- glxsb_dma_free
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 #include <sys/cdefs.h>
27 #include <sys/param.h>
28 #include <sys/systm.h>
29 #include <sys/device.h>
30 #include <sys/malloc.h>
31 #include <sys/mbuf.h>
32 #include <sys/types.h>
33 #include <sys/timeout.h>
34
35 #include <machine/bus.h>
36 #include <machine/pctr.h>
37
38 #include <dev/rndvar.h>
39 #include <dev/pci/pcivar.h>
40 #include <dev/pci/pcidevs.h>
41
42 #ifdef CRYPTO
43 #include <crypto/cryptodev.h>
44 #include <crypto/rijndael.h>
45 #include <crypto/xform.h>
46 #include <crypto/cryptosoft.h>
47 #endif
48
49 #define SB_GLD_MSR_CAP 0x58002000
50 #define SB_GLD_MSR_CONFIG 0x58002001
51 #define SB_GLD_MSR_SMI 0x58002002
52 #define SB_GLD_MSR_ERROR 0x58002003
53 #define SB_GLD_MSR_PM 0x58002004
54 #define SB_GLD_MSR_DIAG 0x58002005
55 #define SB_GLD_MSR_CTRL 0x58002006
56
57
58 #define SB_GMC_DIV0 0x0000
59 #define SB_GMC_DIV1 0x0001
60 #define SB_GMC_DIV2 0x0002
61 #define SB_GMC_DIV3 0x0003
62 #define SB_GMC_DIV_MASK 0x0003
63 #define SB_GMC_SBI 0x0004
64 #define SB_GMC_SBY 0x0008
65 #define SB_GMC_TW 0x0010
66 #define SB_GMC_T_SEL0 0x0000
67 #define SB_GMC_T_SEL1 0x0100
68 #define SB_GMC_T_SEL2 0x0200
69 #define SB_GMC_T_SEL3 0x0300
70 #define SB_GMC_T_SEL_MASK 0x0300
71 #define SB_GMC_T_NE 0x0400
72 #define SB_GMC_T_TM 0x0800
73
74
75
76
77 #define SB_CTL_A 0x0000
78 #define SB_CTL_B 0x0004
79 #define SB_AES_INT 0x0008
80 #define SB_SOURCE_A 0x0010
81 #define SB_DEST_A 0x0014
82 #define SB_LENGTH_A 0x0018
83 #define SB_SOURCE_B 0x0020
84 #define SB_DEST_B 0x0024
85 #define SB_LENGTH_B 0x0028
86 #define SB_WKEY 0x0030
87 #define SB_WKEY_0 0x0030
88 #define SB_WKEY_1 0x0034
89 #define SB_WKEY_2 0x0038
90 #define SB_WKEY_3 0x003C
91 #define SB_CBC_IV 0x0040
92 #define SB_CBC_IV_0 0x0040
93 #define SB_CBC_IV_1 0x0044
94 #define SB_CBC_IV_2 0x0048
95 #define SB_CBC_IV_3 0x004C
96 #define SB_RANDOM_NUM 0x0050
97 #define SB_RANDOM_NUM_STATUS 0x0054
98 #define SB_EEPROM_COMM 0x0800
99 #define SB_EEPROM_ADDR 0x0804
100 #define SB_EEPROM_DATA 0x0808
101 #define SB_EEPROM_SEC_STATE 0x080C
102
103
104 #define SB_CTL_ST 0x0001
105 #define SB_CTL_ENC 0x0002
106 #define SB_CTL_DEC 0x0000
107 #define SB_CTL_WK 0x0004
108 #define SB_CTL_DC 0x0008
109 #define SB_CTL_SC 0x0010
110 #define SB_CTL_CBC 0x0020
111
112
113 #define SB_AI_DISABLE_AES_A 0x0001
114 #define SB_AI_ENABLE_AES_A 0x0000
115 #define SB_AI_DISABLE_AES_B 0x0002
116 #define SB_AI_ENABLE_AES_B 0x0000
117 #define SB_AI_DISABLE_EEPROM 0x0004
118 #define SB_AI_ENABLE_EEPROM 0x0000
119 #define SB_AI_AES_A_COMPLETE 0x0100
120 #define SB_AI_AES_B_COMPLETE 0x0200
121 #define SB_AI_EEPROM_COMPLETE 0x0400
122
123 #define SB_RNS_TRNG_VALID 0x0001
124
125 #define SB_MEM_SIZE 0x0810
126
127 #define SB_AES_ALIGN 0x0010
128
129 #define SB_AES_BLOCK_SIZE 0x0010
130
131
132
133
134
135
136
137
138
139
140 #define GLXSB_MAX_AES_LEN 16384
141
142 #ifdef CRYPTO
143 struct glxsb_dma_map {
144 bus_dmamap_t dma_map;
145 bus_dma_segment_t dma_seg;
146 int dma_nsegs;
147 int dma_size;
148 caddr_t dma_vaddr;
149 uint32_t dma_paddr;
150 };
151 struct glxsb_session {
152 uint32_t ses_key[4];
153 uint8_t ses_iv[SB_AES_BLOCK_SIZE];
154 int ses_klen;
155 int ses_used;
156 struct swcr_data *ses_swd;
157 };
158 #endif
159
160 struct glxsb_softc {
161 struct device sc_dev;
162 bus_space_tag_t sc_iot;
163 bus_space_handle_t sc_ioh;
164 struct timeout sc_to;
165
166 #ifdef CRYPTO
167 bus_dma_tag_t sc_dmat;
168 struct glxsb_dma_map sc_dma;
169 int32_t sc_cid;
170 int sc_nsessions;
171 struct glxsb_session *sc_sessions;
172 #endif
173 };
174
175 int glxsb_match(struct device *, void *, void *);
176 void glxsb_attach(struct device *, struct device *, void *);
177 void glxsb_rnd(void *);
178
179 struct cfattach glxsb_ca = {
180 sizeof(struct glxsb_softc), glxsb_match, glxsb_attach
181 };
182
183 struct cfdriver glxsb_cd = {
184 NULL, "glxsb", DV_DULL
185 };
186
187
188 #ifdef CRYPTO
189
190 #define GLXSB_SESSION(sid) ((sid) & 0x0fffffff)
191 #define GLXSB_SID(crd,ses) (((crd) << 28) | ((ses) & 0x0fffffff))
192
193 static struct glxsb_softc *glxsb_sc;
194 extern int i386_has_xcrypt;
195
196 int glxsb_crypto_setup(struct glxsb_softc *);
197 int glxsb_crypto_newsession(uint32_t *, struct cryptoini *);
198 int glxsb_crypto_process(struct cryptop *);
199 int glxsb_crypto_freesession(uint64_t);
200 static __inline void glxsb_aes(struct glxsb_softc *, uint32_t, uint32_t,
201 uint32_t, void *, int, void *);
202
203 int glxsb_dma_alloc(struct glxsb_softc *, int, struct glxsb_dma_map *);
204 void glxsb_dma_pre_op(struct glxsb_softc *, struct glxsb_dma_map *);
205 void glxsb_dma_post_op(struct glxsb_softc *, struct glxsb_dma_map *);
206 void glxsb_dma_free(struct glxsb_softc *, struct glxsb_dma_map *);
207
208 #endif
209
210
211 int
212 glxsb_match(struct device *parent, void *match, void *aux)
213 {
214 struct pci_attach_args *pa = aux;
215
216 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_AMD &&
217 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_GEODE_LX_CRYPTO)
218 return (1);
219
220 return (0);
221 }
222
223 void
224 glxsb_attach(struct device *parent, struct device *self, void *aux)
225 {
226 struct glxsb_softc *sc = (void *) self;
227 struct pci_attach_args *pa = aux;
228 bus_addr_t membase;
229 bus_size_t memsize;
230 uint64_t msr;
231 #ifdef CRYPTO
232 uint32_t intr;
233 #endif
234
235 msr = rdmsr(SB_GLD_MSR_CAP);
236 if ((msr & 0xFFFF00) != 0x130400) {
237 printf(": unknown ID 0x%x\n", (int) ((msr & 0xFFFF00) >> 16));
238 return;
239 }
240
241
242
243
244 if (pci_mapreg_map(pa, PCI_MAPREG_START,
245 PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, &sc->sc_iot,
246 &sc->sc_ioh, &membase, &memsize, SB_MEM_SIZE)) {
247 printf(": can't find mem space\n");
248 return;
249 }
250
251
252
253
254
255
256
257
258
259 msr = rdmsr(SB_GLD_MSR_CTRL);
260 msr &= ~(SB_GMC_T_TM | SB_GMC_T_SEL_MASK);
261 msr |= SB_GMC_T_NE | SB_GMC_T_SEL3;
262 #if 0
263 msr |= SB_GMC_SBI | SB_GMC_SBY;
264 #endif
265 wrmsr(SB_GLD_MSR_CTRL, msr);
266
267
268 timeout_set(&sc->sc_to, glxsb_rnd, sc);
269 glxsb_rnd(sc);
270 printf(": RNG");
271
272 #ifdef CRYPTO
273
274 intr = SB_AI_DISABLE_AES_A | SB_AI_DISABLE_AES_B |
275 SB_AI_DISABLE_EEPROM | SB_AI_AES_A_COMPLETE |
276 SB_AI_AES_B_COMPLETE | SB_AI_EEPROM_COMPLETE;
277 bus_space_write_4(sc->sc_iot, sc->sc_ioh, SB_AES_INT, intr);
278
279 sc->sc_dmat = pa->pa_dmat;
280
281 if (glxsb_crypto_setup(sc))
282 printf(" AES");
283 #endif
284
285 printf("\n");
286 }
287
288 void
289 glxsb_rnd(void *v)
290 {
291 struct glxsb_softc *sc = v;
292 uint32_t status, value;
293 extern int hz;
294
295 status = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SB_RANDOM_NUM_STATUS);
296 if (status & SB_RNS_TRNG_VALID) {
297 value = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SB_RANDOM_NUM);
298 add_true_randomness(value);
299 }
300
301 timeout_add(&sc->sc_to, (hz > 100) ? (hz / 100) : 1);
302 }
303
304 #ifdef CRYPTO
305 int
306 glxsb_crypto_setup(struct glxsb_softc *sc)
307 {
308 int algs[CRYPTO_ALGORITHM_MAX + 1];
309
310
311 if (glxsb_dma_alloc(sc, GLXSB_MAX_AES_LEN * 2, &sc->sc_dma) != 0)
312 return 0;
313
314 bzero(algs, sizeof(algs));
315 algs[CRYPTO_AES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED;
316 algs[CRYPTO_MD5_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
317 algs[CRYPTO_SHA1_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
318 algs[CRYPTO_RIPEMD160_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
319 algs[CRYPTO_SHA2_256_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
320 algs[CRYPTO_SHA2_384_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
321 algs[CRYPTO_SHA2_512_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
322
323 sc->sc_cid = crypto_get_driverid(0);
324 if (sc->sc_cid < 0)
325 return 0;
326
327 crypto_register(sc->sc_cid, algs, glxsb_crypto_newsession,
328 glxsb_crypto_freesession, glxsb_crypto_process);
329
330 sc->sc_nsessions = 0;
331
332 glxsb_sc = sc;
333
334 return 1;
335 }
336
337 int
338 glxsb_crypto_newsession(uint32_t *sidp, struct cryptoini *cri)
339 {
340 struct glxsb_softc *sc = glxsb_sc;
341 struct glxsb_session *ses = NULL;
342 struct auth_hash *axf;
343 struct cryptoini *c;
344 struct swcr_data *swd;
345 int sesn, i;
346
347 if (sc == NULL || sidp == NULL || cri == NULL)
348 return (EINVAL);
349
350 for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
351 if (sc->sc_sessions[sesn].ses_used == 0) {
352 ses = &sc->sc_sessions[sesn];
353 break;
354 }
355 }
356
357 if (ses == NULL) {
358 sesn = sc->sc_nsessions;
359 ses = malloc((sesn + 1) * sizeof(*ses), M_DEVBUF, M_NOWAIT);
360 if (ses == NULL)
361 return (ENOMEM);
362 if (sesn != 0) {
363 bcopy(sc->sc_sessions, ses, sesn * sizeof(*ses));
364 bzero(sc->sc_sessions, sesn * sizeof(*ses));
365 free(sc->sc_sessions, M_DEVBUF);
366 }
367 sc->sc_sessions = ses;
368 ses = &sc->sc_sessions[sesn];
369 sc->sc_nsessions++;
370 }
371
372 bzero(ses, sizeof(*ses));
373 ses->ses_used = 1;
374
375 for (c = cri; c != NULL; c = c->cri_next) {
376 switch (c->cri_alg) {
377 case CRYPTO_AES_CBC:
378 if (c->cri_klen != 128) {
379 glxsb_crypto_freesession(sesn);
380 return (EINVAL);
381 }
382
383 get_random_bytes(ses->ses_iv, sizeof(ses->ses_iv));
384 ses->ses_klen = c->cri_klen;
385
386
387 bcopy(c->cri_key, ses->ses_key, sizeof(ses->ses_key));
388 break;
389
390 case CRYPTO_MD5_HMAC:
391 axf = &auth_hash_hmac_md5_96;
392 goto authcommon;
393 case CRYPTO_SHA1_HMAC:
394 axf = &auth_hash_hmac_sha1_96;
395 goto authcommon;
396 case CRYPTO_RIPEMD160_HMAC:
397 axf = &auth_hash_hmac_ripemd_160_96;
398 goto authcommon;
399 case CRYPTO_SHA2_256_HMAC:
400 axf = &auth_hash_hmac_sha2_256_96;
401 goto authcommon;
402 case CRYPTO_SHA2_384_HMAC:
403 axf = &auth_hash_hmac_sha2_384_96;
404 goto authcommon;
405 case CRYPTO_SHA2_512_HMAC:
406 axf = &auth_hash_hmac_sha2_512_96;
407 authcommon:
408 MALLOC(swd, struct swcr_data *,
409 sizeof(struct swcr_data), M_CRYPTO_DATA,
410 M_NOWAIT);
411 if (swd == NULL) {
412 glxsb_crypto_freesession(sesn);
413 return (ENOMEM);
414 }
415 bzero(swd, sizeof(struct swcr_data));
416 ses->ses_swd = swd;
417
418 swd->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
419 M_NOWAIT);
420 if (swd->sw_ictx == NULL) {
421 glxsb_crypto_freesession(sesn);
422 return (ENOMEM);
423 }
424
425 swd->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA,
426 M_NOWAIT);
427 if (swd->sw_octx == NULL) {
428 glxsb_crypto_freesession(sesn);
429 return (ENOMEM);
430 }
431
432 for (i = 0; i < c->cri_klen / 8; i++)
433 c->cri_key[i] ^= HMAC_IPAD_VAL;
434
435 axf->Init(swd->sw_ictx);
436 axf->Update(swd->sw_ictx, c->cri_key, c->cri_klen / 8);
437 axf->Update(swd->sw_ictx, hmac_ipad_buffer,
438 HMAC_BLOCK_LEN - (c->cri_klen / 8));
439
440 for (i = 0; i < c->cri_klen / 8; i++)
441 c->cri_key[i] ^= (HMAC_IPAD_VAL ^
442 HMAC_OPAD_VAL);
443
444 axf->Init(swd->sw_octx);
445 axf->Update(swd->sw_octx, c->cri_key, c->cri_klen / 8);
446 axf->Update(swd->sw_octx, hmac_opad_buffer,
447 HMAC_BLOCK_LEN - (c->cri_klen / 8));
448
449 for (i = 0; i < c->cri_klen / 8; i++)
450 c->cri_key[i] ^= HMAC_OPAD_VAL;
451
452 swd->sw_axf = axf;
453 swd->sw_alg = c->cri_alg;
454
455 break;
456 default:
457 glxsb_crypto_freesession(sesn);
458 return (EINVAL);
459 }
460 }
461
462 *sidp = GLXSB_SID(0, sesn);
463 return (0);
464 }
465
466 int
467 glxsb_crypto_freesession(uint64_t tid)
468 {
469 struct glxsb_softc *sc = glxsb_sc;
470 struct swcr_data *swd;
471 struct auth_hash *axf;
472 int sesn;
473 uint32_t sid = ((uint32_t)tid) & 0xffffffff;
474
475 if (sc == NULL)
476 return (EINVAL);
477 sesn = GLXSB_SESSION(sid);
478 if (sesn >= sc->sc_nsessions)
479 return (EINVAL);
480 if (sc->sc_sessions[sesn].ses_swd) {
481 swd = sc->sc_sessions[sesn].ses_swd;
482 axf = swd->sw_axf;
483
484 if (swd->sw_ictx) {
485 bzero(swd->sw_ictx, axf->ctxsize);
486 free(swd->sw_ictx, M_CRYPTO_DATA);
487 }
488 if (swd->sw_octx) {
489 bzero(swd->sw_octx, axf->ctxsize);
490 free(swd->sw_octx, M_CRYPTO_DATA);
491 }
492 FREE(swd, M_CRYPTO_DATA);
493 }
494 bzero(&sc->sc_sessions[sesn], sizeof(sc->sc_sessions[sesn]));
495 return (0);
496 }
497
498
499
500
501 static __inline void
502 glxsb_aes(struct glxsb_softc *sc, uint32_t control, uint32_t psrc,
503 uint32_t pdst, void *key, int len, void *iv)
504 {
505 uint32_t status;
506 int i;
507
508 if (len & 0xF) {
509 printf("%s: len must be a multiple of 16 (not %d)\n",
510 sc->sc_dev.dv_xname, len);
511 return;
512 }
513
514
515 bus_space_write_4(sc->sc_iot, sc->sc_ioh, SB_SOURCE_A, psrc);
516
517
518 bus_space_write_4(sc->sc_iot, sc->sc_ioh, SB_DEST_A, pdst);
519
520
521 bus_space_write_4(sc->sc_iot, sc->sc_ioh, SB_LENGTH_A, len);
522
523
524 if (iv != NULL) {
525 bus_space_write_region_4(sc->sc_iot, sc->sc_ioh,
526 SB_CBC_IV, iv, 4);
527 control |= SB_CTL_CBC;
528 }
529
530
531 bus_space_write_region_4(sc->sc_iot, sc->sc_ioh, SB_WKEY, key, 4);
532
533
534 bus_space_write_4(sc->sc_iot, sc->sc_ioh, SB_CTL_A,
535 control | SB_CTL_WK | SB_CTL_DC | SB_CTL_SC | SB_CTL_ST);
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558 for (i = 0; i < GLXSB_MAX_AES_LEN * 10; i++) {
559 status = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SB_CTL_A);
560
561 if ((status & SB_CTL_ST) == 0)
562 return;
563 }
564
565 printf("%s: operation failed to complete\n", sc->sc_dev.dv_xname);
566 }
567
568 static int
569 glxsb_crypto_swauth(struct cryptop *crp, struct cryptodesc *crd,
570 struct swcr_data *sw, caddr_t buf)
571 {
572 int type;
573
574 if (crp->crp_flags & CRYPTO_F_IMBUF)
575 type = CRYPTO_BUF_MBUF;
576 else
577 type = CRYPTO_BUF_IOV;
578
579 return (swcr_authcompute(crp, crd, sw, buf, type));
580 }
581
582 static int
583 glxsb_crypto_encdec(struct cryptop *crp, struct cryptodesc *crd,
584 struct glxsb_session *ses, struct glxsb_softc *sc, caddr_t buf)
585 {
586 char *op_src, *op_dst;
587 uint32_t op_psrc, op_pdst;
588 uint8_t op_iv[SB_AES_BLOCK_SIZE], *piv;
589 int err = 0;
590 int len, tlen, xlen;
591 int offset;
592 uint32_t control;
593
594 if (crd == NULL || (crd->crd_len % SB_AES_BLOCK_SIZE) != 0) {
595 err = EINVAL;
596 goto out;
597 }
598
599
600 xlen = crd->crd_len > GLXSB_MAX_AES_LEN ?
601 GLXSB_MAX_AES_LEN : crd->crd_len;
602
603
604
605
606
607 op_src = sc->sc_dma.dma_vaddr;
608 op_dst = sc->sc_dma.dma_vaddr + xlen;
609
610 op_psrc = sc->sc_dma.dma_paddr;
611 op_pdst = sc->sc_dma.dma_paddr + xlen;
612
613 if (crd->crd_flags & CRD_F_ENCRYPT) {
614 control = SB_CTL_ENC;
615 if (crd->crd_flags & CRD_F_IV_EXPLICIT)
616 bcopy(crd->crd_iv, op_iv, sizeof(op_iv));
617 else
618 bcopy(ses->ses_iv, op_iv, sizeof(op_iv));
619
620 if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
621 if (crp->crp_flags & CRYPTO_F_IMBUF)
622 m_copyback((struct mbuf *)crp->crp_buf,
623 crd->crd_inject, sizeof(op_iv), op_iv);
624 else if (crp->crp_flags & CRYPTO_F_IOV)
625 cuio_copyback((struct uio *)crp->crp_buf,
626 crd->crd_inject, sizeof(op_iv), op_iv);
627 else
628 bcopy(op_iv,
629 crp->crp_buf + crd->crd_inject, sizeof(op_iv));
630 }
631 } else {
632 control = SB_CTL_DEC;
633 if (crd->crd_flags & CRD_F_IV_EXPLICIT)
634 bcopy(crd->crd_iv, op_iv, sizeof(op_iv));
635 else {
636 if (crp->crp_flags & CRYPTO_F_IMBUF)
637 m_copydata((struct mbuf *)crp->crp_buf,
638 crd->crd_inject, sizeof(op_iv), op_iv);
639 else if (crp->crp_flags & CRYPTO_F_IOV)
640 cuio_copydata((struct uio *)crp->crp_buf,
641 crd->crd_inject, sizeof(op_iv), op_iv);
642 else
643 bcopy(crp->crp_buf + crd->crd_inject,
644 op_iv, sizeof(op_iv));
645 }
646 }
647
648 offset = 0;
649 tlen = crd->crd_len;
650 piv = op_iv;
651
652
653 while (tlen > 0) {
654 len = (tlen > GLXSB_MAX_AES_LEN) ? GLXSB_MAX_AES_LEN : tlen;
655
656 if (crp->crp_flags & CRYPTO_F_IMBUF)
657 m_copydata((struct mbuf *)crp->crp_buf,
658 crd->crd_skip + offset, len, op_src);
659 else if (crp->crp_flags & CRYPTO_F_IOV)
660 cuio_copydata((struct uio *)crp->crp_buf,
661 crd->crd_skip + offset, len, op_src);
662 else
663 bcopy(crp->crp_buf + crd->crd_skip + offset, op_src,
664 len);
665
666 glxsb_dma_pre_op(sc, &sc->sc_dma);
667
668 glxsb_aes(sc, control, op_psrc, op_pdst, ses->ses_key,
669 len, op_iv);
670
671 glxsb_dma_post_op(sc, &sc->sc_dma);
672
673 if (crp->crp_flags & CRYPTO_F_IMBUF)
674 m_copyback((struct mbuf *)crp->crp_buf,
675 crd->crd_skip + offset, len, op_dst);
676 else if (crp->crp_flags & CRYPTO_F_IOV)
677 cuio_copyback((struct uio *)crp->crp_buf,
678 crd->crd_skip + offset, len, op_dst);
679 else
680 bcopy(op_dst, crp->crp_buf + crd->crd_skip + offset,
681 len);
682
683 offset += len;
684 tlen -= len;
685
686 if (tlen <= 0) {
687
688 piv = ses->ses_iv;
689 }
690
691
692
693
694
695
696
697
698 if (crd->crd_flags & CRD_F_ENCRYPT) {
699 bcopy(op_dst + len - sizeof(op_iv), piv, sizeof(op_iv));
700 } else {
701
702 if (tlen > 0) {
703 bcopy(op_src + len - sizeof(op_iv), piv,
704 sizeof(op_iv));
705 }
706 }
707 }
708
709
710 bzero(sc->sc_dma.dma_vaddr, xlen * 2);
711
712 out:
713 return (err);
714 }
715
716 int
717 glxsb_crypto_process(struct cryptop *crp)
718 {
719 struct glxsb_softc *sc = glxsb_sc;
720 struct glxsb_session *ses;
721 struct cryptodesc *crd;
722 int sesn,err = 0;
723 int s;
724
725 s = splnet();
726
727 if (crp == NULL || crp->crp_callback == NULL) {
728 err = EINVAL;
729 goto out;
730 }
731 crd = crp->crp_desc;
732 if (crd == NULL) {
733 err = EINVAL;
734 goto out;
735 }
736
737 sesn = GLXSB_SESSION(crp->crp_sid);
738 if (sesn >= sc->sc_nsessions) {
739 err = EINVAL;
740 goto out;
741 }
742 ses = &sc->sc_sessions[sesn];
743
744 for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
745 switch (crd->crd_alg) {
746 case CRYPTO_AES_CBC:
747 if ((err = glxsb_crypto_encdec(crp, crd, ses, sc,
748 crp->crp_buf)) != 0)
749 goto out;
750 break;
751
752 case CRYPTO_MD5_HMAC:
753 case CRYPTO_SHA1_HMAC:
754 case CRYPTO_RIPEMD160_HMAC:
755 case CRYPTO_SHA2_256_HMAC:
756 case CRYPTO_SHA2_384_HMAC:
757 case CRYPTO_SHA2_512_HMAC:
758 if ((err = glxsb_crypto_swauth(crp, crd, ses->ses_swd,
759 crp->crp_buf)) != 0)
760 goto out;
761 break;
762
763 default:
764 err = EINVAL;
765 goto out;
766 }
767 }
768
769 out:
770 crp->crp_etype = err;
771 crypto_done(crp);
772 splx(s);
773 return (err);
774 }
775
776 int
777 glxsb_dma_alloc(struct glxsb_softc *sc, int size, struct glxsb_dma_map *dma)
778 {
779 int rc;
780
781 dma->dma_nsegs = 1;
782 dma->dma_size = size;
783
784 rc = bus_dmamap_create(sc->sc_dmat, size, dma->dma_nsegs, size,
785 0, BUS_DMA_NOWAIT, &dma->dma_map);
786 if (rc != 0) {
787 printf("%s: couldn't create DMA map for %d bytes (%d)\n",
788 sc->sc_dev.dv_xname, size, rc);
789
790 goto fail0;
791 }
792
793 rc = bus_dmamem_alloc(sc->sc_dmat, size, SB_AES_ALIGN, 0,
794 &dma->dma_seg, dma->dma_nsegs, &dma->dma_nsegs, BUS_DMA_NOWAIT);
795 if (rc != 0) {
796 printf("%s: couldn't allocate DMA memory of %d bytes (%d)\n",
797 sc->sc_dev.dv_xname, size, rc);
798
799 goto fail1;
800 }
801
802 rc = bus_dmamem_map(sc->sc_dmat, &dma->dma_seg, 1, size,
803 &dma->dma_vaddr, BUS_DMA_NOWAIT);
804 if (rc != 0) {
805 printf("%s: couldn't map DMA memory for %d bytes (%d)\n",
806 sc->sc_dev.dv_xname, size, rc);
807
808 goto fail2;
809 }
810
811 rc = bus_dmamap_load(sc->sc_dmat, dma->dma_map, dma->dma_vaddr,
812 size, NULL, BUS_DMA_NOWAIT);
813 if (rc != 0) {
814 printf("%s: couldn't load DMA memory for %d bytes (%d)\n",
815 sc->sc_dev.dv_xname, size, rc);
816
817 goto fail3;
818 }
819
820 dma->dma_paddr = dma->dma_map->dm_segs[0].ds_addr;
821
822 return 0;
823
824 fail3:
825 bus_dmamem_unmap(sc->sc_dmat, dma->dma_vaddr, size);
826 fail2:
827 bus_dmamem_free(sc->sc_dmat, &dma->dma_seg, dma->dma_nsegs);
828 fail1:
829 bus_dmamap_destroy(sc->sc_dmat, dma->dma_map);
830 fail0:
831 return rc;
832 }
833
834 void
835 glxsb_dma_pre_op(struct glxsb_softc *sc, struct glxsb_dma_map *dma)
836 {
837 bus_dmamap_sync(sc->sc_dmat, dma->dma_map, 0, dma->dma_size,
838 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
839 }
840
841 void
842 glxsb_dma_post_op(struct glxsb_softc *sc, struct glxsb_dma_map *dma)
843 {
844 bus_dmamap_sync(sc->sc_dmat, dma->dma_map, 0, dma->dma_size,
845 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
846 }
847
848 void
849 glxsb_dma_free(struct glxsb_softc *sc, struct glxsb_dma_map *dma)
850 {
851 bus_dmamap_unload(sc->sc_dmat, dma->dma_map);
852 bus_dmamem_unmap(sc->sc_dmat, dma->dma_vaddr, dma->dma_size);
853 bus_dmamem_free(sc->sc_dmat, &dma->dma_seg, dma->dma_nsegs);
854 bus_dmamap_destroy(sc->sc_dmat, dma->dma_map);
855 }
856
857 #endif