unsigned int modLen; modLen = rsa_modulusLen(&key->modulus);
RSA_PrivateKeyOp(RSAPrivateKey *key,                  unsigned char *output,                  unsigned char *input){    mp_int p, q, d_p, d_q, qInv;    mp_int m, m1, m2, b2, h, c;    mp_err   err = MP_OKAY;    SECStatus rv = SECSuccess;    unsigned int offset;    unsigned int modLen;    modLen = rsa_modulusLen(&key->modulus);    if (!key || !output || !input) {	PORT_SetError(SEC_ERROR_INVALID_ARGS);	return SECFailure;    }    /* check input out of range (needs to be in range [0..n-1]) */    offset = (key->modulus.data[0] == 0) ? 1 : 0; /* may be leading 0 */    if (memcmp(input, key->modulus.data + offset, modLen) >= 0) {	PORT_SetError(SEC_ERROR_INVALID_ARGS);	return SECFailure;    }    MP_DIGITS(&p)    = 0;    MP_DIGITS(&q)    = 0;    MP_DIGITS(&d_p)  = 0;    MP_DIGITS(&d_q)  = 0;    MP_DIGITS(&qInv) = 0;    MP_DIGITS(&m)    = 0;    MP_DIGITS(&m1)   = 0;    MP_DIGITS(&m2)   = 0;    MP_DIGITS(&b2)   = 0;    MP_DIGITS(&h)    = 0;    MP_DIGITS(&c)    = 0;    CHECK_MPI_OK( mp_init(&p)    );    CHECK_MPI_OK( mp_init(&q)    );    CHECK_MPI_OK( mp_init(&d_p)  );    CHECK_MPI_OK( mp_init(&d_q)  );    CHECK_MPI_OK( mp_init(&qInv) );    CHECK_MPI_OK( mp_init(&m)    );    CHECK_MPI_OK( mp_init(&m1)   );    CHECK_MPI_OK( mp_init(&m2)   );    CHECK_MPI_OK( mp_init(&b2)   );    CHECK_MPI_OK( mp_init(&h)    );    CHECK_MPI_OK( mp_init(&c)    );    /* copy private key parameters into mp integers */    SECITEM_TO_MPINT(key->prime1,      &p);    /* p */    SECITEM_TO_MPINT(key->prime2,      &q);    /* q */    SECITEM_TO_MPINT(key->exponent1,   &d_p);  /* d_p  = d mod (p-1) */    SECITEM_TO_MPINT(key->exponent2,   &d_q);  /* d_p  = q mod (q-1) */    SECITEM_TO_MPINT(key->coefficient, &qInv); /* qInv = q**-1 mod p */    /* copy input into mp integer c */    OCTETS_TO_MPINT(input, &c, modLen);    /* 1. m1 = c**d_p mod p */    CHECK_MPI_OK( mp_exptmod(&c, &d_p, &p, &m1) );    /* 2. m2 = c**d_q mod q */    CHECK_MPI_OK( mp_exptmod(&c, &d_q, &q, &m2) );    /* 3.  h = (m1 - m2) * qInv mod p */    CHECK_MPI_OK( mp_submod(&m1, &m2, &p, &h) );    CHECK_MPI_OK( mp_mulmod(&h, &qInv, &p, &h)  );    /* 4.  m = m2 + h * q */    CHECK_MPI_OK( mp_mul(&h, &q, &m) );    CHECK_MPI_OK( mp_add(&m, &m2, &m) );    /* m is the output */    err = mp_to_fixlen_octets(&m, output, modLen);    if (err >= 0) err = MP_OKAY;cleanup:    mp_clear(&p);    mp_clear(&q);    mp_clear(&d_p);    mp_clear(&d_q);    mp_clear(&qInv);    mp_clear(&m);    mp_clear(&m1);    mp_clear(&m2);    mp_clear(&b2);    mp_clear(&h);    mp_clear(&c);    if (err) {	MP_TO_SEC_ERROR(err);	rv = SECFailure;    }    return rv;}