int16 rsa_public_block(uint8 *input, uint16 input_len, uint8 *output, uint16 *output_len, rsa_public_key *public_key) { uint32 c[MAX_NN_DIGITS] = {0}, e[MAX_NN_DIGITS] = {0}, m[MAX_NN_DIGITS] = {0}, n[MAX_NN_DIGITS] = {0}; uint16 eDigits = 0, nDigits = 0; memset (c, 0, sizeof (c)); memset (m, 0, sizeof (m)); memset (n, 0, sizeof (n)); nn_decode (m, MAX_NN_DIGITS, input, input_len); nn_decode (n, MAX_NN_DIGITS, public_key->modulus, MAX_RSA_MODULUS_LEN); nn_decode (e, MAX_NN_DIGITS, public_key->public_exponent, MAX_RSA_MODULUS_LEN); nDigits = nn_digits (n, MAX_NN_DIGITS); eDigits = nn_digits (e, MAX_NN_DIGITS); if (nn_cmp (m, n, nDigits) >= 0) return -1; /* Compute c = m^e mod n. */ nn_mod_exp (c, m, e, eDigits, n, nDigits); *output_len = (uint16)(public_key->bits + 7) / 8; nn_encode (output, *output_len, c, nDigits); return (0); }
/* w.b. hart */ int zz_cmp(zz_srcptr a, zz_srcptr b) { long asize = a->size; long bsize = b->size; int sgn; if (asize > bsize) return 1; else if (asize < bsize) return -1; sgn = nn_cmp(a->n, b->n, ABS(asize)); return asize < 0 ? -sgn : sgn; }
int16 rsa_private_block(uint8 *input, uint16 input_len, uint8 *output, uint16 *output_len, rsa_private_key *private_key) { uint32 c[MAX_NN_DIGITS] = {0}, cP[MAX_NN_DIGITS] = {0}, cQ[MAX_NN_DIGITS] = {0}, dP[MAX_NN_DIGITS] = {0}, dQ[MAX_NN_DIGITS] = {0}, mP[MAX_NN_DIGITS] = {0}, mQ[MAX_NN_DIGITS] = {0}, n[MAX_NN_DIGITS] = {0}, p[MAX_NN_DIGITS] = {0}, q[MAX_NN_DIGITS] = {0}, qInv[MAX_NN_DIGITS] = {0}, t[MAX_NN_DIGITS] = {0}; uint16 cDigits = 0, nDigits = 0, pDigits = 0; memset (c, 0, sizeof (c)); memset (cP, 0, sizeof (cP)); memset (cQ, 0, sizeof (cQ)); memset (dP, 0, sizeof (dP)); memset (dQ, 0, sizeof (dQ)); memset (mP, 0, sizeof (mP)); memset (mQ, 0, sizeof (mQ)); memset (p, 0, sizeof (p)); memset (q, 0, sizeof (q)); memset (qInv, 0, sizeof (qInv)); memset (t, 0, sizeof (t)); nn_decode (c, MAX_NN_DIGITS, input, input_len); nn_decode (n, MAX_NN_DIGITS, private_key->modulus, MAX_RSA_MODULUS_LEN); nn_decode (p, MAX_NN_DIGITS, private_key->prime[0], MAX_RSA_PRIME_LEN); nn_decode (q, MAX_NN_DIGITS, private_key->prime[1], MAX_RSA_PRIME_LEN); nn_decode (dP, MAX_NN_DIGITS, private_key->prime_exponent[0], MAX_RSA_PRIME_LEN); nn_decode (dQ, MAX_NN_DIGITS, private_key->prime_exponent[1], MAX_RSA_PRIME_LEN); nn_decode (qInv, MAX_NN_DIGITS, private_key->coefficient, MAX_RSA_PRIME_LEN); cDigits = nn_digits (c, MAX_NN_DIGITS); nDigits = nn_digits (n, MAX_NN_DIGITS); pDigits = nn_digits (p, MAX_NN_DIGITS); if (nn_cmp (c, n, nDigits) >= 0) return -1; /* Compute mP = cP^dP mod p and mQ = cQ^dQ mod q. (Assumes q has length at most pDigits, i.e., p > q.) */ nn_mod (cP, c, cDigits, p, pDigits); nn_mod (cQ, c, cDigits, q, pDigits); nn_mod_exp (mP, cP, dP, pDigits, p, pDigits); nn_assign_zero (mQ, nDigits); nn_mod_exp (mQ, cQ, dQ, pDigits, q, pDigits); /* Chinese Remainder Theorem: m = ((((mP - mQ) mod p) * qInv) mod p) * q + mQ. */ if (nn_cmp (mP, mQ, pDigits) >= 0) { nn_sub (t, mP, mQ, pDigits); } else { nn_sub (t, mQ, mP, pDigits); nn_sub (t, p, t, pDigits); } nn_mod_mult (t, t, qInv, p, pDigits); nn_mult (t, t, q, pDigits); nn_add (t, t, mQ, nDigits); *output_len = (uint16)(private_key->bits + 7) / 8; nn_encode (output, *output_len, t, nDigits); return (0); }