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 (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  23  */
  24 
  25 #ifndef _KERNEL
  26 #include <strings.h>
  27 #include <limits.h>
  28 #include <assert.h>
  29 #include <security/cryptoki.h>
  30 #endif
  31 
  32 #include <sys/types.h>
  33 #include <sys/kmem.h>
  34 #include <modes/modes.h>
  35 #include <sys/crypto/common.h>
  36 #include <sys/crypto/impl.h>
  37 #include <sys/byteorder.h>
  38 
  39 #if defined(__i386) || defined(__amd64)
  40 #define UNALIGNED_POINTERS_PERMITTED
  41 #endif
  42 
  43 /*
  44  * Encrypt multiple blocks of data in CCM mode.  Decrypt for CCM mode
  45  * is done in another function.
  46  */
  47 int
  48 ccm_mode_encrypt_contiguous_blocks(ccm_ctx_t *ctx, char *data, size_t length,
  49     crypto_data_t *out, size_t block_size,
  50     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
  51     void (*copy_block)(uint8_t *, uint8_t *),
  52     void (*xor_block)(uint8_t *, uint8_t *))
  53 {
  54         size_t remainder = length;
  55         size_t need;
  56         uint8_t *datap = (uint8_t *)data;
  57         uint8_t *blockp;
  58         uint8_t *lastp;
  59         void *iov_or_mp;
  60         offset_t offset;
  61         uint8_t *out_data_1;
  62         uint8_t *out_data_2;
  63         size_t out_data_1_len;
  64         uint64_t counter;
  65         uint8_t *mac_buf;
  66 
  67         if (length + ctx->ccm_remainder_len < block_size) {
  68                 /* accumulate bytes here and return */
  69                 bcopy(datap,
  70                     (uint8_t *)ctx->ccm_remainder + ctx->ccm_remainder_len,
  71                     length);
  72                 ctx->ccm_remainder_len += length;
  73                 ctx->ccm_copy_to = datap;
  74                 return (CRYPTO_SUCCESS);
  75         }
  76 
  77         lastp = (uint8_t *)ctx->ccm_cb;
  78         if (out != NULL)
  79                 crypto_init_ptrs(out, &iov_or_mp, &offset);
  80 
  81         mac_buf = (uint8_t *)ctx->ccm_mac_buf;
  82 
  83         do {
  84                 /* Unprocessed data from last call. */
  85                 if (ctx->ccm_remainder_len > 0) {
  86                         need = block_size - ctx->ccm_remainder_len;
  87 
  88                         if (need > remainder)
  89                                 return (CRYPTO_DATA_LEN_RANGE);
  90 
  91                         bcopy(datap, &((uint8_t *)ctx->ccm_remainder)
  92                             [ctx->ccm_remainder_len], need);
  93 
  94                         blockp = (uint8_t *)ctx->ccm_remainder;
  95                 } else {
  96                         blockp = datap;
  97                 }
  98 
  99                 /*
 100                  * do CBC MAC
 101                  *
 102                  * XOR the previous cipher block current clear block.
 103                  * mac_buf always contain previous cipher block.
 104                  */
 105                 xor_block(blockp, mac_buf);
 106                 encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf);
 107 
 108                 /* ccm_cb is the counter block */
 109                 encrypt_block(ctx->ccm_keysched, (uint8_t *)ctx->ccm_cb,
 110                     (uint8_t *)ctx->ccm_tmp);
 111 
 112                 lastp = (uint8_t *)ctx->ccm_tmp;
 113 
 114                 /*
 115                  * Increment counter. Counter bits are confined
 116                  * to the bottom 64 bits of the counter block.
 117                  */
 118                 counter = ntohll(ctx->ccm_cb[1] & ctx->ccm_counter_mask);
 119                 counter = htonll(counter + 1);
 120                 counter &= ctx->ccm_counter_mask;
 121                 ctx->ccm_cb[1] =
 122                     (ctx->ccm_cb[1] & ~(ctx->ccm_counter_mask)) | counter;
 123 
 124                 /*
 125                  * XOR encrypted counter block with the current clear block.
 126                  */
 127                 xor_block(blockp, lastp);
 128 
 129                 ctx->ccm_processed_data_len += block_size;
 130 
 131                 if (out == NULL) {
 132                         if (ctx->ccm_remainder_len > 0) {
 133                                 bcopy(blockp, ctx->ccm_copy_to,
 134                                     ctx->ccm_remainder_len);
 135                                 bcopy(blockp + ctx->ccm_remainder_len, datap,
 136                                     need);
 137                         }
 138                 } else {
 139                         crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1,
 140                             &out_data_1_len, &out_data_2, block_size);
 141 
 142                         /* copy block to where it belongs */
 143                         if (out_data_1_len == block_size) {
 144                                 copy_block(lastp, out_data_1);
 145                         } else {
 146                                 bcopy(lastp, out_data_1, out_data_1_len);
 147                                 if (out_data_2 != NULL) {
 148                                         bcopy(lastp + out_data_1_len,
 149                                             out_data_2,
 150                                             block_size - out_data_1_len);
 151                                 }
 152                         }
 153                         /* update offset */
 154                         out->cd_offset += block_size;
 155                 }
 156 
 157                 /* Update pointer to next block of data to be processed. */
 158                 if (ctx->ccm_remainder_len != 0) {
 159                         datap += need;
 160                         ctx->ccm_remainder_len = 0;
 161                 } else {
 162                         datap += block_size;
 163                 }
 164 
 165                 remainder = (size_t)&data[length] - (size_t)datap;
 166 
 167                 /* Incomplete last block. */
 168                 if (remainder > 0 && remainder < block_size) {
 169                         bcopy(datap, ctx->ccm_remainder, remainder);
 170                         ctx->ccm_remainder_len = remainder;
 171                         ctx->ccm_copy_to = datap;
 172                         goto out;
 173                 }
 174                 ctx->ccm_copy_to = NULL;
 175 
 176         } while (remainder > 0);
 177 
 178 out:
 179         return (CRYPTO_SUCCESS);
 180 }
 181 
 182 void
 183 calculate_ccm_mac(ccm_ctx_t *ctx, uint8_t *ccm_mac,
 184     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *))
 185 {
 186         uint64_t counter;
 187         uint8_t *counterp, *mac_buf;
 188         int i;
 189 
 190         mac_buf = (uint8_t *)ctx->ccm_mac_buf;
 191 
 192         /* first counter block start with index 0 */
 193         counter = 0;
 194         ctx->ccm_cb[1] = (ctx->ccm_cb[1] & ~(ctx->ccm_counter_mask)) | counter;
 195 
 196         counterp = (uint8_t *)ctx->ccm_tmp;
 197         encrypt_block(ctx->ccm_keysched, (uint8_t *)ctx->ccm_cb, counterp);
 198 
 199         /* calculate XOR of MAC with first counter block */
 200         for (i = 0; i < ctx->ccm_mac_len; i++) {
 201                 ccm_mac[i] = mac_buf[i] ^ counterp[i];
 202         }
 203 }
 204 
 205 /* ARGSUSED */
 206 int
 207 ccm_encrypt_final(ccm_ctx_t *ctx, crypto_data_t *out, size_t block_size,
 208     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
 209     void (*xor_block)(uint8_t *, uint8_t *))
 210 {
 211         uint8_t *lastp, *mac_buf, *ccm_mac_p, *macp;
 212         void *iov_or_mp;
 213         offset_t offset;
 214         uint8_t *out_data_1;
 215         uint8_t *out_data_2;
 216         size_t out_data_1_len;
 217         int i;
 218 
 219         if (out->cd_length < (ctx->ccm_remainder_len + ctx->ccm_mac_len)) {
 220                 return (CRYPTO_DATA_LEN_RANGE);
 221         }
 222 
 223         /*
 224          * When we get here, the number of bytes of payload processed
 225          * plus whatever data remains, if any,
 226          * should be the same as the number of bytes that's being
 227          * passed in the argument during init time.
 228          */
 229         if ((ctx->ccm_processed_data_len + ctx->ccm_remainder_len)
 230             != (ctx->ccm_data_len)) {
 231                 return (CRYPTO_DATA_LEN_RANGE);
 232         }
 233 
 234         mac_buf = (uint8_t *)ctx->ccm_mac_buf;
 235 
 236         if (ctx->ccm_remainder_len > 0) {
 237 
 238                 /* ccm_mac_input_buf is not used for encryption */
 239                 macp = (uint8_t *)ctx->ccm_mac_input_buf;
 240                 bzero(macp, block_size);
 241 
 242                 /* copy remainder to temporary buffer */
 243                 bcopy(ctx->ccm_remainder, macp, ctx->ccm_remainder_len);
 244 
 245                 /* calculate the CBC MAC */
 246                 xor_block(macp, mac_buf);
 247                 encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf);
 248 
 249                 /* calculate the counter mode */
 250                 lastp = (uint8_t *)ctx->ccm_tmp;
 251                 encrypt_block(ctx->ccm_keysched, (uint8_t *)ctx->ccm_cb, lastp);
 252 
 253                 /* XOR with counter block */
 254                 for (i = 0; i < ctx->ccm_remainder_len; i++) {
 255                         macp[i] ^= lastp[i];
 256                 }
 257                 ctx->ccm_processed_data_len += ctx->ccm_remainder_len;
 258         }
 259 
 260         /* Calculate the CCM MAC */
 261         ccm_mac_p = (uint8_t *)ctx->ccm_tmp;
 262         calculate_ccm_mac(ctx, ccm_mac_p, encrypt_block);
 263 
 264         crypto_init_ptrs(out, &iov_or_mp, &offset);
 265         crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1,
 266             &out_data_1_len, &out_data_2,
 267             ctx->ccm_remainder_len + ctx->ccm_mac_len);
 268 
 269         if (ctx->ccm_remainder_len > 0) {
 270 
 271                 /* copy temporary block to where it belongs */
 272                 if (out_data_2 == NULL) {
 273                         /* everything will fit in out_data_1 */
 274                         bcopy(macp, out_data_1, ctx->ccm_remainder_len);
 275                         bcopy(ccm_mac_p, out_data_1 + ctx->ccm_remainder_len,
 276                             ctx->ccm_mac_len);
 277                 } else {
 278 
 279                         if (out_data_1_len < ctx->ccm_remainder_len) {
 280 
 281                                 size_t data_2_len_used;
 282 
 283                                 bcopy(macp, out_data_1, out_data_1_len);
 284 
 285                                 data_2_len_used = ctx->ccm_remainder_len
 286                                     - out_data_1_len;
 287 
 288                                 bcopy((uint8_t *)macp + out_data_1_len,
 289                                     out_data_2, data_2_len_used);
 290                                 bcopy(ccm_mac_p, out_data_2 + data_2_len_used,
 291                                     ctx->ccm_mac_len);
 292                         } else {
 293                                 bcopy(macp, out_data_1, out_data_1_len);
 294                                 if (out_data_1_len == ctx->ccm_remainder_len) {
 295                                         /* mac will be in out_data_2 */
 296                                         bcopy(ccm_mac_p, out_data_2,
 297                                             ctx->ccm_mac_len);
 298                                 } else {
 299                                         size_t len_not_used = out_data_1_len -
 300                                             ctx->ccm_remainder_len;
 301                                         /*
 302                                          * part of mac in will be in
 303                                          * out_data_1, part of the mac will be
 304                                          * in out_data_2
 305                                          */
 306                                         bcopy(ccm_mac_p,
 307                                             out_data_1 + ctx->ccm_remainder_len,
 308                                             len_not_used);
 309                                         bcopy(ccm_mac_p + len_not_used,
 310                                             out_data_2,
 311                                             ctx->ccm_mac_len - len_not_used);
 312 
 313                                 }
 314                         }
 315                 }
 316         } else {
 317                 /* copy block to where it belongs */
 318                 bcopy(ccm_mac_p, out_data_1, out_data_1_len);
 319                 if (out_data_2 != NULL) {
 320                         bcopy(ccm_mac_p + out_data_1_len, out_data_2,
 321                             block_size - out_data_1_len);
 322                 }
 323         }
 324         out->cd_offset += ctx->ccm_remainder_len + ctx->ccm_mac_len;
 325         ctx->ccm_remainder_len = 0;
 326         return (CRYPTO_SUCCESS);
 327 }
 328 
 329 /*
 330  * This will only deal with decrypting the last block of the input that
 331  * might not be a multiple of block length.
 332  */
 333 void
 334 ccm_decrypt_incomplete_block(ccm_ctx_t *ctx,
 335     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *))
 336 {
 337         uint8_t *datap, *outp, *counterp;
 338         int i;
 339 
 340         datap = (uint8_t *)ctx->ccm_remainder;
 341         outp = &((ctx->ccm_pt_buf)[ctx->ccm_processed_data_len]);
 342 
 343         counterp = (uint8_t *)ctx->ccm_tmp;
 344         encrypt_block(ctx->ccm_keysched, (uint8_t *)ctx->ccm_cb, counterp);
 345 
 346         /* XOR with counter block */
 347         for (i = 0; i < ctx->ccm_remainder_len; i++) {
 348                 outp[i] = datap[i] ^ counterp[i];
 349         }
 350 }
 351 
 352 /*
 353  * This will decrypt the cipher text.  However, the plaintext won't be
 354  * returned to the caller.  It will be returned when decrypt_final() is
 355  * called if the MAC matches
 356  */
 357 /* ARGSUSED */
 358 int
 359 ccm_mode_decrypt_contiguous_blocks(ccm_ctx_t *ctx, char *data, size_t length,
 360     crypto_data_t *out, size_t block_size,
 361     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
 362     void (*copy_block)(uint8_t *, uint8_t *),
 363     void (*xor_block)(uint8_t *, uint8_t *))
 364 {
 365         size_t remainder = length;
 366         size_t need;
 367         uint8_t *datap = (uint8_t *)data;
 368         uint8_t *blockp;
 369         uint8_t *cbp;
 370         uint64_t counter;
 371         size_t pt_len, total_decrypted_len, mac_len, pm_len, pd_len;
 372         uint8_t *resultp;
 373 
 374 
 375         pm_len = ctx->ccm_processed_mac_len;
 376 
 377         if (pm_len > 0) {
 378                 uint8_t *tmp;
 379                 /*
 380                  * all ciphertext has been processed, just waiting for
 381                  * part of the value of the mac
 382                  */
 383                 if ((pm_len + length) > ctx->ccm_mac_len) {
 384                         return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
 385                 }
 386                 tmp = (uint8_t *)ctx->ccm_mac_input_buf;
 387 
 388                 bcopy(datap, tmp + pm_len, length);
 389 
 390                 ctx->ccm_processed_mac_len += length;
 391                 return (CRYPTO_SUCCESS);
 392         }
 393 
 394         /*
 395          * If we decrypt the given data, what total amount of data would
 396          * have been decrypted?
 397          */
 398         pd_len = ctx->ccm_processed_data_len;
 399         total_decrypted_len = pd_len + length + ctx->ccm_remainder_len;
 400 
 401         if (total_decrypted_len >
 402             (ctx->ccm_data_len + ctx->ccm_mac_len)) {
 403                 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
 404         }
 405 
 406         pt_len = ctx->ccm_data_len;
 407 
 408         if (total_decrypted_len > pt_len) {
 409                 /*
 410                  * part of the input will be the MAC, need to isolate that
 411                  * to be dealt with later.  The left-over data in
 412                  * ccm_remainder_len from last time will not be part of the
 413                  * MAC.  Otherwise, it would have already been taken out
 414                  * when this call is made last time.
 415                  */
 416                 size_t pt_part = pt_len - pd_len - ctx->ccm_remainder_len;
 417 
 418                 mac_len = length - pt_part;
 419 
 420                 ctx->ccm_processed_mac_len = mac_len;
 421                 bcopy(data + pt_part, ctx->ccm_mac_input_buf, mac_len);
 422 
 423                 if (pt_part + ctx->ccm_remainder_len < block_size) {
 424                         /*
 425                          * since this is last of the ciphertext, will
 426                          * just decrypt with it here
 427                          */
 428                         bcopy(datap, &((uint8_t *)ctx->ccm_remainder)
 429                             [ctx->ccm_remainder_len], pt_part);
 430                         ctx->ccm_remainder_len += pt_part;
 431                         ccm_decrypt_incomplete_block(ctx, encrypt_block);
 432                         ctx->ccm_processed_data_len += ctx->ccm_remainder_len;
 433                         ctx->ccm_remainder_len = 0;
 434                         return (CRYPTO_SUCCESS);
 435                 } else {
 436                         /* let rest of the code handle this */
 437                         length = pt_part;
 438                 }
 439         } else if (length + ctx->ccm_remainder_len < block_size) {
 440                         /* accumulate bytes here and return */
 441                 bcopy(datap,
 442                     (uint8_t *)ctx->ccm_remainder + ctx->ccm_remainder_len,
 443                     length);
 444                 ctx->ccm_remainder_len += length;
 445                 ctx->ccm_copy_to = datap;
 446                 return (CRYPTO_SUCCESS);
 447         }
 448 
 449         do {
 450                 /* Unprocessed data from last call. */
 451                 if (ctx->ccm_remainder_len > 0) {
 452                         need = block_size - ctx->ccm_remainder_len;
 453 
 454                         if (need > remainder)
 455                                 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
 456 
 457                         bcopy(datap, &((uint8_t *)ctx->ccm_remainder)
 458                             [ctx->ccm_remainder_len], need);
 459 
 460                         blockp = (uint8_t *)ctx->ccm_remainder;
 461                 } else {
 462                         blockp = datap;
 463                 }
 464 
 465                 /* Calculate the counter mode, ccm_cb is the counter block */
 466                 cbp = (uint8_t *)ctx->ccm_tmp;
 467                 encrypt_block(ctx->ccm_keysched, (uint8_t *)ctx->ccm_cb, cbp);
 468 
 469                 /*
 470                  * Increment counter.
 471                  * Counter bits are confined to the bottom 64 bits
 472                  */
 473                 counter = ntohll(ctx->ccm_cb[1] & ctx->ccm_counter_mask);
 474                 counter = htonll(counter + 1);
 475                 counter &= ctx->ccm_counter_mask;
 476                 ctx->ccm_cb[1] =
 477                     (ctx->ccm_cb[1] & ~(ctx->ccm_counter_mask)) | counter;
 478 
 479                 /* XOR with the ciphertext */
 480                 xor_block(blockp, cbp);
 481 
 482                 /* Copy the plaintext to the "holding buffer" */
 483                 resultp = (uint8_t *)ctx->ccm_pt_buf +
 484                     ctx->ccm_processed_data_len;
 485                 copy_block(cbp, resultp);
 486 
 487                 ctx->ccm_processed_data_len += block_size;
 488 
 489                 ctx->ccm_lastp = blockp;
 490 
 491                 /* Update pointer to next block of data to be processed. */
 492                 if (ctx->ccm_remainder_len != 0) {
 493                         datap += need;
 494                         ctx->ccm_remainder_len = 0;
 495                 } else {
 496                         datap += block_size;
 497                 }
 498 
 499                 remainder = (size_t)&data[length] - (size_t)datap;
 500 
 501                 /* Incomplete last block */
 502                 if (remainder > 0 && remainder < block_size) {
 503                         bcopy(datap, ctx->ccm_remainder, remainder);
 504                         ctx->ccm_remainder_len = remainder;
 505                         ctx->ccm_copy_to = datap;
 506                         if (ctx->ccm_processed_mac_len > 0) {
 507                                 /*
 508                                  * not expecting anymore ciphertext, just
 509                                  * compute plaintext for the remaining input
 510                                  */
 511                                 ccm_decrypt_incomplete_block(ctx,
 512                                     encrypt_block);
 513                                 ctx->ccm_processed_data_len += remainder;
 514                                 ctx->ccm_remainder_len = 0;
 515                         }
 516                         goto out;
 517                 }
 518                 ctx->ccm_copy_to = NULL;
 519 
 520         } while (remainder > 0);
 521 
 522 out:
 523         return (CRYPTO_SUCCESS);
 524 }
 525 
 526 int
 527 ccm_decrypt_final(ccm_ctx_t *ctx, crypto_data_t *out, size_t block_size,
 528     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
 529     void (*copy_block)(uint8_t *, uint8_t *),
 530     void (*xor_block)(uint8_t *, uint8_t *))
 531 {
 532         size_t mac_remain, pt_len;
 533         uint8_t *pt, *mac_buf, *macp, *ccm_mac_p;
 534         int rv;
 535 
 536         pt_len = ctx->ccm_data_len;
 537 
 538         /* Make sure output buffer can fit all of the plaintext */
 539         if (out->cd_length < pt_len) {
 540                 return (CRYPTO_DATA_LEN_RANGE);
 541         }
 542 
 543         pt = ctx->ccm_pt_buf;
 544         mac_remain = ctx->ccm_processed_data_len;
 545         mac_buf = (uint8_t *)ctx->ccm_mac_buf;
 546 
 547         macp = (uint8_t *)ctx->ccm_tmp;
 548 
 549         while (mac_remain > 0) {
 550 
 551                 if (mac_remain < block_size) {
 552                         bzero(macp, block_size);
 553                         bcopy(pt, macp, mac_remain);
 554                         mac_remain = 0;
 555                 } else {
 556                         copy_block(pt, macp);
 557                         mac_remain -= block_size;
 558                         pt += block_size;
 559                 }
 560 
 561                 /* calculate the CBC MAC */
 562                 xor_block(macp, mac_buf);
 563                 encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf);
 564         }
 565 
 566         /* Calculate the CCM MAC */
 567         ccm_mac_p = (uint8_t *)ctx->ccm_tmp;
 568         calculate_ccm_mac((ccm_ctx_t *)ctx, ccm_mac_p, encrypt_block);
 569 
 570         /* compare the input CCM MAC value with what we calculated */
 571         if (bcmp(ctx->ccm_mac_input_buf, ccm_mac_p, ctx->ccm_mac_len)) {
 572                 /* They don't match */
 573                 return (CRYPTO_INVALID_MAC);
 574         } else {
 575                 rv = crypto_put_output_data(ctx->ccm_pt_buf, out, pt_len);
 576                 if (rv != CRYPTO_SUCCESS)
 577                         return (rv);
 578                 out->cd_offset += pt_len;
 579         }
 580         return (CRYPTO_SUCCESS);
 581 }
 582 
 583 int
 584 ccm_validate_args(CK_AES_CCM_PARAMS *ccm_param, boolean_t is_encrypt_init)
 585 {
 586         size_t macSize, nonceSize;
 587         uint8_t q;
 588         uint64_t maxValue;
 589 
 590         /*
 591          * Check the length of the MAC.  The only valid
 592          * lengths for the MAC are: 4, 6, 8, 10, 12, 14, 16
 593          */
 594         macSize = ccm_param->ulMACSize;
 595         if ((macSize < 4) || (macSize > 16) || ((macSize % 2) != 0)) {
 596                 return (CRYPTO_MECHANISM_PARAM_INVALID);
 597         }
 598 
 599         /* Check the nonce length.  Valid values are 7, 8, 9, 10, 11, 12, 13 */
 600         nonceSize = ccm_param->ulNonceSize;
 601         if ((nonceSize < 7) || (nonceSize > 13)) {
 602                 return (CRYPTO_MECHANISM_PARAM_INVALID);
 603         }
 604 
 605         /* q is the length of the field storing the length, in bytes */
 606         q = (uint8_t)((15 - nonceSize) & 0xFF);
 607 
 608 
 609         /*
 610          * If it is decrypt, need to make sure size of ciphertext is at least
 611          * bigger than MAC len
 612          */
 613         if ((!is_encrypt_init) && (ccm_param->ulDataSize < macSize)) {
 614                 return (CRYPTO_MECHANISM_PARAM_INVALID);
 615         }
 616 
 617         /*
 618          * Check to make sure the length of the payload is within the
 619          * range of values allowed by q
 620          */
 621         if (q < 8) {
 622                 maxValue = (1ULL << (q * 8)) - 1;
 623         } else {
 624                 maxValue = ULONG_MAX;
 625         }
 626 
 627         if (ccm_param->ulDataSize > maxValue) {
 628                 return (CRYPTO_MECHANISM_PARAM_INVALID);
 629         }
 630         return (CRYPTO_SUCCESS);
 631 }
 632 
 633 /*
 634  * Format the first block used in CBC-MAC (B0) and the initial counter
 635  * block based on formatting functions and counter generation functions
 636  * specified in RFC 3610 and NIST publication 800-38C, appendix A
 637  *
 638  * b0 is the first block used in CBC-MAC
 639  * cb0 is the first counter block
 640  *
 641  * It's assumed that the arguments b0 and cb0 are preallocated AES blocks
 642  *
 643  */
 644 static void
 645 ccm_format_initial_blocks(uchar_t *nonce, ulong_t nonceSize,
 646     ulong_t authDataSize, uint8_t *b0, ccm_ctx_t *aes_ctx)
 647 {
 648         uint64_t payloadSize;
 649         uint8_t t, q, have_adata = 0;
 650         size_t limit;
 651         int i, j, k;
 652         uint64_t mask = 0;
 653         uint8_t *cb;
 654 
 655         q = (uint8_t)((15 - nonceSize) & 0xFF);
 656         t = (uint8_t)((aes_ctx->ccm_mac_len) & 0xFF);
 657 
 658         /* Construct the first octet of b0 */
 659         if (authDataSize > 0) {
 660                 have_adata = 1;
 661         }
 662         b0[0] = (have_adata << 6) | (((t - 2)  / 2) << 3) | (q - 1);
 663 
 664         /* copy the nonce value into b0 */
 665         bcopy(nonce, &(b0[1]), nonceSize);
 666 
 667         /* store the length of the payload into b0 */
 668         bzero(&(b0[1+nonceSize]), q);
 669 
 670         payloadSize = aes_ctx->ccm_data_len;
 671         limit = 8 < q ? 8 : q;
 672 
 673         for (i = 0, j = 0, k = 15; i < limit; i++, j += 8, k--) {
 674                 b0[k] = (uint8_t)((payloadSize >> j) & 0xFF);
 675         }
 676 
 677         /* format the counter block */
 678 
 679         cb = (uint8_t *)aes_ctx->ccm_cb;
 680 
 681         cb[0] = 0x07 & (q-1); /* first byte */
 682 
 683         /* copy the nonce value into the counter block */
 684         bcopy(nonce, &(cb[1]), nonceSize);
 685 
 686         bzero(&(cb[1+nonceSize]), q);
 687 
 688         /* Create the mask for the counter field based on the size of nonce */
 689         q <<= 3;
 690         while (q-- > 0) {
 691                 mask |= (1ULL << q);
 692         }
 693 
 694         aes_ctx->ccm_counter_mask = htonll(mask);
 695 
 696         /*
 697          * During calculation, we start using counter block 1, we will
 698          * set it up right here.
 699          * We can just set the last byte to have the value 1, because
 700          * even with the biggest nonce of 13, the last byte of the
 701          * counter block will be used for the counter value.
 702          */
 703         cb[15] = 0x01;
 704 }
 705 
 706 /*
 707  * Encode the length of the associated data as
 708  * specified in RFC 3610 and NIST publication 800-38C, appendix A
 709  */
 710 static void
 711 encode_adata_len(ulong_t auth_data_len, uint8_t *encoded, size_t *encoded_len)
 712 {
 713 #ifdef UNALIGNED_POINTERS_PERMITTED
 714         uint32_t        *lencoded_ptr;
 715 #ifdef _LP64
 716         uint64_t        *llencoded_ptr;
 717 #endif
 718 #endif  /* UNALIGNED_POINTERS_PERMITTED */
 719 
 720         if (auth_data_len < ((1ULL<<16) - (1ULL<<8))) {
 721                 /* 0 < a < (2^16-2^8) */
 722                 *encoded_len = 2;
 723                 encoded[0] = (auth_data_len & 0xff00) >> 8;
 724                 encoded[1] = auth_data_len & 0xff;
 725 
 726         } else if ((auth_data_len >= ((1ULL<<16) - (1ULL<<8))) &&
 727             (auth_data_len < (1ULL << 31))) {
 728                 /* (2^16-2^8) <= a < 2^32 */
 729                 *encoded_len = 6;
 730                 encoded[0] = 0xff;
 731                 encoded[1] = 0xfe;
 732 #ifdef UNALIGNED_POINTERS_PERMITTED
 733                 lencoded_ptr = (uint32_t *)(void *)&encoded[2];
 734                 *lencoded_ptr = htonl(auth_data_len);
 735 #else
 736                 encoded[2] = (auth_data_len & 0xff000000) >> 24;
 737                 encoded[3] = (auth_data_len & 0xff0000) >> 16;
 738                 encoded[4] = (auth_data_len & 0xff00) >> 8;
 739                 encoded[5] = auth_data_len & 0xff;
 740 #endif  /* UNALIGNED_POINTERS_PERMITTED */
 741 
 742 #ifdef _LP64
 743         } else {
 744                 /* 2^32 <= a < 2^64 */
 745                 *encoded_len = 10;
 746                 encoded[0] = 0xff;
 747                 encoded[1] = 0xff;
 748 #ifdef UNALIGNED_POINTERS_PERMITTED
 749                 llencoded_ptr = (uint64_t *)(void *)&encoded[2];
 750                 *llencoded_ptr = htonl(auth_data_len);
 751 #else
 752                 encoded[2] = (auth_data_len & 0xff00000000000000) >> 56;
 753                 encoded[3] = (auth_data_len & 0xff000000000000) >> 48;
 754                 encoded[4] = (auth_data_len & 0xff0000000000) >> 40;
 755                 encoded[5] = (auth_data_len & 0xff00000000) >> 32;
 756                 encoded[6] = (auth_data_len & 0xff000000) >> 24;
 757                 encoded[7] = (auth_data_len & 0xff0000) >> 16;
 758                 encoded[8] = (auth_data_len & 0xff00) >> 8;
 759                 encoded[9] = auth_data_len & 0xff;
 760 #endif  /* UNALIGNED_POINTERS_PERMITTED */
 761 #endif  /* _LP64 */
 762         }
 763 }
 764 
 765 /*
 766  * The following function should be call at encrypt or decrypt init time
 767  * for AES CCM mode.
 768  */
 769 int
 770 ccm_init(ccm_ctx_t *ctx, unsigned char *nonce, size_t nonce_len,
 771     unsigned char *auth_data, size_t auth_data_len, size_t block_size,
 772     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
 773     void (*xor_block)(uint8_t *, uint8_t *))
 774 {
 775         uint8_t *mac_buf, *datap, *ivp, *authp;
 776         size_t remainder, processed;
 777         uint8_t encoded_a[10]; /* max encoded auth data length is 10 octets */
 778         size_t encoded_a_len = 0;
 779 
 780         mac_buf = (uint8_t *)&(ctx->ccm_mac_buf);
 781 
 782         /*
 783          * Format the 1st block for CBC-MAC and construct the
 784          * 1st counter block.
 785          *
 786          * aes_ctx->ccm_iv is used for storing the counter block
 787          * mac_buf will store b0 at this time.
 788          */
 789         ccm_format_initial_blocks(nonce, nonce_len,
 790             auth_data_len, mac_buf, ctx);
 791 
 792         /* The IV for CBC MAC for AES CCM mode is always zero */
 793         ivp = (uint8_t *)ctx->ccm_tmp;
 794         bzero(ivp, block_size);
 795 
 796         xor_block(ivp, mac_buf);
 797 
 798         /* encrypt the nonce */
 799         encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf);
 800 
 801         /* take care of the associated data, if any */
 802         if (auth_data_len == 0) {
 803                 return (CRYPTO_SUCCESS);
 804         }
 805 
 806         encode_adata_len(auth_data_len, encoded_a, &encoded_a_len);
 807 
 808         remainder = auth_data_len;
 809 
 810         /* 1st block: it contains encoded associated data, and some data */
 811         authp = (uint8_t *)ctx->ccm_tmp;
 812         bzero(authp, block_size);
 813         bcopy(encoded_a, authp, encoded_a_len);
 814         processed = block_size - encoded_a_len;
 815         if (processed > auth_data_len) {
 816                 /* in case auth_data is very small */
 817                 processed = auth_data_len;
 818         }
 819         bcopy(auth_data, authp+encoded_a_len, processed);
 820         /* xor with previous buffer */
 821         xor_block(authp, mac_buf);
 822         encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf);
 823         remainder -= processed;
 824         if (remainder == 0) {
 825                 /* a small amount of associated data, it's all done now */
 826                 return (CRYPTO_SUCCESS);
 827         }
 828 
 829         do {
 830                 if (remainder < block_size) {
 831                         /*
 832                          * There's not a block full of data, pad rest of
 833                          * buffer with zero
 834                          */
 835                         bzero(authp, block_size);
 836                         bcopy(&(auth_data[processed]), authp, remainder);
 837                         datap = (uint8_t *)authp;
 838                         remainder = 0;
 839                 } else {
 840                         datap = (uint8_t *)(&(auth_data[processed]));
 841                         processed += block_size;
 842                         remainder -= block_size;
 843                 }
 844 
 845                 xor_block(datap, mac_buf);
 846                 encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf);
 847 
 848         } while (remainder > 0);
 849 
 850         return (CRYPTO_SUCCESS);
 851 }
 852 
 853 int
 854 ccm_init_ctx(ccm_ctx_t *ccm_ctx, char *param, int kmflag,
 855     boolean_t is_encrypt_init, size_t block_size,
 856     int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
 857     void (*xor_block)(uint8_t *, uint8_t *))
 858 {
 859         int rv;
 860         CK_AES_CCM_PARAMS *ccm_param;
 861 
 862         if (param != NULL) {
 863                 ccm_param = (CK_AES_CCM_PARAMS *)(void *)param;
 864 
 865                 if ((rv = ccm_validate_args(ccm_param,
 866                     is_encrypt_init)) != 0) {
 867                         return (rv);
 868                 }
 869 
 870                 ccm_ctx->ccm_mac_len = ccm_param->ulMACSize;
 871                 if (is_encrypt_init) {
 872                         ccm_ctx->ccm_data_len = ccm_param->ulDataSize;
 873                 } else {
 874                         ccm_ctx->ccm_data_len =
 875                             ccm_param->ulDataSize - ccm_ctx->ccm_mac_len;
 876                         ccm_ctx->ccm_processed_mac_len = 0;
 877                 }
 878                 ccm_ctx->ccm_processed_data_len = 0;
 879 
 880                 ccm_ctx->ccm_flags |= CCM_MODE;
 881         } else {
 882                 rv = CRYPTO_MECHANISM_PARAM_INVALID;
 883                 goto out;
 884         }
 885 
 886         if (ccm_init(ccm_ctx, ccm_param->nonce, ccm_param->ulNonceSize,
 887             ccm_param->authData, ccm_param->ulAuthDataSize, block_size,
 888             encrypt_block, xor_block) != 0) {
 889                 rv = CRYPTO_MECHANISM_PARAM_INVALID;
 890                 goto out;
 891         }
 892         if (!is_encrypt_init) {
 893                 /* allocate buffer for storing decrypted plaintext */
 894 #ifdef _KERNEL
 895                 ccm_ctx->ccm_pt_buf = kmem_alloc(ccm_ctx->ccm_data_len,
 896                     kmflag);
 897 #else
 898                 ccm_ctx->ccm_pt_buf = malloc(ccm_ctx->ccm_data_len);
 899 #endif
 900                 if (ccm_ctx->ccm_pt_buf == NULL) {
 901                         rv = CRYPTO_HOST_MEMORY;
 902                 }
 903         }
 904 out:
 905         return (rv);
 906 }
 907 
 908 void *
 909 ccm_alloc_ctx(int kmflag)
 910 {
 911         ccm_ctx_t *ccm_ctx;
 912 
 913 #ifdef _KERNEL
 914         if ((ccm_ctx = kmem_zalloc(sizeof (ccm_ctx_t), kmflag)) == NULL)
 915 #else
 916         if ((ccm_ctx = calloc(1, sizeof (ccm_ctx_t))) == NULL)
 917 #endif
 918                 return (NULL);
 919 
 920         ccm_ctx->ccm_flags = CCM_MODE;
 921         return (ccm_ctx);
 922 }