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


  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #ifndef _KERNEL
  27 #include <strings.h>
  28 #include <limits.h>
  29 #include <assert.h>
  30 #include <security/cryptoki.h>
  31 #endif
  32 
  33 #include <sys/types.h>
  34 #include <sys/kmem.h>
  35 #include <modes/modes.h>
  36 #include <sys/crypto/common.h>
  37 #include <sys/crypto/impl.h>
  38 





  39 /*
  40  * Encrypt multiple blocks of data in CCM mode.  Decrypt for CCM mode
  41  * is done in another function.
  42  */
  43 int
  44 ccm_mode_encrypt_contiguous_blocks(ccm_ctx_t *ctx, char *data, size_t length,
  45     crypto_data_t *out, size_t block_size,
  46     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
  47     void (*copy_block)(uint8_t *, uint8_t *),
  48     void (*xor_block)(uint8_t *, uint8_t *))
  49 {
  50         size_t remainder = length;
  51         size_t need;
  52         uint8_t *datap = (uint8_t *)data;
  53         uint8_t *blockp;
  54         uint8_t *lastp;
  55         void *iov_or_mp;
  56         offset_t offset;
  57         uint8_t *out_data_1;
  58         uint8_t *out_data_2;
  59         size_t out_data_1_len;
  60         uint64_t counter;
  61         uint8_t *mac_buf;
  62 #ifdef _LITTLE_ENDIAN
  63         uint8_t *p;
  64 #endif
  65 
  66         if (length + ctx->ccm_remainder_len < block_size) {
  67                 /* accumulate bytes here and return */
  68                 bcopy(datap,
  69                     (uint8_t *)ctx->ccm_remainder + ctx->ccm_remainder_len,
  70                     length);
  71                 ctx->ccm_remainder_len += length;
  72                 ctx->ccm_copy_to = datap;
  73                 return (CRYPTO_SUCCESS);
  74         }
  75 
  76         lastp = (uint8_t *)ctx->ccm_cb;
  77         if (out != NULL)
  78                 crypto_init_ptrs(out, &iov_or_mp, &offset);
  79 
  80         mac_buf = (uint8_t *)ctx->ccm_mac_buf;
  81 
  82         do {
  83                 /* Unprocessed data from last call. */
  84                 if (ctx->ccm_remainder_len > 0) {


  97 
  98                 /*
  99                  * do CBC MAC
 100                  *
 101                  * XOR the previous cipher block current clear block.
 102                  * mac_buf always contain previous cipher block.
 103                  */
 104                 xor_block(blockp, mac_buf);
 105                 encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf);
 106 
 107                 /* ccm_cb is the counter block */
 108                 encrypt_block(ctx->ccm_keysched, (uint8_t *)ctx->ccm_cb,
 109                     (uint8_t *)ctx->ccm_tmp);
 110 
 111                 lastp = (uint8_t *)ctx->ccm_tmp;
 112 
 113                 /*
 114                  * Increment counter. Counter bits are confined
 115                  * to the bottom 64 bits of the counter block.
 116                  */
 117                 counter = ctx->ccm_cb[1] & ctx->ccm_counter_mask;
 118 #ifdef _LITTLE_ENDIAN
 119                 p = (uint8_t *)&counter;
 120                 counter = (((uint64_t)p[0] << 56) |
 121                     ((uint64_t)p[1] << 48) |
 122                     ((uint64_t)p[2] << 40) |
 123                     ((uint64_t)p[3] << 32) |
 124                     ((uint64_t)p[4] << 24) |
 125                     ((uint64_t)p[5] << 16) |
 126                     ((uint64_t)p[6] << 8) |
 127                     (uint64_t)p[7]);
 128 #endif
 129                 counter++;
 130 #ifdef _LITTLE_ENDIAN
 131                 counter = (((uint64_t)p[0] << 56) |
 132                     ((uint64_t)p[1] << 48) |
 133                     ((uint64_t)p[2] << 40) |
 134                     ((uint64_t)p[3] << 32) |
 135                     ((uint64_t)p[4] << 24) |
 136                     ((uint64_t)p[5] << 16) |
 137                     ((uint64_t)p[6] << 8) |
 138                     (uint64_t)p[7]);
 139 #endif
 140                 counter &= ctx->ccm_counter_mask;
 141                 ctx->ccm_cb[1] =
 142                     (ctx->ccm_cb[1] & ~(ctx->ccm_counter_mask)) | counter;
 143 
 144                 /*
 145                  * XOR encrypted counter block with the current clear block.
 146                  */
 147                 xor_block(blockp, lastp);
 148 
 149                 ctx->ccm_processed_data_len += block_size;
 150 
 151                 if (out == NULL) {
 152                         if (ctx->ccm_remainder_len > 0) {
 153                                 bcopy(blockp, ctx->ccm_copy_to,
 154                                     ctx->ccm_remainder_len);
 155                                 bcopy(blockp + ctx->ccm_remainder_len, datap,
 156                                     need);
 157                         }
 158                 } else {
 159                         crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1,


 299                         if (out_data_1_len < ctx->ccm_remainder_len) {
 300 
 301                                 size_t data_2_len_used;
 302 
 303                                 bcopy(macp, out_data_1, out_data_1_len);
 304 
 305                                 data_2_len_used = ctx->ccm_remainder_len
 306                                     - out_data_1_len;
 307 
 308                                 bcopy((uint8_t *)macp + out_data_1_len,
 309                                     out_data_2, data_2_len_used);
 310                                 bcopy(ccm_mac_p, out_data_2 + data_2_len_used,
 311                                     ctx->ccm_mac_len);
 312                         } else {
 313                                 bcopy(macp, out_data_1, out_data_1_len);
 314                                 if (out_data_1_len == ctx->ccm_remainder_len) {
 315                                         /* mac will be in out_data_2 */
 316                                         bcopy(ccm_mac_p, out_data_2,
 317                                             ctx->ccm_mac_len);
 318                                 } else {
 319                                         size_t len_not_used
 320                                             = out_data_1_len -
 321                                             ctx->ccm_remainder_len;
 322                                         /*
 323                                          * part of mac in will be in
 324                                          * out_data_1, part of the mac will be
 325                                          * in out_data_2
 326                                          */
 327                                         bcopy(ccm_mac_p,
 328                                             out_data_1 + ctx->ccm_remainder_len,
 329                                             len_not_used);
 330                                         bcopy(ccm_mac_p + len_not_used,
 331                                             out_data_2,
 332                                             ctx->ccm_mac_len - len_not_used);
 333 
 334                                 }
 335                         }
 336                 }
 337         } else {
 338                 /* copy block to where it belongs */
 339                 bcopy(ccm_mac_p, out_data_1, out_data_1_len);
 340                 if (out_data_2 != NULL) {


 477 
 478                         if (need > remainder)
 479                                 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
 480 
 481                         bcopy(datap, &((uint8_t *)ctx->ccm_remainder)
 482                             [ctx->ccm_remainder_len], need);
 483 
 484                         blockp = (uint8_t *)ctx->ccm_remainder;
 485                 } else {
 486                         blockp = datap;
 487                 }
 488 
 489                 /* Calculate the counter mode, ccm_cb is the counter block */
 490                 cbp = (uint8_t *)ctx->ccm_tmp;
 491                 encrypt_block(ctx->ccm_keysched, (uint8_t *)ctx->ccm_cb, cbp);
 492 
 493                 /*
 494                  * Increment counter.
 495                  * Counter bits are confined to the bottom 64 bits
 496                  */
 497                 counter = ctx->ccm_cb[1] & ctx->ccm_counter_mask;
 498 #ifdef _LITTLE_ENDIAN
 499                 p = (uint8_t *)&counter;
 500                 counter = (((uint64_t)p[0] << 56) |
 501                     ((uint64_t)p[1] << 48) |
 502                     ((uint64_t)p[2] << 40) |
 503                     ((uint64_t)p[3] << 32) |
 504                     ((uint64_t)p[4] << 24) |
 505                     ((uint64_t)p[5] << 16) |
 506                     ((uint64_t)p[6] << 8) |
 507                     (uint64_t)p[7]);
 508 #endif
 509                 counter++;
 510 #ifdef _LITTLE_ENDIAN
 511                 counter = (((uint64_t)p[0] << 56) |
 512                     ((uint64_t)p[1] << 48) |
 513                     ((uint64_t)p[2] << 40) |
 514                     ((uint64_t)p[3] << 32) |
 515                     ((uint64_t)p[4] << 24) |
 516                     ((uint64_t)p[5] << 16) |
 517                     ((uint64_t)p[6] << 8) |
 518                     (uint64_t)p[7]);
 519 #endif
 520                 counter &= ctx->ccm_counter_mask;
 521                 ctx->ccm_cb[1] =
 522                     (ctx->ccm_cb[1] & ~(ctx->ccm_counter_mask)) | counter;
 523 
 524                 /* XOR with the ciphertext */
 525                 xor_block(blockp, cbp);
 526 
 527                 /* Copy the plaintext to the "holding buffer" */
 528                 resultp = (uint8_t *)ctx->ccm_pt_buf +
 529                     ctx->ccm_processed_data_len;
 530                 copy_block(cbp, resultp);
 531 
 532                 ctx->ccm_processed_data_len += block_size;
 533 
 534                 ctx->ccm_lastp = blockp;
 535 
 536                 /* Update pointer to next block of data to be processed. */
 537                 if (ctx->ccm_remainder_len != 0) {
 538                         datap += need;
 539                         ctx->ccm_remainder_len = 0;


 687  * Format the first block used in CBC-MAC (B0) and the initial counter
 688  * block based on formatting functions and counter generation functions
 689  * specified in RFC 3610 and NIST publication 800-38C, appendix A
 690  *
 691  * b0 is the first block used in CBC-MAC
 692  * cb0 is the first counter block
 693  *
 694  * It's assumed that the arguments b0 and cb0 are preallocated AES blocks
 695  *
 696  */
 697 static void
 698 ccm_format_initial_blocks(uchar_t *nonce, ulong_t nonceSize,
 699     ulong_t authDataSize, uint8_t *b0, ccm_ctx_t *aes_ctx)
 700 {
 701         uint64_t payloadSize;
 702         uint8_t t, q, have_adata = 0;
 703         size_t limit;
 704         int i, j, k;
 705         uint64_t mask = 0;
 706         uint8_t *cb;
 707 #ifdef _LITTLE_ENDIAN
 708         uint8_t *p8;
 709 #endif  /* _LITTLE_ENDIAN */
 710 
 711         q = (uint8_t)((15 - nonceSize) & 0xFF);
 712         t = (uint8_t)((aes_ctx->ccm_mac_len) & 0xFF);
 713 
 714         /* Construct the first octet of b0 */
 715         if (authDataSize > 0) {
 716                 have_adata = 1;
 717         }
 718         b0[0] = (have_adata << 6) | (((t - 2)  / 2) << 3) | (q - 1);
 719 
 720         /* copy the nonce value into b0 */
 721         bcopy(nonce, &(b0[1]), nonceSize);
 722 
 723         /* store the length of the payload into b0 */
 724         bzero(&(b0[1+nonceSize]), q);
 725 
 726         payloadSize = aes_ctx->ccm_data_len;
 727         limit = 8 < q ? 8 : q;
 728 
 729         for (i = 0, j = 0, k = 15; i < limit; i++, j += 8, k--) {


 731         }
 732 
 733         /* format the counter block */
 734 
 735         cb = (uint8_t *)aes_ctx->ccm_cb;
 736 
 737         cb[0] = 0x07 & (q-1); /* first byte */
 738 
 739         /* copy the nonce value into the counter block */
 740         bcopy(nonce, &(cb[1]), nonceSize);
 741 
 742         bzero(&(cb[1+nonceSize]), q);
 743 
 744         /* Create the mask for the counter field based on the size of nonce */
 745         q <<= 3;
 746         while (q-- > 0) {
 747                 mask |= (1ULL << q);
 748         }
 749 
 750 #ifdef _LITTLE_ENDIAN
 751         p8 = (uint8_t *)&mask;
 752         mask = (((uint64_t)p8[0] << 56) |
 753             ((uint64_t)p8[1] << 48) |
 754             ((uint64_t)p8[2] << 40) |
 755             ((uint64_t)p8[3] << 32) |
 756             ((uint64_t)p8[4] << 24) |
 757             ((uint64_t)p8[5] << 16) |
 758             ((uint64_t)p8[6] << 8) |
 759             (uint64_t)p8[7]);
 760 #endif
 761         aes_ctx->ccm_counter_mask = mask;
 762 
 763         /*
 764          * During calculation, we start using counter block 1, we will
 765          * set it up right here.
 766          * We can just set the last byte to have the value 1, because
 767          * even with the biggest nonce of 13, the last byte of the
 768          * counter block will be used for the counter value.
 769          */
 770         cb[15] = 0x01;
 771 }
 772 
 773 /*
 774  * Encode the length of the associated data as
 775  * specified in RFC 3610 and NIST publication 800-38C, appendix A
 776  */
 777 static void
 778 encode_adata_len(ulong_t auth_data_len, uint8_t *encoded, size_t *encoded_len)
 779 {







 780         if (auth_data_len < ((1ULL<<16) - (1ULL<<8))) {
 781                 /* 0 < a < (2^16-2^8) */
 782                 *encoded_len = 2;
 783                 encoded[0] = (auth_data_len & 0xff00) >> 8;
 784                 encoded[1] = auth_data_len & 0xff;
 785 
 786         } else if ((auth_data_len >= ((1ULL<<16) - (1ULL<<8))) &&
 787             (auth_data_len < (1ULL << 31))) {
 788                 /* (2^16-2^8) <= a < 2^32 */
 789                 *encoded_len = 6;
 790                 encoded[0] = 0xff;
 791                 encoded[1] = 0xfe;




 792                 encoded[2] = (auth_data_len & 0xff000000) >> 24;
 793                 encoded[3] = (auth_data_len & 0xff0000) >> 16;
 794                 encoded[4] = (auth_data_len & 0xff00) >> 8;
 795                 encoded[5] = auth_data_len & 0xff;


 796 #ifdef _LP64
 797         } else {
 798                 /* 2^32 <= a < 2^64 */
 799                 *encoded_len = 10;
 800                 encoded[0] = 0xff;
 801                 encoded[1] = 0xff;




 802                 encoded[2] = (auth_data_len & 0xff00000000000000) >> 56;
 803                 encoded[3] = (auth_data_len & 0xff000000000000) >> 48;
 804                 encoded[4] = (auth_data_len & 0xff0000000000) >> 40;
 805                 encoded[5] = (auth_data_len & 0xff00000000) >> 32;
 806                 encoded[6] = (auth_data_len & 0xff000000) >> 24;
 807                 encoded[7] = (auth_data_len & 0xff0000) >> 16;
 808                 encoded[8] = (auth_data_len & 0xff00) >> 8;
 809                 encoded[9] = auth_data_len & 0xff;

 810 #endif  /* _LP64 */
 811         }
 812 }
 813 
 814 /*
 815  * The following function should be call at encrypt or decrypt init time
 816  * for AES CCM mode.
 817  */
 818 int
 819 ccm_init(ccm_ctx_t *ctx, unsigned char *nonce, size_t nonce_len,
 820     unsigned char *auth_data, size_t auth_data_len, size_t block_size,
 821     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
 822     void (*xor_block)(uint8_t *, uint8_t *))
 823 {
 824         uint8_t *mac_buf, *datap, *ivp, *authp;
 825         size_t remainder, processed;
 826         uint8_t encoded_a[10]; /* max encoded auth data length is 10 octets */
 827         size_t encoded_a_len = 0;
 828 
 829         mac_buf = (uint8_t *)&(ctx->ccm_mac_buf);




  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #ifndef _KERNEL
  27 #include <strings.h>
  28 #include <limits.h>
  29 #include <assert.h>
  30 #include <security/cryptoki.h>
  31 #endif
  32 
  33 #include <sys/types.h>
  34 #include <sys/kmem.h>
  35 #include <modes/modes.h>
  36 #include <sys/crypto/common.h>
  37 #include <sys/crypto/impl.h>
  38 
  39 #if defined(__i386) || defined(__amd64)
  40 #include <sys/byteorder.h>
  41 #define UNALIGNED_POINTERS_PERMITTED
  42 #endif
  43 
  44 /*
  45  * Encrypt multiple blocks of data in CCM mode.  Decrypt for CCM mode
  46  * is done in another function.
  47  */
  48 int
  49 ccm_mode_encrypt_contiguous_blocks(ccm_ctx_t *ctx, char *data, size_t length,
  50     crypto_data_t *out, size_t block_size,
  51     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
  52     void (*copy_block)(uint8_t *, uint8_t *),
  53     void (*xor_block)(uint8_t *, uint8_t *))
  54 {
  55         size_t remainder = length;
  56         size_t need;
  57         uint8_t *datap = (uint8_t *)data;
  58         uint8_t *blockp;
  59         uint8_t *lastp;
  60         void *iov_or_mp;
  61         offset_t offset;
  62         uint8_t *out_data_1;
  63         uint8_t *out_data_2;
  64         size_t out_data_1_len;
  65         uint64_t counter;
  66         uint8_t *mac_buf;



  67 
  68         if (length + ctx->ccm_remainder_len < block_size) {
  69                 /* accumulate bytes here and return */
  70                 bcopy(datap,
  71                     (uint8_t *)ctx->ccm_remainder + ctx->ccm_remainder_len,
  72                     length);
  73                 ctx->ccm_remainder_len += length;
  74                 ctx->ccm_copy_to = datap;
  75                 return (CRYPTO_SUCCESS);
  76         }
  77 
  78         lastp = (uint8_t *)ctx->ccm_cb;
  79         if (out != NULL)
  80                 crypto_init_ptrs(out, &iov_or_mp, &offset);
  81 
  82         mac_buf = (uint8_t *)ctx->ccm_mac_buf;
  83 
  84         do {
  85                 /* Unprocessed data from last call. */
  86                 if (ctx->ccm_remainder_len > 0) {


  99 
 100                 /*
 101                  * do CBC MAC
 102                  *
 103                  * XOR the previous cipher block current clear block.
 104                  * mac_buf always contain previous cipher block.
 105                  */
 106                 xor_block(blockp, mac_buf);
 107                 encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf);
 108 
 109                 /* ccm_cb is the counter block */
 110                 encrypt_block(ctx->ccm_keysched, (uint8_t *)ctx->ccm_cb,
 111                     (uint8_t *)ctx->ccm_tmp);
 112 
 113                 lastp = (uint8_t *)ctx->ccm_tmp;
 114 
 115                 /*
 116                  * Increment counter. Counter bits are confined
 117                  * to the bottom 64 bits of the counter block.
 118                  */

 119 #ifdef _LITTLE_ENDIAN
 120                 counter = ntohll(ctx->ccm_cb[1] & ctx->ccm_counter_mask);
 121                 counter = htonll(counter + 1);
 122 #else
 123                 counter = ctx->ccm_cb[1] & ctx->ccm_counter_mask;






 124                 counter++;
 125 #endif  /* _LITTLE_ENDIAN */









 126                 counter &= ctx->ccm_counter_mask;
 127                 ctx->ccm_cb[1] =
 128                     (ctx->ccm_cb[1] & ~(ctx->ccm_counter_mask)) | counter;
 129 
 130                 /*
 131                  * XOR encrypted counter block with the current clear block.
 132                  */
 133                 xor_block(blockp, lastp);
 134 
 135                 ctx->ccm_processed_data_len += block_size;
 136 
 137                 if (out == NULL) {
 138                         if (ctx->ccm_remainder_len > 0) {
 139                                 bcopy(blockp, ctx->ccm_copy_to,
 140                                     ctx->ccm_remainder_len);
 141                                 bcopy(blockp + ctx->ccm_remainder_len, datap,
 142                                     need);
 143                         }
 144                 } else {
 145                         crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1,


 285                         if (out_data_1_len < ctx->ccm_remainder_len) {
 286 
 287                                 size_t data_2_len_used;
 288 
 289                                 bcopy(macp, out_data_1, out_data_1_len);
 290 
 291                                 data_2_len_used = ctx->ccm_remainder_len
 292                                     - out_data_1_len;
 293 
 294                                 bcopy((uint8_t *)macp + out_data_1_len,
 295                                     out_data_2, data_2_len_used);
 296                                 bcopy(ccm_mac_p, out_data_2 + data_2_len_used,
 297                                     ctx->ccm_mac_len);
 298                         } else {
 299                                 bcopy(macp, out_data_1, out_data_1_len);
 300                                 if (out_data_1_len == ctx->ccm_remainder_len) {
 301                                         /* mac will be in out_data_2 */
 302                                         bcopy(ccm_mac_p, out_data_2,
 303                                             ctx->ccm_mac_len);
 304                                 } else {
 305                                         size_t len_not_used = out_data_1_len -

 306                                             ctx->ccm_remainder_len;
 307                                         /*
 308                                          * part of mac in will be in
 309                                          * out_data_1, part of the mac will be
 310                                          * in out_data_2
 311                                          */
 312                                         bcopy(ccm_mac_p,
 313                                             out_data_1 + ctx->ccm_remainder_len,
 314                                             len_not_used);
 315                                         bcopy(ccm_mac_p + len_not_used,
 316                                             out_data_2,
 317                                             ctx->ccm_mac_len - len_not_used);
 318 
 319                                 }
 320                         }
 321                 }
 322         } else {
 323                 /* copy block to where it belongs */
 324                 bcopy(ccm_mac_p, out_data_1, out_data_1_len);
 325                 if (out_data_2 != NULL) {


 462 
 463                         if (need > remainder)
 464                                 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
 465 
 466                         bcopy(datap, &((uint8_t *)ctx->ccm_remainder)
 467                             [ctx->ccm_remainder_len], need);
 468 
 469                         blockp = (uint8_t *)ctx->ccm_remainder;
 470                 } else {
 471                         blockp = datap;
 472                 }
 473 
 474                 /* Calculate the counter mode, ccm_cb is the counter block */
 475                 cbp = (uint8_t *)ctx->ccm_tmp;
 476                 encrypt_block(ctx->ccm_keysched, (uint8_t *)ctx->ccm_cb, cbp);
 477 
 478                 /*
 479                  * Increment counter.
 480                  * Counter bits are confined to the bottom 64 bits
 481                  */

 482 #ifdef _LITTLE_ENDIAN
 483                 counter = ntohll(ctx->ccm_cb[1] & ctx->ccm_counter_mask);
 484                 counter = htonll(counter + 1);
 485 #else
 486                 counter = ctx->ccm_cb[1] & ctx->ccm_counter_mask;






 487                 counter++;
 488 #endif  /* _LITTLE_ENDIAN */









 489                 counter &= ctx->ccm_counter_mask;
 490                 ctx->ccm_cb[1] =
 491                     (ctx->ccm_cb[1] & ~(ctx->ccm_counter_mask)) | counter;
 492 
 493                 /* XOR with the ciphertext */
 494                 xor_block(blockp, cbp);
 495 
 496                 /* Copy the plaintext to the "holding buffer" */
 497                 resultp = (uint8_t *)ctx->ccm_pt_buf +
 498                     ctx->ccm_processed_data_len;
 499                 copy_block(cbp, resultp);
 500 
 501                 ctx->ccm_processed_data_len += block_size;
 502 
 503                 ctx->ccm_lastp = blockp;
 504 
 505                 /* Update pointer to next block of data to be processed. */
 506                 if (ctx->ccm_remainder_len != 0) {
 507                         datap += need;
 508                         ctx->ccm_remainder_len = 0;


 656  * Format the first block used in CBC-MAC (B0) and the initial counter
 657  * block based on formatting functions and counter generation functions
 658  * specified in RFC 3610 and NIST publication 800-38C, appendix A
 659  *
 660  * b0 is the first block used in CBC-MAC
 661  * cb0 is the first counter block
 662  *
 663  * It's assumed that the arguments b0 and cb0 are preallocated AES blocks
 664  *
 665  */
 666 static void
 667 ccm_format_initial_blocks(uchar_t *nonce, ulong_t nonceSize,
 668     ulong_t authDataSize, uint8_t *b0, ccm_ctx_t *aes_ctx)
 669 {
 670         uint64_t payloadSize;
 671         uint8_t t, q, have_adata = 0;
 672         size_t limit;
 673         int i, j, k;
 674         uint64_t mask = 0;
 675         uint8_t *cb;



 676 
 677         q = (uint8_t)((15 - nonceSize) & 0xFF);
 678         t = (uint8_t)((aes_ctx->ccm_mac_len) & 0xFF);
 679 
 680         /* Construct the first octet of b0 */
 681         if (authDataSize > 0) {
 682                 have_adata = 1;
 683         }
 684         b0[0] = (have_adata << 6) | (((t - 2)  / 2) << 3) | (q - 1);
 685 
 686         /* copy the nonce value into b0 */
 687         bcopy(nonce, &(b0[1]), nonceSize);
 688 
 689         /* store the length of the payload into b0 */
 690         bzero(&(b0[1+nonceSize]), q);
 691 
 692         payloadSize = aes_ctx->ccm_data_len;
 693         limit = 8 < q ? 8 : q;
 694 
 695         for (i = 0, j = 0, k = 15; i < limit; i++, j += 8, k--) {


 697         }
 698 
 699         /* format the counter block */
 700 
 701         cb = (uint8_t *)aes_ctx->ccm_cb;
 702 
 703         cb[0] = 0x07 & (q-1); /* first byte */
 704 
 705         /* copy the nonce value into the counter block */
 706         bcopy(nonce, &(cb[1]), nonceSize);
 707 
 708         bzero(&(cb[1+nonceSize]), q);
 709 
 710         /* Create the mask for the counter field based on the size of nonce */
 711         q <<= 3;
 712         while (q-- > 0) {
 713                 mask |= (1ULL << q);
 714         }
 715 
 716 #ifdef _LITTLE_ENDIAN
 717         mask = htonll(mask);








 718 #endif
 719         aes_ctx->ccm_counter_mask = mask;
 720 
 721         /*
 722          * During calculation, we start using counter block 1, we will
 723          * set it up right here.
 724          * We can just set the last byte to have the value 1, because
 725          * even with the biggest nonce of 13, the last byte of the
 726          * counter block will be used for the counter value.
 727          */
 728         cb[15] = 0x01;
 729 }
 730 
 731 /*
 732  * Encode the length of the associated data as
 733  * specified in RFC 3610 and NIST publication 800-38C, appendix A
 734  */
 735 static void
 736 encode_adata_len(ulong_t auth_data_len, uint8_t *encoded, size_t *encoded_len)
 737 {
 738 #ifdef UNALIGNED_POINTERS_PERMITTED
 739         uint32_t        *lencoded_ptr;
 740 #ifdef _LP64
 741         uint64_t        *llencoded_ptr;
 742 #endif
 743 #endif  /* UNALIGNED_POINTERS_PERMITTED */
 744 
 745         if (auth_data_len < ((1ULL<<16) - (1ULL<<8))) {
 746                 /* 0 < a < (2^16-2^8) */
 747                 *encoded_len = 2;
 748                 encoded[0] = (auth_data_len & 0xff00) >> 8;
 749                 encoded[1] = auth_data_len & 0xff;
 750 
 751         } else if ((auth_data_len >= ((1ULL<<16) - (1ULL<<8))) &&
 752             (auth_data_len < (1ULL << 31))) {
 753                 /* (2^16-2^8) <= a < 2^32 */
 754                 *encoded_len = 6;
 755                 encoded[0] = 0xff;
 756                 encoded[1] = 0xfe;
 757 #ifdef UNALIGNED_POINTERS_PERMITTED
 758                 lencoded_ptr = (uint32_t *)&encoded[2];
 759                 *lencoded_ptr = htonl(auth_data_len);
 760 #else
 761                 encoded[2] = (auth_data_len & 0xff000000) >> 24;
 762                 encoded[3] = (auth_data_len & 0xff0000) >> 16;
 763                 encoded[4] = (auth_data_len & 0xff00) >> 8;
 764                 encoded[5] = auth_data_len & 0xff;
 765 #endif  /* UNALIGNED_POINTERS_PERMITTED */
 766 
 767 #ifdef _LP64
 768         } else {
 769                 /* 2^32 <= a < 2^64 */
 770                 *encoded_len = 10;
 771                 encoded[0] = 0xff;
 772                 encoded[1] = 0xff;
 773 #ifdef UNALIGNED_POINTERS_PERMITTED
 774                 llencoded_ptr = (uint64_t *)&encoded[2];
 775                 *llencoded_ptr = htonl(auth_data_len);
 776 #else
 777                 encoded[2] = (auth_data_len & 0xff00000000000000) >> 56;
 778                 encoded[3] = (auth_data_len & 0xff000000000000) >> 48;
 779                 encoded[4] = (auth_data_len & 0xff0000000000) >> 40;
 780                 encoded[5] = (auth_data_len & 0xff00000000) >> 32;
 781                 encoded[6] = (auth_data_len & 0xff000000) >> 24;
 782                 encoded[7] = (auth_data_len & 0xff0000) >> 16;
 783                 encoded[8] = (auth_data_len & 0xff00) >> 8;
 784                 encoded[9] = auth_data_len & 0xff;
 785 #endif  /* UNALIGNED_POINTERS_PERMITTED */
 786 #endif  /* _LP64 */
 787         }
 788 }
 789 
 790 /*
 791  * The following function should be call at encrypt or decrypt init time
 792  * for AES CCM mode.
 793  */
 794 int
 795 ccm_init(ccm_ctx_t *ctx, unsigned char *nonce, size_t nonce_len,
 796     unsigned char *auth_data, size_t auth_data_len, size_t block_size,
 797     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
 798     void (*xor_block)(uint8_t *, uint8_t *))
 799 {
 800         uint8_t *mac_buf, *datap, *ivp, *authp;
 801         size_t remainder, processed;
 802         uint8_t encoded_a[10]; /* max encoded auth data length is 10 octets */
 803         size_t encoded_a_len = 0;
 804 
 805         mac_buf = (uint8_t *)&(ctx->ccm_mac_buf);