int rsaencrypt(unsigned char *data, int length, struct RSAKey *key) { Bignum b1, b2; int i; unsigned char *p; if (key->bytes < length + 4) return 0; /* RSA key too short! */ memmove(data + key->bytes - length, data, length); data[0] = 0; data[1] = 2; for (i = 2; i < key->bytes - length - 1; i++) { do { data[i] = random_byte(); } while (data[i] == 0); } data[key->bytes - length - 1] = 0; b1 = bignum_from_bytes(data, key->bytes); b2 = modpow(b1, key->exponent, key->modulus); p = data; for (i = key->bytes; i--;) { *p++ = bignum_byte(b2, i); } freebn(b1); freebn(b2); return 1; }
int ec_edgenerate(struct ec_key *key, int bits, progfn_t pfn, void *pfnparam) { struct ec_point *publicKey; if (!ec_ed_alg_and_curve_by_bits(bits, &key->publicKey.curve, &key->signalg)) return 0; { /* EdDSA secret keys are just 32 bytes of hash preimage; the * 64-byte SHA-512 hash of that key will be used when signing, * but the form of the key stored on disk is the preimage * only. */ Bignum privMax = bn_power_2(bits); if (!privMax) return 0; key->privateKey = bignum_random_in_range(Zero, privMax); freebn(privMax); if (!key->privateKey) return 0; } publicKey = ec_public(key->privateKey, key->publicKey.curve); if (!publicKey) { freebn(key->privateKey); key->privateKey = NULL; return 0; } key->publicKey.x = publicKey->x; key->publicKey.y = publicKey->y; key->publicKey.z = NULL; sfree(publicKey); return 1; }
static void dss_freekey(void *key) { struct dss_key *dss = (struct dss_key *)key; freebn(dss->p); freebn(dss->q); freebn(dss->g); freebn(dss->y); sfree(dss); }
void freersakey(struct RSAKey *key) { if (key->modulus) freebn(key->modulus); if (key->exponent) freebn(key->exponent); if (key->private_exponent) freebn(key->private_exponent); if (key->comment) sfree(key->comment); }
void rsaencrypt(unsigned char *data, int length, struct RSAKey *key) { Bignum b1, b2; int w, i; unsigned char *p; debug(key->exponent); memmove(data+key->bytes-length, data, length); data[0] = 0; data[1] = 2; for (i = 2; i < key->bytes-length-1; i++) { do { data[i] = random_byte(); } while (data[i] == 0); } data[key->bytes-length-1] = 0; w = (key->bytes+1)/2; b1 = newbn(w); b2 = newbn(w); p = data; for (i=1; i<=w; i++) b1[i] = 0; for (i=0; i<key->bytes; i++) { unsigned char byte = *p++; if ((key->bytes-i) & 1) b1[w-i/2] |= byte; else b1[w-i/2] |= byte<<8; } debug(b1); modpow(b1, key->exponent, key->modulus, b2); debug(b2); p = data; for (i=0; i<key->bytes; i++) { unsigned char b; if (i & 1) b = b2[w-i/2] & 0xFF; else b = b2[w-i/2] >> 8; *p++ = b; } freebn(b1); freebn(b2); }
static void *dss_createkey(unsigned char *pub_blob, int pub_len, unsigned char *priv_blob, int priv_len) { dss_key *dss; char *pb = (char *) priv_blob; char *hash; int hashlen; SHA_State s; unsigned char digest[20]; Bignum ytest; dss = dss_newkey((char *) pub_blob, pub_len); if (!dss) return NULL; dss->x = getmp(&pb, &priv_len); if (!dss->x) { dss_freekey(dss); return NULL; } /* * Check the obsolete hash in the old DSS key format. */ hashlen = -1; getstring(&pb, &priv_len, &hash, &hashlen); if (hashlen == 20) { SHA_Init(&s); sha_mpint(&s, dss->p); sha_mpint(&s, dss->q); sha_mpint(&s, dss->g); SHA_Final(&s, digest); if (0 != memcmp(hash, digest, 20)) { dss_freekey(dss); return NULL; } } /* * Now ensure g^x mod p really is y. */ ytest = modpow(dss->g, dss->x, dss->p); if (0 != bignum_cmp(ytest, dss->y)) { dss_freekey(dss); freebn(ytest); return NULL; } freebn(ytest); return dss; }
int RSAKey::Generate( int bits ) { Bignum pm1, qm1, phi_n; /* * We don't generate e; we just use a standard one always. */ this->exponent = bignum_from_long(RSA_EXPONENT); /* * Generate p and q: primes with combined length `bits', not * congruent to 1 modulo e. (Strictly speaking, we wanted (p-1) * and e to be coprime, and (q-1) and e to be coprime, but in * general that's slightly more fiddly to arrange. By choosing * a prime e, we can simplify the criterion.) */ this->p = primegen(bits / 2, RSA_EXPONENT, 1, NULL, 1); this->q = primegen(bits - bits / 2, RSA_EXPONENT, 1, NULL, 2); /* * Ensure p > q, by swapping them if not. */ if (bignum_cmp(this->p, this->q) < 0) swap( p, q ); /* * Now we have p, q and e. All we need to do now is work out * the other helpful quantities: n=pq, d=e^-1 mod (p-1)(q-1), * and (q^-1 mod p). */ this->modulus = bigmul(this->p, this->q); pm1 = copybn(this->p); decbn(pm1); qm1 = copybn(this->q); decbn(qm1); phi_n = bigmul(pm1, qm1); freebn(pm1); freebn(qm1); this->private_exponent = modinv(this->exponent, phi_n); this->iqmp = modinv(this->q, this->p); /* * Clean up temporary numbers. */ freebn(phi_n); return 1; }
int ec_generate(struct ec_key *key, int bits, progfn_t pfn, void *pfnparam) { struct ec_point *publicKey; if (!ec_nist_alg_and_curve_by_bits( bits, &key->publicKey.curve, &key->signalg)) return 0; key->privateKey = bignum_random_in_range(One, key->publicKey.curve->w.n); if (!key->privateKey) return 0; publicKey = ec_public(key->privateKey, key->publicKey.curve); if (!publicKey) { freebn(key->privateKey); key->privateKey = NULL; return 0; } key->publicKey.x = publicKey->x; key->publicKey.y = publicKey->y; key->publicKey.z = NULL; sfree(publicKey); return 1; }
int ec_generate(struct ec_key *key, int bits, progfn_t pfn, void *pfnparam) { struct ec_point *publicKey; if (bits == 256) { key->publicKey.curve = ec_p256(); } else if (bits == 384) { key->publicKey.curve = ec_p384(); } else if (bits == 521) { key->publicKey.curve = ec_p521(); } else { return 0; } key->privateKey = bignum_random_in_range(One, key->publicKey.curve->w.n); if (!key->privateKey) return 0; publicKey = ec_public(key->privateKey, key->publicKey.curve); if (!publicKey) { freebn(key->privateKey); key->privateKey = NULL; return 0; } key->publicKey.x = publicKey->x; key->publicKey.y = publicKey->y; key->publicKey.z = NULL; sfree(publicKey); return 1; }
static int rsa2_verifysig(void *key, char *sig, int siglen, char *data, int datalen) { struct RSAKey *rsa = (struct RSAKey *) key; Bignum in, out; char *p; int slen; int bytes, i, j, ret; unsigned char hash[20]; getstring(&sig, &siglen, &p, &slen); if (!p || slen != 7 || memcmp(p, "ssh-rsa", 7)) { return 0; } in = getmp(&sig, &siglen); out = modpow(in, rsa->exponent, rsa->modulus); freebn(in); ret = 1; bytes = (bignum_bitcount(rsa->modulus)+7) / 8; /* Top (partial) byte should be zero. */ if (bignum_byte(out, bytes - 1) != 0) ret = 0; /* First whole byte should be 1. */ if (bignum_byte(out, bytes - 2) != 1) ret = 0; /* Most of the rest should be FF. */ for (i = bytes - 3; i >= 20 + ASN1_LEN; i--) { if (bignum_byte(out, i) != 0xFF) ret = 0; } /* Then we expect to see the asn1_weird_stuff. */ for (i = 20 + ASN1_LEN - 1, j = 0; i >= 20; i--, j++) { if (bignum_byte(out, i) != asn1_weird_stuff[j]) ret = 0; } /* Finally, we expect to see the SHA-1 hash of the signed data. */ SHA_Simple(data, datalen, hash); for (i = 19, j = 0; i >= 0; i--, j++) { if (bignum_byte(out, i) != hash[j]) ret = 0; } freebn(out); return ret; }
static void modmult(Bignum r1, Bignum r2, Bignum modulus, Bignum result) { Bignum temp = newbn(modulus[0]+1); Bignum tmp2 = newbn(modulus[0]+1); int i; int bit, bits, digit, smallbit; enter((">modmult\n")); debug(r1); debug(r2); debug(modulus); for (i=1; i<=result[0]; i++) result[i] = 0; /* result := 0 */ for (i=1; i<=temp[0]; i++) temp[i] = (i > r2[0] ? 0 : r2[i]); /* temp := r2 */ bits = 1+msb(r1); for (bit = 0; bit < bits; bit++) { digit = 1 + bit / 16; smallbit = bit % 16; debug(temp); if (digit <= r1[0] && (r1[digit] & (1<<smallbit))) { dmsg(("bit %d\n", bit)); add(temp, result, tmp2); if (ge(tmp2, modulus)) sub(tmp2, modulus, result); else add(tmp2, Zero, result); debug(result); } add(temp, temp, tmp2); if (ge(tmp2, modulus)) sub(tmp2, modulus, temp); else add(tmp2, Zero, temp); } freebn(temp); freebn(tmp2); debug(result); leave(("<modmult\n")); }
static void dss_freekey(void *key) { dss_key *dss = (dss_key *) key; if (dss->p) freebn(dss->p); if (dss->q) freebn(dss->q); if (dss->g) freebn(dss->g); if (dss->y) freebn(dss->y); if (dss->x) freebn(dss->x); sfree(dss); }
static unsigned char *rsa2_sign(void *key, char *data, int datalen, int *siglen) { struct RSAKey *rsa = (struct RSAKey *) key; unsigned char *bytes; int nbytes; unsigned char hash[20]; Bignum in, out; int i, j; SHA_Simple(data, datalen, hash); nbytes = (bignum_bitcount(rsa->modulus) - 1) / 8; assert(1 <= nbytes - 20 - ASN1_LEN); bytes = snewn(nbytes, unsigned char); bytes[0] = 1; for (i = 1; i < nbytes - 20 - ASN1_LEN; i++) bytes[i] = 0xFF; for (i = nbytes - 20 - ASN1_LEN, j = 0; i < nbytes - 20; i++, j++) bytes[i] = asn1_weird_stuff[j]; for (i = nbytes - 20, j = 0; i < nbytes; i++, j++) bytes[i] = hash[j]; in = bignum_from_bytes(bytes, nbytes); sfree(bytes); out = rsa_privkey_op(in, rsa); freebn(in); nbytes = (bignum_bitcount(out) + 7) / 8; bytes = snewn(4 + 7 + 4 + nbytes, unsigned char); PUT_32BIT(bytes, 7); memcpy(bytes + 4, "ssh-rsa", 7); PUT_32BIT(bytes + 4 + 7, nbytes); for (i = 0; i < nbytes; i++) bytes[4 + 7 + 4 + i] = bignum_byte(out, nbytes - 1 - i); freebn(out); *siglen = 4 + 7 + 4 + nbytes; return bytes; }
bool RSAKey::Verify( const CString &data, const CString &sig ) const { Bignum in, out; int bytes, i, j; unsigned char hash[20]; in = bignum_from_bytes( (const unsigned char *) sig.data(), sig.size() ); /* Base (in) must be smaller than the modulus. */ if( bignum_cmp(in, this->modulus) >= 0 ) { freebn(in); return false; } out = modpow(in, this->exponent, this->modulus); freebn(in); bool ret = true; bytes = (bignum_bitcount(this->modulus)+7) / 8; /* Top (partial) byte should be zero. */ if (bignum_byte(out, bytes - 1) != 0) ret = 0; /* First whole byte should be 1. */ if (bignum_byte(out, bytes - 2) != 1) ret = 0; /* Most of the rest should be FF. */ for (i = bytes - 3; i >= 20; i--) { if (bignum_byte(out, i) != 0xFF) ret = 0; } /* Finally, we expect to see the SHA-1 hash of the signed data. */ SHA_Simple( data.data(), data.size(), hash ); for (i = 19, j = 0; i >= 0; i--, j++) { if (bignum_byte(out, i) != hash[j]) ret = false; } freebn(out); return ret; }
static unsigned char *dss_sign(void *key, char *data, int datalen, int *siglen) { struct dss_key *dss = (struct dss_key *) key; Bignum k, gkp, hash, kinv, hxr, r, s; unsigned char digest[20]; unsigned char *bytes; int nbytes, i; SHA_Simple(data, datalen, digest); k = dss_gen_k("DSA deterministic k generator", dss->q, dss->x, digest, sizeof(digest)); kinv = modinv(k, dss->q); /* k^-1 mod q */ assert(kinv); /* * Now we have k, so just go ahead and compute the signature. */ gkp = modpow(dss->g, k, dss->p); /* g^k mod p */ r = bigmod(gkp, dss->q); /* r = (g^k mod p) mod q */ freebn(gkp); hash = bignum_from_bytes(digest, 20); hxr = bigmuladd(dss->x, r, hash); /* hash + x*r */ s = modmul(kinv, hxr, dss->q); /* s = k^-1 * (hash + x*r) mod q */ freebn(hxr); freebn(kinv); freebn(k); freebn(hash); /* * Signature blob is * * string "ssh-dss" * string two 20-byte numbers r and s, end to end * * i.e. 4+7 + 4+40 bytes. */ nbytes = 4 + 7 + 4 + 40; bytes = snewn(nbytes, unsigned char); PUT_32BIT(bytes, 7); memcpy(bytes + 4, "ssh-dss", 7); PUT_32BIT(bytes + 4 + 7, 40); for (i = 0; i < 20; i++) { bytes[4 + 7 + 4 + i] = bignum_byte(r, 19 - i); bytes[4 + 7 + 4 + 20 + i] = bignum_byte(s, 19 - i); } freebn(r); freebn(s); *siglen = nbytes; return bytes; }
/* * DH stage 2-epsilon: given a number f, validate it to ensure it's in * range. (RFC 4253 section 8: "Values of 'e' or 'f' that are not in * the range [1, p-1] MUST NOT be sent or accepted by either side." * Also, we rule out 1 and p-1 too, since that's easy to do and since * they lead to obviously weak keys that even a passive eavesdropper * can figure out.) */ const char *dh_validate_f(void *handle, Bignum f) { struct dh_ctx *ctx = (struct dh_ctx *)handle; if (bignum_cmp(f, One) <= 0) { return "f value received is too small"; } else { Bignum pm1 = bigsub(ctx->p, One); int cmp = bignum_cmp(f, pm1); freebn(pm1); if (cmp >= 0) return "f value received is too large"; } return NULL; }
/* * DH stage 1: invent a number x between 1 and q, and compute e = * g^x mod p. Return e. * * If `nbits' is greater than zero, it is used as an upper limit * for the number of bits in x. This is safe provided that (a) you * use twice as many bits in x as the number of bits you expect to * use in your session key, and (b) the DH group is a safe prime * (which SSH demands that it must be). * * P. C. van Oorschot, M. J. Wiener * "On Diffie-Hellman Key Agreement with Short Exponents". * Advances in Cryptology: Proceedings of Eurocrypt '96 * Springer-Verlag, May 1996. */ Bignum dh_create_e(void *handle, int nbits) { struct dh_ctx *ctx = (struct dh_ctx *)handle; int i; int nbytes; unsigned char *buf; nbytes = ssh1_bignum_length(ctx->qmask); buf = snewn(nbytes, unsigned char); do { /* * Create a potential x, by ANDing a string of random bytes * with qmask. */ if (ctx->x) freebn(ctx->x); if (nbits == 0 || nbits > bignum_bitcount(ctx->qmask)) { ssh1_write_bignum(buf, ctx->qmask); for (i = 2; i < nbytes; i++) buf[i] &= random_byte(); ssh1_read_bignum(buf, nbytes, &ctx->x); /* can't fail */ } else { int b, nb; ctx->x = bn_power_2(nbits); b = nb = 0; for (i = 0; i < nbits; i++) { if (nb == 0) { nb = 8; b = random_byte(); } bignum_set_bit(ctx->x, i, b & 1); b >>= 1; nb--; } } } while (bignum_cmp(ctx->x, One) <= 0 || bignum_cmp(ctx->x, ctx->q) >= 0); sfree(buf); /* * Done. Now compute e = g^x mod p. */ ctx->e = modpow(ctx->g, ctx->x, ctx->p); return ctx->e; }
/* * Clean up and free a context. */ void dh_cleanup(void *handle) { struct dh_ctx *ctx = (struct dh_ctx *)handle; freebn(ctx->x); freebn(ctx->e); freebn(ctx->p); freebn(ctx->g); freebn(ctx->q); freebn(ctx->qmask); sfree(ctx); }
/* * Verify that the public data in an RSA key matches the private * data. We also check the private data itself: we ensure that p > * q and that iqmp really is the inverse of q mod p. */ bool RSAKey::Check() const { Bignum n, ed, pm1, qm1; int cmp; /* n must equal pq. */ n = bigmul(this->p, this->q); cmp = bignum_cmp(n, this->modulus); freebn(n); if (cmp != 0) return 0; /* e * d must be congruent to 1, modulo (p-1) and modulo (q-1). */ pm1 = copybn(this->p); decbn(pm1); ed = modmul(this->exponent, this->private_exponent, pm1); cmp = bignum_cmp(ed, One); delete [] ed; if (cmp != 0) return 0; qm1 = copybn(this->q); decbn(qm1); ed = modmul(this->exponent, this->private_exponent, qm1); cmp = bignum_cmp(ed, One); delete [] ed; if (cmp != 0) return 0; /* * Ensure p > q. */ if (bignum_cmp(this->p, this->q) <= 0) return 0; /* * Ensure iqmp * q is congruent to 1, modulo p. */ n = modmul(this->iqmp, this->q, this->p); cmp = bignum_cmp(n, One); delete [] n; if (cmp != 0) return 0; return 1; }
/* * Verify that the public data in an RSA key matches the private * data. We also check the private data itself: we ensure that p > * q and that iqmp really is the inverse of q mod p. */ int rsa_verify(struct RSAKey *key) { Bignum n, ed, pm1, qm1; int cmp; /* n must equal pq. */ n = bigmul(key->p, key->q); cmp = bignum_cmp(n, key->modulus); freebn(n); if (cmp != 0) return 0; /* e * d must be congruent to 1, modulo (p-1) and modulo (q-1). */ pm1 = copybn(key->p); decbn(pm1); ed = modmul(key->exponent, key->private_exponent, pm1); cmp = bignum_cmp(ed, One); sfree(ed); if (cmp != 0) return 0; qm1 = copybn(key->q); decbn(qm1); ed = modmul(key->exponent, key->private_exponent, qm1); cmp = bignum_cmp(ed, One); sfree(ed); if (cmp != 0) return 0; /* * Ensure p > q. */ if (bignum_cmp(key->p, key->q) <= 0) return 0; /* * Ensure iqmp * q is congruent to 1, modulo p. */ n = modmul(key->iqmp, key->q, key->p); cmp = bignum_cmp(n, One); sfree(n); if (cmp != 0) return 0; return 1; }
RSAKey::~RSAKey() { if(p) freebn(p); if(q) freebn(q); if(modulus) freebn(modulus); if(exponent) freebn(exponent); if(private_exponent) freebn(private_exponent); if(iqmp) freebn(iqmp); }
int rsa_generate(struct RSAKey *key, struct RSAAux *aux, int bits, progfn_t pfn, void *pfnparam) { Bignum pm1, qm1, phi_n; /* * Set up the phase limits for the progress report. We do this * by passing minus the phase number. * * For prime generation: our initial filter finds things * coprime to everything below 2^16. Computing the product of * (p-1)/p for all prime p below 2^16 gives about 20.33; so * among B-bit integers, one in every 20.33 will get through * the initial filter to be a candidate prime. * * Meanwhile, we are searching for primes in the region of 2^B; * since pi(x) ~ x/log(x), when x is in the region of 2^B, the * prime density will be d/dx pi(x) ~ 1/log(B), i.e. about * 1/0.6931B. So the chance of any given candidate being prime * is 20.33/0.6931B, which is roughly 29.34 divided by B. * * So now we have this probability P, we're looking at an * exponential distribution with parameter P: we will manage in * one attempt with probability P, in two with probability * P(1-P), in three with probability P(1-P)^2, etc. The * probability that we have still not managed to find a prime * after N attempts is (1-P)^N. * * We therefore inform the progress indicator of the number B * (29.34/B), so that it knows how much to increment by each * time. We do this in 16-bit fixed point, so 29.34 becomes * 0x1D.57C4. */ pfn(pfnparam, -1, -0x1D57C4/(bits/2)); pfn(pfnparam, -2, -0x1D57C4/(bits-bits/2)); pfn(pfnparam, -3, 5); /* * We don't generate e; we just use a standard one always. */ key->exponent = bignum_from_short(RSA_EXPONENT); /* * Generate p and q: primes with combined length `bits', not * congruent to 1 modulo e. (Strictly speaking, we wanted (p-1) * and e to be coprime, and (q-1) and e to be coprime, but in * general that's slightly more fiddly to arrange. By choosing * a prime e, we can simplify the criterion.) */ aux->p = primegen(bits/2, RSA_EXPONENT, 1, 1, pfn, pfnparam); aux->q = primegen(bits - bits/2, RSA_EXPONENT, 1, 2, pfn, pfnparam); /* * Ensure p > q, by swapping them if not. */ if (bignum_cmp(aux->p, aux->q) < 0) { Bignum t = aux->p; aux->p = aux->q; aux->q = t; } /* * Now we have p, q and e. All we need to do now is work out * the other helpful quantities: n=pq, d=e^-1 mod (p-1)(q-1), * and (q^-1 mod p). */ pfn(pfnparam, 3, 1); key->modulus = bigmul(aux->p, aux->q); pfn(pfnparam, 3, 2); pm1 = copybn(aux->p); decbn(pm1); qm1 = copybn(aux->q); decbn(qm1); phi_n = bigmul(pm1, qm1); pfn(pfnparam, 3, 3); freebn(pm1); freebn(qm1); key->private_exponent = modinv(key->exponent, phi_n); pfn(pfnparam, 3, 4); aux->iqmp = modinv(aux->q, aux->p); pfn(pfnparam, 3, 5); /* * Clean up temporary numbers. */ freebn(phi_n); return 1; }
/* * This function is a wrapper on modpow(). It has the same effect * as modpow(), but employs RSA blinding to protect against timing * attacks. */ static Bignum rsa_privkey_op(Bignum input, struct RSAKey *key) { Bignum random, random_encrypted, random_inverse; Bignum input_blinded, ret_blinded; Bignum ret; SHA512_State ss; unsigned char digest512[64]; int digestused = lenof(digest512); int hashseq = 0; /* * Start by inventing a random number chosen uniformly from the * range 2..modulus-1. (We do this by preparing a random number * of the right length and retrying if it's greater than the * modulus, to prevent any potential Bleichenbacher-like * attacks making use of the uneven distribution within the * range that would arise from just reducing our number mod n. * There are timing implications to the potential retries, of * course, but all they tell you is the modulus, which you * already knew.) * * To preserve determinism and avoid Pageant needing to share * the random number pool, we actually generate this `random' * number by hashing stuff with the private key. */ while (1) { int bits, byte, bitsleft, v; random = copybn(key->modulus); /* * Find the topmost set bit. (This function will return its * index plus one.) Then we'll set all bits from that one * downwards randomly. */ bits = bignum_bitcount(random); byte = 0; bitsleft = 0; while (bits--) { if (bitsleft <= 0) { bitsleft = 8; /* * Conceptually the following few lines are equivalent to * byte = random_byte(); */ if (digestused >= lenof(digest512)) { unsigned char seqbuf[4]; PUT_32BIT(seqbuf, hashseq); pSHA512_Init(&ss); SHA512_Bytes(&ss, "RSA deterministic blinding", 26); SHA512_Bytes(&ss, seqbuf, sizeof(seqbuf)); sha512_mpint(&ss, key->private_exponent); pSHA512_Final(&ss, digest512); hashseq++; /* * Now hash that digest plus the signature * input. */ pSHA512_Init(&ss); SHA512_Bytes(&ss, digest512, sizeof(digest512)); sha512_mpint(&ss, input); pSHA512_Final(&ss, digest512); digestused = 0; } byte = digest512[digestused++]; } v = byte & 1; byte >>= 1; bitsleft--; bignum_set_bit(random, bits, v); } /* * Now check that this number is strictly greater than * zero, and strictly less than modulus. */ if (bignum_cmp(random, Zero) <= 0 || bignum_cmp(random, key->modulus) >= 0) { freebn(random); continue; } else { break; } } /* * RSA blinding relies on the fact that (xy)^d mod n is equal * to (x^d mod n) * (y^d mod n) mod n. We invent a random pair * y and y^d; then we multiply x by y, raise to the power d mod * n as usual, and divide by y^d to recover x^d. Thus an * attacker can't correlate the timing of the modpow with the * input, because they don't know anything about the number * that was input to the actual modpow. * * The clever bit is that we don't have to do a huge modpow to * get y and y^d; we will use the number we just invented as * _y^d_, and use the _public_ exponent to compute (y^d)^e = y * from it, which is much faster to do. */ random_encrypted = modpow(random, key->exponent, key->modulus); random_inverse = modinv(random, key->modulus); input_blinded = modmul(input, random_encrypted, key->modulus); ret_blinded = modpow(input_blinded, key->private_exponent, key->modulus); ret = modmul(ret_blinded, random_inverse, key->modulus); freebn(ret_blinded); freebn(input_blinded); freebn(random_inverse); freebn(random_encrypted); freebn(random); return ret; }
Bignum *dss_gen_k(const char *id_string, Bignum modulus, Bignum private_key, unsigned char *digest, int digest_len) { /* * The basic DSS signing algorithm is: * * - invent a random k between 1 and q-1 (exclusive). * - Compute r = (g^k mod p) mod q. * - Compute s = k^-1 * (hash + x*r) mod q. * * This has the dangerous properties that: * * - if an attacker in possession of the public key _and_ the * signature (for example, the host you just authenticated * to) can guess your k, he can reverse the computation of s * and work out x = r^-1 * (s*k - hash) mod q. That is, he * can deduce the private half of your key, and masquerade * as you for as long as the key is still valid. * * - since r is a function purely of k and the public key, if * the attacker only has a _range of possibilities_ for k * it's easy for him to work through them all and check each * one against r; he'll never be unsure of whether he's got * the right one. * * - if you ever sign two different hashes with the same k, it * will be immediately obvious because the two signatures * will have the same r, and moreover an attacker in * possession of both signatures (and the public key of * course) can compute k = (hash1-hash2) * (s1-s2)^-1 mod q, * and from there deduce x as before. * * - the Bleichenbacher attack on DSA makes use of methods of * generating k which are significantly non-uniformly * distributed; in particular, generating a 160-bit random * number and reducing it mod q is right out. * * For this reason we must be pretty careful about how we * generate our k. Since this code runs on Windows, with no * particularly good system entropy sources, we can't trust our * RNG itself to produce properly unpredictable data. Hence, we * use a totally different scheme instead. * * What we do is to take a SHA-512 (_big_) hash of the private * key x, and then feed this into another SHA-512 hash that * also includes the message hash being signed. That is: * * proto_k = SHA512 ( SHA512(x) || SHA160(message) ) * * This number is 512 bits long, so reducing it mod q won't be * noticeably non-uniform. So * * k = proto_k mod q * * This has the interesting property that it's _deterministic_: * signing the same hash twice with the same key yields the * same signature. * * Despite this determinism, it's still not predictable to an * attacker, because in order to repeat the SHA-512 * construction that created it, the attacker would have to * know the private key value x - and by assumption he doesn't, * because if he knew that he wouldn't be attacking k! * * (This trick doesn't, _per se_, protect against reuse of k. * Reuse of k is left to chance; all it does is prevent * _excessively high_ chances of reuse of k due to entropy * problems.) * * Thanks to Colin Plumb for the general idea of using x to * ensure k is hard to guess, and to the Cambridge University * Computer Security Group for helping to argue out all the * fine details. */ SHA512_State ss; unsigned char digest512[64]; Bignum proto_k, k; /* * Hash some identifying text plus x. */ SHA512_Init(&ss); SHA512_Bytes(&ss, id_string, strlen(id_string) + 1); sha512_mpint(&ss, private_key); SHA512_Final(&ss, digest512); /* * Now hash that digest plus the message hash. */ SHA512_Init(&ss); SHA512_Bytes(&ss, digest512, sizeof(digest512)); SHA512_Bytes(&ss, digest, digest_len); while (1) { SHA512_State ss2 = ss; /* structure copy */ SHA512_Final(&ss2, digest512); smemclr(&ss2, sizeof(ss2)); /* * Now convert the result into a bignum, and reduce it mod q. */ proto_k = bignum_from_bytes(digest512, 64); k = bigmod(proto_k, modulus); freebn(proto_k); if (bignum_cmp(k, One) != 0 && bignum_cmp(k, Zero) != 0) { smemclr(&ss, sizeof(ss)); smemclr(digest512, sizeof(digest512)); return k; } /* Very unlikely we get here, but if so, k was unsuitable. */ freebn(k); /* Perturb the hash to think of a different k. */ SHA512_Bytes(&ss, "x", 1); /* Go round and try again. */ } }
int dsa_generate(struct dss_key *key, int bits, progfn_t pfn, void *pfnparam) { Bignum qm1, power, g, h, tmp; unsigned pfirst, qfirst; int progress; /* * Set up the phase limits for the progress report. We do this * by passing minus the phase number. * * For prime generation: our initial filter finds things * coprime to everything below 2^16. Computing the product of * (p-1)/p for all prime p below 2^16 gives about 20.33; so * among B-bit integers, one in every 20.33 will get through * the initial filter to be a candidate prime. * * Meanwhile, we are searching for primes in the region of 2^B; * since pi(x) ~ x/log(x), when x is in the region of 2^B, the * prime density will be d/dx pi(x) ~ 1/log(B), i.e. about * 1/0.6931B. So the chance of any given candidate being prime * is 20.33/0.6931B, which is roughly 29.34 divided by B. * * So now we have this probability P, we're looking at an * exponential distribution with parameter P: we will manage in * one attempt with probability P, in two with probability * P(1-P), in three with probability P(1-P)^2, etc. The * probability that we have still not managed to find a prime * after N attempts is (1-P)^N. * * We therefore inform the progress indicator of the number B * (29.34/B), so that it knows how much to increment by each * time. We do this in 16-bit fixed point, so 29.34 becomes * 0x1D.57C4. */ pfn(pfnparam, PROGFN_PHASE_EXTENT, 1, 0x2800); pfn(pfnparam, PROGFN_EXP_PHASE, 1, -0x1D57C4 / 160); pfn(pfnparam, PROGFN_PHASE_EXTENT, 2, 0x40 * bits); pfn(pfnparam, PROGFN_EXP_PHASE, 2, -0x1D57C4 / bits); /* * In phase three we are finding an order-q element of the * multiplicative group of p, by finding an element whose order * is _divisible_ by q and raising it to the power of (p-1)/q. * _Most_ elements will have order divisible by q, since for a * start phi(p) of them will be primitive roots. So * realistically we don't need to set this much below 1 (64K). * Still, we'll set it to 1/2 (32K) to be on the safe side. */ pfn(pfnparam, PROGFN_PHASE_EXTENT, 3, 0x2000); pfn(pfnparam, PROGFN_EXP_PHASE, 3, -32768); /* * In phase four we are finding an element x between 1 and q-1 * (exclusive), by inventing 160 random bits and hoping they * come out to a plausible number; so assuming q is uniformly * distributed between 2^159 and 2^160, the chance of any given * attempt succeeding is somewhere between 0.5 and 1. Lacking * the energy to arrange to be able to specify this probability * _after_ generating q, we'll just set it to 0.75. */ pfn(pfnparam, PROGFN_PHASE_EXTENT, 4, 0x2000); pfn(pfnparam, PROGFN_EXP_PHASE, 4, -49152); pfn(pfnparam, PROGFN_READY, 0, 0); invent_firstbits(&pfirst, &qfirst); /* * Generate q: a prime of length 160. */ key->q = primegen(160, 2, 2, NULL, 1, pfn, pfnparam, qfirst); /* * Now generate p: a prime of length `bits', such that p-1 is * divisible by q. */ key->p = primegen(bits-160, 2, 2, key->q, 2, pfn, pfnparam, pfirst); /* * Next we need g. Raise 2 to the power (p-1)/q modulo p, and * if that comes out to one then try 3, then 4 and so on. As * soon as we hit a non-unit (and non-zero!) one, that'll do * for g. */ power = bigdiv(key->p, key->q); /* this is floor(p/q) == (p-1)/q */ h = bignum_from_long(1); progress = 0; while (1) { pfn(pfnparam, PROGFN_PROGRESS, 3, ++progress); g = modpow(h, power, key->p); if (bignum_cmp(g, One) > 0) break; /* got one */ tmp = h; h = bignum_add_long(h, 1); freebn(tmp); } key->g = g; freebn(h); /* * Now we're nearly done. All we need now is our private key x, * which should be a number between 1 and q-1 exclusive, and * our public key y = g^x mod p. */ qm1 = copybn(key->q); decbn(qm1); progress = 0; while (1) { int i, v, byte, bitsleft; Bignum x; pfn(pfnparam, PROGFN_PROGRESS, 4, ++progress); x = bn_power_2(159); byte = 0; bitsleft = 0; for (i = 0; i < 160; i++) { if (bitsleft <= 0) bitsleft = 8, byte = random_byte(); v = byte & 1; byte >>= 1; bitsleft--; bignum_set_bit(x, i, v); } if (bignum_cmp(x, One) <= 0 || bignum_cmp(x, qm1) >= 0) { freebn(x); continue; } else { key->x = x; break; } } freebn(qm1); key->y = modpow(key->g, key->x, key->p); return 1; }
/* * Generate a prime. We arrange to select a prime with the property * (prime % modulus) != residue (to speed up use in RSA). */ Bignum primegen(int bits, int modulus, int residue, int phase, progfn_t pfn, void *pfnparam) { int i, k, v, byte, bitsleft, check, checks; unsigned long delta, moduli[NPRIMES+1], residues[NPRIMES+1]; Bignum p, pm1, q, wqp, wqp2; int progress = 0; byte = 0; bitsleft = 0; STARTOVER: pfn(pfnparam, phase, ++progress); /* * Generate a k-bit random number with top and bottom bits set. */ p = newbn((bits+15)/16); for (i = 0; i < bits; i++) { if (i == 0 || i == bits-1) v = 1; else { if (bitsleft <= 0) bitsleft = 8; byte = random_byte(); v = byte & 1; byte >>= 1; bitsleft--; } bignum_set_bit(p, i, v); } /* * Ensure this random number is coprime to the first few * primes, by repeatedly adding 2 to it until it is. */ for (i = 0; i < NPRIMES; i++) { moduli[i] = primes[i]; residues[i] = bignum_mod_short(p, primes[i]); } moduli[NPRIMES] = modulus; residues[NPRIMES] = (bignum_mod_short(p, (unsigned short)modulus) + modulus - residue); delta = 0; while (1) { for (i = 0; i < (sizeof(moduli) / sizeof(*moduli)); i++) if (!((residues[i] + delta) % moduli[i])) break; if (i < (sizeof(moduli) / sizeof(*moduli))) {/* we broke */ delta += 2; if (delta < 2) { freebn(p); goto STARTOVER; } continue; } break; } q = p; p = bignum_add_long(q, delta); freebn(q); /* * Now apply the Miller-Rabin primality test a few times. First * work out how many checks are needed. */ checks = 27; if (bits >= 150) checks = 18; if (bits >= 200) checks = 15; if (bits >= 250) checks = 12; if (bits >= 300) checks = 9; if (bits >= 350) checks = 8; if (bits >= 400) checks = 7; if (bits >= 450) checks = 6; if (bits >= 550) checks = 5; if (bits >= 650) checks = 4; if (bits >= 850) checks = 3; if (bits >= 1300) checks = 2; /* * Next, write p-1 as q*2^k. */ for (k = 0; bignum_bit(p, k) == !k; k++); /* find first 1 bit in p-1 */ q = bignum_rshift(p, k); /* And store p-1 itself, which we'll need. */ pm1 = copybn(p); decbn(pm1); /* * Now, for each check ... */ for (check = 0; check < checks; check++) { Bignum w; /* * Invent a random number between 1 and p-1 inclusive. */ while (1) { w = newbn((bits+15)/16); for (i = 0; i < bits; i++) { if (bitsleft <= 0) bitsleft = 8; byte = random_byte(); v = byte & 1; byte >>= 1; bitsleft--; bignum_set_bit(w, i, v); } if (bignum_cmp(w, p) >= 0 || bignum_cmp(w, Zero) == 0) { freebn(w); continue; } break; } pfn(pfnparam, phase, ++progress); /* * Compute w^q mod p. */ wqp = modpow(w, q, p); freebn(w); /* * See if this is 1, or if it is -1, or if it becomes -1 * when squared at most k-1 times. */ if (bignum_cmp(wqp, One) == 0 || bignum_cmp(wqp, pm1) == 0) { freebn(wqp); continue; } for (i = 0; i < k-1; i++) { wqp2 = modmul(wqp, wqp, p); freebn(wqp); wqp = wqp2; if (bignum_cmp(wqp, pm1) == 0) break; } if (i < k-1) { freebn(wqp); continue; } /* * It didn't. Therefore, w is a witness for the * compositeness of p. */ freebn(p); freebn(pm1); freebn(q); goto STARTOVER; } /* * We have a prime! */ freebn(q); freebn(pm1); return p; }
static int dss_verifysig(void *key, char *sig, int siglen, char *data, int datalen) { struct dss_key *dss = (struct dss_key *) key; char *p; int slen; char hash[20]; Bignum r, s, w, gu1p, yu2p, gu1yu2p, u1, u2, sha, v; int ret; if (!dss->p) return 0; #ifdef DEBUG_DSS { int i; printf("sig:"); for (i = 0; i < siglen; i++) printf(" %02x", (unsigned char) (sig[i])); printf("\n"); } #endif /* * Commercial SSH (2.0.13) and OpenSSH disagree over the format * of a DSA signature. OpenSSH is in line with the IETF drafts: * it uses a string "ssh-dss", followed by a 40-byte string * containing two 160-bit integers end-to-end. Commercial SSH * can't be bothered with the header bit, and considers a DSA * signature blob to be _just_ the 40-byte string containing * the two 160-bit integers. We tell them apart by measuring * the length: length 40 means the commercial-SSH bug, anything * else is assumed to be IETF-compliant. */ if (siglen != 40) { /* bug not present; read admin fields */ getstring(&sig, &siglen, &p, &slen); if (!p || slen != 7 || memcmp(p, "ssh-dss", 7)) { return 0; } sig += 4, siglen -= 4; /* skip yet another length field */ } r = get160(&sig, &siglen); s = get160(&sig, &siglen); if (!r || !s) return 0; /* * Step 1. w <- s^-1 mod q. */ w = modinv(s, dss->q); /* * Step 2. u1 <- SHA(message) * w mod q. */ SHA_Simple(data, datalen, (unsigned char *)hash); p = hash; slen = 20; sha = get160(&p, &slen); u1 = modmul(sha, w, dss->q); /* * Step 3. u2 <- r * w mod q. */ u2 = modmul(r, w, dss->q); /* * Step 4. v <- (g^u1 * y^u2 mod p) mod q. */ gu1p = modpow(dss->g, u1, dss->p); yu2p = modpow(dss->y, u2, dss->p); gu1yu2p = modmul(gu1p, yu2p, dss->p); v = modmul(gu1yu2p, One, dss->q); /* * Step 5. v should now be equal to r. */ ret = !bignum_cmp(v, r); freebn(w); freebn(sha); freebn(gu1p); freebn(yu2p); freebn(gu1yu2p); freebn(v); freebn(r); freebn(s); return ret; }
static unsigned char *dss_sign(void *key, char *data, int datalen, int *siglen) { /* * The basic DSS signing algorithm is: * * - invent a random k between 1 and q-1 (exclusive). * - Compute r = (g^k mod p) mod q. * - Compute s = k^-1 * (hash + x*r) mod q. * * This has the dangerous properties that: * * - if an attacker in possession of the public key _and_ the * signature (for example, the host you just authenticated * to) can guess your k, he can reverse the computation of s * and work out x = r^-1 * (s*k - hash) mod q. That is, he * can deduce the private half of your key, and masquerade * as you for as long as the key is still valid. * * - since r is a function purely of k and the public key, if * the attacker only has a _range of possibilities_ for k * it's easy for him to work through them all and check each * one against r; he'll never be unsure of whether he's got * the right one. * * - if you ever sign two different hashes with the same k, it * will be immediately obvious because the two signatures * will have the same r, and moreover an attacker in * possession of both signatures (and the public key of * course) can compute k = (hash1-hash2) * (s1-s2)^-1 mod q, * and from there deduce x as before. * * - the Bleichenbacher attack on DSA makes use of methods of * generating k which are significantly non-uniformly * distributed; in particular, generating a 160-bit random * number and reducing it mod q is right out. * * For this reason we must be pretty careful about how we * generate our k. Since this code runs on Windows, with no * particularly good system entropy sources, we can't trust our * RNG itself to produce properly unpredictable data. Hence, we * use a totally different scheme instead. * * What we do is to take a SHA-512 (_big_) hash of the private * key x, and then feed this into another SHA-512 hash that * also includes the message hash being signed. That is: * * proto_k = SHA512 ( SHA512(x) || SHA160(message) ) * * This number is 512 bits long, so reducing it mod q won't be * noticeably non-uniform. So * * k = proto_k mod q * * This has the interesting property that it's _deterministic_: * signing the same hash twice with the same key yields the * same signature. * * Despite this determinism, it's still not predictable to an * attacker, because in order to repeat the SHA-512 * construction that created it, the attacker would have to * know the private key value x - and by assumption he doesn't, * because if he knew that he wouldn't be attacking k! * * (This trick doesn't, _per se_, protect against reuse of k. * Reuse of k is left to chance; all it does is prevent * _excessively high_ chances of reuse of k due to entropy * problems.) * * Thanks to Colin Plumb for the general idea of using x to * ensure k is hard to guess, and to the Cambridge University * Computer Security Group for helping to argue out all the * fine details. */ struct dss_key *dss = (struct dss_key *) key; SHA512_State ss; unsigned char digest[20], digest512[64]; Bignum proto_k, k, gkp, hash, kinv, hxr, r, s; unsigned char *bytes; int nbytes, i; SHA_Simple(data, datalen, digest); /* * Hash some identifying text plus x. */ SHA512_Init(&ss); SHA512_Bytes(&ss, "DSA deterministic k generator", 30); sha512_mpint(&ss, dss->x); SHA512_Final(&ss, digest512); /* * Now hash that digest plus the message hash. */ SHA512_Init(&ss); SHA512_Bytes(&ss, digest512, sizeof(digest512)); SHA512_Bytes(&ss, digest, sizeof(digest)); SHA512_Final(&ss, digest512); memset(&ss, 0, sizeof(ss)); /* * Now convert the result into a bignum, and reduce it mod q. */ proto_k = bignum_from_bytes(digest512, 64); k = bigmod(proto_k, dss->q); freebn(proto_k); memset(digest512, 0, sizeof(digest512)); /* * Now we have k, so just go ahead and compute the signature. */ gkp = modpow(dss->g, k, dss->p); /* g^k mod p */ r = bigmod(gkp, dss->q); /* r = (g^k mod p) mod q */ freebn(gkp); hash = bignum_from_bytes(digest, 20); kinv = modinv(k, dss->q); /* k^-1 mod q */ hxr = bigmuladd(dss->x, r, hash); /* hash + x*r */ s = modmul(kinv, hxr, dss->q); /* s = k^-1 * (hash + x*r) mod q */ freebn(hxr); freebn(kinv); freebn(hash); /* * Signature blob is * * string "ssh-dss" * string two 20-byte numbers r and s, end to end * * i.e. 4+7 + 4+40 bytes. */ nbytes = 4 + 7 + 4 + 40; bytes = snewn(nbytes, unsigned char); PUT_32BIT(bytes, 7); memcpy(bytes + 4, "ssh-dss", 7); PUT_32BIT(bytes + 4 + 7, 40); for (i = 0; i < 20; i++) { bytes[4 + 7 + 4 + i] = bignum_byte(r, 19 - i); bytes[4 + 7 + 4 + 20 + i] = bignum_byte(s, 19 - i); } freebn(r); freebn(s); *siglen = nbytes; return bytes; }
/* * Return a malloc'ed chunk of memory containing the public blob of * an RSA key, as given in the agent protocol (modulus bits, * exponent, modulus). */ int rsakey_pubblob(const Filename *filename, void **blob, int *bloblen, char **commentptr, const char **errorstr) { FILE *fp; char buf[64]; struct RSAKey key; int ret; const char *error = NULL; /* Default return if we fail. */ *blob = NULL; *bloblen = 0; ret = 0; fp = f_open(filename, "rb", FALSE); if (!fp) { error = "can't open file"; goto end; } /* * Read the first line of the file and see if it's a v1 private * key file. */ if (fgets(buf, sizeof(buf), fp) && !strcmp(buf, rsa_signature)) { memset(&key, 0, sizeof(key)); if (loadrsakey_main(fp, &key, TRUE, commentptr, NULL, &error)) { *blob = rsa_public_blob(&key, bloblen); freersakey(&key); ret = 1; } fp = NULL; /* loadrsakey_main unconditionally closes fp */ } else { /* * Try interpreting the file as an SSH-1 public key. */ char *line, *p, *bitsp, *expp, *modp, *commentp; rewind(fp); line = chomp(fgetline(fp)); p = line; bitsp = p; p += strspn(p, "0123456789"); if (*p != ' ') goto not_public_either; *p++ = '\0'; expp = p; p += strspn(p, "0123456789"); if (*p != ' ') goto not_public_either; *p++ = '\0'; modp = p; p += strspn(p, "0123456789"); if (*p) { if (*p != ' ') goto not_public_either; *p++ = '\0'; commentp = p; } else { commentp = NULL; } memset(&key, 0, sizeof(key)); key.exponent = bignum_from_decimal(expp); key.modulus = bignum_from_decimal(modp); if (atoi(bitsp) != bignum_bitcount(key.modulus)) { freebn(key.exponent); freebn(key.modulus); sfree(line); error = "key bit count does not match in SSH-1 public key file"; goto end; } if (commentptr) *commentptr = commentp ? dupstr(commentp) : NULL; *blob = rsa_public_blob(&key, bloblen); freersakey(&key); return 1; not_public_either: sfree(line); error = "not an SSH-1 RSA file"; } end: if (fp) fclose(fp); if ((ret != 1) && errorstr) *errorstr = error; return ret; }