1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  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) {
  85                         need = block_size - ctx->ccm_remainder_len;
  86 
  87                         if (need > remainder)
  88                                 return (CRYPTO_DATA_LEN_RANGE);
  89 
  90                         bcopy(datap, &((uint8_t *)ctx->ccm_remainder)
  91                             [ctx->ccm_remainder_len], need);
  92 
  93                         blockp = (uint8_t *)ctx->ccm_remainder;
  94                 } else {
  95                         blockp = datap;
  96                 }
  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,
 160                             &out_data_1_len, &out_data_2, block_size);
 161 
 162                         /* copy block to where it belongs */
 163                         if (out_data_1_len == block_size) {
 164                                 copy_block(lastp, out_data_1);
 165                         } else {
 166                                 bcopy(lastp, out_data_1, out_data_1_len);
 167                                 if (out_data_2 != NULL) {
 168                                         bcopy(lastp + out_data_1_len,
 169                                             out_data_2,
 170                                             block_size - out_data_1_len);
 171                                 }
 172                         }
 173                         /* update offset */
 174                         out->cd_offset += block_size;
 175                 }
 176 
 177                 /* Update pointer to next block of data to be processed. */
 178                 if (ctx->ccm_remainder_len != 0) {
 179                         datap += need;
 180                         ctx->ccm_remainder_len = 0;
 181                 } else {
 182                         datap += block_size;
 183                 }
 184 
 185                 remainder = (size_t)&data[length] - (size_t)datap;
 186 
 187                 /* Incomplete last block. */
 188                 if (remainder > 0 && remainder < block_size) {
 189                         bcopy(datap, ctx->ccm_remainder, remainder);
 190                         ctx->ccm_remainder_len = remainder;
 191                         ctx->ccm_copy_to = datap;
 192                         goto out;
 193                 }
 194                 ctx->ccm_copy_to = NULL;
 195 
 196         } while (remainder > 0);
 197 
 198 out:
 199         return (CRYPTO_SUCCESS);
 200 }
 201 
 202 void
 203 calculate_ccm_mac(ccm_ctx_t *ctx, uint8_t *ccm_mac,
 204     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *))
 205 {
 206         uint64_t counter;
 207         uint8_t *counterp, *mac_buf;
 208         int i;
 209 
 210         mac_buf = (uint8_t *)ctx->ccm_mac_buf;
 211 
 212         /* first counter block start with index 0 */
 213         counter = 0;
 214         ctx->ccm_cb[1] = (ctx->ccm_cb[1] & ~(ctx->ccm_counter_mask)) | counter;
 215 
 216         counterp = (uint8_t *)ctx->ccm_tmp;
 217         encrypt_block(ctx->ccm_keysched, (uint8_t *)ctx->ccm_cb, counterp);
 218 
 219         /* calculate XOR of MAC with first counter block */
 220         for (i = 0; i < ctx->ccm_mac_len; i++) {
 221                 ccm_mac[i] = mac_buf[i] ^ counterp[i];
 222         }
 223 }
 224 
 225 /* ARGSUSED */
 226 int
 227 ccm_encrypt_final(ccm_ctx_t *ctx, crypto_data_t *out, size_t block_size,
 228     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
 229     void (*xor_block)(uint8_t *, uint8_t *))
 230 {
 231         uint8_t *lastp, *mac_buf, *ccm_mac_p, *macp;
 232         void *iov_or_mp;
 233         offset_t offset;
 234         uint8_t *out_data_1;
 235         uint8_t *out_data_2;
 236         size_t out_data_1_len;
 237         int i;
 238 
 239         if (out->cd_length < (ctx->ccm_remainder_len + ctx->ccm_mac_len)) {
 240                 return (CRYPTO_DATA_LEN_RANGE);
 241         }
 242 
 243         /*
 244          * When we get here, the number of bytes of payload processed
 245          * plus whatever data remains, if any,
 246          * should be the same as the number of bytes that's being
 247          * passed in the argument during init time.
 248          */
 249         if ((ctx->ccm_processed_data_len + ctx->ccm_remainder_len)
 250             != (ctx->ccm_data_len)) {
 251                 return (CRYPTO_DATA_LEN_RANGE);
 252         }
 253 
 254         mac_buf = (uint8_t *)ctx->ccm_mac_buf;
 255 
 256         if (ctx->ccm_remainder_len > 0) {
 257 
 258                 /* ccm_mac_input_buf is not used for encryption */
 259                 macp = (uint8_t *)ctx->ccm_mac_input_buf;
 260                 bzero(macp, block_size);
 261 
 262                 /* copy remainder to temporary buffer */
 263                 bcopy(ctx->ccm_remainder, macp, ctx->ccm_remainder_len);
 264 
 265                 /* calculate the CBC MAC */
 266                 xor_block(macp, mac_buf);
 267                 encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf);
 268 
 269                 /* calculate the counter mode */
 270                 lastp = (uint8_t *)ctx->ccm_tmp;
 271                 encrypt_block(ctx->ccm_keysched, (uint8_t *)ctx->ccm_cb, lastp);
 272 
 273                 /* XOR with counter block */
 274                 for (i = 0; i < ctx->ccm_remainder_len; i++) {
 275                         macp[i] ^= lastp[i];
 276                 }
 277                 ctx->ccm_processed_data_len += ctx->ccm_remainder_len;
 278         }
 279 
 280         /* Calculate the CCM MAC */
 281         ccm_mac_p = (uint8_t *)ctx->ccm_tmp;
 282         calculate_ccm_mac(ctx, ccm_mac_p, encrypt_block);
 283 
 284         crypto_init_ptrs(out, &iov_or_mp, &offset);
 285         crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1,
 286             &out_data_1_len, &out_data_2,
 287             ctx->ccm_remainder_len + ctx->ccm_mac_len);
 288 
 289         if (ctx->ccm_remainder_len > 0) {
 290 
 291                 /* copy temporary block to where it belongs */
 292                 if (out_data_2 == NULL) {
 293                         /* everything will fit in out_data_1 */
 294                         bcopy(macp, out_data_1, ctx->ccm_remainder_len);
 295                         bcopy(ccm_mac_p, out_data_1 + ctx->ccm_remainder_len,
 296                             ctx->ccm_mac_len);
 297                 } else {
 298 
 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) {
 341                         bcopy(ccm_mac_p + out_data_1_len, out_data_2,
 342                             block_size - out_data_1_len);
 343                 }
 344         }
 345         out->cd_offset += ctx->ccm_remainder_len + ctx->ccm_mac_len;
 346         ctx->ccm_remainder_len = 0;
 347         return (CRYPTO_SUCCESS);
 348 }
 349 
 350 /*
 351  * This will only deal with decrypting the last block of the input that
 352  * might not be a multiple of block length.
 353  */
 354 void
 355 ccm_decrypt_incomplete_block(ccm_ctx_t *ctx,
 356     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *))
 357 {
 358         uint8_t *datap, *outp, *counterp;
 359         int i;
 360 
 361         datap = (uint8_t *)ctx->ccm_remainder;
 362         outp = &((ctx->ccm_pt_buf)[ctx->ccm_processed_data_len]);
 363 
 364         counterp = (uint8_t *)ctx->ccm_tmp;
 365         encrypt_block(ctx->ccm_keysched, (uint8_t *)ctx->ccm_cb, counterp);
 366 
 367         /* XOR with counter block */
 368         for (i = 0; i < ctx->ccm_remainder_len; i++) {
 369                 outp[i] = datap[i] ^ counterp[i];
 370         }
 371 }
 372 
 373 /*
 374  * This will decrypt the cipher text.  However, the plaintext won't be
 375  * returned to the caller.  It will be returned when decrypt_final() is
 376  * called if the MAC matches
 377  */
 378 /* ARGSUSED */
 379 int
 380 ccm_mode_decrypt_contiguous_blocks(ccm_ctx_t *ctx, char *data, size_t length,
 381     crypto_data_t *out, size_t block_size,
 382     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
 383     void (*copy_block)(uint8_t *, uint8_t *),
 384     void (*xor_block)(uint8_t *, uint8_t *))
 385 {
 386         size_t remainder = length;
 387         size_t need;
 388         uint8_t *datap = (uint8_t *)data;
 389         uint8_t *blockp;
 390         uint8_t *cbp;
 391         uint64_t counter;
 392         size_t pt_len, total_decrypted_len, mac_len, pm_len, pd_len;
 393         uint8_t *resultp;
 394 #ifdef _LITTLE_ENDIAN
 395         uint8_t *p;
 396 #endif  /* _LITTLE_ENDIAN */
 397 
 398 
 399         pm_len = ctx->ccm_processed_mac_len;
 400 
 401         if (pm_len > 0) {
 402                 uint8_t *tmp;
 403                 /*
 404                  * all ciphertext has been processed, just waiting for
 405                  * part of the value of the mac
 406                  */
 407                 if ((pm_len + length) > ctx->ccm_mac_len) {
 408                         return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
 409                 }
 410                 tmp = (uint8_t *)ctx->ccm_mac_input_buf;
 411 
 412                 bcopy(datap, tmp + pm_len, length);
 413 
 414                 ctx->ccm_processed_mac_len += length;
 415                 return (CRYPTO_SUCCESS);
 416         }
 417 
 418         /*
 419          * If we decrypt the given data, what total amount of data would
 420          * have been decrypted?
 421          */
 422         pd_len = ctx->ccm_processed_data_len;
 423         total_decrypted_len = pd_len + length + ctx->ccm_remainder_len;
 424 
 425         if (total_decrypted_len >
 426             (ctx->ccm_data_len + ctx->ccm_mac_len)) {
 427                 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
 428         }
 429 
 430         pt_len = ctx->ccm_data_len;
 431 
 432         if (total_decrypted_len > pt_len) {
 433                 /*
 434                  * part of the input will be the MAC, need to isolate that
 435                  * to be dealt with later.  The left-over data in
 436                  * ccm_remainder_len from last time will not be part of the
 437                  * MAC.  Otherwise, it would have already been taken out
 438                  * when this call is made last time.
 439                  */
 440                 size_t pt_part = pt_len - pd_len - ctx->ccm_remainder_len;
 441 
 442                 mac_len = length - pt_part;
 443 
 444                 ctx->ccm_processed_mac_len = mac_len;
 445                 bcopy(data + pt_part, ctx->ccm_mac_input_buf, mac_len);
 446 
 447                 if (pt_part + ctx->ccm_remainder_len < block_size) {
 448                         /*
 449                          * since this is last of the ciphertext, will
 450                          * just decrypt with it here
 451                          */
 452                         bcopy(datap, &((uint8_t *)ctx->ccm_remainder)
 453                             [ctx->ccm_remainder_len], pt_part);
 454                         ctx->ccm_remainder_len += pt_part;
 455                         ccm_decrypt_incomplete_block(ctx, encrypt_block);
 456                         ctx->ccm_remainder_len = 0;
 457                         ctx->ccm_processed_data_len += pt_part;
 458                         return (CRYPTO_SUCCESS);
 459                 } else {
 460                         /* let rest of the code handle this */
 461                         length = pt_part;
 462                 }
 463         } else if (length + ctx->ccm_remainder_len < block_size) {
 464                         /* accumulate bytes here and return */
 465                 bcopy(datap,
 466                     (uint8_t *)ctx->ccm_remainder + ctx->ccm_remainder_len,
 467                     length);
 468                 ctx->ccm_remainder_len += length;
 469                 ctx->ccm_copy_to = datap;
 470                 return (CRYPTO_SUCCESS);
 471         }
 472 
 473         do {
 474                 /* Unprocessed data from last call. */
 475                 if (ctx->ccm_remainder_len > 0) {
 476                         need = block_size - ctx->ccm_remainder_len;
 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;
 540                 } else {
 541                         datap += block_size;
 542                 }
 543 
 544                 remainder = (size_t)&data[length] - (size_t)datap;
 545 
 546                 /* Incomplete last block */
 547                 if (remainder > 0 && remainder < block_size) {
 548                         bcopy(datap, ctx->ccm_remainder, remainder);
 549                         ctx->ccm_remainder_len = remainder;
 550                         ctx->ccm_copy_to = datap;
 551                         if (ctx->ccm_processed_mac_len > 0) {
 552                                 /*
 553                                  * not expecting anymore ciphertext, just
 554                                  * compute plaintext for the remaining input
 555                                  */
 556                                 ccm_decrypt_incomplete_block(ctx,
 557                                     encrypt_block);
 558                                 ctx->ccm_processed_data_len += remainder;
 559                                 ctx->ccm_remainder_len = 0;
 560                         }
 561                         goto out;
 562                 }
 563                 ctx->ccm_copy_to = NULL;
 564 
 565         } while (remainder > 0);
 566 
 567 out:
 568         return (CRYPTO_SUCCESS);
 569 }
 570 
 571 int
 572 ccm_decrypt_final(ccm_ctx_t *ctx, crypto_data_t *out, size_t block_size,
 573     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
 574     void (*copy_block)(uint8_t *, uint8_t *),
 575     void (*xor_block)(uint8_t *, uint8_t *))
 576 {
 577         size_t mac_remain, pt_len;
 578         uint8_t *pt, *mac_buf, *macp, *ccm_mac_p;
 579         void *iov_or_mp;
 580         offset_t offset;
 581         uint8_t *out_data_1, *out_data_2;
 582         size_t out_data_1_len;
 583 
 584         pt_len = ctx->ccm_data_len;
 585 
 586         /* Make sure output buffer can fit all of the plaintext */
 587         if (out->cd_length < pt_len) {
 588                 return (CRYPTO_DATA_LEN_RANGE);
 589         }
 590 
 591         pt = ctx->ccm_pt_buf;
 592         mac_remain = ctx->ccm_processed_data_len;
 593         mac_buf = (uint8_t *)ctx->ccm_mac_buf;
 594 
 595         macp = (uint8_t *)ctx->ccm_tmp;
 596 
 597         while (mac_remain > 0) {
 598 
 599                 if (mac_remain < block_size) {
 600                         bzero(macp, block_size);
 601                         bcopy(pt, macp, mac_remain);
 602                         mac_remain = 0;
 603                 } else {
 604                         copy_block(pt, macp);
 605                         mac_remain -= block_size;
 606                         pt += block_size;
 607                 }
 608 
 609                 /* calculate the CBC MAC */
 610                 xor_block(macp, mac_buf);
 611                 encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf);
 612         }
 613 
 614         /* Calculate the CCM MAC */
 615         ccm_mac_p = (uint8_t *)ctx->ccm_tmp;
 616         calculate_ccm_mac((ccm_ctx_t *)ctx, ccm_mac_p, encrypt_block);
 617 
 618         /* compare the input CCM MAC value with what we calculated */
 619         if (bcmp(ctx->ccm_mac_input_buf, ccm_mac_p, ctx->ccm_mac_len)) {
 620                 /* They don't match */
 621                 return (CRYPTO_INVALID_MAC);
 622         } else {
 623                 crypto_init_ptrs(out, &iov_or_mp, &offset);
 624                 crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1,
 625                     &out_data_1_len, &out_data_2, pt_len);
 626                 bcopy(ctx->ccm_pt_buf, out_data_1, out_data_1_len);
 627                 if (out_data_2 != NULL) {
 628                         bcopy((ctx->ccm_pt_buf) + out_data_1_len,
 629                             out_data_2, pt_len - out_data_1_len);
 630                 }
 631                 out->cd_offset += pt_len;
 632         }
 633         return (CRYPTO_SUCCESS);
 634 }
 635 
 636 int
 637 ccm_validate_args(CK_AES_CCM_PARAMS *ccm_param, boolean_t is_encrypt_init)
 638 {
 639         size_t macSize, nonceSize;
 640         uint8_t q;
 641         uint64_t maxValue;
 642 
 643         /*
 644          * Check the length of the MAC.  The only valid
 645          * lengths for the MAC are: 4, 6, 8, 10, 12, 14, 16
 646          */
 647         macSize = ccm_param->ulMACSize;
 648         if ((macSize < 4) || (macSize > 16) || ((macSize % 2) != 0)) {
 649                 return (CRYPTO_MECHANISM_PARAM_INVALID);
 650         }
 651 
 652         /* Check the nonce length.  Valid values are 7, 8, 9, 10, 11, 12, 13 */
 653         nonceSize = ccm_param->ulNonceSize;
 654         if ((nonceSize < 7) || (nonceSize > 13)) {
 655                 return (CRYPTO_MECHANISM_PARAM_INVALID);
 656         }
 657 
 658         /* q is the length of the field storing the length, in bytes */
 659         q = (uint8_t)((15 - nonceSize) & 0xFF);
 660 
 661 
 662         /*
 663          * If it is decrypt, need to make sure size of ciphertext is at least
 664          * bigger than MAC len
 665          */
 666         if ((!is_encrypt_init) && (ccm_param->ulDataSize < macSize)) {
 667                 return (CRYPTO_MECHANISM_PARAM_INVALID);
 668         }
 669 
 670         /*
 671          * Check to make sure the length of the payload is within the
 672          * range of values allowed by q
 673          */
 674         if (q < 8) {
 675                 maxValue = (1ULL << (q * 8)) - 1;
 676         } else {
 677                 maxValue = ULONG_MAX;
 678         }
 679 
 680         if (ccm_param->ulDataSize > maxValue) {
 681                 return (CRYPTO_MECHANISM_PARAM_INVALID);
 682         }
 683         return (CRYPTO_SUCCESS);
 684 }
 685 
 686 /*
 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--) {
 730                 b0[k] = (uint8_t)((payloadSize >> j) & 0xFF);
 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);
 830 
 831         /*
 832          * Format the 1st block for CBC-MAC and construct the
 833          * 1st counter block.
 834          *
 835          * aes_ctx->ccm_iv is used for storing the counter block
 836          * mac_buf will store b0 at this time.
 837          */
 838         ccm_format_initial_blocks(nonce, nonce_len,
 839             auth_data_len, mac_buf, ctx);
 840 
 841         /* The IV for CBC MAC for AES CCM mode is always zero */
 842         ivp = (uint8_t *)ctx->ccm_tmp;
 843         bzero(ivp, block_size);
 844 
 845         xor_block(ivp, mac_buf);
 846 
 847         /* encrypt the nonce */
 848         encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf);
 849 
 850         /* take care of the associated data, if any */
 851         if (auth_data_len == 0) {
 852                 return (CRYPTO_SUCCESS);
 853         }
 854 
 855         encode_adata_len(auth_data_len, encoded_a, &encoded_a_len);
 856 
 857         remainder = auth_data_len;
 858 
 859         /* 1st block: it contains encoded associated data, and some data */
 860         authp = (uint8_t *)ctx->ccm_tmp;
 861         bzero(authp, block_size);
 862         bcopy(encoded_a, authp, encoded_a_len);
 863         processed = block_size - encoded_a_len;
 864         if (processed > auth_data_len) {
 865                 /* in case auth_data is very small */
 866                 processed = auth_data_len;
 867         }
 868         bcopy(auth_data, authp+encoded_a_len, processed);
 869         /* xor with previous buffer */
 870         xor_block(authp, mac_buf);
 871         encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf);
 872         remainder -= processed;
 873         if (remainder == 0) {
 874                 /* a small amount of associated data, it's all done now */
 875                 return (CRYPTO_SUCCESS);
 876         }
 877 
 878         do {
 879                 if (remainder < block_size) {
 880                         /*
 881                          * There's not a block full of data, pad rest of
 882                          * buffer with zero
 883                          */
 884                         bzero(authp, block_size);
 885                         bcopy(&(auth_data[processed]), authp, remainder);
 886                         datap = (uint8_t *)authp;
 887                         remainder = 0;
 888                 } else {
 889                         datap = (uint8_t *)(&(auth_data[processed]));
 890                         processed += block_size;
 891                         remainder -= block_size;
 892                 }
 893 
 894                 xor_block(datap, mac_buf);
 895                 encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf);
 896 
 897         } while (remainder > 0);
 898 
 899         return (CRYPTO_SUCCESS);
 900 }
 901 
 902 int
 903 ccm_init_ctx(ccm_ctx_t *ccm_ctx, char *param, int kmflag,
 904     boolean_t is_encrypt_init, size_t block_size,
 905     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
 906     void (*xor_block)(uint8_t *, uint8_t *))
 907 {
 908         int rv;
 909         CK_AES_CCM_PARAMS *ccm_param;
 910 
 911         if (param != NULL) {
 912                 ccm_param = (CK_AES_CCM_PARAMS *)param;
 913 
 914                 if ((rv = ccm_validate_args(ccm_param,
 915                     is_encrypt_init)) != 0) {
 916                         return (rv);
 917                 }
 918 
 919                 ccm_ctx->ccm_mac_len = ccm_param->ulMACSize;
 920                 if (is_encrypt_init) {
 921                         ccm_ctx->ccm_data_len = ccm_param->ulDataSize;
 922                 } else {
 923                         ccm_ctx->ccm_data_len =
 924                             ccm_param->ulDataSize - ccm_ctx->ccm_mac_len;
 925                         ccm_ctx->ccm_processed_mac_len = 0;
 926                 }
 927                 ccm_ctx->ccm_processed_data_len = 0;
 928 
 929                 ccm_ctx->ccm_flags |= CCM_MODE;
 930         } else {
 931                 rv = CRYPTO_MECHANISM_PARAM_INVALID;
 932                 goto out;
 933         }
 934 
 935         if (ccm_init(ccm_ctx, ccm_param->nonce, ccm_param->ulNonceSize,
 936             ccm_param->authData, ccm_param->ulAuthDataSize, block_size,
 937             encrypt_block, xor_block) != 0) {
 938                 rv = CRYPTO_MECHANISM_PARAM_INVALID;
 939                 goto out;
 940         }
 941         if (!is_encrypt_init) {
 942                 /* allocate buffer for storing decrypted plaintext */
 943 #ifdef _KERNEL
 944                 ccm_ctx->ccm_pt_buf = kmem_alloc(ccm_ctx->ccm_data_len,
 945                     kmflag);
 946 #else
 947                 ccm_ctx->ccm_pt_buf = malloc(ccm_ctx->ccm_data_len);
 948 #endif
 949                 if (ccm_ctx->ccm_pt_buf == NULL) {
 950                         rv = CRYPTO_HOST_MEMORY;
 951                 }
 952         }
 953 out:
 954         return (rv);
 955 }
 956 
 957 void *
 958 ccm_alloc_ctx(int kmflag)
 959 {
 960         ccm_ctx_t *ccm_ctx;
 961 
 962 #ifdef _KERNEL
 963         if ((ccm_ctx = kmem_zalloc(sizeof (ccm_ctx_t), kmflag)) == NULL)
 964 #else
 965         if ((ccm_ctx = calloc(1, sizeof (ccm_ctx_t))) == NULL)
 966 #endif
 967                 return (NULL);
 968 
 969         ccm_ctx->ccm_flags = CCM_MODE;
 970         return (ccm_ctx);
 971 }