Print this page
3882 remove xmod & friends

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/des/des_crypt.c
          +++ new/usr/src/uts/common/des/des_crypt.c
↓ open down ↓ 43 lines elided ↑ open up ↑
  44   44  #include <sys/ddi.h>
  45   45  #include <sys/crypto/common.h>
  46   46  #include <sys/crypto/spi.h>
  47   47  #include <sys/sysmacros.h>
  48   48  #include <sys/strsun.h>
  49   49  #include <sys/note.h>
  50   50  #include <modes/modes.h>
  51   51  #define _DES_IMPL
  52   52  #include <des/des_impl.h>
  53   53  
  54      -/* EXPORT DELETE START */
  55   54  #include <sys/types.h>
  56   55  #include <rpc/des_crypt.h>
  57   56  #include <des/des.h>
  58   57  
  59   58  #ifdef sun_hardware
  60   59  #include <sys/ioctl.h>
  61   60  #ifdef _KERNEL
  62   61  #include <sys/conf.h>
  63   62  static int g_desfd = -1;
  64   63  #define getdesfd()      (cdevsw[11].d_open(0, 0) ? -1 : 0)
↓ open down ↓ 1 lines elided ↑ open up ↑
  66   65  #else
  67   66  #define getdesfd()      (open("/dev/des", 0, 0))
  68   67  #endif  /* _KERNEL */
  69   68  #endif  /* sun */
  70   69  
  71   70  static int common_crypt(char *key, char *buf, size_t len,
  72   71      unsigned int mode, struct desparams *desp);
  73   72  
  74   73  extern int _des_crypt(char *buf, size_t len, struct desparams *desp);
  75   74  
  76      -/* EXPORT DELETE END */
  77      -
  78   75  extern struct mod_ops mod_cryptoops;
  79   76  
  80   77  /*
  81   78   * Module linkage information for the kernel.
  82   79   */
  83   80  static struct modlmisc modlmisc = {
  84   81          &mod_miscops,
  85   82          "des encryption",
  86   83  };
  87   84  
↓ open down ↓ 2 lines elided ↑ open up ↑
  90   87          "DES Kernel SW Provider"
  91   88  };
  92   89  
  93   90  static struct modlinkage modlinkage = {
  94   91          MODREV_1,
  95   92          &modlmisc,
  96   93          &modlcrypto,
  97   94          NULL
  98   95  };
  99   96  
 100      -/* EXPORT DELETE START */
 101      -
 102   97  #define DES_MIN_KEY_LEN         DES_MINBYTES
 103   98  #define DES_MAX_KEY_LEN         DES_MAXBYTES
 104   99  #define DES3_MIN_KEY_LEN        DES3_MAXBYTES   /* no CKK_DES2 support */
 105  100  #define DES3_MAX_KEY_LEN        DES3_MAXBYTES
 106  101  
 107      -/* EXPORT DELETE END */
 108      -
 109  102  #ifndef DES_MIN_KEY_LEN
 110  103  #define DES_MIN_KEY_LEN         0
 111  104  #endif
 112  105  
 113  106  #ifndef DES_MAX_KEY_LEN
 114  107  #define DES_MAX_KEY_LEN         0
 115  108  #endif
 116  109  
 117  110  #ifndef DES3_MIN_KEY_LEN
 118  111  #define DES3_MIN_KEY_LEN        0
↓ open down ↓ 185 lines elided ↑ open up ↑
 304  297  }
 305  298  
 306  299  /*
 307  300   * CBC mode encryption
 308  301   */
 309  302  /* ARGSUSED */
 310  303  int
 311  304  cbc_crypt(char *key, char *buf, size_t len, unsigned int mode, char *ivec)
 312  305  {
 313  306          int err = 0;
 314      -/* EXPORT DELETE START */
 315  307          struct desparams dp;
 316  308  
 317  309          dp.des_mode = CBC;
 318  310          COPY8(ivec, dp.des_ivec);
 319  311          err = common_crypt(key, buf, len, mode, &dp);
 320  312          COPY8(dp.des_ivec, ivec);
 321      -/* EXPORT DELETE END */
 322  313          return (err);
 323  314  }
 324  315  
 325  316  
 326  317  /*
 327  318   * ECB mode encryption
 328  319   */
 329  320  /* ARGSUSED */
 330  321  int
 331  322  ecb_crypt(char *key, char *buf, size_t len, unsigned int mode)
 332  323  {
 333  324          int err = 0;
 334      -/* EXPORT DELETE START */
 335  325          struct desparams dp;
 336  326  
 337  327          dp.des_mode = ECB;
 338  328          err = common_crypt(key, buf, len, mode, &dp);
 339      -/* EXPORT DELETE END */
 340  329          return (err);
 341  330  }
 342  331  
 343  332  
 344  333  
 345      -/* EXPORT DELETE START */
 346  334  /*
 347  335   * Common code to cbc_crypt() & ecb_crypt()
 348  336   */
 349  337  static int
 350  338  common_crypt(char *key, char *buf, size_t len, unsigned int mode,
 351  339      struct desparams *desp)
 352  340  {
 353  341          int desdev;
 354  342  
 355  343          if ((len % 8) != 0 || len > DES_MAXDATA)
↓ open down ↓ 65 lines elided ↑ open up ↑
 421  409           * Initialize key schedule even if key is weak.
 422  410           */
 423  411          if (key->ck_data == NULL)
 424  412                  return (CRYPTO_ARGUMENTS_BAD);
 425  413  
 426  414          des_parity_fix(key->ck_data, strength, corrected_key);
 427  415          des_init_keysched(corrected_key, strength, newbie);
 428  416          return (CRYPTO_SUCCESS);
 429  417  }
 430  418  
 431      -/* EXPORT DELETE END */
 432      -
 433  419  /*
 434  420   * KCF software provider control entry points.
 435  421   */
 436  422  /* ARGSUSED */
 437  423  static void
 438  424  des_provider_status(crypto_provider_handle_t provider, uint_t *status)
 439  425  {
 440  426          *status = CRYPTO_PROVIDER_READY;
 441  427  }
 442  428  
 443  429  /*
 444  430   * KCF software provider encrypt entry points.
 445  431   */
 446  432  static int
 447  433  des_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
 448  434      crypto_key_t *key, crypto_spi_ctx_template_t template,
 449  435      crypto_req_handle_t req)
 450  436  {
 451  437  
 452      -/* EXPORT DELETE START */
 453      -
 454  438          des_strength_t strength;
 455  439          des_ctx_t *des_ctx = NULL;
 456  440          int rv;
 457  441          int kmflag;
 458  442  
 459  443          /*
 460  444           * Only keys by value are supported by this module.
 461  445           */
 462  446          if (key->ck_format != CRYPTO_KEY_RAW) {
 463  447                  return (CRYPTO_KEY_TYPE_INCONSISTENT);
↓ open down ↓ 33 lines elided ↑ open up ↑
 497  481          }
 498  482  
 499  483          if ((rv = des_common_init_ctx(des_ctx, template, mechanism, key,
 500  484              strength, kmflag)) != CRYPTO_SUCCESS) {
 501  485                  crypto_free_mode_ctx(des_ctx);
 502  486                  return (rv);
 503  487          }
 504  488  
 505  489          ctx->cc_provider_private = des_ctx;
 506  490  
 507      -/* EXPORT DELETE END */
 508      -
 509  491          return (CRYPTO_SUCCESS);
 510  492  }
 511  493  
 512  494  static void
 513  495  des_copy_block64(uint8_t *in, uint64_t *out)
 514  496  {
 515  497          if (IS_P2ALIGNED(in, sizeof (uint64_t))) {
 516  498                  /* LINTED: pointer alignment */
 517  499                  out[0] = *(uint64_t *)&in[0];
 518  500          } else {
↓ open down ↓ 23 lines elided ↑ open up ↑
 542  524          }
 543  525  }
 544  526  
 545  527  /* ARGSUSED */
 546  528  static int
 547  529  des_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
 548  530      crypto_data_t *ciphertext, crypto_req_handle_t req)
 549  531  {
 550  532          int ret;
 551  533  
 552      -/* EXPORT DELETE START */
 553  534          des_ctx_t *des_ctx;
 554  535  
 555  536          /*
 556  537           * Plaintext must be a multiple of the block size.
 557  538           * This test only works for non-padded mechanisms
 558  539           * when blocksize is 2^N.
 559  540           */
 560  541          if ((plaintext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
 561  542                  return (CRYPTO_DATA_LEN_RANGE);
 562  543  
↓ open down ↓ 11 lines elided ↑ open up ↑
 574  555                  return (CRYPTO_BUFFER_TOO_SMALL);
 575  556          }
 576  557  
 577  558          /*
 578  559           * Do an update on the specified input data.
 579  560           */
 580  561          ret = des_encrypt_update(ctx, plaintext, ciphertext, req);
 581  562          ASSERT(des_ctx->dc_remainder_len == 0);
 582  563          (void) des_free_context(ctx);
 583  564  
 584      -/* EXPORT DELETE END */
 585      -
 586  565          /* LINTED */
 587  566          return (ret);
 588  567  }
 589  568  
 590  569  /* ARGSUSED */
 591  570  static int
 592  571  des_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
 593  572      crypto_data_t *plaintext, crypto_req_handle_t req)
 594  573  {
 595  574          int ret;
 596  575  
 597      -/* EXPORT DELETE START */
 598  576          des_ctx_t *des_ctx;
 599  577  
 600  578          /*
 601  579           * Ciphertext must be a multiple of the block size.
 602  580           * This test only works for non-padded mechanisms
 603  581           * when blocksize is 2^N.
 604  582           */
 605  583          if ((ciphertext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
 606  584                  return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
 607  585  
↓ open down ↓ 11 lines elided ↑ open up ↑
 619  597                  return (CRYPTO_BUFFER_TOO_SMALL);
 620  598          }
 621  599  
 622  600          /*
 623  601           * Do an update on the specified input data.
 624  602           */
 625  603          ret = des_decrypt_update(ctx, ciphertext, plaintext, req);
 626  604          ASSERT(des_ctx->dc_remainder_len == 0);
 627  605          (void) des_free_context(ctx);
 628  606  
 629      -/* EXPORT DELETE END */
 630      -
 631  607          /* LINTED */
 632  608          return (ret);
 633  609  }
 634  610  
 635  611  /* ARGSUSED */
 636  612  static int
 637  613  des_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
 638  614      crypto_data_t *ciphertext, crypto_req_handle_t req)
 639  615  {
 640  616          off_t saved_offset;
 641  617          size_t saved_length, out_len;
 642  618          int ret = CRYPTO_SUCCESS;
 643  619  
 644      -/* EXPORT DELETE START */
 645      -
 646  620          ASSERT(ctx->cc_provider_private != NULL);
 647  621  
 648  622          DES_ARG_INPLACE(plaintext, ciphertext);
 649  623  
 650  624          /* compute number of bytes that will hold the ciphertext */
 651  625          out_len = ((des_ctx_t *)ctx->cc_provider_private)->dc_remainder_len;
 652  626          out_len += plaintext->cd_length;
 653  627          out_len &= ~(DES_BLOCK_LEN - 1);
 654  628  
 655  629          /* return length needed to store the output */
↓ open down ↓ 30 lines elided ↑ open up ↑
 686  660  
 687  661          if (ret == CRYPTO_SUCCESS) {
 688  662                  if (plaintext != ciphertext)
 689  663                          ciphertext->cd_length =
 690  664                              ciphertext->cd_offset - saved_offset;
 691  665          } else {
 692  666                  ciphertext->cd_length = saved_length;
 693  667          }
 694  668          ciphertext->cd_offset = saved_offset;
 695  669  
 696      -/* EXPORT DELETE END */
 697      -
 698  670          return (ret);
 699  671  }
 700  672  
 701  673  /* ARGSUSED */
 702  674  static int
 703  675  des_decrypt_update(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
 704  676      crypto_data_t *plaintext, crypto_req_handle_t req)
 705  677  {
 706  678          off_t saved_offset;
 707  679          size_t saved_length, out_len;
 708  680          int ret = CRYPTO_SUCCESS;
 709  681  
 710      -/* EXPORT DELETE START */
 711      -
 712  682          ASSERT(ctx->cc_provider_private != NULL);
 713  683  
 714  684          DES_ARG_INPLACE(ciphertext, plaintext);
 715  685  
 716  686          /* compute number of bytes that will hold the plaintext */
 717  687          out_len = ((des_ctx_t *)ctx->cc_provider_private)->dc_remainder_len;
 718  688          out_len += ciphertext->cd_length;
 719  689          out_len &= ~(DES_BLOCK_LEN - 1);
 720  690  
 721  691          /* return length needed to store the output */
↓ open down ↓ 30 lines elided ↑ open up ↑
 752  722  
 753  723          if (ret == CRYPTO_SUCCESS) {
 754  724                  if (ciphertext != plaintext)
 755  725                          plaintext->cd_length =
 756  726                              plaintext->cd_offset - saved_offset;
 757  727          } else {
 758  728                  plaintext->cd_length = saved_length;
 759  729          }
 760  730          plaintext->cd_offset = saved_offset;
 761  731  
 762      -/* EXPORT DELETE END */
 763      -
 764  732          return (ret);
 765  733  }
 766  734  
 767  735  /* ARGSUSED */
 768  736  static int
 769  737  des_encrypt_final(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
 770  738      crypto_req_handle_t req)
 771  739  {
 772      -
 773      -/* EXPORT DELETE START */
 774      -
 775  740          des_ctx_t *des_ctx;
 776  741  
 777  742          ASSERT(ctx->cc_provider_private != NULL);
 778  743          des_ctx = ctx->cc_provider_private;
 779  744  
 780  745          /*
 781  746           * There must be no unprocessed plaintext.
 782  747           * This happens if the length of the last data is
 783  748           * not a multiple of the DES block length.
 784  749           */
 785  750          if (des_ctx->dc_remainder_len > 0)
 786  751                  return (CRYPTO_DATA_LEN_RANGE);
 787  752  
 788  753          (void) des_free_context(ctx);
 789  754          ciphertext->cd_length = 0;
 790  755  
 791      -/* EXPORT DELETE END */
 792      -
 793  756          return (CRYPTO_SUCCESS);
 794  757  }
 795  758  
 796  759  /* ARGSUSED */
 797  760  static int
 798  761  des_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *plaintext,
 799  762      crypto_req_handle_t req)
 800  763  {
 801      -
 802      -/* EXPORT DELETE START */
 803      -
 804  764          des_ctx_t *des_ctx;
 805  765  
 806  766          ASSERT(ctx->cc_provider_private != NULL);
 807  767          des_ctx = ctx->cc_provider_private;
 808  768  
 809  769          /*
 810  770           * There must be no unprocessed ciphertext.
 811  771           * This happens if the length of the last ciphertext is
 812  772           * not a multiple of the DES block length.
 813  773           */
 814  774          if (des_ctx->dc_remainder_len > 0)
 815  775                  return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
 816  776  
 817  777          (void) des_free_context(ctx);
 818  778          plaintext->cd_length = 0;
 819  779  
 820      -/* EXPORT DELETE END */
 821      -
 822  780          return (CRYPTO_SUCCESS);
 823  781  }
 824  782  
 825  783  /* ARGSUSED */
 826  784  static int
 827  785  des_encrypt_atomic(crypto_provider_handle_t provider,
 828  786      crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
 829  787      crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext,
 830  788      crypto_spi_ctx_template_t template, crypto_req_handle_t req)
 831  789  {
 832  790          int ret;
 833  791  
 834      -/* EXPORT DELETE START */
 835      -
 836  792          des_ctx_t des_ctx;              /* on the stack */
 837  793          des_strength_t strength;
 838  794          off_t saved_offset;
 839  795          size_t saved_length;
 840  796  
 841  797          DES_ARG_INPLACE(plaintext, ciphertext);
 842  798  
 843  799          /*
 844  800           * Plaintext must be a multiple of the block size.
 845  801           * This test only works for non-padded mechanisms
↓ open down ↓ 70 lines elided ↑ open up ↑
 916  872          if (ret == CRYPTO_SUCCESS) {
 917  873                  ASSERT(des_ctx.dc_remainder_len == 0);
 918  874                  if (plaintext != ciphertext)
 919  875                          ciphertext->cd_length =
 920  876                              ciphertext->cd_offset - saved_offset;
 921  877          } else {
 922  878                  ciphertext->cd_length = saved_length;
 923  879          }
 924  880          ciphertext->cd_offset = saved_offset;
 925  881  
 926      -/* EXPORT DELETE END */
 927      -
 928  882          /* LINTED */
 929  883          return (ret);
 930  884  }
 931  885  
 932  886  /* ARGSUSED */
 933  887  static int
 934  888  des_decrypt_atomic(crypto_provider_handle_t provider,
 935  889      crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
 936  890      crypto_key_t *key, crypto_data_t *ciphertext, crypto_data_t *plaintext,
 937  891      crypto_spi_ctx_template_t template, crypto_req_handle_t req)
 938  892  {
 939  893          int ret;
 940  894  
 941      -/* EXPORT DELETE START */
 942      -
 943  895          des_ctx_t des_ctx;      /* on the stack */
 944  896          des_strength_t strength;
 945  897          off_t saved_offset;
 946  898          size_t saved_length;
 947  899  
 948  900          DES_ARG_INPLACE(ciphertext, plaintext);
 949  901  
 950  902          /*
 951  903           * Ciphertext must be a multiple of the block size.
 952  904           * This test only works for non-padded mechanisms
↓ open down ↓ 70 lines elided ↑ open up ↑
1023  975          if (ret == CRYPTO_SUCCESS) {
1024  976                  ASSERT(des_ctx.dc_remainder_len == 0);
1025  977                  if (ciphertext != plaintext)
1026  978                          plaintext->cd_length =
1027  979                              plaintext->cd_offset - saved_offset;
1028  980          } else {
1029  981                  plaintext->cd_length = saved_length;
1030  982          }
1031  983          plaintext->cd_offset = saved_offset;
1032  984  
1033      -/* EXPORT DELETE END */
1034      -
1035  985          /* LINTED */
1036  986          return (ret);
1037  987  }
1038  988  
1039  989  /*
1040  990   * KCF software provider context template entry points.
1041  991   */
1042  992  /* ARGSUSED */
1043  993  static int
1044  994  des_create_ctx_template(crypto_provider_handle_t provider,
1045  995      crypto_mechanism_t *mechanism, crypto_key_t *key,
1046  996      crypto_spi_ctx_template_t *tmpl, size_t *tmpl_size, crypto_req_handle_t req)
1047  997  {
1048  998  
1049      -/* EXPORT DELETE START */
1050      -
1051  999          des_strength_t strength;
1052 1000          void *keysched;
1053 1001          size_t size;
1054 1002          int rv;
1055 1003  
1056 1004          switch (mechanism->cm_type) {
1057 1005          case DES_ECB_MECH_INFO_TYPE:
1058 1006                  strength = DES;
1059 1007                  break;
1060 1008          case DES_CBC_MECH_INFO_TYPE:
↓ open down ↓ 20 lines elided ↑ open up ↑
1081 1029           */
1082 1030          if ((rv = init_keysched(key, keysched, strength)) != CRYPTO_SUCCESS) {
1083 1031                  bzero(keysched, size);
1084 1032                  kmem_free(keysched, size);
1085 1033                  return (rv);
1086 1034          }
1087 1035  
1088 1036          *tmpl = keysched;
1089 1037          *tmpl_size = size;
1090 1038  
1091      -/* EXPORT DELETE END */
1092      -
1093 1039          return (CRYPTO_SUCCESS);
1094 1040  }
1095 1041  
1096 1042  /* ARGSUSED */
1097 1043  static int
1098 1044  des_free_context(crypto_ctx_t *ctx)
1099 1045  {
1100      -
1101      -/* EXPORT DELETE START */
1102      -
1103 1046          des_ctx_t *des_ctx = ctx->cc_provider_private;
1104 1047  
1105 1048          if (des_ctx != NULL) {
1106 1049                  if (des_ctx->dc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
1107 1050                          ASSERT(des_ctx->dc_keysched_len != 0);
1108 1051                          bzero(des_ctx->dc_keysched, des_ctx->dc_keysched_len);
1109 1052                          kmem_free(des_ctx->dc_keysched,
1110 1053                              des_ctx->dc_keysched_len);
1111 1054                  }
1112 1055                  crypto_free_mode_ctx(des_ctx);
1113 1056                  ctx->cc_provider_private = NULL;
1114 1057          }
1115 1058  
1116      -/* EXPORT DELETE END */
1117      -
1118 1059          return (CRYPTO_SUCCESS);
1119 1060  }
1120 1061  
1121 1062  /*
1122 1063   * Pass it to des_keycheck() which will
1123 1064   * fix it (parity bits), and check if the fixed key is weak.
1124 1065   */
1125 1066  /* ARGSUSED */
1126 1067  static int
1127 1068  des_key_check(crypto_provider_handle_t pd, crypto_mechanism_t *mech,
1128 1069      crypto_key_t *key)
1129 1070  {
1130      -
1131      -/* EXPORT DELETE START */
1132      -
1133 1071          int expectedkeylen;
1134 1072          des_strength_t strength;
1135 1073          uint8_t keydata[DES3_MAX_KEY_LEN];
1136 1074  
1137 1075          if ((mech == NULL) || (key == NULL))
1138 1076                  return (CRYPTO_ARGUMENTS_BAD);
1139 1077  
1140 1078          switch (mech->cm_type) {
1141 1079          case DES_ECB_MECH_INFO_TYPE:
1142 1080          case DES_CBC_MECH_INFO_TYPE:
↓ open down ↓ 13 lines elided ↑ open up ↑
1156 1094                  return (CRYPTO_KEY_TYPE_INCONSISTENT);
1157 1095  
1158 1096          if (key->ck_length != expectedkeylen)
1159 1097                  return (CRYPTO_KEY_SIZE_RANGE);
1160 1098  
1161 1099          bcopy(key->ck_data, keydata, CRYPTO_BITS2BYTES(expectedkeylen));
1162 1100  
1163 1101          if (des_keycheck(keydata, strength, key->ck_data) == B_FALSE)
1164 1102                  return (CRYPTO_WEAK_KEY);
1165 1103  
1166      -/* EXPORT DELETE END */
1167      -
1168 1104          return (CRYPTO_SUCCESS);
1169 1105  }
1170 1106  
1171 1107  /* ARGSUSED */
1172 1108  static int
1173 1109  des_common_init_ctx(des_ctx_t *des_ctx, crypto_spi_ctx_template_t *template,
1174 1110      crypto_mechanism_t *mechanism, crypto_key_t *key, des_strength_t strength,
1175 1111      int kmflag)
1176 1112  {
1177 1113          int rv = CRYPTO_SUCCESS;
1178 1114  
1179      -/* EXPORT DELETE START */
1180      -
1181 1115          void *keysched;
1182 1116          size_t size;
1183 1117  
1184 1118          if (template == NULL) {
1185 1119                  if ((keysched = des_alloc_keysched(&size, strength,
1186 1120                      kmflag)) == NULL)
1187 1121                          return (CRYPTO_HOST_MEMORY);
1188 1122                  /*
1189 1123                   * Initialize key schedule.
1190 1124                   * Key length is stored in the key.
↓ open down ↓ 24 lines elided ↑ open up ↑
1215 1149                  des_ctx->dc_flags |= ECB_MODE;
1216 1150          }
1217 1151  
1218 1152          if (rv != CRYPTO_SUCCESS) {
1219 1153                  if (des_ctx->dc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
1220 1154                          bzero(keysched, size);
1221 1155                          kmem_free(keysched, size);
1222 1156                  }
1223 1157          }
1224 1158  
1225      -/* EXPORT DELETE END */
1226      -
1227 1159          return (rv);
1228 1160  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX