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

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/crypto/io/dca_3des.c
          +++ new/usr/src/uts/common/crypto/io/dca_3des.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * When distributing Covered Code, include this CDDL HEADER in each
  15   15   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16   16   * If applicable, add the following below this CDDL HEADER, with the
  17   17   * fields enclosed by brackets "[]" replaced with your own identifying
  18   18   * information: Portions Copyright [yyyy] [name of copyright owner]
  19   19   *
  20   20   * CDDL HEADER END
  21   21   */
  22   22  
  23   23  /*
  24      - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
       24 + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  25   25   * Use is subject to license terms.
  26   26   */
  27   27  
  28      -#pragma ident   "%Z%%M% %I%     %E% SMI"
  29      -
  30   28  /*
  31   29   * Deimos - cryptographic acceleration based upon Broadcom 582x.
  32   30   */
  33   31  
  34   32  #include <sys/types.h>
  35   33  #include <sys/ddi.h>
  36   34  #include <sys/sunddi.h>
  37   35  #include <sys/kmem.h>
  38   36  #include <sys/note.h>
  39   37  #include <sys/crypto/common.h>
  40   38  #include <sys/crypto/spi.h>
  41   39  #include <sys/crypto/dca.h>
  42   40  
       41 +#if defined(__i386) || defined(__amd64)
       42 +#include <sys/byteorder.h>
       43 +#define UNALIGNED_POINTERS_PERMITTED
       44 +#endif
       45 +
  43   46  /*
  44   47   * 3DES implementation.
  45   48   */
  46   49  
  47   50  static int dca_3desstart(dca_t *, uint32_t, dca_request_t *);
  48   51  static void dca_3desdone(dca_request_t *, int);
  49   52  
  50   53  
  51   54  int
  52   55  dca_3des(crypto_ctx_t *ctx, crypto_data_t *in,
↓ open down ↓ 14 lines elided ↑ open up ↑
  67   70                          return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
  68   71                  } else {
  69   72                          return (CRYPTO_DATA_LEN_RANGE);
  70   73                  }
  71   74          }
  72   75  
  73   76          /*
  74   77           * If cd_miscdata non-null then this contains the IV.
  75   78           */
  76   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
  77   85                  uchar_t *p = (uchar_t *)in->cd_miscdata;
  78   86                  des_ctx->dr_ctx.iv[0] = p[0]<<24 | p[1]<<16 | p[2]<<8 | p[3];
  79   87                  des_ctx->dr_ctx.iv[1] = p[4]<<24 | p[5]<<16 | p[6]<<8 | p[7];
       88 +#endif  /* UNALIGNED_POINTERS_PERMITTED */
  80   89          }
  81   90  
  82   91          if (len > dca_length(out)) {
  83   92                  DBG(dca, DWARN, "inadequate output space (need %d, got %d)",
  84   93                      len, dca_length(out));
  85   94                  out->cd_length = len;
  86   95                  /* Do not free the context since the app will call again */
  87   96                  return (CRYPTO_BUFFER_TOO_SMALL);
  88   97          }
  89   98  
↓ open down ↓ 71 lines elided ↑ open up ↑
 161  170          dca_t                   *dca = ctx->cc_provider;
 162  171          crypto_data_t           *nin = &reqp->dr_ctx.in_dup;
 163  172  
 164  173          rawlen = dca_length(in) + des_ctx->dr_ctx.residlen;
 165  174  
 166  175          len = ROUNDDOWN(rawlen, DESBLOCK);
 167  176          /*
 168  177           * If cd_miscdata non-null then this contains the IV.
 169  178           */
 170  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
 171  185                  uchar_t *p = (uchar_t *)in->cd_miscdata;
 172  186                  des_ctx->dr_ctx.iv[0] = p[0]<<24 | p[1]<<16 | p[2]<<8 | p[3];
 173  187                  des_ctx->dr_ctx.iv[1] = p[4]<<24 | p[5]<<16 | p[6]<<8 | p[7];
      188 +#endif  /* UNALIGNED_POINTERS_PERMITTED */
 174  189          }
 175  190  
 176  191          if (len > dca_length(out)) {
 177  192                  DBG(dca, DWARN, "not enough output space (need %d, got %d)",
 178  193                      len, dca_length(out));
 179  194                  out->cd_length = len;
 180  195                  /* Do not free the context since the app will call again */
 181  196                  return (CRYPTO_BUFFER_TOO_SMALL);
 182  197          }
 183  198  
↓ open down ↓ 201 lines elided ↑ open up ↑
 385  400          iv[1] = ctx->dr_ctx.iv[1];
 386  401  
 387  402          /*
 388  403           * And also, for decrypt, collect the IV for the next pass.  For
 389  404           * decrypt, the IV must be collected BEFORE decryption, or else
 390  405           * we will lose it.  (For encrypt, we grab the IV AFTER encryption,
 391  406           * in dca_3desdone.
 392  407           */
 393  408          if (flags & DR_DECRYPT) {
 394  409                  uchar_t         ivstore[DESBLOCK];
      410 +#ifdef UNALIGNED_POINTERS_PERMITTED
      411 +                uint32_t        *ivp = (uint32_t *)ivstore;
      412 +#else
 395  413                  uchar_t         *ivp = ivstore;
      414 +#endif  /* UNALIGNED_POINTERS_PERMITTED */
 396  415  
 397  416                  /* get last 8 bytes of ciphertext for IV of next op */
 398  417                  /*
 399  418                   * If we're processing only a DESBLOCKS worth of data
 400  419                   * and there is active residual present then it will be
 401  420                   * needed for the IV also.
 402  421                   */
 403  422                  if ((len == DESBLOCK) && ctx->dr_ctx.activeresidlen) {
 404  423                          /* Bring the active residual into play */
 405  424                          bcopy(ctx->dr_ctx.activeresid, ivstore,
↓ open down ↓ 7 lines elided ↑ open up ↑
 413  432                              DESBLOCK, ivstore);
 414  433                  }
 415  434  
 416  435                  if (rv != CRYPTO_SUCCESS) {
 417  436                          DBG(dca, DWARN,
 418  437                              "dca_3desstart: dca_getbufbytes() failed");
 419  438                          return (rv);
 420  439                  }
 421  440  
 422  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
 423  446                  ctx->dr_ctx.iv[0] =
 424  447                      ivp[0]<<24 | ivp[1]<<16 | ivp[2]<<8 | ivp[3];
 425  448                  ctx->dr_ctx.iv[1] =
 426  449                      ivp[4]<<24 | ivp[5]<<16 | ivp[6]<<8 | ivp[7];
      450 +#endif  /* UNALIGNED_POINTERS_PERMITTED */
 427  451          }
 428  452  
 429  453          /* For now we force a pullup.  Add direct DMA later. */
 430  454          reqp->dr_flags &= ~(DR_SCATTER | DR_GATHER);
 431  455          if ((len < dca_mindma) || (ctx->dr_ctx.activeresidlen > 0) ||
 432  456              dca_sgcheck(dca, reqp->dr_in, DCA_SG_CONTIG) ||
 433  457              dca_sgcheck(dca, reqp->dr_out, DCA_SG_WALIGN)) {
 434  458                  reqp->dr_flags |= DR_SCATTER | DR_GATHER;
 435  459          }
 436  460  
↓ open down ↓ 106 lines elided ↑ open up ↑
 543  567                          out->cd_length += reqp->dr_pkt_length;
 544  568                  }
 545  569  
 546  570  
 547  571                  /*
 548  572                   * For encryption only, we have to grab the IV for the
 549  573                   * next pass AFTER encryption.
 550  574                   */
 551  575                  if (reqp->dr_flags & DR_ENCRYPT) {
 552  576                          uchar_t         ivstore[DESBLOCK];
      577 +#ifdef UNALIGNED_POINTERS_PERMITTED
      578 +                        uint32_t        *iv = (uint32_t *)ivstore;
      579 +#else
 553  580                          uchar_t         *iv = ivstore;
      581 +#endif  /* UNALIGNED_POINTERS_PERMITTED */
 554  582  
 555  583                          /* get last 8 bytes for IV of next op */
 556      -                        errno = dca_getbufbytes(out, off, DESBLOCK, iv);
      584 +                        errno = dca_getbufbytes(out, off, DESBLOCK,
      585 +                            (uchar_t *)iv);
 557  586                          if (errno != CRYPTO_SUCCESS) {
 558  587                                  DBG(NULL, DWARN,
 559  588                                      "dca_3desdone: dca_getbufbytes() failed");
 560  589                                  goto errout;
 561  590                          }
      591 +
 562  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
 563  597                          ctx->dr_ctx.iv[0] =
 564  598                              iv[0]<<24 | iv[1]<<16 | iv[2]<<8 | iv[3];
 565  599                          ctx->dr_ctx.iv[1] =
 566  600                              iv[4]<<24 | iv[5]<<16 | iv[6]<<8 | iv[7];
      601 +#endif  /* UNALIGNED_POINTERS_PERMITTED */
 567  602                  }
 568  603  
 569  604                  /*
 570  605                   * If there is more to do, then reschedule another
 571  606                   * pass.
 572  607                   */
 573  608                  if (dca_length(reqp->dr_in) >= 8) {
 574  609                          errno = dca_3desstart(reqp->dr_dca, reqp->dr_flags,
 575  610                              reqp);
 576  611                          if (errno == CRYPTO_QUEUED) {
↓ open down ↓ 39 lines elided ↑ open up ↑
 616  651          }
 617  652  }
 618  653  
 619  654  /* ARGSUSED */
 620  655  int
 621  656  dca_3desctxinit(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
 622  657      crypto_key_t *key, int kmflag, int flags)
 623  658  {
 624  659          dca_request_t   *des_ctx;
 625  660          dca_t           *dca = ctx->cc_provider;
      661 +#ifdef UNALIGNED_POINTERS_PERMITTED
      662 +        uint32_t        *param;
      663 +        uint32_t        *value32;
      664 +#else
 626  665          uchar_t         *param;
      666 +#endif  /* UNALIGNED_POINTERS_PERMITTED */
 627  667          uchar_t         *value;
 628  668          size_t          paramsz;
 629  669          unsigned        len;
 630  670          int             i, j;
 631  671  
 632  672          paramsz = mechanism->cm_param_len;
      673 +#ifdef UNALIGNED_POINTERS_PERMITTED
      674 +        param = (uint32_t *)mechanism->cm_param;
      675 +#else
 633  676          param = (uchar_t *)mechanism->cm_param;
      677 +#endif  /* UNALIGNED_POINTERS_PERMITTED */
      678 +
 634  679          if ((paramsz != 0) && (paramsz != DES_IV_LEN)) {
 635  680                  DBG(NULL, DWARN,
 636  681                      "dca_3desctxinit: parameter(IV) length not %d (%d)",
 637  682                      DES_IV_LEN, paramsz);
 638  683                  return (CRYPTO_MECHANISM_PARAM_INVALID);
 639  684          }
 640  685  
 641  686          if ((des_ctx = dca_getreq(dca, MCR1, 1)) == NULL) {
 642  687                  dca_error(dca, "unable to allocate request for 3DES");
 643  688                  return (CRYPTO_HOST_MEMORY);
 644  689          }
 645  690          /*
 646  691           * Identify and store the IV as a pair of native 32-bit words.
 647  692           *
 648  693           * If cm_param == NULL then the IV comes from the cd_miscdata field
 649  694           * in the crypto_data structure.
 650  695           */
 651  696          if (param != NULL) {
 652  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
 653  702                  des_ctx->dr_ctx.iv[0] = param[0]<<24 | param[1]<<16 |
 654  703                      param[2]<<8 | param[3];
 655  704                  des_ctx->dr_ctx.iv[1] = param[4]<<24 | param[5]<<16 |
 656  705                      param[6]<<8 | param[7];
      706 +#endif  /* UNALIGNED_POINTERS_PERMITTED */
 657  707          }
 658  708          des_ctx->dr_ctx.residlen = 0;
 659  709          des_ctx->dr_ctx.activeresidlen = 0;
 660  710          des_ctx->dr_ctx.ctx_cm_type = mechanism->cm_type;
 661  711          ctx->cc_provider_private = des_ctx;
 662  712  
 663  713          if (key->ck_format != CRYPTO_KEY_RAW) {
 664  714                  DBG(NULL, DWARN,
 665  715          "dca_3desctxinit: only raw crypto key type support with DES/3DES");
 666  716                  dca_3desctxfree(ctx);
↓ open down ↓ 35 lines elided ↑ open up ↑
 702  752                          dca_3desctxfree(ctx);
 703  753                          return (CRYPTO_KEY_SIZE_RANGE);
 704  754                  }
 705  755          } else {
 706  756                  /* single DES */
 707  757                  if (len != 64) {
 708  758                          DBG(NULL, DWARN, "Incorrect DES keysize (%d)", len);
 709  759                          dca_3desctxfree(ctx);
 710  760                          return (CRYPTO_KEY_SIZE_RANGE);
 711  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
 712  768                  des_ctx->dr_ctx.key[0] =
 713  769                      value[0]<<24 | value[1]<<16 | value[2]<<8 | value[3];
 714  770                  des_ctx->dr_ctx.key[1] =
 715  771                      value[4]<<24 | value[5]<<16 | value[6]<<8 | value[7];
      772 +#endif  /* UNALIGNED_POINTERS_PERMITTED */
      773 +
 716  774                  /* for single des just repeat des key */
 717  775                  des_ctx->dr_ctx.key[4] =
 718  776                      des_ctx->dr_ctx.key[2] = des_ctx->dr_ctx.key[0];
 719  777                  des_ctx->dr_ctx.key[5] =
 720  778                      des_ctx->dr_ctx.key[3] = des_ctx->dr_ctx.key[1];
 721  779          }
 722  780  
 723  781          /*
 724  782           * Setup the context here so that we do not need to setup it up
 725  783           * for every update
↓ open down ↓ 14 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX