Print this page
5007142 Add ntohll and htonll to sys/byteorder.h
6717509 Need to use bswap/bswapq for byte swap of 64-bit integer on x32/x64
PSARC 2008/474


   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]);