4 *
5 * The contents of this file are subject to the terms of the
6 * Common Development and Distribution License (the "License").
7 * You may not use this file except in compliance with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22
23 /*
24 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 */
27
28 #pragma ident "%Z%%M% %I% %E% SMI"
29
30 /*
31 * Deimos - cryptographic acceleration based upon Broadcom 582x.
32 */
33
34 #include <sys/types.h>
35 #include <sys/ddi.h>
36 #include <sys/sunddi.h>
37 #include <sys/kmem.h>
38 #include <sys/note.h>
39 #include <sys/crypto/common.h>
40 #include <sys/crypto/spi.h>
41 #include <sys/crypto/dca.h>
42
43 /*
44 * 3DES implementation.
45 */
46
47 static int dca_3desstart(dca_t *, uint32_t, dca_request_t *);
48 static void dca_3desdone(dca_request_t *, int);
49
50
51 int
52 dca_3des(crypto_ctx_t *ctx, crypto_data_t *in,
53 crypto_data_t *out, crypto_req_handle_t req, int flags)
54 {
55 int len;
56 int rv;
57 dca_request_t *reqp = ctx->cc_provider_private;
58 dca_request_t *des_ctx = ctx->cc_provider_private;
59 dca_t *dca = ctx->cc_provider;
60 crypto_data_t *nin = &reqp->dr_ctx.in_dup;
61
62 len = dca_length(in);
63 if (len % DESBLOCK) {
64 DBG(dca, DWARN, "input not an integral number of DES blocks");
65 (void) dca_free_context(ctx);
66 if (flags & DR_DECRYPT) {
67 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
68 } else {
69 return (CRYPTO_DATA_LEN_RANGE);
70 }
71 }
72
73 /*
74 * If cd_miscdata non-null then this contains the IV.
75 */
76 if (in->cd_miscdata != NULL) {
77 uchar_t *p = (uchar_t *)in->cd_miscdata;
78 des_ctx->dr_ctx.iv[0] = p[0]<<24 | p[1]<<16 | p[2]<<8 | p[3];
79 des_ctx->dr_ctx.iv[1] = p[4]<<24 | p[5]<<16 | p[6]<<8 | p[7];
80 }
81
82 if (len > dca_length(out)) {
83 DBG(dca, DWARN, "inadequate output space (need %d, got %d)",
84 len, dca_length(out));
85 out->cd_length = len;
86 /* Do not free the context since the app will call again */
87 return (CRYPTO_BUFFER_TOO_SMALL);
88 }
89
90 if ((rv = dca_verifyio(in, out)) != CRYPTO_SUCCESS) {
91 (void) dca_free_context(ctx);
92 return (rv);
93 }
94
95 /* special handling for null-sized input buffers */
96 if (len == 0) {
97 out->cd_length = 0;
98 (void) dca_free_context(ctx);
99 return (CRYPTO_SUCCESS);
151
152 int
153 dca_3desupdate(crypto_ctx_t *ctx, crypto_data_t *in,
154 crypto_data_t *out, crypto_req_handle_t req, int flags)
155 {
156 int len;
157 int rawlen;
158 int rv;
159 dca_request_t *reqp = ctx->cc_provider_private;
160 dca_request_t *des_ctx = ctx->cc_provider_private;
161 dca_t *dca = ctx->cc_provider;
162 crypto_data_t *nin = &reqp->dr_ctx.in_dup;
163
164 rawlen = dca_length(in) + des_ctx->dr_ctx.residlen;
165
166 len = ROUNDDOWN(rawlen, DESBLOCK);
167 /*
168 * If cd_miscdata non-null then this contains the IV.
169 */
170 if (in->cd_miscdata != NULL) {
171 uchar_t *p = (uchar_t *)in->cd_miscdata;
172 des_ctx->dr_ctx.iv[0] = p[0]<<24 | p[1]<<16 | p[2]<<8 | p[3];
173 des_ctx->dr_ctx.iv[1] = p[4]<<24 | p[5]<<16 | p[6]<<8 | p[7];
174 }
175
176 if (len > dca_length(out)) {
177 DBG(dca, DWARN, "not enough output space (need %d, got %d)",
178 len, dca_length(out));
179 out->cd_length = len;
180 /* Do not free the context since the app will call again */
181 return (CRYPTO_BUFFER_TOO_SMALL);
182 }
183
184 if ((rv = dca_verifyio(in, out)) != CRYPTO_SUCCESS) {
185 (void) dca_free_context(ctx);
186 return (rv);
187 }
188
189 reqp->dr_kcf_req = req;
190
191 /*
192 * From here on out, we are committed.
193 */
375 * 3) likewise for out
376 * 4) there is enough space in the output
377 * 5) we perform a block for block encrypt
378 */
379 len = ctx->dr_ctx.activeresidlen + dca_length(in);
380 len = ROUNDDOWN(min(len, MAXPACKET), DESBLOCK);
381 reqp->dr_pkt_length = (uint16_t)len;
382
383 /* collect IVs for this pass */
384 iv[0] = ctx->dr_ctx.iv[0];
385 iv[1] = ctx->dr_ctx.iv[1];
386
387 /*
388 * And also, for decrypt, collect the IV for the next pass. For
389 * decrypt, the IV must be collected BEFORE decryption, or else
390 * we will lose it. (For encrypt, we grab the IV AFTER encryption,
391 * in dca_3desdone.
392 */
393 if (flags & DR_DECRYPT) {
394 uchar_t ivstore[DESBLOCK];
395 uchar_t *ivp = ivstore;
396
397 /* get last 8 bytes of ciphertext for IV of next op */
398 /*
399 * If we're processing only a DESBLOCKS worth of data
400 * and there is active residual present then it will be
401 * needed for the IV also.
402 */
403 if ((len == DESBLOCK) && ctx->dr_ctx.activeresidlen) {
404 /* Bring the active residual into play */
405 bcopy(ctx->dr_ctx.activeresid, ivstore,
406 ctx->dr_ctx.activeresidlen);
407 rv = dca_getbufbytes(in, 0,
408 DESBLOCK - ctx->dr_ctx.activeresidlen,
409 ivstore + ctx->dr_ctx.activeresidlen);
410 } else {
411 rv = dca_getbufbytes(in,
412 len - DESBLOCK - ctx->dr_ctx.activeresidlen,
413 DESBLOCK, ivstore);
414 }
415
416 if (rv != CRYPTO_SUCCESS) {
417 DBG(dca, DWARN,
418 "dca_3desstart: dca_getbufbytes() failed");
419 return (rv);
420 }
421
422 /* store as a pair of native 32-bit values */
423 ctx->dr_ctx.iv[0] =
424 ivp[0]<<24 | ivp[1]<<16 | ivp[2]<<8 | ivp[3];
425 ctx->dr_ctx.iv[1] =
426 ivp[4]<<24 | ivp[5]<<16 | ivp[6]<<8 | ivp[7];
427 }
428
429 /* For now we force a pullup. Add direct DMA later. */
430 reqp->dr_flags &= ~(DR_SCATTER | DR_GATHER);
431 if ((len < dca_mindma) || (ctx->dr_ctx.activeresidlen > 0) ||
432 dca_sgcheck(dca, reqp->dr_in, DCA_SG_CONTIG) ||
433 dca_sgcheck(dca, reqp->dr_out, DCA_SG_WALIGN)) {
434 reqp->dr_flags |= DR_SCATTER | DR_GATHER;
435 }
436
437 /* Try to do direct DMA. */
438 if (!(reqp->dr_flags & (DR_SCATTER | DR_GATHER))) {
439 if (dca_bindchains(reqp, len, len) == DDI_SUCCESS) {
440 reqp->dr_in->cd_offset += len;
441 reqp->dr_in->cd_length -= len;
442 } else {
443 DBG(dca, DWARN,
444 "dca_3desstart: dca_bindchains() failed");
445 return (CRYPTO_DEVICE_ERROR);
446 }
533 errno = dca_scatter(reqp->dr_obuf_kaddr,
534 reqp->dr_out, reqp->dr_out_len, 0);
535 if (errno != CRYPTO_SUCCESS) {
536 DBG(NULL, DWARN,
537 "dca_3desdone: dca_scatter() failed");
538 goto errout;
539 }
540
541 } else {
542 /* we've processed some more data */
543 out->cd_length += reqp->dr_pkt_length;
544 }
545
546
547 /*
548 * For encryption only, we have to grab the IV for the
549 * next pass AFTER encryption.
550 */
551 if (reqp->dr_flags & DR_ENCRYPT) {
552 uchar_t ivstore[DESBLOCK];
553 uchar_t *iv = ivstore;
554
555 /* get last 8 bytes for IV of next op */
556 errno = dca_getbufbytes(out, off, DESBLOCK, iv);
557 if (errno != CRYPTO_SUCCESS) {
558 DBG(NULL, DWARN,
559 "dca_3desdone: dca_getbufbytes() failed");
560 goto errout;
561 }
562 /* store as a pair of native 32-bit values */
563 ctx->dr_ctx.iv[0] =
564 iv[0]<<24 | iv[1]<<16 | iv[2]<<8 | iv[3];
565 ctx->dr_ctx.iv[1] =
566 iv[4]<<24 | iv[5]<<16 | iv[6]<<8 | iv[7];
567 }
568
569 /*
570 * If there is more to do, then reschedule another
571 * pass.
572 */
573 if (dca_length(reqp->dr_in) >= 8) {
574 errno = dca_3desstart(reqp->dr_dca, reqp->dr_flags,
575 reqp);
576 if (errno == CRYPTO_QUEUED) {
577 return;
578 }
579 }
580 }
581
582 errout:
583
584 /*
585 * If this is an atomic operation perform the final function
586 * tasks (equivalent to to dca_3desfinal()).
606
607 /* This has to be done after notifing the framework */
608 if (reqp->dr_ctx.atomic) {
609 reqp->dr_context = NULL;
610 reqp->dr_ctx.atomic = 0;
611 reqp->dr_ctx.ctx_cm_type = 0;
612 if (reqp->destroy)
613 dca_destroyreq(reqp);
614 else
615 dca_freereq(reqp);
616 }
617 }
618
619 /* ARGSUSED */
620 int
621 dca_3desctxinit(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
622 crypto_key_t *key, int kmflag, int flags)
623 {
624 dca_request_t *des_ctx;
625 dca_t *dca = ctx->cc_provider;
626 uchar_t *param;
627 uchar_t *value;
628 size_t paramsz;
629 unsigned len;
630 int i, j;
631
632 paramsz = mechanism->cm_param_len;
633 param = (uchar_t *)mechanism->cm_param;
634 if ((paramsz != 0) && (paramsz != DES_IV_LEN)) {
635 DBG(NULL, DWARN,
636 "dca_3desctxinit: parameter(IV) length not %d (%d)",
637 DES_IV_LEN, paramsz);
638 return (CRYPTO_MECHANISM_PARAM_INVALID);
639 }
640
641 if ((des_ctx = dca_getreq(dca, MCR1, 1)) == NULL) {
642 dca_error(dca, "unable to allocate request for 3DES");
643 return (CRYPTO_HOST_MEMORY);
644 }
645 /*
646 * Identify and store the IV as a pair of native 32-bit words.
647 *
648 * If cm_param == NULL then the IV comes from the cd_miscdata field
649 * in the crypto_data structure.
650 */
651 if (param != NULL) {
652 ASSERT(paramsz == DES_IV_LEN);
653 des_ctx->dr_ctx.iv[0] = param[0]<<24 | param[1]<<16 |
654 param[2]<<8 | param[3];
655 des_ctx->dr_ctx.iv[1] = param[4]<<24 | param[5]<<16 |
656 param[6]<<8 | param[7];
657 }
658 des_ctx->dr_ctx.residlen = 0;
659 des_ctx->dr_ctx.activeresidlen = 0;
660 des_ctx->dr_ctx.ctx_cm_type = mechanism->cm_type;
661 ctx->cc_provider_private = des_ctx;
662
663 if (key->ck_format != CRYPTO_KEY_RAW) {
664 DBG(NULL, DWARN,
665 "dca_3desctxinit: only raw crypto key type support with DES/3DES");
666 dca_3desctxfree(ctx);
667 return (CRYPTO_KEY_TYPE_INCONSISTENT);
668 }
669
670 len = key->ck_length;
671 value = (uchar_t *)key->ck_data;
672
673 if (flags & DR_TRIPLE) {
674 /* 3DES */
675 switch (len) {
676 case 192:
692 des_ctx->dr_ctx.key[i] |= *value;
693 value++;
694 }
695 }
696 des_ctx->dr_ctx.key[4] = des_ctx->dr_ctx.key[0];
697 des_ctx->dr_ctx.key[5] = des_ctx->dr_ctx.key[1];
698 break;
699
700 default:
701 DBG(NULL, DWARN, "Incorrect 3DES keysize (%d)", len);
702 dca_3desctxfree(ctx);
703 return (CRYPTO_KEY_SIZE_RANGE);
704 }
705 } else {
706 /* single DES */
707 if (len != 64) {
708 DBG(NULL, DWARN, "Incorrect DES keysize (%d)", len);
709 dca_3desctxfree(ctx);
710 return (CRYPTO_KEY_SIZE_RANGE);
711 }
712 des_ctx->dr_ctx.key[0] =
713 value[0]<<24 | value[1]<<16 | value[2]<<8 | value[3];
714 des_ctx->dr_ctx.key[1] =
715 value[4]<<24 | value[5]<<16 | value[6]<<8 | value[7];
716 /* for single des just repeat des key */
717 des_ctx->dr_ctx.key[4] =
718 des_ctx->dr_ctx.key[2] = des_ctx->dr_ctx.key[0];
719 des_ctx->dr_ctx.key[5] =
720 des_ctx->dr_ctx.key[3] = des_ctx->dr_ctx.key[1];
721 }
722
723 /*
724 * Setup the context here so that we do not need to setup it up
725 * for every update
726 */
727 PUTCTX16(des_ctx, CTX_LENGTH, CTX_3DES_LENGTH);
728 PUTCTX16(des_ctx, CTX_CMD, CMD_3DES);
729 PUTCTX32(des_ctx, CTX_3DESDIRECTION,
730 flags & DR_ENCRYPT ? CTX_3DES_ENCRYPT : CTX_3DES_DECRYPT);
731 PUTCTX32(des_ctx, CTX_3DESKEY1HI, des_ctx->dr_ctx.key[0]);
732 PUTCTX32(des_ctx, CTX_3DESKEY1LO, des_ctx->dr_ctx.key[1]);
733 PUTCTX32(des_ctx, CTX_3DESKEY2HI, des_ctx->dr_ctx.key[2]);
734 PUTCTX32(des_ctx, CTX_3DESKEY2LO, des_ctx->dr_ctx.key[3]);
735 PUTCTX32(des_ctx, CTX_3DESKEY3HI, des_ctx->dr_ctx.key[4]);
|
4 *
5 * The contents of this file are subject to the terms of the
6 * Common Development and Distribution License (the "License").
7 * You may not use this file except in compliance with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22
23 /*
24 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 */
27
28 /*
29 * Deimos - cryptographic acceleration based upon Broadcom 582x.
30 */
31
32 #include <sys/types.h>
33 #include <sys/ddi.h>
34 #include <sys/sunddi.h>
35 #include <sys/kmem.h>
36 #include <sys/note.h>
37 #include <sys/crypto/common.h>
38 #include <sys/crypto/spi.h>
39 #include <sys/crypto/dca.h>
40
41 #if defined(__i386) || defined(__amd64)
42 #include <sys/byteorder.h>
43 #define UNALIGNED_POINTERS_PERMITTED
44 #endif
45
46 /*
47 * 3DES implementation.
48 */
49
50 static int dca_3desstart(dca_t *, uint32_t, dca_request_t *);
51 static void dca_3desdone(dca_request_t *, int);
52
53
54 int
55 dca_3des(crypto_ctx_t *ctx, crypto_data_t *in,
56 crypto_data_t *out, crypto_req_handle_t req, int flags)
57 {
58 int len;
59 int rv;
60 dca_request_t *reqp = ctx->cc_provider_private;
61 dca_request_t *des_ctx = ctx->cc_provider_private;
62 dca_t *dca = ctx->cc_provider;
63 crypto_data_t *nin = &reqp->dr_ctx.in_dup;
64
65 len = dca_length(in);
66 if (len % DESBLOCK) {
67 DBG(dca, DWARN, "input not an integral number of DES blocks");
68 (void) dca_free_context(ctx);
69 if (flags & DR_DECRYPT) {
70 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
71 } else {
72 return (CRYPTO_DATA_LEN_RANGE);
73 }
74 }
75
76 /*
77 * If cd_miscdata non-null then this contains the IV.
78 */
79 if (in->cd_miscdata != NULL) {
80 #ifdef UNALIGNED_POINTERS_PERMITTED
81 uint32_t *p = (uint32_t *)in->cd_miscdata;
82 des_ctx->dr_ctx.iv[0] = htonl(p[0]);
83 des_ctx->dr_ctx.iv[1] = htonl(p[1]);
84 #else
85 uchar_t *p = (uchar_t *)in->cd_miscdata;
86 des_ctx->dr_ctx.iv[0] = p[0]<<24 | p[1]<<16 | p[2]<<8 | p[3];
87 des_ctx->dr_ctx.iv[1] = p[4]<<24 | p[5]<<16 | p[6]<<8 | p[7];
88 #endif /* UNALIGNED_POINTERS_PERMITTED */
89 }
90
91 if (len > dca_length(out)) {
92 DBG(dca, DWARN, "inadequate output space (need %d, got %d)",
93 len, dca_length(out));
94 out->cd_length = len;
95 /* Do not free the context since the app will call again */
96 return (CRYPTO_BUFFER_TOO_SMALL);
97 }
98
99 if ((rv = dca_verifyio(in, out)) != CRYPTO_SUCCESS) {
100 (void) dca_free_context(ctx);
101 return (rv);
102 }
103
104 /* special handling for null-sized input buffers */
105 if (len == 0) {
106 out->cd_length = 0;
107 (void) dca_free_context(ctx);
108 return (CRYPTO_SUCCESS);
160
161 int
162 dca_3desupdate(crypto_ctx_t *ctx, crypto_data_t *in,
163 crypto_data_t *out, crypto_req_handle_t req, int flags)
164 {
165 int len;
166 int rawlen;
167 int rv;
168 dca_request_t *reqp = ctx->cc_provider_private;
169 dca_request_t *des_ctx = ctx->cc_provider_private;
170 dca_t *dca = ctx->cc_provider;
171 crypto_data_t *nin = &reqp->dr_ctx.in_dup;
172
173 rawlen = dca_length(in) + des_ctx->dr_ctx.residlen;
174
175 len = ROUNDDOWN(rawlen, DESBLOCK);
176 /*
177 * If cd_miscdata non-null then this contains the IV.
178 */
179 if (in->cd_miscdata != NULL) {
180 #ifdef UNALIGNED_POINTERS_PERMITTED
181 uint32_t *p = (uint32_t *)in->cd_miscdata;
182 des_ctx->dr_ctx.iv[0] = htonl(p[0]);
183 des_ctx->dr_ctx.iv[1] = htonl(p[1]);
184 #else
185 uchar_t *p = (uchar_t *)in->cd_miscdata;
186 des_ctx->dr_ctx.iv[0] = p[0]<<24 | p[1]<<16 | p[2]<<8 | p[3];
187 des_ctx->dr_ctx.iv[1] = p[4]<<24 | p[5]<<16 | p[6]<<8 | p[7];
188 #endif /* UNALIGNED_POINTERS_PERMITTED */
189 }
190
191 if (len > dca_length(out)) {
192 DBG(dca, DWARN, "not enough output space (need %d, got %d)",
193 len, dca_length(out));
194 out->cd_length = len;
195 /* Do not free the context since the app will call again */
196 return (CRYPTO_BUFFER_TOO_SMALL);
197 }
198
199 if ((rv = dca_verifyio(in, out)) != CRYPTO_SUCCESS) {
200 (void) dca_free_context(ctx);
201 return (rv);
202 }
203
204 reqp->dr_kcf_req = req;
205
206 /*
207 * From here on out, we are committed.
208 */
390 * 3) likewise for out
391 * 4) there is enough space in the output
392 * 5) we perform a block for block encrypt
393 */
394 len = ctx->dr_ctx.activeresidlen + dca_length(in);
395 len = ROUNDDOWN(min(len, MAXPACKET), DESBLOCK);
396 reqp->dr_pkt_length = (uint16_t)len;
397
398 /* collect IVs for this pass */
399 iv[0] = ctx->dr_ctx.iv[0];
400 iv[1] = ctx->dr_ctx.iv[1];
401
402 /*
403 * And also, for decrypt, collect the IV for the next pass. For
404 * decrypt, the IV must be collected BEFORE decryption, or else
405 * we will lose it. (For encrypt, we grab the IV AFTER encryption,
406 * in dca_3desdone.
407 */
408 if (flags & DR_DECRYPT) {
409 uchar_t ivstore[DESBLOCK];
410 #ifdef UNALIGNED_POINTERS_PERMITTED
411 uint32_t *ivp = (uint32_t *)ivstore;
412 #else
413 uchar_t *ivp = ivstore;
414 #endif /* UNALIGNED_POINTERS_PERMITTED */
415
416 /* get last 8 bytes of ciphertext for IV of next op */
417 /*
418 * If we're processing only a DESBLOCKS worth of data
419 * and there is active residual present then it will be
420 * needed for the IV also.
421 */
422 if ((len == DESBLOCK) && ctx->dr_ctx.activeresidlen) {
423 /* Bring the active residual into play */
424 bcopy(ctx->dr_ctx.activeresid, ivstore,
425 ctx->dr_ctx.activeresidlen);
426 rv = dca_getbufbytes(in, 0,
427 DESBLOCK - ctx->dr_ctx.activeresidlen,
428 ivstore + ctx->dr_ctx.activeresidlen);
429 } else {
430 rv = dca_getbufbytes(in,
431 len - DESBLOCK - ctx->dr_ctx.activeresidlen,
432 DESBLOCK, ivstore);
433 }
434
435 if (rv != CRYPTO_SUCCESS) {
436 DBG(dca, DWARN,
437 "dca_3desstart: dca_getbufbytes() failed");
438 return (rv);
439 }
440
441 /* store as a pair of native 32-bit values */
442 #ifdef UNALIGNED_POINTERS_PERMITTED
443 ctx->dr_ctx.iv[0] = htonl(ivp[0]);
444 ctx->dr_ctx.iv[1] = htonl(ivp[1]);
445 #else
446 ctx->dr_ctx.iv[0] =
447 ivp[0]<<24 | ivp[1]<<16 | ivp[2]<<8 | ivp[3];
448 ctx->dr_ctx.iv[1] =
449 ivp[4]<<24 | ivp[5]<<16 | ivp[6]<<8 | ivp[7];
450 #endif /* UNALIGNED_POINTERS_PERMITTED */
451 }
452
453 /* For now we force a pullup. Add direct DMA later. */
454 reqp->dr_flags &= ~(DR_SCATTER | DR_GATHER);
455 if ((len < dca_mindma) || (ctx->dr_ctx.activeresidlen > 0) ||
456 dca_sgcheck(dca, reqp->dr_in, DCA_SG_CONTIG) ||
457 dca_sgcheck(dca, reqp->dr_out, DCA_SG_WALIGN)) {
458 reqp->dr_flags |= DR_SCATTER | DR_GATHER;
459 }
460
461 /* Try to do direct DMA. */
462 if (!(reqp->dr_flags & (DR_SCATTER | DR_GATHER))) {
463 if (dca_bindchains(reqp, len, len) == DDI_SUCCESS) {
464 reqp->dr_in->cd_offset += len;
465 reqp->dr_in->cd_length -= len;
466 } else {
467 DBG(dca, DWARN,
468 "dca_3desstart: dca_bindchains() failed");
469 return (CRYPTO_DEVICE_ERROR);
470 }
557 errno = dca_scatter(reqp->dr_obuf_kaddr,
558 reqp->dr_out, reqp->dr_out_len, 0);
559 if (errno != CRYPTO_SUCCESS) {
560 DBG(NULL, DWARN,
561 "dca_3desdone: dca_scatter() failed");
562 goto errout;
563 }
564
565 } else {
566 /* we've processed some more data */
567 out->cd_length += reqp->dr_pkt_length;
568 }
569
570
571 /*
572 * For encryption only, we have to grab the IV for the
573 * next pass AFTER encryption.
574 */
575 if (reqp->dr_flags & DR_ENCRYPT) {
576 uchar_t ivstore[DESBLOCK];
577 #ifdef UNALIGNED_POINTERS_PERMITTED
578 uint32_t *iv = (uint32_t *)ivstore;
579 #else
580 uchar_t *iv = ivstore;
581 #endif /* UNALIGNED_POINTERS_PERMITTED */
582
583 /* get last 8 bytes for IV of next op */
584 errno = dca_getbufbytes(out, off, DESBLOCK,
585 (uchar_t *)iv);
586 if (errno != CRYPTO_SUCCESS) {
587 DBG(NULL, DWARN,
588 "dca_3desdone: dca_getbufbytes() failed");
589 goto errout;
590 }
591
592 /* store as a pair of native 32-bit values */
593 #ifdef UNALIGNED_POINTERS_PERMITTED
594 ctx->dr_ctx.iv[0] = htonl(iv[0]);
595 ctx->dr_ctx.iv[1] = htonl(iv[1]);
596 #else
597 ctx->dr_ctx.iv[0] =
598 iv[0]<<24 | iv[1]<<16 | iv[2]<<8 | iv[3];
599 ctx->dr_ctx.iv[1] =
600 iv[4]<<24 | iv[5]<<16 | iv[6]<<8 | iv[7];
601 #endif /* UNALIGNED_POINTERS_PERMITTED */
602 }
603
604 /*
605 * If there is more to do, then reschedule another
606 * pass.
607 */
608 if (dca_length(reqp->dr_in) >= 8) {
609 errno = dca_3desstart(reqp->dr_dca, reqp->dr_flags,
610 reqp);
611 if (errno == CRYPTO_QUEUED) {
612 return;
613 }
614 }
615 }
616
617 errout:
618
619 /*
620 * If this is an atomic operation perform the final function
621 * tasks (equivalent to to dca_3desfinal()).
641
642 /* This has to be done after notifing the framework */
643 if (reqp->dr_ctx.atomic) {
644 reqp->dr_context = NULL;
645 reqp->dr_ctx.atomic = 0;
646 reqp->dr_ctx.ctx_cm_type = 0;
647 if (reqp->destroy)
648 dca_destroyreq(reqp);
649 else
650 dca_freereq(reqp);
651 }
652 }
653
654 /* ARGSUSED */
655 int
656 dca_3desctxinit(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
657 crypto_key_t *key, int kmflag, int flags)
658 {
659 dca_request_t *des_ctx;
660 dca_t *dca = ctx->cc_provider;
661 #ifdef UNALIGNED_POINTERS_PERMITTED
662 uint32_t *param;
663 uint32_t *value32;
664 #else
665 uchar_t *param;
666 #endif /* UNALIGNED_POINTERS_PERMITTED */
667 uchar_t *value;
668 size_t paramsz;
669 unsigned len;
670 int i, j;
671
672 paramsz = mechanism->cm_param_len;
673 #ifdef UNALIGNED_POINTERS_PERMITTED
674 param = (uint32_t *)mechanism->cm_param;
675 #else
676 param = (uchar_t *)mechanism->cm_param;
677 #endif /* UNALIGNED_POINTERS_PERMITTED */
678
679 if ((paramsz != 0) && (paramsz != DES_IV_LEN)) {
680 DBG(NULL, DWARN,
681 "dca_3desctxinit: parameter(IV) length not %d (%d)",
682 DES_IV_LEN, paramsz);
683 return (CRYPTO_MECHANISM_PARAM_INVALID);
684 }
685
686 if ((des_ctx = dca_getreq(dca, MCR1, 1)) == NULL) {
687 dca_error(dca, "unable to allocate request for 3DES");
688 return (CRYPTO_HOST_MEMORY);
689 }
690 /*
691 * Identify and store the IV as a pair of native 32-bit words.
692 *
693 * If cm_param == NULL then the IV comes from the cd_miscdata field
694 * in the crypto_data structure.
695 */
696 if (param != NULL) {
697 ASSERT(paramsz == DES_IV_LEN);
698 #ifdef UNALIGNED_POINTERS_PERMITTED
699 des_ctx->dr_ctx.iv[0] = htonl(param[0]);
700 des_ctx->dr_ctx.iv[1] = htonl(param[1]);
701 #else
702 des_ctx->dr_ctx.iv[0] = param[0]<<24 | param[1]<<16 |
703 param[2]<<8 | param[3];
704 des_ctx->dr_ctx.iv[1] = param[4]<<24 | param[5]<<16 |
705 param[6]<<8 | param[7];
706 #endif /* UNALIGNED_POINTERS_PERMITTED */
707 }
708 des_ctx->dr_ctx.residlen = 0;
709 des_ctx->dr_ctx.activeresidlen = 0;
710 des_ctx->dr_ctx.ctx_cm_type = mechanism->cm_type;
711 ctx->cc_provider_private = des_ctx;
712
713 if (key->ck_format != CRYPTO_KEY_RAW) {
714 DBG(NULL, DWARN,
715 "dca_3desctxinit: only raw crypto key type support with DES/3DES");
716 dca_3desctxfree(ctx);
717 return (CRYPTO_KEY_TYPE_INCONSISTENT);
718 }
719
720 len = key->ck_length;
721 value = (uchar_t *)key->ck_data;
722
723 if (flags & DR_TRIPLE) {
724 /* 3DES */
725 switch (len) {
726 case 192:
742 des_ctx->dr_ctx.key[i] |= *value;
743 value++;
744 }
745 }
746 des_ctx->dr_ctx.key[4] = des_ctx->dr_ctx.key[0];
747 des_ctx->dr_ctx.key[5] = des_ctx->dr_ctx.key[1];
748 break;
749
750 default:
751 DBG(NULL, DWARN, "Incorrect 3DES keysize (%d)", len);
752 dca_3desctxfree(ctx);
753 return (CRYPTO_KEY_SIZE_RANGE);
754 }
755 } else {
756 /* single DES */
757 if (len != 64) {
758 DBG(NULL, DWARN, "Incorrect DES keysize (%d)", len);
759 dca_3desctxfree(ctx);
760 return (CRYPTO_KEY_SIZE_RANGE);
761 }
762
763 #ifdef UNALIGNED_POINTERS_PERMITTED
764 value32 = (uint32_t *)value;
765 des_ctx->dr_ctx.key[0] = htonl(value32[0]);
766 des_ctx->dr_ctx.key[1] = htonl(value32[1]);
767 #else
768 des_ctx->dr_ctx.key[0] =
769 value[0]<<24 | value[1]<<16 | value[2]<<8 | value[3];
770 des_ctx->dr_ctx.key[1] =
771 value[4]<<24 | value[5]<<16 | value[6]<<8 | value[7];
772 #endif /* UNALIGNED_POINTERS_PERMITTED */
773
774 /* for single des just repeat des key */
775 des_ctx->dr_ctx.key[4] =
776 des_ctx->dr_ctx.key[2] = des_ctx->dr_ctx.key[0];
777 des_ctx->dr_ctx.key[5] =
778 des_ctx->dr_ctx.key[3] = des_ctx->dr_ctx.key[1];
779 }
780
781 /*
782 * Setup the context here so that we do not need to setup it up
783 * for every update
784 */
785 PUTCTX16(des_ctx, CTX_LENGTH, CTX_3DES_LENGTH);
786 PUTCTX16(des_ctx, CTX_CMD, CMD_3DES);
787 PUTCTX32(des_ctx, CTX_3DESDIRECTION,
788 flags & DR_ENCRYPT ? CTX_3DES_ENCRYPT : CTX_3DES_DECRYPT);
789 PUTCTX32(des_ctx, CTX_3DESKEY1HI, des_ctx->dr_ctx.key[0]);
790 PUTCTX32(des_ctx, CTX_3DESKEY1LO, des_ctx->dr_ctx.key[1]);
791 PUTCTX32(des_ctx, CTX_3DESKEY2HI, des_ctx->dr_ctx.key[2]);
792 PUTCTX32(des_ctx, CTX_3DESKEY2LO, des_ctx->dr_ctx.key[3]);
793 PUTCTX32(des_ctx, CTX_3DESKEY3HI, des_ctx->dr_ctx.key[4]);
|