cmscipher.c (24444B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 /* 6 * Encryption/decryption routines for CMS implementation, none of which are exported. 7 */ 8 9 #include "cmslocal.h" 10 11 #include "secoid.h" 12 #include "secitem.h" 13 #include "pk11func.h" 14 #include "secerr.h" 15 #include "secpkcs5.h" 16 17 /* 18 * ------------------------------------------------------------------- 19 * Cipher stuff. 20 */ 21 22 typedef SECStatus (*nss_cms_cipher_function)(void *, unsigned char *, unsigned int *, 23 unsigned int, const unsigned char *, unsigned int); 24 typedef SECStatus (*nss_cms_cipher_destroy)(void *, PRBool); 25 26 #define BLOCK_SIZE 4096 27 28 struct NSSCMSCipherContextStr { 29 void *cx; /* PK11 cipher context */ 30 nss_cms_cipher_function doit; 31 nss_cms_cipher_destroy destroy; 32 PRBool encrypt; /* encrypt / decrypt switch */ 33 int block_size; /* block & pad sizes for cipher */ 34 int pad_size; 35 int pending_count; /* pending data (not yet en/decrypted */ 36 unsigned char pending_buf[BLOCK_SIZE]; /* because of blocking */ 37 }; 38 39 /* 40 * NSS_CMSCipherContext_StartDecrypt - create a cipher context to do decryption 41 * based on the given bulk encryption key and algorithm identifier (which 42 * may include an iv). 43 * 44 * XXX Once both are working, it might be nice to combine this and the 45 * function below (for starting up encryption) into one routine, and just 46 * have two simple cover functions which call it. 47 */ 48 NSSCMSCipherContext * 49 NSS_CMSCipherContext_StartDecrypt(PK11SymKey *key, SECAlgorithmID *algid) 50 { 51 NSSCMSCipherContext *cc; 52 void *ciphercx; 53 CK_MECHANISM_TYPE cryptoMechType; 54 PK11SlotInfo *slot; 55 SECOidTag algtag; 56 SECItem *param = NULL; 57 58 algtag = SECOID_GetAlgorithmTag(algid); 59 60 /* set param and mechanism */ 61 if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) { 62 SECItem *pwitem; 63 64 pwitem = PK11_GetSymKeyUserData(key); 65 if (!pwitem) 66 return NULL; 67 68 cryptoMechType = PK11_GetPBECryptoMechanism(algid, ¶m, pwitem); 69 if (cryptoMechType == CKM_INVALID_MECHANISM) { 70 SECITEM_FreeItem(param, PR_TRUE); 71 return NULL; 72 } 73 74 } else { 75 cryptoMechType = PK11_AlgtagToMechanism(algtag); 76 if ((param = PK11_ParamFromAlgid(algid)) == NULL) 77 return NULL; 78 } 79 80 cc = (NSSCMSCipherContext *)PORT_ZAlloc(sizeof(NSSCMSCipherContext)); 81 if (cc == NULL) { 82 SECITEM_FreeItem(param, PR_TRUE); 83 return NULL; 84 } 85 86 /* figure out pad and block sizes */ 87 cc->pad_size = PK11_GetBlockSize(cryptoMechType, param); 88 slot = PK11_GetSlotFromKey(key); 89 cc->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : cc->pad_size; 90 PK11_FreeSlot(slot); 91 92 /* create PK11 cipher context */ 93 ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_DECRYPT, 94 key, param); 95 SECITEM_FreeItem(param, PR_TRUE); 96 if (ciphercx == NULL) { 97 PORT_Free(cc); 98 return NULL; 99 } 100 101 cc->cx = ciphercx; 102 cc->doit = (nss_cms_cipher_function)PK11_CipherOp; 103 cc->destroy = (nss_cms_cipher_destroy)PK11_DestroyContext; 104 cc->encrypt = PR_FALSE; 105 cc->pending_count = 0; 106 107 return cc; 108 } 109 110 /* 111 * NSS_CMSCipherContext_StartEncrypt - create a cipher object to do encryption, 112 * based on the given bulk encryption key and algorithm tag. Fill in the 113 * algorithm identifier (which may include an iv) appropriately. 114 * 115 * XXX Once both are working, it might be nice to combine this and the 116 * function above (for starting up decryption) into one routine, and just 117 * have two simple cover functions which call it. 118 */ 119 NSSCMSCipherContext * 120 NSS_CMSCipherContext_StartEncrypt(PLArenaPool *poolp, PK11SymKey *key, SECAlgorithmID *algid) 121 { 122 NSSCMSCipherContext *cc; 123 void *ciphercx = NULL; 124 SECStatus rv; 125 CK_MECHANISM_TYPE cryptoMechType; 126 PK11SlotInfo *slot; 127 SECItem *param = NULL; 128 PRBool needToEncodeAlgid = PR_FALSE; 129 SECOidTag algtag = SECOID_GetAlgorithmTag(algid); 130 131 /* set param and mechanism */ 132 if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) { 133 SECItem *pwitem; 134 135 pwitem = PK11_GetSymKeyUserData(key); 136 if (!pwitem) 137 return NULL; 138 139 cryptoMechType = PK11_GetPBECryptoMechanism(algid, ¶m, pwitem); 140 if (cryptoMechType == CKM_INVALID_MECHANISM) { 141 SECITEM_FreeItem(param, PR_TRUE); 142 return NULL; 143 } 144 } else { 145 cryptoMechType = PK11_AlgtagToMechanism(algtag); 146 if ((param = PK11_GenerateNewParam(cryptoMechType, key)) == NULL) 147 return NULL; 148 needToEncodeAlgid = PR_TRUE; 149 } 150 151 cc = (NSSCMSCipherContext *)PORT_ZAlloc(sizeof(NSSCMSCipherContext)); 152 if (cc == NULL) { 153 goto loser; 154 } 155 156 /* now find pad and block sizes for our mechanism */ 157 cc->pad_size = PK11_GetBlockSize(cryptoMechType, param); 158 slot = PK11_GetSlotFromKey(key); 159 cc->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : cc->pad_size; 160 PK11_FreeSlot(slot); 161 162 /* and here we go, creating a PK11 cipher context */ 163 ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_ENCRYPT, 164 key, param); 165 if (ciphercx == NULL) { 166 PORT_Free(cc); 167 cc = NULL; 168 goto loser; 169 } 170 171 /* 172 * These are placed after the CreateContextBySymKey() because some 173 * mechanisms have to generate their IVs from their card (i.e. FORTEZZA). 174 * Don't move it from here. 175 * XXX is that right? the purpose of this is to get the correct algid 176 * containing the IVs etc. for encoding. this means we need to set this up 177 * BEFORE encoding the algid in the contentInfo, right? 178 */ 179 if (needToEncodeAlgid) { 180 rv = PK11_ParamToAlgid(algtag, param, poolp, algid); 181 if (rv != SECSuccess) { 182 PORT_Free(cc); 183 cc = NULL; 184 goto loser; 185 } 186 } 187 188 cc->cx = ciphercx; 189 ciphercx = NULL; 190 cc->doit = (nss_cms_cipher_function)PK11_CipherOp; 191 cc->destroy = (nss_cms_cipher_destroy)PK11_DestroyContext; 192 cc->encrypt = PR_TRUE; 193 cc->pending_count = 0; 194 195 loser: 196 SECITEM_FreeItem(param, PR_TRUE); 197 if (ciphercx) { 198 PK11_DestroyContext(ciphercx, PR_TRUE); 199 } 200 201 return cc; 202 } 203 204 void 205 NSS_CMSCipherContext_Destroy(NSSCMSCipherContext *cc) 206 { 207 PORT_Assert(cc != NULL); 208 if (cc == NULL) 209 return; 210 (*cc->destroy)(cc->cx, PR_TRUE); 211 PORT_Free(cc); 212 } 213 214 /* 215 * NSS_CMSCipherContext_DecryptLength - find the output length of the next call to decrypt. 216 * 217 * cc - the cipher context 218 * input_len - number of bytes used as input 219 * final - true if this is the final chunk of data 220 * 221 * Result can be used to perform memory allocations. Note that the amount 222 * is exactly accurate only when not doing a block cipher or when final 223 * is false, otherwise it is an upper bound on the amount because until 224 * we see the data we do not know how many padding bytes there are 225 * (always between 1 and bsize). 226 * 227 * Note that this can return zero, which does not mean that the decrypt 228 * operation can be skipped! (It simply means that there are not enough 229 * bytes to make up an entire block; the bytes will be reserved until 230 * there are enough to encrypt/decrypt at least one block.) However, 231 * if zero is returned it *does* mean that no output buffer need be 232 * passed in to the subsequent decrypt operation, as no output bytes 233 * will be stored. 234 */ 235 unsigned int 236 NSS_CMSCipherContext_DecryptLength(NSSCMSCipherContext *cc, unsigned int input_len, PRBool final) 237 { 238 int blocks, block_size; 239 240 PORT_Assert(!cc->encrypt); 241 242 block_size = cc->block_size; 243 244 /* 245 * If this is not a block cipher, then we always have the same 246 * number of output bytes as we had input bytes. 247 */ 248 if (block_size == 0) 249 return input_len; 250 251 /* 252 * On the final call, we will always use up all of the pending 253 * bytes plus all of the input bytes, *but*, there will be padding 254 * at the end and we cannot predict how many bytes of padding we 255 * will end up removing. The amount given here is actually known 256 * to be at least 1 byte too long (because we know we will have 257 * at least 1 byte of padding), but seemed clearer/better to me. 258 */ 259 if (final) 260 return cc->pending_count + input_len; 261 262 /* 263 * Okay, this amount is exactly what we will output on the 264 * next cipher operation. We will always hang onto the last 265 * 1 - block_size bytes for non-final operations. That is, 266 * we will do as many complete blocks as we can *except* the 267 * last block (complete or partial). (This is because until 268 * we know we are at the end, we cannot know when to interpret 269 * and removing the padding byte(s), which are guaranteed to 270 * be there.) 271 */ 272 blocks = (cc->pending_count + input_len - 1) / block_size; 273 return blocks * block_size; 274 } 275 276 /* 277 * NSS_CMSCipherContext_EncryptLength - find the output length of the next call to encrypt. 278 * 279 * cc - the cipher context 280 * input_len - number of bytes used as input 281 * final - true if this is the final chunk of data 282 * 283 * Result can be used to perform memory allocations. 284 * 285 * Note that this can return zero, which does not mean that the encrypt 286 * operation can be skipped! (It simply means that there are not enough 287 * bytes to make up an entire block; the bytes will be reserved until 288 * there are enough to encrypt/decrypt at least one block.) However, 289 * if zero is returned it *does* mean that no output buffer need be 290 * passed in to the subsequent encrypt operation, as no output bytes 291 * will be stored. 292 */ 293 unsigned int 294 NSS_CMSCipherContext_EncryptLength(NSSCMSCipherContext *cc, unsigned int input_len, PRBool final) 295 { 296 int blocks, block_size; 297 int pad_size; 298 299 PORT_Assert(cc->encrypt); 300 301 block_size = cc->block_size; 302 pad_size = cc->pad_size; 303 304 /* 305 * If this is not a block cipher, then we always have the same 306 * number of output bytes as we had input bytes. 307 */ 308 if (block_size == 0) 309 return input_len; 310 311 /* 312 * On the final call, we only send out what we need for 313 * remaining bytes plus the padding. (There is always padding, 314 * so even if we have an exact number of blocks as input, we 315 * will add another full block that is just padding.) 316 */ 317 if (final) { 318 if (pad_size == 0) { 319 return cc->pending_count + input_len; 320 } else { 321 blocks = (cc->pending_count + input_len) / pad_size; 322 blocks++; 323 return blocks * pad_size; 324 } 325 } 326 327 /* 328 * Now, count the number of complete blocks of data we have. 329 */ 330 blocks = (cc->pending_count + input_len) / block_size; 331 332 return blocks * block_size; 333 } 334 335 /* 336 * NSS_CMSCipherContext_Decrypt - do the decryption 337 * 338 * cc - the cipher context 339 * output - buffer for decrypted result bytes 340 * output_len_p - number of bytes in output 341 * max_output_len - upper bound on bytes to put into output 342 * input - pointer to input bytes 343 * input_len - number of input bytes 344 * final - true if this is the final chunk of data 345 * 346 * Decrypts a given length of input buffer (starting at "input" and 347 * containing "input_len" bytes), placing the decrypted bytes in 348 * "output" and storing the output length in "*output_len_p". 349 * "cc" is the return value from NSS_CMSCipher_StartDecrypt. 350 * When "final" is true, this is the last of the data to be decrypted. 351 * 352 * This is much more complicated than it sounds when the cipher is 353 * a block-type, meaning that the decryption function will only 354 * operate on whole blocks. But our caller is operating stream-wise, 355 * and can pass in any number of bytes. So we need to keep track 356 * of block boundaries. We save excess bytes between calls in "cc". 357 * We also need to determine which bytes are padding, and remove 358 * them from the output. We can only do this step when we know we 359 * have the final block of data. PKCS #7 specifies that the padding 360 * used for a block cipher is a string of bytes, each of whose value is 361 * the same as the length of the padding, and that all data is padded. 362 * (Even data that starts out with an exact multiple of blocks gets 363 * added to it another block, all of which is padding.) 364 */ 365 SECStatus 366 NSS_CMSCipherContext_Decrypt(NSSCMSCipherContext *cc, unsigned char *output, 367 unsigned int *output_len_p, unsigned int max_output_len, 368 const unsigned char *input, unsigned int input_len, 369 PRBool final) 370 { 371 unsigned int blocks, bsize, pcount, padsize; 372 unsigned int max_needed, ifraglen, ofraglen, output_len; 373 unsigned char *pbuf; 374 SECStatus rv; 375 376 PORT_Assert(!cc->encrypt); 377 378 /* 379 * Check that we have enough room for the output. Our caller should 380 * already handle this; failure is really an internal error (i.e. bug). 381 */ 382 max_needed = NSS_CMSCipherContext_DecryptLength(cc, input_len, final); 383 PORT_Assert(max_output_len >= max_needed); 384 if (max_output_len < max_needed) { 385 /* PORT_SetError (XXX); */ 386 return SECFailure; 387 } 388 389 /* 390 * hardware encryption does not like small decryption sizes here, so we 391 * allow both blocking and padding. 392 */ 393 bsize = cc->block_size; 394 padsize = cc->pad_size; 395 396 /* 397 * When no blocking or padding work to do, we can simply call the 398 * cipher function and we are done. 399 */ 400 if (bsize == 0) { 401 return (*cc->doit)(cc->cx, output, output_len_p, max_output_len, 402 input, input_len); 403 } 404 405 pcount = cc->pending_count; 406 pbuf = cc->pending_buf; 407 408 output_len = 0; 409 410 if (pcount) { 411 /* 412 * Try to fill in an entire block, starting with the bytes 413 * we already have saved away. 414 */ 415 while (input_len && pcount < bsize) { 416 pbuf[pcount++] = *input++; 417 input_len--; 418 } 419 /* 420 * If we have at most a whole block and this is not our last call, 421 * then we are done for now. (We do not try to decrypt a lone 422 * single block because we cannot interpret the padding bytes 423 * until we know we are handling the very last block of all input.) 424 */ 425 if (input_len == 0 && !final) { 426 cc->pending_count = pcount; 427 if (output_len_p) 428 *output_len_p = 0; 429 return SECSuccess; 430 } 431 /* 432 * Given the logic above, we expect to have a full block by now. 433 * If we do not, there is something wrong, either with our own 434 * logic or with (length of) the data given to us. 435 */ 436 if ((padsize != 0) && (pcount % padsize) != 0) { 437 PORT_Assert(final); 438 PORT_SetError(SEC_ERROR_BAD_DATA); 439 return SECFailure; 440 } 441 /* 442 * Decrypt the block. 443 */ 444 rv = (*cc->doit)(cc->cx, output, &ofraglen, max_output_len, 445 pbuf, pcount); 446 if (rv != SECSuccess) 447 return rv; 448 449 /* 450 * For now anyway, all of our ciphers have the same number of 451 * bytes of output as they do input. If this ever becomes untrue, 452 * then NSS_CMSCipherContext_DecryptLength needs to be made smarter! 453 */ 454 PORT_Assert(ofraglen == pcount); 455 456 /* 457 * Account for the bytes now in output. 458 */ 459 max_output_len -= ofraglen; 460 output_len += ofraglen; 461 output += ofraglen; 462 } 463 464 /* 465 * If this is our last call, we expect to have an exact number of 466 * blocks left to be decrypted; we will decrypt them all. 467 * 468 * If not our last call, we always save between 1 and bsize bytes 469 * until next time. (We must do this because we cannot be sure 470 * that none of the decrypted bytes are padding bytes until we 471 * have at least another whole block of data. You cannot tell by 472 * looking -- the data could be anything -- you can only tell by 473 * context, knowing you are looking at the last block.) We could 474 * decrypt a whole block now but it is easier if we just treat it 475 * the same way we treat partial block bytes. 476 */ 477 if (final) { 478 if (padsize) { 479 blocks = input_len / padsize; 480 ifraglen = blocks * padsize; 481 } else 482 ifraglen = input_len; 483 PORT_Assert(ifraglen == input_len); 484 485 if (ifraglen != input_len) { 486 PORT_SetError(SEC_ERROR_BAD_DATA); 487 return SECFailure; 488 } 489 } else { 490 blocks = (input_len - 1) / bsize; 491 ifraglen = blocks * bsize; 492 PORT_Assert(ifraglen < input_len); 493 494 pcount = input_len - ifraglen; 495 PORT_Memcpy(pbuf, input + ifraglen, pcount); 496 cc->pending_count = pcount; 497 } 498 499 if (ifraglen) { 500 rv = (*cc->doit)(cc->cx, output, &ofraglen, max_output_len, 501 input, ifraglen); 502 if (rv != SECSuccess) 503 return rv; 504 505 /* 506 * For now anyway, all of our ciphers have the same number of 507 * bytes of output as they do input. If this ever becomes untrue, 508 * then sec_PKCS7DecryptLength needs to be made smarter! 509 */ 510 PORT_Assert(ifraglen == ofraglen); 511 if (ifraglen != ofraglen) { 512 PORT_SetError(SEC_ERROR_BAD_DATA); 513 return SECFailure; 514 } 515 516 output_len += ofraglen; 517 } else { 518 ofraglen = 0; 519 } 520 521 /* 522 * If we just did our very last block, "remove" the padding by 523 * adjusting the output length. 524 */ 525 if (final && (padsize != 0)) { 526 unsigned int padlen = *(output + ofraglen - 1); 527 528 if (padlen == 0 || padlen > padsize) { 529 PORT_SetError(SEC_ERROR_BAD_DATA); 530 return SECFailure; 531 } 532 output_len -= padlen; 533 } 534 535 PORT_Assert(output_len_p != NULL || output_len == 0); 536 if (output_len_p != NULL) 537 *output_len_p = output_len; 538 539 return SECSuccess; 540 } 541 542 /* 543 * NSS_CMSCipherContext_Encrypt - do the encryption 544 * 545 * cc - the cipher context 546 * output - buffer for decrypted result bytes 547 * output_len_p - number of bytes in output 548 * max_output_len - upper bound on bytes to put into output 549 * input - pointer to input bytes 550 * input_len - number of input bytes 551 * final - true if this is the final chunk of data 552 * 553 * Encrypts a given length of input buffer (starting at "input" and 554 * containing "input_len" bytes), placing the encrypted bytes in 555 * "output" and storing the output length in "*output_len_p". 556 * "cc" is the return value from NSS_CMSCipher_StartEncrypt. 557 * When "final" is true, this is the last of the data to be encrypted. 558 * 559 * This is much more complicated than it sounds when the cipher is 560 * a block-type, meaning that the encryption function will only 561 * operate on whole blocks. But our caller is operating stream-wise, 562 * and can pass in any number of bytes. So we need to keep track 563 * of block boundaries. We save excess bytes between calls in "cc". 564 * We also need to add padding bytes at the end. PKCS #7 specifies 565 * that the padding used for a block cipher is a string of bytes, 566 * each of whose value is the same as the length of the padding, 567 * and that all data is padded. (Even data that starts out with 568 * an exact multiple of blocks gets added to it another block, 569 * all of which is padding.) 570 * 571 * XXX I would kind of like to combine this with the function above 572 * which does decryption, since they have a lot in common. But the 573 * tricky parts about padding and filling blocks would be much 574 * harder to read that way, so I left them separate. At least for 575 * now until it is clear that they are right. 576 */ 577 SECStatus 578 NSS_CMSCipherContext_Encrypt(NSSCMSCipherContext *cc, unsigned char *output, 579 unsigned int *output_len_p, unsigned int max_output_len, 580 const unsigned char *input, unsigned int input_len, 581 PRBool final) 582 { 583 int blocks, bsize, padlen, pcount, padsize; 584 unsigned int max_needed, ifraglen, ofraglen, output_len; 585 unsigned char *pbuf; 586 SECStatus rv; 587 588 PORT_Assert(cc->encrypt); 589 590 /* 591 * Check that we have enough room for the output. Our caller should 592 * already handle this; failure is really an internal error (i.e. bug). 593 */ 594 max_needed = NSS_CMSCipherContext_EncryptLength(cc, input_len, final); 595 PORT_Assert(max_output_len >= max_needed); 596 if (max_output_len < max_needed) { 597 /* PORT_SetError (XXX); */ 598 return SECFailure; 599 } 600 601 bsize = cc->block_size; 602 padsize = cc->pad_size; 603 604 /* 605 * When no blocking and padding work to do, we can simply call the 606 * cipher function and we are done. 607 */ 608 if (bsize == 0) { 609 return (*cc->doit)(cc->cx, output, output_len_p, max_output_len, 610 input, input_len); 611 } 612 613 pcount = cc->pending_count; 614 pbuf = cc->pending_buf; 615 616 output_len = 0; 617 618 if (pcount) { 619 /* 620 * Try to fill in an entire block, starting with the bytes 621 * we already have saved away. 622 */ 623 while (input_len && pcount < bsize) { 624 pbuf[pcount++] = *input++; 625 input_len--; 626 } 627 /* 628 * If we do not have a full block and we know we will be 629 * called again, then we are done for now. 630 */ 631 if (pcount < bsize && !final) { 632 cc->pending_count = pcount; 633 if (output_len_p != NULL) 634 *output_len_p = 0; 635 return SECSuccess; 636 } 637 /* 638 * If we have a whole block available, encrypt it. 639 */ 640 if ((padsize == 0) || (pcount % padsize) == 0) { 641 rv = (*cc->doit)(cc->cx, output, &ofraglen, max_output_len, 642 pbuf, pcount); 643 if (rv != SECSuccess) 644 return rv; 645 646 /* 647 * For now anyway, all of our ciphers have the same number of 648 * bytes of output as they do input. If this ever becomes untrue, 649 * then sec_PKCS7EncryptLength needs to be made smarter! 650 */ 651 PORT_Assert(ofraglen == pcount); 652 653 /* 654 * Account for the bytes now in output. 655 */ 656 max_output_len -= ofraglen; 657 output_len += ofraglen; 658 output += ofraglen; 659 660 pcount = 0; 661 } 662 } 663 664 if (input_len) { 665 PORT_Assert(pcount == 0); 666 667 blocks = input_len / bsize; 668 ifraglen = blocks * bsize; 669 670 if (ifraglen) { 671 rv = (*cc->doit)(cc->cx, output, &ofraglen, max_output_len, 672 input, ifraglen); 673 if (rv != SECSuccess) 674 return rv; 675 676 /* 677 * For now anyway, all of our ciphers have the same number of 678 * bytes of output as they do input. If this ever becomes untrue, 679 * then sec_PKCS7EncryptLength needs to be made smarter! 680 */ 681 PORT_Assert(ifraglen == ofraglen); 682 683 max_output_len -= ofraglen; 684 output_len += ofraglen; 685 output += ofraglen; 686 } 687 688 pcount = input_len - ifraglen; 689 PORT_Assert(pcount < bsize); 690 if (pcount) 691 PORT_Memcpy(pbuf, input + ifraglen, pcount); 692 } 693 694 if (final) { 695 if (padsize <= 0) { 696 padlen = 0; 697 } else { 698 padlen = padsize - (pcount % padsize); 699 PORT_Memset(pbuf + pcount, padlen, padlen); 700 } 701 rv = (*cc->doit)(cc->cx, output, &ofraglen, max_output_len, 702 pbuf, pcount + padlen); 703 if (rv != SECSuccess) 704 return rv; 705 706 /* 707 * For now anyway, all of our ciphers have the same number of 708 * bytes of output as they do input. If this ever becomes untrue, 709 * then sec_PKCS7EncryptLength needs to be made smarter! 710 */ 711 PORT_Assert(ofraglen == (pcount + padlen)); 712 output_len += ofraglen; 713 } else { 714 cc->pending_count = pcount; 715 } 716 717 PORT_Assert(output_len_p != NULL || output_len == 0); 718 if (output_len_p != NULL) 719 *output_len_p = output_len; 720 721 return SECSuccess; 722 }