PORT_Assert (padlen > 0 && padlen <= padsize);
NSS_CMSCipherContext_Decrypt(NSSCMSCipherContext *cc, unsigned char *output,		  unsigned int *output_len_p, unsigned int max_output_len,		  const unsigned char *input, unsigned int input_len,		  PRBool final){    int blocks, bsize, pcount, padsize;    unsigned int max_needed, ifraglen, ofraglen, output_len;    unsigned char *pbuf;    SECStatus rv;    PORT_Assert (! cc->encrypt);    /*     * Check that we have enough room for the output.  Our caller should     * already handle this; failure is really an internal error (i.e. bug).     */    max_needed = NSS_CMSCipherContext_DecryptLength(cc, input_len, final);    PORT_Assert (max_output_len >= max_needed);    if (max_output_len < max_needed) {	/* PORT_SetError (XXX); */	return SECFailure;    }    /*     * hardware encryption does not like small decryption sizes here, so we     * allow both blocking and padding.     */    bsize = cc->block_size;    padsize = cc->pad_size;    /*     * When no blocking or padding work to do, we can simply call the     * cipher function and we are done.     */    if (bsize == 0) {	return (* cc->doit) (cc->cx, output, output_len_p, max_output_len,			      input, input_len);    }    pcount = cc->pending_count;    pbuf = cc->pending_buf;    output_len = 0;    if (pcount) {	/*	 * Try to fill in an entire block, starting with the bytes	 * we already have saved away.	 */	while (input_len && pcount < bsize) {	    pbuf[pcount++] = *input++;	    input_len--;	}	/*	 * If we have at most a whole block and this is not our last call,	 * then we are done for now.  (We do not try to decrypt a lone	 * single block because we cannot interpret the padding bytes	 * until we know we are handling the very last block of all input.)	 */	if (input_len == 0 && !final) {	    cc->pending_count = pcount;	    if (output_len_p)		*output_len_p = 0;	    return SECSuccess;	}	/*	 * Given the logic above, we expect to have a full block by now.	 * If we do not, there is something wrong, either with our own	 * logic or with (length of) the data given to us.	 */	PORT_Assert ((padsize == 0) || (pcount % padsize) == 0);	if ((padsize != 0) && (pcount % padsize) != 0) {	    PORT_Assert (final);		    PORT_SetError (SEC_ERROR_BAD_DATA);	    return SECFailure;	}	/*	 * Decrypt the block.	 */	rv = (*cc->doit)(cc->cx, output, &ofraglen, max_output_len,			    pbuf, pcount);	if (rv != SECSuccess)	    return rv;	/*	 * For now anyway, all of our ciphers have the same number of	 * bytes of output as they do input.  If this ever becomes untrue,	 * then NSS_CMSCipherContext_DecryptLength needs to be made smarter!	 */	PORT_Assert(ofraglen == pcount);	/*	 * Account for the bytes now in output.	 */	max_output_len -= ofraglen;	output_len += ofraglen;	output += ofraglen;    }    /*     * If this is our last call, we expect to have an exact number of     * blocks left to be decrypted; we will decrypt them all.     *      * If not our last call, we always save between 1 and bsize bytes     * until next time.  (We must do this because we cannot be sure     * that none of the decrypted bytes are padding bytes until we     * have at least another whole block of data.  You cannot tell by     * looking -- the data could be anything -- you can only tell by     * context, knowing you are looking at the last block.)  We could     * decrypt a whole block now but it is easier if we just treat it     * the same way we treat partial block bytes.     */    if (final) {	if (padsize) {	    blocks = input_len / padsize;	    ifraglen = blocks * padsize;	} else ifraglen = input_len;	PORT_Assert (ifraglen == input_len);	if (ifraglen != input_len) {	    PORT_SetError(SEC_ERROR_BAD_DATA);	    return SECFailure;	}    } else {	blocks = (input_len - 1) / bsize;	ifraglen = blocks * bsize;	PORT_Assert (ifraglen < input_len);	pcount = input_len - ifraglen;	PORT_Memcpy (pbuf, input + ifraglen, pcount);	cc->pending_count = pcount;    }    if (ifraglen) {	rv = (* cc->doit)(cc->cx, output, &ofraglen, max_output_len,			    input, ifraglen);	if (rv != SECSuccess)	    return rv;	/*	 * For now anyway, all of our ciphers have the same number of	 * bytes of output as they do input.  If this ever becomes untrue,	 * then sec_PKCS7DecryptLength needs to be made smarter!	 */	PORT_Assert (ifraglen == ofraglen);	if (ifraglen != ofraglen) {	    PORT_SetError(SEC_ERROR_BAD_DATA);	    return SECFailure;	}	output_len += ofraglen;    } else {	ofraglen = 0;    }    /*     * If we just did our very last block, "remove" the padding by     * adjusting the output length.     */    if (final && (padsize != 0)) {	unsigned int padlen = *(output + ofraglen - 1);	PORT_Assert (padlen > 0 && padlen <= padsize);	if (padlen == 0 || padlen > padsize) {	    PORT_SetError(SEC_ERROR_BAD_DATA);	    return SECFailure;	}	output_len -= padlen;    }    PORT_Assert (output_len_p != NULL || output_len == 0);    if (output_len_p != NULL)	*output_len_p = output_len;    return SECSuccess;}